15 use Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory as EavAttributeFactory;
20 use Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\CollectionFactory as GroupCollectionFactory;
36 use Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory as AttributeCollectionFactory;
145 private $scopeOverriddenValue;
150 private $attributesToDisable;
167 private $attributes = [];
172 private $attributeGroups = [];
177 private $canDisplayUseDefault = [];
182 private $bannedInputTypes = [
'media_image'];
187 private $prevSetAttributes;
192 private $localeCurrency;
198 private $attributesCache = [];
203 private $attributeCollectionFactory;
208 private $wysiwygConfigProcessor;
213 private $scopeConfig;
259 $attributesToDisable = [],
263 AttributeCollectionFactory $attributeCollectionFactory =
null 280 $this->scopeOverriddenValue = $scopeOverriddenValue;
282 $this->attributesToDisable = $attributesToDisable;
285 ->get(CompositeConfigProcessor::class);
287 ->get(ScopeConfigInterface::class);
288 $this->attributeCollectionFactory = $attributeCollectionFactory
300 foreach ($this->getGroups() as $groupCode =>
$group) {
301 $attributes = !empty($this->getAttributes()[$groupCode]) ? $this->getAttributes()[$groupCode] : [];
304 $meta[$groupCode][
'children'] = $this->getAttributesMeta($attributes, $groupCode);
305 $meta[$groupCode][
'arguments'][
'data'][
'config'][
'componentType'] =
Fieldset::NAME;
306 $meta[$groupCode][
'arguments'][
'data'][
'config'][
'label'] =
__(
$group->getAttributeGroupName());
307 $meta[$groupCode][
'arguments'][
'data'][
'config'][
'collapsible'] =
true;
309 $meta[$groupCode][
'arguments'][
'data'][
'config'][
'sortOrder'] =
327 private function getAttributesMeta(array $attributes, $groupCode)
331 foreach ($attributes as $sortOrder =>
$attribute) {
332 if (in_array(
$attribute->getFrontendInput(), $this->bannedInputTypes)) {
346 $meta[static::CONTAINER_PREFIX .
$attribute->getAttributeCode()] = $attributeContainer;
364 array $attributeContainer,
369 foreach ($this->
getContainerChildren($attribute, $groupCode, $sortOrder) as $childCode => $child) {
370 $attributeContainer[
'children'][$childCode] = $child;
373 $attributeContainer = $this->arrayManager->merge(
377 'sortOrder' => $sortOrder * self::SORT_ORDER_MULTIPLIER
381 return $attributeContainer;
400 return [
$attribute->getAttributeCode() => $child];
409 if (!$this->locator->getProduct()->getId() && $this->dataPersistor->get(
'catalog_product')) {
410 return $this->resolvePersistentData(
$data);
413 $productId = $this->locator->getProduct()->getId();
416 foreach (array_keys($this->getGroups()) as $groupCode) {
418 $attributes = !empty($this->getAttributes()[$groupCode]) ? $this->getAttributes()[$groupCode] : [];
422 if (
$attribute->getFrontendInput() ===
'price' && is_scalar($attributeValue)) {
423 $attributeValue = $this->
formatPrice($attributeValue);
439 private function resolvePersistentData(array
$data)
441 $persistentData = (array)$this->dataPersistor->get(
'catalog_product');
442 $this->dataPersistor->clear(
'catalog_product');
443 $productId = $this->locator->getProduct()->getId();
462 private function getProductType()
464 return (
string)$this->request->getParam(
'type', $this->locator->getProduct()->getTypeId());
472 private function getPreviousSetId()
474 return (
int)$this->request->getParam(
'prev_set_id', 0);
482 private function getGroups()
484 if (!$this->attributeGroups) {
486 $attributeGroupSearchResult = $this->attributeGroupRepository->getList(
$searchCriteria);
487 foreach ($attributeGroupSearchResult->getItems() as
$group) {
488 $this->attributeGroups[$this->calculateGroupCode(
$group)] =
$group;
492 return $this->attributeGroups;
500 private function prepareGroupSearchCriteria()
502 return $this->searchCriteriaBuilder->addFilter(
504 $this->getAttributeSetId()
513 private function getAttributeSetId()
515 return $this->locator->getProduct()->getAttributeSetId();
523 private function getAttributes()
525 if (!$this->attributes) {
526 $this->attributes = $this->loadAttributesForGroups($this->getGroups());
529 return $this->attributes;
538 private function loadAttributesForGroups(array $groups)
543 foreach ($groups as
$group) {
544 $groupIds[
$group->getAttributeGroupId()] = $this->calculateGroupCode(
$group);
548 $collection = $this->attributeCollectionFactory->create();
549 $collection->setAttributeGroupFilter(array_keys($groupIds));
551 $mapAttributeToGroup = [];
557 $sortOrder = $this->sortOrderBuilder
558 ->setField(
'sort_order')
559 ->setAscendingDirection()
565 ->addSortOrder($sortOrder)
568 $groupAttributes = $this->attributeRepository->getList(
$searchCriteria)->getItems();
570 $productType = $this->getProductType();
574 $isRelated = !$applyTo || in_array($productType, $applyTo);
591 private function getPreviousSetAttributes()
593 if ($this->prevSetAttributes ===
null) {
595 ->addFilter(
'attribute_set_id', $this->getPreviousSetId())
598 $this->prevSetAttributes = [];
600 $this->prevSetAttributes[] =
$attribute->getAttributeCode();
604 return $this->prevSetAttributes;
612 private function isProductExists()
614 return (
bool) $this->locator->getProduct()->getId();
634 $meta = $this->arrayManager->set($configPath, [], [
636 'formElement' => $this->getFormElementsMapValue(
$attribute->getFrontendInput()),
640 'default' => (!$this->isProductExists()) ? $this->getAttributeDefaultValue(
$attribute) :
null,
643 'source' => $groupCode,
644 'scopeLabel' => $this->getScopeLabel(
$attribute),
645 'globalScope' => $this->isScopeGlobal(
$attribute),
650 $attributeModel = $this->getAttributeModel(
$attribute);
651 if ($attributeModel->usesSource()) {
652 $options = $attributeModel->getSource()->getAllOptions();
653 $meta = $this->arrayManager->merge($configPath, $meta, [
654 'options' => $this->convertOptionsValueToString(
$options),
658 if ($this->canDisplayUseDefault(
$attribute)) {
659 $meta = $this->arrayManager->merge($configPath, $meta, [
661 'template' =>
'ui/form/element/helper/service',
666 if (!$this->arrayManager->exists($configPath .
'/componentType', $meta)) {
667 $meta = $this->arrayManager->merge($configPath, $meta, [
672 $product = $this->locator->getProduct();
675 $meta = $this->arrayManager->merge($configPath, $meta, [
681 $childData = $this->arrayManager->get($configPath, $meta, []);
682 if ((
$rules = $this->catalogEavValidationRules->build($this->getAttributeModel(
$attribute), $childData))) {
683 $meta = $this->arrayManager->merge($configPath, $meta, [
688 $meta = $this->addUseDefaultValueCheckbox(
$attribute, $meta);
692 $meta = $this->customizeCheckbox(
$attribute, $meta);
695 $meta = $this->customizeWysiwyg(
$attribute, $meta);
698 $meta = $this->customizePriceAttribute(
$attribute, $meta);
717 if (
$attribute->getAttributeCode() ===
'page_layout') {
718 $defaultValue = $this->scopeConfig->getValue(
719 'web/default_layouts/default_product_layout',
721 $this->storeManager->getStore()
734 private function convertOptionsValueToString(array
$options) : array
737 if (isset(
$value[
'value']) && is_scalar(
$value[
'value'])) {
752 private function addUseDefaultValueCheckbox(ProductAttributeInterface
$attribute, array $meta)
754 $canDisplayService = $this->canDisplayUseDefault(
$attribute);
755 if ($canDisplayService) {
756 $meta[
'arguments'][
'data'][
'config'][
'service'] = [
757 'template' =>
'ui/form/element/helper/service',
760 $meta[
'arguments'][
'data'][
'config'][
'disabled'] = !$this->scopeOverriddenValue->containsValue(
761 \
Magento\Catalog\Api\Data\ProductInterface::class,
762 $this->locator->getProduct(),
764 $this->locator->getStore()->getId()
780 $containerMeta = $this->arrayManager->set(
781 'arguments/data/config',
784 'formElement' =>
'container',
785 'componentType' =>
'container',
786 'breakLine' =>
false,
787 'label' =>
$attribute->getDefaultFrontendLabel(),
793 $containerMeta = $this->arrayManager->merge(
794 'arguments/data/config',
797 'component' =>
'Magento_Ui/js/form/components/group' 802 return $containerMeta;
815 $product = $this->locator->getProduct();
817 $prevSetId = $this->getPreviousSetId();
818 $notUsed = !$prevSetId
819 || ($prevSetId && !in_array(
$attribute->getAttributeCode(), $this->getPreviousSetAttributes()));
837 if (
$attribute->getFrontendInput() ===
'boolean') {
838 $meta[
'arguments'][
'data'][
'config'][
'prefer'] =
'toggle';
839 $meta[
'arguments'][
'data'][
'config'][
'valueMap'] = [
857 if (
$attribute->getFrontendInput() ===
'price') {
858 $meta[
'arguments'][
'data'][
'config'][
'addbefore'] = $this->locator->getStore()
860 ->getCurrencySymbol();
873 private function customizeWysiwyg(ProductAttributeInterface
$attribute, array $meta)
879 $meta[
'arguments'][
'data'][
'config'][
'formElement'] = WysiwygElement::NAME;
880 $meta[
'arguments'][
'data'][
'config'][
'wysiwyg'] =
true;
881 $meta[
'arguments'][
'data'][
'config'][
'wysiwygConfigData'] = $this->wysiwygConfigProcessor->process(
$attribute);
892 private function getFormElementsMapValue(
$value)
894 $valueMap = $this->formElementMapper->getMappings();
905 private function getValue(ProductAttributeInterface
$attribute)
908 $product = $this->locator->getProduct();
919 private function getScopeLabel(ProductAttributeInterface
$attribute)
921 if ($this->storeManager->isSingleStoreMode()
929 return __(
'[GLOBAL]');
931 return __(
'[WEBSITE]');
933 return __(
'[STORE VIEW]');
945 private function canDisplayUseDefault(ProductAttributeInterface
$attribute)
949 $product = $this->locator->getProduct();
985 private function getAttributeModel(
$attribute)
989 if (!array_key_exists($attributeId, $this->attributesCache)) {
990 $this->attributesCache[$attributeId] = $this->eavAttributeFactory->create()->load($attributeId);
993 return $this->attributesCache[$attributeId];
1006 private function calculateGroupCode(AttributeGroupInterface
$group)
1008 $attributeGroupCode =
$group->getAttributeGroupCode();
1010 if ($attributeGroupCode ===
'images') {
1011 $attributeGroupCode =
'image-management';
1014 return $attributeGroupCode;
1024 private function getLocaleCurrency()
1026 if ($this->localeCurrency ===
null) {
1029 return $this->localeCurrency;
1041 if (!is_numeric(
$value)) {
1045 $store = $this->storeManager->getStore();
1046 $currency = $this->getLocaleCurrency()->getCurrency(
$store->getBaseCurrencyCode());
1047 $value = $currency->toCurrency(
$value, [
'display' => \
Magento\Framework\Currency::NO_SYMBOL]);
const DEFAULT_PATH_DELIMITER