123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- <?php
- declare(strict_types=1);
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Customer\Model;
- use Magento\Customer\Model\ResourceModel\Address\Attribute\Source\CountryWithWebsites;
- use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
- use Magento\Customer\Api\Data\AddressInterface;
- use Magento\Ui\DataProvider\EavValidationRules;
- use Magento\Ui\Component\Form\Field;
- use Magento\Eav\Model\Entity\Type;
- use Magento\Eav\Api\Data\AttributeInterface;
- use Magento\Framework\View\Element\UiComponent\ContextInterface;
- use Magento\Customer\Api\Data\CustomerInterface;
- use Magento\Customer\Model\Config\Share as ShareConfig;
- /**
- * Class to build meta data of the customer or customer address attribute
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class AttributeMetadataResolver
- {
- /**
- * EAV attribute properties to fetch from meta storage
- * @var array
- */
- private static $metaProperties = [
- 'dataType' => 'frontend_input',
- 'visible' => 'is_visible',
- 'required' => 'is_required',
- 'label' => 'frontend_label',
- 'sortOrder' => 'sort_order',
- 'notice' => 'note',
- 'default' => 'default_value',
- 'size' => 'multiline_count',
- ];
- /**
- * Form element mapping
- *
- * @var array
- */
- private static $formElement = [
- 'text' => 'input',
- 'hidden' => 'input',
- 'boolean' => 'checkbox',
- ];
- /**
- * @var CountryWithWebsites
- */
- private $countryWithWebsiteSource;
- /**
- * @var EavValidationRules
- */
- private $eavValidationRules;
- /**
- * @var FileUploaderDataResolver
- */
- private $fileUploaderDataResolver;
- /**
- * @var ContextInterface
- */
- private $context;
- /**
- * @var ShareConfig
- */
- private $shareConfig;
- /**
- * @param CountryWithWebsites $countryWithWebsiteSource
- * @param EavValidationRules $eavValidationRules
- * @param \Magento\Customer\Model\FileUploaderDataResolver $fileUploaderDataResolver
- * @param ContextInterface $context
- * @param ShareConfig $shareConfig
- */
- public function __construct(
- CountryWithWebsites $countryWithWebsiteSource,
- EavValidationRules $eavValidationRules,
- fileUploaderDataResolver $fileUploaderDataResolver,
- ContextInterface $context,
- ShareConfig $shareConfig
- ) {
- $this->countryWithWebsiteSource = $countryWithWebsiteSource;
- $this->eavValidationRules = $eavValidationRules;
- $this->fileUploaderDataResolver = $fileUploaderDataResolver;
- $this->context = $context;
- $this->shareConfig = $shareConfig;
- }
- /**
- * Get meta data of the customer or customer address attribute
- *
- * @param AbstractAttribute $attribute
- * @param Type $entityType
- * @param bool $allowToShowHiddenAttributes
- * @param string $requestFieldName
- * @return array
- * @throws \Magento\Framework\Exception\LocalizedException
- */
- public function getAttributesMeta(
- AbstractAttribute $attribute,
- Type $entityType,
- bool $allowToShowHiddenAttributes,
- string $requestFieldName
- ): array {
- $meta = $this->modifyBooleanAttributeMeta($attribute);
- // use getDataUsingMethod, since some getters are defined and apply additional processing of returning value
- foreach (self::$metaProperties as $metaName => $origName) {
- $value = $attribute->getDataUsingMethod($origName);
- $meta['arguments']['data']['config'][$metaName] = ($metaName === 'label') ? __($value) : $value;
- if ('frontend_input' === $origName) {
- $meta['arguments']['data']['config']['formElement'] = self::$formElement[$value] ?? $value;
- }
- }
- if ($attribute->usesSource()) {
- if ($attribute->getAttributeCode() === AddressInterface::COUNTRY_ID) {
- $meta['arguments']['data']['config']['options'] = $this->countryWithWebsiteSource
- ->getAllOptions();
- } else {
- $meta['arguments']['data']['config']['options'] = $attribute->getSource()->getAllOptions();
- }
- }
- $rules = $this->eavValidationRules->build($attribute, $meta['arguments']['data']['config']);
- if (!empty($rules)) {
- $meta['arguments']['data']['config']['validation'] = $rules;
- }
- $meta['arguments']['data']['config']['componentType'] = Field::NAME;
- $meta['arguments']['data']['config']['visible'] = $this->canShowAttribute(
- $attribute,
- $requestFieldName,
- $allowToShowHiddenAttributes
- );
- $this->fileUploaderDataResolver->overrideFileUploaderMetadata(
- $entityType,
- $attribute,
- $meta['arguments']['data']['config']
- );
- return $meta;
- }
- /**
- * Detect can we show attribute on specific form or not
- *
- * @param AbstractAttribute $customerAttribute
- * @param string $requestFieldName
- * @param bool $allowToShowHiddenAttributes
- * @return bool
- */
- private function canShowAttribute(
- AbstractAttribute $customerAttribute,
- string $requestFieldName,
- bool $allowToShowHiddenAttributes
- ) {
- $userDefined = (bool)$customerAttribute->getIsUserDefined();
- if (!$userDefined) {
- return $customerAttribute->getIsVisible();
- }
- $canShowOnForm = $this->canShowAttributeInForm($customerAttribute, $requestFieldName);
- return ($allowToShowHiddenAttributes && $canShowOnForm) ||
- (!$allowToShowHiddenAttributes && $canShowOnForm && $customerAttribute->getIsVisible());
- }
- /**
- * Check whether the specific attribute can be shown in form: customer registration, customer edit, etc...
- *
- * @param AbstractAttribute $customerAttribute
- * @param string $requestFieldName
- * @return bool
- */
- private function canShowAttributeInForm(AbstractAttribute $customerAttribute, string $requestFieldName): bool
- {
- $isRegistration = $this->context->getRequestParam($requestFieldName) === null;
- if ($customerAttribute->getEntityType()->getEntityTypeCode() === 'customer') {
- return \is_array($customerAttribute->getUsedInForms()) &&
- (
- (\in_array('customer_account_create', $customerAttribute->getUsedInForms(), true)
- && $isRegistration) ||
- (\in_array('customer_account_edit', $customerAttribute->getUsedInForms(), true)
- && !$isRegistration)
- );
- }
- return \is_array($customerAttribute->getUsedInForms()) &&
- \in_array('customer_address_edit', $customerAttribute->getUsedInForms(), true);
- }
- /**
- * Modify boolean attribute meta data
- *
- * @param AttributeInterface $attribute
- * @return array
- */
- private function modifyBooleanAttributeMeta(AttributeInterface $attribute): array
- {
- $meta = [];
- if ($attribute->getFrontendInput() === 'boolean') {
- $meta['arguments']['data']['config']['prefer'] = 'toggle';
- $meta['arguments']['data']['config']['valueMap'] = [
- 'true' => '1',
- 'false' => '0',
- ];
- }
- return $meta;
- }
- /**
- * Add global scope parameter and filter options to website meta
- *
- * @param array $meta
- * @return void
- */
- public function processWebsiteMeta(&$meta): void
- {
- if (isset($meta[CustomerInterface::WEBSITE_ID]) && $this->shareConfig->isGlobalScope()) {
- $meta[CustomerInterface::WEBSITE_ID]['arguments']['data']['config']['isGlobalScope'] = 1;
- }
- if (isset($meta[AddressInterface::COUNTRY_ID]) && !$this->shareConfig->isGlobalScope()) {
- $meta[AddressInterface::COUNTRY_ID]['arguments']['data']['config']['filterBy'] = [
- 'target' => 'customer_form.customer_form_data_source:data.customer.website_id',
- 'field' => 'website_ids'
- ];
- }
- }
- }
|