1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27:
28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:
48: class Mage_Wishlist_Model_Item extends Mage_Core_Model_Abstract
49: implements Mage_Catalog_Model_Product_Configuration_Item_Interface
50: {
51: const EXCEPTION_CODE_NOT_SALABLE = 901;
52: const EXCEPTION_CODE_HAS_REQUIRED_OPTIONS = 902;
53: 54: 55: 56: 57: 58:
59: const EXCEPTION_CODE_IS_GROUPED_PRODUCT = 903;
60:
61: 62: 63: 64:
65: protected $_customOptionDownloadUrl = 'wishlist/index/downloadCustomOption';
66:
67: 68: 69: 70: 71:
72: protected $_eventPrefix = 'wishlist_item';
73:
74: 75: 76: 77: 78: 79: 80:
81: protected $_eventObject = 'item';
82:
83: 84: 85: 86: 87:
88: protected $_options = array();
89:
90: 91: 92: 93: 94:
95: protected $_optionsByCode = array();
96:
97: 98: 99: 100: 101:
102: protected $_notRepresentOptions = array('info_buyRequest');
103:
104: 105: 106: 107:
108: protected $_flagOptionsSaved = null;
109:
110: 111: 112: 113:
114: protected function _construct()
115: {
116: $this->_init('wishlist/item');
117: }
118:
119: 120: 121: 122: 123: 124:
125: public function setQty($qty)
126: {
127: $this->setData('qty', ($qty >= 0) ? $qty : 1 );
128: return $this;
129: }
130:
131: 132: 133: 134: 135:
136: protected function _getResource()
137: {
138: return parent::_getResource();
139: }
140:
141: 142: 143: 144: 145: 146: 147:
148: protected function _compareOptions($options1, $options2)
149: {
150: $skipOptions = array('id', 'qty', 'return_url');
151: foreach ($options1 as $code => $value) {
152: if (in_array($code, $skipOptions)) {
153: continue;
154: }
155: if (!isset($options2[$code]) || $options2[$code] != $value) {
156: return false;
157: }
158: }
159: return true;
160: }
161:
162: 163: 164: 165: 166: 167:
168: protected function _addOptionCode($option)
169: {
170: if (!isset($this->_optionsByCode[$option->getCode()])) {
171: $this->_optionsByCode[$option->getCode()] = $option;
172: }
173: else {
174: Mage::throwException(Mage::helper('sales')->__('An item option with code %s already exists.', $option->getCode()));
175: }
176: return $this;
177: }
178:
179: 180: 181: 182: 183: 184:
185: protected function _hasModelChanged()
186: {
187: if (!$this->hasDataChanges()) {
188: return false;
189: }
190:
191: return $this->_getResource()->hasDataChanged($this);
192: }
193:
194: 195: 196: 197: 198:
199: protected function _saveItemOptions()
200: {
201: foreach ($this->_options as $index => $option) {
202: if ($option->isDeleted()) {
203: $option->delete();
204: unset($this->_options[$index]);
205: unset($this->_optionsByCode[$option->getCode()]);
206: } else {
207: $option->save();
208: }
209: }
210:
211: $this->_flagOptionsSaved = true;
212:
213: return $this;
214: }
215:
216: 217: 218: 219:
220: public function save()
221: {
222: $hasDataChanges = $this->hasDataChanges();
223: $this->_flagOptionsSaved = false;
224:
225: parent::save();
226:
227: if ($hasDataChanges && !$this->_flagOptionsSaved) {
228: $this->_saveItemOptions();
229: }
230: }
231:
232: 233: 234: 235: 236:
237: protected function _afterSave()
238: {
239: $this->_saveItemOptions();
240: return parent::_afterSave();
241: }
242:
243: 244: 245: 246: 247: 248:
249: public function validate()
250: {
251: if (!$this->getWishlistId()) {
252: Mage::throwException(Mage::helper('wishlist')->__('Cannot specify wishlist.'));
253: }
254: if (!$this->getProductId()) {
255: Mage::throwException(Mage::helper('wishlist')->__('Cannot specify product.'));
256: }
257:
258: return true;
259: }
260:
261: 262: 263: 264: 265:
266: protected function _beforeSave()
267: {
268: parent::_beforeSave();
269:
270:
271: $this->validate();
272:
273:
274: if (is_null($this->getStoreId())) {
275: $this->setStoreId(Mage::app()->getStore()->getId());
276: }
277:
278:
279: if (is_null($this->getAddedAt())) {
280: $this->setAddedAt(Mage::getSingleton('core/date')->gmtDate());
281: }
282:
283: return $this;
284: }
285:
286: 287: 288: 289: 290: 291:
292: public function getDataForSave()
293: {
294: $data = array();
295: $data['product_id'] = $this->getProductId();
296: $data['wishlist_id'] = $this->getWishlistId();
297: $data['added_at'] = $this->getAddedAt() ? $this->getAddedAt() : Mage::getSingleton('core/date')->gmtDate();
298: $data['description'] = $this->getDescription();
299: $data['store_id'] = $this->getStoreId() ? $this->getStoreId() : Mage::app()->getStore()->getId();
300:
301: return $data;
302: }
303:
304: 305: 306: 307: 308: 309: 310: 311:
312: public function loadByProductWishlist($wishlistId, $productId, $sharedStores)
313: {
314: $this->_getResource()->loadByProductWishlist($this, $wishlistId, $productId, $sharedStores);
315: $this->_afterLoad();
316: $this->setOrigData();
317:
318: return $this;
319: }
320:
321: 322: 323: 324: 325: 326:
327: public function getProduct()
328: {
329: $product = $this->_getData('product');
330: if (is_null($product)) {
331: if (!$this->getProductId()) {
332: Mage::throwException(Mage::helper('wishlist')->__('Cannot specify product.'));
333: }
334:
335: $product = Mage::getModel('catalog/product')
336: ->setStoreId($this->getStoreId())
337: ->load($this->getProductId());
338:
339: $this->setData('product', $product);
340: }
341:
342: 343: 344:
345: $product->setFinalPrice(null);
346: $product->setCustomOptions($this->_optionsByCode);
347: return $product;
348: }
349:
350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360:
361: public function addToCart(Mage_Checkout_Model_Cart $cart, $delete = false)
362: {
363: $product = $this->getProduct();
364:
365: $storeId = $this->getStoreId();
366:
367: if ($product->getStatus() != Mage_Catalog_Model_Product_Status::STATUS_ENABLED) {
368: return false;
369: }
370:
371: if (!$product->isVisibleInSiteVisibility()) {
372: if ($product->getStoreId() == $storeId) {
373: return false;
374: }
375: $urlData = Mage::getResourceSingleton('catalog/url')
376: ->getRewriteByProductStore(array($product->getId() => $storeId));
377: if (!isset($urlData[$product->getId()])) {
378: return false;
379: }
380: $product->setUrlDataObject(new Varien_Object($urlData));
381: $visibility = $product->getUrlDataObject()->getVisibility();
382: if (!in_array($visibility, $product->getVisibleInSiteVisibilities())) {
383: return false;
384: }
385: }
386:
387: if (!$product->isSalable()) {
388: throw new Mage_Core_Exception(null, self::EXCEPTION_CODE_NOT_SALABLE);
389: }
390:
391: $buyRequest = $this->getBuyRequest();
392:
393: $cart->addProduct($product, $buyRequest);
394: if (!$product->isVisibleInSiteVisibility()) {
395: $cart->getQuote()->getItemByProduct($product)->setStoreId($storeId);
396: }
397:
398: if ($delete) {
399: $this->delete();
400: }
401:
402: return true;
403: }
404:
405: 406: 407: 408: 409: 410: 411:
412: public function getProductUrl()
413: {
414: $product = $this->getProduct();
415: $query = array();
416:
417: if ($product->getTypeInstance(true)->hasRequiredOptions($product)) {
418: $query['options'] = 'cart';
419: }
420:
421: return $product->getUrlModel()->getUrl($product, array('_query' => $query));
422: }
423:
424: 425: 426: 427: 428: 429:
430: public function getBuyRequest()
431: {
432: $option = $this->getOptionByCode('info_buyRequest');
433: $initialData = $option ? unserialize($option->getValue()) : null;
434:
435:
436: if ($initialData instanceof Varien_Object) {
437: $initialData = $initialData->getData();
438: }
439:
440: $buyRequest = new Varien_Object($initialData);
441: $buyRequest->setOriginalQty($buyRequest->getQty())
442: ->setQty($this->getQty() * 1);
443: return $buyRequest;
444: }
445:
446: 447: 448: 449: 450: 451:
452: public function mergeBuyRequest($buyRequest) {
453: if ($buyRequest instanceof Varien_Object) {
454: $buyRequest = $buyRequest->getData();
455: }
456:
457: if (empty($buyRequest) || !is_array($buyRequest)) {
458: return $this;
459: }
460:
461: $oldBuyRequest = $this->getBuyRequest()
462: ->getData();
463: $sBuyRequest = serialize($buyRequest + $oldBuyRequest);
464:
465: $option = $this->getOptionByCode('info_buyRequest');
466: if ($option) {
467: $option->setValue($sBuyRequest);
468: } else {
469: $this->addOption(array(
470: 'code' => 'info_buyRequest',
471: 'value' => $sBuyRequest
472: ));
473: }
474:
475: return $this;
476: }
477:
478: 479: 480: 481: 482: 483:
484: public function setBuyRequest($buyRequest)
485: {
486: $buyRequest->setId($this->getId());
487:
488: $_buyRequest = serialize($buyRequest->getData());
489: $this->setData('buy_request', $_buyRequest);
490: return $this;
491: }
492:
493: 494: 495: 496: 497: 498: 499:
500: public function isRepresent($product, $buyRequest)
501: {
502: if ($this->getProductId() != $product->getId()) {
503: return false;
504: }
505:
506: $selfOptions = $this->getBuyRequest()->getData();
507:
508: if (empty($buyRequest) && !empty($selfOptions)) {
509: return false;
510: }
511: if (empty($selfOptions) && !empty($buyRequest)) {
512: if (!$product->isComposite()){
513: return true;
514: } else {
515: return false;
516: }
517: }
518:
519: $requestArray = $buyRequest->getData();
520:
521: if(!$this->_compareOptions($requestArray, $selfOptions)){
522: return false;
523: }
524: if(!$this->_compareOptions($selfOptions, $requestArray)){
525: return false;
526: }
527: return true;
528: }
529:
530: 531: 532: 533: 534: 535:
536: public function representProduct($product)
537: {
538: $itemProduct = $this->getProduct();
539: if ($itemProduct->getId() != $product->getId()) {
540: return false;
541: }
542:
543: $itemOptions = $this->getOptionsByCode();
544: $productOptions = $product->getCustomOptions();
545:
546: if(!$this->compareOptions($itemOptions, $productOptions)){
547: return false;
548: }
549: if(!$this->compareOptions($productOptions, $itemOptions)){
550: return false;
551: }
552: return true;
553: }
554:
555: 556: 557: 558: 559: 560: 561: 562: 563:
564: public function compareOptions($options1, $options2)
565: {
566: foreach ($options1 as $option) {
567: $code = $option->getCode();
568: if (in_array($code, $this->_notRepresentOptions )) {
569: continue;
570: }
571: if ( !isset($options2[$code])
572: || ($options2[$code]->getValue() === null)
573: || $options2[$code]->getValue() != $option->getValue()) {
574: return false;
575: }
576: }
577: return true;
578: }
579:
580: 581: 582: 583: 584: 585:
586: public function setOptions($options)
587: {
588: foreach ($options as $option) {
589: $this->addOption($option);
590: }
591: return $this;
592: }
593:
594: 595: 596: 597: 598:
599: public function getOptions()
600: {
601: return $this->_options;
602: }
603:
604: 605: 606: 607: 608:
609: public function getOptionsByCode()
610: {
611: return $this->_optionsByCode;
612: }
613:
614: 615: 616: 617: 618: 619:
620: public function addOption($option)
621: {
622: if (is_array($option)) {
623: $option = Mage::getModel('wishlist/item_option')->setData($option)
624: ->setItem($this);
625: } else if ($option instanceof Mage_Wishlist_Model_Item_Option) {
626: $option->setItem($this);
627: } else if ($option instanceof Varien_Object) {
628: $option = Mage::getModel('wishlist/item_option')->setData($option->getData())
629: ->setProduct($option->getProduct())
630: ->setItem($this);
631: } else {
632: Mage::throwException(Mage::helper('sales')->__('Invalid item option format.'));
633: }
634:
635: $exOption = $this->getOptionByCode($option->getCode());
636: if ($exOption) {
637: $exOption->addData($option->getData());
638: } else {
639: $this->_addOptionCode($option);
640: $this->_options[] = $option;
641: }
642: return $this;
643: }
644:
645: 646: 647: 648: 649: 650:
651: public function removeOption($code)
652: {
653: $option = $this->getOptionByCode($code);
654: if ($option) {
655: $option->isDeleted(true);
656: }
657: return $this;
658: }
659:
660: 661: 662: 663: 664: 665:
666: public function getOptionByCode($code)
667: {
668: if (isset($this->_optionsByCode[$code]) && !$this->_optionsByCode[$code]->isDeleted()) {
669: return $this->_optionsByCode[$code];
670: }
671: return null;
672: }
673:
674: 675: 676: 677: 678:
679: public function canHaveQty()
680: {
681: $product = $this->getProduct();
682: return $product->getTypeId() != Mage_Catalog_Model_Product_Type_Grouped::TYPE_CODE;
683: }
684:
685: 686: 687:
688: public function getCustomDownloadUrl()
689: {
690: return $this->_customOptionDownloadUrl;
691: }
692:
693: 694: 695:
696: public function setCustomDownloadUrl($url)
697: {
698: $this->_customOptionDownloadUrl = $url;
699: }
700:
701: 702: 703: 704: 705: 706: 707: 708:
709: public function getFileDownloadParams()
710: {
711: $params = new Varien_Object();
712: $params->setUrl($this->_customOptionDownloadUrl);
713: return $params;
714: }
715:
716: 717: 718: 719: 720: 721: 722: 723: 724: 725:
726: public function loadWithOptions($id, $optionsFilter = null)
727: {
728: $this->load($id);
729: if (!$this->getId()) {
730: return $this;
731: }
732:
733: $options = Mage::getResourceModel('wishlist/item_option_collection')
734: ->addItemFilter($this);
735: if ($optionsFilter) {
736: $options->addFieldToFilter('code', $optionsFilter);
737: }
738:
739: $this->setOptions($options->getOptionsByItem($this));
740: return $this;
741: }
742: }
743: