OXID eShop CE  4.8.12
 All Classes Files Functions Variables Pages
oxbasketreservation.php
Go to the documentation of this file.
1 <?php
2 
8 {
14  protected $_oReservations = null;
15 
21  protected $_aCurrentlyReserved = null;
22 
28  protected function _getReservationsId()
29  {
30  $sId = oxSession::getVar('basketReservationToken');
31  if (!$sId) {
32  $sId = oxUtilsObject::getInstance()->generateUId();
33  oxSession::setVar( 'basketReservationToken', $sId );
34  }
35  return $sId;
36  }
37 
45  protected function _loadReservations($sBasketId)
46  {
47  $oReservations = oxNew( 'oxuserbasket' );
48  $aWhere = array( 'oxuserbaskets.oxuserid' => $sBasketId, 'oxuserbaskets.oxtitle' => 'reservations' );
49 
50  // creating if it does not exist
51  if ( !$oReservations->assignRecord( $oReservations->buildSelectString( $aWhere ) ) ) {
52  $oReservations->oxuserbaskets__oxtitle = new oxField('reservations');
53  $oReservations->oxuserbaskets__oxuserid = new oxField($sBasketId);
54  // marking basket as new (it will not be saved in DB yet)
55  $oReservations->setIsNewBasket();
56  }
57  return $oReservations;
58  }
59 
65  public function getReservations()
66  {
67  if ($this->_oReservations) {
68  return $this->_oReservations;
69  }
70 
71  if (!$sBasketId = $this->_getReservationsId()) {
72  return null;
73  }
74 
75  $this->_oReservations = $this->_loadReservations($sBasketId);
76 
77  return $this->_oReservations;
78  }
79 
85  protected function _getReservedItems()
86  {
87  if (isset($this->_aCurrentlyReserved)) {
89  }
90 
91  $oReserved = $this->getReservations();
92  if (!$oReserved) {
93  return array();
94  }
95 
96  $this->_aCurrentlyReserved = array();
97  foreach ( $oReserved->getItems(false, false) as $oItem ) {
98  if (!isset($this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value])) {
99  $this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value] = 0;
100  }
101  $this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value] += $oItem->oxuserbasketitems__oxamount->value;
102  }
104  }
105 
113  public function getReservedAmount($sArticleId)
114  {
115  $aCurrentlyReserved = $this->_getReservedItems();
116  if (isset($aCurrentlyReserved[$sArticleId])) {
117  return $aCurrentlyReserved[$sArticleId];
118  }
119  return 0;
120  }
121 
129  protected function _basketDifference(oxBasket $oBasket)
130  {
131  $aDiff = $this->_getReservedItems();
132  // refreshing history
133  foreach ( $oBasket->getContents() as $oItem ) {
134  $sProdId = $oItem->getProductId();
135  if (!isset($aDiff[$sProdId])) {
136  $aDiff[$sProdId] = -$oItem->getAmount();
137  } else {
138  $aDiff[$sProdId] -= $oItem->getAmount();
139  }
140  }
141  return $aDiff;
142  }
143 
153  protected function _reserveArticles($aBasketDiff)
154  {
155  $blAllowNegativeStock = $this->getConfig()->getConfigParam( 'blAllowNegativeStock' );
156 
157  $oReserved = $this->getReservations();
158  foreach ($aBasketDiff as $sId => $dAmount) {
159  if ($dAmount != 0) {
160  $oArticle = oxNew('oxarticle');
161  if ($oArticle->load($sId)) {
162  $oArticle->reduceStock(-$dAmount, $blAllowNegativeStock);
163  $oReserved->addItemToBasket( $sId, -$dAmount );
164  }
165  }
166  }
167  $this->_aCurrentlyReserved = null;
168  }
169 
177  public function reserveBasket(oxBasket $oBasket)
178  {
179  $this->_reserveArticles( $this->_basketDifference($oBasket) );
180  }
181 
192  public function commitArticleReservation($sArticleId, $dAmount)
193  {
194  $dReserved = $this->getReservedAmount($sArticleId);
195 
196  if ($dReserved < $dAmount) {
197  $dAmount = $dReserved;
198  }
199 
200  $oArticle = oxNew( 'oxarticle' );
201  $oArticle->load( $sArticleId );
202 
203  $this->getReservations()->addItemToBasket($sArticleId, -$dAmount);
204  $oArticle->beforeUpdate();
205  $oArticle->updateSoldAmount( $dAmount );
206  $this->_aCurrentlyReserved = null;
207  }
208 
217  public function discardArticleReservation($sArticleId)
218  {
219  $dReserved = $this->getReservedAmount($sArticleId);
220  if ($dReserved) {
221  $oArticle = oxNew('oxarticle');
222  if ($oArticle->load($sArticleId)) {
223  $oArticle->reduceStock(-$dReserved, true);
224  $this->getReservations()->addItemToBasket($sArticleId, 0, null, true);
225  $this->_aCurrentlyReserved = null;
226  }
227  }
228  }
229 
235  public function discardReservations()
236  {
237  foreach ( array_keys($this->_getReservedItems()) as $sArticleId) {
238  $this->discardArticleReservation($sArticleId);
239  }
240  if ($this->_oReservations) {
241  $this->_oReservations->delete();
242  $this->_oReservations = null;
243  $this->_aCurrentlyReserved = null;
244  }
245  }
246 
255  public function discardUnusedReservations($iLimit)
256  {
258  $iStartTime = oxRegistry::get("oxUtilsDate")->getTime() - (int) $this->getConfig()->getConfigParam( 'iPsBasketReservationTimeout' );
259  $oRs = $oDb->select("select oxid from oxuserbaskets where oxtitle = 'reservations' and oxupdate <= $iStartTime limit $iLimit", false, false);
260  if ($oRs->EOF) {
261  return;
262  }
263  $aFinished = array();
264  while (!$oRs->EOF) {
265  $aFinished[] = $oDb->quote($oRs->fields['oxid']);
266  $oRs->MoveNext();
267  }
268  $oRs = $oDb->select("select oxartid, oxamount from oxuserbasketitems where oxbasketid in (".implode(",", $aFinished).")", false, false );
269  while (!$oRs->EOF) {
270  $oArticle = oxNew('oxarticle');
271  if ($oArticle->load($oRs->fields['oxartid'])) {
272  $oArticle->reduceStock(-$oRs->fields['oxamount'], true);
273  }
274  $oRs->MoveNext();
275  }
276  $oDb->execute("delete from oxuserbasketitems where oxbasketid in (".implode(",", $aFinished).")");
277  $oDb->execute("delete from oxuserbaskets where oxid in (".implode(",", $aFinished).")");
278 
279  // cleanup basket history also..
280  $oDb->execute("delete from oxuserbaskets where oxtitle = 'savedbasket' and oxupdate <= $iStartTime");
281 
282  $this->_aCurrentlyReserved = null;
283  }
284 
290  public function getTimeLeft()
291  {
292  $iTimeout = $this->getConfig()->getConfigParam( 'iPsBasketReservationTimeout' );
293  if ( $iTimeout > 0 ) {
294  $oRev = $this->getReservations();
295  if ( $oRev && $oRev->getId() ) {
296  $iTimeout -= ( oxRegistry::get("oxUtilsDate")->getTime() - (int) $oRev->oxuserbaskets__oxupdate->value );
297  oxSession::setVar( "iBasketReservationTimeout", $oRev->oxuserbaskets__oxupdate->value );
298  } elseif ( ( $iSessionTimeout = oxSession::getVar( "iBasketReservationTimeout" ) ) ) {
299  $iTimeout -= ( oxRegistry::get("oxUtilsDate")->getTime() - (int) $iSessionTimeout );
300  }
301 
302  return $iTimeout < 0 ? 0 : $iTimeout;
303  }
304  return 0;
305  }
306 
312  public function renewExpiration()
313  {
314  if ($oReserved = $this->getReservations()) {
315  $iTime = oxRegistry::get("oxUtilsDate")->getTime();
316  $oReserved->oxuserbaskets__oxupdate = new oxField( $iTime );
317  $oReserved->save();
318 
319  oxSession::deleteVar( "iBasketReservationTimeout" );
320  }
321  }
322 }