Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
AbstractResource.php
Go to the documentation of this file.
1 <?php
8 
10 
19 abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity
20 {
26  protected $_storeManager;
27 
33  protected $_modelFactory;
34 
41  public function __construct(
42  \Magento\Eav\Model\Entity\Context $context,
44  \Magento\Catalog\Model\Factory $modelFactory,
45  $data = []
46  ) {
47  $this->_storeManager = $storeManager;
48  $this->_modelFactory = $modelFactory;
49  parent::__construct($context, $data);
50  }
51 
57  protected function _getDefaultAttributeModel()
58  {
59  return \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class;
60  }
61 
67  public function getDefaultStoreId()
68  {
69  return \Magento\Store\Model\Store::DEFAULT_STORE_ID;
70  }
71 
79  protected function _isApplicableAttribute($object, $attribute)
80  {
81  $applyTo = $attribute->getApplyTo() ?: [];
82  return (count($applyTo) == 0 || in_array($object->getTypeId(), $applyTo))
83  && $attribute->isInSet($object->getAttributeSetId());
84  }
85 
96  protected function _isCallableAttributeInstance($instance, $method, $args)
97  {
98  if ($instance instanceof \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
99  && ($method == 'beforeSave' || $method == 'afterSave')
100  ) {
101  $attributeCode = $instance->getAttribute()->getAttributeCode();
102  if (isset($args[0])
103  && $args[0] instanceof \Magento\Framework\DataObject
104  && $args[0]->getData($attributeCode) === false
105  ) {
106  return false;
107  }
108  }
109 
110  return parent::_isCallableAttributeInstance($instance, $method, $args);
111  }
112 
121  protected function _getLoadAttributesSelect($object, $table)
122  {
128  if ($this->_storeManager->hasSingleStore()) {
129  $storeId = (int) $this->_storeManager->getStore(true)->getId();
130  } else {
131  $storeId = (int) $object->getStoreId();
132  }
133 
134  $setId = $object->getAttributeSetId();
135  $storeIds = [$this->getDefaultStoreId()];
136  if ($storeId != $this->getDefaultStoreId()) {
137  $storeIds[] = $storeId;
138  }
139 
140  $select = $this->getConnection()
141  ->select()
142  ->from(['attr_table' => $table], [])
143  ->where("attr_table.{$this->getLinkField()} = ?", $object->getData($this->getLinkField()))
144  ->where('attr_table.store_id IN (?)', $storeIds);
145 
146  if ($setId) {
147  $select->join(
148  ['set_table' => $this->getTable('eav_entity_attribute')],
149  $this->getConnection()->quoteInto(
150  'attr_table.attribute_id = set_table.attribute_id' . ' AND set_table.attribute_set_id = ?',
151  $setId
152  ),
153  []
154  );
155  }
156  return $select;
157  }
158 
165  protected function _prepareLoadSelect(array $selects)
166  {
167  $select = parent::_prepareLoadSelect($selects);
168  $select->order('store_id');
169  return $select;
170  }
171 
180  protected function _saveAttributeValue($object, $attribute, $value)
181  {
182  $connection = $this->getConnection();
183  $hasSingleStore = $this->_storeManager->hasSingleStore();
184  $storeId = $hasSingleStore
185  ? $this->getDefaultStoreId()
186  : (int) $this->_storeManager->getStore($object->getStoreId())->getId();
187  $table = $attribute->getBackend()->getTable();
188 
194  $entityIdField = $this->getLinkField();
195  $conditions = [
196  'attribute_id = ?' => $attribute->getAttributeId(),
197  "{$entityIdField} = ?" => $object->getData($entityIdField),
198  'store_id <> ?' => $storeId
199  ];
200  if ($hasSingleStore
201  && !$object->isObjectNew()
202  && $this->isAttributePresentForNonDefaultStore($attribute, $conditions)
203  ) {
204  $connection->delete(
205  $table,
206  $conditions
207  );
208  }
209 
210  $data = new \Magento\Framework\DataObject(
211  [
212  'attribute_id' => $attribute->getAttributeId(),
213  'store_id' => $storeId,
214  $entityIdField => $object->getData($entityIdField),
215  'value' => $this->_prepareValueForSave($value, $attribute),
216  ]
217  );
218  $bind = $this->_prepareDataForTable($data, $table);
219 
220  if ($attribute->isScopeStore()) {
224  $this->_attributeValuesToSave[$table][] = $bind;
225  } elseif ($attribute->isScopeWebsite() && $storeId != $this->getDefaultStoreId()) {
229  $storeIds = $this->_storeManager->getStore($storeId)->getWebsite()->getStoreIds(true);
230  foreach ($storeIds as $storeId) {
231  $bind['store_id'] = (int) $storeId;
232  $this->_attributeValuesToSave[$table][] = $bind;
233  }
234  } else {
238  $bind['store_id'] = $this->getDefaultStoreId();
239  $this->_attributeValuesToSave[$table][] = $bind;
240  }
241 
242  return $this;
243  }
244 
254  private function isAttributePresentForNonDefaultStore($attribute, $conditions)
255  {
256  $connection = $this->getConnection();
257  $select = $connection->select()->from($attribute->getBackend()->getTable());
258  foreach ($conditions as $condition => $conditionValue) {
259  $select->where($condition, $conditionValue);
260  }
261  $select->limit(1);
262 
263  return !empty($connection->fetchRow($select));
264  }
265 
274  protected function _insertAttribute($object, $attribute, $value)
275  {
279  $storeId = (int) $this->_storeManager->getStore($object->getStoreId())->getId();
280  if ($this->getDefaultStoreId() != $storeId) {
281  if ($attribute->getIsRequired() || $attribute->getIsRequiredInAdminStore()) {
282  $table = $attribute->getBackend()->getTable();
283 
284  $select = $this->getConnection()->select()
285  ->from($table)
286  ->where('attribute_id = ?', $attribute->getAttributeId())
287  ->where('store_id = ?', $this->getDefaultStoreId())
288  ->where($this->getLinkField() . ' = ?', $object->getData($this->getLinkField()));
289  $row = $this->getConnection()->fetchOne($select);
290 
291  if (!$row) {
292  $data = new \Magento\Framework\DataObject(
293  [
294  'attribute_id' => $attribute->getAttributeId(),
295  'store_id' => $this->getDefaultStoreId(),
296  $this->getLinkField() => $object->getData($this->getLinkField()),
297  'value' => $this->_prepareValueForSave($value, $attribute),
298  ]
299  );
300  $bind = $this->_prepareDataForTable($data, $table);
301  $this->getConnection()->insertOnDuplicate($table, $bind, ['value']);
302  }
303  }
304  }
305 
306  return $this->_saveAttributeValue($object, $attribute, $value);
307  }
308 
319  protected function _updateAttribute($object, $attribute, $valueId, $value)
320  {
321  return $this->_saveAttributeValue($object, $attribute, $value);
322  }
323 
333  protected function _updateAttributeForStore($object, $attribute, $value, $storeId)
334  {
335  $connection = $this->getConnection();
336  $table = $attribute->getBackend()->getTable();
337  $entityIdField = $this->getLinkField();
338  $select = $connection->select()
339  ->from($table, 'value_id')
340  ->where("$entityIdField = :entity_field_id")
341  ->where('store_id = :store_id')
342  ->where('attribute_id = :attribute_id');
343  $bind = [
344  'entity_field_id' => $object->getId(),
345  'store_id' => $storeId,
346  'attribute_id' => $attribute->getId(),
347  ];
348  $valueId = $connection->fetchOne($select, $bind);
352  if ($valueId) {
353  $bind = ['value' => $this->_prepareValueForSave($value, $attribute)];
354  $where = ['value_id = ?' => (int) $valueId];
355 
356  $connection->update($table, $bind, $where);
357  } else {
358  $bind = [
359  $entityIdField => (int) $object->getId(),
360  'attribute_id' => (int) $attribute->getId(),
361  'value' => $this->_prepareValueForSave($value, $attribute),
362  'store_id' => (int) $storeId,
363  ];
364 
365  $connection->insert($table, $bind);
366  }
367 
368  return $this;
369  }
370 
379  protected function _deleteAttributes($object, $table, $info)
380  {
381  $connection = $this->getConnection();
382  $entityIdField = $this->getLinkField();
383  $globalValues = [];
384  $websiteAttributes = [];
385  $storeAttributes = [];
386 
390  foreach ($info as $itemData) {
391  $attribute = $this->getAttribute($itemData['attribute_id']);
392  if ($attribute->isScopeStore()) {
393  $storeAttributes[] = (int) $itemData['attribute_id'];
394  } elseif ($attribute->isScopeWebsite()) {
395  $websiteAttributes[] = (int) $itemData['attribute_id'];
396  } elseif ($itemData['value_id'] !== null) {
397  $globalValues[] = (int) $itemData['value_id'];
398  }
399  }
400 
404  if (!empty($globalValues)) {
405  $connection->delete($table, ['value_id IN (?)' => $globalValues]);
406  }
407 
408  $condition = [
409  $entityIdField . ' = ?' => $object->getId(),
410  ];
411 
415  if (!empty($websiteAttributes)) {
416  $storeIds = $object->getWebsiteStoreIds();
417  if (!empty($storeIds)) {
418  $delCondition = $condition;
419  $delCondition['attribute_id IN(?)'] = $websiteAttributes;
420  $delCondition['store_id IN(?)'] = $storeIds;
421 
422  $connection->delete($table, $delCondition);
423  }
424  }
425 
429  if (!empty($storeAttributes)) {
430  $delCondition = $condition;
431  $delCondition['attribute_id IN(?)'] = $storeAttributes;
432  $delCondition['store_id = ?'] = (int) $object->getStoreId();
433 
434  $connection->delete($table, $delCondition);
435  }
436 
437  return $this;
438  }
439 
446  protected function _getOrigObject($object)
447  {
448  //TODO:
449  $className = get_class($object);
450  $origObject = $this->_modelFactory->create($className);
451  $origObject->setData([]);
452  $origObject->setStoreId($object->getStoreId());
453  $this->load($origObject, $object->getData($this->getEntityIdField()));
454 
455  return $origObject;
456  }
457 
468  protected function _canUpdateAttribute(AbstractAttribute $attribute, $value, array &$origData)
469  {
470  $result = parent::_canUpdateAttribute($attribute, $value, $origData);
471  if ($result
472  && ($attribute->isScopeStore() || $attribute->isScopeWebsite())
473  && !$this->_isAttributeValueEmpty($attribute, $value)
474  && $value == $origData[$attribute->getAttributeCode()]
475  && isset($origData['store_id'])
476  && $origData['store_id'] != $this->getDefaultStoreId()
477  ) {
478  return false;
479  }
480 
481  return $result;
482  }
483 
495  public function getAttributeRawValue($entityId, $attribute, $store)
496  {
497  if (!$entityId || empty($attribute)) {
498  return false;
499  }
500  if (!is_array($attribute)) {
502  }
503 
504  $attributesData = [];
505  $staticAttributes = [];
506  $typedAttributes = [];
507  $staticTable = null;
508  $connection = $this->getConnection();
509 
510  foreach ($attribute as $item) {
511  /* @var $attribute \Magento\Catalog\Model\Entity\Attribute */
512  $item = $this->getAttribute($item);
513  if (!$item) {
514  continue;
515  }
516  $attributeCode = $item->getAttributeCode();
517  $attrTable = $item->getBackend()->getTable();
518  $isStatic = $item->getBackend()->isStatic();
519 
520  if ($isStatic) {
521  $staticAttributes[] = $attributeCode;
522  $staticTable = $attrTable;
523  } else {
527  $typedAttributes[$attrTable][$item->getId()] = $attributeCode;
528  }
529  }
530 
534  if ($staticAttributes) {
535  $select = $connection->select()->from(
536  $staticTable,
537  $staticAttributes
538  )->join(
539  ['e' => $this->getTable($this->getEntityTable())],
540  'e.' . $this->getLinkField() . ' = ' . $staticTable . '.' . $this->getLinkField()
541  )->where(
542  'e.entity_id = :entity_id'
543  );
544  $attributesData = $connection->fetchRow($select, ['entity_id' => $entityId]);
545  }
546 
550  if ($store instanceof \Magento\Store\Model\Store) {
551  $store = $store->getId();
552  }
553 
554  $store = (int) $store;
555  if ($typedAttributes) {
556  foreach ($typedAttributes as $table => $_attributes) {
557  $select = $connection->select()
558  ->from(['default_value' => $table], ['attribute_id'])
559  ->join(
560  ['e' => $this->getTable($this->getEntityTable())],
561  'e.' . $this->getLinkField() . ' = ' . 'default_value.' . $this->getLinkField(),
562  ''
563  )->where('default_value.attribute_id IN (?)', array_keys($_attributes))
564  ->where("e.entity_id = :entity_id")
565  ->where('default_value.store_id = ?', 0);
566 
567  $bind = ['entity_id' => $entityId];
568 
569  if ($store != $this->getDefaultStoreId()) {
570  $valueExpr = $connection->getCheckSql(
571  'store_value.value IS NULL',
572  'default_value.value',
573  'store_value.value'
574  );
575  $joinCondition = [
576  $connection->quoteInto('store_value.attribute_id IN (?)', array_keys($_attributes)),
577  "store_value.{$this->getLinkField()} = e.{$this->getLinkField()}",
578  'store_value.store_id = :store_id',
579  ];
580 
581  $select->joinLeft(
582  ['store_value' => $table],
583  implode(' AND ', $joinCondition),
584  ['attr_value' => $valueExpr]
585  );
586 
587  $bind['store_id'] = $store;
588  } else {
589  $select->columns(['attr_value' => 'value'], 'default_value');
590  }
591 
592  $result = $connection->fetchPairs($select, $bind);
593  foreach ($result as $attrId => $value) {
594  $attrCode = $typedAttributes[$table][$attrId];
595  $attributesData[$attrCode] = $value;
596  }
597  }
598  }
599 
600  if (is_array($attributesData) && sizeof($attributesData) == 1) {
601  $attributesData = array_shift($attributesData);
602  }
603 
604  return $attributesData === false ? false : $attributesData;
605  }
606 }
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
return false
Definition: gallery.phtml:36
load($object, $entityId, $attributes=[])
$storeManager
_updateAttribute($object, $attribute, $valueId, $value)
$attributesData
$value
Definition: gender.phtml:16
_prepareValueForSave($value, AbstractAttribute $attribute)
$attributeCode
Definition: extend.phtml:12
_isAttributeValueEmpty(AbstractAttribute $attribute, $value)
$method
Definition: info.phtml:13
__construct(\Magento\Eav\Model\Entity\Context $context, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Catalog\Model\Factory $modelFactory, $data=[])
foreach( $_productCollection as $_product)() ?>" class $info
Definition: listing.phtml:52
$connection
Definition: bulk.php:13
$table
Definition: trigger.php:14
_canUpdateAttribute(AbstractAttribute $attribute, $value, array &$origData)
$_attributes
_updateAttributeForStore($object, $attribute, $value, $storeId)
if($currentSelectedMethod==$_code) $className
Definition: form.phtml:31