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     public 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.*
00344                         FROM $sArticleTable INNER JOIN oxobject2article ON oxobject2article.oxobjectid=$sArticleTable.oxid ";
00345         $sSelect .= "WHERE oxobject2article.oxarticlenid = $sArticleId ";
00346         $sSelect .= " AND " .$oBaseObject->getSqlActiveSnippet();
00347 
00348         // #525 bidirectional cross selling
00349         if ( $myConfig->getConfigParam( 'blBidirectCross' ) ) {
00350             $sSelect = "
00351                 (
00352                     SELECT $sArticleTable.* FROM $sArticleTable
00353                         INNER JOIN oxobject2article AS O2A1 on
00354                             ( O2A1.oxobjectid = $sArticleTable.oxid AND O2A1.oxarticlenid = $sArticleId )
00355                     WHERE 1
00356                     AND " . $oBaseObject->getSqlActiveSnippet() . "
00357                     AND ($sArticleTable.oxid != $sArticleId)
00358                 )
00359                 UNION
00360                 (
00361                     SELECT $sArticleTable.* FROM $sArticleTable
00362                         INNER JOIN oxobject2article AS O2A2 ON
00363                             ( O2A2.oxarticlenid = $sArticleTable.oxid AND O2A2.oxobjectid = $sArticleId )
00364                     WHERE 1
00365                     AND " . $oBaseObject->getSqlActiveSnippet() . "
00366                     AND ($sArticleTable.oxid != $sArticleId)
00367                 )";
00368         }
00369 
00370         $this->setSqlLimit( 0, $myConfig->getConfigParam( 'iNrofCrossellArticles' ));
00371         $this->selectString( $sSelect );
00372     }
00373 
00381     public function loadArticleAccessoires( $sArticleId )
00382     {
00383         $myConfig = $this->getConfig();
00384 
00385         // Performance
00386         if ( !$myConfig->getConfigParam( 'bl_perfLoadAccessoires' ) ) {
00387             return;
00388         }
00389 
00390         $sArticleId = oxDb::getDb()->quote($sArticleId);
00391 
00392         $oBaseObject   = $this->getBaseObject();
00393         $sArticleTable = $oBaseObject->getViewName();
00394 
00395         $sSelect  = "select $sArticleTable.* from oxaccessoire2article left join $sArticleTable on oxaccessoire2article.oxobjectid=$sArticleTable.oxid ";
00396         $sSelect .= "where oxaccessoire2article.oxarticlenid = $sArticleId ";
00397         $sSelect .= " and $sArticleTable.oxid is not null and " .$oBaseObject->getSqlActiveSnippet();
00398         //sorting articles
00399         $sSelect .= " order by oxaccessoire2article.oxsort";
00400 
00401         $this->selectString( $sSelect );
00402     }
00403 
00412     public function loadCategoryIds( $sCatId, $aSessionFilter )
00413     {
00414         $sArticleTable = $this->getBaseObject()->getViewName();
00415         $sSelect = $this->_getCategorySelect( $sArticleTable.'.oxid as oxid', $sCatId, $aSessionFilter );
00416 
00417         $this->_createIdListFromSql( $sSelect );
00418     }
00419 
00429     public function loadCategoryArticles( $sCatId, $aSessionFilter, $iLimit = null )
00430     {
00431         $sArticleFields = $this->getBaseObject()->getSelectFields();
00432 
00433         $sSelect = $this->_getCategorySelect( $sArticleFields, $sCatId, $aSessionFilter );
00434 
00435         // calc count - we can not use count($this) here as we might have paging enabled
00436         // #1970C - if any filters are used, we can not use cached category article count
00437         $iArticleCount = null;
00438         if ( $aSessionFilter) {
00439             $iArticleCount = oxDb::getDb()->getOne( $this->_getCategoryCountSelect( $sCatId, $aSessionFilter ) );
00440         }
00441 
00442         if ($iLimit = (int) $iLimit) {
00443             $sSelect .= " LIMIT $iLimit";
00444         }
00445 
00446         $this->selectString( $sSelect );
00447 
00448         if ( $iArticleCount !== null ) {
00449             return $iArticleCount;
00450         }
00451 
00452         // this select is FAST so no need to hazzle here with getNrOfArticles()
00453         return oxRegistry::get("oxUtilsCount")->getCatArticleCount( $sCatId );
00454     }
00455 
00464     public function loadRecommArticles( $sRecommId, $sArticlesFilter = null )
00465     {
00466         $sSelect = $this->_getArticleSelect( $sRecommId, $sArticlesFilter);
00467         $this->selectString( $sSelect );
00468     }
00469 
00478     public function loadRecommArticleIds( $sRecommId, $sArticlesFilter )
00479     {
00480         $sSelect = $this->_getArticleSelect( $sRecommId, $sArticlesFilter );
00481 
00482         $sArtView = getViewName( 'oxarticles' );
00483         $sPartial = substr( $sSelect, strpos( $sSelect, ' from ' ) );
00484         $sSelect  = "select distinct $sArtView.oxid $sPartial ";
00485 
00486         $this->_createIdListFromSql( $sSelect );
00487     }
00488 
00497     protected function _getArticleSelect( $sRecommId, $sArticlesFilter = null )
00498     {
00499         $sRecommId = oxDb::getDb()->quote($sRecommId);
00500 
00501         $sArtView = getViewName( 'oxarticles' );
00502         $sSelect  = "select distinct $sArtView.*, oxobject2list.oxdesc from oxobject2list ";
00503         $sSelect .= "left join $sArtView on oxobject2list.oxobjectid = $sArtView.oxid ";
00504         $sSelect .= "where (oxobject2list.oxlistid = $sRecommId) ".$sArticlesFilter;
00505 
00506         return $sSelect;
00507     }
00508 
00519     public function loadSearchIds( $sSearchStr = '', $sSearchCat = '', $sSearchVendor = '', $sSearchManufacturer = '' )
00520     {
00521         $oDb = oxDb::getDb();
00522         $sSearchCat    = $sSearchCat?$sSearchCat:null;
00523         $sSearchVendor = $sSearchVendor?$sSearchVendor:null;
00524         $sSearchManufacturer = $sSearchManufacturer?$sSearchManufacturer:null;
00525 
00526         $sWhere = null;
00527 
00528         if ( $sSearchStr ) {
00529             $sWhere = $this->_getSearchSelect( $sSearchStr );
00530         }
00531 
00532         $sArticleTable = getViewName('oxarticles');
00533 
00534         // longdesc field now is kept on different table
00535         $sDescTable = '';
00536         $sDescJoin  = '';
00537         if ( is_array( $aSearchCols = $this->getConfig()->getConfigParam( 'aSearchCols' ) ) ) {
00538             if ( in_array( 'oxlongdesc', $aSearchCols ) || in_array( 'oxtags', $aSearchCols ) ) {
00539                 $sDescView  = getViewName( 'oxartextends' );
00540                 $sDescJoin  = " LEFT JOIN $sDescView ON {$sDescView}.oxid={$sArticleTable}.oxid ";
00541             }
00542         }
00543 
00544         // load the articles
00545         $sSelect  =  "select $sArticleTable.oxid, $sArticleTable.oxtimestamp from $sArticleTable $sDescJoin where ";
00546 
00547         // must be additional conditions in select if searching in category
00548         if ( $sSearchCat ) {
00549             $sO2CView = getViewName('oxobject2category');
00550             $sSelect  = "select $sArticleTable.oxid from $sO2CView as oxobject2category, $sArticleTable $sDescJoin ";
00551             $sSelect .= "where oxobject2category.oxcatnid=".$oDb->quote( $sSearchCat )." and oxobject2category.oxobjectid=$sArticleTable.oxid and ";
00552         }
00553         $sSelect .= $this->getBaseObject()->getSqlActiveSnippet();
00554         $sSelect .= " and $sArticleTable.oxparentid = '' and $sArticleTable.oxissearch = 1 ";
00555 
00556         // #671
00557         if ( $sSearchVendor ) {
00558             $sSelect .= " and $sArticleTable.oxvendorid = ".$oDb->quote( $sSearchVendor )." ";
00559         }
00560 
00561         if ( $sSearchManufacturer ) {
00562             $sSelect .= " and $sArticleTable.oxmanufacturerid = ".$oDb->quote( $sSearchManufacturer )." ";
00563         }
00564         $sSelect .= $sWhere;
00565 
00566         if ($this->_sCustomSorting) {
00567             $sSelect .= " order by {$this->_sCustomSorting} ";
00568         }
00569 
00570         $this->_createIdListFromSql($sSelect);
00571     }
00572 
00581     public function loadPriceIds( $dPriceFrom, $dPriceTo )
00582     {
00583         $sSelect = $this->_getPriceSelect( $dPriceFrom, $dPriceTo );
00584         $this->_createIdListFromSql( $sSelect );
00585     }
00586 
00597     public function loadPriceArticles( $dPriceFrom, $dPriceTo, $oCategory = null)
00598     {
00599         $sSelect =  $this->_getPriceSelect( $dPriceFrom, $dPriceTo );
00600 
00601         startProfile("loadPriceArticles");
00602         $this->selectString( $sSelect);
00603         stopProfile("loadPriceArticles");
00604 
00605         if ( !$oCategory ) {
00606             return $this->count();
00607         }
00608 
00609         return oxRegistry::get("oxUtilsCount")->getPriceCatArticleCount( $oCategory->getId(), $dPriceFrom, $dPriceTo );
00610     }
00611 
00619     public function loadVendorIDs( $sVendorId)
00620     {
00621         $sSelect = $this->_getVendorSelect($sVendorId);
00622         $this->_createIdListFromSql($sSelect);
00623     }
00624 
00632     public function loadManufacturerIDs( $sManufacturerId)
00633     {
00634         $sSelect = $this->_getManufacturerSelect($sManufacturerId);
00635         $this->_createIdListFromSql($sSelect);
00636     }
00637 
00647     public function loadVendorArticles( $sVendorId, $oVendor = null )
00648     {
00649         $sSelect = $this->_getVendorSelect($sVendorId);
00650         $this->selectString( $sSelect);
00651 
00652         return oxRegistry::get("oxUtilsCount")->getVendorArticleCount( $sVendorId );
00653     }
00654 
00664     public function loadManufacturerArticles( $sManufacturerId, $oManufacturer = null )
00665     {
00666         $sSelect = $this->_getManufacturerSelect($sManufacturerId);
00667         $this->selectString( $sSelect);
00668 
00669         return oxRegistry::get("oxUtilsCount")->getManufacturerArticleCount( $sManufacturerId );
00670     }
00671 
00680     public function loadTagArticles( $sTag, $iLang )
00681     {
00682         $oListObject = $this->getBaseObject();
00683         $sArticleTable = $oListObject->getViewName();
00684         $sArticleFields = $oListObject->getSelectFields();
00685         $sViewName = getViewName( 'oxartextends', $iLang );
00686 
00687         $oTag = oxNew( 'oxtag', $sTag );
00688         $oTag->addUnderscores();
00689         $sTag = $oTag->get();
00690 
00691         $sQ = "select {$sArticleFields} from {$sViewName} inner join {$sArticleTable} on ".
00692               "{$sArticleTable}.oxid = {$sViewName}.oxid where {$sArticleTable}.oxparentid = '' AND match ( {$sViewName}.oxtags ) ".
00693               "against( ".oxDb::getDb()->quote( "\"".$sTag."\"" )." IN BOOLEAN MODE )";
00694 
00695         // checking stock etc
00696         if ( ( $sActiveSnippet = $oListObject->getSqlActiveSnippet() ) ) {
00697             $sQ .= " and {$sActiveSnippet}";
00698         }
00699 
00700         if ( $this->_sCustomSorting ) {
00701             $sSort = $this->_sCustomSorting;
00702             if (strpos($sSort, '.') === false) {
00703                 $sSort = $sArticleTable.'.'.$sSort;
00704             }
00705             $sQ .= " order by $sSort ";
00706         }
00707 
00708         $this->selectString( $sQ );
00709 
00710         // calc count - we can not use count($this) here as we might have paging enabled
00711         return oxRegistry::get("oxUtilsCount")->getTagArticleCount( $sTag, $iLang );
00712     }
00713 
00722     public function getTagArticleIds( $sTag, $iLang )
00723     {
00724         $oListObject = $this->getBaseObject();
00725         $sArticleTable = $oListObject->getViewName();
00726         $sViewName = getViewName( 'oxartextends', $iLang );
00727 
00728         $oTag = oxNew( 'oxtag', $sTag );
00729         $oTag->addUnderscores();
00730         $sTag = $oTag->get();
00731 
00732         $sQ = "select {$sViewName}.oxid from {$sViewName} inner join {$sArticleTable} on ".
00733             "{$sArticleTable}.oxid = {$sViewName}.oxid where {$sArticleTable}.oxparentid = '' and {$sArticleTable}.oxissearch = 1 and ".
00734             "match ( {$sViewName}.oxtags ) ".
00735             "against( ".oxDb::getDb()->quote( "\"".$sTag."\"" )." IN BOOLEAN MODE )";
00736 
00737         // checking stock etc
00738         if ( ( $sActiveSnippet = $oListObject->getSqlActiveSnippet() ) ) {
00739             $sQ .= " and {$sActiveSnippet}";
00740         }
00741 
00742         if ( $this->_sCustomSorting ) {
00743             $sSort = $this->_sCustomSorting;
00744             if (strpos($sSort, '.') === false) {
00745                 $sSort = $sArticleTable.'.'.$sSort;
00746             }
00747             $sQ .= " order by $sSort ";
00748         }
00749 
00750         return $this->_createIdListFromSql( $sQ );
00751     }
00752 
00760     public function loadIds($aIds)
00761     {
00762         if (!count($aIds)) {
00763             $this->clear();
00764             return;
00765         }
00766 
00767         foreach ($aIds as $iKey => $sVal) {
00768             $aIds[$iKey] = oxDb::getInstance()->escapeString($sVal);
00769         }
00770 
00771         $oBaseObject    = $this->getBaseObject();
00772         $sArticleTable  = $oBaseObject->getViewName();
00773         $sArticleFields = $oBaseObject->getSelectFields();
00774 
00775         $sSelect  = "select $sArticleFields from $sArticleTable ";
00776         $sSelect .= "where $sArticleTable.oxid in ( '".implode("','", $aIds)."' ) and ";
00777         $sSelect .= $oBaseObject->getSqlActiveSnippet();
00778 
00779         $this->selectString($sSelect);
00780     }
00781 
00789     public function loadOrderArticles($aOrders)
00790     {
00791         if (!count($aOrders)) {
00792             $this->clear();
00793             return;
00794         }
00795 
00796         foreach ($aOrders as $iKey => $oOrder) {
00797             $aOrdersIds[] = $oOrder->getId();
00798         }
00799 
00800         $oBaseObject    = $this->getBaseObject();
00801         $sArticleTable  = $oBaseObject->getViewName();
00802         $sArticleFields = $oBaseObject->getSelectFields();
00803         $sArticleFields = str_replace( "`$sArticleTable`.`oxid`", "`oxorderarticles`.`oxartid` AS `oxid`", $sArticleFields );
00804 
00805         $sSelect  = "SELECT $sArticleFields FROM oxorderarticles ";
00806         $sSelect .= "left join $sArticleTable on oxorderarticles.oxartid = $sArticleTable.oxid ";
00807         $sSelect .= "WHERE oxorderarticles.oxorderid IN ( '".implode("','", $aOrdersIds)."' ) ";
00808         $sSelect .= "order by $sArticleTable.oxid ";
00809 
00810         $this->selectString( $sSelect );
00811 
00812         // not active or not available products must not have button "tobasket"
00813         $sNow = date('Y-m-d H:i:s');
00814         foreach ( $this as $oArticle ) {
00815             if ( !$oArticle->oxarticles__oxactive->value  &&
00816              (  $oArticle->oxarticles__oxactivefrom->value > $sNow ||
00817                 $oArticle->oxarticles__oxactiveto->value < $sNow
00818              )) {
00819                 $oArticle->setBuyableState( false );
00820             }
00821         }
00822     }
00823 
00831     public function loadStockRemindProducts( $aBasketContents )
00832     {
00833         if ( is_array( $aBasketContents ) && count( $aBasketContents ) ) {
00834             $oDb = oxDb::getDb();
00835             foreach ( $aBasketContents as $oBasketItem ) {
00836                 $aArtIds[] = $oDb->quote($oBasketItem->getProductId());
00837             }
00838 
00839             $oBaseObject = $this->getBaseObject();
00840 
00841             $sFieldNames = $oBaseObject->getSelectFields();
00842             $sTable      = $oBaseObject->getViewName();
00843 
00844             // fetching actual db stock state and reminder status
00845             $sQ = "select {$sFieldNames} from {$sTable} where {$sTable}.oxid in ( ".implode( ",", $aArtIds )." ) and
00846                           oxremindactive = '1' and oxstock <= oxremindamount";
00847             $this->selectString( $sQ );
00848 
00849             // updating stock reminder state
00850             if ( $this->count() ) {
00851                 $sQ = "update {$sTable} set oxremindactive = '2' where {$sTable}.oxid in ( ".implode( ",", $aArtIds )." ) and
00852                               oxremindactive = '1' and oxstock <= oxremindamount";
00853                 $oDb->execute( $sQ );
00854             }
00855         }
00856     }
00857 
00863     public function renewPriceUpdateTime()
00864     {
00865         $oDb = oxDb::getDb();
00866 
00867         // fetching next update time
00868         $sQ = "select unix_timestamp( oxupdatepricetime ) from %s where oxupdatepricetime > 0 order by oxupdatepricetime asc";
00869         $iTimeToUpdate = $oDb->getOne( sprintf( $sQ, "`oxarticles`" ), false, false );
00870 
00871 
00872         // next day?
00873         $iCurrUpdateTime = oxRegistry::get("oxUtilsDate")->getTime();
00874         $iNextUpdateTime = $iCurrUpdateTime + 3600 * 24;
00875 
00876         // renew next update time
00877         if ( !$iTimeToUpdate || $iTimeToUpdate > $iNextUpdateTime ) {
00878             $iTimeToUpdate = $iNextUpdateTime;
00879         }
00880 
00881         $this->getConfig()->saveShopConfVar( "int", "iTimeToUpdatePrices", $iTimeToUpdate );
00882 
00883         return $iTimeToUpdate;
00884     }
00885 
00894     public function updateUpcomingPrices( $blForceUpdate = false )
00895     {
00896         $blUpdated = false;
00897 
00898         if ( $blForceUpdate || $this->_canUpdatePrices() ) {
00899 
00900             $oDb = oxDb::getDb();
00901 
00902             $oDb->startTransaction();
00903 
00904             $sCurrUpdateTime = date( "Y-m-d H:i:s", oxRegistry::get("oxUtilsDate")->getTime() );
00905 
00906             // Collect article id's for later recalculation.
00907             $sQ = "SELECT `oxid` FROM `oxarticles`
00908                    WHERE `oxupdatepricetime` > 0 AND `oxupdatepricetime` <= '{$sCurrUpdateTime}'";
00909             $aUpdatedArticleIds = $oDb->getCol( $sQ, false, false );
00910 
00911             // updating oxarticles
00912             $sQ = "UPDATE %s SET
00913                        `oxprice`  = IF( `oxupdateprice` > 0, `oxupdateprice`, `oxprice` ),
00914                        `oxpricea` = IF( `oxupdatepricea` > 0, `oxupdatepricea`, `oxpricea` ),
00915                        `oxpriceb` = IF( `oxupdatepriceb` > 0, `oxupdatepriceb`, `oxpriceb` ),
00916                        `oxpricec` = IF( `oxupdatepricec` > 0, `oxupdatepricec`, `oxpricec` ),
00917                        `oxupdatepricetime` = 0,
00918                        `oxupdateprice`     = 0,
00919                        `oxupdatepricea`    = 0,
00920                        `oxupdatepriceb`    = 0,
00921                        `oxupdatepricec`    = 0
00922                    WHERE
00923                        `oxupdatepricetime` > 0 AND
00924                        `oxupdatepricetime` <= '{$sCurrUpdateTime}'" ;
00925             $blUpdated = $oDb->execute( sprintf( $sQ, "`oxarticles`" ) );
00926 
00927 
00928             // renew update time in case update is not forced
00929             if ( !$blForceUpdate ) {
00930                 $this->renewPriceUpdateTime();
00931             }
00932 
00933             $oDb->commitTransaction();
00934 
00935             // recalculate oxvarminprice and oxvarmaxprice for parent
00936             if( is_array($aUpdatedArticleIds) ) {
00937                 foreach ($aUpdatedArticleIds as $sArticleId) {
00938                     $oArticle = oxNew('oxarticle');
00939                     $oArticle->load($sArticleId);
00940                     $oArticle->onChange();
00941                 }
00942             }
00943 
00944         }
00945 
00946         return $blUpdated;
00947     }
00948 
00956     protected function _createIdListFromSql( $sSql)
00957     {
00958         $rs = oxDb::getDb( oxDb::FETCH_MODE_ASSOC )->select( $sSql );
00959         if ($rs != false && $rs->recordCount() > 0) {
00960             while (!$rs->EOF) {
00961                 $rs->fields = array_change_key_case($rs->fields, CASE_LOWER);
00962                 $this[$rs->fields['oxid']] =  $rs->fields['oxid']; //only the oxid
00963                 $rs->moveNext();
00964             }
00965         }
00966     }
00967 
00976     protected function _getFilterIdsSql( $sCatId, $aFilter )
00977     {
00978         $sO2CView = getViewName( 'oxobject2category' );
00979         $sO2AView = getViewName( 'oxobject2attribute' );
00980 
00981         $sFilter = '';
00982         $iCnt    = 0;
00983 
00984         $oDb = oxDb::getDb();
00985         foreach ( $aFilter as $sAttrId => $sValue ) {
00986             if ( $sValue ) {
00987                 if ( $sFilter ) {
00988                     $sFilter .= ' or ';
00989                 }
00990                 $sValue  = $oDb->quote( $sValue );
00991                 $sAttrId = $oDb->quote( $sAttrId );
00992 
00993                 $sFilter .= "( oa.oxattrid = {$sAttrId} and oa.oxvalue = {$sValue} )";
00994                 $iCnt++;
00995             }
00996         }
00997         if ( $sFilter ) {
00998             $sFilter = "WHERE $sFilter ";
00999         }
01000 
01001         $sFilterSelect = "select oc.oxobjectid as oxobjectid, count(*) as cnt from ";
01002         $sFilterSelect.= "(SELECT * FROM $sO2CView WHERE $sO2CView.oxcatnid = '$sCatId' GROUP BY $sO2CView.oxobjectid, $sO2CView.oxcatnid) as oc ";
01003         $sFilterSelect.= "INNER JOIN $sO2AView as oa ON ( oa.oxobjectid = oc.oxobjectid ) ";
01004         return $sFilterSelect . "{$sFilter} GROUP BY oa.oxobjectid HAVING cnt = $iCnt ";
01005     }
01006 
01015     protected function _getFilterSql( $sCatId, $aFilter )
01016     {
01017         $sArticleTable = getViewName( 'oxarticles' );
01018         $aIds = oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->getAll( $this->_getFilterIdsSql( $sCatId, $aFilter ) );
01019         $sIds = '';
01020 
01021         if ( $aIds ) {
01022             foreach ( $aIds as $aArt ) {
01023                 if ( $sIds ) {
01024                     $sIds .= ', ';
01025                 }
01026                 $sIds .= oxDb::getDb()->quote( current( $aArt ) );
01027             }
01028 
01029             if ( $sIds ) {
01030                 $sFilterSql = " and $sArticleTable.oxid in ( $sIds ) ";
01031             }
01032         // bug fix #0001695: if no articles found return false
01033         } elseif ( !( current( $aFilter ) == '' && count( array_unique( $aFilter ) ) == 1 ) ) {
01034             $sFilterSql = " and false ";
01035         }
01036 
01037         return $sFilterSql;
01038     }
01039 
01049     protected function _getCategorySelect( $sFields, $sCatId, $aSessionFilter )
01050     {
01051         $sArticleTable = getViewName( 'oxarticles' );
01052         $sO2CView      = getViewName( 'oxobject2category' );
01053 
01054         // ----------------------------------
01055         // sorting
01056         $sSorting = '';
01057         if ( $this->_sCustomSorting ) {
01058             $sSorting = " {$this->_sCustomSorting} , ";
01059         }
01060 
01061         // ----------------------------------
01062         // filtering ?
01063         $sFilterSql = '';
01064         $iLang = oxRegistry::getLang()->getBaseLanguage();
01065         if ( $aSessionFilter && isset( $aSessionFilter[$sCatId][$iLang] ) ) {
01066             $sFilterSql = $this->_getFilterSql($sCatId, $aSessionFilter[$sCatId][$iLang]);
01067         }
01068 
01069         $oDb = oxDb::getDb();
01070 
01071         $sSelect = "SELECT $sFields, $sArticleTable.oxtimestamp FROM $sO2CView as oc left join $sArticleTable
01072                     ON $sArticleTable.oxid = oc.oxobjectid
01073                     WHERE ".$this->getBaseObject()->getSqlActiveSnippet()." and $sArticleTable.oxparentid = ''
01074                     and oc.oxcatnid = ".$oDb->quote($sCatId)." $sFilterSql ORDER BY $sSorting oc.oxpos, oc.oxobjectid ";
01075 
01076         return $sSelect;
01077     }
01078 
01087     protected function _getCategoryCountSelect( $sCatId, $aSessionFilter )
01088     {
01089         $sArticleTable = getViewName( 'oxarticles' );
01090         $sO2CView      = getViewName( 'oxobject2category' );
01091 
01092 
01093         // ----------------------------------
01094         // filtering ?
01095         $sFilterSql = '';
01096         $iLang = oxRegistry::getLang()->getBaseLanguage();
01097         if ( $aSessionFilter && isset( $aSessionFilter[$sCatId][$iLang] ) ) {
01098             $sFilterSql = $this->_getFilterSql($sCatId, $aSessionFilter[$sCatId][$iLang]);
01099         }
01100 
01101         $oDb = oxDb::getDb();
01102 
01103         $sSelect = "SELECT COUNT(*) FROM $sO2CView as oc left join $sArticleTable
01104                     ON $sArticleTable.oxid = oc.oxobjectid
01105                     WHERE ".$this->getBaseObject()->getSqlActiveSnippet()." and $sArticleTable.oxparentid = ''
01106                     and oc.oxcatnid = ".$oDb->quote($sCatId)." $sFilterSql ";
01107 
01108         return $sSelect;
01109     }
01110 
01118     protected function _getSearchSelect( $sSearchString )
01119     {
01120         // check if it has string at all
01121         if ( !$sSearchString || !str_replace( ' ', '', $sSearchString ) ) {
01122             return '';
01123         }
01124 
01125         $oDb = oxDb::getDb();
01126         $myConfig = $this->getConfig();
01127         $myUtils  = oxRegistry::getUtils();
01128         $sArticleTable = $this->getBaseObject()->getViewName();
01129 
01130         $aSearch = explode( ' ', $sSearchString);
01131 
01132         $sSearch  = ' and ( ';
01133         $blSep = false;
01134 
01135         // #723
01136         if ( $myConfig->getConfigParam( 'blSearchUseAND' ) ) {
01137             $sSearchSep = ' and ';
01138         } else {
01139             $sSearchSep = ' or ';
01140         }
01141 
01142         $aSearchCols = $myConfig->getConfigParam( 'aSearchCols' );
01143         $oBaseObject = $this->getBaseObject();
01144         $myUtilsString = oxRegistry::get("oxUtilsString");
01145         foreach ( $aSearch as $sSearchString) {
01146 
01147             if ( !strlen( $sSearchString ) ) {
01148                 continue;
01149             }
01150 
01151             if ( $blSep ) {
01152                 $sSearch .= $sSearchSep;
01153             }
01154             $blSep2   = false;
01155             $sSearch .= '( ';
01156 
01157             $sUml = $myUtilsString->prepareStrForSearch($sSearchString);
01158             foreach ( $aSearchCols as $sField ) {
01159 
01160                 if ( $blSep2) {
01161                     $sSearch  .= ' or ';
01162                 }
01163 
01164                 // as long description now is on different table table must differ
01165                 if ( $sField == 'oxlongdesc' || $sField == 'oxtags') {
01166                     $sSearchTable = getViewName( 'oxartextends' );
01167                 } else {
01168                     $sSearchTable = $sArticleTable;
01169                 }
01170 
01171                 $sSearch .= $sSearchTable.'.'.$sField.' like '.$oDb->quote('%'.$sSearchString.'%') . ' ';
01172                 if ( $sUml ) {
01173                     $sSearch  .= ' or '.$sSearchTable.'.'.$sField.' like '.$oDb->quote('%'.$sUml.'%');
01174                 }
01175                 $blSep2 = true;
01176             }
01177             $sSearch  .= ' ) ';
01178             $blSep = true;
01179         }
01180         $sSearch .= ' ) ';
01181 
01182         return $sSearch;
01183     }
01184 
01193     protected function _getPriceSelect( $dPriceFrom, $dPriceTo )
01194     {
01195         $oBaseObject   = $this->getBaseObject();
01196         $sArticleTable = $oBaseObject->getViewName();
01197         $sSelectFields = $oBaseObject->getSelectFields();
01198 
01199         $sSubSelect = "";
01200 
01201         $sSelect  = "select {$sSelectFields} from {$sArticleTable} where oxvarminprice >= 0 ";
01202         $sSelect .= $dPriceTo ? "and oxvarminprice <= " . (double)$dPriceTo . " " : " ";
01203         $sSelect .= $dPriceFrom ? "and oxvarminprice  >= " . (double)$dPriceFrom . " " : " ";
01204 
01205         $sSelect .= " and ".$oBaseObject->getSqlActiveSnippet()." and {$sArticleTable}.oxissearch = 1";
01206 
01207         if ( !$this->_sCustomSorting ) {
01208             $sSelect .= " order by {$sArticleTable}.oxvarminprice asc , {$sArticleTable}.oxid";
01209         } else {
01210             $sSelect .= " order by {$this->_sCustomSorting}, {$sArticleTable}.oxid ";
01211         }
01212 
01213         return $sSelect;
01214     }
01215 
01223     protected function _getVendorSelect( $sVendorId )
01224     {
01225         $sArticleTable = getViewName('oxarticles');
01226         $oBaseObject = $this->getBaseObject();
01227         $sFieldNames = $oBaseObject->getSelectFields();
01228         $sSelect  = "select $sFieldNames from $sArticleTable ";
01229         $sSelect .= "where $sArticleTable.oxvendorid = ".oxDb::getDb()->quote($sVendorId)." ";
01230         $sSelect .= " and " . $oBaseObject->getSqlActiveSnippet() . " and $sArticleTable.oxparentid = ''  ";
01231 
01232         if ( $this->_sCustomSorting ) {
01233             $sSelect .= " ORDER BY {$this->_sCustomSorting} ";
01234         }
01235 
01236         return $sSelect;
01237     }
01238 
01246     protected function _getManufacturerSelect( $sManufacturerId )
01247     {
01248         $sArticleTable = getViewName('oxarticles');
01249         $oBaseObject = $this->getBaseObject();
01250         $sFieldNames = $oBaseObject->getSelectFields();
01251         $sSelect  = "select $sFieldNames from $sArticleTable ";
01252         $sSelect .= "where $sArticleTable.oxmanufacturerid = ".oxDb::getDb()->quote($sManufacturerId)." ";
01253         $sSelect .= " and " . $oBaseObject->getSqlActiveSnippet() . " and $sArticleTable.oxparentid = ''  ";
01254 
01255         if ( $this->_sCustomSorting ) {
01256             $sSelect .= " ORDER BY {$this->_sCustomSorting} ";
01257         }
01258 
01259         return $sSelect;
01260     }
01261 
01267     protected function _canUpdatePrices()
01268     {
01269         $oConfig = $this->getConfig();
01270         $blCan = false;
01271 
01272         // crontab is off?
01273         if ( !$oConfig->getConfigParam( "blUseCron" ) ) {
01274             $iTimeToUpdate = $oConfig->getConfigParam( "iTimeToUpdatePrices" );
01275             if ( !$iTimeToUpdate || $iTimeToUpdate <= oxRegistry::get("oxUtilsDate")->getTime() ) {
01276                 $blCan = true;
01277             }
01278         }
01279         return $blCan;
01280     }
01281 
01282 }