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
00041 if ( !$oReservations->assignRecord( $oReservations->buildSelectString( $aWhere ) ) ) {
00042 $oReservations->oxuserbaskets__oxtitle = new oxField('reservations');
00043 $oReservations->oxuserbaskets__oxuserid = new oxField($sBasketId);
00044
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
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 }