|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZBasket class 00004 // 00005 // Created on: <04-Jul-2002 15:28:58 bf> 00006 // 00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00008 // SOFTWARE NAME: eZ Publish 00009 // SOFTWARE RELEASE: 4.0.x 00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS 00011 // SOFTWARE LICENSE: GNU General Public License v2.0 00012 // NOTICE: > 00013 // This program is free software; you can redistribute it and/or 00014 // modify it under the terms of version 2.0 of the GNU General 00015 // Public License as published by the Free Software Foundation. 00016 // 00017 // This program is distributed in the hope that it will be useful, 00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of version 2.0 of the GNU General 00023 // Public License along with this program; if not, write to the Free 00024 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00025 // MA 02110-1301, USA. 00026 // 00027 // 00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00029 // 00030 00031 /*! 00032 \class eZBasket ezbasket.php 00033 \brief eZBasket handles shopping baskets 00034 \ingroup eZKernel 00035 00036 \sa eZProductCollection 00037 */ 00038 00039 //include_once( "kernel/classes/ezpersistentobject.php" ); 00040 //include_once( "kernel/classes/ezproductcollection.php" ); 00041 //include_once( "kernel/classes/ezproductcollectionitem.php" ); 00042 //include_once( "kernel/classes/datatypes/ezuser/ezuser.php" ); 00043 //include_once( "kernel/classes/ezuserdiscountrule.php" ); 00044 //include_once( "kernel/classes/ezcontentobjecttreenode.php" ); 00045 //include_once( "kernel/classes/ezshippingmanager.php" ); 00046 //include_once( "kernel/classes/ezorder.php" ); 00047 00048 class eZBasket extends eZPersistentObject 00049 { 00050 /*! 00051 Controls the default value for how many items are cleaned in one batch operation. 00052 */ 00053 const ITEM_LIMIT = 3000; 00054 00055 /*! 00056 */ 00057 function eZBasket( $row ) 00058 { 00059 $this->eZPersistentObject( $row ); 00060 } 00061 00062 /*! 00063 \return the persistent object definition for the eZCard class. 00064 */ 00065 static function definition() 00066 { 00067 return array( "fields" => array( "id" => array( 'name' => 'ID', 00068 'datatype' => 'integer', 00069 'default' => 0, 00070 'required' => true ), 00071 "session_id" => array( 'name' => "SessionID", 00072 'datatype' => 'string', 00073 'default' => '', 00074 'required' => true ), 00075 "productcollection_id" => array( 'name' => "ProductCollectionID", 00076 'datatype' => 'integer', 00077 'default' => '0', 00078 'required' => true, 00079 'foreign_class' => 'eZProductCollection', 00080 'foreign_attribute' => 'id', 00081 'multiplicity' => '1..*' ), 00082 "order_id" => array( 'name' => "OrderID", 00083 'datatype' => 'integer', 00084 'default' => 0, 00085 'required' => false, 00086 'foreign_class' => 'eZOrder', 00087 'foreign_attribute' => 'id', 00088 'multiplicity' => '1..*') ), 00089 'function_attributes' => array( 'items' => 'items', 00090 'total_ex_vat' => 'totalExVAT', 00091 'total_inc_vat' => 'totalIncVAT', 00092 'is_empty' => 'isEmpty', 00093 'productcollection' => 'productCollection', 00094 'items_info' => 'itemsInfo' ), 00095 "keys" => array( "id" ), 00096 "increment_key" => "id", 00097 "class_name" => "eZBasket", 00098 "name" => "ezbasket" ); 00099 } 00100 00101 function items( $asObject = true ) 00102 { 00103 $productItems = eZPersistentObject::fetchObjectList( eZProductCollectionItem::definition(), 00104 null, 00105 array( 'productcollection_id' => $this->ProductCollectionID ), 00106 array( 'contentobject_id' => 'desc' ), 00107 null, 00108 $asObject ); 00109 $addedProducts = array(); 00110 foreach ( $productItems as $productItem ) 00111 { 00112 $discountPercent = 0.0; 00113 $isVATIncluded = true; 00114 $id = $productItem->attribute( 'id' ); 00115 $contentObject = $productItem->attribute( 'contentobject' ); 00116 00117 if ( $contentObject !== null ) 00118 { 00119 $vatValue = $productItem->attribute( 'vat_value' ); 00120 00121 // If VAT is unknown yet then we use zero VAT percentage for price calculation. 00122 $realVatValue = $vatValue; 00123 if ( $vatValue == -1 ) 00124 $vatValue = 0; 00125 00126 $count = $productItem->attribute( 'item_count' ); 00127 $discountPercent = $productItem->attribute( 'discount' ); 00128 $nodeID = $contentObject->attribute( 'main_node_id' ); 00129 $objectName = $contentObject->name( false, $contentObject->currentLanguage() ); 00130 00131 $isVATIncluded = $productItem->attribute( 'is_vat_inc' ); 00132 $price = $productItem->attribute( 'price' ); 00133 00134 if ( $isVATIncluded ) 00135 { 00136 $priceExVAT = $price / ( 100 + $vatValue ) * 100; 00137 $priceIncVAT = $price; 00138 $totalPriceExVAT = $count * $priceExVAT * ( 100 - $discountPercent ) / 100; 00139 $totalPriceIncVAT = $count * $priceIncVAT * ( 100 - $discountPercent ) / 100 ; 00140 } 00141 else 00142 { 00143 $priceExVAT = $price; 00144 $priceIncVAT = $price * ( 100 + $vatValue ) / 100; 00145 $totalPriceExVAT = $count * $priceExVAT * ( 100 - $discountPercent ) / 100; 00146 $totalPriceIncVAT = $count * $priceIncVAT * ( 100 - $discountPercent ) / 100 ; 00147 } 00148 00149 $addedProduct = array( "id" => $id, 00150 "vat_value" => $realVatValue, 00151 "item_count" => $count, 00152 "node_id" => $nodeID, 00153 "object_name" => $objectName, 00154 "price_ex_vat" => $priceExVAT, 00155 "price_inc_vat" => $priceIncVAT, 00156 "discount_percent" => $discountPercent, 00157 "total_price_ex_vat" => $totalPriceExVAT, 00158 "total_price_inc_vat" => $totalPriceIncVAT, 00159 'item_object' => $productItem ); 00160 $addedProducts[] = $addedProduct; 00161 } 00162 } 00163 return $addedProducts; 00164 } 00165 /*! 00166 Fetching calculated information about the product items. 00167 */ 00168 function itemsInfo() 00169 { 00170 $basketInfo = array(); 00171 // Build a price summary for the items based on VAT. 00172 foreach ( $this->items() as $item ) 00173 { 00174 $vatValue = $item['vat_value']; 00175 $itemCount = abs( $item['item_count'] ); 00176 $priceExVAT = $item['price_ex_vat']; 00177 $priceIncVAT = $item['price_inc_vat']; 00178 $totalPriceExVAT = $item['total_price_ex_vat']; 00179 $totalPriceIncVAT = $item['total_price_inc_vat']; 00180 00181 if ( !isset( $basketInfo['price_info'][$vatValue]['price_ex_vat'] ) ) 00182 { 00183 $basketInfo['price_info'][$vatValue]['price_ex_vat'] = ( $priceExVAT * $itemCount ); 00184 $basketInfo['price_info'][$vatValue]['price_inc_vat'] = ( $priceIncVAT * $itemCount ); 00185 $basketInfo['price_info'][$vatValue]['price_vat'] = ( $priceIncVAT - $priceExVAT ) * $itemCount; 00186 00187 $basketInfo['price_info'][$vatValue]['total_price_ex_vat'] = $totalPriceExVAT; 00188 $basketInfo['price_info'][$vatValue]['total_price_inc_vat'] = $totalPriceIncVAT; 00189 $basketInfo['price_info'][$vatValue]['total_price_vat'] = $totalPriceIncVAT - $totalPriceExVAT; 00190 } 00191 else 00192 { 00193 $basketInfo['price_info'][$vatValue]['price_ex_vat'] += ( $priceExVAT * $itemCount ); 00194 $basketInfo['price_info'][$vatValue]['price_inc_vat'] += ( $priceIncVAT * $itemCount ); 00195 $basketInfo['price_info'][$vatValue]['price_vat'] += ( $priceIncVAT - $priceExVAT ) * $itemCount; 00196 00197 $basketInfo['price_info'][$vatValue]['total_price_ex_vat'] += $totalPriceExVAT; 00198 $basketInfo['price_info'][$vatValue]['total_price_inc_vat'] += $totalPriceIncVAT; 00199 $basketInfo['price_info'][$vatValue]['total_price_vat'] += ( $totalPriceIncVAT - $totalPriceExVAT ); 00200 } 00201 00202 if ( !isset( $basketInfo['total_price_info']['total_price_ex_vat'] ) ) 00203 { 00204 $basketInfo['total_price_info']['price_ex_vat'] = ( $priceExVAT * $itemCount ); 00205 $basketInfo['total_price_info']['price_inc_vat'] = ( $priceIncVAT * $itemCount ); 00206 $basketInfo['total_price_info']['price_vat'] = ( ( $priceIncVAT - $priceExVAT ) * $itemCount ); 00207 00208 $basketInfo['total_price_info']['total_price_ex_vat'] = $totalPriceExVAT; 00209 $basketInfo['total_price_info']['total_price_inc_vat'] = $totalPriceIncVAT; 00210 $basketInfo['total_price_info']['total_price_vat'] = ( $totalPriceIncVAT - $totalPriceExVAT ); 00211 } 00212 else 00213 { 00214 $basketInfo['total_price_info']['price_ex_vat'] += ( $priceExVAT * $itemCount ); 00215 $basketInfo['total_price_info']['price_inc_vat'] += ( $priceIncVAT * $itemCount ); 00216 $basketInfo['total_price_info']['price_vat'] += ( ( $priceIncVAT - $priceExVAT ) * $itemCount ); 00217 00218 $basketInfo['total_price_info']['total_price_ex_vat'] += $totalPriceExVAT; 00219 $basketInfo['total_price_info']['total_price_inc_vat'] += $totalPriceIncVAT; 00220 $basketInfo['total_price_info']['total_price_vat'] += ( $totalPriceIncVAT - $totalPriceExVAT ); 00221 } 00222 } 00223 00224 // Add shipping cost to the total items price and add / update additional price information. 00225 $productCollectionID = $this->attribute( 'productcollection_id' ); 00226 00227 // Add additional calculated information to the basketInfo array, that can be used in the template. 00228 $shippingUpdateStatus = eZShippingManager::updatePriceInfo( $productCollectionID, $basketInfo ); 00229 00230 ksort( $basketInfo['price_info'] ); 00231 return $basketInfo; 00232 } 00233 00234 /*! 00235 Returns true if VAT percentage is known for all basket items. 00236 00237 \public 00238 */ 00239 function isVATKnown() 00240 { 00241 $result = true; 00242 foreach ( $this->items() as $item ) 00243 { 00244 if ( $item['vat_value'] == -1 ) 00245 return false; 00246 } 00247 00248 return true; 00249 } 00250 00251 function totalIncVAT() 00252 { 00253 $items = $this->items(); 00254 00255 $total = 0.0; 00256 foreach ( $items as $item ) 00257 { 00258 $total += $item['total_price_inc_vat']; 00259 } 00260 return $total; 00261 } 00262 00263 function totalExVAT() 00264 { 00265 $items = $this->items(); 00266 00267 $total = 0.0; 00268 foreach ( $items as $item ) 00269 { 00270 $total += $item['total_price_ex_vat']; 00271 } 00272 return $total; 00273 } 00274 00275 /*! 00276 \note Transaction unsafe. If you call several transaction unsafe methods you must enclose 00277 the calls within a db transaction; thus within db->begin and db->commit. 00278 */ 00279 function removeItem( $itemID ) 00280 { 00281 $item = eZProductCollectionItem::fetch( $itemID ); 00282 if ( is_object( $item ) && $this->attribute( 'productcollection_id' ) == $item->attribute( 'productcollection_id' ) ) 00283 { 00284 $item->remove(); 00285 } 00286 } 00287 00288 function isEmpty() 00289 { 00290 $items = $this->items(); 00291 return count( $items ) < 1; 00292 } 00293 00294 /*! 00295 Fetches the basket which belongs to session \a $sessionKey. 00296 \param $sessionKey A string containing the session key. 00297 \return An eZSessionBasket object or \c false if none was found. 00298 */ 00299 static function fetch( $sessionKey ) 00300 { 00301 return eZPersistentObject::fetchObject( eZBasket::definition(), 00302 null, array( "session_id" => $sessionKey ), 00303 true ); 00304 } 00305 00306 /*! 00307 Will return the basket for the current session. If a basket does not exist one will be created. 00308 \return current eZBasket object 00309 \note Transaction unsafe. If you call several transaction unsafe methods you must enclose 00310 the calls within a db transaction; thus within db->begin and db->commit. 00311 */ 00312 static function currentBasket( $asObject=true, $byOrderID=-1 ) 00313 { 00314 $basketList = array(); 00315 00316 if( $byOrderID != -1 ) 00317 { 00318 $basketList = eZPersistentObject::fetchObjectList( eZBasket::definition(), 00319 null, array( "order_id" => $byOrderID ), 00320 null, null, 00321 $asObject ); 00322 } 00323 else 00324 { 00325 $http = eZHTTPTool::instance(); 00326 $sessionID = $http->sessionID(); 00327 00328 $basketList = eZPersistentObject::fetchObjectList( eZBasket::definition(), 00329 null, array( "session_id" => $sessionID ), 00330 null, null, 00331 $asObject ); 00332 } 00333 00334 $currentBasket = false; 00335 if ( count( $basketList ) == 0 ) 00336 { 00337 $db = eZDB::instance(); 00338 $db->begin(); 00339 $collection = eZProductCollection::create(); 00340 $collection->store(); 00341 00342 $currentBasket = new eZBasket( array( "session_id" => $sessionID, 00343 "productcollection_id" => $collection->attribute( "id" ) ) ); 00344 $currentBasket->store(); 00345 $db->commit(); 00346 } 00347 else 00348 { 00349 $currentBasket = $basketList[0]; 00350 } 00351 return $currentBasket; 00352 } 00353 00354 /*! 00355 Creates a temporary order for the current basket. 00356 The order object is returned. 00357 \note Transaction unsafe. If you call several transaction unsafe methods you must enclose 00358 the calls within a db transaction; thus within db->begin and db->commit. 00359 */ 00360 function createOrder() 00361 { 00362 // Make order 00363 $productCollectionID = $this->attribute( 'productcollection_id' ); 00364 00365 $user = eZUser::currentUser(); 00366 $userID = $user->attribute( 'contentobject_id' ); 00367 00368 //include_once( 'kernel/classes/ezorderstatus.php' ); 00369 $time = time(); 00370 $order = new eZOrder( array( 'productcollection_id' => $productCollectionID, 00371 'user_id' => $userID, 00372 'is_temporary' => 1, 00373 'created' => $time, 00374 'status_id' => eZOrderStatus::PENDING, 00375 'status_modified' => $time, 00376 'status_modifier_id' => $userID 00377 ) ); 00378 00379 $db = eZDB::instance(); 00380 $db->begin(); 00381 $order->store(); 00382 00383 $orderID = $order->attribute( 'id' ); 00384 $this->setAttribute( 'order_id', $orderID ); 00385 $this->store(); 00386 $db->commit(); 00387 00388 return $order; 00389 } 00390 00391 /*! 00392 \note Transaction unsafe. If you call several transaction unsafe methods you must enclose 00393 the calls within a db transaction; thus within db->begin and db->commit. 00394 */ 00395 function updatePrices() 00396 { 00397 $productCollection = $this->attribute( 'productcollection' ); 00398 if ( $productCollection ) 00399 { 00400 //include_once( 'kernel/shop/classes/ezshopfunctions.php' ); 00401 00402 $currencyCode = ''; 00403 $items = $this->items(); 00404 00405 $db = eZDB::instance(); 00406 $db->begin(); 00407 foreach( $items as $itemArray ) 00408 { 00409 $item = $itemArray['item_object']; 00410 $productContentObject = $item->attribute( 'contentobject' ); 00411 $priceObj = null; 00412 $price = 0.0; 00413 $attributes = $productContentObject->contentObjectAttributes(); 00414 foreach ( $attributes as $attribute ) 00415 { 00416 $dataType = $attribute->dataType(); 00417 if ( eZShopFunctions::isProductDatatype( $dataType->isA() ) ) 00418 { 00419 $priceObj = $attribute->content(); 00420 $price += $priceObj->attribute( 'price' ); 00421 break; 00422 } 00423 } 00424 if ( !is_object( $priceObj ) ) 00425 break; 00426 00427 $currency = $priceObj->attribute( 'currency' ); 00428 $optionsPrice = $item->calculatePriceWithOptions( $currency ); 00429 00430 $price += $optionsPrice; 00431 $item->setAttribute( "price", $price ); 00432 if ( $priceObj->attribute( 'is_vat_included' ) ) 00433 { 00434 $item->setAttribute( "is_vat_inc", '1' ); 00435 } 00436 else 00437 { 00438 $item->setAttribute( "is_vat_inc", '0' ); 00439 } 00440 $item->setAttribute( "vat_value", $priceObj->VATPercent( $productContentObject ) ); 00441 $item->setAttribute( "discount", $priceObj->attribute( 'discount_percent' ) ); 00442 $item->store(); 00443 00444 $currencyCode = $priceObj->attribute( 'currency' ); 00445 } 00446 00447 $productCollection->setAttribute( 'currency_code', $currencyCode ); 00448 $productCollection->store(); 00449 $db->commit(); 00450 00451 // update prices that are related to shipping values. 00452 eZShippingManager::updateShippingInfo( $productCollection->attribute( 'id' ) ); 00453 } 00454 } 00455 00456 /*! 00457 \static 00458 Removes all baskets which are considered expired (due to session expiration). 00459 \note This will also remove the product collection the basket is using. 00460 */ 00461 static function cleanupExpired( $time ) 00462 { 00463 $db = eZDB::instance(); 00464 00465 if ( $db->hasRequiredServerVersion( '4.0', 'mysql' ) ) 00466 { 00467 // If we have the required MySQL version we use a DELETE statement 00468 // with multiple tables 00469 $sql = "DELETE FROM ezbasket, ezproductcollection, ezproductcollection_item, ezproductcollection_item_opt 00470 USING ezsession 00471 JOIN ezbasket 00472 ON ezsession.session_key = ezbasket.session_id 00473 LEFT JOIN ezproductcollection 00474 ON ezbasket.productcollection_id = ezproductcollection.id 00475 LEFT JOIN ezproductcollection_item 00476 ON ezproductcollection.id = ezproductcollection_item.productcollection_id 00477 LEFT JOIN ezproductcollection_item_opt 00478 ON ezproductcollection_item.id = ezproductcollection_item_opt.item_id"; 00479 if ( $time !== false ) 00480 $sql .= "\nWHERE ezsession.expiration_time < " . (int)$time; 00481 $db->query( $sql ); 00482 return; 00483 } 00484 00485 // Find all baskets whos session will expire 00486 $sql = "SELECT id, productcollection_id 00487 FROM ezbasket, ezsession 00488 WHERE ezbasket.session_id = ezsession.session_key AND 00489 ezsession.expiration_time < " . (int)$time; 00490 $limit = self::ITEM_LIMIT; 00491 00492 do 00493 { 00494 $rows = $db->arrayQuery( $sql, array( 'offset' => 0, 'limit' => $limit ) ); 00495 if ( count( $rows ) == 0 ) 00496 break; 00497 00498 $productCollectionIDList = array(); 00499 $idList = array(); 00500 foreach ( $rows as $row ) 00501 { 00502 $idList[] = (int)$row['id']; 00503 $productCollectionIDList[] = (int)$row['productcollection_id']; 00504 } 00505 eZProductCollection::cleanupList( $productCollectionIDList ); 00506 00507 $ids = implode( ', ', $idList ); 00508 $db->query( "DELETE FROM ezbasket WHERE id IN ( $ids )" ); 00509 00510 } while ( true ); 00511 } 00512 00513 /*! 00514 \static 00515 Removes all baskets for all users. 00516 \note Transaction unsafe. If you call several transaction unsafe methods you must enclose 00517 the calls within a db transaction; thus within db->begin and db->commit. 00518 */ 00519 static function cleanup() 00520 { 00521 $db = eZDB::instance(); 00522 $sql = "SELECT productcollection_id FROM ezbasket"; 00523 $limit = self::ITEM_LIMIT; 00524 00525 $db->begin(); 00526 do 00527 { 00528 $rows = $db->arrayQuery( $sql, array( 'offset' => 0, 'limit' => $limit ) ); 00529 00530 if ( count( $rows ) == 0 ) 00531 break; 00532 00533 $productCollectionIDList = array(); 00534 foreach ( $rows as $row ) 00535 { 00536 $productCollectionIDList[] = (int)$row['productcollection_id']; 00537 } 00538 eZProductCollection::cleanupList( $productCollectionIDList ); 00539 00540 $ids = implode( ', ', $productCollectionIDList ); 00541 $db->query( "DELETE FROM ezbasket WHERE productcollection_id IN ( $ids )" ); 00542 } 00543 while ( true ); 00544 $db->commit(); 00545 } 00546 00547 /*! 00548 \returns the type of basket. In other words: what type of products the basket contains. 00549 */ 00550 function type() 00551 { 00552 $type = false; 00553 00554 // get first product 00555 $productCollectionItemList = eZProductCollectionItem::fetchList( array( 'productcollection_id' => $this->attribute( 'productcollection_id' ) ), 00556 true, 00557 0, 00558 1 ); 00559 00560 if ( is_array( $productCollectionItemList ) && count( $productCollectionItemList ) === 1 ) 00561 { 00562 $product = $productCollectionItemList[0]->attribute( 'contentobject' ); 00563 if ( is_object( $product ) ) 00564 { 00565 //include_once( 'kernel/shop/classes/ezshopfunctions.php' ); 00566 $type = eZShopFunctions::productTypeByObject( $product ); 00567 } 00568 } 00569 00570 return $type; 00571 } 00572 00573 function canAddProduct( $contentObject ) 00574 { 00575 //include_once( 'kernel/shop/classes/ezshopfunctions.php' ); 00576 //include_once( 'kernel/shop/errors.php' ); 00577 00578 $error = eZError::SHOP_OK; 00579 00580 $productType = eZShopFunctions::productTypeByObject( $contentObject ); 00581 if ( $productType === false ) 00582 { 00583 $error = eZError::SHOP_NOT_A_PRODUCT; 00584 } 00585 else 00586 { 00587 if ( !eZShopFunctions::isSimplePriceProductType( $productType ) ) 00588 $error = eZShopFunctions::isPreferredCurrencyValid(); 00589 00590 if ( $error === eZError::SHOP_OK ) 00591 { 00592 $basketType = $this->type(); 00593 if ( $basketType !== false && $basketType !== $productType ) 00594 $error = eZError::SHOP_BASKET_INCOMPATIBLE_PRODUCT_TYPE; 00595 } 00596 } 00597 00598 return $error; 00599 } 00600 00601 function productCollection() 00602 { 00603 return eZProductCollection::fetch( $this->attribute( 'productcollection_id' ) ); 00604 } 00605 00606 /*! 00607 \static 00608 Removes current basket. 00609 \param $useSetting - if "true" use ini setting in site.ini [ShopSettings].ClearBasketOnLogout, 00610 or just clear current basket otherwise. 00611 \note Transaction unsafe. If you call several transaction unsafe methods you must enclose 00612 the calls within a db transaction; thus within db->begin and db->commit. 00613 00614 */ 00615 static function cleanupCurrentBasket( $useSetting = true ) 00616 { 00617 $ini = eZINI::instance(); 00618 $removeBasket = true; 00619 if ( $useSetting ) 00620 $removeBasket = $ini->hasVariable( 'ShopSettings', 'ClearBasketOnLogout' ) ? $ini->variable( 'ShopSettings', 'ClearBasketOnLogout' ) == 'enabled' : false; 00621 00622 if ( $removeBasket ) 00623 { 00624 $basket = eZBasket::currentBasket(); 00625 if ( !is_object( $basket ) ) 00626 return false; 00627 $db = eZDB::instance(); 00628 $db->begin(); 00629 $productCollectionID = $basket->attribute( 'productcollection_id' ); 00630 eZProductCollection::cleanupList( array( $productCollectionID ) ); 00631 $basket->remove(); 00632 $db->commit(); 00633 } 00634 00635 return true; 00636 } 00637 } 00638 00639 ?>