Overview

Packages

  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Datatype
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationMain
    • NavigationTop
  • mpAutoloaderClassMap
  • None
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SearchSolr
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • cRequestValidator
  • cSecurity
  • cUpdateNotifier
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3:  * This file contains the update notifier class.
  4:  *
  5:  * @package    Core
  6:  * @subpackage Security
  7:  * @version    SVN Revision $Rev:$
  8:  *
  9:  * @author     Dominik Ziegler
 10:  * @copyright  four for business AG <www.4fb.de>
 11:  * @license    http://www.contenido.org/license/LIZENZ.txt
 12:  * @link       http://www.4fb.de
 13:  * @link       http://www.contenido.org
 14:  */
 15: 
 16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 17: 
 18: /**
 19:  * This class contains function for the update notifier.
 20:  *
 21:  * @package    Core
 22:  * @subpackage Security
 23:  */
 24: class cUpdateNotifier {
 25: 
 26:     /**
 27:      * Minor release for the simplexml xpath() method
 28:      *
 29:      * @var string
 30:      */
 31:     protected $sMinorRelease = "";
 32: 
 33:     /**
 34:      * Host for vendor XML
 35:      *
 36:      * @var string
 37:      */
 38:     protected $sVendorHost = "www.contenido.org";
 39: 
 40:     /**
 41:      * Path to files
 42:      *
 43:      * @var string
 44:      */
 45:     protected $sVendorHostPath = "con_version_check_feeds/";
 46: 
 47:     /**
 48:      * Vendor XML file
 49:      *
 50:      * @var string
 51:      */
 52:     protected $sVendorXMLFile = "vendor.xml";
 53: 
 54:     /**
 55:      * German Vendor RSS file
 56:      *
 57:      * @var string
 58:      */
 59:     protected $sVendorRssDeFile = "rss_de.xml";
 60: 
 61:     /**
 62:      * English Vendor RSS file
 63:      *
 64:      * @var string
 65:      */
 66:     protected $sVendorRssEnFile = "rss_en.xml";
 67: 
 68:     /**
 69:      * Language specific RSS file
 70:      *
 71:      * @var string
 72:      */
 73:     protected $sRSSFile = "";
 74: 
 75:     /**
 76:      * Timestamp cache file
 77:      *
 78:      * @var string
 79:      */
 80:     protected $sTimestampCacheFile = "update.txt";
 81: 
 82:     /**
 83:      * Content of the XML file
 84:      *
 85:      * @var string
 86:      */
 87:     protected $sXMLContent = "";
 88: 
 89:     /**
 90:      * Content of the language specific RSS file
 91:      *
 92:      * @var string
 93:      */
 94:     protected $sRSSContent = "";
 95: 
 96:     /**
 97:      * Current available vendor version
 98:      *
 99:      * @var string
100:      */
101:     protected $sVendorVersion = "";
102: 
103:     /**
104:      * Download URL
105:      *
106:      * @var string
107:      */
108:     protected $sVendorURL = "http://www.contenido.org/de/redir";
109: 
110:     /**
111:      * Current backend language
112:      *
113:      * @var string
114:      */
115:     protected $sBackendLanguage = "";
116: 
117:     /**
118:      * Contains the cache path.
119:      *
120:      * @var string
121:      */
122:     protected $sCacheDirectory = "";
123: 
124:     /**
125:      * SimpleXML object
126:      *
127:      * @var object
128:      */
129:     protected $oXML = null;
130: 
131:     /**
132:      * Properties object
133:      *
134:      * @var object
135:      */
136:     protected $oProperties = null;
137: 
138:     /**
139:      * Session object
140:      *
141:      * @var object
142:      */
143:     protected $oSession = null;
144: 
145:     /**
146:      * Timeout for the fsockopen connection
147:      *
148:      * @access protected
149:      * @var integer
150:      */
151:     protected $iConnectTimeout = 3;
152: 
153:     /**
154:      * Cache duration in minutes
155:      *
156:      * @var integer
157:      */
158:     protected $iCacheDuration = 60;
159: 
160:     /**
161:      * Check for system setting
162:      *
163:      * @var boolean
164:      */
165:     protected $bEnableCheck = false;
166: 
167:     /**
168:      * Check for system setting Rss
169:      *
170:      * @var boolean
171:      */
172:     protected $bEnableCheckRss = false;
173: 
174:     /**
175:      * If true CONTENIDO displays a special error message due to missing write
176:      * permissions.
177:      *
178:      * @var boolean
179:      */
180:     protected $bNoWritePermissions = false;
181: 
182:     /**
183:      * Display update notification based on user rights (sysadmin only)
184:      *
185:      * @var boolean
186:      */
187:     protected $bEnableView = false;
188: 
189:     /**
190:      * Update necessity
191:      *
192:      * @var boolean
193:      */
194:     protected $bUpdateNecessity = false;
195: 
196:     /**
197:      * Vendor host reachability.
198:      *
199:      * @var boolean
200:      */
201:     private $bVendorHostReachable = true;
202: 
203:     /**
204:      * Property configuration array
205:      *
206:      * @var array
207:      */
208:     protected $aPropConf = array(
209:         "itemType" => "update",
210:         "itemID" => 1,
211:         "type" => "file_check",
212:         "name" => "xml"
213:     );
214: 
215:     /**
216:      * System property configuration array for update notification
217:      *
218:      * @var array
219:      */
220:     protected $aSysPropConf = array(
221:         "type" => "update",
222:         "name" => "check"
223:     );
224: 
225:     /**
226:      * System property configuration array for rss notification
227:      *
228:      * @var array
229:      */
230:     protected $aSysPropConfRss = array(
231:         "type" => "update",
232:         "name" => "news_feed"
233:     );
234: 
235:     /**
236:      * System property configuration array for update period
237:      *
238:      * @var array
239:      */
240:     protected $aSysPropConfPeriod = array(
241:         "type" => "update",
242:         "name" => "check_period"
243:     );
244: 
245:     /**
246:      * CONTENIDO configuration array
247:      *
248:      * @var array
249:      */
250:     protected $aCfg = array();
251: 
252:     /**
253:      * Constructor of Contenido_UpdateNotifier
254:      *
255:      * @param string $sConVersion
256:      */
257:     public function __construct($aCfg, $oUser, $oPerm, $oSession, $sBackendLanguage) {
258: 
259:         $this->oProperties = new cApiPropertyCollection();
260:         $this->oSession = $oSession;
261:         $this->aCfg = $aCfg;
262:         $this->sBackendLanguage = $sBackendLanguage;
263: 
264:         if ($oPerm->isSysadmin($oUser) != 1) {
265:             $this->bEnableView = false;
266:         } else {
267:             $this->bEnableView = true;
268: 
269:             $sAction = $_GET['do'];
270:             if ($sAction != "") {
271:                 $this->updateSystemProperty($sAction);
272:             }
273: 
274:             $sPropUpdate = getSystemProperty($this->aSysPropConf['type'], $this->aSysPropConf['name']);
275:             $sPropRSS = getSystemProperty($this->aSysPropConfRss['type'], $this->aSysPropConfRss['name']);
276:             $sPeriod = getSystemProperty($this->aSysPropConfPeriod['type'], $this->aSysPropConfPeriod['name']);
277:             $iPeriod = cSecurity::toInteger($sPeriod);
278: 
279:             if ($sPropUpdate == "true" || $sPropRSS == "true") {
280: 
281:                 if ($sPropUpdate == "true") {
282:                     $this->bEnableCheck = true;
283:                 }
284: 
285:                 if ($sPropRSS == "true") {
286:                     $this->bEnableCheckRss = true;
287:                 }
288: 
289:                 // default cache duration of 60 minutes
290:                 if ($iPeriod >= 60) {
291:                     $this->iCacheDuration = $iPeriod;
292:                 } else {
293:                     $this->iCacheDuration = 60;
294:                 }
295: 
296:                 $this->setCachePath();
297:                 if ($this->sCacheDirectory != "") {
298:                     $this->setRSSFile();
299:                     $this->detectMinorRelease();
300:                     $this->checkUpdateNecessity();
301:                     $this->readVendorContent();
302:                 }
303:             }
304:         }
305:     }
306: 
307:     /**
308:      * Sets the actual RSS file for the reader
309:      */
310:     protected function setRSSFile() {
311:         if ($this->sBackendLanguage == "de_DE") {
312:             $this->sRSSFile = $this->sVendorRssDeFile;
313:         } else {
314:             $this->sRSSFile = $this->sVendorRssEnFile;
315:         }
316:     }
317: 
318:     /**
319:      * Updates the system property for activation/deactivation requests
320:      *
321:      * @param $sAction string
322:      */
323:     protected function updateSystemProperty($sAction) {
324:         if ($sAction == "activate") {
325:             setSystemProperty($this->aSysPropConf['type'], $this->aSysPropConf['name'], "true");
326:         } else if ($sAction == "deactivate") {
327:             setSystemProperty($this->aSysPropConf['type'], $this->aSysPropConf['name'], "false");
328:         } else if ($sAction == "activate_rss") {
329:             setSystemProperty($this->aSysPropConfRss['type'], $this->aSysPropConfRss['name'], "true");
330:         } else if ($sAction == "deactivate_rss") {
331:             setSystemProperty($this->aSysPropConfRss['type'], $this->aSysPropConfRss['name'], "false");
332:         }
333:     }
334: 
335:     /**
336:      * Sets the cache path
337:      */
338:     protected function setCachePath() {
339:         $sCachePath = $this->aCfg['path']['contenido_cache'];
340:         if (!is_dir($sCachePath)) {
341:             mkdir($sCachePath, 0777);
342:         }
343: 
344:         if (!is_writable($sCachePath)) {
345:             // setting special flag for error message
346:             $this->bNoWritePermissions = true;
347:         } else {
348:             $this->sCacheDirectory = $sCachePath;
349:         }
350:     }
351: 
352:     /**
353:      * Checks if the xml files must be loaded from the vendor host or local
354:      * cache
355:      */
356:     protected function checkUpdateNecessity() {
357:         $bUpdateNecessity = false;
358: 
359:         $aCheckFiles = array(
360:             $this->sVendorXMLFile,
361:             $this->sVendorRssDeFile,
362:             $this->sVendorRssEnFile,
363:             $this->sTimestampCacheFile
364:         );
365:         foreach ($aCheckFiles as $sFilename) {
366:             if (!cFileHandler::exists($this->sCacheDirectory . $sFilename)) {
367:                 $bUpdateNecessity = true;
368:                 break;
369:             }
370:         }
371: 
372:         if ($bUpdateNecessity == false) {
373:             $iLastUpdate = cFileHandler::read($this->sCacheDirectory . $this->sTimestampCacheFile);
374: 
375:             $iCheckTimestamp = $iLastUpdate + ($this->iCacheDuration * 60);
376:             $iCurrentTime = time();
377: 
378:             if ($iCheckTimestamp > $iCurrentTime) {
379:                 $bUpdateNecessity = false;
380:             } else {
381:                 $bUpdateNecessity = true;
382:             }
383:         }
384: 
385:         $this->bUpdateNecessity = $bUpdateNecessity;
386:     }
387: 
388:     /**
389:      * Detects and converts the minor release of the system version
390:      */
391:     protected function detectMinorRelease() {
392:         $sVersion = $this->aCfg['version'];
393:         $aExplode = explode(".", $sVersion);
394:         $sMinorRelease = "con" . $aExplode[0] . $aExplode[1];
395:         $this->sMinorRelease = $sMinorRelease;
396:     }
397: 
398:     /**
399:      * Reads the xml files from vendor host or cache and checks for file
400:      * manipulations
401:      */
402:     protected function readVendorContent() {
403:         $this->sXMLContent = "";
404: 
405:         if ($this->bUpdateNecessity == true) {
406:             $aXmlContent = $this->getVendorHostFiles();
407: 
408:             if (isset($aXmlContent[$this->sVendorXMLFile]) && isset($aXmlContent[$this->sVendorRssDeFile]) && isset($aXmlContent[$this->sVendorRssEnFile])) {
409:                 $this->handleVendorUpdate($aXmlContent);
410:             }
411:         } else {
412: 
413:             $sXMLContent = cFileHandler::read($this->sCacheDirectory . $this->sVendorXMLFile);
414:             $aRSSContent[$this->sVendorRssDeFile] = cFileHandler::read($this->sCacheDirectory . $this->sVendorRssDeFile);
415:             $aRSSContent[$this->sVendorRssEnFile] = cFileHandler::read($this->sCacheDirectory . $this->sVendorRssEnFile);
416: 
417:             $sXMLHash = md5($sXMLContent . $aRSSContent[$this->sVendorRssDeFile] . $aRSSContent[$this->sVendorRssEnFile]);
418:             $sPropertyHash = $this->getHashProperty();
419:             if ($sXMLHash == $sPropertyHash) {
420:                 $this->sXMLContent = $sXMLContent;
421:                 $this->sRSSContent = $aRSSContent[$this->sRSSFile];
422:             } else {
423:                 $aXmlContent = $this->getVendorHostFiles();
424:                 if (isset($aXmlContent[$this->sVendorXMLFile]) && isset($aXmlContent[$this->sVendorRssDeFile]) && isset($aXmlContent[$this->sVendorRssEnFile])) {
425:                     $this->handleVendorUpdate($aXmlContent);
426:                 }
427:             }
428:         }
429: 
430:         //echo $this->sXMLContent;
431:         //echo $this->sRSSContent;
432:         if ($this->sXMLContent != "") {
433: 
434:             $this->oXML = simplexml_load_string($this->sXMLContent);
435:             if (!is_object($this->oXML)) {
436:                 $sErrorMessage = i18n('Unable to check for new updates!') . " " . i18n('Could not handle server response!');
437:                 $this->sErrorOutput = $this->renderOutput($sErrorMessage);
438:             } else {
439:                 $oVersion = $this->oXML->xpath("/fourforbusiness/contenido/releases/" . $this->sMinorRelease);
440:                 if (!isset($oVersion[0])) {
441:                     $sErrorMessage = i18n('Unable to check for new updates!') . " " . i18n('Could not determine vendor version!');
442:                     $this->sErrorOutput = $this->renderOutput($sErrorMessage);
443:                 } else {
444:                     $this->sVendorVersion = $oVersion[0];
445:                 }
446:             }
447:         }
448:     }
449: 
450:     /**
451:      * Handles the update of files coming per vendor host
452:      */
453:     protected function handleVendorUpdate($aXMLContent) {
454:         $bValidXMLFile = true;
455:         $bValidDeRSSFile = true;
456:         $bValidEnRSSFile = true;
457: 
458:         $sCheckXML = stristr($aXMLContent[$this->sVendorXMLFile], "<fourforbusiness>");
459:         if ($sCheckXML == false) {
460:             $bValidXMLFile = false;
461:         }
462: 
463:         $sCheckDeRSS = stristr($aXMLContent[$this->sVendorRssDeFile], "<channel>");
464:         if ($sCheckDeRSS == false) {
465:             $bValidDeRSSFile = false;
466:         }
467: 
468:         $sCheckEnRSS = stristr($aXMLContent[$this->sVendorRssEnFile], "<channel>");
469:         if ($sCheckEnRSS == false) {
470:             $bValidEnRSSFile = false;
471:         }
472: 
473:         // To prevent simplexml and rss reader parser errors by loading an error
474:         // page from the vendor host
475:         // the content will be replaced with the cached file (if existing) or a
476:         // string
477:         if ($bValidXMLFile != true) {
478:             if (cFileHandler::exists($this->sCacheDirectory . $this->sVendorXMLFile)) {
479:                 $sXMLReplace = cFileHandler::read($this->sCacheDirectory . $this->sVendorXMLFile);
480:             } else {
481:                 $sXMLReplace = "<error>The vendor host file at " . $this->sVendorHost . " is not availiable!</error>";
482:             }
483:             $aXMLContent[$this->sVendorXMLFile] = $sXMLReplace;
484:         }
485: 
486:         if ($bValidDeRSSFile != true) {
487:             if (cFileHandler::exists($this->sCacheDirectory . $this->sVendorRssDeFile)) {
488:                 $sDeRSSReplace = cFileHandler::read($this->sCacheDirectory . $this->sVendorRssDeFile);
489:             } else {
490:                 $sDeRSSReplace = "<rss></rss>";
491:             }
492:             $aXMLContent[$this->sVendorRssDeFile] = $sDeRSSReplace;
493:         }
494: 
495:         if ($bValidEnRSSFile != true) {
496:             if (cFileHandler::exists($this->sCacheDirectory . $this->sVendorRssEnFile)) {
497:                 $sEnRSSReplace = cFileHandler::read($this->sCacheDirectory . $this->sVendorRssEnFile);
498:             } else {
499:                 $sEnRSSReplace = "<rss></rss>";
500:             }
501:             $aXMLContent[$this->sVendorRssEnFile] = $sEnRSSReplace;
502:         }
503: 
504:         $this->sXMLContent = $aXMLContent[$this->sVendorXMLFile];
505:         $this->sRSSContent = $aXMLContent[$this->sRSSFile];
506:         $this->updateCacheFiles($aXMLContent);
507:         $this->updateHashProperty($aXMLContent);
508: 
509:     }
510: 
511:     /**
512:      * Connects with vendor host and gets the xml files
513:      *
514:      * @return array
515:      */
516:     protected function getVendorHostFiles() {
517:         $aXMLContent = array();
518:         // get update file
519:         $sXMLUpdate = $this->fetchUrl($this->sVendorHostPath . $this->sVendorXMLFile);
520: 
521:         // get german rss file
522:         $sDeRSSContent = $this->fetchUrl($this->sVendorHostPath . $this->sVendorRssDeFile);
523: 
524:         // get english rss file
525:         $sEnRSSContent = $this->fetchUrl($this->sVendorHostPath . $this->sVendorRssEnFile);
526: 
527:         $aXMLContent[$this->sVendorXMLFile] = $sXMLUpdate;
528:         $aXMLContent[$this->sVendorRssDeFile] = $sDeRSSContent;
529:         $aXMLContent[$this->sVendorRssEnFile] = $sEnRSSContent;
530: 
531:         return $aXMLContent;
532:     }
533: 
534:     /**
535:      * Updates the files in cache
536:      *
537:      * @param $aRSSContent array
538:      */
539:     protected function updateCacheFiles($aRSSContent) {
540:         $aWriteCache = array();
541:         $aWriteCache[$this->sVendorXMLFile] = $this->sXMLContent;
542:         $aWriteCache[$this->sVendorRssDeFile] = $aRSSContent[$this->sVendorRssDeFile];
543:         $aWriteCache[$this->sVendorRssEnFile] = $aRSSContent[$this->sVendorRssEnFile];
544:         $aWriteCache[$this->sTimestampCacheFile] = time();
545: 
546:         if (is_writable($this->sCacheDirectory)) {
547:             foreach ($aWriteCache as $sFile => $sContent) {
548:                 $sCacheFile = $this->sCacheDirectory . $sFile;
549:                 cFileHandler::write($sCacheFile, $sContent, false);
550:             }
551:         }
552:     }
553: 
554:     /**
555:      * Gets the xml file hash from the property table
556:      *
557:      * @return string
558:      */
559:     protected function getHashProperty() {
560:         $sProperty = $this->oProperties->getValue($this->aPropConf['itemType'], $this->aPropConf['itemID'], $this->aPropConf['type'], $this->aPropConf['name']);
561:         return $sProperty;
562:     }
563: 
564:     /**
565:      * Updates the xml file hash in the property table
566:      *
567:      * @param $aRSSContent array
568:      */
569:     protected function updateHashProperty($aXMLContent) {
570:         $sXML = $aXMLContent[$this->sVendorXMLFile];
571:         $sDeRSS = $aXMLContent[$this->sVendorRssDeFile];
572:         $sEnRSS = $aXMLContent[$this->sVendorRssEnFile];
573: 
574:         $sPropValue = md5($sXML . $sDeRSS . $sEnRSS);
575:         $this->oProperties->setValue($this->aPropConf['itemType'], $this->aPropConf['itemID'], $this->aPropConf['type'], $this->aPropConf['name'], $sPropValue);
576:     }
577: 
578:     /**
579:      * Checks the patch level of system and vendor version
580:      *
581:      * @return string
582:      */
583:     protected function checkPatchLevel() {
584:         $sVersionCompare = version_compare($this->aCfg['version'], $this->sVendorVersion);
585:         return $sVersionCompare;
586:     }
587: 
588:     /**
589:      * Generates the download URL
590:      *
591:      * @return string
592:      */
593:     protected function getDownloadURL() {
594:         $sVendorURLVersion = str_replace(".", "_", $this->sVendorVersion);
595:         $sVendorURL = $this->sVendorURL . "/Contenido_" . $sVendorURLVersion;
596:         return $sVendorURL;
597:     }
598: 
599:     /**
600:      * Generates the output for the backend
601:      *
602:      * @param $sMessage string
603:      * @return string
604:      */
605:     protected function renderOutput($sMessage) {
606:         $oTpl = new cTemplate();
607:         $oTpl->set('s', 'UPDATE_MESSAGE', $sMessage);
608: 
609:         if ($this->bEnableCheck == true) {
610:             $oTpl->set('s', 'UPDATE_ACTIVATION', i18n('Disable update notification'));
611:             $oTpl->set('s', 'IMG_BUT_UPDATE', 'but_cancel.gif');
612:             $oTpl->set('s', 'LABEL_BUT_UPDATE', i18n('Disable notification'));
613:             $oTpl->set('s', 'URL_UPDATE', $this->oSession->url('main.php?frame=4&amp;area=mycontenido&amp;do=deactivate'));
614:         } else {
615:             $oTpl->set('s', 'UPDATE_ACTIVATION', i18n('Enable update notification (recommended)'));
616:             $oTpl->set('s', 'IMG_BUT_UPDATE', 'but_ok.gif');
617:             $oTpl->set('s', 'LABEL_BUT_UPDATE', i18n('Enable notification'));
618:             $oTpl->set('s', 'URL_UPDATE', $this->oSession->url('main.php?frame=4&amp;area=mycontenido&amp;do=activate'));
619:         }
620: 
621:         if ($this->bEnableCheckRss == true) {
622:             $oTpl->set('s', 'RSS_ACTIVATION', i18n('Disable RSS notification'));
623:             $oTpl->set('s', 'IMG_BUT_RSS', 'but_cancel.gif');
624:             $oTpl->set('s', 'LABEL_BUT_RSS', i18n('Disable notification'));
625:             $oTpl->set('s', 'URL_RSS', $this->oSession->url('main.php?frame=4&amp;area=mycontenido&amp;do=deactivate_rss'));
626: 
627:             $oTpl = $this->renderRss($oTpl);
628:         } else {
629:             $oTpl->set('s', 'RSS_ACTIVATION', i18n('Enable RSS notification (recommended)'));
630:             $oTpl->set('s', 'IMG_BUT_RSS', 'but_ok.gif');
631:             $oTpl->set('s', 'LABEL_BUT_RSS', i18n('Enable notification'));
632:             $oTpl->set('s', 'URL_RSS', $this->oSession->url('main.php?frame=4&amp;area=mycontenido&amp;do=activate_rss'));
633:             $oTpl->set('s', 'NEWS_NOCONTENT', i18n('RSS notification is disabled'));
634:             $oTpl->set("s", "DISPLAY_DISABLED", 'block');
635:         }
636: 
637:         return $oTpl->generate('templates/standard/' . $this->aCfg['templates']['welcome_update'], 1);
638:     }
639: 
640:     /**
641:      * Generates the output for the rss informations
642:      *
643:      * @param $oTpl
644:      * @return cTemplate CONTENIDO template object
645:      */
646:     protected function renderRss($oTpl) {
647:         if (!is_object($oTpl)) {
648:             $oTpl = new cTemplate();
649:         }
650: 
651:         if ($this->sRSSContent != '<rss></rss>') {
652:             $doc = new cXmlReader();
653:             $doc->load($this->sCacheDirectory . $this->sRSSFile);
654: 
655:             $maxFeedItems = 3;
656: 
657:             for ($iCnt = 0; $iCnt < $maxFeedItems; $iCnt++) {
658:                 $title = $doc->getXpathValue('*/channel/item/title', $iCnt);
659:                 $link = $doc->getXpathValue('*/channel/item/link', $iCnt);
660:                 $description = $doc->getXpathValue('*/channel/item/description', $iCnt);
661:                 $date = $doc->getXpathValue('*/channel/item/pubDate', $iCnt);
662: 
663:                 // hotfix do not call conHtmlentities because of different umlaut handling on PHP 5.3 and PHP 5.4
664:                 // perhaps it is a bug in conHtmlentities.
665:                 $title = utf8_encode($title);
666:                 $sText = utf8_encode($description);
667: 
668:                 if (strlen($sText) > 150) {
669:                     $sText = cApiStrTrimAfterWord($sText, 150) . '...';
670:                 }
671: 
672:                 $date = date(getEffectiveSetting("dateformat", "full", "Y-m-d H:i:s"), strtotime($date));
673: 
674:                 // highlight newest rss news
675:                 if ($iCnt == 0) {
676:                     $oTpl->set("d", "NEWS_NEWEST_CSS", "newest_news");
677:                 } else {
678:                     $oTpl->set("d", "NEWS_NEWEST_CSS", "");
679:                 }
680: 
681:                 $oTpl->set("d", "NEWS_DATE", $date);
682:                 $oTpl->set("d", "NEWS_TITLE", $title);
683:                 $oTpl->set("d", "NEWS_TEXT", $sText);
684:                 $oTpl->set("d", "NEWS_URL", $link);
685:                 $oTpl->set("d", "LABEL_MORE", i18n('read more'));
686:                 $oTpl->next();
687:             }
688: 
689:             if ($iCnt == 0) {
690:                 $oTpl->set("s", "NEWS_NOCONTENT", i18n("No RSS content available"));
691:                 $oTpl->set("s", "DISPLAY_DISABLED", 'block');
692:             } else {
693:                 $oTpl->set("s", "NEWS_NOCONTENT", "");
694:                 $oTpl->set("s", "DISPLAY_DISABLED", 'none');
695:             }
696:         } else if ($this->bNoWritePermissions == true) {
697:             $oTpl->set("s", "NEWS_NOCONTENT", i18n('Your webserver does not have write permissions for the directory /contenido/data/cache/!'));
698:         } else {
699:             $oTpl->set("s", "NEWS_NOCONTENT", i18n("No RSS content available"));
700:         }
701: 
702:         return $oTpl;
703:     }
704: 
705:     /**
706:      * fetches given url for vendorfiles
707:      *
708:      * @todo add a retry counter and a deathpoint with warning in errorlog
709:      * @param string $sUrl
710:      */
711:     private function fetchUrl($sUrl) {
712:         if ($this->bVendorHostReachable != true) {
713:             return false;
714:         }
715: 
716:         $oSocket = @fsockopen($this->sVendorHost, 80, $errno, $errstr, $this->iConnectTimeout);
717:         if (!is_resource($oSocket)) {
718:             $sErrorMessage = i18n('Unable to check for new updates!') . " " . i18n('Connection to contenido.org failed!');
719:             $this->sErrorOutput = $this->renderOutput($sErrorMessage);
720:             $this->bVendorHostReachable = false;
721:             return false;
722:         } else {
723:             // get file
724:             if (!fputs($oSocket, "GET /" . $sUrl . " HTTP/1.0\r\nHost: " . $this->sVendorHost . "\r\n\r\n")) {
725:                 return false;
726:             }
727: 
728:             $sVendorFile = '';
729: 
730:             while (!feof($oSocket)) {
731:                 $sVendorFile .= fgets($oSocket, 128);
732: 
733:             }
734: 
735:             $sSeparator = strpos($sVendorFile, "\r\n\r\n");
736:             $sVendorFile = substr($sVendorFile, $sSeparator + 4);
737: 
738: 
739:             fclose($oSocket);
740:         }
741: 
742:         return ($sVendorFile != "") ? $sVendorFile : false;
743:     }
744: 
745:     /**
746:      * Displays the rendered output
747:      *
748:      * @return string
749:      */
750:     public function displayOutput() {
751:         if (!$this->bEnableView) {
752:             $sOutput = "";
753:         } else if ($this->bNoWritePermissions == true) {
754:             $sMessage = i18n('Your webserver does not have write permissions for the directory /contenido/data/cache/!');
755:             $sOutput = $this->renderOutput($sMessage);
756:         } else if (!$this->bEnableCheck) {
757:             $sMessage = i18n('Update notification is disabled! For actual update information, please activate.');
758:             $sOutput = $this->renderOutput($sMessage);
759:         } else if ($this->sErrorOutput != "") {
760:             $sOutput = $this->sErrorOutput;
761:         } else if ($this->sVendorVersion == '') {
762:             $sMessage = i18n('You have an unknown or unsupported version of CONTENIDO!');
763:             $sOutput = $this->renderOutput($sMessage);
764:         } else if ($this->sVendorVersion == "deprecated") {
765:             $sMessage = sprintf(i18n("Your version of CONTENIDO is deprecated and not longer supported for any updates. Please update to a higher version! <br /> <a href='%s' class='blue' target='_blank'>Download now!</a>"), 'http://www.contenido.org');
766:             $sOutput = $this->renderOutput($sMessage);
767:         } else if ($this->checkPatchLevel() == "-1") {
768:             $sVendorDownloadURL = $this->getDownloadURL();
769:             $sMessage = sprintf(i18n("A new version of CONTENIDO is available! <br /> <a href='%s' class='blue' target='_blank'>Download %s now!</a>"), $sVendorDownloadURL, $this->sVendorVersion);
770:             $sOutput = $this->renderOutput($sMessage);
771:         } else if ($this->checkPatchLevel() == "1") {
772:             $sMessage = sprintf(i18n('It seems to be that your version string was manipulated. CONTENIDO %s does not exist!'), $this->aCfg['version']);
773:             $sOutput = $this->renderOutput($sMessage);
774:         } else {
775:             $sMessage = i18n('Your version of CONTENIDO is up to date!');
776:             $sOutput = $this->renderOutput($sMessage);
777:         }
778: 
779:         return $sOutput;
780:     }
781: 
782: }
783: 
CMS CONTENIDO 4.9.0 API documentation generated by ApiGen 2.8.0