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 
00157         $oReserved = $this->getReservations();
00158         foreach ($aBasketDiff as $sId => $dAmount) {
00159             if ($dAmount != 0) {
00160                 $oArticle = oxNew('oxarticle');
00161                 if ($oArticle->load($sId)) {
00162                     $oArticle->reduceStock(-$dAmount, $blAllowNegativeStock);
00163                     $oReserved->addItemToBasket( $sId, -$dAmount );
00164                 }
00165             }
00166         }
00167         $this->_aCurrentlyReserved = null;
00168     }
00169 
00177     public function reserveBasket(oxBasket $oBasket)
00178     {
00179         $this->_reserveArticles( $this->_basketDifference($oBasket) );
00180     }
00181 
00192     public function commitArticleReservation($sArticleId, $dAmount)
00193     {
00194         $dReserved = $this->getReservedAmount($sArticleId);
00195 
00196         if ($dReserved < $dAmount) {
00197             $dAmount = $dReserved;
00198         }
00199 
00200         $oArticle = oxNew( 'oxarticle' );
00201         $oArticle->load( $sArticleId );
00202 
00203         $this->getReservations()->addItemToBasket($sArticleId, -$dAmount);
00204         $oArticle->beforeUpdate();
00205         $oArticle->updateSoldAmount( $dAmount );
00206         $this->_aCurrentlyReserved = null;
00207     }
00208 
00217     public function discardArticleReservation($sArticleId)
00218     {
00219         $dReserved = $this->getReservedAmount($sArticleId);
00220         if ($dReserved) {
00221             $oArticle = oxNew('oxarticle');
00222             if ($oArticle->load($sArticleId)) {
00223                 $oArticle->reduceStock(-$dReserved, true);
00224                 $this->getReservations()->addItemToBasket($sArticleId, 0, null, true);
00225                 $this->_aCurrentlyReserved = null;
00226             }
00227         }
00228     }
00229 
00235     public function discardReservations()
00236     {
00237         foreach ( array_keys($this->_getReservedItems()) as $sArticleId) {
00238             $this->discardArticleReservation($sArticleId);
00239         }
00240         if ($this->_oReservations) {
00241             $this->_oReservations->delete();
00242             $this->_oReservations = null;
00243             $this->_aCurrentlyReserved = null;
00244         }
00245     }
00246 
00255     public function discardUnusedReservations($iLimit)
00256     {
00257         $oDb = oxDb::getDb( oxDb::FETCH_MODE_ASSOC );
00258         $iStartTime = oxRegistry::get("oxUtilsDate")->getTime() - (int) $this->getConfig()->getConfigParam( 'iPsBasketReservationTimeout' );
00259         $oRs = $oDb->select("select oxid from oxuserbaskets where oxtitle = 'reservations' and oxupdate <= $iStartTime limit $iLimit", false, false);
00260         if ($oRs->EOF) {
00261             return;
00262         }
00263         $aFinished = array();
00264         while (!$oRs->EOF) {
00265             $aFinished[] = $oDb->quote($oRs->fields['oxid']);
00266             $oRs->MoveNext();
00267         }
00268         $oRs = $oDb->select("select oxartid, oxamount from oxuserbasketitems where oxbasketid in (".implode(",", $aFinished).")", false, false );
00269         while (!$oRs->EOF) {
00270             $oArticle = oxNew('oxarticle');
00271             if ($oArticle->load($oRs->fields['oxartid'])) {
00272                 $oArticle->reduceStock(-$oRs->fields['oxamount'], true);
00273             }
00274             $oRs->MoveNext();
00275         }
00276         $oDb->execute("delete from oxuserbasketitems where oxbasketid in (".implode(",", $aFinished).")");
00277         $oDb->execute("delete from oxuserbaskets where oxid in (".implode(",", $aFinished).")");
00278 
00279         // cleanup basket history also..
00280         $oDb->execute("delete from oxuserbaskets where oxtitle = 'savedbasket' and oxupdate <= $iStartTime");
00281 
00282         $this->_aCurrentlyReserved = null;
00283     }
00284 
00290     public function getTimeLeft()
00291     {
00292         $iTimeout = $this->getConfig()->getConfigParam( 'iPsBasketReservationTimeout' );
00293         if ( $iTimeout > 0 ) {
00294             $oRev = $this->getReservations();
00295             if ( $oRev && $oRev->getId() ) {
00296                 $iTimeout -= ( oxRegistry::get("oxUtilsDate")->getTime() - (int) $oRev->oxuserbaskets__oxupdate->value );
00297                 oxSession::setVar( "iBasketReservationTimeout", $oRev->oxuserbaskets__oxupdate->value );
00298             } elseif ( ( $iSessionTimeout = oxSession::getVar( "iBasketReservationTimeout" ) ) ) {
00299                 $iTimeout -= ( oxRegistry::get("oxUtilsDate")->getTime() - (int) $iSessionTimeout );
00300             }
00301 
00302             return $iTimeout < 0 ? 0 : $iTimeout;
00303         }
00304         return 0;
00305     }
00306 
00312     public function renewExpiration()
00313     {
00314         if ($oReserved = $this->getReservations()) {
00315             $iTime = oxRegistry::get("oxUtilsDate")->getTime();
00316             $oReserved->oxuserbaskets__oxupdate = new oxField( $iTime );
00317             $oReserved->save();
00318 
00319             oxSession::deleteVar( "iBasketReservationTimeout" );
00320         }
00321     }
00322 }