Item.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Wishlist\Model;
  7. use Magento\Catalog\Api\ProductRepositoryInterface;
  8. use Magento\Catalog\Model\Product\Configuration\Item\ItemInterface;
  9. use Magento\Framework\Exception\NoSuchEntityException;
  10. use Magento\Framework\Model\AbstractModel;
  11. use Magento\Wishlist\Model\Item\Option;
  12. use Magento\Wishlist\Model\Item\OptionFactory;
  13. use Magento\Wishlist\Model\ResourceModel\Item\Option\CollectionFactory;
  14. use Magento\Catalog\Model\Product\Exception as ProductException;
  15. /**
  16. * Wishlist item model
  17. *
  18. * @method int getWishlistId()
  19. * @method \Magento\Wishlist\Model\Item setWishlistId(int $value)
  20. * @method int getProductId()
  21. * @method \Magento\Wishlist\Model\Item setProductId(int $value)
  22. * @method int getStoreId()
  23. * @method \Magento\Wishlist\Model\Item setStoreId(int $value)
  24. * @method string getAddedAt()
  25. * @method \Magento\Wishlist\Model\Item setAddedAt(string $value)
  26. * @method string getDescription()
  27. * @method \Magento\Wishlist\Model\Item setDescription(string $value)
  28. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  29. *
  30. * @api
  31. * @since 100.0.2
  32. */
  33. class Item extends AbstractModel implements ItemInterface
  34. {
  35. /**
  36. * Custom path to download attached file
  37. * @var string
  38. */
  39. protected $_customOptionDownloadUrl = 'wishlist/index/downloadCustomOption';
  40. /**
  41. * Prefix of model events names
  42. *
  43. * @var string
  44. */
  45. protected $_eventPrefix = 'wishlist_item';
  46. /**
  47. * Parameter name in event
  48. *
  49. * In observe method you can use $observer->getEvent()->getItem() in this case
  50. *
  51. * @var string
  52. */
  53. protected $_eventObject = 'item';
  54. /**
  55. * Item options array
  56. *
  57. * @var Option[]
  58. */
  59. protected $_options = [];
  60. /**
  61. * Item options by code cache
  62. *
  63. * @var array
  64. */
  65. protected $_optionsByCode = [];
  66. /**
  67. * Not Represent options
  68. *
  69. * @var string[]
  70. */
  71. protected $_notRepresentOptions = ['info_buyRequest'];
  72. /**
  73. * Flag stating that options were successfully saved
  74. *
  75. * @var bool|null
  76. */
  77. protected $_flagOptionsSaved = null;
  78. /**
  79. * @var \Magento\Store\Model\StoreManagerInterface
  80. */
  81. protected $_storeManager;
  82. /**
  83. * @var \Magento\Framework\Stdlib\DateTime\DateTime
  84. */
  85. protected $_date;
  86. /**
  87. * @var \Magento\Catalog\Model\ResourceModel\Url
  88. */
  89. protected $_catalogUrl;
  90. /**
  91. * @var OptionFactory
  92. */
  93. protected $_wishlistOptFactory;
  94. /**
  95. * @var CollectionFactory
  96. */
  97. protected $_wishlOptionCollectionFactory;
  98. /**
  99. * @var \Magento\Catalog\Model\ProductTypes\ConfigInterface
  100. */
  101. protected $productTypeConfig;
  102. /**
  103. * @var ProductRepositoryInterface
  104. */
  105. protected $productRepository;
  106. /**
  107. * Serializer interface instance.
  108. *
  109. * @var \Magento\Framework\Serialize\Serializer\Json
  110. */
  111. private $serializer;
  112. /**
  113. * @param \Magento\Framework\Model\Context $context
  114. * @param \Magento\Framework\Registry $registry
  115. * @param \Magento\Store\Model\StoreManagerInterface $storeManager
  116. * @param \Magento\Framework\Stdlib\DateTime\DateTime $date
  117. * @param \Magento\Catalog\Model\ResourceModel\Url $catalogUrl
  118. * @param OptionFactory $wishlistOptFactory
  119. * @param CollectionFactory $wishlOptionCollectionFactory
  120. * @param \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig
  121. * @param ProductRepositoryInterface $productRepository
  122. * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
  123. * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
  124. * @param array $data
  125. * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer
  126. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  127. */
  128. public function __construct(
  129. \Magento\Framework\Model\Context $context,
  130. \Magento\Framework\Registry $registry,
  131. \Magento\Store\Model\StoreManagerInterface $storeManager,
  132. \Magento\Framework\Stdlib\DateTime\DateTime $date,
  133. \Magento\Catalog\Model\ResourceModel\Url $catalogUrl,
  134. OptionFactory $wishlistOptFactory,
  135. CollectionFactory $wishlOptionCollectionFactory,
  136. \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig,
  137. ProductRepositoryInterface $productRepository,
  138. \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
  139. \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
  140. array $data = [],
  141. \Magento\Framework\Serialize\Serializer\Json $serializer = null
  142. ) {
  143. $this->productTypeConfig = $productTypeConfig;
  144. $this->_storeManager = $storeManager;
  145. $this->_date = $date;
  146. $this->_catalogUrl = $catalogUrl;
  147. $this->_wishlistOptFactory = $wishlistOptFactory;
  148. $this->_wishlOptionCollectionFactory = $wishlOptionCollectionFactory;
  149. $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
  150. ->get(\Magento\Framework\Serialize\Serializer\Json::class);
  151. parent::__construct($context, $registry, $resource, $resourceCollection, $data);
  152. $this->productRepository = $productRepository;
  153. }
  154. /**
  155. * Initialize resource model
  156. *
  157. * @return void
  158. */
  159. protected function _construct()
  160. {
  161. $this->_init(\Magento\Wishlist\Model\ResourceModel\Item::class);
  162. }
  163. /**
  164. * Set quantity. If quantity is less than 0 - set it to 1
  165. *
  166. * @param int $qty
  167. * @return $this
  168. */
  169. public function setQty($qty)
  170. {
  171. $this->setData('qty', $qty >= 0 ? $qty : 1);
  172. return $this;
  173. }
  174. /**
  175. * Check if two options array are identical
  176. *
  177. * @param array $options1
  178. * @param array $options2
  179. * @return bool
  180. */
  181. protected function _compareOptions($options1, $options2)
  182. {
  183. $skipOptions = ['id', 'qty', 'return_url'];
  184. foreach ($options1 as $code => $value) {
  185. if (in_array($code, $skipOptions)) {
  186. continue;
  187. }
  188. if (!isset($options2[$code]) || $options2[$code] != $value) {
  189. return false;
  190. }
  191. }
  192. return true;
  193. }
  194. /**
  195. * Register option code
  196. *
  197. * @param Option $option
  198. * @return $this
  199. * @throws \Magento\Framework\Exception\LocalizedException
  200. */
  201. protected function _addOptionCode($option)
  202. {
  203. if (!isset($this->_optionsByCode[$option->getCode()])) {
  204. $this->_optionsByCode[$option->getCode()] = $option;
  205. } else {
  206. throw new \Magento\Framework\Exception\LocalizedException(
  207. __('An item option with code %1 already exists.', $option->getCode())
  208. );
  209. }
  210. return $this;
  211. }
  212. /**
  213. * Checks that item model has data changes.
  214. * Call save item options if model isn't need to save in DB
  215. *
  216. * @return boolean
  217. */
  218. protected function _hasModelChanged()
  219. {
  220. if (!$this->hasDataChanges()) {
  221. return false;
  222. }
  223. return $this->_getResource()->hasDataChanged($this);
  224. }
  225. /**
  226. * Save item options
  227. *
  228. * @return $this
  229. */
  230. public function saveItemOptions()
  231. {
  232. foreach ($this->_options as $index => $option) {
  233. if ($option->isDeleted()) {
  234. $option->delete();
  235. unset($this->_options[$index]);
  236. unset($this->_optionsByCode[$option->getCode()]);
  237. } else {
  238. $option->save();
  239. }
  240. }
  241. $this->_flagOptionsSaved = true;
  242. // Report to watchers that options were saved
  243. return $this;
  244. }
  245. /**
  246. * Mark option save requirement
  247. *
  248. * @param bool $flag
  249. * @return void
  250. */
  251. public function setIsOptionsSaved($flag)
  252. {
  253. $this->_flagOptionsSaved = $flag;
  254. }
  255. /**
  256. * Were options saved?
  257. *
  258. * @return bool
  259. */
  260. public function isOptionsSaved()
  261. {
  262. return $this->_flagOptionsSaved;
  263. }
  264. /**
  265. * Save item options after item saved
  266. *
  267. * @return $this
  268. */
  269. public function afterSave()
  270. {
  271. $this->saveItemOptions();
  272. return parent::afterSave();
  273. }
  274. /**
  275. * Validate wish list item data
  276. *
  277. * @return bool
  278. * @throws \Magento\Framework\Exception\LocalizedException
  279. */
  280. public function validate()
  281. {
  282. if (!$this->getWishlistId()) {
  283. throw new \Magento\Framework\Exception\LocalizedException(__('We can\'t specify a wish list.'));
  284. }
  285. if (!$this->getProductId()) {
  286. throw new \Magento\Framework\Exception\LocalizedException(__('Cannot specify product.'));
  287. }
  288. return true;
  289. }
  290. /**
  291. * Check required data
  292. *
  293. * @return $this
  294. */
  295. public function beforeSave()
  296. {
  297. parent::beforeSave();
  298. // validate required item data
  299. $this->validate();
  300. // set current store id if it is not defined
  301. if ($this->getStoreId() === null) {
  302. $this->setStoreId($this->_storeManager->getStore()->getId());
  303. }
  304. // set current date if added at data is not defined
  305. if ($this->getAddedAt() === null) {
  306. $this->setAddedAt($this->_date->gmtDate());
  307. }
  308. return $this;
  309. }
  310. /**
  311. * Load item by product, wishlist and shared stores
  312. *
  313. * @param int $wishlistId
  314. * @param int $productId
  315. * @param array $sharedStores
  316. * @return $this
  317. */
  318. public function loadByProductWishlist($wishlistId, $productId, $sharedStores)
  319. {
  320. $this->_getResource()->loadByProductWishlist($this, $wishlistId, $productId, $sharedStores);
  321. $this->_afterLoad();
  322. $this->setOrigData();
  323. return $this;
  324. }
  325. /**
  326. * Retrieve item product instance
  327. *
  328. * @throws \Magento\Framework\Exception\LocalizedException
  329. * @return \Magento\Catalog\Model\Product
  330. */
  331. public function getProduct()
  332. {
  333. $product = $this->_getData('product');
  334. if ($product === null) {
  335. if (!$this->getProductId()) {
  336. throw new \Magento\Framework\Exception\LocalizedException(__('Cannot specify product.'));
  337. }
  338. try {
  339. $product = $this->productRepository->getById($this->getProductId(), false, $this->getStoreId(), true);
  340. } catch (NoSuchEntityException $e) {
  341. throw new \Magento\Framework\Exception\LocalizedException(__('Cannot specify product.'), $e);
  342. }
  343. $this->setData('product', $product);
  344. }
  345. /**
  346. * Reset product final price because it related to custom options
  347. */
  348. $product->setFinalPrice(null);
  349. $product->setCustomOptions($this->_optionsByCode);
  350. return $product;
  351. }
  352. /**
  353. * Add or Move item product to shopping cart
  354. *
  355. * Return true if product was successful added or exception with code
  356. * Return false for disabled or unvisible products
  357. *
  358. * @param \Magento\Checkout\Model\Cart $cart
  359. * @param bool $delete delete the item after successful add to cart
  360. * @return bool
  361. * @throws \Magento\Catalog\Model\Product\Exception
  362. */
  363. public function addToCart(\Magento\Checkout\Model\Cart $cart, $delete = false)
  364. {
  365. $product = $this->getProduct();
  366. $storeId = $this->getStoreId();
  367. if ($product->getStatus() != \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) {
  368. return false;
  369. }
  370. if (!$product->isVisibleInSiteVisibility()) {
  371. if ($product->getStoreId() == $storeId) {
  372. return false;
  373. }
  374. $urlData = $this->_catalogUrl->getRewriteByProductStore([$product->getId() => $storeId]);
  375. if (!isset($urlData[$product->getId()])) {
  376. return false;
  377. }
  378. $product->setUrlDataObject(new \Magento\Framework\DataObject($urlData));
  379. $visibility = $product->getUrlDataObject()->getVisibility();
  380. if (!in_array($visibility, $product->getVisibleInSiteVisibilities())) {
  381. return false;
  382. }
  383. }
  384. if (!$product->isSalable()) {
  385. throw new ProductException(__('Product is not salable.'));
  386. }
  387. $buyRequest = $this->getBuyRequest();
  388. $cart->addProduct($product, $buyRequest);
  389. if (!$product->isVisibleInSiteVisibility()) {
  390. $cart->getQuote()->getItemByProduct($product)->setStoreId($storeId);
  391. }
  392. if ($delete) {
  393. $this->delete();
  394. }
  395. return true;
  396. }
  397. /**
  398. * Retrieve Product View Page URL
  399. *
  400. * If product has required options add special key to URL
  401. *
  402. * @return string
  403. */
  404. public function getProductUrl()
  405. {
  406. $product = $this->getProduct();
  407. $query = [];
  408. if ($product->getTypeInstance()->hasRequiredOptions($product)) {
  409. $query['options'] = 'cart';
  410. }
  411. return $product->getUrlModel()->getUrl($product, ['_query' => $query]);
  412. }
  413. /**
  414. * Returns formatted buy request - object, holding request received from
  415. * product view page with keys and options for configured product
  416. *
  417. * @return \Magento\Framework\DataObject
  418. */
  419. public function getBuyRequest()
  420. {
  421. $option = $this->getOptionByCode('info_buyRequest');
  422. $initialData = $option ? $this->serializer->unserialize($option->getValue()) : [];
  423. if ($initialData instanceof \Magento\Framework\DataObject) {
  424. $initialData = $initialData->getData();
  425. }
  426. $buyRequest = new \Magento\Framework\DataObject($initialData);
  427. $buyRequest->setOriginalQty($buyRequest->getQty())->setQty($this->getQty() * 1);
  428. return $buyRequest;
  429. }
  430. /**
  431. * Merge data to item info_buyRequest option
  432. *
  433. * @param array|\Magento\Framework\DataObject $buyRequest
  434. * @return $this
  435. */
  436. public function mergeBuyRequest($buyRequest)
  437. {
  438. if ($buyRequest instanceof \Magento\Framework\DataObject) {
  439. $buyRequest = $buyRequest->getData();
  440. }
  441. if (empty($buyRequest) || !is_array($buyRequest)) {
  442. return $this;
  443. }
  444. $oldBuyRequest = $this->getBuyRequest()->getData();
  445. $sBuyRequest = $this->serializer->serialize($buyRequest + $oldBuyRequest);
  446. $option = $this->getOptionByCode('info_buyRequest');
  447. if ($option) {
  448. $option->setValue($sBuyRequest);
  449. } else {
  450. $this->addOption(['code' => 'info_buyRequest', 'value' => $sBuyRequest]);
  451. }
  452. return $this;
  453. }
  454. /**
  455. * Set buy request - object, holding request received from
  456. * product view page with keys and options for configured product
  457. *
  458. * @param \Magento\Framework\DataObject $buyRequest
  459. * @return $this
  460. */
  461. public function setBuyRequest($buyRequest)
  462. {
  463. $buyRequest->setId($this->getId());
  464. $_buyRequest = $this->serializer->serialize($buyRequest->getData());
  465. $this->setData('buy_request', $_buyRequest);
  466. return $this;
  467. }
  468. /**
  469. * Check product representation in item
  470. *
  471. * @param \Magento\Catalog\Model\Product $product
  472. * @param \Magento\Framework\DataObject $buyRequest
  473. * @return bool
  474. */
  475. public function isRepresent($product, $buyRequest)
  476. {
  477. if ($this->getProductId() != $product->getId()) {
  478. return false;
  479. }
  480. $selfOptions = $this->getBuyRequest()->getData();
  481. if (empty($buyRequest) && !empty($selfOptions)) {
  482. return false;
  483. }
  484. if (empty($selfOptions) && !empty($buyRequest)) {
  485. if (!$product->isComposite()) {
  486. return true;
  487. } else {
  488. return false;
  489. }
  490. }
  491. $requestArray = $buyRequest->getData();
  492. if (!$this->_compareOptions($requestArray, $selfOptions)) {
  493. return false;
  494. }
  495. if (!$this->_compareOptions($selfOptions, $requestArray)) {
  496. return false;
  497. }
  498. return true;
  499. }
  500. /**
  501. * Check product representation in item
  502. *
  503. * @param \Magento\Catalog\Model\Product $product
  504. * @return bool
  505. */
  506. public function representProduct($product)
  507. {
  508. $itemProduct = $this->getProduct();
  509. if ($itemProduct->getId() != $product->getId()) {
  510. return false;
  511. }
  512. $itemOptions = $this->getOptionsByCode();
  513. $productOptions = $product->getCustomOptions();
  514. if (!$this->compareOptions($itemOptions, $productOptions)) {
  515. return false;
  516. }
  517. if (!$this->compareOptions($productOptions, $itemOptions)) {
  518. return false;
  519. }
  520. return true;
  521. }
  522. /**
  523. * Check if two options array are identical
  524. * First options array is prerogative
  525. * Second options array checked against first one
  526. *
  527. * @param array $options1
  528. * @param array $options2
  529. * @return bool
  530. */
  531. public function compareOptions($options1, $options2)
  532. {
  533. foreach ($options1 as $option) {
  534. $code = $option->getCode();
  535. if (in_array($code, $this->_notRepresentOptions)) {
  536. continue;
  537. }
  538. if (!isset($options2[$code]) || $options2[$code]->getValue() != $option->getValue()) {
  539. return false;
  540. }
  541. }
  542. return true;
  543. }
  544. /**
  545. * Initialize item options
  546. *
  547. * @param array $options
  548. * @return $this
  549. */
  550. public function setOptions($options)
  551. {
  552. foreach ($options as $option) {
  553. $this->addOption($option);
  554. }
  555. return $this;
  556. }
  557. /**
  558. * Get all item options
  559. *
  560. * @return Option[]
  561. */
  562. public function getOptions()
  563. {
  564. return $this->_options;
  565. }
  566. /**
  567. * Get all item options as array with codes in array key
  568. *
  569. * @return array
  570. */
  571. public function getOptionsByCode()
  572. {
  573. return $this->_optionsByCode;
  574. }
  575. /**
  576. * Add option to item
  577. *
  578. * @param Option|\Magento\Framework\DataObject|array $option
  579. * @return $this
  580. * @throws \Magento\Framework\Exception\LocalizedException
  581. */
  582. public function addOption($option)
  583. {
  584. if (is_array($option)) {
  585. $option = $this->_wishlistOptFactory->create()->setData($option)->setItem($this);
  586. } elseif ($option instanceof Option) {
  587. $option->setItem($this);
  588. } elseif ($option instanceof \Magento\Framework\DataObject) {
  589. $option = $this->_wishlistOptFactory->create()->setData($option->getData())
  590. ->setProduct($option->getProduct())
  591. ->setItem($this);
  592. } else {
  593. throw new \Magento\Framework\Exception\LocalizedException(__('Invalid item option format.'));
  594. }
  595. $exOption = $this->getOptionByCode($option->getCode());
  596. if ($exOption) {
  597. $exOption->addData($option->getData());
  598. } else {
  599. $this->_addOptionCode($option);
  600. $this->_options[] = $option;
  601. }
  602. return $this;
  603. }
  604. /**
  605. * Remove option from item options
  606. *
  607. * @param string $code
  608. * @return $this
  609. */
  610. public function removeOption($code)
  611. {
  612. $option = $this->getOptionByCode($code);
  613. if ($option) {
  614. $option->isDeleted(true);
  615. }
  616. return $this;
  617. }
  618. /**
  619. * Get item option by code
  620. *
  621. * @param string $code
  622. * @return Option|null
  623. */
  624. public function getOptionByCode($code)
  625. {
  626. if (isset($this->_optionsByCode[$code]) && !$this->_optionsByCode[$code]->isDeleted()) {
  627. return $this->_optionsByCode[$code];
  628. }
  629. return null;
  630. }
  631. /**
  632. * Returns whether Qty field is valid for this item
  633. *
  634. * @return bool
  635. */
  636. public function canHaveQty()
  637. {
  638. $product = $this->getProduct();
  639. return !$this->productTypeConfig->isProductSet($product->getTypeId());
  640. }
  641. /**
  642. * Get current custom option download url
  643. *
  644. * @return string
  645. */
  646. public function getCustomDownloadUrl()
  647. {
  648. return $this->_customOptionDownloadUrl;
  649. }
  650. /**
  651. * Sets custom option download url
  652. *
  653. * @param string $url
  654. * @return void
  655. */
  656. public function setCustomDownloadUrl($url)
  657. {
  658. $this->_customOptionDownloadUrl = $url;
  659. }
  660. /**
  661. * Returns special download params (if needed) for custom option with type = 'file'.
  662. * Needed to implement \Magento\Catalog\Model\Product\Configuration\Item\Interface.
  663. *
  664. * We have to customize only controller url, so return it.
  665. *
  666. * @return null|\Magento\Framework\DataObject
  667. */
  668. public function getFileDownloadParams()
  669. {
  670. $params = new \Magento\Framework\DataObject();
  671. $params->setUrl($this->_customOptionDownloadUrl);
  672. return $params;
  673. }
  674. /**
  675. * Loads item together with its options (default load() method doesn't load options).
  676. * If we need to load only some of options, then option code or array of option codes
  677. * can be provided in $optionsFilter.
  678. *
  679. * @param int $id
  680. * @param null|string|array $optionsFilter
  681. *
  682. * @return $this
  683. */
  684. public function loadWithOptions($id, $optionsFilter = null)
  685. {
  686. $this->load($id);
  687. if (!$this->getId()) {
  688. return $this;
  689. }
  690. $options = $this->_wishlOptionCollectionFactory->create()->addItemFilter($this);
  691. if ($optionsFilter) {
  692. $options->addFieldToFilter('code', $optionsFilter);
  693. }
  694. $this->setOptions($options->getOptionsByItem($this));
  695. return $this;
  696. }
  697. }