oxbasketreservation.php

Go to the documentation of this file.
00001 <?php
00002 
00007 class oxBasketReservation extends oxSuperCfg
00008 {
00009 
00015     protected $_oReservations = null;
00016 
00022     protected $_aCurrentlyReserved = null;
00023 
00029     protected function _getReservationsId()
00030     {
00031         $sId = oxRegistry::getSession()->getVariable('basketReservationToken');
00032         if (!$sId) {
00033             $sId = oxUtilsObject::getInstance()->generateUId();
00034             oxRegistry::getSession()->setVariable('basketReservationToken', $sId);
00035         }
00036 
00037         return $sId;
00038     }
00039 
00047     protected function _loadReservations($sBasketId)
00048     {
00049         $oReservations = oxNew('oxuserbasket');
00050         $aWhere = array('oxuserbaskets.oxuserid' => $sBasketId, 'oxuserbaskets.oxtitle' => 'reservations');
00051 
00052         // creating if it does not exist
00053         if (!$oReservations->assignRecord($oReservations->buildSelectString($aWhere))) {
00054             $oReservations->oxuserbaskets__oxtitle = new oxField('reservations');
00055             $oReservations->oxuserbaskets__oxuserid = new oxField($sBasketId);
00056             // marking basket as new (it will not be saved in DB yet)
00057             $oReservations->setIsNewBasket();
00058         }
00059 
00060         return $oReservations;
00061     }
00062 
00068     public function getReservations()
00069     {
00070         if ($this->_oReservations) {
00071             return $this->_oReservations;
00072         }
00073 
00074         if (!$sBasketId = $this->_getReservationsId()) {
00075             return null;
00076         }
00077 
00078         $this->_oReservations = $this->_loadReservations($sBasketId);
00079 
00080         return $this->_oReservations;
00081     }
00082 
00088     protected function _getReservedItems()
00089     {
00090         if (isset($this->_aCurrentlyReserved)) {
00091             return $this->_aCurrentlyReserved;
00092         }
00093 
00094         $oReserved = $this->getReservations();
00095         if (!$oReserved) {
00096             return array();
00097         }
00098 
00099         $this->_aCurrentlyReserved = array();
00100         foreach ($oReserved->getItems(false, false) as $oItem) {
00101             if (!isset($this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value])) {
00102                 $this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value] = 0;
00103             }
00104             $this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value] += $oItem->oxuserbasketitems__oxamount->value;
00105         }
00106 
00107         return $this->_aCurrentlyReserved;
00108     }
00109 
00117     public function getReservedAmount($sArticleId)
00118     {
00119         $aCurrentlyReserved = $this->_getReservedItems();
00120         if (isset($aCurrentlyReserved[$sArticleId])) {
00121             return $aCurrentlyReserved[$sArticleId];
00122         }
00123 
00124         return 0;
00125     }
00126 
00134     protected function _basketDifference(oxBasket $oBasket)
00135     {
00136         $aDiff = $this->_getReservedItems();
00137         // refreshing history
00138         foreach ($oBasket->getContents() as $oItem) {
00139             $sProdId = $oItem->getProductId();
00140             if (!isset($aDiff[$sProdId])) {
00141                 $aDiff[$sProdId] = -$oItem->getAmount();
00142             } else {
00143                 $aDiff[$sProdId] -= $oItem->getAmount();
00144             }
00145         }
00146 
00147         return $aDiff;
00148     }
00149 
00157     protected function _reserveArticles($aBasketDiff)
00158     {
00159         $blAllowNegativeStock = $this->getConfig()->getConfigParam('blAllowNegativeStock');
00160 
00161         $oReserved = $this->getReservations();
00162         foreach ($aBasketDiff as $sId => $dAmount) {
00163             if ($dAmount != 0) {
00164                 $oArticle = oxNew('oxarticle');
00165                 if ($oArticle->load($sId)) {
00166                     $oArticle->reduceStock(-$dAmount, $blAllowNegativeStock);
00167                     $oReserved->addItemToBasket($sId, -$dAmount);
00168                 }
00169             }
00170         }
00171         $this->_aCurrentlyReserved = null;
00172     }
00173 
00179     public function reserveBasket(oxBasket $oBasket)
00180     {
00181         $this->_reserveArticles($this->_basketDifference($oBasket));
00182     }
00183 
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 
00215     public function discardArticleReservation($sArticleId)
00216     {
00217         $dReserved = $this->getReservedAmount($sArticleId);
00218         if ($dReserved) {
00219             $oArticle = oxNew('oxarticle');
00220             if ($oArticle->load($sArticleId)) {
00221                 $oArticle->reduceStock(-$dReserved, true);
00222                 $this->getReservations()->addItemToBasket($sArticleId, 0, null, true);
00223                 $this->_aCurrentlyReserved = null;
00224             }
00225         }
00226     }
00227 
00231     public function discardReservations()
00232     {
00233         foreach (array_keys($this->_getReservedItems()) as $sArticleId) {
00234             $this->discardArticleReservation($sArticleId);
00235         }
00236         if ($this->_oReservations) {
00237             $this->_oReservations->delete();
00238             $this->_oReservations = null;
00239             $this->_aCurrentlyReserved = null;
00240         }
00241     }
00242 
00251     public function discardUnusedReservations($iLimit)
00252     {
00253         $oDb = oxDb::getDb(oxDb::FETCH_MODE_ASSOC);
00254         $iStartTime = oxRegistry::get("oxUtilsDate")->getTime() - (int) $this->getConfig()->getConfigParam('iPsBasketReservationTimeout');
00255         $oRs = $oDb->select("select oxid from oxuserbaskets where oxtitle = 'reservations' and oxupdate <= $iStartTime limit $iLimit", false, false);
00256         if ($oRs->EOF) {
00257             return;
00258         }
00259         $aFinished = array();
00260         while (!$oRs->EOF) {
00261             $aFinished[] = $oDb->quote($oRs->fields['oxid']);
00262             $oRs->MoveNext();
00263         }
00264         $oRs = $oDb->select("select oxartid, oxamount from oxuserbasketitems where oxbasketid in (" . implode(",", $aFinished) . ")", false, false);
00265         while (!$oRs->EOF) {
00266             $oArticle = oxNew('oxarticle');
00267             if ($oArticle->load($oRs->fields['oxartid'])) {
00268                 $oArticle->reduceStock(-$oRs->fields['oxamount'], true);
00269             }
00270             $oRs->MoveNext();
00271         }
00272         $oDb->execute("delete from oxuserbasketitems where oxbasketid in (" . implode(",", $aFinished) . ")");
00273         $oDb->execute("delete from oxuserbaskets where oxid in (" . implode(",", $aFinished) . ")");
00274 
00275         // cleanup basket history also..
00276         $oDb->execute("delete from oxuserbaskets where oxtitle = 'savedbasket' and oxupdate <= $iStartTime");
00277 
00278         $this->_aCurrentlyReserved = null;
00279     }
00280 
00286     public function getTimeLeft()
00287     {
00288         $iTimeout = $this->getConfig()->getConfigParam('iPsBasketReservationTimeout');
00289         if ($iTimeout > 0) {
00290             $oRev = $this->getReservations();
00291             if ($oRev && $oRev->getId()) {
00292                 $iTimeout -= (oxRegistry::get("oxUtilsDate")->getTime() - (int) $oRev->oxuserbaskets__oxupdate->value);
00293                 oxRegistry::getSession()->setVariable("iBasketReservationTimeout", $oRev->oxuserbaskets__oxupdate->value);
00294             } elseif (($iSessionTimeout = oxRegistry::getSession()->getVariable("iBasketReservationTimeout"))) {
00295                 $iTimeout -= (oxRegistry::get("oxUtilsDate")->getTime() - (int) $iSessionTimeout);
00296             }
00297 
00298             return $iTimeout < 0 ? 0 : $iTimeout;
00299         }
00300 
00301         return 0;
00302     }
00303 
00307     public function renewExpiration()
00308     {
00309         if ($oReserved = $this->getReservations()) {
00310             $iTime = oxRegistry::get("oxUtilsDate")->getTime();
00311             $oReserved->oxuserbaskets__oxupdate = new oxField($iTime);
00312             $oReserved->save();
00313 
00314             oxRegistry::getSession()->deleteVariable("iBasketReservationTimeout");
00315         }
00316     }
00317 }