oxbasketreservation.php

Go to the documentation of this file.
00001 <?php
00002 
00007 class oxBasketReservation extends oxSuperCfg
00008 {
00014     protected $_oReservations = null;
00015 
00021     protected $_aCurrentlyReserved = null;
00022 
00028     protected function _getReservationsId()
00029     {
00030         $sId = oxSession::getVar('basketReservationToken');
00031         if (!$sId) {
00032             $sId = oxUtilsObject::getInstance()->generateUId();
00033             oxSession::setVar( 'basketReservationToken', $sId );
00034         }
00035         return $sId;
00036     }
00037 
00045     protected function _loadReservations($sBasketId)
00046     {
00047         $oReservations = oxNew( 'oxuserbasket' );
00048         $aWhere = array( 'oxuserbaskets.oxuserid' => $sBasketId, 'oxuserbaskets.oxtitle' => 'reservations' );
00049 
00050         // creating if it does not exist
00051         if ( !$oReservations->assignRecord( $oReservations->buildSelectString( $aWhere ) ) ) {
00052             $oReservations->oxuserbaskets__oxtitle  = new oxField('reservations');
00053             $oReservations->oxuserbaskets__oxuserid = new oxField($sBasketId);
00054             // marking basket as new (it will not be saved in DB yet)
00055             $oReservations->setIsNewBasket();
00056         }
00057         return $oReservations;
00058     }
00059 
00065     public function getReservations()
00066     {
00067         if ($this->_oReservations) {
00068             return $this->_oReservations;
00069         }
00070 
00071         if (!$sBasketId = $this->_getReservationsId()) {
00072             return null;
00073         }
00074 
00075         $this->_oReservations = $this->_loadReservations($sBasketId);
00076 
00077         return $this->_oReservations;
00078     }
00079 
00085     protected function _getReservedItems()
00086     {
00087         if (isset($this->_aCurrentlyReserved)) {
00088             return $this->_aCurrentlyReserved;
00089         }
00090 
00091         $oReserved = $this->getReservations();
00092         if (!$oReserved) {
00093             return array();
00094         }
00095 
00096         $this->_aCurrentlyReserved = array();
00097         foreach ( $oReserved->getItems(false, false) as $oItem ) {
00098             if (!isset($this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value])) {
00099                 $this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value] = 0;
00100             }
00101             $this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value] += $oItem->oxuserbasketitems__oxamount->value;
00102         }
00103         return $this->_aCurrentlyReserved;
00104     }
00105 
00113     public function getReservedAmount($sArticleId)
00114     {
00115         $aCurrentlyReserved = $this->_getReservedItems();
00116         if (isset($aCurrentlyReserved[$sArticleId])) {
00117             return $aCurrentlyReserved[$sArticleId];
00118         }
00119         return 0;
00120     }
00121 
00129     protected function _basketDifference(oxBasket $oBasket)
00130     {
00131         $aDiff = $this->_getReservedItems();
00132         // refreshing history
00133         foreach ( $oBasket->getContents() as $oItem ) {
00134             $sProdId = $oItem->getProductId();
00135             if (!isset($aDiff[$sProdId])) {
00136                 $aDiff[$sProdId] = -$oItem->getAmount();
00137             } else {
00138                 $aDiff[$sProdId] -= $oItem->getAmount();
00139             }
00140         }
00141         return $aDiff;
00142     }
00143 
00153     protected function _reserveArticles($aBasketDiff)
00154     {
00155         $blAllowNegativeStock = $this->getConfig()->getConfigParam( 'blAllowNegativeStock' );
00156         $oDb = oxDb::getDb();
00157 
00158         $oReserved = $this->getReservations();
00159         foreach ($aBasketDiff as $sId => $dAmount) {
00160             if ($dAmount != 0) {
00161                 $oArticle = oxNew('oxarticle');
00162                 if ($oArticle->load($sId)) {
00163                     $oArticle->reduceStock(-$dAmount, $blAllowNegativeStock);
00164                     $oReserved->addItemToBasket( $sId, -$dAmount );
00165                 }
00166             }
00167         }
00168         $this->_aCurrentlyReserved = null;
00169     }
00170 
00178     public function reserveBasket(oxBasket $oBasket)
00179     {
00180         $this->_reserveArticles( $this->_basketDifference($oBasket) );
00181     }
00182 
00193     public function commitArticleReservation($sArticleId, $dAmount)
00194     {
00195         $dReserved = $this->getReservedAmount($sArticleId);
00196 
00197         if ($dReserved < $dAmount) {
00198             $dAmount = $dReserved;
00199         }
00200 
00201         $oArticle = oxNew( 'oxarticle' );
00202         $oArticle->load( $sArticleId );
00203 
00204         $this->getReservations()->addItemToBasket($sArticleId, -$dAmount);
00205         $oArticle->beforeUpdate();
00206         $oArticle->updateSoldAmount( $dAmount );
00207         $this->_aCurrentlyReserved = null;
00208     }
00209 
00218     public function discardArticleReservation($sArticleId)
00219     {
00220         $dReserved = $this->getReservedAmount($sArticleId);
00221         if ($dReserved) {
00222             $oArticle = oxNew('oxarticle');
00223             if ($oArticle->load($sArticleId)) {
00224                 $oArticle->reduceStock(-$dReserved, true);
00225                 $this->getReservations()->addItemToBasket($sArticleId, 0, null, true);
00226                 $this->_aCurrentlyReserved = null;
00227             }
00228         }
00229     }
00230 
00236     public function discardReservations()
00237     {
00238         foreach ( array_keys($this->_getReservedItems()) as $sArticleId) {
00239             $this->discardArticleReservation($sArticleId);
00240         }
00241         if ($this->_oReservations) {
00242             $this->_oReservations->delete();
00243             $this->_oReservations = null;
00244             $this->_aCurrentlyReserved = null;
00245         }
00246     }
00247 
00256     public function discardUnusedReservations($iLimit)
00257     {
00258         $oDb = oxDb::getDb(true);
00259         $iStartTime = oxUtilsDate::getInstance()->getTime() - (int) $this->getConfig()->getConfigParam( 'iPsBasketReservationTimeout' );
00260         $oRs = $oDb->execute("select oxid from oxuserbaskets where oxtitle = 'reservations' and oxupdate <= $iStartTime limit $iLimit");
00261         if ($oRs->EOF) {
00262             return;
00263         }
00264         $aFinished = array();
00265         while (!$oRs->EOF) {
00266             $aFinished[] = $oDb->quote($oRs->fields['oxid']);
00267             $oRs->MoveNext();
00268         }
00269         $oRs = $oDb->execute("select oxartid, oxamount from oxuserbasketitems where oxbasketid in (".implode(",", $aFinished).")");
00270         while (!$oRs->EOF) {
00271             $oArticle = oxNew('oxarticle');
00272             if ($oArticle->load($oRs->fields['oxartid'])) {
00273                 $oArticle->reduceStock(-$oRs->fields['oxamount'], true);
00274             }
00275             $oRs->MoveNext();
00276         }
00277         $oDb->execute("delete from oxuserbasketitems where oxbasketid in (".implode(",", $aFinished).")");
00278         $oDb->execute("delete from oxuserbaskets where oxid in (".implode(",", $aFinished).")");
00279 
00280         // cleanup basket history also..
00281         $oDb->execute("delete from oxuserbaskets where oxtitle = 'savedbasket' and oxupdate <= $iStartTime");
00282 
00283         $this->_aCurrentlyReserved = null;
00284     }
00285 
00291     public function getTimeLeft()
00292     {
00293         $iTimeout = $this->getConfig()->getConfigParam( 'iPsBasketReservationTimeout' );
00294         if ( $iTimeout > 0 ) {
00295             $oRev = $this->getReservations();
00296             if ( $oRev && $oRev->getId() ) {
00297                 $iTimeout -= ( oxUtilsDate::getInstance()->getTime() - (int) $oRev->oxuserbaskets__oxupdate->value );
00298                 oxSession::setVar( "iBasketReservationTimeout", $oRev->oxuserbaskets__oxupdate->value );
00299             } elseif ( ( $iSessionTimeout = oxSession::getVar( "iBasketReservationTimeout" ) ) ) {
00300                 $iTimeout -= ( oxUtilsDate::getInstance()->getTime() - (int) $iSessionTimeout );
00301             }
00302 
00303             return $iTimeout < 0 ? 0 : $iTimeout;
00304         }
00305         return 0;
00306     }
00307 
00313     public function renewExpiration()
00314     {
00315         if ($oReserved = $this->getReservations()) {
00316             $iTime = oxUtilsDate::getInstance()->getTime();
00317             $oReserved->oxuserbaskets__oxupdate = new oxField( $iTime );
00318             $oReserved->save();
00319 
00320             oxSession::deleteVar( "iBasketReservationTimeout" );
00321         }
00322     }
00323 }