OXID eShop CE  4.8.12
 All Classes Files Functions Variables Pages
oxarticlelist.php
Go to the documentation of this file.
1 <?php
2 
8 class oxArticleList extends oxList
9 {
13  protected $_sCustomSorting;
14 
20  protected $_sObjectsInListName = 'oxarticle';
21 
27  protected $_blLoadSelectLists = false;
28 
36  public function setCustomSorting( $sSorting )
37  {
38  $this->_sCustomSorting = $sSorting;
39  }
40 
46  public function enableSelectLists()
47  {
48  $this->_blLoadSelectLists = true;
49  }
50 
59  public function selectString( $sSelect )
60  {
61  startProfile("loadinglists");
62  $oRes = parent::selectString( $sSelect );
63  stopProfile("loadinglists");
64 
65  return $oRes;
66  }
67 
73  public function getHistoryArticles()
74  {
75  $aResult = array();
76 
77  if ($aArticlesIds = $this->getSession()->getVariable('aHistoryArticles')) {
78  $aResult = $aArticlesIds;
79  } elseif ( $sArticlesIds = oxRegistry::get("oxUtilsServer")->getOxCookie('aHistoryArticles')) {
80  $aResult = explode('|', $sArticlesIds);
81  }
82 
83  return $aResult;
84  }
85 
93  public function setHistoryArticles($aArticlesIds)
94  {
95  if ($this->getSession()->getId()) {
96  $this->getSession()->setVariable('aHistoryArticles', $aArticlesIds);
97  // clean cookie, if session started
98  oxRegistry::get("oxUtilsServer")->setOxCookie('aHistoryArticles', '');
99  } else {
100  oxRegistry::get("oxUtilsServer")->setOxCookie('aHistoryArticles', implode('|', $aArticlesIds));
101  }
102  }
103 
113  public function loadHistoryArticles( $sArtId, $iCnt = 4 )
114  {
115  $aHistoryArticles = $this->getHistoryArticles();
116  $aHistoryArticles[] = $sArtId;
117 
118  // removing dublicates
119  $aHistoryArticles = array_unique( $aHistoryArticles );
120  if ( count( $aHistoryArticles ) > ( $iCnt + 1 ) ) {
121  array_shift( $aHistoryArticles );
122  }
123 
124  $this->setHistoryArticles( $aHistoryArticles );
125 
126  //remove current article and return array
127  //asignment =, not ==
128  if ( ( $iCurrentArt = array_search( $sArtId, $aHistoryArticles ) ) !== false ) {
129  unset( $aHistoryArticles[$iCurrentArt] );
130  }
131 
132  $aHistoryArticles = array_values( $aHistoryArticles );
133  $this->loadIds( $aHistoryArticles );
134  $this->sortByIds( $aHistoryArticles );
135  }
136 
144  public function sortByIds( $aIds )
145  {
146  $this->_aOrderMap = array_flip( $aIds );
147  uksort($this->_aArray, array($this, '_sortByOrderMapCallback'));
148  }
149 
160  protected function _sortByOrderMapCallback($key1, $key2)
161  {
162  if (isset($this->_aOrderMap[$key1])) {
163  if (isset($this->_aOrderMap[$key2])) {
164  $iDiff = $this->_aOrderMap[$key2] - $this->_aOrderMap[$key1];
165  if ($iDiff > 0) {
166  return -1;
167  } elseif ($iDiff < 0) {
168  return 1;
169  } else {
170  return 0;
171  }
172  } else {
173  // first is here, but 2nd is not - 1st gets more priority
174  return -1;
175  }
176  } elseif (isset($this->_aOrderMap[$key2])) {
177  // first is not here, but 2nd is - 2nd gets more priority
178  return 1;
179  } else {
180  // both unset, equal
181  return 0;
182  }
183  }
184 
192  public function loadNewestArticles( $iLimit = null )
193  {
194  //has module?
195  $myConfig = $this->getConfig();
196 
197  if ( !$myConfig->getConfigParam( 'bl_perfLoadPriceForAddList' ) ) {
198  $this->getBaseObject()->disablePriceLoad();
199  }
200 
201  $this->_aArray = array();
202  switch( $myConfig->getConfigParam( 'iNewestArticlesMode' ) ) {
203  case 0:
204  // switched off, do nothing
205  break;
206  case 1:
207  // manually entered
208  $this->loadActionArticles( 'oxnewest', $iLimit );
209  break;
210  case 2:
211  $sArticleTable = getViewName('oxarticles');
212  if ( $myConfig->getConfigParam( 'blNewArtByInsert' ) ) {
213  $sType = 'oxinsert';
214  } else {
215  $sType = 'oxtimestamp';
216  }
217  $sSelect = "select * from $sArticleTable ";
218  $sSelect .= "where oxparentid = '' and ".$this->getBaseObject()->getSqlActiveSnippet()." and oxissearch = 1 order by $sType desc ";
219  if (!($iLimit = (int) $iLimit)) {
220  $iLimit = $myConfig->getConfigParam( 'iNrofNewcomerArticles' );
221  }
222  $sSelect .= "limit " . $iLimit;
223 
224  $this->selectString($sSelect);
225  break;
226  }
227 
228  }
229 
237  public function loadTop5Articles( $iLimit = null )
238  {
239  //has module?
240  $myConfig = $this->getConfig();
241 
242  if ( !$myConfig->getConfigParam( 'bl_perfLoadPriceForAddList' ) ) {
243  $this->getBaseObject()->disablePriceLoad();
244  }
245 
246  switch( $myConfig->getConfigParam( 'iTop5Mode' ) ) {
247  case 0:
248  // switched off, do nothing
249  break;
250  case 1:
251  // manually entered
252  $this->loadActionArticles( 'oxtop5', $iLimit );
253  break;
254  case 2:
255  $sArticleTable = getViewName('oxarticles');
256 
257  //by default limit 5
258  $sLimit = ( $iLimit > 0 ) ? "limit " . $iLimit : 'limit 5';
259 
260  $sSelect = "select * from $sArticleTable ";
261  $sSelect .= "where ".$this->getBaseObject()->getSqlActiveSnippet()." and $sArticleTable.oxissearch = 1 ";
262  $sSelect .= "and $sArticleTable.oxparentid = '' and $sArticleTable.oxsoldamount>0 ";
263  $sSelect .= "order by $sArticleTable.oxsoldamount desc $sLimit";
264 
265  $this->selectString($sSelect);
266  break;
267  }
268  }
269 
278  public function loadActionArticles( $sActionID, $iLimit = null )
279  {
280  // Performance
281  if ( !trim( $sActionID) ) {
282  return;
283  }
284 
285  $sShopID = $this->getConfig()->getShopId();
286  $sActionID = oxDb::getDb()->quote(strtolower( $sActionID));
287 
288  //echo $sSelect;
289  $oBaseObject = $this->getBaseObject();
290  $sArticleTable = $oBaseObject->getViewName();
291  $sArticleFields = $oBaseObject->getSelectFields();
292 
293  $oBase = oxNew("oxactions");
294  $sActiveSql = $oBase->getSqlActiveSnippet();
295  $sViewName = $oBase->getViewName();
296 
297  $sLimit = ( $iLimit > 0 ) ? "limit " . $iLimit : '';
298 
299  $sSelect = "select $sArticleFields from oxactions2article
300  left join $sArticleTable on $sArticleTable.oxid = oxactions2article.oxartid
301  left join $sViewName on $sViewName.oxid = oxactions2article.oxactionid
302  where oxactions2article.oxshopid = '$sShopID' and oxactions2article.oxactionid = $sActionID and $sActiveSql
303  and $sArticleTable.oxid is not null and " .$oBaseObject->getSqlActiveSnippet(). "
304  order by oxactions2article.oxsort $sLimit";
305 
306  $this->selectString( $sSelect );
307  }
308 
309 
320  public function loadAktionArticles( $sActionID, $iLimit = null )
321  {
322  $this->loadActionArticles( $sActionID, $iLimit = null );
323 
324  }
325 
333  public function loadArticleCrossSell( $sArticleId )
334  {
335  $myConfig = $this->getConfig();
336 
337  // Performance
338  if ( !$myConfig->getConfigParam( 'bl_perfLoadCrossselling' ) ) {
339  return null;
340  }
341 
342  $oBaseObject = $this->getBaseObject();
343  $sArticleTable = $oBaseObject->getViewName();
344 
345  $sArticleId = oxDb::getDb()->quote($sArticleId);
346 
347  $sSelect = "SELECT $sArticleTable.*
348  FROM $sArticleTable INNER JOIN oxobject2article ON oxobject2article.oxobjectid=$sArticleTable.oxid ";
349  $sSelect .= "WHERE oxobject2article.oxarticlenid = $sArticleId ";
350  $sSelect .= " AND " .$oBaseObject->getSqlActiveSnippet();
351 
352  // #525 bidirectional cross selling
353  if ( $myConfig->getConfigParam( 'blBidirectCross' ) ) {
354  $sSelect = "
355  (
356  SELECT $sArticleTable.* FROM $sArticleTable
357  INNER JOIN oxobject2article AS O2A1 on
358  ( O2A1.oxobjectid = $sArticleTable.oxid AND O2A1.oxarticlenid = $sArticleId )
359  WHERE 1
360  AND " . $oBaseObject->getSqlActiveSnippet() . "
361  AND ($sArticleTable.oxid != $sArticleId)
362  )
363  UNION
364  (
365  SELECT $sArticleTable.* FROM $sArticleTable
366  INNER JOIN oxobject2article AS O2A2 ON
367  ( O2A2.oxarticlenid = $sArticleTable.oxid AND O2A2.oxobjectid = $sArticleId )
368  WHERE 1
369  AND " . $oBaseObject->getSqlActiveSnippet() . "
370  AND ($sArticleTable.oxid != $sArticleId)
371  )";
372  }
373 
374  $this->setSqlLimit( 0, $myConfig->getConfigParam( 'iNrofCrossellArticles' ));
375  $this->selectString( $sSelect );
376  }
377 
385  public function loadArticleAccessoires( $sArticleId )
386  {
387  $myConfig = $this->getConfig();
388 
389  // Performance
390  if ( !$myConfig->getConfigParam( 'bl_perfLoadAccessoires' ) ) {
391  return;
392  }
393 
394  $sArticleId = oxDb::getDb()->quote($sArticleId);
395 
396  $oBaseObject = $this->getBaseObject();
397  $sArticleTable = $oBaseObject->getViewName();
398 
399  $sSelect = "select $sArticleTable.* from oxaccessoire2article left join $sArticleTable on oxaccessoire2article.oxobjectid=$sArticleTable.oxid ";
400  $sSelect .= "where oxaccessoire2article.oxarticlenid = $sArticleId ";
401  $sSelect .= " and $sArticleTable.oxid is not null and " .$oBaseObject->getSqlActiveSnippet();
402  //sorting articles
403  $sSelect .= " order by oxaccessoire2article.oxsort";
404 
405  $this->selectString( $sSelect );
406  }
407 
416  public function loadCategoryIds( $sCatId, $aSessionFilter )
417  {
418  $sArticleTable = $this->getBaseObject()->getViewName();
419  $sSelect = $this->_getCategorySelect( $sArticleTable.'.oxid as oxid', $sCatId, $aSessionFilter );
420 
421  $this->_createIdListFromSql( $sSelect );
422  }
423 
433  public function loadCategoryArticles( $sCatId, $aSessionFilter, $iLimit = null )
434  {
435  $sArticleFields = $this->getBaseObject()->getSelectFields();
436 
437  $sSelect = $this->_getCategorySelect( $sArticleFields, $sCatId, $aSessionFilter );
438 
439  // calc count - we can not use count($this) here as we might have paging enabled
440  // #1970C - if any filters are used, we can not use cached category article count
441  $iArticleCount = null;
442  if ( $aSessionFilter) {
443  $iArticleCount = oxDb::getDb()->getOne( $this->_getCategoryCountSelect( $sCatId, $aSessionFilter ) );
444  }
445 
446  if ($iLimit = (int) $iLimit) {
447  $sSelect .= " LIMIT $iLimit";
448  }
449 
450  $this->selectString( $sSelect );
451 
452  if ( $iArticleCount !== null ) {
453  return $iArticleCount;
454  }
455 
456  // this select is FAST so no need to hazzle here with getNrOfArticles()
457  return oxRegistry::get("oxUtilsCount")->getCatArticleCount( $sCatId );
458  }
459 
468  public function loadRecommArticles( $sRecommId, $sArticlesFilter = null )
469  {
470  $sSelect = $this->_getArticleSelect( $sRecommId, $sArticlesFilter);
471  $this->selectString( $sSelect );
472  }
473 
482  public function loadRecommArticleIds( $sRecommId, $sArticlesFilter )
483  {
484  $sSelect = $this->_getArticleSelect( $sRecommId, $sArticlesFilter );
485 
486  $sArtView = getViewName( 'oxarticles' );
487  $sPartial = substr( $sSelect, strpos( $sSelect, ' from ' ) );
488  $sSelect = "select distinct $sArtView.oxid $sPartial ";
489 
490  $this->_createIdListFromSql( $sSelect );
491  }
492 
501  protected function _getArticleSelect( $sRecommId, $sArticlesFilter = null )
502  {
503  $sRecommId = oxDb::getDb()->quote($sRecommId);
504 
505  $sArtView = getViewName( 'oxarticles' );
506  $sSelect = "select distinct $sArtView.*, oxobject2list.oxdesc from oxobject2list ";
507  $sSelect .= "left join $sArtView on oxobject2list.oxobjectid = $sArtView.oxid ";
508  $sSelect .= "where (oxobject2list.oxlistid = $sRecommId) ".$sArticlesFilter;
509 
510  return $sSelect;
511  }
512 
523  public function loadSearchIds( $sSearchStr = '', $sSearchCat = '', $sSearchVendor = '', $sSearchManufacturer = '' )
524  {
525  $oDb = oxDb::getDb();
526  $sSearchCat = $sSearchCat?$sSearchCat:null;
527  $sSearchVendor = $sSearchVendor?$sSearchVendor:null;
528  $sSearchManufacturer = $sSearchManufacturer?$sSearchManufacturer:null;
529 
530  $sWhere = null;
531 
532  if ( $sSearchStr ) {
533  $sWhere = $this->_getSearchSelect( $sSearchStr );
534  }
535 
536  $sArticleTable = getViewName('oxarticles');
537 
538  // longdesc field now is kept on different table
539  $sDescJoin = '';
540  if ( is_array( $aSearchCols = $this->getConfig()->getConfigParam( 'aSearchCols' ) ) ) {
541  if ( in_array( 'oxlongdesc', $aSearchCols ) || in_array( 'oxtags', $aSearchCols ) ) {
542  $sDescView = getViewName( 'oxartextends' );
543  $sDescJoin = " LEFT JOIN $sDescView ON {$sDescView}.oxid={$sArticleTable}.oxid ";
544  }
545  }
546 
547  // load the articles
548  $sSelect = "select $sArticleTable.oxid, $sArticleTable.oxtimestamp from $sArticleTable $sDescJoin where ";
549 
550  // must be additional conditions in select if searching in category
551  if ( $sSearchCat ) {
552  $sO2CView = getViewName('oxobject2category');
553  $sSelect = "select $sArticleTable.oxid from $sO2CView as oxobject2category, $sArticleTable $sDescJoin ";
554  $sSelect .= "where oxobject2category.oxcatnid=".$oDb->quote( $sSearchCat )." and oxobject2category.oxobjectid=$sArticleTable.oxid and ";
555  }
556  $sSelect .= $this->getBaseObject()->getSqlActiveSnippet();
557  $sSelect .= " and $sArticleTable.oxparentid = '' and $sArticleTable.oxissearch = 1 ";
558 
559  // #671
560  if ( $sSearchVendor ) {
561  $sSelect .= " and $sArticleTable.oxvendorid = ".$oDb->quote( $sSearchVendor )." ";
562  }
563 
564  if ( $sSearchManufacturer ) {
565  $sSelect .= " and $sArticleTable.oxmanufacturerid = ".$oDb->quote( $sSearchManufacturer )." ";
566  }
567  $sSelect .= $sWhere;
568 
569  if ($this->_sCustomSorting) {
570  $sSelect .= " order by {$this->_sCustomSorting} ";
571  }
572 
573  $this->_createIdListFromSql($sSelect);
574  }
575 
584  public function loadPriceIds( $dPriceFrom, $dPriceTo )
585  {
586  $sSelect = $this->_getPriceSelect( $dPriceFrom, $dPriceTo );
587  $this->_createIdListFromSql( $sSelect );
588  }
589 
600  public function loadPriceArticles( $dPriceFrom, $dPriceTo, $oCategory = null)
601  {
602  $sSelect = $this->_getPriceSelect( $dPriceFrom, $dPriceTo );
603 
604  startProfile("loadPriceArticles");
605  $this->selectString( $sSelect);
606  stopProfile("loadPriceArticles");
607 
608  if ( !$oCategory ) {
609  return $this->count();
610  }
611 
612  return oxRegistry::get("oxUtilsCount")->getPriceCatArticleCount( $oCategory->getId(), $dPriceFrom, $dPriceTo );
613  }
614 
622  public function loadVendorIDs( $sVendorId)
623  {
624  $sSelect = $this->_getVendorSelect($sVendorId);
625  $this->_createIdListFromSql($sSelect);
626  }
627 
635  public function loadManufacturerIDs( $sManufacturerId)
636  {
637  $sSelect = $this->_getManufacturerSelect($sManufacturerId);
638  $this->_createIdListFromSql($sSelect);
639  }
640 
650  public function loadVendorArticles( $sVendorId, $oVendor = null )
651  {
652  $sSelect = $this->_getVendorSelect($sVendorId);
653  $this->selectString( $sSelect);
654 
655  return oxRegistry::get("oxUtilsCount")->getVendorArticleCount( $sVendorId );
656  }
657 
667  public function loadManufacturerArticles( $sManufacturerId, $oManufacturer = null )
668  {
669  $sSelect = $this->_getManufacturerSelect($sManufacturerId);
670  $this->selectString( $sSelect);
671 
672  return oxRegistry::get("oxUtilsCount")->getManufacturerArticleCount( $sManufacturerId );
673  }
674 
683  public function loadTagArticles( $sTag, $iLang )
684  {
685  $oListObject = $this->getBaseObject();
686  $sArticleTable = $oListObject->getViewName();
687  $sArticleFields = $oListObject->getSelectFields();
688  $sViewName = getViewName( 'oxartextends', $iLang );
689 
690  $oTag = oxNew( 'oxtag', $sTag );
691  $oTag->addUnderscores();
692  $sTag = $oTag->get();
693 
694  $sQ = "select {$sArticleFields} from {$sViewName} inner join {$sArticleTable} on ".
695  "{$sArticleTable}.oxid = {$sViewName}.oxid where {$sArticleTable}.oxparentid = '' AND match ( {$sViewName}.oxtags ) ".
696  "against( ".oxDb::getDb()->quote( "\"".$sTag."\"" )." IN BOOLEAN MODE )";
697 
698  // checking stock etc
699  if ( ( $sActiveSnippet = $oListObject->getSqlActiveSnippet() ) ) {
700  $sQ .= " and {$sActiveSnippet}";
701  }
702 
703  if ( $this->_sCustomSorting ) {
704  $sSort = $this->_sCustomSorting;
705  if (strpos($sSort, '.') === false) {
706  $sSort = $sArticleTable.'.'.$sSort;
707  }
708  $sQ .= " order by $sSort ";
709  }
710 
711  $this->selectString( $sQ );
712 
713  // calc count - we can not use count($this) here as we might have paging enabled
714  return oxRegistry::get("oxUtilsCount")->getTagArticleCount( $sTag, $iLang );
715  }
716 
725  public function getTagArticleIds( $sTag, $iLang )
726  {
727  $oListObject = $this->getBaseObject();
728  $sArticleTable = $oListObject->getViewName();
729  $sViewName = getViewName( 'oxartextends', $iLang );
730 
731  $oTag = oxNew( 'oxtag', $sTag );
732  $oTag->addUnderscores();
733  $sTag = $oTag->get();
734 
735  $sQ = "select {$sViewName}.oxid from {$sViewName} inner join {$sArticleTable} on ".
736  "{$sArticleTable}.oxid = {$sViewName}.oxid where {$sArticleTable}.oxparentid = '' and {$sArticleTable}.oxissearch = 1 and ".
737  "match ( {$sViewName}.oxtags ) ".
738  "against( ".oxDb::getDb()->quote( "\"".$sTag."\"" )." IN BOOLEAN MODE )";
739 
740  // checking stock etc
741  if ( ( $sActiveSnippet = $oListObject->getSqlActiveSnippet() ) ) {
742  $sQ .= " and {$sActiveSnippet}";
743  }
744 
745  if ( $this->_sCustomSorting ) {
746  $sSort = $this->_sCustomSorting;
747  if (strpos($sSort, '.') === false) {
748  $sSort = $sArticleTable.'.'.$sSort;
749  }
750  $sQ .= " order by $sSort ";
751  }
752 
753  return $this->_createIdListFromSql( $sQ );
754  }
755 
763  public function loadIds($aIds)
764  {
765  if (!count($aIds)) {
766  $this->clear();
767  return;
768  }
769 
770  foreach ($aIds as $iKey => $sVal) {
771  $aIds[$iKey] = oxDb::getInstance()->escapeString($sVal);
772  }
773 
774  $oBaseObject = $this->getBaseObject();
775  $sArticleTable = $oBaseObject->getViewName();
776  $sArticleFields = $oBaseObject->getSelectFields();
777 
778  $sSelect = "select $sArticleFields from $sArticleTable ";
779  $sSelect .= "where $sArticleTable.oxid in ( '".implode("','", $aIds)."' ) and ";
780  $sSelect .= $oBaseObject->getSqlActiveSnippet();
781 
782  $this->selectString($sSelect);
783  }
784 
792  public function loadOrderArticles($aOrders)
793  {
794  if (!count($aOrders)) {
795  $this->clear();
796  return;
797  }
798 
799  foreach ($aOrders as $oOrder) {
800  $aOrdersIds[] = $oOrder->getId();
801  }
802 
803  $oBaseObject = $this->getBaseObject();
804  $sArticleTable = $oBaseObject->getViewName();
805  $sArticleFields = $oBaseObject->getSelectFields();
806  $sArticleFields = str_replace( "`$sArticleTable`.`oxid`", "`oxorderarticles`.`oxartid` AS `oxid`", $sArticleFields );
807 
808  $sSelect = "SELECT $sArticleFields FROM oxorderarticles ";
809  $sSelect .= "left join $sArticleTable on oxorderarticles.oxartid = $sArticleTable.oxid ";
810  $sSelect .= "WHERE oxorderarticles.oxorderid IN ( '".implode("','", $aOrdersIds)."' ) ";
811  $sSelect .= "order by $sArticleTable.oxid ";
812 
813  $this->selectString( $sSelect );
814 
815  // not active or not available products must not have button "tobasket"
816  $sNow = date('Y-m-d H:i:s');
817  foreach ( $this as $oArticle ) {
818  if ( !$oArticle->oxarticles__oxactive->value &&
819  ( $oArticle->oxarticles__oxactivefrom->value > $sNow ||
820  $oArticle->oxarticles__oxactiveto->value < $sNow
821  )) {
822  $oArticle->setBuyableState( false );
823  }
824  }
825  }
826 
834  public function loadStockRemindProducts( $aBasketContents )
835  {
836  if ( is_array( $aBasketContents ) && count( $aBasketContents ) ) {
837  $oDb = oxDb::getDb();
838  foreach ( $aBasketContents as $oBasketItem ) {
839  $aArtIds[] = $oDb->quote($oBasketItem->getProductId());
840  }
841 
842  $oBaseObject = $this->getBaseObject();
843 
844  $sFieldNames = $oBaseObject->getSelectFields();
845  $sTable = $oBaseObject->getViewName();
846 
847  // fetching actual db stock state and reminder status
848  $sQ = "select {$sFieldNames} from {$sTable} where {$sTable}.oxid in ( ".implode( ",", $aArtIds )." ) and
849  oxremindactive = '1' and oxstock <= oxremindamount";
850  $this->selectString( $sQ );
851 
852  // updating stock reminder state
853  if ( $this->count() ) {
854  $sQ = "update {$sTable} set oxremindactive = '2' where {$sTable}.oxid in ( ".implode( ",", $aArtIds )." ) and
855  oxremindactive = '1' and oxstock <= oxremindamount";
856  $oDb->execute( $sQ );
857  }
858  }
859  }
860 
866  public function renewPriceUpdateTime()
867  {
868  $oDb = oxDb::getDb();
869 
870  // fetching next update time
871  $sQ = "select unix_timestamp( oxupdatepricetime ) from %s where oxupdatepricetime > 0 order by oxupdatepricetime asc";
872  $iTimeToUpdate = $oDb->getOne( sprintf( $sQ, "`oxarticles`" ), false, false );
873 
874 
875  // next day?
876  $iCurrUpdateTime = oxRegistry::get("oxUtilsDate")->getTime();
877  $iNextUpdateTime = $iCurrUpdateTime + 3600 * 24;
878 
879  // renew next update time
880  if ( !$iTimeToUpdate || $iTimeToUpdate > $iNextUpdateTime ) {
881  $iTimeToUpdate = $iNextUpdateTime;
882  }
883 
884  $this->getConfig()->saveShopConfVar( "int", "iTimeToUpdatePrices", $iTimeToUpdate );
885 
886  return $iTimeToUpdate;
887  }
888 
897  public function updateUpcomingPrices( $blForceUpdate = false )
898  {
899  $blUpdated = false;
900 
901  if ( $blForceUpdate || $this->_canUpdatePrices() ) {
902 
903  $oDb = oxDb::getDb();
904 
905  $oDb->startTransaction();
906 
907  $sCurrUpdateTime = date( "Y-m-d H:i:s", oxRegistry::get("oxUtilsDate")->getTime() );
908 
909  // Collect article id's for later recalculation.
910  $sQ = "SELECT `oxid` FROM `oxarticles`
911  WHERE `oxupdatepricetime` > 0 AND `oxupdatepricetime` <= '{$sCurrUpdateTime}'";
912  $aUpdatedArticleIds = $oDb->getCol( $sQ, false, false );
913 
914  // updating oxarticles
915  $sQ = "UPDATE %s SET
916  `oxprice` = IF( `oxupdateprice` > 0, `oxupdateprice`, `oxprice` ),
917  `oxpricea` = IF( `oxupdatepricea` > 0, `oxupdatepricea`, `oxpricea` ),
918  `oxpriceb` = IF( `oxupdatepriceb` > 0, `oxupdatepriceb`, `oxpriceb` ),
919  `oxpricec` = IF( `oxupdatepricec` > 0, `oxupdatepricec`, `oxpricec` ),
920  `oxupdatepricetime` = 0,
921  `oxupdateprice` = 0,
922  `oxupdatepricea` = 0,
923  `oxupdatepriceb` = 0,
924  `oxupdatepricec` = 0
925  WHERE
926  `oxupdatepricetime` > 0 AND
927  `oxupdatepricetime` <= '{$sCurrUpdateTime}'" ;
928  $blUpdated = $oDb->execute( sprintf( $sQ, "`oxarticles`" ) );
929 
930 
931  // renew update time in case update is not forced
932  if ( !$blForceUpdate ) {
933  $this->renewPriceUpdateTime();
934  }
935 
936  $oDb->commitTransaction();
937 
938  // recalculate oxvarminprice and oxvarmaxprice for parent
939  if ( is_array($aUpdatedArticleIds) ) {
940  foreach ($aUpdatedArticleIds as $sArticleId) {
941  $oArticle = oxNew('oxarticle');
942  $oArticle->load($sArticleId);
943  $oArticle->onChange();
944  }
945  }
946 
947  }
948 
949  return $blUpdated;
950  }
951 
959  protected function _createIdListFromSql( $sSql)
960  {
961  $rs = oxDb::getDb( oxDb::FETCH_MODE_ASSOC )->select( $sSql );
962  if ($rs != false && $rs->recordCount() > 0) {
963  while (!$rs->EOF) {
964  $rs->fields = array_change_key_case($rs->fields, CASE_LOWER);
965  $this[$rs->fields['oxid']] = $rs->fields['oxid']; //only the oxid
966  $rs->moveNext();
967  }
968  }
969  }
970 
979  protected function _getFilterIdsSql( $sCatId, $aFilter )
980  {
981  $sO2CView = getViewName( 'oxobject2category' );
982  $sO2AView = getViewName( 'oxobject2attribute' );
983 
984  $sFilter = '';
985  $iCnt = 0;
986 
987  $oDb = oxDb::getDb();
988  foreach ( $aFilter as $sAttrId => $sValue ) {
989  if ( $sValue ) {
990  if ( $sFilter ) {
991  $sFilter .= ' or ';
992  }
993  $sValue = $oDb->quote( $sValue );
994  $sAttrId = $oDb->quote( $sAttrId );
995 
996  $sFilter .= "( oa.oxattrid = {$sAttrId} and oa.oxvalue = {$sValue} )";
997  $iCnt++;
998  }
999  }
1000  if ( $sFilter ) {
1001  $sFilter = "WHERE $sFilter ";
1002  }
1003 
1004  $sFilterSelect = "select oc.oxobjectid as oxobjectid, count(*) as cnt from ";
1005  $sFilterSelect.= "(SELECT * FROM $sO2CView WHERE $sO2CView.oxcatnid = '$sCatId' GROUP BY $sO2CView.oxobjectid, $sO2CView.oxcatnid) as oc ";
1006  $sFilterSelect.= "INNER JOIN $sO2AView as oa ON ( oa.oxobjectid = oc.oxobjectid ) ";
1007  return $sFilterSelect . "{$sFilter} GROUP BY oa.oxobjectid HAVING cnt = $iCnt ";
1008  }
1009 
1018  protected function _getFilterSql( $sCatId, $aFilter )
1019  {
1020  $sArticleTable = getViewName( 'oxarticles' );
1021  $aIds = oxDb::getDb(oxDb::FETCH_MODE_ASSOC)->getAll( $this->_getFilterIdsSql( $sCatId, $aFilter ) );
1022  $sIds = '';
1023 
1024  if ( $aIds ) {
1025  foreach ( $aIds as $aArt ) {
1026  if ( $sIds ) {
1027  $sIds .= ', ';
1028  }
1029  $sIds .= oxDb::getDb()->quote( current( $aArt ) );
1030  }
1031 
1032  if ( $sIds ) {
1033  $sFilterSql = " and $sArticleTable.oxid in ( $sIds ) ";
1034  }
1035  // bug fix #0001695: if no articles found return false
1036  } elseif ( !( current( $aFilter ) == '' && count( array_unique( $aFilter ) ) == 1 ) ) {
1037  $sFilterSql = " and false ";
1038  }
1039 
1040  return $sFilterSql;
1041  }
1042 
1052  protected function _getCategorySelect( $sFields, $sCatId, $aSessionFilter )
1053  {
1054  $sArticleTable = getViewName( 'oxarticles' );
1055  $sO2CView = getViewName( 'oxobject2category' );
1056 
1057  // ----------------------------------
1058  // sorting
1059  $sSorting = '';
1060  if ( $this->_sCustomSorting ) {
1061  $sSorting = " {$this->_sCustomSorting} , ";
1062  }
1063 
1064  // ----------------------------------
1065  // filtering ?
1066  $sFilterSql = '';
1067  $iLang = oxRegistry::getLang()->getBaseLanguage();
1068  if ( $aSessionFilter && isset( $aSessionFilter[$sCatId][$iLang] ) ) {
1069  $sFilterSql = $this->_getFilterSql($sCatId, $aSessionFilter[$sCatId][$iLang]);
1070  }
1071 
1072  $oDb = oxDb::getDb();
1073 
1074  $sSelect = "SELECT $sFields, $sArticleTable.oxtimestamp FROM $sO2CView as oc left join $sArticleTable
1075  ON $sArticleTable.oxid = oc.oxobjectid
1076  WHERE ".$this->getBaseObject()->getSqlActiveSnippet()." and $sArticleTable.oxparentid = ''
1077  and oc.oxcatnid = ".$oDb->quote($sCatId)." $sFilterSql ORDER BY $sSorting oc.oxpos, oc.oxobjectid ";
1078 
1079  return $sSelect;
1080  }
1081 
1090  protected function _getCategoryCountSelect( $sCatId, $aSessionFilter )
1091  {
1092  $sArticleTable = getViewName( 'oxarticles' );
1093  $sO2CView = getViewName( 'oxobject2category' );
1094 
1095 
1096  // ----------------------------------
1097  // filtering ?
1098  $sFilterSql = '';
1099  $iLang = oxRegistry::getLang()->getBaseLanguage();
1100  if ( $aSessionFilter && isset( $aSessionFilter[$sCatId][$iLang] ) ) {
1101  $sFilterSql = $this->_getFilterSql($sCatId, $aSessionFilter[$sCatId][$iLang]);
1102  }
1103 
1104  $oDb = oxDb::getDb();
1105 
1106  $sSelect = "SELECT COUNT(*) FROM $sO2CView as oc left join $sArticleTable
1107  ON $sArticleTable.oxid = oc.oxobjectid
1108  WHERE ".$this->getBaseObject()->getSqlActiveSnippet()." and $sArticleTable.oxparentid = ''
1109  and oc.oxcatnid = ".$oDb->quote($sCatId)." $sFilterSql ";
1110 
1111  return $sSelect;
1112  }
1113 
1121  protected function _getSearchSelect( $sSearchString )
1122  {
1123  // check if it has string at all
1124  if ( !$sSearchString || !str_replace( ' ', '', $sSearchString ) ) {
1125  return '';
1126  }
1127 
1128  $oDb = oxDb::getDb();
1129  $myConfig = $this->getConfig();
1130 
1131  $sArticleTable = $this->getBaseObject()->getViewName();
1132 
1133  $aSearch = explode( ' ', $sSearchString);
1134 
1135  $sSearch = ' and ( ';
1136  $blSep = false;
1137 
1138  // #723
1139  if ( $myConfig->getConfigParam( 'blSearchUseAND' ) ) {
1140  $sSearchSep = ' and ';
1141  } else {
1142  $sSearchSep = ' or ';
1143  }
1144 
1145  $aSearchCols = $myConfig->getConfigParam( 'aSearchCols' );
1146  $myUtilsString = oxRegistry::get("oxUtilsString");
1147  foreach ( $aSearch as $sSearchString) {
1148 
1149  if ( !strlen( $sSearchString ) ) {
1150  continue;
1151  }
1152 
1153  if ( $blSep ) {
1154  $sSearch .= $sSearchSep;
1155  }
1156  $blSep2 = false;
1157  $sSearch .= '( ';
1158 
1159  $sUml = $myUtilsString->prepareStrForSearch($sSearchString);
1160  foreach ( $aSearchCols as $sField ) {
1161 
1162  if ( $blSep2) {
1163  $sSearch .= ' or ';
1164  }
1165 
1166  // as long description now is on different table table must differ
1167  if ( $sField == 'oxlongdesc' || $sField == 'oxtags') {
1168  $sSearchTable = getViewName( 'oxartextends' );
1169  } else {
1170  $sSearchTable = $sArticleTable;
1171  }
1172 
1173  $sSearch .= $sSearchTable.'.'.$sField.' like '.$oDb->quote('%'.$sSearchString.'%') . ' ';
1174  if ( $sUml ) {
1175  $sSearch .= ' or '.$sSearchTable.'.'.$sField.' like '.$oDb->quote('%'.$sUml.'%');
1176  }
1177  $blSep2 = true;
1178  }
1179  $sSearch .= ' ) ';
1180  $blSep = true;
1181  }
1182  $sSearch .= ' ) ';
1183 
1184  return $sSearch;
1185  }
1186 
1195  protected function _getPriceSelect( $dPriceFrom, $dPriceTo )
1196  {
1197  $oBaseObject = $this->getBaseObject();
1198  $sArticleTable = $oBaseObject->getViewName();
1199  $sSelectFields = $oBaseObject->getSelectFields();
1200 
1201  $sSelect = "select {$sSelectFields} from {$sArticleTable} where oxvarminprice >= 0 ";
1202  $sSelect .= $dPriceTo ? "and oxvarminprice <= " . (double)$dPriceTo . " " : " ";
1203  $sSelect .= $dPriceFrom ? "and oxvarminprice >= " . (double)$dPriceFrom . " " : " ";
1204 
1205  $sSelect .= " and ".$oBaseObject->getSqlActiveSnippet()." and {$sArticleTable}.oxissearch = 1";
1206 
1207  if ( !$this->_sCustomSorting ) {
1208  $sSelect .= " order by {$sArticleTable}.oxvarminprice asc , {$sArticleTable}.oxid";
1209  } else {
1210  $sSelect .= " order by {$this->_sCustomSorting}, {$sArticleTable}.oxid ";
1211  }
1212 
1213  return $sSelect;
1214  }
1215 
1223  protected function _getVendorSelect( $sVendorId )
1224  {
1225  $sArticleTable = getViewName('oxarticles');
1226  $oBaseObject = $this->getBaseObject();
1227  $sFieldNames = $oBaseObject->getSelectFields();
1228  $sSelect = "select $sFieldNames from $sArticleTable ";
1229  $sSelect .= "where $sArticleTable.oxvendorid = ".oxDb::getDb()->quote($sVendorId)." ";
1230  $sSelect .= " and " . $oBaseObject->getSqlActiveSnippet() . " and $sArticleTable.oxparentid = '' ";
1231 
1232  if ( $this->_sCustomSorting ) {
1233  $sSelect .= " ORDER BY {$this->_sCustomSorting} ";
1234  }
1235 
1236  return $sSelect;
1237  }
1238 
1246  protected function _getManufacturerSelect( $sManufacturerId )
1247  {
1248  $sArticleTable = getViewName('oxarticles');
1249  $oBaseObject = $this->getBaseObject();
1250  $sFieldNames = $oBaseObject->getSelectFields();
1251  $sSelect = "select $sFieldNames from $sArticleTable ";
1252  $sSelect .= "where $sArticleTable.oxmanufacturerid = ".oxDb::getDb()->quote($sManufacturerId)." ";
1253  $sSelect .= " and " . $oBaseObject->getSqlActiveSnippet() . " and $sArticleTable.oxparentid = '' ";
1254 
1255  if ( $this->_sCustomSorting ) {
1256  $sSelect .= " ORDER BY {$this->_sCustomSorting} ";
1257  }
1258 
1259  return $sSelect;
1260  }
1261 
1267  protected function _canUpdatePrices()
1268  {
1269  $oConfig = $this->getConfig();
1270  $blCan = false;
1271 
1272  // crontab is off?
1273  if ( !$oConfig->getConfigParam( "blUseCron" ) ) {
1274  $iTimeToUpdate = $oConfig->getConfigParam( "iTimeToUpdatePrices" );
1275  if ( !$iTimeToUpdate || $iTimeToUpdate <= oxRegistry::get("oxUtilsDate")->getTime() ) {
1276  $blCan = true;
1277  }
1278  }
1279  return $blCan;
1280  }
1281 
1282 }