Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
EavSetup.php
Go to the documentation of this file.
1 <?php
7 namespace Magento\Eav\Setup;
8 
11 use Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\CollectionFactory;
17 
25 class EavSetup
26 {
32  private $cache;
33 
39  private $attrGroupCollectionFactory;
40 
46  private $attributeMapper;
47 
53  private $setup;
54 
60  private $_generalGroupName = 'General';
61 
67  private $defaultGroupIdAssociations = ['general' => 1];
68 
74  private $_defaultGroupName = 'Default';
75 
81  private $_defaultAttributeSetName = 'Default';
82 
91  public function __construct(
93  Context $context,
94  CacheInterface $cache,
95  CollectionFactory $attrGroupCollectionFactory
96  ) {
97  $this->cache = $cache;
98  $this->attrGroupCollectionFactory = $attrGroupCollectionFactory;
99  $this->attributeMapper = $context->getAttributeMapper();
100  $this->setup = $setup;
101  }
102 
108  public function getSetup()
109  {
110  return $this->setup;
111  }
112 
119  {
120  return $this->attrGroupCollectionFactory->create();
121  }
122 
128  public function cleanCache()
129  {
130  $this->cache->clean([\Magento\Eav\Model\Cache\Type::CACHE_TAG]);
131  return $this;
132  }
133 
139  public function installDefaultGroupIds()
140  {
141  $setIds = $this->getAllAttributeSetIds();
142  foreach ($this->defaultGroupIdAssociations as $defaultGroupCode => $defaultGroupId) {
143  foreach ($setIds as $set) {
144  $groupId = $this->setup->getTableRow(
145  'eav_attribute_group',
146  'attribute_group_code',
147  $defaultGroupCode,
148  'attribute_group_id',
149  'attribute_set_id',
150  $set
151  );
152  if (!$groupId) {
153  $groupId = $this->setup->getTableRow(
154  'eav_attribute_group',
155  'attribute_set_id',
156  $set,
157  'attribute_group_id'
158  );
159  }
160  $this->setup->updateTableRow(
161  'eav_attribute_group',
162  'attribute_group_id',
163  $groupId,
164  'default_id',
166  );
167  }
168  }
169 
170  return $this;
171  }
172 
173  /******************* ENTITY TYPES *****************/
174 
184  public function addEntityType($code, array $params)
185  {
186  $data = [
187  'entity_type_code' => $code,
188  'entity_model' => $params['entity_model'],
189  'attribute_model' => $this->_getValue($params, 'attribute_model'),
190  'entity_table' => $this->_getValue($params, 'table', 'eav_entity'),
191  'value_table_prefix' => $this->_getValue($params, 'table_prefix'),
192  'entity_id_field' => $this->_getValue($params, 'id_field'),
193  'increment_model' => $this->_getValue($params, 'increment_model'),
194  'increment_per_store' => $this->_getValue($params, 'increment_per_store', 0),
195  'increment_pad_length' => $this->_getValue($params, 'increment_pad_length', 8),
196  'increment_pad_char' => $this->_getValue($params, 'increment_pad_char', 0),
197  'additional_attribute_table' => $this->_getValue($params, 'additional_attribute_table'),
198  'entity_attribute_collection' => $this->_getValue($params, 'entity_attribute_collection'),
199  ];
200  if (isset($params['entity_type_id'])) {
201  $data['entity_type_id'] = $params['entity_type_id'];
202  }
203 
204  if ($this->getEntityType($code, 'entity_type_id')) {
205  $this->updateEntityType($code, $data);
206  } else {
207  $this->setup->getConnection()->insert(
208  $this->setup->getTable('eav_entity_type'),
209  $data
210  );
211  }
212 
213  if (isset($params['entity_type_id'])) {
214  $this->addAttributeSet($code, $this->_defaultAttributeSetName, null, $params['entity_type_id']);
215  } else {
216  $this->addAttributeSet($code, $this->_defaultAttributeSetName);
217  }
218  $this->addAttributeGroup($code, $this->_defaultGroupName, $this->_generalGroupName);
219 
220  return $this;
221  }
222 
231  public function updateEntityType($code, $field, $value = null)
232  {
233  $this->setup->updateTableRow(
234  'eav_entity_type',
235  'entity_type_id',
236  $this->getEntityTypeId($code),
237  $field,
238  $value
239  );
240  return $this;
241  }
242 
250  public function getEntityType($id, $field = null)
251  {
252  return $this->setup->getTableRow(
253  'eav_entity_type',
254  is_numeric($id) ? 'entity_type_id' : 'entity_type_code',
255  $id,
256  $field
257  );
258  }
259 
268  {
269  if (!is_numeric($entityTypeId)) {
270  $entityTypeId = $this->getEntityType($entityTypeId, 'entity_type_id');
271  }
272  if (!is_numeric($entityTypeId)) {
273  throw new LocalizedException(__('The entity ID is incorrect. Verify the ID and try again.'));
274  }
275 
276  return $entityTypeId;
277  }
278 
285  public function removeEntityType($id)
286  {
287  if (is_numeric($id)) {
288  $this->setup->deleteTableRow('eav_entity_type', 'entity_type_id', $id);
289  } else {
290  $this->setup->deleteTableRow('eav_entity_type', 'entity_type_code', (string)$id);
291  }
292 
293  return $this;
294  }
295 
296  /******************* ATTRIBUTE SETS *****************/
297 
305  public function getAttributeSetSortOrder($entityTypeId, $sortOrder = null)
306  {
307  if (!is_numeric($sortOrder)) {
308  $bind = ['entity_type_id' => $this->getEntityTypeId($entityTypeId)];
309  $select = $this->setup->getConnection()->select()->from(
310  $this->setup->getTable('eav_attribute_set'),
311  'MAX(sort_order)'
312  )->where(
313  'entity_type_id = :entity_type_id'
314  );
315 
316  $sortOrder = $this->setup->getConnection()->fetchOne($select, $bind) + 1;
317  }
318 
319  return $sortOrder;
320  }
321 
331  public function addAttributeSet($entityTypeId, $name, $sortOrder = null, $setId = null)
332  {
333  $data = [
334  'entity_type_id' => $this->getEntityTypeId($entityTypeId),
335  'attribute_set_name' => $name,
336  'sort_order' => $this->getAttributeSetSortOrder($entityTypeId, $sortOrder),
337  ];
338 
339  if ($setId !== null) {
340  $data['attribute_set_id'] = $setId;
341  }
342 
343  $setId = $this->getAttributeSet($entityTypeId, $name, 'attribute_set_id');
344  if ($setId) {
345  $this->updateAttributeSet($entityTypeId, $setId, $data);
346  } else {
347  $this->setup->getConnection()->insert(
348  $this->setup->getTable('eav_attribute_set'),
349  $data
350  );
351 
352  $this->addAttributeGroup($entityTypeId, $name, $this->_generalGroupName);
353  }
354 
355  return $this;
356  }
357 
367  public function updateAttributeSet($entityTypeId, $id, $field, $value = null)
368  {
369  $this->setup->updateTableRow(
370  'eav_attribute_set',
371  'attribute_set_id',
373  $field,
374  $value,
375  'entity_type_id',
377  );
378  return $this;
379  }
380 
389  public function getAttributeSet($entityTypeId, $id, $field = null)
390  {
391  return $this->setup->getTableRow(
392  'eav_attribute_set',
393  is_numeric($id) ? 'attribute_set_id' : 'attribute_set_name',
394  $id,
395  $field,
396  'entity_type_id',
398  );
399  }
400 
409  public function getAttributeSetId($entityTypeId, $setId)
410  {
411  if (!is_numeric($setId)) {
412  $setId = $this->getAttributeSet($entityTypeId, $setId, 'attribute_set_id');
413  }
414  if (!is_numeric($setId)) {
415  throw new LocalizedException(__('The attribute set ID is incorrect. Verify the ID and try again.'));
416  }
417 
418  return $setId;
419  }
420 
429  {
430  $this->setup->deleteTableRow(
431  'eav_attribute_set',
432  'attribute_set_id',
434  );
435  return $this;
436  }
437 
446  {
449  $this->updateEntityType($entityTypeId, 'default_attribute_set_id', $setId);
450  return $this;
451  }
452 
459  public function getAllAttributeSetIds($entityTypeId = null)
460  {
461  $select = $this->setup->getConnection()->select()
462  ->from($this->setup->getTable('eav_attribute_set'), 'attribute_set_id');
463 
464  $bind = [];
465  if ($entityTypeId !== null) {
466  $bind['entity_type_id'] = $this->getEntityTypeId($entityTypeId);
467  $select->where('entity_type_id = :entity_type_id');
468  }
469 
470  return $this->setup->getConnection()->fetchCol($select, $bind);
471  }
472 
480  {
481  $bind = ['entity_type' => $entityType];
482  if (is_numeric($entityType)) {
483  $where = 'entity_type_id = :entity_type';
484  } else {
485  $where = 'entity_type_code = :entity_type';
486  }
487  $select = $this->setup->getConnection()->select()->from(
488  $this->setup->getTable('eav_entity_type'),
489  'default_attribute_set_id'
490  )->where(
491  $where
492  );
493 
494  return $this->setup->getConnection()->fetchOne($select, $bind);
495  }
496 
497  /******************* ATTRIBUTE GROUPS *****************/
498 
507  public function getAttributeGroupSortOrder($entityTypeId, $setId, $sortOrder = null)
508  {
509  if (!is_numeric($sortOrder)) {
510  $bind = ['attribute_set_id' => $this->getAttributeSetId($entityTypeId, $setId)];
511  $select = $this->setup->getConnection()->select()->from(
512  $this->setup->getTable('eav_attribute_group'),
513  'MAX(sort_order)'
514  )->where(
515  'attribute_set_id = :attribute_set_id'
516  );
517 
518  $sortOrder = $this->setup->getConnection()->fetchOne($select, $bind) + 1;
519  }
520 
521  return $sortOrder;
522  }
523 
533  public function addAttributeGroup($entityTypeId, $setId, $name, $sortOrder = null)
534  {
535  $setId = $this->getAttributeSetId($entityTypeId, $setId);
536  $data = ['attribute_set_id' => $setId, 'attribute_group_name' => $name];
537  $attributeGroupCode = $this->convertToAttributeGroupCode($name);
538 
539  if (isset($this->defaultGroupIdAssociations[$attributeGroupCode])) {
540  $data['default_id'] = $this->defaultGroupIdAssociations[$attributeGroupCode];
541  }
542 
543  if ($sortOrder !== null) {
544  $data['sort_order'] = $sortOrder;
545  }
546 
547  $groupId = $this->getAttributeGroup($entityTypeId, $setId, $attributeGroupCode, 'attribute_group_id');
548  if ($groupId) {
550  } else {
551  if ($sortOrder === null) {
552  $data['sort_order'] = $this->getAttributeGroupSortOrder($entityTypeId, $setId, $sortOrder);
553  }
554  if (empty($data['attribute_group_code'])) {
555  if (empty($attributeGroupCode)) {
556  // in the following code md5 is not used for security purposes
557  $attributeGroupCode = md5($name);
558  }
559  $data['attribute_group_code'] = $attributeGroupCode;
560  }
561  $this->setup->getConnection()->insert(
562  $this->setup->getTable('eav_attribute_group'),
563  $data
564  );
565  }
566 
567  return $this;
568  }
569 
575  public function convertToAttributeGroupCode($groupName)
576  {
577  return trim(preg_replace('/[^a-z0-9]+/', '-', strtolower($groupName)), '-');
578  }
579 
590  public function updateAttributeGroup($entityTypeId, $setId, $id, $field, $value = null)
591  {
592  $this->setup->updateTableRow(
593  'eav_attribute_group',
594  'attribute_group_id',
595  $this->getAttributeGroupId($entityTypeId, $setId, $id),
596  $field,
597  $value,
598  'attribute_set_id',
599  $this->getAttributeSetId($entityTypeId, $setId)
600  );
601 
602  return $this;
603  }
604 
614  public function getAttributeGroup($entityTypeId, $setId, $id, $field = null)
615  {
616  if (is_numeric($id)) {
617  $searchField = 'attribute_group_id';
618  } else {
620  if (isset($this->defaultGroupIdAssociations[$id])) {
621  $searchField = 'default_id';
622  $id = $this->defaultGroupIdAssociations[$id];
623  } else {
624  $searchField = 'attribute_group_code';
625  }
626  }
627 
628  return $this->setup->getTableRow(
629  'eav_attribute_group',
630  $searchField,
631  $id,
632  $field,
633  'attribute_set_id',
634  $this->getAttributeSetId($entityTypeId, $setId)
635  );
636  }
637 
648  public function getAttributeGroupByCode($entityTypeId, $setId, $code, $field = null)
649  {
650  return $this->setup->getTableRow(
651  'eav_attribute_group',
652  'attribute_group_code',
653  $code,
654  $field,
655  'attribute_set_id',
656  $this->getAttributeSetId($entityTypeId, $setId)
657  );
658  }
659 
669  public function getAttributeGroupId($entityTypeId, $setId, $groupId)
670  {
671  if (!is_numeric($groupId)) {
672  $groupId = $this->getAttributeGroup($entityTypeId, $setId, $groupId, 'attribute_group_id');
673  }
674 
675  if (!is_numeric($groupId)) {
677  }
678 
679  if (!is_numeric($groupId)) {
680  throw new LocalizedException(__('The attribute group ID is incorrect. Verify the ID and try again.'));
681  }
682  return $groupId;
683  }
684 
693  public function removeAttributeGroup($entityTypeId, $setId, $id)
694  {
695  $this->setup->deleteTableRow(
696  'eav_attribute_group',
697  'attribute_group_id',
698  $this->getAttributeGroupId($entityTypeId, $setId, $id)
699  );
700  return $this;
701  }
702 
711  {
713  if (!is_numeric($attributeSetId)) {
715  }
716  $bind = ['attribute_set_id' => $attributeSetId];
717  $select = $this->setup->getConnection()->select()->from(
718  $this->setup->getTable('eav_attribute_group'),
719  'attribute_group_id'
720  )->where(
721  'attribute_set_id = :attribute_set_id'
722  )->order(
723  ['default_id ' . \Magento\Framework\DB\Select::SQL_DESC, 'sort_order']
724  )->limit(
725  1
726  );
727 
728  return $this->setup->getConnection()->fetchOne($select, $bind);
729  }
730 
741  {
742  $select = $this->setup->getConnection()->select()->from(
743  $this->setup->getTable('eav_entity_attribute'),
744  ['count' => 'COUNT(*)']
745  )->where(
746  'attribute_group_id = ?',
748  )->where(
749  'entity_type_id = ?',
751  )->where(
752  'attribute_set_id = ?',
753  $setId
754  );
755 
756  return $this->setup->getConnection()->fetchOne($select);
757  }
758 
759  /******************* ATTRIBUTES *****************/
760 
769  private function _getValue($array, $key, $default = null)
770  {
771  if (isset($array[$key]) && is_bool($array[$key])) {
772  $array[$key] = (int)$array[$key];
773  }
774  return isset($array[$key]) ? $array[$key] : $default;
775  }
776 
784  private function _validateAttributeData($data)
785  {
786  $minLength = \Magento\Eav\Model\Entity\Attribute::ATTRIBUTE_CODE_MIN_LENGTH;
787  $maxLength = \Magento\Eav\Model\Entity\Attribute::ATTRIBUTE_CODE_MAX_LENGTH;
788  $attributeCode = isset($data['attribute_code']) ? $data['attribute_code'] : '';
789 
790  $isAllowedLength = \Zend_Validate::is(
791  trim($attributeCode),
792  'StringLength',
793  ['min' => $minLength, 'max' => $maxLength]
794  );
795 
796  if (!$isAllowedLength) {
797  $errorMessage = __(
798  'An attribute code must not be less than %1 and more than %2 characters.',
799  $minLength,
800  $maxLength
801  );
802 
803  throw new LocalizedException($errorMessage);
804  }
805 
806  return true;
807  }
808 
819  public function addAttribute($entityTypeId, $code, array $attr)
820  {
822 
823  $data = array_replace(
824  ['entity_type_id' => $entityTypeId, 'attribute_code' => $code],
825  $this->attributeMapper->map($attr, $entityTypeId)
826  );
827 
828  $this->_validateAttributeData($data);
829 
830  $sortOrder = isset($attr['sort_order']) ? $attr['sort_order'] : null;
831  $attributeId = $this->getAttribute($entityTypeId, $code, 'attribute_id');
832  if ($attributeId) {
833  $this->updateAttribute($entityTypeId, $attributeId, $data, null, $sortOrder);
834  } else {
835  $this->_insertAttribute($data);
836  }
837 
838  if (!empty($attr['group']) || empty($attr['user_defined'])) {
839  $select = $this->setup->getConnection()->select()->from(
840  $this->setup->getTable('eav_attribute_set')
841  )->where(
842  'entity_type_id = :entity_type_id'
843  );
844  $sets = $this->setup->getConnection()->fetchAll($select, ['entity_type_id' => $entityTypeId]);
845  foreach ($sets as $set) {
846  if (!empty($attr['group'])) {
847  $this->addAttributeGroup($entityTypeId, $set['attribute_set_id'], $attr['group']);
848  $this->addAttributeToSet(
850  $set['attribute_set_id'],
851  $attr['group'],
852  $code,
853  $sortOrder
854  );
855  } else {
856  $this->addAttributeToSet(
858  $set['attribute_set_id'],
859  $this->_generalGroupName,
860  $code,
861  $sortOrder
862  );
863  }
864  }
865  }
866 
867  if (isset($attr['option']) && is_array($attr['option'])) {
868  $option = $attr['option'];
869  $option['attribute_id'] = $this->getAttributeId($entityTypeId, $code);
870  $this->addAttributeOption($option);
871  }
872 
873  return $this;
874  }
875 
884  public function addAttributeOption($option)
885  {
886  $optionTable = $this->setup->getTable('eav_attribute_option');
887  $optionValueTable = $this->setup->getTable('eav_attribute_option_value');
888 
889  if (isset($option['value'])) {
890  foreach ($option['value'] as $optionId => $values) {
891  $intOptionId = (int)$optionId;
892  if (!empty($option['delete'][$optionId])) {
893  if ($intOptionId) {
894  $condition = ['option_id =?' => $intOptionId];
895  $this->setup->getConnection()->delete($optionTable, $condition);
896  }
897  continue;
898  }
899 
900  if (!$intOptionId) {
901  $data = [
902  'attribute_id' => $option['attribute_id'],
903  'sort_order' => isset($option['order'][$optionId]) ? $option['order'][$optionId] : 0,
904  ];
905  $this->setup->getConnection()->insert($optionTable, $data);
906  $intOptionId = $this->setup->getConnection()->lastInsertId($optionTable);
907  } else {
908  $data = [
909  'sort_order' => isset($option['order'][$optionId]) ? $option['order'][$optionId] : 0,
910  ];
911  $this->setup->getConnection()->update(
912  $optionTable,
913  $data,
914  ['option_id=?' => $intOptionId]
915  );
916  }
917 
918  // Default value
919  if (!isset($values[0])) {
920  throw new \Magento\Framework\Exception\LocalizedException(
921  __("The default option isn't defined. Set the option and try again.")
922  );
923  }
924  $condition = ['option_id =?' => $intOptionId];
925  $this->setup->getConnection()->delete($optionValueTable, $condition);
926  foreach ($values as $storeId => $value) {
927  $data = ['option_id' => $intOptionId, 'store_id' => $storeId, 'value' => $value];
928  $this->setup->getConnection()->insert($optionValueTable, $data);
929  }
930  }
931  } elseif (isset($option['values'])) {
932  foreach ($option['values'] as $sortOrder => $label) {
933  // add option
934  $data = ['attribute_id' => $option['attribute_id'], 'sort_order' => $sortOrder];
935  $this->setup->getConnection()->insert($optionTable, $data);
936  $intOptionId = $this->setup->getConnection()->lastInsertId($optionTable);
937 
938  $data = ['option_id' => $intOptionId, 'store_id' => 0, 'value' => $label];
939  $this->setup->getConnection()->insert($optionValueTable, $data);
940  }
941  }
942  }
943 
954  public function updateAttribute($entityTypeId, $id, $field, $value = null, $sortOrder = null)
955  {
956  $this->_updateAttribute($entityTypeId, $id, $field, $value, $sortOrder);
957  $this->_updateAttributeAdditionalData($entityTypeId, $id, $field, $value);
958  return $this;
959  }
960 
972  private function _updateAttribute($entityTypeId, $id, $field, $value = null, $sortOrder = null)
973  {
974  if ($sortOrder !== null) {
975  $this->setup->updateTableRow(
976  'eav_entity_attribute',
977  'attribute_id',
979  'sort_order',
980  $sortOrder
981  );
982  }
983 
984  $attributeFields = $this->_getAttributeTableFields();
985  if (is_array($field)) {
986  $bind = [];
987  foreach ($field as $k => $v) {
988  if (isset($attributeFields[$k])) {
989  $bind[$k] = $this->setup->getConnection()->prepareColumnValue(
990  $attributeFields[$k],
991  $v
992  );
993  }
994  }
995  if (!$bind) {
996  return $this;
997  }
998  $field = $bind;
999  } else {
1000  if (!isset($attributeFields[$field])) {
1001  return $this;
1002  }
1003  }
1004  $attributeId = $this->getAttributeId($entityTypeId, $id);
1005  if (false === $attributeId) {
1006  throw new LocalizedException(__('Attribute with ID: "%1" does not exist', $id));
1007  }
1008 
1009  $this->setup->updateTableRow(
1010  'eav_attribute',
1011  'attribute_id',
1012  $attributeId,
1013  $field,
1014  $value,
1015  'entity_type_id',
1017  );
1018 
1019  return $this;
1020  }
1021 
1032  private function _updateAttributeAdditionalData($entityTypeId, $id, $field, $value = null)
1033  {
1034  $additionalTable = $this->getEntityType($entityTypeId, 'additional_attribute_table');
1035  if (!$additionalTable) {
1036  return $this;
1037  }
1038  $additionalTableExists = $this->setup->getConnection()->isTableExists(
1039  $this->setup->getTable($additionalTable)
1040  );
1041  if (!$additionalTableExists) {
1042  return $this;
1043  }
1044  $attributeFields = $this->setup->getConnection()->describeTable(
1045  $this->setup->getTable($additionalTable)
1046  );
1047  if (is_array($field)) {
1048  $bind = [];
1049  foreach ($field as $k => $v) {
1050  if (isset($attributeFields[$k])) {
1051  $bind[$k] = $this->setup->getConnection()->prepareColumnValue(
1052  $attributeFields[$k],
1053  $v
1054  );
1055  }
1056  }
1057  if (!$bind) {
1058  return $this;
1059  }
1060  $field = $bind;
1061  } else {
1062  if (!isset($attributeFields[$field])) {
1063  return $this;
1064  }
1065  }
1066 
1067  $attributeId = $this->getAttributeId($entityTypeId, $id);
1068  if (false === $attributeId) {
1069  throw new LocalizedException(__('Attribute with ID: "%1" does not exist', $id));
1070  }
1071  $this->setup->updateTableRow(
1072  $this->setup->getTable($additionalTable),
1073  'attribute_id',
1074  $this->getAttributeId($entityTypeId, $id),
1075  $field,
1076  $value
1077  );
1078 
1080  $this->updateCachedRow($field, $value, $attribute);
1081 
1082  return $this;
1083  }
1084 
1094  private function updateCachedRow($field, $value, $attribute)
1095  {
1096  $setupCache = $this->setup->getSetupCache();
1097  $mainTable = $this->setup->getTable('eav_attribute');
1098  if (is_array($field)) {
1099  $oldRow = $setupCache->has($mainTable, $attribute['entity_type_id'], $attribute['attribute_code']) ?
1100  $setupCache->get($mainTable, $attribute['entity_type_id'], $attribute['attribute_code']) :
1101  [];
1102  $newRowData = array_merge($oldRow, $field);
1103  $setupCache->setRow(
1104  $mainTable,
1105  $attribute['entity_type_id'],
1106  $attribute['attribute_code'],
1107  $newRowData
1108  );
1109  } else {
1110  $setupCache->setField(
1111  $mainTable,
1112  $attribute['entity_type_id'],
1113  $attribute['attribute_code'],
1114  $field,
1115  $value
1116  );
1117  }
1118  }
1119 
1128  public function getAttribute($entityTypeId, $id, $field = null)
1129  {
1130  $additionalTable = $this->getEntityType($entityTypeId, 'additional_attribute_table');
1132  $idField = is_numeric($id) ? 'attribute_id' : 'attribute_code';
1133  if (!$additionalTable) {
1134  return $this->setup->getTableRow('eav_attribute', $idField, $id, $field, 'entity_type_id', $entityTypeId);
1135  }
1136 
1137  $mainTable = $this->setup->getTable('eav_attribute');
1138  $setupCache = $this->setup->getSetupCache();
1139  if (!$setupCache->has($mainTable, $entityTypeId, $id)) {
1140  $additionalTable = $this->setup->getTable($additionalTable);
1141  $bind = ['id' => $id, 'entity_type_id' => $entityTypeId];
1142  $select = $this->setup->getConnection()->select()->from(
1143  ['main' => $mainTable]
1144  )->join(
1145  ['additional' => $additionalTable],
1146  'main.attribute_id = additional.attribute_id'
1147  )->where(
1148  "main.{$idField} = :id"
1149  )->where(
1150  'main.entity_type_id = :entity_type_id'
1151  );
1152 
1153  $row = $this->setup->getConnection()->fetchRow($select, $bind);
1154  if (!$row) {
1155  $setupCache->setRow($mainTable, $entityTypeId, $id, []);
1156  } else {
1157  $setupCache->setRow($mainTable, $entityTypeId, $row['attribute_id'], $row);
1158  $setupCache->setRow($mainTable, $entityTypeId, $row['attribute_code'], $row);
1159  }
1160  }
1161 
1162  $row = $setupCache->get($mainTable, $entityTypeId, $id);
1163  if ($field !== null) {
1164  return isset($row[$field]) ? $row[$field] : false;
1165  }
1166 
1167  return $row;
1168  }
1169 
1178  {
1179  if (!is_numeric($id)) {
1180  $id = $this->getAttribute($entityTypeId, $id, 'attribute_id');
1181  }
1182  if (!is_numeric($id)) {
1183  return false;
1184  }
1185  return $id;
1186  }
1187 
1196  {
1197  $entityKeyName = is_numeric($entityTypeId) ? 'entity_type_id' : 'entity_type_code';
1198  $attributeKeyName = is_numeric($id) ? 'attribute_id' : 'attribute_code';
1199 
1200  $bind = ['id' => $id, 'entity_type_id' => $entityTypeId];
1201  $select = $this->setup->getConnection()->select()->from(
1202  ['entity_type' => $this->setup->getTable('eav_entity_type')],
1203  ['entity_table']
1204  )->join(
1205  ['attribute' => $this->setup->getTable('eav_attribute')],
1206  'attribute.entity_type_id = entity_type.entity_type_id',
1207  ['backend_type']
1208  )->where(
1209  "entity_type.{$entityKeyName} = :entity_type_id"
1210  )->where(
1211  "attribute.{$attributeKeyName} = :id"
1212  )->limit(
1213  1
1214  );
1215 
1216  $result = $this->setup->getConnection()->fetchRow($select, $bind);
1217  if ($result) {
1218  $table = $this->setup->getTable($result['entity_table']);
1219  if ($result['backend_type'] != 'static') {
1220  $table .= '_' . $result['backend_type'];
1221  }
1222  return $table;
1223  }
1224 
1225  return false;
1226  }
1227 
1236  {
1237  $mainTable = $this->setup->getTable('eav_attribute');
1239  if ($attribute) {
1240  $this->setup->deleteTableRow('eav_attribute', 'attribute_id', $attribute['attribute_id']);
1241  $setupCache = $this->setup->getSetupCache();
1242  if ($setupCache->has($mainTable, $attribute['entity_type_id'], $attribute['attribute_code'])) {
1243  $setupCache->remove($mainTable, $attribute['entity_type_id'], $attribute['attribute_code']);
1244  }
1245  }
1246  return $this;
1247  }
1248 
1258  public function getAttributeSortOrder($entityTypeId, $setId, $groupId, $sortOrder = null)
1259  {
1260  if (!is_numeric($sortOrder)) {
1261  $bind = ['attribute_group_id' => $this->getAttributeGroupId($entityTypeId, $setId, $groupId)];
1262  $select = $this->setup->getConnection()->select()->from(
1263  $this->setup->getTable('eav_entity_attribute'),
1264  'MAX(sort_order)'
1265  )->where(
1266  'attribute_group_id = :attribute_group_id'
1267  );
1268 
1269  $sortOrder = $this->setup->getConnection()->fetchOne($select, $bind) + 1;
1270  }
1271 
1272  return $sortOrder;
1273  }
1274 
1285  public function addAttributeToSet($entityTypeId, $setId, $groupId, $attributeId, $sortOrder = null)
1286  {
1288  $setId = $this->getAttributeSetId($entityTypeId, $setId);
1290  $attributeId = $this->getAttributeId($entityTypeId, $attributeId);
1291  $table = $this->setup->getTable('eav_entity_attribute');
1292 
1293  $bind = ['attribute_set_id' => $setId, 'attribute_id' => $attributeId];
1294  $select = $this->setup->getConnection()->select()->from(
1295  $table
1296  )->where(
1297  'attribute_set_id = :attribute_set_id'
1298  )->where(
1299  'attribute_id = :attribute_id'
1300  );
1301  $result = $this->setup->getConnection()->fetchRow($select, $bind);
1302 
1303  if ($result) {
1304  if ($result['attribute_group_id'] != $groupId) {
1305  $where = ['entity_attribute_id =?' => $result['entity_attribute_id']];
1306  $data = ['attribute_group_id' => $groupId];
1307  $this->setup->getConnection()->update($table, $data, $where);
1308  }
1309  } else {
1310  $data = [
1311  'entity_type_id' => $entityTypeId,
1312  'attribute_set_id' => $setId,
1313  'attribute_group_id' => $groupId,
1314  'attribute_id' => $attributeId,
1315  'sort_order' => $this->getAttributeSortOrder($entityTypeId, $setId, $groupId, $sortOrder),
1316  ];
1317 
1318  $this->setup->getConnection()->insert($table, $data);
1319  }
1320 
1321  return $this;
1322  }
1323 
1334  public function addAttributeToGroup($entityType, $setId, $groupId, $attributeId, $sortOrder = null)
1335  {
1337  $setId = $this->getAttributeSetId($entityType, $setId);
1338  $groupId = $this->getAttributeGroupId($entityType, $setId, $groupId);
1339  $attributeId = $this->getAttributeId($entityType, $attributeId);
1340 
1341  $data = [
1342  'entity_type_id' => $entityType,
1343  'attribute_set_id' => $setId,
1344  'attribute_group_id' => $groupId,
1345  'attribute_id' => $attributeId,
1346  ];
1347 
1348  $bind = ['entity_type_id' => $entityType, 'attribute_set_id' => $setId, 'attribute_id' => $attributeId];
1349  $select = $this->setup->getConnection()->select()->from(
1350  $this->setup->getTable('eav_entity_attribute')
1351  )->where(
1352  'entity_type_id = :entity_type_id'
1353  )->where(
1354  'attribute_set_id = :attribute_set_id'
1355  )->where(
1356  'attribute_id = :attribute_id'
1357  );
1358  $row = $this->setup->getConnection()->fetchRow($select, $bind);
1359  if ($row) {
1360  // update
1361  if ($sortOrder !== null) {
1362  $data['sort_order'] = $sortOrder;
1363  }
1364 
1365  $this->setup->getConnection()->update(
1366  $this->setup->getTable('eav_entity_attribute'),
1367  $data,
1368  $this->setup->getConnection()->quoteInto('entity_attribute_id=?', $row['entity_attribute_id'])
1369  );
1370  } else {
1371  if ($sortOrder === null) {
1372  $select = $this->setup->getConnection()->select()->from(
1373  $this->setup->getTable('eav_entity_attribute'),
1374  'MAX(sort_order)'
1375  )->where(
1376  'entity_type_id = :entity_type_id'
1377  )->where(
1378  'attribute_set_id = :attribute_set_id'
1379  )->where(
1380  'attribute_id = :attribute_id'
1381  );
1382 
1383  $sortOrder = $this->setup->getConnection()->fetchOne($select, $bind) + 10;
1384  }
1385  $sortOrder = is_numeric($sortOrder) ? $sortOrder : 1;
1386  $data['sort_order'] = $sortOrder;
1387  $this->setup->getConnection()->insert(
1388  $this->setup->getTable('eav_entity_attribute'),
1389  $data
1390  );
1391  }
1392 
1393  return $this;
1394  }
1395 
1396  /******************* BULK INSTALL *****************/
1397 
1403  public function getDefaultEntities()
1404  {
1405  return [];
1406  }
1407 
1416  public function installEntities($entities = null)
1417  {
1418  $this->cleanCache();
1419 
1420  if ($entities === null) {
1421  $entities = $this->getDefaultEntities();
1422  }
1423 
1424  foreach ($entities as $entityName => $entity) {
1425  $this->addEntityType($entityName, $entity);
1426 
1427  $frontendPrefix = isset($entity['frontend_prefix']) ? $entity['frontend_prefix'] : '';
1428  $backendPrefix = isset($entity['backend_prefix']) ? $entity['backend_prefix'] : '';
1429  $sourcePrefix = isset($entity['source_prefix']) ? $entity['source_prefix'] : '';
1430 
1431  if (is_array($entity['attributes']) && !empty($entity['attributes'])) {
1432  foreach ($entity['attributes'] as $attrCode => $attr) {
1433  if (!empty($attr['backend'])) {
1434  if ('_' === $attr['backend']) {
1435  $attr['backend'] = $backendPrefix;
1436  } elseif ('_' === $attr['backend'][0]) {
1437  $attr['backend'] = $backendPrefix . $attr['backend'];
1438  }
1439  }
1440  if (!empty($attr['frontend'])) {
1441  if ('_' === $attr['frontend']) {
1442  $attr['frontend'] = $frontendPrefix;
1443  } elseif ('_' === $attr['frontend'][0]) {
1444  $attr['frontend'] = $frontendPrefix . $attr['frontend'];
1445  }
1446  }
1447  if (!empty($attr['source'])) {
1448  if ('_' === $attr['source']) {
1449  $attr['source'] = $sourcePrefix;
1450  } elseif ('_' === $attr['source'][0]) {
1451  $attr['source'] = $sourcePrefix . $attr['source'];
1452  }
1453  }
1454 
1455  $this->addAttribute($entityName, $attrCode, $attr);
1456  }
1457  }
1458  $this->setDefaultSetToEntityType($entityName);
1459  }
1460 
1461  return $this;
1462  }
1463 
1469  private function _getAttributeTableFields()
1470  {
1471  return $this->setup->getConnection()->describeTable(
1472  $this->setup->getTable('eav_attribute')
1473  );
1474  }
1475 
1482  private function _insertAttribute(array $data)
1483  {
1484  $bind = [];
1485 
1486  $fields = $this->_getAttributeTableFields();
1487 
1488  foreach ($data as $k => $v) {
1489  if (isset($fields[$k])) {
1490  $bind[$k] = $this->setup->getConnection()->prepareColumnValue($fields[$k], $v);
1491  }
1492  }
1493  if (!$bind) {
1494  return $this;
1495  }
1496 
1497  $this->setup->getConnection()->insert(
1498  $this->setup->getTable('eav_attribute'),
1499  $bind
1500  );
1501  $attributeId = $this->setup->getConnection()->lastInsertId(
1502  $this->setup->getTable('eav_attribute')
1503  );
1504  $this->_insertAttributeAdditionalData(
1505  $data['entity_type_id'],
1506  array_merge(['attribute_id' => $attributeId], $data)
1507  );
1508 
1509  return $this;
1510  }
1511 
1519  private function _insertAttributeAdditionalData($entityTypeId, array $data)
1520  {
1521  $additionalTable = $this->getEntityType($entityTypeId, 'additional_attribute_table');
1522  if (!$additionalTable) {
1523  return $this;
1524  }
1525  $additionalTableExists = $this->setup->getConnection()->isTableExists(
1526  $this->setup->getTable($additionalTable)
1527  );
1528  if ($additionalTable && $additionalTableExists) {
1529  $bind = [];
1530  $fields = $this->setup->getConnection()->describeTable(
1531  $this->setup->getTable($additionalTable)
1532  );
1533  foreach ($data as $k => $v) {
1534  if (isset($fields[$k])) {
1535  $bind[$k] = $this->setup->getConnection()->prepareColumnValue($fields[$k], $v);
1536  }
1537  }
1538  if (!$bind) {
1539  return $this;
1540  }
1541  $this->setup->getConnection()->insert(
1542  $this->setup->getTable($additionalTable),
1543  $bind
1544  );
1545  }
1546 
1547  return $this;
1548  }
1549 }
getAttributeSet($entityTypeId, $id, $field=null)
Definition: EavSetup.php:389
getAttributeGroupId($entityTypeId, $setId, $groupId)
Definition: EavSetup.php:669
getEntityTypeId($entityTypeId)
Definition: EavSetup.php:267
convertToAttributeGroupCode($groupName)
Definition: EavSetup.php:575
addAttributeToGroup($entityType, $setId, $groupId, $attributeId, $sortOrder=null)
Definition: EavSetup.php:1334
removeAttribute($entityTypeId, $code)
Definition: EavSetup.php:1235
getAttributeSortOrder($entityTypeId, $setId, $groupId, $sortOrder=null)
Definition: EavSetup.php:1258
getAttributeSetId($entityTypeId, $setId)
Definition: EavSetup.php:409
getDefaultAttributeSetId($entityType)
Definition: EavSetup.php:479
getAttributeId($entityTypeId, $id)
Definition: EavSetup.php:1177
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
$attr
Definition: text.phtml:8
$id
Definition: fieldset.phtml:14
updateAttributeGroup($entityTypeId, $setId, $id, $field, $value=null)
Definition: EavSetup.php:590
addAttributeGroup($entityTypeId, $setId, $name, $sortOrder=null)
Definition: EavSetup.php:533
getAttribute($entityTypeId, $id, $field=null)
Definition: EavSetup.php:1128
$fields
Definition: details.phtml:14
$values
Definition: options.phtml:88
__()
Definition: __.php:13
getAttributeTable($entityTypeId, $id)
Definition: EavSetup.php:1195
__construct(ModuleDataSetupInterface $setup, Context $context, CacheInterface $cache, CollectionFactory $attrGroupCollectionFactory)
Definition: EavSetup.php:91
setDefaultSetToEntityType($entityType, $attributeSet='Default')
Definition: EavSetup.php:445
installEntities($entities=null)
Definition: EavSetup.php:1416
addAttribute($entityTypeId, $code, array $attr)
Definition: EavSetup.php:819
$label
Definition: details.phtml:21
$value
Definition: gender.phtml:16
getAttributeGroupSortOrder($entityTypeId, $setId, $sortOrder=null)
Definition: EavSetup.php:507
getEntityType($id, $field=null)
Definition: EavSetup.php:250
getAllAttributeSetIds($entityTypeId=null)
Definition: EavSetup.php:459
addAttributeToSet($entityTypeId, $setId, $groupId, $attributeId, $sortOrder=null)
Definition: EavSetup.php:1285
$attributeCode
Definition: extend.phtml:12
getAttributesNumberInGroup($entityTypeId, $setId, $groupId)
Definition: EavSetup.php:740
updateEntityType($code, $field, $value=null)
Definition: EavSetup.php:231
getDefaultAttributeGroupId($entityType, $attributeSetId=null)
Definition: EavSetup.php:710
addAttributeSet($entityTypeId, $name, $sortOrder=null, $setId=null)
Definition: EavSetup.php:331
$entity
Definition: element.phtml:22
$setup
Definition: trigger.php:12
getAttributeSetSortOrder($entityTypeId, $sortOrder=null)
Definition: EavSetup.php:305
removeAttributeGroup($entityTypeId, $setId, $id)
Definition: EavSetup.php:693
getAttributeGroupByCode($entityTypeId, $setId, $code, $field=null)
Definition: EavSetup.php:648
removeAttributeSet($entityTypeId, $id)
Definition: EavSetup.php:428
static is($value, $classBaseName, array $args=array(), $namespaces=array())
Definition: Validate.php:195
$table
Definition: trigger.php:14
addEntityType($code, array $params)
Definition: EavSetup.php:184
$params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE]
Definition: website.php:18
getAttributeGroup($entityTypeId, $setId, $id, $field=null)
Definition: EavSetup.php:614
updateAttribute($entityTypeId, $id, $field, $value=null, $sortOrder=null)
Definition: EavSetup.php:954
$code
Definition: info.phtml:12
updateAttributeSet($entityTypeId, $id, $field, $value=null)
Definition: EavSetup.php:367
if(!isset($_GET['name'])) $name
Definition: log.php:14