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
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
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 }