/** * Clear useless attribute values * * @param \Magento\Framework\Model\AbstractModel $object * @return $this */ protected function _clearUselessAttributeValues(\Magento\Framework\Model\AbstractModel $object) { $origData = $object->getOrigData(); if ($object->isScopeGlobal() && isset($origData['is_global']) && \Magento\Catalog\Model\ResourceModel\Eav\Attribute::SCOPE_GLOBAL != $origData['is_global']) { $attributeStoreIds = array_keys($this->_storeManager->getStores()); if (!empty($attributeStoreIds)) { $delCondition = ['attribute_id = ?' => $object->getId(), 'store_id IN(?)' => $attributeStoreIds]; $this->getConnection()->delete($object->getBackendTable(), $delCondition); } } return $this; }
/** * Tests \Magento\Framework\Object->setOrigData() */ public function testOrigData() { $data = ['key1' => 'value1', 'key2' => 'value2']; $this->model->setData($data); $this->model->setOrigData(); $this->model->setData('key1', 'test'); $this->assertTrue($this->model->dataHasChangedFor('key1')); $this->assertEquals($data, $this->model->getOrigData()); $this->model->setOrigData('key1', 'test'); $this->assertEquals('test', $this->model->getOrigData('key1')); }
/** * @param \Magento\Store\Model\ResourceModel\Group $object * @param callable $proceed * @param AbstractModel $group * @return \Magento\Store\Model\ResourceModel\Group * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function aroundSave(\Magento\Store\Model\ResourceModel\Group $object, \Closure $proceed, AbstractModel $group) { $originGroup = $group; $result = $proceed($originGroup); if (!$group->isObjectNew() && ($group->dataHasChangedFor('website_id') || $group->dataHasChangedFor('root_category_id'))) { $this->storeManager->reinitStores(); foreach ($group->getStoreIds() as $storeId) { $this->urlPersist->deleteByData([UrlRewrite::STORE_ID => $storeId]); } $this->urlPersist->replace($this->generateCategoryUrls($group->getRootCategoryId(), $group->getStoreIds())); $this->urlPersist->replace($this->generateProductUrls($group->getWebsiteId(), $group->getOrigData('website_id'))); } return $result; }
protected function _beforeSave(\Magento\Framework\Model\AbstractModel $object) { $origData = $object->getOrigData(); if (empty($origData)) { $object->setData('create_date', $this->getHelper('Data')->getCurrentGmtDate()); } $object->setData('update_date', $this->getHelper('Data')->getCurrentGmtDate()); $result = parent::_beforeSave($object); // TODO test it on magento 2.0 // fix for Varien\Db\Adapter\Pdo\Mysql::prepareColumnValue // an empty string cannot be saved -> NULL is saved instead // for Magento version > 1.6.x.x foreach ($object->getData() as $key => $value) { $value === '' && $object->setData($key, new \Zend_Db_Expr("''")); } return $result; }
/** * Successful if $value is \Magento\Framework\Model\AbstractModel an all condition are fulfilled. * * If read-only properties are set than $value mustn't have changes in them. * * @param AbstractModel $value * @return bool * @throws \InvalidArgumentException when $value is not instanceof \Magento\Framework\DataObject * @api */ public function isValid($value) { $this->_clearMessages(); if (!$value instanceof AbstractModel) { throw new \InvalidArgumentException('Instance of \\Magento\\Framework\\Model\\AbstractModel is expected.'); } if ($this->_readOnlyProperties) { if (!$value->hasDataChanges()) { return true; } foreach ($this->_readOnlyProperties as $property) { if ($this->_hasChanges($value->getData($property), $value->getOrigData($property))) { $this->_messages[__CLASS__] = [(string) new \Magento\Framework\Phrase("Read-only property cannot be changed.")]; break; } } } return !count($this->_messages); }
/** * Check that model data fields that can be saved * has really changed comparing with origData * * @param \Magento\Framework\Model\AbstractModel $object * @return bool */ public function hasDataChanged($object) { if (!$object->getOrigData()) { return true; } $fields = $this->_getWriteAdapter()->describeTable($this->getMainTable()); foreach (array_keys($fields) as $field) { if ($object->getOrigData($field) != $object->getData($field)) { return true; } } return false; }
/** * Check is model empty or not * * @param \Magento\Framework\Model\AbstractModel $model */ protected function _assertEmpty($model) { $this->assertEquals([], $model->getData()); $this->assertEmpty($model->getOrigData()); $this->assertEquals([], $model->getCustomOptions()); // impossible to test $_optionInstance $this->assertEquals([], $model->getOptions()); $this->assertFalse($model->canAffectOptions()); }
/** * Prepare entity object data for save * * Result array structure: * array ( * 'newObject', 'entityRow', 'insert', 'update', 'delete' * ) * * @param \Magento\Framework\Model\AbstractModel $newObject * @return array * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ protected function _collectSaveData($newObject) { $newData = $newObject->getData(); $entityId = $newObject->getData($this->getEntityIdField()); // define result data $entityRow = []; $insert = []; $update = []; $delete = []; if (!empty($entityId)) { $origData = $newObject->getOrigData(); /** * get current data in db for this entity if original data is empty */ if (empty($origData)) { $origData = $this->_getOrigObject($newObject)->getOrigData(); } if (is_null($origData)) { $origData = []; } /** * drop attributes that are unknown in new data * not needed after introduction of partial entity loading */ foreach ($origData as $k => $v) { if (!array_key_exists($k, $newData)) { unset($origData[$k]); } } } else { $origData = []; } $staticFields = $this->getConnection()->describeTable($this->getEntityTable()); $staticFields = array_keys($staticFields); $attributeCodes = array_keys($this->_attributesByCode); foreach ($newData as $k => $v) { /** * Check if data key is presented in static fields or attribute codes */ if (!in_array($k, $staticFields) && !in_array($k, $attributeCodes)) { continue; } $attribute = $this->getAttribute($k); if (empty($attribute)) { continue; } if (!$attribute->isInSet($newObject->getAttributeSetId()) && !in_array($k, $staticFields)) { $this->_aggregateDeleteData($delete, $attribute, $newObject); continue; } $attrId = $attribute->getAttributeId(); /** * Only scalar values can be stored in generic tables */ if (!$attribute->getBackend()->isScalar()) { continue; } /** * if attribute is static add to entity row and continue */ if ($this->isAttributeStatic($k)) { $entityRow[$k] = $this->_prepareStaticValue($k, $v); continue; } /** * Check comparability for attribute value */ if ($this->_canUpdateAttribute($attribute, $v, $origData)) { if ($this->_isAttributeValueEmpty($attribute, $v)) { $this->_aggregateDeleteData($delete, $attribute, $newObject); } elseif (!is_numeric($v) && $v !== $origData[$k] || is_numeric($v) && $v != $origData[$k]) { $update[$attrId] = ['value_id' => $attribute->getBackend()->getEntityValueId($newObject), 'value' => is_array($v) ? array_shift($v) : $v]; } } elseif (!$this->_isAttributeValueEmpty($attribute, $v)) { $insert[$attrId] = is_array($v) ? array_shift($v) : $v; //@TODO: MAGETWO-44182 } } $result = compact('newObject', 'entityRow', 'insert', 'update', 'delete'); return $result; }
/** * @param \Magento\Sales\Model\Spi\InvoiceResourceInterface $subject * @param \Closure $proceed * * I include both the extended AbstractModel and implemented Interface here for the IDE's benefit * @param \Magento\Framework\Model\AbstractModel|\Magento\Sales\Api\Data\InvoiceInterface $entity * @return \Magento\Sales\Model\Spi\InvoiceResourceInterface * @throws \Magento\Framework\Exception\CouldNotSaveException */ public function aroundSave(InvoiceResourceInterface $subject, \Closure $proceed, AbstractModel $entity) { // Check to see if this is a newly created entity and store the determination for later evaluation after // the entity is saved via plugin closure. After the entity is saved it will not be listed as new any longer. $isObjectNew = $entity->isObjectNew(); // Save AvaTax extension attributes if ($this->avaTaxConfig->isModuleEnabled($entity->getStoreId())) { // check to see if any extension attributes exist and set them on the model for saving to the db $extensionAttributes = $entity->getExtensionAttributes(); if ($extensionAttributes && $extensionAttributes->getAvataxIsUnbalanced() !== null) { $entity->setData('avatax_is_unbalanced', $extensionAttributes->getAvataxIsUnbalanced()); } if ($extensionAttributes && $extensionAttributes->getBaseAvataxTaxAmount() !== null) { $entity->setData('base_avatax_tax_amount', $extensionAttributes->getBaseAvataxTaxAmount()); } // Updating a field to trigger a change to the record when avatax_is_unbalanced and base_avatax_tax_amount // are both false or 0 which evaluate the same as null in the isModified check if ($extensionAttributes && ($extensionAttributes->getAvataxIsUnbalanced() !== null && ($entity->getOrigData('avatax_is_unbalanced') === null || $extensionAttributes->getAvataxIsUnbalanced() != $entity->getOrigData('avatax_is_unbalanced')) || $extensionAttributes->getBaseAvataxTaxAmount() !== null && ($entity->getOrigData('base_avatax_tax_amount') === null || $extensionAttributes->getBaseAvataxTaxAmount() != $entity->getOrigData('base_avatax_tax_amount')))) { $entity->setUpdatedAt($this->dateTime->gmtDate()); } } /** @var \Magento\Sales\Model\Spi\InvoiceResourceInterface $resultEntity */ $resultEntity = $proceed($entity); /** @var \Magento\Sales\Model\Order $order */ $order = $entity->getOrder(); $isVirtual = $order->getIsVirtual(); $address = $isVirtual ? $entity->getBillingAddress() : $entity->getShippingAddress(); $storeId = $entity->getStoreId(); // Queue the entity to be sent to AvaTax if ($this->avaTaxConfig->isModuleEnabled($entity->getStoreId()) && $this->avaTaxConfig->getTaxMode($entity->getStoreId()) == Config::TAX_MODE_ESTIMATE_AND_SUBMIT && $this->avaTaxConfig->isAddressTaxable($address, $storeId)) { // Add this entity to the avatax processing queue if this is a new entity if ($isObjectNew) { /** @var Queue $queue */ $queue = $this->queueFactory->create(); $queue->build($entity->getStoreId(), Queue::ENTITY_TYPE_CODE_INVOICE, $entity->getEntityId(), $entity->getIncrementId(), Queue::QUEUE_STATUS_PENDING); $queue->save(); $this->avaTaxLogger->debug(__('Added entity to the queue'), ['queue_id' => $queue->getId(), 'entity_type_code' => Queue::ENTITY_TYPE_CODE_INVOICE, 'entity_id' => $entity->getEntityId()]); } } return $resultEntity; }
/** * @param \Magento\Store\Model\ResourceModel\Store $object * @param callable $proceed * @param AbstractModel $store * @return \Magento\Store\Model\ResourceModel\Store * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function aroundSave(\Magento\Store\Model\ResourceModel\Store $object, \Closure $proceed, AbstractModel $store) { $originStore = $store; $result = $proceed($originStore); if ($store->isObjectNew() || $store->dataHasChangedFor('group_id')) { if (!$store->isObjectNew()) { $this->urlPersist->deleteByData([UrlRewrite::STORE_ID => $store->getId()]); } $this->urlPersist->replace($this->generateCategoryUrls($store->getRootCategoryId(), $store->getId())); $this->urlPersist->replace($this->generateProductUrls($store->getWebsiteId(), $store->getOrigData('website_id'), $store->getId())); } return $result; }