00001 <?php
00002
00009 class oxRssFeed extends oxSuperCfg
00010 {
00014 const CACHE_TTL = 10800;
00015
00019 const RSS_TOPSHOP = 'RSS_TopShop';
00020 const RSS_NEWARTS = 'RSS_NewArts';
00021 const RSS_CATARTS = 'RSS_CatArts';
00022 const RSS_ARTRECOMMLISTS = 'RSS_ARTRECOMMLISTS';
00023 const RSS_RECOMMLISTARTS = 'RSS_RECOMMLISTARTS';
00024 const RSS_BARGAIN = 'RSS_Bargain';
00025
00032 protected $_aChannel = array();
00033
00040 public function getChannel()
00041 {
00042 return $this->_aChannel;
00043 }
00044
00051 protected function _loadBaseChannel()
00052 {
00053 $oShop = $this->getConfig()->getActiveShop();
00054 $this->_aChannel['title'] = $oShop->oxshops__oxname->value;
00055 $this->_aChannel['link'] = oxUtils::getInstance()->prepareUrlForNoSession($this->getConfig()->getShopHomeURL());
00056 $this->_aChannel['description'] = '';
00057 $aLangIds = oxLang::getInstance()->getLanguageIds();
00058 $this->_aChannel['language'] = $aLangIds[oxLang::getInstance()->getBaseLanguage()];
00059 $this->_aChannel['copyright'] = $oShop->oxshops__oxname->value;
00060 $this->_aChannel['selflink'] = '';
00061 if (oxUtils::getInstance()->isValidEmail( $oShop->oxshops__oxinfoemail->value )) {
00062 $this->_aChannel['managingEditor'] = $oShop->oxshops__oxinfoemail->value;
00063 }
00064
00065
00066 $this->_aChannel['generator'] = 'OXID eShop '.$oShop->oxshops__oxversion->value;
00067 $this->_aChannel['image']['url'] = $this->getConfig()->getImageUrl().'logo.png';
00068
00069
00070 $this->_aChannel['image']['title'] = $this->_aChannel['title'];
00071 $this->_aChannel['image']['link'] = $this->_aChannel['link'];
00072 }
00073
00082 protected function _getCacheId($name)
00083 {
00084 return $name.'_'.$this->getConfig()->getShopId().'_'.oxLang::getInstance()->getBaseLanguage().'_'.(int) oxConfig::getParameter('currency');
00085 }
00086
00095 protected function _loadFromCache($name)
00096 {
00097 if ($aRes = oxUtils::getInstance()->fromFileCache($this->_getCacheId($name))) {
00098 if ($aRes['timestamp'] > time() - self::CACHE_TTL) {
00099 return $aRes['content'];
00100 }
00101 }
00102 return false;
00103 }
00104
00105
00116 protected function _getLastBuildDate($name, $aData)
00117 {
00118 if ($aData2 = oxUtils::getInstance()->fromFileCache($this->_getCacheId($name))) {
00119 $sLastBuildDate = $aData2['content']['lastBuildDate'];
00120 $aData2['content']['lastBuildDate'] = '';
00121 $aData['lastBuildDate'] = '';
00122 if (!strcmp(serialize($aData), serialize($aData2['content']))) {
00123 return $sLastBuildDate;
00124 }
00125 }
00126 return date('D, d M Y H:i:s O');
00127 }
00128
00141 protected function _saveToCache($name, $aContent)
00142 {
00143 $aData = array( 'timestamp' => time(), 'content' => $aContent );
00144 return oxUtils::getInstance()->toFileCache($this->_getCacheId($name), $aData);
00145 }
00146
00147
00156 protected function _getArticleItems(oxArticleList $oList)
00157 {
00158 $aItems = array();
00159 foreach ($oList as $oArticle) {
00160 $oItem = new oxStdClass();
00161 $oActCur = $this->getConfig()->getActShopCurrencyObject();
00162 $sPrice = $oArticle->getPriceFromPrefix().oxLang::getInstance()->formatCurrency( $oArticle->getPrice()->getBruttoPrice(), $oActCur );
00163 $oItem->title = strip_tags($oArticle->oxarticles__oxtitle->value . " " . $sPrice . " ". $oActCur->sign);
00164 $oItem->guid = $oItem->link = oxUtils::getInstance()->prepareUrlForNoSession($oArticle->getLink());
00165 $oItem->isGuidPermalink = true;
00166 $oItem->description = $oArticle->getArticleLongDesc()->value;
00167 if (trim(str_replace(' ', '', (strip_tags($oItem->description)))) == '') {
00168 $oItem->description = $oArticle->oxarticles__oxshortdesc->value;
00169 }
00170 $oItem->description = htmlspecialchars(trim($oItem->description));
00171
00172 $aItems[] = $oItem;
00173 }
00174 return $aItems;
00175 }
00176
00187 protected function _prepareUrl($sUri, $sTitle)
00188 {
00189 $iLang = oxLang::getInstance()->getBaseLanguage();
00190 $sUrl = $this->_getShopUrl();
00191 $sUrl .= $sUri.'&lang='.$iLang;
00192
00193 if ( oxUtils::getInstance()->seoIsActive() ) {
00194 $oEncoder = oxSeoEncoder::getInstance();
00195 $sUrl = $oEncoder->getDynamicUrl( $sUrl, "rss/{$sTitle}/", $iLang );
00196 }
00197
00198 return oxUtils::getInstance()->prepareUrlForNoSession( $sUrl );
00199 }
00200
00210 protected function _prepareFeedName($sTitle)
00211 {
00212 $oShop = $this->getConfig()->getActiveShop();
00213
00214 return $oShop->oxshops__oxname->value . "/" . $sTitle;
00215 }
00216
00223 protected function _getShopUrl()
00224 {
00225 $sUrl = $this->getConfig()->getShopUrl();
00226 if (strpos($sUrl, '?')) {
00227 if (!preg_match('/[?&](amp;)?$/i', $sUrl)) {
00228 $sUrl .= '&';
00229 }
00230 } else {
00231 $sUrl .= '?';
00232 }
00233 return $sUrl;
00234 }
00235
00249 protected function _loadData($sTag, $sTitle, $sDesc, $aItems, $sRssUrl, $sTargetUrl = null)
00250 {
00251 $this->_loadBaseChannel();
00252
00253 $this->_aChannel['selflink'] = $sRssUrl;
00254
00255 if ($sTargetUrl) {
00256 $this->_aChannel['link'] = $this->_aChannel['image']['link'] = $sTargetUrl;
00257 }
00258
00259 $this->_aChannel['image']['title'] = $this->_aChannel['title'] = $sTitle;
00260 $this->_aChannel['image']['description'] = $this->_aChannel['description'] = $sDesc;
00261
00262 $this->_aChannel['items'] = $aItems;
00263
00264 if ($sTag) {
00265 $this->_aChannel['lastBuildDate'] = $this->_getLastBuildDate($sTag, $this->_aChannel);
00266 $this->_saveToCache($sTag, $this->_aChannel);
00267 } else {
00268 $this->_aChannel['lastBuildDate'] = date('D, d M Y H:i:s O');
00269 }
00270 }
00271
00279 public function getTopInShopTitle()
00280 {
00281 $oLang = oxLang::getInstance();
00282 $iLang = $oLang->getBaseLanguage();
00283 return $this->_prepareFeedName( $oLang->translateString( 'RSS_TOPSHOP_TITLE', $iLang ) );
00284 }
00285
00293 public function getTopInShopUrl()
00294 {
00295 return $this->_prepareUrl("cl=rss&fnc=topshop", $this->getTopInShopTitle());
00296 }
00297
00305 public function loadTopInShop()
00306 {
00307 if ( ( $this->_aChannel = $this->_loadFromCache( self::RSS_TOPSHOP ) ) ) {
00308 return;
00309 }
00310
00311 $oArtList = oxNew( 'oxarticlelist' );
00312 $oArtList->loadTop5Articles();
00313
00314 $oLang = oxLang::getInstance();
00315 $this->_loadData(
00316 self::RSS_TOPSHOP,
00317 $this->getTopInShopTitle(),
00318 $oLang->translateString( 'RSS_TOPSHOP_DESCRIPTION', $oLang->getBaseLanguage() ),
00319 $this->_getArticleItems($oArtList),
00320 $this->getTopInShopUrl()
00321 );
00322 }
00323
00324
00325
00333 public function getNewestArticlesTitle()
00334 {
00335 $oLang = oxLang::getInstance();
00336 $iLang = $oLang->getBaseLanguage();
00337 return $this->_prepareFeedName( $oLang->translateString( 'RSS_NEWESTARTICLES_TITLE', $iLang ) );
00338 }
00339
00347 public function getNewestArticlesUrl()
00348 {
00349 return $this->_prepareUrl("cl=rss&fnc=newarts", $this->getNewestArticlesTitle());
00350 }
00351
00359 public function loadNewestArticles()
00360 {
00361 if ( ( $this->_aChannel = $this->_loadFromCache(self::RSS_NEWARTS ) ) ) {
00362 return;
00363 }
00364 $oArtList = oxNew( 'oxarticlelist' );
00365 $oArtList->loadNewestArticles( $this->getConfig()->getConfigParam( 'iRssItemsCount' ) );
00366
00367 $oLang = oxLang::getInstance();
00368 $this->_loadData(
00369 self::RSS_NEWARTS,
00370 $this->getNewestArticlesTitle( ),
00371 $oLang->translateString( 'RSS_NEWESTARTICLES_DESCRIPTION', $oLang->getBaseLanguage() ),
00372 $this->_getArticleItems($oArtList),
00373 $this->getNewestArticlesUrl()
00374 );
00375 }
00376
00377
00387 public function getCategoryArticlesTitle(oxCategory $oCat)
00388 {
00389 $oLang = oxLang::getInstance();
00390 $iLang = $oLang->getBaseLanguage();
00391 $sTitle = $this->_getCatPath($oCat);
00392 return $this->_prepareFeedName( $sTitle . $oLang->translateString( 'RSS_CATEGORYARTICLES_TITLE', $iLang ) );
00393 }
00394
00402 protected function _getCatPath( $oCat )
00403 {
00404 $sCatPathString = '';
00405 $sSep = '';
00406 while ( $oCat ) {
00407
00408 $sCatPathString = $oCat->oxcategories__oxtitle->value.$sSep.$sCatPathString ;
00409 $sSep = '/';
00410
00411 $oCat = $oCat->getParentCategory();
00412 }
00413 return $sCatPathString;
00414 }
00415
00425 public function getCategoryArticlesUrl(oxCategory $oCat)
00426 {
00427 $oLang = oxLang::getInstance();
00428 return $this->_prepareUrl("cl=rss&fnc=catarts&cat=".urlencode($oCat->getId()),
00429 sprintf($oLang->translateString( 'RSS_CATEGORYARTICLES_URL', $oLang->getBaseLanguage() ), $oCat->oxcategories__oxtitle->value));
00430 }
00431
00441 public function loadCategoryArticles( oxCategory $oCat )
00442 {
00443 $sId = $oCat->getId();
00444 if ( ( $this->_aChannel = $this->_loadFromCache( self::RSS_CATARTS.$sId ) ) ) {
00445 return;
00446 }
00447
00448 $oArtList = oxNew( 'oxarticlelist' );
00449 $oArtList->setCustomSorting('oc.oxtime desc');
00450 $oArtList->loadCategoryArticles($oCat->getId(), null, $this->getConfig()->getConfigParam( 'iRssItemsCount' ));
00451
00452 $oLang = oxLang::getInstance();
00453 $this->_loadData(
00454 self::RSS_CATARTS.$sId,
00455 $this->getCategoryArticlesTitle($oCat),
00456 sprintf($oLang->translateString( 'RSS_CATEGORYARTICLES_DESCRIPTION', $oLang->getBaseLanguage() ), $oCat->oxcategories__oxtitle->value),
00457 $this->_getArticleItems($oArtList),
00458 $this->getCategoryArticlesUrl($oCat),
00459 $oCat->getLink()
00460 );
00461 }
00462
00463
00475 public function getSearchArticlesTitle($sSearch, $sCatId, $sVendorId)
00476 {
00477 return $this->_prepareFeedName( htmlspecialchars($this->_getSearchParamsTranslation('RSS_SEARCHARTICLES_TITLE', $sSearch, $sCatId, $sVendorId)) );
00478 }
00479
00491 protected function _getSearchParamsUrl($sSearch, $sCatId, $sVendorId)
00492 {
00493 $sParams = "searchparam=".urlencode($sSearch);
00494 if ($sCatId) {
00495 $sParams .= "&searchcnid=".urlencode($sCatId);
00496 }
00497
00498 if ($sVendorId) {
00499 $sParams .= "&searchvendor=".urlencode($sVendorId);
00500 }
00501
00502 return $sParams;
00503 }
00504
00515 protected function _getObjectField($sId, $sObject, $sField)
00516 {
00517 if (!$sId) {
00518 return '';
00519 }
00520 $oObj = oxNew($sObject);
00521 if ($oObj->load($sId)) {
00522 return $oObj->$sField->value;
00523 }
00524 return '';
00525 }
00526
00539 protected function _getSearchParamsTranslation($sId, $sSearch, $sCatId, $sVendorId)
00540 {
00541 $oLang = oxLang::getInstance();
00542 $sCatTitle = '';
00543 if ($sTitle = $this->_getObjectField($sCatId, 'oxcategory', 'oxcategories__oxtitle')) {
00544 $sCatTitle = sprintf($oLang->translateString( 'RSS_SEARCHARTICLES_TAG_CATEGORY', $oLang->getBaseLanguage() ), $sTitle);
00545 }
00546 $sVendorTitle = '';
00547 if ($sTitle = $this->_getObjectField($sVendorId, 'oxvendor', 'oxvendor__oxtitle')) {
00548 $sVendorTitle = sprintf($oLang->translateString( 'RSS_SEARCHARTICLES_TAG_VENDOR', $oLang->getBaseLanguage() ), $sTitle);
00549 }
00550
00551 $sRet = sprintf($oLang->translateString( $sId, $oLang->getBaseLanguage() ), $sSearch);
00552
00553 $sRet = str_replace('<TAG_CATEGORY>', $sCatTitle, $sRet);
00554 $sRet = str_replace('<TAG_VENDOR>', $sVendorTitle, $sRet);
00555
00556 return $sRet;
00557 }
00558
00570 public function getSearchArticlesUrl( $sSearch, $sCatId, $sVendorId )
00571 {
00572 $oLang = oxLang::getInstance();
00573 $sUrl = $this->_prepareUrl("cl=rss&fnc=searcharts", $oLang->translateString( 'RSS_SEARCHARTICLES_URL', $oLang->getBaseLanguage()));
00574
00575 $sJoin = '?';
00576 if (strpos($sUrl, '?')) {
00577 $sJoin = '&';
00578 }
00579 return $sUrl.$sJoin.$this->_getSearchParamsUrl($sSearch, $sCatId, $sVendorId);
00580 }
00581
00593 public function loadSearchArticles( $sSearch, $sCatId, $sVendorId )
00594 {
00595
00596
00597
00598
00599
00600 $oConfig = $this->getConfig();
00601 $oConfig->setConfigParam('iNrofCatArticles', $oConfig->getConfigParam( 'iRssItemsCount' ));
00602
00603 $oArtList = oxNew( 'oxsearch' )->getSearchArticles($sSearch, $sCatId, $sVendorId, oxNew('oxarticle')->getViewName().'.oxtimestamp desc');
00604
00605 $this->_loadData(
00606
00607 null,
00608
00609 $this->getSearchArticlesTitle($sSearch, $sCatId, $sVendorId),
00610 $this->_getSearchParamsTranslation('RSS_SEARCHARTICLES_DESCRIPTION', htmlspecialchars($sSearch), $sCatId, $sVendorId),
00611 $this->_getArticleItems($oArtList),
00612 $this->getSearchArticlesUrl($sSearch, $sCatId, $sVendorId),
00613 $this->_getShopUrl()."cl=search&".$this->_getSearchParamsUrl($sSearch, $sCatId, $sVendorId)
00614 );
00615 }
00616
00624 public function getRecommListsTitle(oxArticle $oArticle)
00625 {
00626 $oLang = oxLang::getInstance();
00627 $iLang = $oLang->getBaseLanguage();
00628 return $this->_prepareFeedName( sprintf($oLang->translateString( 'RSS_ARTRECOMMLISTS_TITLE', $iLang ), $oArticle->oxarticles__oxtitle->value) );
00629 }
00630
00638 public function getRecommListsUrl(oxArticle $oArticle)
00639 {
00640 $oLang = oxLang::getInstance();
00641 $iLang = $oLang->getBaseLanguage();
00642 return $this->_prepareUrl("cl=rss&fnc=recommlists&anid=".$oArticle->getId(),
00643 sprintf($oLang->translateString( 'RSS_ARTRECOMMLISTS_URL', $iLang ), $oArticle->oxarticles__oxtitle->value));
00644 }
00645
00653 protected function _getRecommListItems($oList)
00654 {
00655 $aItems = array();
00656 foreach ($oList as $oRecommList) {
00657 $oItem = new oxStdClass();
00658 $oItem->title = $oRecommList->oxrecommlists__oxtitle->value;
00659 $oItem->guid = $oItem->link = oxUtils::getInstance()->prepareUrlForNoSession($oRecommList->getLink());
00660 $oItem->isGuidPermalink = true;
00661 $oItem->description = $oRecommList->oxrecommlists__oxdesc->value;
00662
00663 $aItems[] = $oItem;
00664 }
00665 return $aItems;
00666 }
00667
00675 public function loadRecommLists(oxArticle $oArticle)
00676 {
00677 if ( ( $this->_aChannel = $this->_loadFromCache( self::RSS_ARTRECOMMLISTS.$oArticle->getId() ) ) ) {
00678 return;
00679 }
00680
00681 $oConfig = $this->getConfig();
00682 $oConfig->setConfigParam('iNrofCrossellArticles', $oConfig->getConfigParam( 'iRssItemsCount' ));
00683
00684 $oList = oxNew( 'oxrecommlist' )->getRecommListsByIds(array($oArticle->getId()));
00685 if ($oList == null) {
00686 $oList = oxNew('oxlist');
00687 }
00688
00689 $oLang = oxLang::getInstance();
00690 $this->_loadData(
00691 self::RSS_ARTRECOMMLISTS.$oArticle->getId(),
00692 $this->getRecommListsTitle($oArticle),
00693 sprintf($oLang->translateString( 'RSS_ARTRECOMMLISTS_DESCRIPTION', $oLang->getBaseLanguage() ), $oArticle->oxarticles__oxtitle->value),
00694 $this->_getRecommListItems($oList),
00695 $this->getRecommListsUrl($oArticle),
00696 $oArticle->getLink()
00697 );
00698 }
00699
00707 public function getRecommListArticlesTitle(oxRecommList $oRecommList)
00708 {
00709 $oLang = oxLang::getInstance();
00710 $iLang = $oLang->getBaseLanguage();
00711 return $this->_prepareFeedName( sprintf($oLang->translateString( 'RSS_RECOMMLISTARTICLES_TITLE', $iLang ), $oRecommList->oxrecommlists__oxtitle->value) );
00712 }
00713
00721 public function getRecommListArticlesUrl(oxRecommList $oRecommList)
00722 {
00723 $oLang = oxLang::getInstance();
00724 $iLang = $oLang->getBaseLanguage();
00725 return $this->_prepareUrl("cl=rss&fnc=recommlistarts&recommid=".$oRecommList->getId(),
00726 sprintf($oLang->translateString( 'RSS_RECOMMLISTARTICLES_URL', $iLang ), $oRecommList->oxrecommlists__oxtitle->value));
00727 }
00728
00736 public function loadRecommListArticles(oxRecommList $oRecommList)
00737 {
00738 if ( ( $this->_aChannel = $this->_loadFromCache( self::RSS_RECOMMLISTARTS.$oRecommList->getId() ) ) ) {
00739 return;
00740 }
00741
00742 $oList = oxNew( 'oxarticlelist' );
00743 $oList->loadRecommArticles( $oRecommList->getId(), ' order by oxobject2list.oxtimestamp desc limit '. $this->getConfig()->getConfigParam( 'iRssItemsCount' ) );
00744
00745 $oLang = oxLang::getInstance();
00746 $this->_loadData(
00747 self::RSS_RECOMMLISTARTS.$oRecommList->getId(),
00748 $this->getRecommListArticlesTitle($oRecommList),
00749 sprintf($oLang->translateString( 'RSS_RECOMMLISTARTICLES_DESCRIPTION', $oLang->getBaseLanguage() ), $oRecommList->oxrecommlists__oxtitle->value),
00750 $this->_getArticleItems($oList),
00751 $this->getRecommListArticlesUrl($oRecommList),
00752 $oRecommList->getLink()
00753 );
00754 }
00755
00763 public function getBargainTitle()
00764 {
00765 $oLang = oxLang::getInstance();
00766 $iLang = $oLang->getBaseLanguage();
00767 return $this->_prepareFeedName( $oLang->translateString( 'RSS_BARGAIN_TITLE', $iLang ) );
00768 }
00769
00777 public function getBargainUrl()
00778 {
00779 return $this->_prepareUrl("cl=rss&fnc=bargain", $this->getBargainTitle());
00780 }
00781
00789 public function loadBargain()
00790 {
00791 if ( ( $this->_aChannel = $this->_loadFromCache( self::RSS_BARGAIN ) ) ) {
00792 return;
00793 }
00794
00795 $oArtList = oxNew( 'oxarticlelist' );
00796 $oArtList->loadAktionArticles( 'OXBARGAIN' );
00797
00798 $oLang = oxLang::getInstance();
00799 $this->_loadData(
00800 self::RSS_BARGAIN,
00801 $this->getBargainTitle(),
00802 $oLang->translateString( 'RSS_BARGAIN_DESCRIPTION', $oLang->getBaseLanguage() ),
00803 $this->_getArticleItems($oArtList),
00804 $this->getBargainUrl()
00805 );
00806 }
00807
00808 }
00809