Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Option.php
Go to the documentation of this file.
1 <?php
8 
11 use Magento\Catalog\Api\Data\ProductCustomOptionValuesInterfaceFactory;
19 
33 {
38  protected $optionRepository;
39 
44  protected static $typePercent = 'percent';
45 
49  const KEY_PRODUCT_SKU = 'product_sku';
50  const KEY_OPTION_ID = 'option_id';
51  const KEY_TITLE = 'title';
52  const KEY_TYPE = 'type';
53  const KEY_SORT_ORDER = 'sort_order';
54  const KEY_IS_REQUIRE = 'is_require';
55  const KEY_PRICE = 'price';
56  const KEY_PRICE_TYPE = 'price_type';
57  const KEY_SKU = 'sku';
58  const KEY_FILE_EXTENSION = 'file_extension';
59  const KEY_MAX_CHARACTERS = 'max_characters';
60  const KEY_IMAGE_SIZE_Y = 'image_size_y';
61  const KEY_IMAGE_SIZE_X = 'image_size_x';
65  protected $product;
66 
70  protected $options = [];
71 
75  protected $values = null;
76 
83 
89  protected $optionTypeFactory;
90 
94  protected $string;
95 
99  protected $validatorPool;
100 
104  private $metadataPool;
105 
109  private $customOptionValuesFactory;
110 
126  public function __construct(
127  \Magento\Framework\Model\Context $context,
128  \Magento\Framework\Registry $registry,
129  \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
133  \Magento\Framework\Stdlib\StringUtils $string,
135  \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
136  \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
137  array $data = [],
138  ProductCustomOptionValuesInterfaceFactory $customOptionValuesFactory = null
139  ) {
140  $this->productOptionValue = $productOptionValue;
141  $this->optionTypeFactory = $optionFactory;
142  $this->validatorPool = $validatorPool;
143  $this->string = $string;
144  $this->customOptionValuesFactory = $customOptionValuesFactory ?:
145  \Magento\Framework\App\ObjectManager::getInstance()->get(ProductCustomOptionValuesInterfaceFactory::class);
146 
147  parent::__construct(
148  $context,
149  $registry,
150  $extensionFactory,
152  $resource,
153  $resourceCollection,
154  $data
155  );
156  }
157 
164  protected function _getResource()
165  {
166  return $this->_resource ?: parent::_getResource();
167  }
168 
172  protected function _construct()
173  {
174  $this->_init(\Magento\Catalog\Model\ResourceModel\Product\Option::class);
175  parent::_construct();
176  }
177 
184  public function addValue(Option\Value $value)
185  {
186  $this->values[$value->getId()] = $value;
187  return $this;
188  }
189 
196  public function getValueById($valueId)
197  {
198  if (isset($this->values[$valueId])) {
199  return $this->values[$valueId];
200  }
201 
202  return null;
203  }
204 
212  public function hasValues($type = null)
213  {
215  }
216 
220  public function getValues()
221  {
222  return $this->values;
223  }
224 
230  public function getValueInstance()
231  {
233  }
234 
241  public function addOption($option)
242  {
243  $this->options[] = $option;
244  return $this;
245  }
246 
252  public function getOptions()
253  {
254  return $this->options;
255  }
256 
263  public function setOptions($options)
264  {
265  $this->options = $options;
266  return $this;
267  }
268 
274  public function unsetOptions()
275  {
276  $this->options = [];
277  return $this;
278  }
279 
285  public function getProduct()
286  {
287  return $this->product;
288  }
289 
296  public function setProduct(Product $product = null)
297  {
298  $this->product = $product;
299  return $this;
300  }
301 
308  public function getGroupByType($type = null)
309  {
310  if ($type === null) {
311  $type = $this->getType();
312  }
313  $optionGroupsToTypes = [
314  self::OPTION_TYPE_FIELD => self::OPTION_GROUP_TEXT,
315  self::OPTION_TYPE_AREA => self::OPTION_GROUP_TEXT,
316  self::OPTION_TYPE_FILE => self::OPTION_GROUP_FILE,
317  self::OPTION_TYPE_DROP_DOWN => self::OPTION_GROUP_SELECT,
318  self::OPTION_TYPE_RADIO => self::OPTION_GROUP_SELECT,
319  self::OPTION_TYPE_CHECKBOX => self::OPTION_GROUP_SELECT,
320  self::OPTION_TYPE_MULTIPLE => self::OPTION_GROUP_SELECT,
321  self::OPTION_TYPE_DATE => self::OPTION_GROUP_DATE,
322  self::OPTION_TYPE_DATE_TIME => self::OPTION_GROUP_DATE,
323  self::OPTION_TYPE_TIME => self::OPTION_GROUP_DATE,
324  ];
325 
326  return $optionGroupsToTypes[$type] ?? '';
327  }
328 
336  public function groupFactory($type)
337  {
338  $group = $this->getGroupByType($type);
339  if (!empty($group)) {
340  return $this->optionTypeFactory->create(
341  'Magento\Catalog\Model\Product\Option\Type\\' . $this->string->upperCaseWords($group)
342  );
343  }
344  throw new LocalizedException(__('The option type to get group instance is incorrect.'));
345  }
346 
352  public function beforeSave()
353  {
354  parent::beforeSave();
355  if ($this->getData('previous_type') != '') {
356  $previousType = $this->getData('previous_type');
357 
362  if ($this->getGroupByType($previousType) != $this->getGroupByType($this->getData('type'))) {
363  switch ($this->getGroupByType($previousType)) {
365  $this->unsetData('values');
366  if ($this->getId()) {
367  $this->getValueInstance()->deleteValue($this->getId());
368  }
369  break;
371  $this->setData('file_extension', '');
372  $this->setData('image_size_x', '0');
373  $this->setData('image_size_y', '0');
374  break;
376  $this->setData('max_characters', '0');
377  break;
379  break;
380  }
381  if ($this->getGroupByType($this->getData('type')) == self::OPTION_GROUP_SELECT) {
382  $this->setData('sku', '');
383  $this->unsetData('price');
384  $this->unsetData('price_type');
385  if ($this->getId()) {
386  $this->deletePrices($this->getId());
387  }
388  }
389  }
390  }
391  if ($this->getGroupByType($this->getData('type')) === self::OPTION_GROUP_FILE) {
392  $this->cleanFileExtensions();
393  }
394 
395  return $this;
396  }
397 
402  public function afterSave()
403  {
404  $values = $this->getValues() ?: $this->getData('values');
405  if (is_array($values)) {
406  foreach ($values as $value) {
408  $data = $value->getData();
409  } else {
410  $data = $value;
411  }
412 
413  $this->customOptionValuesFactory->create()
414  ->addValue($data)
415  ->setOption($this)
416  ->saveValues();
417  }
418  } elseif ($this->getGroupByType($this->getType()) === self::OPTION_GROUP_SELECT) {
419  throw new LocalizedException(__('Select type options required values rows.'));
420  }
421 
422  return parent::afterSave();
423  }
424 
432  public function getPrice($flag = false)
433  {
434  if ($flag && $this->getPriceType() == self::$typePercent) {
435  $basePrice = $this->getProduct()->getPriceInfo()->getPrice(BasePrice::PRICE_CODE)->getValue();
436  $price = $basePrice * ($this->_getData(self::KEY_PRICE) / 100);
437  return $price;
438  }
439  return $this->_getData(self::KEY_PRICE);
440  }
441 
448  public function deletePrices($optionId)
449  {
450  $this->getResource()->deletePrices($optionId);
451  return $this;
452  }
453 
460  public function deleteTitles($optionId)
461  {
462  $this->getResource()->deleteTitles($optionId);
463  return $this;
464  }
465 
474  {
475  return $this->getOptionRepository()->getProductOptions($product, $this->getAddRequiredFilter());
476  }
477 
483  public function getValuesCollection()
484  {
485  $collection = $this->getValueInstance()->getValuesCollection($this);
486 
487  return $collection;
488  }
489 
498  {
499  $collection = $this->productOptionValue->getValuesByOption($optionIds, $this->getId(), $storeId);
500 
501  return $collection;
502  }
503 
511  public function duplicate($oldProductId, $newProductId)
512  {
513  $this->getResource()->duplicate($this, $oldProductId, $newProductId);
514 
515  return $this;
516  }
517 
526  {
527  return $this->_getResource()->getSearchableData($productId, $storeId);
528  }
529 
535  protected function _clearData()
536  {
537  $this->_data = [];
538  $this->values = null;
539  return $this;
540  }
541 
547  protected function _clearReferences()
548  {
549  if (!empty($this->values)) {
550  foreach ($this->values as $value) {
551  $value->unsetOption();
552  }
553  }
554  return $this;
555  }
556 
560  protected function _getValidationRulesBeforeSave()
561  {
562  return $this->validatorPool->get($this->getType());
563  }
564 
570  public function getProductSku()
571  {
572  $productSku = $this->_getData(self::KEY_PRODUCT_SKU);
573  if (!$productSku && $this->getProduct()) {
574  $productSku = $this->getProduct()->getSku();
575  }
576  return $productSku;
577  }
578 
585  public function getOptionId()
586  {
587  return $this->_getData(self::KEY_OPTION_ID);
588  }
589 
595  public function getTitle()
596  {
597  return $this->_getData(self::KEY_TITLE);
598  }
599 
605  public function getType()
606  {
607  return $this->_getData(self::KEY_TYPE);
608  }
609 
615  public function getSortOrder()
616  {
617  return $this->_getData(self::KEY_SORT_ORDER);
618  }
619 
626  public function getIsRequire()
627  {
628  return $this->_getData(self::KEY_IS_REQUIRE);
629  }
630 
636  public function getPriceType()
637  {
638  return $this->_getData(self::KEY_PRICE_TYPE);
639  }
640 
646  public function getSku()
647  {
648  return $this->_getData(self::KEY_SKU);
649  }
650 
654  public function getFileExtension()
655  {
656  return $this->getData(self::KEY_FILE_EXTENSION);
657  }
658 
662  public function getMaxCharacters()
663  {
664  return $this->getData(self::KEY_MAX_CHARACTERS);
665  }
666 
670  public function getImageSizeX()
671  {
672  return $this->getData(self::KEY_IMAGE_SIZE_X);
673  }
674 
678  public function getImageSizeY()
679  {
680  return $this->getData(self::KEY_IMAGE_SIZE_Y);
681  }
682 
689  public function setProductSku($productSku)
690  {
691  return $this->setData(self::KEY_PRODUCT_SKU, $productSku);
692  }
693 
700  public function setOptionId($optionId)
701  {
702  return $this->setData(self::KEY_OPTION_ID, $optionId);
703  }
704 
711  public function setTitle($title)
712  {
713  return $this->setData(self::KEY_TITLE, $title);
714  }
715 
722  public function setType($type)
723  {
724  return $this->setData(self::KEY_TYPE, $type);
725  }
726 
733  public function setSortOrder($sortOrder)
734  {
735  return $this->setData(self::KEY_SORT_ORDER, $sortOrder);
736  }
737 
744  public function setIsRequire($isRequired)
745  {
746  return $this->setData(self::KEY_IS_REQUIRE, $isRequired);
747  }
748 
755  public function setPrice($price)
756  {
757  return $this->setData(self::KEY_PRICE, $price);
758  }
759 
766  public function setPriceType($priceType)
767  {
768  return $this->setData(self::KEY_PRICE_TYPE, $priceType);
769  }
770 
777  public function setSku($sku)
778  {
779  return $this->setData(self::KEY_SKU, $sku);
780  }
781 
786  public function setFileExtension($fileExtension)
787  {
788  return $this->setData(self::KEY_FILE_EXTENSION, $fileExtension);
789  }
790 
795  public function setMaxCharacters($maxCharacters)
796  {
797  return $this->setData(self::KEY_MAX_CHARACTERS, $maxCharacters);
798  }
799 
804  public function setImageSizeX($imageSizeX)
805  {
806  return $this->setData(self::KEY_IMAGE_SIZE_X, $imageSizeX);
807  }
808 
813  public function setImageSizeY($imageSizeY)
814  {
815  return $this->setData(self::KEY_IMAGE_SIZE_Y, $imageSizeY);
816  }
817 
822  public function setValues(array $values = null)
823  {
824  $this->values = $values;
825  return $this;
826  }
827 
833  public function getExtensionAttributes()
834  {
835  return $this->_getExtensionAttributes();
836  }
837 
844  public function getRegularPrice()
845  {
846  if ($this->getPriceType() == self::$typePercent) {
847  $basePrice = $this->getProduct()->getPriceInfo()->getPrice('regular_price')->getAmount()->getValue();
848  $price = $basePrice * ($this->_getData(self::KEY_PRICE) / 100);
849  return $price;
850  }
851  return $this->_getData(self::KEY_PRICE);
852  }
853 
859  {
860  $collection = clone $this->getCollection();
861  $collection->addFieldToFilter(
862  'product_id',
863  $product->getData($this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField())
864  )->addTitleToResult(
865  $product->getStoreId()
866  )->addPriceToResult(
867  $product->getStoreId()
868  )->setOrder(
869  'sort_order',
870  'asc'
871  )->setOrder(
872  'title',
873  'asc'
874  );
875 
876  if ($this->getAddRequiredFilter()) {
877  $collection->addRequiredFilter($this->getAddRequiredFilterValue());
878  }
879 
880  $collection->addValuesToResult($product->getStoreId());
881  return $collection;
882  }
883 
890  public function setExtensionAttributes(
891  \Magento\Catalog\Api\Data\ProductCustomOptionExtensionInterface $extensionAttributes
892  ) {
893  return $this->_setExtensionAttributes($extensionAttributes);
894  }
895 
899  private function getOptionRepository()
900  {
901  if (null === $this->optionRepository) {
902  $this->optionRepository = \Magento\Framework\App\ObjectManager::getInstance()
903  ->get(\Magento\Catalog\Model\Product\Option\Repository::class);
904  }
906  }
907 
911  private function getMetadataPool()
912  {
913  if (null === $this->metadataPool) {
915  ->get(\Magento\Framework\EntityManager\MetadataPool::class);
916  }
917  return $this->metadataPool;
918  }
919 
920  //@codeCoverageIgnoreEnd
921 
927  private function cleanFileExtensions()
928  {
929  $rawExtensions = $this->getFileExtension();
930  $matches = [];
931  preg_match_all('/(?<extensions>[a-z0-9]+)/i', strtolower($rawExtensions), $matches);
932  if (!empty($matches)) {
933  $extensions = implode(', ', array_unique($matches['extensions']));
934  }
935  $this->setFileExtension($extensions);
936  }
937 }
$title
Definition: default.phtml:14
duplicate($oldProductId, $newProductId)
Definition: Option.php:511
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
_setExtensionAttributes(\Magento\Framework\Api\ExtensionAttributesInterface $extensionAttributes)
getOptionValuesByOptionId($optionIds, $storeId)
Definition: Option.php:497
__construct(\Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory, Option\Value $productOptionValue, \Magento\Catalog\Model\Product\Option\Type\Factory $optionFactory, \Magento\Framework\Stdlib\StringUtils $string, Option\Validator\Pool $validatorPool, \Magento\Framework\Model\ResourceModel\AbstractResource $resource=null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection=null, array $data=[], ProductCustomOptionValuesInterfaceFactory $customOptionValuesFactory=null)
Definition: Option.php:126
$group
Definition: sections.phtml:16
__()
Definition: __.php:13
$resource
Definition: bulk.php:12
$price
$type
Definition: item.phtml:13
$value
Definition: gender.phtml:16
setExtensionAttributes(\Magento\Catalog\Api\Data\ProductCustomOptionExtensionInterface $extensionAttributes)
Definition: Option.php:890
$priceType
Definition: msrp.phtml:18
setValues(array $values=null)
Definition: Option.php:822
getProductOptions(Product $product)
Definition: Option.php:473
addValue(Option\Value $value)
Definition: Option.php:184
getSearchableData($productId, $storeId)
Definition: Option.php:525
getProductOptionCollection(Product $product)
Definition: Option.php:858
setProduct(Product $product=null)
Definition: Option.php:296