Overview

Packages

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