oxarticlelist.php

Go to the documentation of this file.
00001 <?php
00002 
00008 class oxArticleList extends oxList
00009 {
00010 
00014     protected $_sCustomSorting;
00015 
00021     protected $_sObjectsInListName = 'oxarticle';
00022 
00028     protected $_blLoadSelectLists = false;
00029 
00035     public function setCustomSorting($sSorting)
00036     {
00037         $this->_sCustomSorting = $sSorting;
00038     }
00039 
00043     public function enableSelectLists()
00044     {
00045         $this->_blLoadSelectLists = true;
00046     }
00047 
00056     public function selectString($sSelect)
00057     {
00058         startProfile("loadinglists");
00059         $oRes = parent::selectString($sSelect);
00060         stopProfile("loadinglists");
00061 
00062         return $oRes;
00063     }
00064 
00070     public function getHistoryArticles()
00071     {
00072         if ($aArticlesIds = $this->getSession()->getVariable('aHistoryArticles')) {
00073             return $aArticlesIds;
00074         } elseif ($sArticlesIds = oxRegistry::get("oxUtilsServer")->getOxCookie('aHistoryArticles')) {
00075             return explode('|', $sArticlesIds);
00076         }
00077     }
00078 
00084     public function setHistoryArticles($aArticlesIds)
00085     {
00086         if ($this->getSession()->getId()) {
00087             oxRegistry::getSession()->setVariable('aHistoryArticles', $aArticlesIds);
00088             // clean cookie, if session started
00089             oxRegistry::get("oxUtilsServer")->setOxCookie('aHistoryArticles', '');
00090         } else {
00091             oxRegistry::get("oxUtilsServer")->setOxCookie('aHistoryArticles', implode('|', $aArticlesIds));
00092         }
00093     }
00094 
00102     public function loadHistoryArticles($sArtId, $iCnt = 4)
00103     {
00104         $aHistoryArticles = $this->getHistoryArticles();
00105         $aHistoryArticles[] = $sArtId;
00106 
00107         // removing dublicates
00108         $aHistoryArticles = array_unique($aHistoryArticles);
00109         if (count($aHistoryArticles) > ($iCnt + 1)) {
00110             array_shift($aHistoryArticles);
00111         }
00112 
00113         $this->setHistoryArticles($aHistoryArticles);
00114 
00115         //remove current article and return array
00116         //asignment =, not ==
00117         if (($iCurrentArt = array_search($sArtId, $aHistoryArticles)) !== false) {
00118             unset($aHistoryArticles[$iCurrentArt]);
00119         }
00120 
00121         $aHistoryArticles = array_values($aHistoryArticles);
00122         $this->loadIds($aHistoryArticles);
00123         $this->sortByIds($aHistoryArticles);
00124     }
00125 
00131     public function sortByIds($aIds)
00132     {
00133         $this->_aOrderMap = array_flip($aIds);
00134         uksort($this->_aArray, array($this, '_sortByOrderMapCallback'));
00135     }
00136 
00147     protected function _sortByOrderMapCallback($key1, $key2)
00148     {
00149         if (isset($this->_aOrderMap[$key1])) {
00150             if (isset($this->_aOrderMap[$key2])) {
00151                 $iDiff = $this->_aOrderMap[$key2] - $this->_aOrderMap[$key1];
00152                 if ($iDiff > 0) {
00153                     return -1;
00154                 } elseif ($iDiff < 0) {
00155                     return 1;
00156                 } else {
00157                     return 0;
00158                 }
00159             } else {
00160                 // first is here, but 2nd is not - 1st gets more priority
00161                 return -1;
00162             }
00163         } elseif (isset($this->_aOrderMap[$key2])) {
00164             // first is not here, but 2nd is - 2nd gets more priority
00165             return 1;
00166         } else {
00167             // both unset, equal
00168             return 0;
00169         }
00170     }
00171 
00177     public function loadNewestArticles($iLimit = null)
00178     {
00179         //has module?
00180         $myConfig = $this->getConfig();
00181 
00182         if (!$myConfig->getConfigParam('bl_perfLoadPriceForAddList')) {
00183             $this->getBaseObject()->disablePriceLoad();
00184         }
00185 
00186         $this->_aArray = array();
00187         switch ($myConfig->getConfigParam('iNewestArticlesMode')) {
00188             case 0:
00189                 // switched off, do nothing
00190                 break;
00191             case 1:
00192                 // manually entered
00193                 $this->loadActionArticles('oxnewest', $iLimit);
00194                 break;
00195             case 2:
00196                 $sArticleTable = getViewName('oxarticles');
00197                 if ($myConfig->getConfigParam('blNewArtByInsert')) {
00198                     $sType = 'oxinsert';
00199                 } else {
00200                     $sType = 'oxtimestamp';
00201                 }
00202                 $sSelect = "select * from $sArticleTable ";
00203                 $sSelect .= "where oxparentid = '' and " . $this->getBaseObject()->getSqlActiveSnippet() . " and oxissearch = 1 order by $sType desc ";
00204                 if (!($iLimit = (int) $iLimit)) {
00205                     $iLimit = $myConfig->getConfigParam('iNrofNewcomerArticles');
00206                 }
00207                 $sSelect .= "limit " . $iLimit;
00208 
00209                 $this->selectString($sSelect);
00210                 break;
00211         }
00212 
00213     }
00214 
00220     public function loadTop5Articles($iLimit = null)
00221     {
00222         //has module?
00223         $myConfig = $this->getConfig();
00224 
00225         if (!$myConfig->getConfigParam('bl_perfLoadPriceForAddList')) {
00226             $this->getBaseObject()->disablePriceLoad();
00227         }
00228 
00229         switch ($myConfig->getConfigParam('iTop5Mode')) {
00230             case 0:
00231                 // switched off, do nothing
00232                 break;
00233             case 1:
00234                 // manually entered
00235                 $this->loadActionArticles('oxtop5', $iLimit);
00236                 break;
00237             case 2:
00238                 $sArticleTable = getViewName('oxarticles');
00239 
00240                 //by default limit 5
00241                 $sLimit = ($iLimit > 0) ? "limit " . $iLimit : 'limit 5';
00242 
00243                 $sSelect = "select * from $sArticleTable ";
00244                 $sSelect .= "where " . $this->getBaseObject()->getSqlActiveSnippet() . " and $sArticleTable.oxissearch = 1 ";
00245                 $sSelect .= "and $sArticleTable.oxparentid = '' and $sArticleTable.oxsoldamount>0 ";
00246                 $sSelect .= "order by $sArticleTable.oxsoldamount desc $sLimit";
00247 
00248                 $this->selectString($sSelect);
00249                 break;
00250         }
00251     }
00252 
00261     public function loadActionArticles($sActionID, $iLimit = null)
00262     {
00263         // Performance
00264         if (!trim($sActionID)) {
00265             return;
00266         }
00267 
00268         $sShopID = $this->getConfig()->getShopId();
00269         $sActionID = oxDb::getDb()->quote(strtolower($sActionID));
00270 
00271         //echo $sSelect;
00272         $oBaseObject = $this->getBaseObject();
00273         $sArticleTable = $oBaseObject->getViewName();
00274         $sArticleFields = $oBaseObject->getSelectFields();
00275 
00276         $oBase = oxNew("oxactions");
00277         $sActiveSql = $oBase->getSqlActiveSnippet();
00278         $sViewName = $oBase->getViewName();
00279 
00280         $sLimit = ($iLimit > 0) ? "limit " . $iLimit : '';
00281 
00282         $sSelect = "select $sArticleFields from oxactions2article
00283                               left join $sArticleTable on $sArticleTable.oxid = oxactions2article.oxartid
00284                               left join $sViewName on $sViewName.oxid = oxactions2article.oxactionid
00285                               where oxactions2article.oxshopid = '$sShopID' and oxactions2article.oxactionid = $sActionID and $sActiveSql
00286                               and $sArticleTable.oxid is not null and " . $oBaseObject->getSqlActiveSnippet() . "
00287                               order by oxactions2article.oxsort $sLimit";
00288 
00289         $this->selectString($sSelect);
00290     }
00291 
00299     public function loadArticleCrossSell($sArticleId)
00300     {
00301         $myConfig = $this->getConfig();
00302 
00303         // Performance
00304         if (!$myConfig->getConfigParam('bl_perfLoadCrossselling')) {
00305             return null;
00306         }
00307 
00308         $oBaseObject = $this->getBaseObject();
00309         $sArticleTable = $oBaseObject->getViewName();
00310 
00311         $sArticleId = oxDb::getDb()->quote($sArticleId);
00312 
00313         $sSelect = "SELECT $sArticleTable.*
00314                         FROM $sArticleTable INNER JOIN oxobject2article ON oxobject2article.oxobjectid=$sArticleTable.oxid ";
00315         $sSelect .= "WHERE oxobject2article.oxarticlenid = $sArticleId ";
00316         $sSelect .= " AND " . $oBaseObject->getSqlActiveSnippet();
00317 
00318         // #525 bidirectional cross selling
00319         if ($myConfig->getConfigParam('blBidirectCross')) {
00320             $sSelect = "
00321                 (
00322                     SELECT $sArticleTable.* FROM $sArticleTable
00323                         INNER JOIN oxobject2article AS O2A1 on
00324                             ( O2A1.oxobjectid = $sArticleTable.oxid AND O2A1.oxarticlenid = $sArticleId )
00325                     WHERE 1
00326                     AND " . $oBaseObject->getSqlActiveSnippet() . "
00327                     AND ($sArticleTable.oxid != $sArticleId)
00328                 )
00329                 UNION
00330                 (
00331                     SELECT $sArticleTable.* FROM $sArticleTable
00332                         INNER JOIN oxobject2article AS O2A2 ON
00333                             ( O2A2.oxarticlenid = $sArticleTable.oxid AND O2A2.oxobjectid = $sArticleId )
00334                     WHERE 1
00335                     AND " . $oBaseObject->getSqlActiveSnippet() . "
00336                     AND ($sArticleTable.oxid != $sArticleId)
00337                 )";
00338         }
00339 
00340         $this->setSqlLimit(0, $myConfig->getConfigParam('iNrofCrossellArticles'));
00341         $this->selectString($sSelect);
00342     }
00343 
00351     public function loadArticleAccessoires($sArticleId)
00352     {
00353         $myConfig = $this->getConfig();
00354 
00355         // Performance
00356         if (!$myConfig->getConfigParam('bl_perfLoadAccessoires')) {
00357             return;
00358         }
00359 
00360         $sArticleId = oxDb::getDb()->quote($sArticleId);
00361 
00362         $oBaseObject = $this->getBaseObject();
00363         $sArticleTable = $oBaseObject->getViewName();
00364 
00365         $sSelect = "select $sArticleTable.* from oxaccessoire2article left join $sArticleTable on oxaccessoire2article.oxobjectid=$sArticleTable.oxid ";
00366         $sSelect .= "where oxaccessoire2article.oxarticlenid = $sArticleId ";
00367         $sSelect .= " and $sArticleTable.oxid is not null and " . $oBaseObject->getSqlActiveSnippet();
00368         //sorting articles
00369         $sSelect .= " order by oxaccessoire2article.oxsort";
00370 
00371         $this->selectString($sSelect);
00372     }
00373 
00380     public function loadCategoryIds($sCatId, $aSessionFilter)
00381     {
00382         $sArticleTable = $this->getBaseObject()->getViewName();
00383         $sSelect = $this->_getCategorySelect($sArticleTable . '.oxid as oxid', $sCatId, $aSessionFilter);
00384 
00385         $this->_createIdListFromSql($sSelect);
00386     }
00387 
00397     public function loadCategoryArticles($sCatId, $aSessionFilter, $iLimit = null)
00398     {
00399         $sArticleFields = $this->getBaseObject()->getSelectFields();
00400 
00401         $sSelect = $this->_getCategorySelect($sArticleFields, $sCatId, $aSessionFilter);
00402 
00403         // calc count - we can not use count($this) here as we might have paging enabled
00404         // #1970C - if any filters are used, we can not use cached category article count
00405         $iArticleCount = null;
00406         if ($aSessionFilter) {
00407             $iArticleCount = oxDb::getDb()->getOne($this->_getCategoryCountSelect($sCatId, $aSessionFilter));
00408         }
00409 
00410         if ($iLimit = (int) $iLimit) {
00411             $sSelect .= " LIMIT $iLimit";
00412         }
00413 
00414         $this->selectString($sSelect);
00415 
00416         if ($iArticleCount !== null) {
00417             return $iArticleCount;
00418         }
00419 
00420         // this select is FAST so no need to hazzle here with getNrOfArticles()
00421         return oxRegistry::get("oxUtilsCount")->getCatArticleCount($sCatId);
00422     }
00423 
00430     public function loadRecommArticles($sRecommId, $sArticlesFilter = null)
00431     {
00432         $sSelect = $this->_getArticleSelect($sRecommId, $sArticlesFilter);
00433         $this->selectString($sSelect);
00434     }
00435 
00442     public function loadRecommArticleIds($sRecommId, $sArticlesFilter)
00443     {
00444         $sSelect = $this->_getArticleSelect($sRecommId, $sArticlesFilter);
00445 
00446         $sArtView = getViewName('oxarticles');
00447         $sPartial = substr($sSelect, strpos($sSelect, ' from '));
00448         $sSelect = "select distinct $sArtView.oxid $sPartial ";
00449 
00450         $this->_createIdListFromSql($sSelect);
00451     }
00452 
00461     protected function _getArticleSelect($sRecommId, $sArticlesFilter = null)
00462     {
00463         $sRecommId = oxDb::getDb()->quote($sRecommId);
00464 
00465         $sArtView = getViewName('oxarticles');
00466         $sSelect = "select distinct $sArtView.*, oxobject2list.oxdesc from oxobject2list ";
00467         $sSelect .= "left join $sArtView on oxobject2list.oxobjectid = $sArtView.oxid ";
00468         $sSelect .= "where (oxobject2list.oxlistid = $sRecommId) " . $sArticlesFilter;
00469 
00470         return $sSelect;
00471     }
00472 
00481     public function loadSearchIds($sSearchStr = '', $sSearchCat = '', $sSearchVendor = '', $sSearchManufacturer = '')
00482     {
00483         $oDb = oxDb::getDb();
00484         $sSearchCat = $sSearchCat ? $sSearchCat : null;
00485         $sSearchVendor = $sSearchVendor ? $sSearchVendor : null;
00486         $sSearchManufacturer = $sSearchManufacturer ? $sSearchManufacturer : null;
00487 
00488         $sWhere = null;
00489 
00490         if ($sSearchStr) {
00491             $sWhere = $this->_getSearchSelect($sSearchStr);
00492         }
00493 
00494         $sArticleTable = getViewName('oxarticles');
00495 
00496         // longdesc field now is kept on different table
00497         $sDescTable = '';
00498         $sDescJoin = '';
00499         if (is_array($aSearchCols = $this->getConfig()->getConfigParam('aSearchCols'))) {
00500             if (in_array('oxlongdesc', $aSearchCols) || in_array('oxtags', $aSearchCols)) {
00501                 $sDescView = getViewName('oxartextends');
00502                 $sDescJoin = " LEFT JOIN $sDescView ON {$sDescView}.oxid={$sArticleTable}.oxid ";
00503             }
00504         }
00505 
00506         // load the articles
00507         $sSelect = "select $sArticleTable.oxid, $sArticleTable.oxtimestamp from $sArticleTable $sDescJoin where ";
00508 
00509         // must be additional conditions in select if searching in category
00510         if ($sSearchCat) {
00511             $sO2CView = getViewName('oxobject2category');
00512             $sSelect = "select $sArticleTable.oxid from $sO2CView as oxobject2category, $sArticleTable $sDescJoin ";
00513             $sSelect .= "where oxobject2category.oxcatnid=" . $oDb->quote($sSearchCat) . " and oxobject2category.oxobjectid=$sArticleTable.oxid and ";
00514         }
00515         $sSelect .= $this->getBaseObject()->getSqlActiveSnippet();
00516         $sSelect .= " and $sArticleTable.oxparentid = '' and $sArticleTable.oxissearch = 1 ";
00517 
00518         // #671
00519         if ($sSearchVendor) {
00520             $sSelect .= " and $sArticleTable.oxvendorid = " . $oDb->quote($sSearchVendor) . " ";
00521         }
00522 
00523         if ($sSearchManufacturer) {
00524             $sSelect .= " and $sArticleTable.oxmanufacturerid = " . $oDb->quote($sSearchManufacturer) . " ";
00525         }
00526         $sSelect .= $sWhere;
00527 
00528         if ($this->_sCustomSorting) {
00529             $sSelect .= " order by {$this->_sCustomSorting} ";
00530         }
00531 
00532         $this->_createIdListFromSql($sSelect);
00533     }
00534 
00541     public function loadPriceIds($dPriceFrom, $dPriceTo)
00542     {
00543         $sSelect = $this->_getPriceSelect($dPriceFrom, $dPriceTo);
00544         $this->_createIdListFromSql($sSelect);
00545     }
00546 
00557     public function loadPriceArticles($dPriceFrom, $dPriceTo, $oCategory = null)
00558     {
00559         $sSelect = $this->_getPriceSelect($dPriceFrom, $dPriceTo);
00560 
00561         startProfile("loadPriceArticles");
00562         $this->selectString($sSelect);
00563         stopProfile("loadPriceArticles");
00564 
00565         if (!$oCategory) {
00566             return $this->count();
00567         }
00568 
00569         return oxRegistry::get("oxUtilsCount")->getPriceCatArticleCount($oCategory->getId(), $dPriceFrom, $dPriceTo);
00570     }
00571 
00577     public function loadVendorIDs($sVendorId)
00578     {
00579         $sSelect = $this->_getVendorSelect($sVendorId);
00580         $this->_createIdListFromSql($sSelect);
00581     }
00582 
00588     public function loadManufacturerIDs($sManufacturerId)
00589     {
00590         $sSelect = $this->_getManufacturerSelect($sManufacturerId);
00591         $this->_createIdListFromSql($sSelect);
00592     }
00593 
00603     public function loadVendorArticles($sVendorId, $oVendor = null)
00604     {
00605         $sSelect = $this->_getVendorSelect($sVendorId);
00606         $this->selectString($sSelect);
00607 
00608         return oxRegistry::get("oxUtilsCount")->getVendorArticleCount($sVendorId);
00609     }
00610 
00620     public function loadManufacturerArticles($sManufacturerId, $oManufacturer = null)
00621     {
00622         $sSelect = $this->_getManufacturerSelect($sManufacturerId);
00623         $this->selectString($sSelect);
00624 
00625         return oxRegistry::get("oxUtilsCount")->getManufacturerArticleCount($sManufacturerId);
00626     }
00627 
00636     public function loadTagArticles($sTag, $iLang)
00637     {
00638         $oListObject = $this->getBaseObject();
00639         $sArticleTable = $oListObject->getViewName();
00640         $sArticleFields = $oListObject->getSelectFields();
00641         $sViewName = getViewName('oxartextends', $iLang);
00642 
00643         $oTag = oxNew('oxtag', $sTag);
00644         $oTag->addUnderscores();
00645         $sTag = $oTag->get();
00646 
00647         $sQ = "select {$sArticleFields} from {$sViewName} inner join {$sArticleTable} on " .
00648               "{$sArticleTable}.oxid = {$sViewName}.oxid where {$sArticleTable}.oxparentid = '' AND match ( {$sViewName}.oxtags ) " .
00649               "against( " . oxDb::getDb()->quote("\"" . $sTag . "\"") . " IN BOOLEAN MODE )";
00650 
00651         // checking stock etc
00652         if (($sActiveSnippet = $oListObject->getSqlActiveSnippet())) {
00653             $sQ .= " and {$sActiveSnippet}";
00654         }
00655 
00656         if ($this->_sCustomSorting) {
00657             $sSort = $this->_sCustomSorting;
00658             if (strpos($sSort, '.') === false) {
00659                 $sSort = $sArticleTable . '.' . $sSort;
00660             }
00661             $sQ .= " order by $sSort ";
00662         }
00663 
00664         $this->selectString($sQ);
00665 
00666         // calc count - we can not use count($this) here as we might have paging enabled
00667         return oxRegistry::get("oxUtilsCount")->getTagArticleCount($sTag, $iLang);
00668     }
00669 
00678     public function getTagArticleIds($sTag, $iLang)
00679     {
00680         $oListObject = $this->getBaseObject();
00681         $sArticleTable = $oListObject->getViewName();
00682         $sViewName = getViewName('oxartextends', $iLang);
00683 
00684         $oTag = oxNew('oxtag', $sTag);
00685         $oTag->addUnderscores();
00686         $sTag = $oTag->get();
00687 
00688         $sQ = "select {$sViewName}.oxid from {$sViewName} inner join {$sArticleTable} on " .
00689               "{$sArticleTable}.oxid = {$sViewName}.oxid where {$sArticleTable}.oxparentid = '' and {$sArticleTable}.oxissearch = 1 and " .
00690               "match ( {$sViewName}.oxtags ) " .
00691               "against( " . oxDb::getDb()->quote("\"" . $sTag . "\"") . " IN BOOLEAN MODE )";
00692 
00693         // checking stock etc
00694         if (($sActiveSnippet = $oListObject->getSqlActiveSnippet())) {
00695             $sQ .= " and {$sActiveSnippet}";
00696         }
00697 
00698         if ($this->_sCustomSorting) {
00699             $sSort = $this->_sCustomSorting;
00700             if (strpos($sSort, '.') === false) {
00701                 $sSort = $sArticleTable . '.' . $sSort;
00702             }
00703             $sQ .= " order by $sSort ";
00704         }
00705 
00706         return $this->_createIdListFromSql($sQ);
00707     }
00708 
00716     public function loadIds($aIds)
00717     {
00718         if (!count($aIds)) {
00719             $this->clear();
00720 
00721             return;
00722         }
00723 
00724         foreach ($aIds as $iKey => $sVal) {
00725             $aIds[$iKey] = oxDb::getInstance()->escapeString($sVal);
00726         }
00727 
00728         $oBaseObject = $this->getBaseObject();
00729         $sArticleTable = $oBaseObject->getViewName();
00730         $sArticleFields = $oBaseObject->getSelectFields();
00731 
00732         $sSelect = "select $sArticleFields from $sArticleTable ";
00733         $sSelect .= "where $sArticleTable.oxid in ( '" . implode("','", $aIds) . "' ) and ";
00734         $sSelect .= $oBaseObject->getSqlActiveSnippet();
00735 
00736         $this->selectString($sSelect);
00737     }
00738 
00746     public function loadOrderArticles($aOrders)
00747     {
00748         if (!count($aOrders)) {
00749             $this->clear();
00750 
00751             return;
00752         }
00753 
00754         foreach ($aOrders as $iKey => $oOrder) {
00755             $aOrdersIds[] = $oOrder->getId();
00756         }
00757 
00758         $oBaseObject = $this->getBaseObject();
00759         $sArticleTable = $oBaseObject->getViewName();
00760         $sArticleFields = $oBaseObject->getSelectFields();
00761         $sArticleFields = str_replace("`$sArticleTable`.`oxid`", "`oxorderarticles`.`oxartid` AS `oxid`", $sArticleFields);
00762 
00763         $sSelect = "SELECT $sArticleFields FROM oxorderarticles ";
00764         $sSelect .= "left join $sArticleTable on oxorderarticles.oxartid = $sArticleTable.oxid ";
00765         $sSelect .= "WHERE oxorderarticles.oxorderid IN ( '" . implode("','", $aOrdersIds) . "' ) ";
00766         $sSelect .= "order by $sArticleTable.oxid ";
00767 
00768         $this->selectString($sSelect);
00769 
00770         // not active or not available products must not have button "tobasket"
00771         $sNow = date('Y-m-d H:i:s');
00772         foreach ($this as $oArticle) {
00773             if (!$oArticle->oxarticles__oxactive->value &&
00774                 ($oArticle->oxarticles__oxactivefrom->value > $sNow ||
00775                  $oArticle->oxarticles__oxactiveto->value < $sNow
00776                 )
00777             ) {
00778                 $oArticle->setBuyableState(false);
00779             }
00780         }
00781     }
00782 
00788     public function loadStockRemindProducts($aBasketContents)
00789     {
00790         if (is_array($aBasketContents) && count($aBasketContents)) {
00791             $oDb = oxDb::getDb();
00792             foreach ($aBasketContents as $oBasketItem) {
00793                 $aArtIds[] = $oDb->quote($oBasketItem->getProductId());
00794             }
00795 
00796             $oBaseObject = $this->getBaseObject();
00797 
00798             $sFieldNames = $oBaseObject->getSelectFields();
00799             $sTable = $oBaseObject->getViewName();
00800 
00801             // fetching actual db stock state and reminder status
00802             $sQ = "select {$sFieldNames} from {$sTable} where {$sTable}.oxid in ( " . implode(",", $aArtIds) . " ) and
00803                           oxremindactive = '1' and oxstock <= oxremindamount";
00804             $this->selectString($sQ);
00805 
00806             // updating stock reminder state
00807             if ($this->count()) {
00808                 $sQ = "update {$sTable} set oxremindactive = '2' where {$sTable}.oxid in ( " . implode(",", $aArtIds) . " ) and
00809                               oxremindactive = '1' and oxstock <= oxremindamount";
00810                 $oDb->execute($sQ);
00811             }
00812         }
00813     }
00814 
00820     public function renewPriceUpdateTime()
00821     {
00822         $oDb = oxDb::getDb();
00823 
00824         // fetching next update time
00825         $sQ = "select unix_timestamp( oxupdatepricetime ) from %s where oxupdatepricetime > 0 order by oxupdatepricetime asc";
00826         $iTimeToUpdate = $oDb->getOne(sprintf($sQ, "`oxarticles`"), false, false);
00827 
00828 
00829         // next day?
00830         $iCurrUpdateTime = oxRegistry::get("oxUtilsDate")->getTime();
00831         $iNextUpdateTime = $iCurrUpdateTime + 3600 * 24;
00832 
00833         // renew next update time
00834         if (!$iTimeToUpdate || $iTimeToUpdate > $iNextUpdateTime) {
00835             $iTimeToUpdate = $iNextUpdateTime;
00836         }
00837 
00838         $this->getConfig()->saveShopConfVar("int", "iTimeToUpdatePrices", $iTimeToUpdate);
00839 
00840         return $iTimeToUpdate;
00841     }
00842 
00851     public function updateUpcomingPrices($blForceUpdate = false)
00852     {
00853         $blUpdated = false;
00854 
00855         if ($blForceUpdate || $this->_canUpdatePrices()) {
00856 
00857             $oDb = oxDb::getDb();
00858 
00859             $oDb->startTransaction();
00860 
00861             $sCurrUpdateTime = date("Y-m-d H:i:s", oxRegistry::get("oxUtilsDate")->getTime());
00862 
00863             // Collect article id's for later recalculation.
00864             $sQ = "SELECT `oxid` FROM `oxarticles`
00865                    WHERE `oxupdatepricetime` > 0 AND `oxupdatepricetime` <= '{$sCurrUpdateTime}'";
00866             $aUpdatedArticleIds = $oDb->getCol($sQ, false, false);
00867 
00868             // updating oxarticles
00869             $sQ = "UPDATE %s SET
00870                        `oxprice`  = IF( `oxupdateprice` > 0, `oxupdateprice`, `oxprice` ),
00871                        `oxpricea` = IF( `oxupdatepricea` > 0, `oxupdatepricea`, `oxpricea` ),
00872                        `oxpriceb` = IF( `oxupdatepriceb` > 0, `oxupdatepriceb`, `oxpriceb` ),
00873                        `oxpricec` = IF( `oxupdatepricec` > 0, `oxupdatepricec`, `oxpricec` ),
00874                        `oxupdatepricetime` = 0,
00875                        `oxupdateprice`     = 0,
00876                        `oxupdatepricea`    = 0,
00877                        `oxupdatepriceb`    = 0,
00878                        `oxupdatepricec`    = 0
00879                    WHERE
00880                        `oxupdatepricetime` > 0 AND
00881                        `oxupdatepricetime` <= '{$sCurrUpdateTime}'";
00882             $blUpdated = $oDb->execute(sprintf($sQ, "`oxarticles`"));
00883 
00884 
00885             // renew update time in case update is not forced
00886             if (!$blForceUpdate) {
00887                 $this->renewPriceUpdateTime();
00888             }
00889 
00890             $oDb->commitTransaction();
00891 
00892             // recalculate oxvarminprice and oxvarmaxprice for parent
00893             if (is_array($aUpdatedArticleIds)) {
00894                 foreach ($aUpdatedArticleIds as $sArticleId) {
00895                     $oArticle = oxNew('oxarticle');
00896                     $oArticle->load($sArticleId);
00897                     $oArticle->onChange();
00898                 }
00899             }
00900 
00901         }
00902 
00903         return $blUpdated;
00904     }
00905 
00911     protected function _createIdListFromSql($sSql)
00912     {
00913         $rs = oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->select($sSql);
00914         if ($rs != false && $rs->recordCount() > 0) {
00915             while (!$rs->EOF) {
00916                 $rs->fields = array_change_key_case($rs->fields, CASE_LOWER);
00917                 $this[$rs->fields['oxid']] = $rs->fields['oxid']; //only the oxid
00918                 $rs->moveNext();
00919             }
00920         }
00921     }
00922 
00931     protected function _getFilterIdsSql($sCatId, $aFilter)
00932     {
00933         $sO2CView = getViewName('oxobject2category');
00934         $sO2AView = getViewName('oxobject2attribute');
00935 
00936         $sFilter = '';
00937         $iCnt = 0;
00938 
00939         $oDb = oxDb::getDb();
00940         foreach ($aFilter as $sAttrId => $sValue) {
00941             if ($sValue) {
00942                 if ($sFilter) {
00943                     $sFilter .= ' or ';
00944                 }
00945                 $sValue = $oDb->quote($sValue);
00946                 $sAttrId = $oDb->quote($sAttrId);
00947 
00948                 $sFilter .= "( oa.oxattrid = {$sAttrId} and oa.oxvalue = {$sValue} )";
00949                 $iCnt++;
00950             }
00951         }
00952         if ($sFilter) {
00953             $sFilter = "WHERE $sFilter ";
00954         }
00955 
00956         $sFilterSelect = "select oc.oxobjectid as oxobjectid, count(*) as cnt from ";
00957         $sFilterSelect .= "(SELECT * FROM $sO2CView WHERE $sO2CView.oxcatnid = '$sCatId' GROUP BY $sO2CView.oxobjectid, $sO2CView.oxcatnid) as oc ";
00958         $sFilterSelect .= "INNER JOIN $sO2AView as oa ON ( oa.oxobjectid = oc.oxobjectid ) ";
00959 
00960         return $sFilterSelect . "{$sFilter} GROUP BY oa.oxobjectid HAVING cnt = $iCnt ";
00961     }
00962 
00971     protected function _getFilterSql($sCatId, $aFilter)
00972     {
00973         $sArticleTable = getViewName('oxarticles');
00974         $aIds = oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->getAll($this->_getFilterIdsSql($sCatId, $aFilter));
00975         $sIds = '';
00976 
00977         if ($aIds) {
00978             foreach ($aIds as $aArt) {
00979                 if ($sIds) {
00980                     $sIds .= ', ';
00981                 }
00982                 $sIds .= oxDb::getDb()->quote(current($aArt));
00983             }
00984 
00985             if ($sIds) {
00986                 $sFilterSql = " and $sArticleTable.oxid in ( $sIds ) ";
00987             }
00988             // bug fix #0001695: if no articles found return false
00989         } elseif (!(current($aFilter) == '' && count(array_unique($aFilter)) == 1)) {
00990             $sFilterSql = " and false ";
00991         }
00992 
00993         return $sFilterSql;
00994     }
00995 
01005     protected function _getCategorySelect($sFields, $sCatId, $aSessionFilter)
01006     {
01007         $sArticleTable = getViewName('oxarticles');
01008         $sO2CView = getViewName('oxobject2category');
01009 
01010         // ----------------------------------
01011         // sorting
01012         $sSorting = '';
01013         if ($this->_sCustomSorting) {
01014             $sSorting = " {$this->_sCustomSorting} , ";
01015         }
01016 
01017         // ----------------------------------
01018         // filtering ?
01019         $sFilterSql = '';
01020         $iLang = oxRegistry::getLang()->getBaseLanguage();
01021         if ($aSessionFilter && isset($aSessionFilter[$sCatId][$iLang])) {
01022             $sFilterSql = $this->_getFilterSql($sCatId, $aSessionFilter[$sCatId][$iLang]);
01023         }
01024 
01025         $oDb = oxDb::getDb();
01026 
01027         $sSelect = "SELECT $sFields, $sArticleTable.oxtimestamp FROM $sO2CView as oc left join $sArticleTable
01028                     ON $sArticleTable.oxid = oc.oxobjectid
01029                     WHERE " . $this->getBaseObject()->getSqlActiveSnippet() . " and $sArticleTable.oxparentid = ''
01030                     and oc.oxcatnid = " . $oDb->quote($sCatId) . " $sFilterSql ORDER BY $sSorting oc.oxpos, oc.oxobjectid ";
01031 
01032         return $sSelect;
01033     }
01034 
01043     protected function _getCategoryCountSelect($sCatId, $aSessionFilter)
01044     {
01045         $sArticleTable = getViewName('oxarticles');
01046         $sO2CView = getViewName('oxobject2category');
01047 
01048 
01049         // ----------------------------------
01050         // filtering ?
01051         $sFilterSql = '';
01052         $iLang = oxRegistry::getLang()->getBaseLanguage();
01053         if ($aSessionFilter && isset($aSessionFilter[$sCatId][$iLang])) {
01054             $sFilterSql = $this->_getFilterSql($sCatId, $aSessionFilter[$sCatId][$iLang]);
01055         }
01056 
01057         $oDb = oxDb::getDb();
01058 
01059         $sSelect = "SELECT COUNT(*) FROM $sO2CView as oc left join $sArticleTable
01060                     ON $sArticleTable.oxid = oc.oxobjectid
01061                     WHERE " . $this->getBaseObject()->getSqlActiveSnippet() . " and $sArticleTable.oxparentid = ''
01062                     and oc.oxcatnid = " . $oDb->quote($sCatId) . " $sFilterSql ";
01063 
01064         return $sSelect;
01065     }
01066 
01074     protected function _getSearchSelect($sSearchString)
01075     {
01076         // check if it has string at all
01077         if (!$sSearchString || !str_replace(' ', '', $sSearchString)) {
01078             return '';
01079         }
01080 
01081         $oDb = oxDb::getDb();
01082         $myConfig = $this->getConfig();
01083         $myUtils = oxRegistry::getUtils();
01084         $sArticleTable = $this->getBaseObject()->getViewName();
01085 
01086         $aSearch = explode(' ', $sSearchString);
01087 
01088         $sSearch = ' and ( ';
01089         $blSep = false;
01090 
01091         // #723
01092         if ($myConfig->getConfigParam('blSearchUseAND')) {
01093             $sSearchSep = ' and ';
01094         } else {
01095             $sSearchSep = ' or ';
01096         }
01097 
01098         $aSearchCols = $myConfig->getConfigParam('aSearchCols');
01099         $oBaseObject = $this->getBaseObject();
01100         $myUtilsString = oxRegistry::get("oxUtilsString");
01101         foreach ($aSearch as $sSearchString) {
01102 
01103             if (!strlen($sSearchString)) {
01104                 continue;
01105             }
01106 
01107             if ($blSep) {
01108                 $sSearch .= $sSearchSep;
01109             }
01110             $blSep2 = false;
01111             $sSearch .= '( ';
01112 
01113             $sUml = $myUtilsString->prepareStrForSearch($sSearchString);
01114             foreach ($aSearchCols as $sField) {
01115 
01116                 if ($blSep2) {
01117                     $sSearch .= ' or ';
01118                 }
01119 
01120                 // as long description now is on different table table must differ
01121                 if ($sField == 'oxlongdesc' || $sField == 'oxtags') {
01122                     $sSearchTable = getViewName('oxartextends');
01123                 } else {
01124                     $sSearchTable = $sArticleTable;
01125                 }
01126 
01127                 $sSearch .= $sSearchTable . '.' . $sField . ' like ' . $oDb->quote('%' . $sSearchString . '%') . ' ';
01128                 if ($sUml) {
01129                     $sSearch .= ' or ' . $sSearchTable . '.' . $sField . ' like ' . $oDb->quote('%' . $sUml . '%');
01130                 }
01131                 $blSep2 = true;
01132             }
01133             $sSearch .= ' ) ';
01134             $blSep = true;
01135         }
01136         $sSearch .= ' ) ';
01137 
01138         return $sSearch;
01139     }
01140 
01149     protected function _getPriceSelect($dPriceFrom, $dPriceTo)
01150     {
01151         $oBaseObject = $this->getBaseObject();
01152         $sArticleTable = $oBaseObject->getViewName();
01153         $sSelectFields = $oBaseObject->getSelectFields();
01154 
01155         $sSubSelect = "";
01156 
01157         $sSelect = "select {$sSelectFields} from {$sArticleTable} where oxvarminprice >= 0 ";
01158         $sSelect .= $dPriceTo ? "and oxvarminprice <= " . (double) $dPriceTo . " " : " ";
01159         $sSelect .= $dPriceFrom ? "and oxvarminprice  >= " . (double) $dPriceFrom . " " : " ";
01160 
01161         $sSelect .= " and " . $oBaseObject->getSqlActiveSnippet() . " and {$sArticleTable}.oxissearch = 1";
01162 
01163         if (!$this->_sCustomSorting) {
01164             $sSelect .= " order by {$sArticleTable}.oxvarminprice asc , {$sArticleTable}.oxid";
01165         } else {
01166             $sSelect .= " order by {$this->_sCustomSorting}, {$sArticleTable}.oxid ";
01167         }
01168 
01169         return $sSelect;
01170     }
01171 
01179     protected function _getVendorSelect($sVendorId)
01180     {
01181         $sArticleTable = getViewName('oxarticles');
01182         $oBaseObject = $this->getBaseObject();
01183         $sFieldNames = $oBaseObject->getSelectFields();
01184         $sSelect = "select $sFieldNames from $sArticleTable ";
01185         $sSelect .= "where $sArticleTable.oxvendorid = " . oxDb::getDb()->quote($sVendorId) . " ";
01186         $sSelect .= " and " . $oBaseObject->getSqlActiveSnippet() . " and $sArticleTable.oxparentid = ''  ";
01187 
01188         if ($this->_sCustomSorting) {
01189             $sSelect .= " ORDER BY {$this->_sCustomSorting} ";
01190         }
01191 
01192         return $sSelect;
01193     }
01194 
01202     protected function _getManufacturerSelect($sManufacturerId)
01203     {
01204         $sArticleTable = getViewName('oxarticles');
01205         $oBaseObject = $this->getBaseObject();
01206         $sFieldNames = $oBaseObject->getSelectFields();
01207         $sSelect = "select $sFieldNames from $sArticleTable ";
01208         $sSelect .= "where $sArticleTable.oxmanufacturerid = " . oxDb::getDb()->quote($sManufacturerId) . " ";
01209         $sSelect .= " and " . $oBaseObject->getSqlActiveSnippet() . " and $sArticleTable.oxparentid = ''  ";
01210 
01211         if ($this->_sCustomSorting) {
01212             $sSelect .= " ORDER BY {$this->_sCustomSorting} ";
01213         }
01214 
01215         return $sSelect;
01216     }
01217 
01223     protected function _canUpdatePrices()
01224     {
01225         $oConfig = $this->getConfig();
01226         $blCan = false;
01227 
01228         // crontab is off?
01229         if (!$oConfig->getConfigParam("blUseCron")) {
01230             $iTimeToUpdate = $oConfig->getConfigParam("iTimeToUpdatePrices");
01231             if (!$iTimeToUpdate || $iTimeToUpdate <= oxRegistry::get("oxUtilsDate")->getTime()) {
01232                 $blCan = true;
01233             }
01234         }
01235 
01236         return $blCan;
01237     }
01238 }