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
00051 if ( !$oReservations->assignRecord( $oReservations->buildSelectString( $aWhere ) ) ) {
00052 $oReservations->oxuserbaskets__oxtitle = new oxField('reservations');
00053 $oReservations->oxuserbaskets__oxuserid = new oxField($sBasketId);
00054
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
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
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 }