oxbasketreservation.php

Go to the documentation of this file.
00001 <?php
00002 
00007 class oxBasketReservation extends oxSuperCfg
00008 {
00009     protected $_oReservations = null;
00010     protected $_aCurrentlyReserved = null;
00011 
00012 
00018     protected function _getReservationsId()
00019     {
00020         $sId = $this->getSession()->getVar('basketReservationToken');
00021         if (!$sId) {
00022             $sId = oxUtilsObject::getInstance()->generateUID();
00023             $this->getSession()->setVar('basketReservationToken', $sId);
00024         }
00025         return $sId;
00026     }
00027 
00035     protected function _loadReservations($sBasketId)
00036     {
00037         $oReservations = oxNew( 'oxuserbasket' );
00038         $aWhere = array( 'oxuserbaskets.oxuserid' => $sBasketId, 'oxuserbaskets.oxtitle' => 'reservations' );
00039 
00040         // creating if it does not exist
00041         if ( !$oReservations->assignRecord( $oReservations->buildSelectString( $aWhere ) ) ) {
00042             $oReservations->oxuserbaskets__oxtitle  = new oxField('reservations');
00043             $oReservations->oxuserbaskets__oxuserid = new oxField($sBasketId);
00044             // marking basket as new (it will not be saved in DB yet)
00045             $oReservations->setIsNewBasket();
00046         }
00047         return $oReservations;
00048     }
00049 
00055     public function getReservations()
00056     {
00057         if ($this->_oReservations) {
00058             return $this->_oReservations;
00059         }
00060 
00061         if (!$sBasketId = $this->_getReservationsId()) {
00062             return null;
00063         }
00064 
00065         $this->_oReservations = $this->_loadReservations($sBasketId);
00066 
00067         return $this->_oReservations;
00068     }
00069 
00075     protected function _getReservedItems()
00076     {
00077         if (isset($this->_aCurrentlyReserved)) {
00078             return $this->_aCurrentlyReserved;
00079         }
00080 
00081         $oReserved = $this->getReservations();
00082         if (!$oReserved) {
00083             return array();
00084         }
00085 
00086         $this->_aCurrentlyReserved = array();
00087         foreach ( $oReserved->getItems(false, false) as $oItem ) {
00088             if (!isset($this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value])) {
00089                 $this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value] = 0;
00090             }
00091             $this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value] += $oItem->oxuserbasketitems__oxamount->value;
00092         }
00093         return $this->_aCurrentlyReserved;
00094     }
00095 
00103     public function getReservedAmount($sArticleId)
00104     {
00105         $aCurrentlyReserved = $this->_getReservedItems();
00106         if (isset($aCurrentlyReserved[$sArticleId])) {
00107             return $aCurrentlyReserved[$sArticleId];
00108         }
00109         return 0;
00110     }
00111 
00119     protected function _basketDifference(oxBasket $oBasket)
00120     {
00121         $aDiff = $this->_getReservedItems();
00122         // refreshing history
00123         foreach ( $oBasket->getContents() as $oItem ) {
00124             $sProdId = $oItem->getProductId();
00125             if (!isset($aDiff[$sProdId])) {
00126                 $aDiff[$sProdId] = -$oItem->getAmount();
00127             } else {
00128                 $aDiff[$sProdId] -= $oItem->getAmount();
00129             }
00130         }
00131         return $aDiff;
00132     }
00133 
00143     protected function _reserveArticles($aBasketDiff)
00144     {
00145         $blAllowNegativeStock = $this->getConfig()->getConfigParam( 'blAllowNegativeStock' );
00146         $oDb = oxDb::getDb();
00147 
00148         $oReserved = $this->getReservations();
00149         foreach ($aBasketDiff as $sId => $dAmount) {
00150             if ($dAmount != 0) {
00151                 $oArticle = oxNew('oxarticle');
00152                 if ($oArticle->load($sId)) {
00153                     $oArticle->reduceStock(-$dAmount, $blAllowNegativeStock);
00154                     $oReserved->addItemToBasket( $sId, -$dAmount );
00155                 }
00156             }
00157         }
00158         $this->_aCurrentlyReserved = null;
00159     }
00160 
00168     public function reserveBasket(oxBasket $oBasket)
00169     {
00170         $this->_reserveArticles( $this->_basketDifference($oBasket) );
00171     }
00172 
00183     public function commitArticleReservation($sArticleId, $dAmount)
00184     {
00185         $dReserved = $this->getReservedAmount($sArticleId);
00186 
00187         if ($dReserved < $dAmount) {
00188             $dAmount = $dReserved;
00189         }
00190 
00191         $oArticle = oxNew( 'oxarticle' );
00192         $oArticle->load( $sArticleId );
00193 
00194         $this->getReservations()->addItemToBasket($sArticleId, -$dAmount);
00195         $oArticle->beforeUpdate();
00196         $oArticle->updateSoldAmount( $dAmount );
00197         $this->_aCurrentlyReserved = null;
00198     }
00199 
00208     public function discardArticleReservation($sArticleId)
00209     {
00210         $dReserved = $this->getReservedAmount($sArticleId);
00211         if ($dReserved) {
00212             $oArticle = oxNew('oxarticle');
00213             if ($oArticle->load($sArticleId)) {
00214                 $oArticle->reduceStock(-$dReserved, true);
00215                 $this->getReservations()->addItemToBasket($sArticleId, 0, null, true);
00216                 $this->_aCurrentlyReserved = null;
00217             }
00218         }
00219     }
00220 
00226     public function discardReservations()
00227     {
00228         foreach ( array_keys($this->_getReservedItems()) as $sArticleId) {
00229             $this->discardArticleReservation($sArticleId);
00230         }
00231         if ($this->_oReservations) {
00232             $this->_oReservations->delete();
00233             $this->_oReservations = null;
00234             $this->_aCurrentlyReserved = null;
00235         }
00236     }
00237 
00246     public function discardUnusedReservations($iLimit)
00247     {
00248         $oDb = oxDb::getDb(true);
00249         $iStartTime = oxUtilsDate::getInstance()->getTime() - (int) $this->getConfig()->getConfigParam( 'iPsBasketReservationTimeout' );
00250         $oRs = $oDb->execute("select oxid from oxuserbaskets where oxtitle = 'reservations' and oxupdate <= $iStartTime limit $iLimit");
00251         if ($oRs->EOF) {
00252             return;
00253         }
00254         $aFinished = array();
00255         while (!$oRs->EOF) {
00256             $aFinished[] = $oDb->quote($oRs->fields['oxid']);
00257             $oRs->MoveNext();
00258         }
00259         $oRs = $oDb->execute("select oxartid, oxamount from oxuserbasketitems where oxbasketid in (".implode(",", $aFinished).")");
00260         while (!$oRs->EOF) {
00261             $oArticle = oxNew('oxarticle');
00262             if ($oArticle->load($oRs->fields['oxartid'])) {
00263                 $oArticle->reduceStock(-$oRs->fields['oxamount'], true);
00264             }
00265             $oRs->MoveNext();
00266         }
00267         $oDb->execute("delete from oxuserbasketitems where oxbasketid in (".implode(",", $aFinished).")");
00268         $oDb->execute("delete from oxuserbaskets where oxid in (".implode(",", $aFinished).")");
00269         $this->_aCurrentlyReserved = null;
00270     }
00271 
00277     public function getTimeLeft()
00278     {
00279         $iTimeout = $this->getConfig()->getConfigParam( 'iPsBasketReservationTimeout' );
00280         if ($iTimeout > 0) {
00281             if ($oRev = $this->getReservations()) {
00282                 $iTimeout -= (oxUtilsDate::getInstance()->getTime() - $oRev->oxuserbaskets__oxupdate->value);
00283                 if ($iTimeout < 0) {
00284                     return 0;
00285                 }
00286                 return $iTimeout;
00287             }
00288         }
00289         return 0;
00290     }
00291 
00297     public function renewExpiration()
00298     {
00299         if ($oReserved = $this->getReservations()) {
00300             $iTime = oxUtilsDate::getInstance()->getTime();
00301             $oReserved->oxuserbaskets__oxupdate = new oxField( $iTime );
00302             $oReserved->save();
00303         }
00304     }
00305 }