oxarticlelist.php

Go to the documentation of this file.
00001 <?php
00002 
00008 class oxArticleList extends oxList
00009 {
00013     protected $_sCustomSorting;
00014 
00020     protected $_sObjectsInListName = 'oxarticle';
00021 
00027     protected $_blLoadSelectLists = false;
00028 
00036     public function setCustomSorting( $sSorting )
00037     {
00038         $this->_sCustomSorting = $sSorting;
00039     }
00040 
00046     public function enableSelectLists()
00047     {
00048         $this->_blLoadSelectLists = true;
00049     }
00050 
00059     public function selectString( $sSelect )
00060     {
00061         startProfile("loadinglists");
00062         $oRes = parent::selectString( $sSelect );
00063         stopProfile("loadinglists");
00064 
00065         return $oRes;
00066     }
00067 
00073     public function getHistoryArticles()
00074     {
00075         if ($aArticlesIds = $this->getSession()->getVar('aHistoryArticles')) {
00076             return $aArticlesIds;
00077         } elseif ( $sArticlesIds = oxRegistry::get("oxUtilsServer")->getOxCookie('aHistoryArticles')) {
00078             return explode('|', $sArticlesIds);
00079         }
00080     }
00081 
00089     public function setHistoryArticles($aArticlesIds)
00090     {
00091         if ($this->getSession()->getId()) {
00092             oxSession::setVar('aHistoryArticles', $aArticlesIds);
00093             // clean cookie, if session started
00094             oxRegistry::get("oxUtilsServer")->setOxCookie('aHistoryArticles', '');
00095         } else {
00096             oxRegistry::get("oxUtilsServer")->setOxCookie('aHistoryArticles', implode('|', $aArticlesIds));
00097         }
00098     }
00099 
00109     public function loadHistoryArticles( $sArtId, $iCnt = 4 )
00110     {
00111         $aHistoryArticles = $this->getHistoryArticles();
00112         $aHistoryArticles[] = $sArtId;
00113 
00114         // removing dublicates
00115         $aHistoryArticles = array_unique( $aHistoryArticles );
00116         if ( count( $aHistoryArticles ) > ( $iCnt + 1 ) ) {
00117             array_shift( $aHistoryArticles );
00118         }
00119 
00120         $this->setHistoryArticles( $aHistoryArticles );
00121 
00122         //remove current article and return array
00123         //asignment =, not ==
00124         if ( ( $iCurrentArt = array_search( $sArtId, $aHistoryArticles ) ) !== false ) {
00125             unset( $aHistoryArticles[$iCurrentArt] );
00126         }
00127 
00128         $aHistoryArticles = array_values( $aHistoryArticles );
00129         $this->loadIds( $aHistoryArticles );
00130         $this->sortByIds( $aHistoryArticles );
00131     }
00132 
00140     protected function sortByIds($aIds)
00141     {
00142         $this->_aOrderMap = array_flip($aIds);
00143         uksort($this->_aArray, array($this, '_sortByOrderMapCallback'));
00144     }
00145 
00156     protected function _sortByOrderMapCallback($key1, $key2)
00157     {
00158         if (isset($this->_aOrderMap[$key1])) {
00159             if (isset($this->_aOrderMap[$key2])) {
00160                 $iDiff = $this->_aOrderMap[$key2] - $this->_aOrderMap[$key1];
00161                 if ($iDiff > 0) {
00162                     return -1;
00163                 } elseif ($iDiff < 0) {
00164                     return 1;
00165                 } else {
00166                     return 0;
00167                 }
00168             } else {
00169                 // first is here, but 2nd is not - 1st gets more priority
00170                 return -1;
00171             }
00172         } elseif (isset($this->_aOrderMap[$key2])) {
00173             // first is not here, but 2nd is - 2nd gets more priority
00174             return 1;
00175         } else {
00176             // both unset, equal
00177             return 0;
00178         }
00179     }
00180 
00188     public function loadNewestArticles( $iLimit = null )
00189     {
00190         //has module?
00191         $myConfig = $this->getConfig();
00192 
00193         if ( !$myConfig->getConfigParam( 'bl_perfLoadPriceForAddList' ) ) {
00194             $this->getBaseObject()->disablePriceLoad();
00195         }
00196 
00197         $this->_aArray = array();
00198         switch( $myConfig->getConfigParam( 'iNewestArticlesMode' ) ) {
00199             case 0:
00200                 // switched off, do nothing
00201                 break;
00202             case 1:
00203                 // manually entered
00204                 $this->loadActionArticles( 'oxnewest', $iLimit );
00205                 break;
00206             case 2:
00207                 $sArticleTable = getViewName('oxarticles');
00208                 if ( $myConfig->getConfigParam( 'blNewArtByInsert' ) ) {
00209                     $sType = 'oxinsert';
00210                 } else {
00211                     $sType = 'oxtimestamp';
00212                 }
00213                 $sSelect  = "select * from $sArticleTable ";
00214                 $sSelect .= "where oxparentid = '' and ".$this->getBaseObject()->getSqlActiveSnippet()." and oxissearch = 1 order by $sType desc ";
00215                 if (!($iLimit = (int) $iLimit)) {
00216                     $iLimit = $myConfig->getConfigParam( 'iNrofNewcomerArticles' );
00217                 }
00218                 $sSelect .= "limit " . $iLimit;
00219 
00220                 $this->selectString($sSelect);
00221                 break;
00222         }
00223 
00224     }
00225 
00233     public function loadTop5Articles( $iLimit = null )
00234     {
00235         //has module?
00236         $myConfig = $this->getConfig();
00237 
00238         if ( !$myConfig->getConfigParam( 'bl_perfLoadPriceForAddList' ) ) {
00239             $this->getBaseObject()->disablePriceLoad();
00240         }
00241 
00242         switch( $myConfig->getConfigParam( 'iTop5Mode' ) ) {
00243             case 0:
00244                 // switched off, do nothing
00245                 break;
00246             case 1:
00247                 // manually entered
00248                 $this->loadActionArticles( 'oxtop5', $iLimit );
00249                 break;
00250             case 2:
00251                 $sArticleTable = getViewName('oxarticles');
00252 
00253                 //by default limit 5
00254                 $sLimit = ( $iLimit > 0 ) ? "limit " . $iLimit : 'limit 5';
00255 
00256                 $sSelect  = "select * from $sArticleTable ";
00257                 $sSelect .= "where ".$this->getBaseObject()->getSqlActiveSnippet()." and $sArticleTable.oxissearch = 1 ";
00258                 $sSelect .= "and $sArticleTable.oxparentid = '' and $sArticleTable.oxsoldamount>0 ";
00259                 $sSelect .= "order by $sArticleTable.oxsoldamount desc $sLimit";
00260 
00261                 $this->selectString($sSelect);
00262                 break;
00263         }
00264     }
00265 
00274     public function loadActionArticles( $sActionID, $iLimit = null )
00275     {
00276         // Performance
00277         if ( !trim( $sActionID) ) {
00278             return;
00279         }
00280 
00281         $sShopID        = $this->getConfig()->getShopId();
00282         $sActionID      = oxDb::getDb()->quote(strtolower( $sActionID));
00283 
00284         //echo $sSelect;
00285         $oBaseObject    = $this->getBaseObject();
00286         $sArticleTable  = $oBaseObject->getViewName();
00287         $sArticleFields = $oBaseObject->getSelectFields();
00288 
00289         $oBase = oxNew("oxactions");
00290         $sActiveSql = $oBase->getSqlActiveSnippet();
00291         $sViewName = $oBase->getViewName();
00292 
00293         $sLimit = ( $iLimit > 0 ) ? "limit " . $iLimit : '';
00294 
00295         $sSelect = "select $sArticleFields from oxactions2article
00296                               left join $sArticleTable on $sArticleTable.oxid = oxactions2article.oxartid
00297                               left join $sViewName on $sViewName.oxid = oxactions2article.oxactionid
00298                               where oxactions2article.oxshopid = '$sShopID' and oxactions2article.oxactionid = $sActionID and $sActiveSql
00299                               and $sArticleTable.oxid is not null and " .$oBaseObject->getSqlActiveSnippet(). "
00300                               order by oxactions2article.oxsort $sLimit";
00301 
00302         $this->selectString( $sSelect );
00303     }
00304 
00305 
00316     public function loadAktionArticles( $sActionID, $iLimit = null )
00317     {
00318         $this->loadActionArticles( $sActionID, $iLimit = null );
00319 
00320     }
00321 
00329     public function loadArticleCrossSell( $sArticleId )
00330     {
00331         $myConfig = $this->getConfig();
00332 
00333         // Performance
00334         if ( !$myConfig->getConfigParam( 'bl_perfLoadCrossselling' ) ) {
00335             return null;
00336         }
00337 
00338         $oBaseObject   = $this->getBaseObject();
00339         $sArticleTable = $oBaseObject->getViewName();
00340 
00341         $sArticleId = oxDb::getDb()->quote($sArticleId);
00342 
00343         $sSelect  = "select $sArticleTable.* from oxobject2article left join $sArticleTable on oxobject2article.oxobjectid=$sArticleTable.oxid ";
00344         $sSelect .= "where oxobject2article.oxarticlenid = $sArticleId ";
00345         $sSelect .= " and $sArticleTable.oxid is not null and " .$oBaseObject->getSqlActiveSnippet(). " order by rand()";
00346 
00347         // #525 bidirectional crossselling
00348         if ( $myConfig->getConfigParam( 'blBidirectCross' ) ) {
00349             $sSelect = "SELECT $sArticleTable.* FROM $sArticleTable
00350                 LEFT JOIN oxobject2article AS O2A1 on
00351                     ( O2A1.oxobjectid = $sArticleTable.oxid AND O2A1.oxarticlenid = $sArticleId )
00352                 LEFT JOIN oxobject2article AS O2A2 ON
00353                     ( O2A2.oxarticlenid = $sArticleTable.oxid AND O2A2.oxobjectid = $sArticleId )
00354                 WHERE 1
00355                     AND ( O2A2.oxarticlenid IS NOT NULL OR O2A1.oxobjectid IS NOT NULL )
00356                     AND " . $oBaseObject->getSqlActiveSnippet() . "
00357                     AND ($sArticleTable.oxid != $sArticleId) order by rand()";
00358         }
00359 
00360         $this->setSqlLimit( 0, $myConfig->getConfigParam( 'iNrofCrossellArticles' ));
00361         $this->selectString( $sSelect );
00362     }
00363 
00371     public function loadArticleAccessoires( $sArticleId )
00372     {
00373         $myConfig = $this->getConfig();
00374 
00375         // Performance
00376         if ( !$myConfig->getConfigParam( 'bl_perfLoadAccessoires' ) ) {
00377             return;
00378         }
00379 
00380         $sArticleId = oxDb::getDb()->quote($sArticleId);
00381 
00382         $oBaseObject   = $this->getBaseObject();
00383         $sArticleTable = $oBaseObject->getViewName();
00384 
00385         $sSelect  = "select $sArticleTable.* from oxaccessoire2article left join $sArticleTable on oxaccessoire2article.oxobjectid=$sArticleTable.oxid ";
00386         $sSelect .= "where oxaccessoire2article.oxarticlenid = $sArticleId ";
00387         $sSelect .= " and $sArticleTable.oxid is not null and " .$oBaseObject->getSqlActiveSnippet();
00388         //sorting articles
00389         $sSelect .= " order by oxaccessoire2article.oxsort";
00390 
00391         $this->selectString( $sSelect );
00392     }
00393 
00402     public function loadCategoryIds( $sCatId, $aSessionFilter )
00403     {
00404         $sArticleTable = $this->getBaseObject()->getViewName();
00405         $sSelect = $this->_getCategorySelect( $sArticleTable.'.oxid as oxid', $sCatId, $aSessionFilter );
00406 
00407         $this->_createIdListFromSql( $sSelect );
00408     }
00409 
00419     public function loadCategoryArticles( $sCatId, $aSessionFilter, $iLimit = null )
00420     {
00421         $sArticleFields = $this->getBaseObject()->getSelectFields();
00422 
00423         $sSelect = $this->_getCategorySelect( $sArticleFields, $sCatId, $aSessionFilter );
00424 
00425         // calc count - we can not use count($this) here as we might have paging enabled
00426         // #1970C - if any filters are used, we can not use cached category article count
00427         $iArticleCount = null;
00428         if ( $aSessionFilter) {
00429             $iArticleCount = oxDb::getDb()->getOne( $this->_getCategoryCountSelect( $sCatId, $aSessionFilter ) );
00430         }
00431 
00432         if ($iLimit = (int) $iLimit) {
00433             $sSelect .= " LIMIT $iLimit";
00434         }
00435 
00436         $this->selectString( $sSelect );
00437 
00438         if ( $iArticleCount !== null ) {
00439             return $iArticleCount;
00440         }
00441 
00442         // this select is FAST so no need to hazzle here with getNrOfArticles()
00443         return oxRegistry::get("oxUtilsCount")->getCatArticleCount( $sCatId );
00444     }
00445 
00454     public function loadRecommArticles( $sRecommId, $sArticlesFilter = null )
00455     {
00456         $sSelect = $this->_getArticleSelect( $sRecommId, $sArticlesFilter);
00457         $this->selectString( $sSelect );
00458     }
00459 
00468     public function loadRecommArticleIds( $sRecommId, $sArticlesFilter )
00469     {
00470         $sSelect = $this->_getArticleSelect( $sRecommId, $sArticlesFilter );
00471 
00472         $sArtView = getViewName( 'oxarticles' );
00473         $sPartial = substr( $sSelect, strpos( $sSelect, ' from ' ) );
00474         $sSelect  = "select distinct $sArtView.oxid $sPartial ";
00475 
00476         $this->_createIdListFromSql( $sSelect );
00477     }
00478 
00487     protected function _getArticleSelect( $sRecommId, $sArticlesFilter = null )
00488     {
00489         $sRecommId = oxDb::getDb()->quote($sRecommId);
00490 
00491         $sArtView = getViewName( 'oxarticles' );
00492         $sSelect  = "select distinct $sArtView.*, oxobject2list.oxdesc from oxobject2list ";
00493         $sSelect .= "left join $sArtView on oxobject2list.oxobjectid = $sArtView.oxid ";
00494         $sSelect .= "where (oxobject2list.oxlistid = $sRecommId) ".$sArticlesFilter;
00495 
00496         return $sSelect;
00497     }
00498 
00509     public function loadSearchIds( $sSearchStr = '', $sSearchCat = '', $sSearchVendor = '', $sSearchManufacturer = '' )
00510     {
00511         $oDb = oxDb::getDb();
00512         $sSearchCat    = $sSearchCat?$sSearchCat:null;
00513         $sSearchVendor = $sSearchVendor?$sSearchVendor:null;
00514         $sSearchManufacturer = $sSearchManufacturer?$sSearchManufacturer:null;
00515 
00516         $sWhere = null;
00517 
00518         if ( $sSearchStr ) {
00519             $sWhere = $this->_getSearchSelect( $sSearchStr );
00520         }
00521 
00522         $sArticleTable = getViewName('oxarticles');
00523 
00524         // longdesc field now is kept on different table
00525         $sDescTable = '';
00526         $sDescJoin  = '';
00527         if ( is_array( $aSearchCols = $this->getConfig()->getConfigParam( 'aSearchCols' ) ) ) {
00528             if ( in_array( 'oxlongdesc', $aSearchCols ) || in_array( 'oxtags', $aSearchCols ) ) {
00529                 $sDescView  = getViewName( 'oxartextends' );
00530                 $sDescJoin  = " LEFT JOIN $sDescView ON {$sDescView}.oxid={$sArticleTable}.oxid ";
00531             }
00532         }
00533 
00534         // load the articles
00535         $sSelect  =  "select $sArticleTable.oxid from $sArticleTable $sDescJoin where ";
00536 
00537         // must be additional conditions in select if searching in category
00538         if ( $sSearchCat ) {
00539             $sO2CView = getViewName('oxobject2category');
00540             $sSelect  = "select $sArticleTable.oxid from $sO2CView as oxobject2category, $sArticleTable $sDescJoin ";
00541             $sSelect .= "where oxobject2category.oxcatnid=".$oDb->quote( $sSearchCat )." and oxobject2category.oxobjectid=$sArticleTable.oxid and ";
00542         }
00543         $sSelect .= $this->getBaseObject()->getSqlActiveSnippet();
00544         $sSelect .= " and $sArticleTable.oxparentid = '' and $sArticleTable.oxissearch = 1 ";
00545 
00546         // #671
00547         if ( $sSearchVendor ) {
00548             $sSelect .= " and $sArticleTable.oxvendorid = ".$oDb->quote( $sSearchVendor )." ";
00549         }
00550 
00551         if ( $sSearchManufacturer ) {
00552             $sSelect .= " and $sArticleTable.oxmanufacturerid = ".$oDb->quote( $sSearchManufacturer )." ";
00553         }
00554         $sSelect .= $sWhere;
00555 
00556         if ($this->_sCustomSorting) {
00557             $sSelect .= " order by {$this->_sCustomSorting} ";
00558         }
00559 
00560         $this->_createIdListFromSql($sSelect);
00561     }
00562 
00571     public function loadPriceIds( $dPriceFrom, $dPriceTo )
00572     {
00573         $sSelect = $this->_getPriceSelect( $dPriceFrom, $dPriceTo );
00574         $this->_createIdListFromSql( $sSelect );
00575     }
00576 
00587     public function loadPriceArticles( $dPriceFrom, $dPriceTo, $oCategory = null)
00588     {
00589         $sSelect =  $this->_getPriceSelect( $dPriceFrom, $dPriceTo );
00590 
00591         startProfile("loadPriceArticles");
00592         $this->selectString( $sSelect);
00593         stopProfile("loadPriceArticles");
00594 
00595         if ( !$oCategory ) {
00596             return $this->count();
00597         }
00598 
00599         return oxRegistry::get("oxUtilsCount")->getPriceCatArticleCount( $oCategory->getId(), $dPriceFrom, $dPriceTo );
00600     }
00601 
00609     public function loadVendorIDs( $sVendorId)
00610     {
00611         $sSelect = $this->_getVendorSelect($sVendorId);
00612         $this->_createIdListFromSql($sSelect);
00613     }
00614 
00622     public function loadManufacturerIDs( $sManufacturerId)
00623     {
00624         $sSelect = $this->_getManufacturerSelect($sManufacturerId);
00625         $this->_createIdListFromSql($sSelect);
00626     }
00627 
00637     public function loadVendorArticles( $sVendorId, $oVendor = null )
00638     {
00639         $sSelect = $this->_getVendorSelect($sVendorId);
00640         $this->selectString( $sSelect);
00641 
00642         return oxRegistry::get("oxUtilsCount")->getVendorArticleCount( $sVendorId );
00643     }
00644 
00654     public function loadManufacturerArticles( $sManufacturerId, $oManufacturer = null )
00655     {
00656         $sSelect = $this->_getManufacturerSelect($sManufacturerId);
00657         $this->selectString( $sSelect);
00658 
00659         return oxRegistry::get("oxUtilsCount")->getManufacturerArticleCount( $sManufacturerId );
00660     }
00661 
00670     public function loadTagArticles( $sTag, $iLang )
00671     {
00672         $oListObject = $this->getBaseObject();
00673         $sArticleTable = $oListObject->getViewName();
00674         $sArticleFields = $oListObject->getSelectFields();
00675         $sViewName = getViewName( 'oxartextends', $iLang );
00676 
00677         $oTag = oxNew( 'oxtag', $sTag );
00678         $oTag->addUnderscores();
00679         $sTag = $oTag->get();
00680 
00681         $sQ = "select {$sArticleFields} from {$sViewName} inner join {$sArticleTable} on ".
00682               "{$sArticleTable}.oxid = {$sViewName}.oxid where {$sArticleTable}.oxparentid = '' AND match ( {$sViewName}.oxtags ) ".
00683               "against( ".oxDb::getDb()->quote( "\"".$sTag."\"" )." IN BOOLEAN MODE )";
00684 
00685         // checking stock etc
00686         if ( ( $sActiveSnippet = $oListObject->getSqlActiveSnippet() ) ) {
00687             $sQ .= " and {$sActiveSnippet}";
00688         }
00689 
00690         if ( $this->_sCustomSorting ) {
00691             $sSort = $this->_sCustomSorting;
00692             if (strpos($sSort, '.') === false) {
00693                 $sSort = $sArticleTable.'.'.$sSort;
00694             }
00695             $sQ .= " order by $sSort ";
00696         }
00697 
00698         $this->selectString( $sQ );
00699 
00700         // calc count - we can not use count($this) here as we might have paging enabled
00701         return oxRegistry::get("oxUtilsCount")->getTagArticleCount( $sTag, $iLang );
00702     }
00703 
00712     public function getTagArticleIds( $sTag, $iLang )
00713     {
00714         $oListObject = $this->getBaseObject();
00715         $sArticleTable = $oListObject->getViewName();
00716         $sViewName = getViewName( 'oxartextends', $iLang );
00717 
00718         $oTag = oxNew( 'oxtag', $sTag );
00719         $oTag->addUnderscores();
00720         $sTag = $oTag->get();
00721 
00722         $sQ = "select {$sViewName}.oxid from {$sViewName} inner join {$sArticleTable} on ".
00723             "{$sArticleTable}.oxid = {$sViewName}.oxid where {$sArticleTable}.oxparentid = '' and {$sArticleTable}.oxissearch = 1 and ".
00724             "match ( {$sViewName}.oxtags ) ".
00725             "against( ".oxDb::getDb()->quote( "\"".$sTag."\"" )." IN BOOLEAN MODE )";
00726 
00727         // checking stock etc
00728         if ( ( $sActiveSnippet = $oListObject->getSqlActiveSnippet() ) ) {
00729             $sQ .= " and {$sActiveSnippet}";
00730         }
00731 
00732         if ( $this->_sCustomSorting ) {
00733             $sSort = $this->_sCustomSorting;
00734             if (strpos($sSort, '.') === false) {
00735                 $sSort = $sArticleTable.'.'.$sSort;
00736             }
00737             $sQ .= " order by $sSort ";
00738         }
00739 
00740         return $this->_createIdListFromSql( $sQ );
00741     }
00742 
00750     public function loadIds($aIds)
00751     {
00752         if (!count($aIds)) {
00753             $this->clear();
00754             return;
00755         }
00756 
00757         foreach ($aIds as $iKey => $sVal) {
00758             $aIds[$iKey] = oxDb::getInstance()->escapeString($sVal);
00759         }
00760 
00761         $oBaseObject    = $this->getBaseObject();
00762         $sArticleTable  = $oBaseObject->getViewName();
00763         $sArticleFields = $oBaseObject->getSelectFields();
00764 
00765         $sSelect  = "select $sArticleFields from $sArticleTable ";
00766         $sSelect .= "where $sArticleTable.oxid in ( '".implode("','", $aIds)."' ) and ";
00767         $sSelect .= $oBaseObject->getSqlActiveSnippet();
00768 
00769         $this->selectString($sSelect);
00770     }
00771 
00779     public function loadOrderArticles($aOrders)
00780     {
00781         if (!count($aOrders)) {
00782             $this->clear();
00783             return;
00784         }
00785 
00786         foreach ($aOrders as $iKey => $oOrder) {
00787             $aOrdersIds[] = $oOrder->getId();
00788         }
00789 
00790         $oBaseObject    = $this->getBaseObject();
00791         $sArticleTable  = $oBaseObject->getViewName();
00792         $sArticleFields = $oBaseObject->getSelectFields();
00793         $sArticleFields = str_replace( "`$sArticleTable`.`oxid`", "`oxorderarticles`.`oxartid` AS `oxid`", $sArticleFields );
00794 
00795         $sSelect  = "SELECT $sArticleFields FROM oxorderarticles ";
00796         $sSelect .= "left join $sArticleTable on oxorderarticles.oxartid = $sArticleTable.oxid ";
00797         $sSelect .= "WHERE oxorderarticles.oxorderid IN ( '".implode("','", $aOrdersIds)."' ) ";
00798         $sSelect .= "order by $sArticleTable.oxid ";
00799 
00800         $this->selectString( $sSelect );
00801 
00802         // not active or not available products must not have button "tobasket"
00803         $sNow = date('Y-m-d H:i:s');
00804         foreach ( $this as $oArticle ) {
00805             if ( !$oArticle->oxarticles__oxactive->value  &&
00806              (  $oArticle->oxarticles__oxactivefrom->value > $sNow ||
00807                 $oArticle->oxarticles__oxactiveto->value < $sNow
00808              )) {
00809                 $oArticle->setBuyableState( false );
00810             }
00811         }
00812     }
00813 
00821     public function loadStockRemindProducts( $aBasketContents )
00822     {
00823         if ( is_array( $aBasketContents ) && count( $aBasketContents ) ) {
00824             $oDb = oxDb::getDb();
00825             foreach ( $aBasketContents as $oBasketItem ) {
00826                 $aArtIds[] = $oDb->quote($oBasketItem->getProductId());
00827             }
00828 
00829             $oBaseObject = $this->getBaseObject();
00830 
00831             $sFieldNames = $oBaseObject->getSelectFields();
00832             $sTable      = $oBaseObject->getViewName();
00833 
00834             // fetching actual db stock state and reminder status
00835             $sQ = "select {$sFieldNames} from {$sTable} where {$sTable}.oxid in ( ".implode( ",", $aArtIds )." ) and
00836                           oxremindactive = '1' and oxstock <= oxremindamount";
00837             $this->selectString( $sQ );
00838 
00839             // updating stock reminder state
00840             if ( $this->count() ) {
00841                 $sQ = "update {$sTable} set oxremindactive = '2' where {$sTable}.oxid in ( ".implode( ",", $aArtIds )." ) and
00842                               oxremindactive = '1' and oxstock <= oxremindamount";
00843                 $oDb->execute( $sQ );
00844             }
00845         }
00846     }
00847 
00853     public function renewPriceUpdateTime()
00854     {
00855         $oDb = oxDb::getDb();
00856 
00857         // fetching next update time
00858         $sQ = "select unix_timestamp( oxupdatepricetime ) from %s where oxupdatepricetime > 0 order by oxupdatepricetime asc";
00859         $iTimeToUpdate = $oDb->getOne( sprintf( $sQ, "`oxarticles`" ), false, false );
00860 
00861 
00862         // next day?
00863         $iCurrUpdateTime = oxRegistry::get("oxUtilsDate")->getTime();
00864         $iNextUpdateTime = $iCurrUpdateTime + 3600 * 24;
00865 
00866         // renew next update time
00867         if ( !$iTimeToUpdate || $iTimeToUpdate > $iNextUpdateTime ) {
00868             $iTimeToUpdate = $iNextUpdateTime;
00869         }
00870 
00871         $this->getConfig()->saveShopConfVar( "int", "iTimeToUpdatePrices", $iTimeToUpdate );
00872 
00873         return $iTimeToUpdate;
00874     }
00875 
00884     public function updateUpcomingPrices( $blForceUpdate = false )
00885     {
00886         $blUpdated = false;
00887 
00888         if ( $blForceUpdate || $this->_canUpdatePrices() ) {
00889 
00890             $oDb = oxDb::getDb();
00891 
00892             $oDb->startTransaction();
00893 
00894             $sCurrUpdateTime = date( "Y-m-d H:i:s", oxRegistry::get("oxUtilsDate")->getTime() );
00895 
00896 
00897             // updating oxarticles
00898             $sQ = "UPDATE %s SET
00899                        `oxprice`  = IF( `oxupdateprice` > 0, `oxupdateprice`, `oxprice` ),
00900                        `oxpricea` = IF( `oxupdatepricea` > 0, `oxupdatepricea`, `oxpricea` ),
00901                        `oxpriceb` = IF( `oxupdatepriceb` > 0, `oxupdatepriceb`, `oxpriceb` ),
00902                        `oxpricec` = IF( `oxupdatepricec` > 0, `oxupdatepricec`, `oxpricec` ),
00903                        `oxupdatepricetime` = 0,
00904                        `oxupdateprice`     = 0,
00905                        `oxupdatepricea`    = 0,
00906                        `oxupdatepriceb`    = 0,
00907                        `oxupdatepricec`    = 0
00908                    WHERE
00909                        `oxupdatepricetime` > 0 AND
00910                        `oxupdatepricetime` <= '{$sCurrUpdateTime}'" ;
00911             $blUpdated = $oDb->execute( sprintf( $sQ, "`oxarticles`" ) );
00912 
00913 
00914             // update oxvarminprice field value also
00915             $sQ = "CREATE TEMPORARY TABLE IF NOT EXISTS `__oxprices` (
00916                     `oxid` CHAR(32) character set latin1 collate latin1_general_ci NOT NULL,
00917                     `oxminprice` DOUBLE NOT NULL,
00918                     `oxmaxprice` DOUBLE NOT NULL,
00919                     PRIMARY KEY ( `oxid` )
00920                   ) ENGINE=MYISAM
00921                   SELECT `oxparentid` AS `oxid`, MIN(`oxprice`) AS `oxminprice`, MAX(`oxprice`) AS `oxmaxprice`
00922                       FROM `oxarticles` WHERE `oxparentid` <> '' GROUP BY `oxparentid`";
00923 
00924                 $blUpdated = $oDb->execute( $sQ );
00925 
00926             $sQ = "UPDATE `oxarticles`
00927                     INNER JOIN `__oxprices` ON `__oxprices`.`oxid` = `oxarticles`.`oxid`
00928                   SET
00929                       `oxarticles`.`oxvarminprice` = `__oxprices`.`oxminprice`,
00930                       `oxarticles`.`oxvarmaxprice` = `__oxprices`.`oxmaxprice";
00931 
00932             $blUpdated = $oDb->execute( $sQ );
00933             $blUpdated = $oDb->execute( "DROP TEMPORARY TABLE `__oxprices`" );
00934 
00935             // renew update time in case update is not forced
00936             if ( !$blForceUpdate ) {
00937                 $this->renewPriceUpdateTime();
00938             }
00939 
00940             $oDb->commitTransaction();
00941 
00942         }
00943 
00944         return $blUpdated;
00945     }
00946 
00954     protected function _createIdListFromSql( $sSql)
00955     {
00956         $rs = oxDb::getDb( oxDb::FETCH_MODE_ASSOC )->select( $sSql );
00957         if ($rs != false && $rs->recordCount() > 0) {
00958             while (!$rs->EOF) {
00959                 $rs->fields = array_change_key_case($rs->fields, CASE_LOWER);
00960                 $this[$rs->fields['oxid']] =  $rs->fields['oxid']; //only the oxid
00961                 $rs->moveNext();
00962             }
00963         }
00964     }
00965 
00974     protected function _getFilterIdsSql( $sCatId, $aFilter )
00975     {
00976         $sO2CView = getViewName( 'oxobject2category' );
00977         $sO2AView = getViewName( 'oxobject2attribute' );
00978 
00979         $sFilter = '';
00980         $iCnt    = 0;
00981 
00982         $oDb = oxDb::getDb();
00983         foreach ( $aFilter as $sAttrId => $sValue ) {
00984             if ( $sValue ) {
00985                 if ( $sFilter ) {
00986                     $sFilter .= ' or ';
00987                 }
00988                 $sValue  = $oDb->quote( $sValue );
00989                 $sAttrId = $oDb->quote( $sAttrId );
00990 
00991                 $sFilter .= "( oa.oxattrid = {$sAttrId} and oa.oxvalue = {$sValue} )";
00992                 $iCnt++;
00993             }
00994         }
00995         if ( $sFilter ) {
00996             $sFilter = "WHERE $sFilter ";
00997         }
00998 
00999         $sFilterSelect = "select oc.oxobjectid as oxobjectid, count(*) as cnt from ";
01000         $sFilterSelect.= "(SELECT * FROM $sO2CView WHERE $sO2CView.oxcatnid = '$sCatId' GROUP BY $sO2CView.oxobjectid, $sO2CView.oxcatnid) as oc ";
01001         $sFilterSelect.= "INNER JOIN $sO2AView as oa ON ( oa.oxobjectid = oc.oxobjectid ) ";
01002         return $sFilterSelect . "{$sFilter} GROUP BY oa.oxobjectid HAVING cnt = $iCnt ";
01003     }
01004 
01013     protected function _getFilterSql( $sCatId, $aFilter )
01014     {
01015         $sArticleTable = getViewName( 'oxarticles' );
01016         $aIds = oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->getAll( $this->_getFilterIdsSql( $sCatId, $aFilter ) );
01017         $sIds = '';
01018 
01019         if ( $aIds ) {
01020             foreach ( $aIds as $aArt ) {
01021                 if ( $sIds ) {
01022                     $sIds .= ', ';
01023                 }
01024                 $sIds .= oxDb::getDb()->quote( current( $aArt ) );
01025             }
01026 
01027             if ( $sIds ) {
01028                 $sFilterSql = " and $sArticleTable.oxid in ( $sIds ) ";
01029             }
01030         // bug fix #0001695: if no articles found return false
01031         } elseif ( !( current( $aFilter ) == '' && count( array_unique( $aFilter ) ) == 1 ) ) {
01032             $sFilterSql = " and false ";
01033         }
01034 
01035         return $sFilterSql;
01036     }
01037 
01047     protected function _getCategorySelect( $sFields, $sCatId, $aSessionFilter )
01048     {
01049         $sArticleTable = getViewName( 'oxarticles' );
01050         $sO2CView      = getViewName( 'oxobject2category' );
01051 
01052         // ----------------------------------
01053         // sorting
01054         $sSorting = '';
01055         if ( $this->_sCustomSorting ) {
01056             $sSorting = " {$this->_sCustomSorting} , ";
01057         }
01058 
01059         // ----------------------------------
01060         // filtering ?
01061         $sFilterSql = '';
01062         $iLang = oxRegistry::getLang()->getBaseLanguage();
01063         if ( $aSessionFilter && isset( $aSessionFilter[$sCatId][$iLang] ) ) {
01064             $sFilterSql = $this->_getFilterSql($sCatId, $aSessionFilter[$sCatId][$iLang]);
01065         }
01066 
01067         $oDb = oxDb::getDb();
01068 
01069         $sSelect = "SELECT $sFields FROM $sO2CView as oc left join $sArticleTable
01070                     ON $sArticleTable.oxid = oc.oxobjectid
01071                     WHERE ".$this->getBaseObject()->getSqlActiveSnippet()." and $sArticleTable.oxparentid = ''
01072                     and oc.oxcatnid = ".$oDb->quote($sCatId)." $sFilterSql ORDER BY $sSorting oc.oxpos, oc.oxobjectid ";
01073 
01074         return $sSelect;
01075     }
01076 
01085     protected function _getCategoryCountSelect( $sCatId, $aSessionFilter )
01086     {
01087         $sArticleTable = getViewName( 'oxarticles' );
01088         $sO2CView      = getViewName( 'oxobject2category' );
01089 
01090 
01091         // ----------------------------------
01092         // filtering ?
01093         $sFilterSql = '';
01094         $iLang = oxRegistry::getLang()->getBaseLanguage();
01095         if ( $aSessionFilter && isset( $aSessionFilter[$sCatId][$iLang] ) ) {
01096             $sFilterSql = $this->_getFilterSql($sCatId, $aSessionFilter[$sCatId][$iLang]);
01097         }
01098 
01099         $oDb = oxDb::getDb();
01100 
01101         $sSelect = "SELECT COUNT(*) FROM $sO2CView as oc left join $sArticleTable
01102                     ON $sArticleTable.oxid = oc.oxobjectid
01103                     WHERE ".$this->getBaseObject()->getSqlActiveSnippet()." and $sArticleTable.oxparentid = ''
01104                     and oc.oxcatnid = ".$oDb->quote($sCatId)." $sFilterSql ";
01105 
01106         return $sSelect;
01107     }
01108 
01116     protected function _getSearchSelect( $sSearchString )
01117     {
01118         // check if it has string at all
01119         if ( !$sSearchString || !str_replace( ' ', '', $sSearchString ) ) {
01120             return '';
01121         }
01122 
01123         $oDb = oxDb::getDb();
01124         $myConfig = $this->getConfig();
01125         $myUtils  = oxRegistry::getUtils();
01126         $sArticleTable = $this->getBaseObject()->getViewName();
01127 
01128         $aSearch = explode( ' ', $sSearchString);
01129 
01130         $sSearch  = ' and ( ';
01131         $blSep = false;
01132 
01133         // #723
01134         if ( $myConfig->getConfigParam( 'blSearchUseAND' ) ) {
01135             $sSearchSep = ' and ';
01136         } else {
01137             $sSearchSep = ' or ';
01138         }
01139 
01140         $aSearchCols = $myConfig->getConfigParam( 'aSearchCols' );
01141         $oBaseObject = $this->getBaseObject();
01142         $myUtilsString = oxRegistry::get("oxUtilsString");
01143         foreach ( $aSearch as $sSearchString) {
01144 
01145             if ( !strlen( $sSearchString ) ) {
01146                 continue;
01147             }
01148 
01149             if ( $blSep ) {
01150                 $sSearch .= $sSearchSep;
01151             }
01152             $blSep2   = false;
01153             $sSearch .= '( ';
01154 
01155             $sUml = $myUtilsString->prepareStrForSearch($sSearchString);
01156             foreach ( $aSearchCols as $sField ) {
01157 
01158                 if ( $blSep2) {
01159                     $sSearch  .= ' or ';
01160                 }
01161 
01162                 // as long description now is on different table table must differ
01163                 if ( $sField == 'oxlongdesc' || $sField == 'oxtags') {
01164                     $sSearchTable = getViewName( 'oxartextends' );
01165                 } else {
01166                     $sSearchTable = $sArticleTable;
01167                 }
01168 
01169                 $sSearch .= $sSearchTable.'.'.$sField.' like '.$oDb->quote('%'.$sSearchString.'%') . ' ';
01170                 if ( $sUml ) {
01171                     $sSearch  .= ' or '.$sSearchTable.'.'.$sField.' like '.$oDb->quote('%'.$sUml.'%');
01172                 }
01173                 $blSep2 = true;
01174             }
01175             $sSearch  .= ' ) ';
01176             $blSep = true;
01177         }
01178         $sSearch .= ' ) ';
01179 
01180         return $sSearch;
01181     }
01182 
01191     protected function _getPriceSelect( $dPriceFrom, $dPriceTo )
01192     {
01193         $oBaseObject   = $this->getBaseObject();
01194         $sArticleTable = $oBaseObject->getViewName();
01195         $sSelectFields = $oBaseObject->getSelectFields();
01196 
01197         $sSubSelect = "";
01198 
01199         $sSelect  = "select {$sSelectFields} from {$sArticleTable} where oxvarminprice >= 0 ";
01200         $sSelect .= $dPriceTo ? "and oxvarminprice <= " . (double)$dPriceTo . " " : " ";
01201         $sSelect .= $dPriceFrom ? "and oxvarminprice  >= " . (double)$dPriceFrom . " " : " ";
01202 
01203         $sSelect .= " and ".$oBaseObject->getSqlActiveSnippet()." and {$sArticleTable}.oxissearch = 1";
01204 
01205         if ( !$this->_sCustomSorting ) {
01206             $sSelect .= " order by {$sArticleTable}.oxvarminprice asc , {$sArticleTable}.oxid";
01207         } else {
01208             $sSelect .= " order by {$this->_sCustomSorting}, {$sArticleTable}.oxid ";
01209         }
01210 
01211         return $sSelect;
01212     }
01213 
01221     protected function _getVendorSelect( $sVendorId )
01222     {
01223         $sArticleTable = getViewName('oxarticles');
01224         $oBaseObject = $this->getBaseObject();
01225         $sFieldNames = $oBaseObject->getSelectFields();
01226         $sSelect  = "select $sFieldNames from $sArticleTable ";
01227         $sSelect .= "where $sArticleTable.oxvendorid = ".oxDb::getDb()->quote($sVendorId)." ";
01228         $sSelect .= " and " . $oBaseObject->getSqlActiveSnippet() . " and $sArticleTable.oxparentid = ''  ";
01229 
01230         if ( $this->_sCustomSorting ) {
01231             $sSelect .= " ORDER BY {$this->_sCustomSorting} ";
01232         }
01233 
01234         return $sSelect;
01235     }
01236 
01244     protected function _getManufacturerSelect( $sManufacturerId )
01245     {
01246         $sArticleTable = getViewName('oxarticles');
01247         $oBaseObject = $this->getBaseObject();
01248         $sFieldNames = $oBaseObject->getSelectFields();
01249         $sSelect  = "select $sFieldNames from $sArticleTable ";
01250         $sSelect .= "where $sArticleTable.oxmanufacturerid = ".oxDb::getDb()->quote($sManufacturerId)." ";
01251         $sSelect .= " and " . $oBaseObject->getSqlActiveSnippet() . " and $sArticleTable.oxparentid = ''  ";
01252 
01253         if ( $this->_sCustomSorting ) {
01254             $sSelect .= " ORDER BY {$this->_sCustomSorting} ";
01255         }
01256 
01257         return $sSelect;
01258     }
01259 
01265     protected function _canUpdatePrices()
01266     {
01267         $oConfig = $this->getConfig();
01268         $blCan = false;
01269 
01270         // crontab is off?
01271         if ( !$oConfig->getConfigParam( "blUseCron" ) ) {
01272             $iTimeToUpdate = $oConfig->getConfigParam( "iTimeToUpdatePrices" );
01273             if ( !$iTimeToUpdate || $iTimeToUpdate <= oxRegistry::get("oxUtilsDate")->getTime() ) {
01274                 $blCan = true;
01275             }
01276         }
01277         return $blCan;
01278     }
01279 
01280 }