123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Eav\Model\Entity;
- use Magento\Framework\Api\AttributeValueFactory;
- use Magento\Framework\Exception\LocalizedException;
- use Magento\Framework\Stdlib\DateTime;
- use Magento\Framework\Stdlib\DateTime\DateTimeFormatterInterface;
- /**
- * EAV Entity attribute model
- *
- * @api
- * @method \Magento\Eav\Model\Entity\Attribute setOption($value)
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- * @since 100.0.2
- */
- class Attribute extends \Magento\Eav\Model\Entity\Attribute\AbstractAttribute implements
- \Magento\Framework\DataObject\IdentityInterface
- {
- /**
- * Attribute code max length.
- *
- * The value is defined as 60 because in the flat mode attribute code will be transformed into column name.
- * MySQL allows only 64 symbols in column name.
- */
- const ATTRIBUTE_CODE_MAX_LENGTH = 60;
- /**
- * Attribute code min length.
- */
- const ATTRIBUTE_CODE_MIN_LENGTH = 1;
- /**
- * Cache tag
- */
- const CACHE_TAG = 'EAV_ATTRIBUTE';
- /**
- * Prefix of model events names
- *
- * @var string
- */
- protected $_eventPrefix = 'eav_entity_attribute';
- /**
- * Parameter name in event
- *
- * In observe method you can use $observer->getEvent()->getAttribute() in this case
- *
- * @var string
- */
- protected $_eventObject = 'attribute';
- /**
- * @var string
- */
- protected $_cacheTag = self::CACHE_TAG;
- /**
- * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
- */
- protected $_localeDate;
- /**
- * @var \Magento\Catalog\Model\Product\ReservedAttributeList
- */
- protected $reservedAttributeList;
- /**
- * @var \Magento\Framework\Locale\ResolverInterface
- */
- protected $_localeResolver;
- /**
- * @var DateTimeFormatterInterface
- */
- protected $dateTimeFormatter;
- /**
- * @param \Magento\Framework\Model\Context $context
- * @param \Magento\Framework\Registry $registry
- * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
- * @param AttributeValueFactory $customAttributeFactory
- * @param \Magento\Eav\Model\Config $eavConfig
- * @param TypeFactory $eavTypeFactory
- * @param \Magento\Store\Model\StoreManagerInterface $storeManager
- * @param \Magento\Eav\Model\ResourceModel\Helper $resourceHelper
- * @param \Magento\Framework\Validator\UniversalFactory $universalFactory
- * @param \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory $optionDataFactory
- * @param \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor
- * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
- * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
- * @param \Magento\Catalog\Model\Product\ReservedAttributeList $reservedAttributeList
- * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
- * @param DateTimeFormatterInterface $dateTimeFormatter
- * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
- * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
- * @param array $data
- * @SuppressWarnings(PHPMD.ExcessiveParameterList)
- * @codeCoverageIgnore
- */
- public function __construct(
- \Magento\Framework\Model\Context $context,
- \Magento\Framework\Registry $registry,
- \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
- AttributeValueFactory $customAttributeFactory,
- \Magento\Eav\Model\Config $eavConfig,
- \Magento\Eav\Model\Entity\TypeFactory $eavTypeFactory,
- \Magento\Store\Model\StoreManagerInterface $storeManager,
- \Magento\Eav\Model\ResourceModel\Helper $resourceHelper,
- \Magento\Framework\Validator\UniversalFactory $universalFactory,
- \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory $optionDataFactory,
- \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor,
- \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
- \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
- \Magento\Catalog\Model\Product\ReservedAttributeList $reservedAttributeList,
- \Magento\Framework\Locale\ResolverInterface $localeResolver,
- DateTimeFormatterInterface $dateTimeFormatter,
- \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
- \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
- array $data = []
- ) {
- parent::__construct(
- $context,
- $registry,
- $extensionFactory,
- $customAttributeFactory,
- $eavConfig,
- $eavTypeFactory,
- $storeManager,
- $resourceHelper,
- $universalFactory,
- $optionDataFactory,
- $dataObjectProcessor,
- $dataObjectHelper,
- $resource,
- $resourceCollection,
- $data
- );
- $this->_localeDate = $localeDate;
- $this->_localeResolver = $localeResolver;
- $this->reservedAttributeList = $reservedAttributeList;
- $this->dateTimeFormatter = $dateTimeFormatter;
- }
- /**
- * Retrieve default attribute backend model by attribute code
- *
- * @return string
- */
- protected function _getDefaultBackendModel()
- {
- switch ($this->getAttributeCode()) {
- case 'created_at':
- return \Magento\Eav\Model\Entity\Attribute\Backend\Time\Created::class;
- case 'updated_at':
- return \Magento\Eav\Model\Entity\Attribute\Backend\Time\Updated::class;
- case 'store_id':
- return \Magento\Eav\Model\Entity\Attribute\Backend\Store::class;
- case 'increment_id':
- return \Magento\Eav\Model\Entity\Attribute\Backend\Increment::class;
- default:
- break;
- }
- return parent::_getDefaultBackendModel();
- }
- /**
- * Retrieve default attribute source model
- *
- * @return string
- */
- protected function _getDefaultSourceModel()
- {
- if ($this->getAttributeCode() == 'store_id') {
- return \Magento\Eav\Model\Entity\Attribute\Source\Store::class;
- }
- return parent::_getDefaultSourceModel();
- }
- /**
- * Delete entity
- *
- * @return \Magento\Eav\Model\ResourceModel\Entity\Attribute
- * @codeCoverageIgnore
- */
- public function deleteEntity()
- {
- return $this->_getResource()->deleteEntity($this);
- }
- /**
- * Load entity_attribute_id into $this by $this->attribute_set_id
- *
- * @return $this
- */
- public function loadEntityAttributeIdBySet()
- {
- // load attributes collection filtered by attribute_id and attribute_set_id
- $filteredAttributes = $this->getResourceCollection()->setAttributeSetFilter(
- $this->getAttributeSetId()
- )->addFieldToFilter(
- 'entity_attribute.attribute_id',
- $this->getId()
- )->load();
- if (count($filteredAttributes) > 0) {
- // getFirstItem() can be used as we can have one or zero records in the collection
- $this->setEntityAttributeId($filteredAttributes->getFirstItem()->getEntityAttributeId());
- }
- return $this;
- }
- /**
- * Prepare data for save
- *
- * @return $this
- * @throws LocalizedException
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- * @SuppressWarnings(PHPMD.NPathComplexity)
- */
- public function beforeSave()
- {
- // prevent overriding product data
- if (isset($this->_data['attribute_code']) && $this->reservedAttributeList->isReservedAttribute($this)) {
- throw new LocalizedException(
- __(
- 'The attribute code \'%1\' is reserved by system. Please try another attribute code',
- $this->_data['attribute_code']
- )
- );
- }
- /**
- * Check for maximum attribute_code length
- */
- if (isset(
- $this->_data['attribute_code']
- ) && !\Zend_Validate::is(
- $this->_data['attribute_code'],
- 'StringLength',
- ['max' => self::ATTRIBUTE_CODE_MAX_LENGTH]
- )
- ) {
- throw new LocalizedException(
- __(
- 'The attribute code needs to be %1 characters or fewer. Re-enter the code and try again.',
- self::ATTRIBUTE_CODE_MAX_LENGTH
- )
- );
- }
- $defaultValue = $this->getDefaultValue();
- $hasDefaultValue = (string)$defaultValue != '';
- if ($this->getBackendType() == 'decimal' && $hasDefaultValue) {
- $numberFormatter = new \NumberFormatter($this->_localeResolver->getLocale(), \NumberFormatter::DECIMAL);
- $defaultValue = $numberFormatter->parse($defaultValue);
- if ($defaultValue === false) {
- throw new LocalizedException(
- __('The default decimal value is invalid. Verify the value and try again.')
- );
- }
- $this->setDefaultValue($defaultValue);
- }
- if ($this->getBackendType() == 'datetime') {
- if (!$this->getBackendModel()) {
- $this->setBackendModel(\Magento\Eav\Model\Entity\Attribute\Backend\Datetime::class);
- }
- if (!$this->getFrontendModel()) {
- $this->setFrontendModel(\Magento\Eav\Model\Entity\Attribute\Frontend\Datetime::class);
- }
- // save default date value as timestamp
- if ($hasDefaultValue) {
- try {
- $locale = $this->_localeResolver->getLocale();
- $defaultValue = $this->_localeDate->date($defaultValue, $locale, false, false);
- $this->setDefaultValue($defaultValue->format(DateTime::DATETIME_PHP_FORMAT));
- } catch (\Exception $e) {
- throw new LocalizedException(__('The default date is invalid. Verify the date and try again.'));
- }
- }
- }
- if ($this->getFrontendInput() == 'media_image') {
- if (!$this->getFrontendModel()) {
- $this->setFrontendModel(\Magento\Catalog\Model\Product\Attribute\Frontend\Image::class);
- }
- }
- if ($this->getBackendType() == 'gallery') {
- if (!$this->getBackendModel()) {
- $this->setBackendModel(\Magento\Eav\Model\Entity\Attribute\Backend\DefaultBackend::class);
- }
- }
- return parent::beforeSave();
- }
- /**
- * Save additional data
- *
- * @return $this
- */
- public function afterSave()
- {
- $this->_getResource()->saveInSetIncluding($this);
- return parent::afterSave();
- }
- /**
- * @inheritdoc
- * @since 100.0.7
- */
- public function afterDelete()
- {
- return parent::afterDelete();
- }
- /**
- * Detect backend storage type using frontend input type
- *
- * @param string $type frontend_input field value
- * @return string backend_type field value
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- */
- public function getBackendTypeByInput($type)
- {
- $field = null;
- switch ($type) {
- case 'text':
- case 'gallery':
- case 'media_image':
- case 'multiselect':
- $field = 'varchar';
- break;
- case 'image':
- case 'textarea':
- $field = 'text';
- break;
- case 'date':
- $field = 'datetime';
- break;
- case 'select':
- case 'boolean':
- $field = 'int';
- break;
- case 'price':
- case 'weight':
- $field = 'decimal';
- break;
- default:
- break;
- }
- return $field;
- }
- /**
- * Detect default value using frontend input type
- *
- * @param string $type frontend_input field name
- * @return string default_value field value
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- */
- public function getDefaultValueByInput($type)
- {
- $field = '';
- switch ($type) {
- case 'select':
- case 'gallery':
- case 'media_image':
- break;
- case 'multiselect':
- $field = null;
- break;
- case 'text':
- case 'price':
- case 'image':
- case 'weight':
- $field = 'default_value_text';
- break;
- case 'textarea':
- case 'texteditor':
- $field = 'default_value_textarea';
- break;
- case 'date':
- $field = 'default_value_date';
- break;
- case 'boolean':
- $field = 'default_value_yesno';
- break;
- default:
- break;
- }
- return $field;
- }
- /**
- * Retrieve attribute codes by frontend type
- *
- * @param string $type
- * @return array
- * @codeCoverageIgnore
- */
- public function getAttributeCodesByFrontendType($type)
- {
- return $this->getResource()->getAttributeCodesByFrontendType($type);
- }
- /**
- * Return array of labels of stores
- *
- * @return string[]
- */
- public function getStoreLabels()
- {
- if (!$this->getData('store_labels')) {
- $storeLabel = $this->getResource()->getStoreLabelsByAttributeId($this->getId());
- $this->setData('store_labels', $storeLabel);
- }
- return $this->getData('store_labels');
- }
- /**
- * Return store label of attribute
- *
- * @param int|null $storeId
- * @return string
- */
- public function getStoreLabel($storeId = null)
- {
- if ($this->hasData('store_label')) {
- return $this->getData('store_label');
- }
- $store = $this->_storeManager->getStore($storeId);
- $labels = $this->getStoreLabels();
- if (isset($labels[$store->getId()])) {
- return $labels[$store->getId()];
- } else {
- return $this->getFrontendLabel();
- }
- }
- /**
- * Get attribute sort weight
- *
- * @param int $setId
- * @return float
- */
- public function getSortWeight($setId)
- {
- $groupSortWeight = isset($this->_data['attribute_set_info'][$setId]['group_sort'])
- ? (float) $this->_data['attribute_set_info'][$setId]['group_sort'] * 1000
- : 0.0;
- $sortWeight = isset($this->_data['attribute_set_info'][$setId]['sort'])
- ? (float) $this->_data['attribute_set_info'][$setId]['sort'] * 0.0001
- : 0.0;
- return $groupSortWeight + $sortWeight;
- }
- /**
- * Get identities
- *
- * @return array
- * @codeCoverageIgnore
- */
- public function getIdentities()
- {
- return [self::CACHE_TAG . '_' . $this->getId()];
- }
- /**
- * @inheritdoc
- * @since 100.0.7
- */
- public function __sleep()
- {
- $this->unsetData('attribute_set_info');
- return array_diff(
- parent::__sleep(),
- ['_localeDate', '_localeResolver', 'reservedAttributeList', 'dateTimeFormatter']
- );
- }
- /**
- * @inheritdoc
- * @since 100.0.7
- */
- public function __wakeup()
- {
- parent::__wakeup();
- $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
- $this->_localeDate = $objectManager->get(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::class);
- $this->_localeResolver = $objectManager->get(\Magento\Framework\Locale\ResolverInterface::class);
- $this->reservedAttributeList = $objectManager->get(\Magento\Catalog\Model\Product\ReservedAttributeList::class);
- $this->dateTimeFormatter = $objectManager->get(DateTimeFormatterInterface::class);
- }
- }
|