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         $aResult = array();
00076 
00077         if ($aArticlesIds = $this->getSession()->getVariable('aHistoryArticles')) {
00078             $aResult = $aArticlesIds;
00079         } elseif ( $sArticlesIds = oxRegistry::get("oxUtilsServer")->getOxCookie('aHistoryArticles')) {
00080             $aResult = explode('|', $sArticlesIds);
00081         }
00082 
00083         return $aResult;
00084     }
00085 
00093     public function setHistoryArticles($aArticlesIds)
00094     {
00095         if ($this->getSession()->getId()) {
00096             $this->getSession()->setVariable('aHistoryArticles', $aArticlesIds);
00097             // clean cookie, if session started
00098             oxRegistry::get("oxUtilsServer")->setOxCookie('aHistoryArticles', '');
00099         } else {
00100             oxRegistry::get("oxUtilsServer")->setOxCookie('aHistoryArticles', implode('|', $aArticlesIds));
00101         }
00102     }
00103 
00113     public function loadHistoryArticles( $sArtId, $iCnt = 4 )
00114     {
00115         $aHistoryArticles = $this->getHistoryArticles();
00116         $aHistoryArticles[] = $sArtId;
00117 
00118         // removing dublicates
00119         $aHistoryArticles = array_unique( $aHistoryArticles );
00120         if ( count( $aHistoryArticles ) > ( $iCnt + 1 ) ) {
00121             array_shift( $aHistoryArticles );
00122         }
00123 
00124         $this->setHistoryArticles( $aHistoryArticles );
00125 
00126         //remove current article and return array
00127         //asignment =, not ==
00128         if ( ( $iCurrentArt = array_search( $sArtId, $aHistoryArticles ) ) !== false ) {
00129             unset( $aHistoryArticles[$iCurrentArt] );
00130         }
00131 
00132         $aHistoryArticles = array_values( $aHistoryArticles );
00133         $this->loadIds( $aHistoryArticles );
00134         $this->sortByIds( $aHistoryArticles );
00135     }
00136 
00144     public function sortByIds( $aIds )
00145     {
00146         $this->_aOrderMap = array_flip( $aIds );
00147         uksort($this->_aArray, array($this, '_sortByOrderMapCallback'));
00148     }
00149 
00160     protected function _sortByOrderMapCallback($key1, $key2)
00161     {
00162         if (isset($this->_aOrderMap[$key1])) {
00163             if (isset($this->_aOrderMap[$key2])) {
00164                 $iDiff = $this->_aOrderMap[$key2] - $this->_aOrderMap[$key1];
00165                 if ($iDiff > 0) {
00166                     return -1;
00167                 } elseif ($iDiff < 0) {
00168                     return 1;
00169                 } else {
00170                     return 0;
00171                 }
00172             } else {
00173                 // first is here, but 2nd is not - 1st gets more priority
00174                 return -1;
00175             }
00176         } elseif (isset($this->_aOrderMap[$key2])) {
00177             // first is not here, but 2nd is - 2nd gets more priority
00178             return 1;
00179         } else {
00180             // both unset, equal
00181             return 0;
00182         }
00183     }
00184 
00192     public function loadNewestArticles( $iLimit = null )
00193     {
00194         //has module?
00195         $myConfig = $this->getConfig();
00196 
00197         if ( !$myConfig->getConfigParam( 'bl_perfLoadPriceForAddList' ) ) {
00198             $this->getBaseObject()->disablePriceLoad();
00199         }
00200 
00201         $this->_aArray = array();
00202         switch( $myConfig->getConfigParam( 'iNewestArticlesMode' ) ) {
00203             case 0:
00204                 // switched off, do nothing
00205                 break;
00206             case 1:
00207                 // manually entered
00208                 $this->loadActionArticles( 'oxnewest', $iLimit );
00209                 break;
00210             case 2:
00211                 $sArticleTable = getViewName('oxarticles');
00212                 if ( $myConfig->getConfigParam( 'blNewArtByInsert' ) ) {
00213                     $sType = 'oxinsert';
00214                 } else {
00215                     $sType = 'oxtimestamp';
00216                 }
00217                 $sSelect  = "select * from $sArticleTable ";
00218                 $sSelect .= "where oxparentid = '' and ".$this->getBaseObject()->getSqlActiveSnippet()." and oxissearch = 1 order by $sType desc ";
00219                 if (!($iLimit = (int) $iLimit)) {
00220                     $iLimit = $myConfig->getConfigParam( 'iNrofNewcomerArticles' );
00221                 }
00222                 $sSelect .= "limit " . $iLimit;
00223 
00224                 $this->selectString($sSelect);
00225                 break;
00226         }
00227 
00228     }
00229 
00237     public function loadTop5Articles( $iLimit = null )
00238     {
00239         //has module?
00240         $myConfig = $this->getConfig();
00241 
00242         if ( !$myConfig->getConfigParam( 'bl_perfLoadPriceForAddList' ) ) {
00243             $this->getBaseObject()->disablePriceLoad();
00244         }
00245 
00246         switch( $myConfig->getConfigParam( 'iTop5Mode' ) ) {
00247             case 0:
00248                 // switched off, do nothing
00249                 break;
00250             case 1:
00251                 // manually entered
00252                 $this->loadActionArticles( 'oxtop5', $iLimit );
00253                 break;
00254             case 2:
00255                 $sArticleTable = getViewName('oxarticles');
00256 
00257                 //by default limit 5
00258                 $sLimit = ( $iLimit > 0 ) ? "limit " . $iLimit : 'limit 5';
00259 
00260                 $sSelect  = "select * from $sArticleTable ";
00261                 $sSelect .= "where ".$this->getBaseObject()->getSqlActiveSnippet()." and $sArticleTable.oxissearch = 1 ";
00262                 $sSelect .= "and $sArticleTable.oxparentid = '' and $sArticleTable.oxsoldamount>0 ";
00263                 $sSelect .= "order by $sArticleTable.oxsoldamount desc $sLimit";
00264 
00265                 $this->selectString($sSelect);
00266                 break;
00267         }
00268     }
00269 
00278     public function loadActionArticles( $sActionID, $iLimit = null )
00279     {
00280         // Performance
00281         if ( !trim( $sActionID) ) {
00282             return;
00283         }
00284 
00285         $sShopID        = $this->getConfig()->getShopId();
00286         $sActionID      = oxDb::getDb()->quote(strtolower( $sActionID));
00287 
00288         //echo $sSelect;
00289         $oBaseObject    = $this->getBaseObject();
00290         $sArticleTable  = $oBaseObject->getViewName();
00291         $sArticleFields = $oBaseObject->getSelectFields();
00292 
00293         $oBase = oxNew("oxactions");
00294         $sActiveSql = $oBase->getSqlActiveSnippet();
00295         $sViewName = $oBase->getViewName();
00296 
00297         $sLimit = ( $iLimit > 0 ) ? "limit " . $iLimit : '';
00298 
00299         $sSelect = "select $sArticleFields from oxactions2article
00300                               left join $sArticleTable on $sArticleTable.oxid = oxactions2article.oxartid
00301                               left join $sViewName on $sViewName.oxid = oxactions2article.oxactionid
00302                               where oxactions2article.oxshopid = '$sShopID' and oxactions2article.oxactionid = $sActionID and $sActiveSql
00303                               and $sArticleTable.oxid is not null and " .$oBaseObject->getSqlActiveSnippet(). "
00304                               order by oxactions2article.oxsort $sLimit";
00305 
00306         $this->selectString( $sSelect );
00307     }
00308 
00309 
00320     public function loadAktionArticles( $sActionID, $iLimit = null )
00321     {
00322         $this->loadActionArticles( $sActionID, $iLimit = null );
00323 
00324     }
00325 
00333     public function loadArticleCrossSell( $sArticleId )
00334     {
00335         $myConfig = $this->getConfig();
00336 
00337         // Performance
00338         if ( !$myConfig->getConfigParam( 'bl_perfLoadCrossselling' ) ) {
00339             return null;
00340         }
00341 
00342         $oBaseObject   = $this->getBaseObject();
00343         $sArticleTable = $oBaseObject->getViewName();
00344 
00345         $sArticleId = oxDb::getDb()->quote($sArticleId);
00346 
00347         $sSelect  = "SELECT $sArticleTable.*
00348                         FROM $sArticleTable INNER JOIN oxobject2article ON oxobject2article.oxobjectid=$sArticleTable.oxid ";
00349         $sSelect .= "WHERE oxobject2article.oxarticlenid = $sArticleId ";
00350         $sSelect .= " AND " .$oBaseObject->getSqlActiveSnippet();
00351 
00352         // #525 bidirectional cross selling
00353         if ( $myConfig->getConfigParam( 'blBidirectCross' ) ) {
00354             $sSelect = "
00355                 (
00356                     SELECT $sArticleTable.* FROM $sArticleTable
00357                         INNER JOIN oxobject2article AS O2A1 on
00358                             ( O2A1.oxobjectid = $sArticleTable.oxid AND O2A1.oxarticlenid = $sArticleId )
00359                     WHERE 1
00360                     AND " . $oBaseObject->getSqlActiveSnippet() . "
00361                     AND ($sArticleTable.oxid != $sArticleId)
00362                 )
00363                 UNION
00364                 (
00365                     SELECT $sArticleTable.* FROM $sArticleTable
00366                         INNER JOIN oxobject2article AS O2A2 ON
00367                             ( O2A2.oxarticlenid = $sArticleTable.oxid AND O2A2.oxobjectid = $sArticleId )
00368                     WHERE 1
00369                     AND " . $oBaseObject->getSqlActiveSnippet() . "
00370                     AND ($sArticleTable.oxid != $sArticleId)
00371                 )";
00372         }
00373 
00374         $this->setSqlLimit( 0, $myConfig->getConfigParam( 'iNrofCrossellArticles' ));
00375         $this->selectString( $sSelect );
00376     }
00377 
00385     public function loadArticleAccessoires( $sArticleId )
00386     {
00387         $myConfig = $this->getConfig();
00388 
00389         // Performance
00390         if ( !$myConfig->getConfigParam( 'bl_perfLoadAccessoires' ) ) {
00391             return;
00392         }
00393 
00394         $sArticleId = oxDb::getDb()->quote($sArticleId);
00395 
00396         $oBaseObject   = $this->getBaseObject();
00397         $sArticleTable = $oBaseObject->getViewName();
00398 
00399         $sSelect  = "select $sArticleTable.* from oxaccessoire2article left join $sArticleTable on oxaccessoire2article.oxobjectid=$sArticleTable.oxid ";
00400         $sSelect .= "where oxaccessoire2article.oxarticlenid = $sArticleId ";
00401         $sSelect .= " and $sArticleTable.oxid is not null and " .$oBaseObject->getSqlActiveSnippet();
00402         //sorting articles
00403         $sSelect .= " order by oxaccessoire2article.oxsort";
00404 
00405         $this->selectString( $sSelect );
00406     }
00407 
00416     public function loadCategoryIds( $sCatId, $aSessionFilter )
00417     {
00418         $sArticleTable = $this->getBaseObject()->getViewName();
00419         $sSelect = $this->_getCategorySelect( $sArticleTable.'.oxid as oxid', $sCatId, $aSessionFilter );
00420 
00421         $this->_createIdListFromSql( $sSelect );
00422     }
00423 
00433     public function loadCategoryArticles( $sCatId, $aSessionFilter, $iLimit = null )
00434     {
00435         $sArticleFields = $this->getBaseObject()->getSelectFields();
00436 
00437         $sSelect = $this->_getCategorySelect( $sArticleFields, $sCatId, $aSessionFilter );
00438 
00439         // calc count - we can not use count($this) here as we might have paging enabled
00440         // #1970C - if any filters are used, we can not use cached category article count
00441         $iArticleCount = null;
00442         if ( $aSessionFilter) {
00443             $iArticleCount = oxDb::getDb()->getOne( $this->_getCategoryCountSelect( $sCatId, $aSessionFilter ) );
00444         }
00445 
00446         if ($iLimit = (int) $iLimit) {
00447             $sSelect .= " LIMIT $iLimit";
00448         }
00449 
00450         $this->selectString( $sSelect );
00451 
00452         if ( $iArticleCount !== null ) {
00453             return $iArticleCount;
00454         }
00455 
00456         // this select is FAST so no need to hazzle here with getNrOfArticles()
00457         return oxRegistry::get("oxUtilsCount")->getCatArticleCount( $sCatId );
00458     }
00459 
00468     public function loadRecommArticles( $sRecommId, $sArticlesFilter = null )
00469     {
00470         $sSelect = $this->_getArticleSelect( $sRecommId, $sArticlesFilter);
00471         $this->selectString( $sSelect );
00472     }
00473 
00482     public function loadRecommArticleIds( $sRecommId, $sArticlesFilter )
00483     {
00484         $sSelect = $this->_getArticleSelect( $sRecommId, $sArticlesFilter );
00485 
00486         $sArtView = getViewName( 'oxarticles' );
00487         $sPartial = substr( $sSelect, strpos( $sSelect, ' from ' ) );
00488         $sSelect  = "select distinct $sArtView.oxid $sPartial ";
00489 
00490         $this->_createIdListFromSql( $sSelect );
00491     }
00492 
00501     protected function _getArticleSelect( $sRecommId, $sArticlesFilter = null )
00502     {
00503         $sRecommId = oxDb::getDb()->quote($sRecommId);
00504 
00505         $sArtView = getViewName( 'oxarticles' );
00506         $sSelect  = "select distinct $sArtView.*, oxobject2list.oxdesc from oxobject2list ";
00507         $sSelect .= "left join $sArtView on oxobject2list.oxobjectid = $sArtView.oxid ";
00508         $sSelect .= "where (oxobject2list.oxlistid = $sRecommId) ".$sArticlesFilter;
00509 
00510         return $sSelect;
00511     }
00512 
00523     public function loadSearchIds( $sSearchStr = '', $sSearchCat = '', $sSearchVendor = '', $sSearchManufacturer = '' )
00524     {
00525         $oDb = oxDb::getDb();
00526         $sSearchCat    = $sSearchCat?$sSearchCat:null;
00527         $sSearchVendor = $sSearchVendor?$sSearchVendor:null;
00528         $sSearchManufacturer = $sSearchManufacturer?$sSearchManufacturer:null;
00529 
00530         $sWhere = null;
00531 
00532         if ( $sSearchStr ) {
00533             $sWhere = $this->_getSearchSelect( $sSearchStr );
00534         }
00535 
00536         $sArticleTable = getViewName('oxarticles');
00537 
00538         // longdesc field now is kept on different table
00539         $sDescJoin  = '';
00540         if ( is_array( $aSearchCols = $this->getConfig()->getConfigParam( 'aSearchCols' ) ) ) {
00541             if ( in_array( 'oxlongdesc', $aSearchCols ) || in_array( 'oxtags', $aSearchCols ) ) {
00542                 $sDescView  = getViewName( 'oxartextends' );
00543                 $sDescJoin  = " LEFT JOIN $sDescView ON {$sDescView}.oxid={$sArticleTable}.oxid ";
00544             }
00545         }
00546 
00547         // load the articles
00548         $sSelect  =  "select $sArticleTable.oxid, $sArticleTable.oxtimestamp from $sArticleTable $sDescJoin where ";
00549 
00550         // must be additional conditions in select if searching in category
00551         if ( $sSearchCat ) {
00552             $sO2CView = getViewName('oxobject2category');
00553             $sSelect  = "select $sArticleTable.oxid from $sO2CView as oxobject2category, $sArticleTable $sDescJoin ";
00554             $sSelect .= "where oxobject2category.oxcatnid=".$oDb->quote( $sSearchCat )." and oxobject2category.oxobjectid=$sArticleTable.oxid and ";
00555         }
00556         $sSelect .= $this->getBaseObject()->getSqlActiveSnippet();
00557         $sSelect .= " and $sArticleTable.oxparentid = '' and $sArticleTable.oxissearch = 1 ";
00558 
00559         // #671
00560         if ( $sSearchVendor ) {
00561             $sSelect .= " and $sArticleTable.oxvendorid = ".$oDb->quote( $sSearchVendor )." ";
00562         }
00563 
00564         if ( $sSearchManufacturer ) {
00565             $sSelect .= " and $sArticleTable.oxmanufacturerid = ".$oDb->quote( $sSearchManufacturer )." ";
00566         }
00567         $sSelect .= $sWhere;
00568 
00569         if ($this->_sCustomSorting) {
00570             $sSelect .= " order by {$this->_sCustomSorting} ";
00571         }
00572 
00573         $this->_createIdListFromSql($sSelect);
00574     }
00575 
00584     public function loadPriceIds( $dPriceFrom, $dPriceTo )
00585     {
00586         $sSelect = $this->_getPriceSelect( $dPriceFrom, $dPriceTo );
00587         $this->_createIdListFromSql( $sSelect );
00588     }
00589 
00600     public function loadPriceArticles( $dPriceFrom, $dPriceTo, $oCategory = null)
00601     {
00602         $sSelect =  $this->_getPriceSelect( $dPriceFrom, $dPriceTo );
00603 
00604         startProfile("loadPriceArticles");
00605         $this->selectString( $sSelect);
00606         stopProfile("loadPriceArticles");
00607 
00608         if ( !$oCategory ) {
00609             return $this->count();
00610         }
00611 
00612         return oxRegistry::get("oxUtilsCount")->getPriceCatArticleCount( $oCategory->getId(), $dPriceFrom, $dPriceTo );
00613     }
00614 
00622     public function loadVendorIDs( $sVendorId)
00623     {
00624         $sSelect = $this->_getVendorSelect($sVendorId);
00625         $this->_createIdListFromSql($sSelect);
00626     }
00627 
00635     public function loadManufacturerIDs( $sManufacturerId)
00636     {
00637         $sSelect = $this->_getManufacturerSelect($sManufacturerId);
00638         $this->_createIdListFromSql($sSelect);
00639     }
00640 
00650     public function loadVendorArticles( $sVendorId, $oVendor = null )
00651     {
00652         $sSelect = $this->_getVendorSelect($sVendorId);
00653         $this->selectString( $sSelect);
00654 
00655         return oxRegistry::get("oxUtilsCount")->getVendorArticleCount( $sVendorId );
00656     }
00657 
00667     public function loadManufacturerArticles( $sManufacturerId, $oManufacturer = null )
00668     {
00669         $sSelect = $this->_getManufacturerSelect($sManufacturerId);
00670         $this->selectString( $sSelect);
00671 
00672         return oxRegistry::get("oxUtilsCount")->getManufacturerArticleCount( $sManufacturerId );
00673     }
00674 
00683     public function loadTagArticles( $sTag, $iLang )
00684     {
00685         $oListObject = $this->getBaseObject();
00686         $sArticleTable = $oListObject->getViewName();
00687         $sArticleFields = $oListObject->getSelectFields();
00688         $sViewName = getViewName( 'oxartextends', $iLang );
00689 
00690         $oTag = oxNew( 'oxtag', $sTag );
00691         $oTag->addUnderscores();
00692         $sTag = $oTag->get();
00693 
00694         $sQ = "select {$sArticleFields} from {$sViewName} inner join {$sArticleTable} on ".
00695               "{$sArticleTable}.oxid = {$sViewName}.oxid where {$sArticleTable}.oxparentid = '' AND match ( {$sViewName}.oxtags ) ".
00696               "against( ".oxDb::getDb()->quote( "\"".$sTag."\"" )." IN BOOLEAN MODE )";
00697 
00698         // checking stock etc
00699         if ( ( $sActiveSnippet = $oListObject->getSqlActiveSnippet() ) ) {
00700             $sQ .= " and {$sActiveSnippet}";
00701         }
00702 
00703         if ( $this->_sCustomSorting ) {
00704             $sSort = $this->_sCustomSorting;
00705             if (strpos($sSort, '.') === false) {
00706                 $sSort = $sArticleTable.'.'.$sSort;
00707             }
00708             $sQ .= " order by $sSort ";
00709         }
00710 
00711         $this->selectString( $sQ );
00712 
00713         // calc count - we can not use count($this) here as we might have paging enabled
00714         return oxRegistry::get("oxUtilsCount")->getTagArticleCount( $sTag, $iLang );
00715     }
00716 
00725     public function getTagArticleIds( $sTag, $iLang )
00726     {
00727         $oListObject = $this->getBaseObject();
00728         $sArticleTable = $oListObject->getViewName();
00729         $sViewName = getViewName( 'oxartextends', $iLang );
00730 
00731         $oTag = oxNew( 'oxtag', $sTag );
00732         $oTag->addUnderscores();
00733         $sTag = $oTag->get();
00734 
00735         $sQ = "select {$sViewName}.oxid from {$sViewName} inner join {$sArticleTable} on ".
00736             "{$sArticleTable}.oxid = {$sViewName}.oxid where {$sArticleTable}.oxparentid = '' and {$sArticleTable}.oxissearch = 1 and ".
00737             "match ( {$sViewName}.oxtags ) ".
00738             "against( ".oxDb::getDb()->quote( "\"".$sTag."\"" )." IN BOOLEAN MODE )";
00739 
00740         // checking stock etc
00741         if ( ( $sActiveSnippet = $oListObject->getSqlActiveSnippet() ) ) {
00742             $sQ .= " and {$sActiveSnippet}";
00743         }
00744 
00745         if ( $this->_sCustomSorting ) {
00746             $sSort = $this->_sCustomSorting;
00747             if (strpos($sSort, '.') === false) {
00748                 $sSort = $sArticleTable.'.'.$sSort;
00749             }
00750             $sQ .= " order by $sSort ";
00751         }
00752 
00753         return $this->_createIdListFromSql( $sQ );
00754     }
00755 
00763     public function loadIds($aIds)
00764     {
00765         if (!count($aIds)) {
00766             $this->clear();
00767             return;
00768         }
00769 
00770         foreach ($aIds as $iKey => $sVal) {
00771             $aIds[$iKey] = oxDb::getInstance()->escapeString($sVal);
00772         }
00773 
00774         $oBaseObject    = $this->getBaseObject();
00775         $sArticleTable  = $oBaseObject->getViewName();
00776         $sArticleFields = $oBaseObject->getSelectFields();
00777 
00778         $sSelect  = "select $sArticleFields from $sArticleTable ";
00779         $sSelect .= "where $sArticleTable.oxid in ( '".implode("','", $aIds)."' ) and ";
00780         $sSelect .= $oBaseObject->getSqlActiveSnippet();
00781 
00782         $this->selectString($sSelect);
00783     }
00784 
00792     public function loadOrderArticles($aOrders)
00793     {
00794         if (!count($aOrders)) {
00795             $this->clear();
00796             return;
00797         }
00798 
00799         foreach ($aOrders as $oOrder) {
00800             $aOrdersIds[] = $oOrder->getId();
00801         }
00802 
00803         $oBaseObject    = $this->getBaseObject();
00804         $sArticleTable  = $oBaseObject->getViewName();
00805         $sArticleFields = $oBaseObject->getSelectFields();
00806         $sArticleFields = str_replace( "`$sArticleTable`.`oxid`", "`oxorderarticles`.`oxartid` AS `oxid`", $sArticleFields );
00807 
00808         $sSelect  = "SELECT $sArticleFields FROM oxorderarticles ";
00809         $sSelect .= "left join $sArticleTable on oxorderarticles.oxartid = $sArticleTable.oxid ";
00810         $sSelect .= "WHERE oxorderarticles.oxorderid IN ( '".implode("','", $aOrdersIds)."' ) ";
00811         $sSelect .= "order by $sArticleTable.oxid ";
00812 
00813         $this->selectString( $sSelect );
00814 
00815         // not active or not available products must not have button "tobasket"
00816         $sNow = date('Y-m-d H:i:s');
00817         foreach ( $this as $oArticle ) {
00818             if ( !$oArticle->oxarticles__oxactive->value  &&
00819              (  $oArticle->oxarticles__oxactivefrom->value > $sNow ||
00820                 $oArticle->oxarticles__oxactiveto->value < $sNow
00821              )) {
00822                 $oArticle->setBuyableState( false );
00823             }
00824         }
00825     }
00826 
00834     public function loadStockRemindProducts( $aBasketContents )
00835     {
00836         if ( is_array( $aBasketContents ) && count( $aBasketContents ) ) {
00837             $oDb = oxDb::getDb();
00838             foreach ( $aBasketContents as $oBasketItem ) {
00839                 $aArtIds[] = $oDb->quote($oBasketItem->getProductId());
00840             }
00841 
00842             $oBaseObject = $this->getBaseObject();
00843 
00844             $sFieldNames = $oBaseObject->getSelectFields();
00845             $sTable      = $oBaseObject->getViewName();
00846 
00847             // fetching actual db stock state and reminder status
00848             $sQ = "select {$sFieldNames} from {$sTable} where {$sTable}.oxid in ( ".implode( ",", $aArtIds )." ) and
00849                           oxremindactive = '1' and oxstock <= oxremindamount";
00850             $this->selectString( $sQ );
00851 
00852             // updating stock reminder state
00853             if ( $this->count() ) {
00854                 $sQ = "update {$sTable} set oxremindactive = '2' where {$sTable}.oxid in ( ".implode( ",", $aArtIds )." ) and
00855                               oxremindactive = '1' and oxstock <= oxremindamount";
00856                 $oDb->execute( $sQ );
00857             }
00858         }
00859     }
00860 
00866     public function renewPriceUpdateTime()
00867     {
00868         $oDb = oxDb::getDb();
00869 
00870         // fetching next update time
00871         $sQ = "select unix_timestamp( oxupdatepricetime ) from %s where oxupdatepricetime > 0 order by oxupdatepricetime asc";
00872         $iTimeToUpdate = $oDb->getOne( sprintf( $sQ, "`oxarticles`" ), false, false );
00873 
00874 
00875         // next day?
00876         $iCurrUpdateTime = oxRegistry::get("oxUtilsDate")->getTime();
00877         $iNextUpdateTime = $iCurrUpdateTime + 3600 * 24;
00878 
00879         // renew next update time
00880         if ( !$iTimeToUpdate || $iTimeToUpdate > $iNextUpdateTime ) {
00881             $iTimeToUpdate = $iNextUpdateTime;
00882         }
00883 
00884         $this->getConfig()->saveShopConfVar( "int", "iTimeToUpdatePrices", $iTimeToUpdate );
00885 
00886         return $iTimeToUpdate;
00887     }
00888 
00897     public function updateUpcomingPrices( $blForceUpdate = false )
00898     {
00899         $blUpdated = false;
00900 
00901         if ( $blForceUpdate || $this->_canUpdatePrices() ) {
00902 
00903             $oDb = oxDb::getDb();
00904 
00905             $oDb->startTransaction();
00906 
00907             $sCurrUpdateTime = date( "Y-m-d H:i:s", oxRegistry::get("oxUtilsDate")->getTime() );
00908 
00909             // Collect article id's for later recalculation.
00910             $sQ = "SELECT `oxid` FROM `oxarticles`
00911                    WHERE `oxupdatepricetime` > 0 AND `oxupdatepricetime` <= '{$sCurrUpdateTime}'";
00912             $aUpdatedArticleIds = $oDb->getCol( $sQ, false, false );
00913 
00914             // updating oxarticles
00915             $sQ = "UPDATE %s SET
00916                        `oxprice`  = IF( `oxupdateprice` > 0, `oxupdateprice`, `oxprice` ),
00917                        `oxpricea` = IF( `oxupdatepricea` > 0, `oxupdatepricea`, `oxpricea` ),
00918                        `oxpriceb` = IF( `oxupdatepriceb` > 0, `oxupdatepriceb`, `oxpriceb` ),
00919                        `oxpricec` = IF( `oxupdatepricec` > 0, `oxupdatepricec`, `oxpricec` ),
00920                        `oxupdatepricetime` = 0,
00921                        `oxupdateprice`     = 0,
00922                        `oxupdatepricea`    = 0,
00923                        `oxupdatepriceb`    = 0,
00924                        `oxupdatepricec`    = 0
00925                    WHERE
00926                        `oxupdatepricetime` > 0 AND
00927                        `oxupdatepricetime` <= '{$sCurrUpdateTime}'" ;
00928             $blUpdated = $oDb->execute( sprintf( $sQ, "`oxarticles`" ) );
00929 
00930 
00931             // renew update time in case update is not forced
00932             if ( !$blForceUpdate ) {
00933                 $this->renewPriceUpdateTime();
00934             }
00935 
00936             $oDb->commitTransaction();
00937 
00938             // recalculate oxvarminprice and oxvarmaxprice for parent
00939             if ( is_array($aUpdatedArticleIds) ) {
00940                 foreach ($aUpdatedArticleIds as $sArticleId) {
00941                     $oArticle = oxNew('oxarticle');
00942                     $oArticle->load($sArticleId);
00943                     $oArticle->onChange();
00944                 }
00945             }
00946 
00947         }
00948 
00949         return $blUpdated;
00950     }
00951 
00959     protected function _createIdListFromSql( $sSql)
00960     {
00961         $rs = oxDb::getDb( oxDb::FETCH_MODE_ASSOC )->select( $sSql );
00962         if ($rs != false && $rs->recordCount() > 0) {
00963             while (!$rs->EOF) {
00964                 $rs->fields = array_change_key_case($rs->fields, CASE_LOWER);
00965                 $this[$rs->fields['oxid']] =  $rs->fields['oxid']; //only the oxid
00966                 $rs->moveNext();
00967             }
00968         }
00969     }
00970 
00979     protected function _getFilterIdsSql( $sCatId, $aFilter )
00980     {
00981         $sO2CView = getViewName( 'oxobject2category' );
00982         $sO2AView = getViewName( 'oxobject2attribute' );
00983 
00984         $sFilter = '';
00985         $iCnt    = 0;
00986 
00987         $oDb = oxDb::getDb();
00988         foreach ( $aFilter as $sAttrId => $sValue ) {
00989             if ( $sValue ) {
00990                 if ( $sFilter ) {
00991                     $sFilter .= ' or ';
00992                 }
00993                 $sValue  = $oDb->quote( $sValue );
00994                 $sAttrId = $oDb->quote( $sAttrId );
00995 
00996                 $sFilter .= "( oa.oxattrid = {$sAttrId} and oa.oxvalue = {$sValue} )";
00997                 $iCnt++;
00998             }
00999         }
01000         if ( $sFilter ) {
01001             $sFilter = "WHERE $sFilter ";
01002         }
01003 
01004         $sFilterSelect = "select oc.oxobjectid as oxobjectid, count(*) as cnt from ";
01005         $sFilterSelect.= "(SELECT * FROM $sO2CView WHERE $sO2CView.oxcatnid = '$sCatId' GROUP BY $sO2CView.oxobjectid, $sO2CView.oxcatnid) as oc ";
01006         $sFilterSelect.= "INNER JOIN $sO2AView as oa ON ( oa.oxobjectid = oc.oxobjectid ) ";
01007         return $sFilterSelect . "{$sFilter} GROUP BY oa.oxobjectid HAVING cnt = $iCnt ";
01008     }
01009 
01018     protected function _getFilterSql( $sCatId, $aFilter )
01019     {
01020         $sArticleTable = getViewName( 'oxarticles' );
01021         $aIds = oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->getAll( $this->_getFilterIdsSql( $sCatId, $aFilter ) );
01022         $sIds = '';
01023 
01024         if ( $aIds ) {
01025             foreach ( $aIds as $aArt ) {
01026                 if ( $sIds ) {
01027                     $sIds .= ', ';
01028                 }
01029                 $sIds .= oxDb::getDb()->quote( current( $aArt ) );
01030             }
01031 
01032             if ( $sIds ) {
01033                 $sFilterSql = " and $sArticleTable.oxid in ( $sIds ) ";
01034             }
01035         // bug fix #0001695: if no articles found return false
01036         } elseif ( !( current( $aFilter ) == '' && count( array_unique( $aFilter ) ) == 1 ) ) {
01037             $sFilterSql = " and false ";
01038         }
01039 
01040         return $sFilterSql;
01041     }
01042 
01052     protected function _getCategorySelect( $sFields, $sCatId, $aSessionFilter )
01053     {
01054         $sArticleTable = getViewName( 'oxarticles' );
01055         $sO2CView      = getViewName( 'oxobject2category' );
01056 
01057         // ----------------------------------
01058         // sorting
01059         $sSorting = '';
01060         if ( $this->_sCustomSorting ) {
01061             $sSorting = " {$this->_sCustomSorting} , ";
01062         }
01063 
01064         // ----------------------------------
01065         // filtering ?
01066         $sFilterSql = '';
01067         $iLang = oxRegistry::getLang()->getBaseLanguage();
01068         if ( $aSessionFilter && isset( $aSessionFilter[$sCatId][$iLang] ) ) {
01069             $sFilterSql = $this->_getFilterSql($sCatId, $aSessionFilter[$sCatId][$iLang]);
01070         }
01071 
01072         $oDb = oxDb::getDb();
01073 
01074         $sSelect = "SELECT $sFields, $sArticleTable.oxtimestamp FROM $sO2CView as oc left join $sArticleTable
01075                     ON $sArticleTable.oxid = oc.oxobjectid
01076                     WHERE ".$this->getBaseObject()->getSqlActiveSnippet()." and $sArticleTable.oxparentid = ''
01077                     and oc.oxcatnid = ".$oDb->quote($sCatId)." $sFilterSql ORDER BY $sSorting oc.oxpos, oc.oxobjectid ";
01078 
01079         return $sSelect;
01080     }
01081 
01090     protected function _getCategoryCountSelect( $sCatId, $aSessionFilter )
01091     {
01092         $sArticleTable = getViewName( 'oxarticles' );
01093         $sO2CView      = getViewName( 'oxobject2category' );
01094 
01095 
01096         // ----------------------------------
01097         // filtering ?
01098         $sFilterSql = '';
01099         $iLang = oxRegistry::getLang()->getBaseLanguage();
01100         if ( $aSessionFilter && isset( $aSessionFilter[$sCatId][$iLang] ) ) {
01101             $sFilterSql = $this->_getFilterSql($sCatId, $aSessionFilter[$sCatId][$iLang]);
01102         }
01103 
01104         $oDb = oxDb::getDb();
01105 
01106         $sSelect = "SELECT COUNT(*) FROM $sO2CView as oc left join $sArticleTable
01107                     ON $sArticleTable.oxid = oc.oxobjectid
01108                     WHERE ".$this->getBaseObject()->getSqlActiveSnippet()." and $sArticleTable.oxparentid = ''
01109                     and oc.oxcatnid = ".$oDb->quote($sCatId)." $sFilterSql ";
01110 
01111         return $sSelect;
01112     }
01113 
01121     protected function _getSearchSelect( $sSearchString )
01122     {
01123         // check if it has string at all
01124         if ( !$sSearchString || !str_replace( ' ', '', $sSearchString ) ) {
01125             return '';
01126         }
01127 
01128         $oDb = oxDb::getDb();
01129         $myConfig = $this->getConfig();
01130 
01131         $sArticleTable = $this->getBaseObject()->getViewName();
01132 
01133         $aSearch = explode( ' ', $sSearchString);
01134 
01135         $sSearch  = ' and ( ';
01136         $blSep = false;
01137 
01138         // #723
01139         if ( $myConfig->getConfigParam( 'blSearchUseAND' ) ) {
01140             $sSearchSep = ' and ';
01141         } else {
01142             $sSearchSep = ' or ';
01143         }
01144 
01145         $aSearchCols = $myConfig->getConfigParam( 'aSearchCols' );
01146         $myUtilsString = oxRegistry::get("oxUtilsString");
01147         foreach ( $aSearch as $sSearchString) {
01148 
01149             if ( !strlen( $sSearchString ) ) {
01150                 continue;
01151             }
01152 
01153             if ( $blSep ) {
01154                 $sSearch .= $sSearchSep;
01155             }
01156             $blSep2   = false;
01157             $sSearch .= '( ';
01158 
01159             $sUml = $myUtilsString->prepareStrForSearch($sSearchString);
01160             foreach ( $aSearchCols as $sField ) {
01161 
01162                 if ( $blSep2) {
01163                     $sSearch  .= ' or ';
01164                 }
01165 
01166                 // as long description now is on different table table must differ
01167                 if ( $sField == 'oxlongdesc' || $sField == 'oxtags') {
01168                     $sSearchTable = getViewName( 'oxartextends' );
01169                 } else {
01170                     $sSearchTable = $sArticleTable;
01171                 }
01172 
01173                 $sSearch .= $sSearchTable.'.'.$sField.' like '.$oDb->quote('%'.$sSearchString.'%') . ' ';
01174                 if ( $sUml ) {
01175                     $sSearch  .= ' or '.$sSearchTable.'.'.$sField.' like '.$oDb->quote('%'.$sUml.'%');
01176                 }
01177                 $blSep2 = true;
01178             }
01179             $sSearch  .= ' ) ';
01180             $blSep = true;
01181         }
01182         $sSearch .= ' ) ';
01183 
01184         return $sSearch;
01185     }
01186 
01195     protected function _getPriceSelect( $dPriceFrom, $dPriceTo )
01196     {
01197         $oBaseObject   = $this->getBaseObject();
01198         $sArticleTable = $oBaseObject->getViewName();
01199         $sSelectFields = $oBaseObject->getSelectFields();
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 }