OXID eShop CE  4.9.11
 All Classes Files Functions Variables Pages
oxbasketreservation.php
Go to the documentation of this file.
1 <?php
2 
8 {
9 
15  protected $_oReservations = null;
16 
22  protected $_aCurrentlyReserved = null;
23 
29  protected function _getReservationsId()
30  {
31  $sId = oxRegistry::getSession()->getVariable('basketReservationToken');
32  if (!$sId) {
33  $sId = oxUtilsObject::getInstance()->generateUId();
34  oxRegistry::getSession()->setVariable('basketReservationToken', $sId);
35  }
36 
37  return $sId;
38  }
39 
47  protected function _loadReservations($sBasketId)
48  {
49  $oReservations = oxNew('oxuserbasket');
50  $aWhere = array('oxuserbaskets.oxuserid' => $sBasketId, 'oxuserbaskets.oxtitle' => 'reservations');
51 
52  // creating if it does not exist
53  if (!$oReservations->assignRecord($oReservations->buildSelectString($aWhere))) {
54  $oReservations->oxuserbaskets__oxtitle = new oxField('reservations');
55  $oReservations->oxuserbaskets__oxuserid = new oxField($sBasketId);
56  // marking basket as new (it will not be saved in DB yet)
57  $oReservations->setIsNewBasket();
58  }
59 
60  return $oReservations;
61  }
62 
68  public function getReservations()
69  {
70  if ($this->_oReservations) {
71  return $this->_oReservations;
72  }
73 
74  if (!$sBasketId = $this->_getReservationsId()) {
75  return null;
76  }
77 
78  $this->_oReservations = $this->_loadReservations($sBasketId);
79 
80  return $this->_oReservations;
81  }
82 
88  protected function _getReservedItems()
89  {
90  if (isset($this->_aCurrentlyReserved)) {
92  }
93 
94  $oReserved = $this->getReservations();
95  if (!$oReserved) {
96  return array();
97  }
98 
99  $this->_aCurrentlyReserved = array();
100  foreach ($oReserved->getItems(false, false) as $oItem) {
101  if (!isset($this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value])) {
102  $this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value] = 0;
103  }
104  $this->_aCurrentlyReserved[$oItem->oxuserbasketitems__oxartid->value] += $oItem->oxuserbasketitems__oxamount->value;
105  }
106 
108  }
109 
117  public function getReservedAmount($sArticleId)
118  {
119  $aCurrentlyReserved = $this->_getReservedItems();
120  if (isset($aCurrentlyReserved[$sArticleId])) {
121  return $aCurrentlyReserved[$sArticleId];
122  }
123 
124  return 0;
125  }
126 
134  protected function _basketDifference(oxBasket $oBasket)
135  {
136  $aDiff = $this->_getReservedItems();
137  // refreshing history
138  foreach ($oBasket->getContents() as $oItem) {
139  $sProdId = $oItem->getProductId();
140  if (!isset($aDiff[$sProdId])) {
141  $aDiff[$sProdId] = -$oItem->getAmount();
142  } else {
143  $aDiff[$sProdId] -= $oItem->getAmount();
144  }
145  }
146 
147  return $aDiff;
148  }
149 
157  protected function _reserveArticles($aBasketDiff)
158  {
159  $blAllowNegativeStock = $this->getConfig()->getConfigParam('blAllowNegativeStock');
160 
161  $oReserved = $this->getReservations();
162  foreach ($aBasketDiff as $sId => $dAmount) {
163  if ($dAmount != 0) {
164  $oArticle = oxNew('oxarticle');
165  if ($oArticle->load($sId)) {
166  $oArticle->reduceStock(-$dAmount, $blAllowNegativeStock);
167  $oReserved->addItemToBasket($sId, -$dAmount);
168  }
169  }
170  }
171  $this->_aCurrentlyReserved = null;
172  }
173 
179  public function reserveBasket(oxBasket $oBasket)
180  {
181  if (!$this->isAdmin()) {
182  $this->_reserveArticles($this->_basketDifference($oBasket));
183  }
184  }
185 
194  public function commitArticleReservation($sArticleId, $dAmount)
195  {
196  $dReserved = $this->getReservedAmount($sArticleId);
197 
198  if ($dReserved < $dAmount) {
199  $dAmount = $dReserved;
200  }
201 
202  $oArticle = oxNew('oxarticle');
203  $oArticle->load($sArticleId);
204 
205  $this->getReservations()->addItemToBasket($sArticleId, -$dAmount);
206  $oArticle->beforeUpdate();
207  $oArticle->updateSoldAmount($dAmount);
208  $this->_aCurrentlyReserved = null;
209  }
210 
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 
233  public function discardReservations()
234  {
235  foreach (array_keys($this->_getReservedItems()) as $sArticleId) {
236  $this->discardArticleReservation($sArticleId);
237  }
238  if ($this->_oReservations) {
239  $this->_oReservations->delete();
240  $this->_oReservations = null;
241  $this->_aCurrentlyReserved = null;
242  }
243  }
244 
253  public function discardUnusedReservations($iLimit)
254  {
256  $iStartTime = oxRegistry::get("oxUtilsDate")->getTime() - (int) $this->getConfig()->getConfigParam('iPsBasketReservationTimeout');
257  $oRs = $oDb->select("select oxid from oxuserbaskets where oxtitle = 'reservations' and oxupdate <= $iStartTime limit $iLimit", false, false);
258  if ($oRs->EOF) {
259  return;
260  }
261  $aFinished = array();
262  while (!$oRs->EOF) {
263  $aFinished[] = $oDb->quote($oRs->fields['oxid']);
264  $oRs->MoveNext();
265  }
266  $oRs = $oDb->select("select oxartid, oxamount from oxuserbasketitems where oxbasketid in (" . implode(",", $aFinished) . ")", false, false);
267  while (!$oRs->EOF) {
268  $oArticle = oxNew('oxarticle');
269  if ($oArticle->load($oRs->fields['oxartid'])) {
270  $oArticle->reduceStock(-$oRs->fields['oxamount'], true);
271  }
272  $oRs->MoveNext();
273  }
274  $oDb->execute("delete from oxuserbasketitems where oxbasketid in (" . implode(",", $aFinished) . ")");
275  $oDb->execute("delete from oxuserbaskets where oxid in (" . implode(",", $aFinished) . ")");
276 
277  // cleanup basket history also..
278  $oDb->execute("delete from oxuserbaskets where oxtitle = 'savedbasket' and oxupdate <= $iStartTime");
279 
280  $this->_aCurrentlyReserved = null;
281  }
282 
288  public function getTimeLeft()
289  {
290  $iTimeout = $this->getConfig()->getConfigParam('iPsBasketReservationTimeout');
291  if ($iTimeout > 0) {
292  $oRev = $this->getReservations();
293  if ($oRev && $oRev->getId()) {
294  $iTimeout -= (oxRegistry::get("oxUtilsDate")->getTime() - (int) $oRev->oxuserbaskets__oxupdate->value);
295  oxRegistry::getSession()->setVariable("iBasketReservationTimeout", $oRev->oxuserbaskets__oxupdate->value);
296  } elseif (($iSessionTimeout = oxRegistry::getSession()->getVariable("iBasketReservationTimeout"))) {
297  $iTimeout -= (oxRegistry::get("oxUtilsDate")->getTime() - (int) $iSessionTimeout);
298  }
299 
300  return $iTimeout < 0 ? 0 : $iTimeout;
301  }
302 
303  return 0;
304  }
305 
309  public function renewExpiration()
310  {
311  if ($oReserved = $this->getReservations()) {
312  $iTime = oxRegistry::get("oxUtilsDate")->getTime();
313  $oReserved->oxuserbaskets__oxupdate = new oxField($iTime);
314  $oReserved->save();
315 
316  oxRegistry::getSession()->deleteVariable("iBasketReservationTimeout");
317  }
318  }
319 }