![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/module-checkout/Block/Checkout/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Checkout\Block\Checkout; use Magento\Customer\Api\CustomerRepositoryInterface as CustomerRepository; use Magento\Customer\Api\Data\CustomerInterface; use Magento\Customer\Helper\Address as AddressHelper; use Magento\Customer\Model\Session; use Magento\Directory\Helper\Data as DirectoryHelper; use Magento\Directory\Model\AllowedCountries; use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NoSuchEntityException; /** * Fields attribute merger. * * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) */ class AttributeMerger { /** * Map form element * * @var array */ protected $formElementMap = [ 'checkbox' => 'Magento_Ui/js/form/element/select', 'select' => 'Magento_Ui/js/form/element/select', 'textarea' => 'Magento_Ui/js/form/element/textarea', 'multiline' => 'Magento_Ui/js/form/components/group', 'multiselect' => 'Magento_Ui/js/form/element/multiselect', 'image' => 'Magento_Ui/js/form/element/media', 'file' => 'Magento_Ui/js/form/element/media', ]; /** * Map template * * @var array */ protected $templateMap = [ 'image' => 'media', 'file' => 'media', ]; /** * Map input_validation and validation rule from js * * @var array */ protected $inputValidationMap = [ 'alpha' => 'validate-alpha', 'numeric' => 'validate-number', 'alphanumeric' => 'validate-alphanum', 'alphanum-with-spaces' => 'validate-alphanum-with-spaces', 'url' => 'validate-url', 'email' => 'email2', 'length' => 'validate-length', ]; /** * @var AddressHelper */ private $addressHelper; /** * @var Session */ private $customerSession; /** * @var CustomerRepository */ private $customerRepository; /** * @var CustomerInterface */ private $customer; /** * @var \Magento\Directory\Helper\Data */ private $directoryHelper; /** * List of codes of countries that must be shown on the top of country list * * @var array */ private $topCountryCodes; /** * @var AllowedCountries|null */ private $allowedCountryReader; /** * @param AddressHelper $addressHelper * @param Session $customerSession * @param CustomerRepository $customerRepository * @param DirectoryHelper $directoryHelper * @param AllowedCountries $allowedCountryReader */ public function __construct( AddressHelper $addressHelper, Session $customerSession, CustomerRepository $customerRepository, DirectoryHelper $directoryHelper, ?AllowedCountries $allowedCountryReader = null ) { $this->addressHelper = $addressHelper; $this->customerSession = $customerSession; $this->customerRepository = $customerRepository; $this->directoryHelper = $directoryHelper; $this->topCountryCodes = $directoryHelper->getTopCountryCodes(); $this->allowedCountryReader = $allowedCountryReader ?: ObjectManager::getInstance()->get(AllowedCountries::class); } /** * Merge additional address fields for given provider * * @param array $elements * @param string $providerName name of the storage container used by UI component * @param string $dataScopePrefix * @param array $fields * @return array */ public function merge($elements, $providerName, $dataScopePrefix, array $fields = []) { foreach ($elements as $attributeCode => $attributeConfig) { $additionalConfig = isset($fields[$attributeCode]) ? $fields[$attributeCode] : []; if (!$this->isFieldVisible($attributeCode, $attributeConfig, $additionalConfig)) { continue; } $fields[$attributeCode] = $this->getFieldConfig( $attributeCode, $attributeConfig, $additionalConfig, $providerName, $dataScopePrefix ); } return $fields; } /** * Retrieve UI field configuration for given attribute * * @param string $attributeCode * @param array $attributeConfig * @param array $additionalConfig field configuration provided via layout XML * @param string $providerName name of the storage container used by UI component * @param string $dataScopePrefix * @return array * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ protected function getFieldConfig( $attributeCode, array $attributeConfig, array $additionalConfig, $providerName, $dataScopePrefix ) { // street attribute is unique in terms of configuration, so it has its own configuration builder if (isset($attributeConfig['validation']['input_validation'])) { $validationRule = $attributeConfig['validation']['input_validation']; $attributeConfig['validation'][$this->inputValidationMap[$validationRule]] = true; unset($attributeConfig['validation']['input_validation']); } if ($attributeConfig['formElement'] == 'multiline') { return $this->getMultilineFieldConfig($attributeCode, $attributeConfig, $providerName, $dataScopePrefix); } $uiComponent = isset($this->formElementMap[$attributeConfig['formElement']]) ? $this->formElementMap[$attributeConfig['formElement']] : 'Magento_Ui/js/form/element/abstract'; $elementTemplate = isset($this->templateMap[$attributeConfig['formElement']]) ? 'ui/form/element/' . $this->templateMap[$attributeConfig['formElement']] : 'ui/form/element/' . $attributeConfig['formElement']; $element = [ 'component' => isset($additionalConfig['component']) ? $additionalConfig['component'] : $uiComponent, 'config' => $this->mergeConfigurationNode( 'config', $additionalConfig, [ 'config' => [ // customScope is used to group elements within a single // form (e.g. they can be validated separately) 'customScope' => $dataScopePrefix, 'template' => 'ui/form/field', 'elementTmpl' => $elementTemplate, ], ] ), 'dataScope' => $dataScopePrefix . '.' . $attributeCode, 'label' => $attributeConfig['label'], 'provider' => $providerName, 'sortOrder' => isset($additionalConfig['sortOrder']) ? $additionalConfig['sortOrder'] : $attributeConfig['sortOrder'], 'validation' => $this->mergeConfigurationNode('validation', $additionalConfig, $attributeConfig), 'options' => $this->getFieldOptions($attributeCode, $attributeConfig), 'filterBy' => isset($additionalConfig['filterBy']) ? $additionalConfig['filterBy'] : null, 'customEntry' => isset($additionalConfig['customEntry']) ? $additionalConfig['customEntry'] : null, 'visible' => isset($additionalConfig['visible']) ? $additionalConfig['visible'] : true, ]; if ($attributeCode === 'region_id' || $attributeCode === 'country_id') { unset($element['options']); $element['deps'] = [$providerName]; $element['imports'] = [ 'initialOptions' => 'index = ' . $providerName . ':dictionaries.' . $attributeCode, 'setOptions' => 'index = ' . $providerName . ':dictionaries.' . $attributeCode ]; } if (isset($attributeConfig['value']) && $attributeConfig['value'] != null) { $element['value'] = $attributeConfig['value']; } elseif (isset($attributeConfig['default']) && $attributeConfig['default'] != null) { $element['value'] = $attributeConfig['default']; } else { $defaultValue = $this->getDefaultValue($attributeCode); if (null !== $defaultValue) { $element['value'] = $defaultValue; } } return $element; } /** * Merge two configuration nodes recursively * * @param string $nodeName * @param array $mainSource * @param array $additionalSource * @return array */ protected function mergeConfigurationNode($nodeName, array $mainSource, array $additionalSource) { $mainData = isset($mainSource[$nodeName]) ? $mainSource[$nodeName] : []; $additionalData = isset($additionalSource[$nodeName]) ? $additionalSource[$nodeName] : []; return array_replace_recursive($additionalData, $mainData); } /** * Check if address attribute is visible on frontend * * @param string $attributeCode * @param array $attributeConfig * @param array $additionalConfig field configuration provided via layout XML * @return bool */ protected function isFieldVisible($attributeCode, array $attributeConfig, array $additionalConfig = []) { // TODO move this logic to separate model so it can be customized if ($attributeConfig['visible'] == false || (isset($additionalConfig['visible']) && $additionalConfig['visible'] == false) ) { return false; } if ($attributeCode == 'vat_id' && !$this->addressHelper->isVatAttributeVisible()) { return false; } return true; } /** * Retrieve field configuration for street address attribute * * @param string $attributeCode * @param array $attributeConfig * @param string $providerName name of the storage container used by UI component * @param string $dataScopePrefix * @return array */ protected function getMultilineFieldConfig($attributeCode, array $attributeConfig, $providerName, $dataScopePrefix) { $lines = []; unset($attributeConfig['validation']['required-entry']); for ($lineIndex = 0; $lineIndex < (int)$attributeConfig['size']; $lineIndex++) { $isFirstLine = $lineIndex === 0; $line = [ 'label' => __("%1: Line %2", $attributeConfig['label'], $lineIndex + 1), 'component' => 'Magento_Ui/js/form/element/abstract', 'config' => [ // customScope is used to group elements within a single form e.g. they can be validated separately 'customScope' => $dataScopePrefix, 'template' => 'ui/form/field', 'elementTmpl' => 'ui/form/element/input' ], 'dataScope' => $lineIndex, 'provider' => $providerName, 'validation' => $isFirstLine // phpcs:ignore Magento2.Performance.ForeachArrayMerge ? array_merge( ['required-entry' => (bool)$attributeConfig['required']], $attributeConfig['validation'] ) : $attributeConfig['validation'], 'additionalClasses' => $isFirstLine ? 'field' : 'additional' ]; if ($isFirstLine && isset($attributeConfig['default']) && $attributeConfig['default'] != null) { $line['value'] = $attributeConfig['default']; } $lines[] = $line; } return [ 'component' => 'Magento_Ui/js/form/components/group', 'label' => $attributeConfig['label'], 'required' => (bool)$attributeConfig['required'], 'dataScope' => $dataScopePrefix . '.' . $attributeCode, 'provider' => $providerName, 'sortOrder' => $attributeConfig['sortOrder'], 'type' => 'group', 'config' => [ 'template' => 'ui/group/group', 'additionalClasses' => $attributeCode ], 'children' => $lines, ]; } /** * Returns default attribute value. * * @param string $attributeCode * @throws NoSuchEntityException * @throws LocalizedException * @return null|string */ protected function getDefaultValue($attributeCode): ?string { if ($attributeCode === 'country_id') { $defaultCountryId = $this->directoryHelper->getDefaultCountry(); if (!in_array($defaultCountryId, $this->allowedCountryReader->getAllowedCountries())) { $defaultCountryId = null; } return $defaultCountryId; } $customer = $this->getCustomer(); if ($customer === null) { return null; } $attributeValue = null; switch ($attributeCode) { case 'prefix': $attributeValue = $customer->getPrefix(); break; case 'firstname': $attributeValue = $customer->getFirstname(); break; case 'middlename': $attributeValue = $customer->getMiddlename(); break; case 'lastname': $attributeValue = $customer->getLastname(); break; case 'suffix': $attributeValue = $customer->getSuffix(); break; } return $attributeValue; } /** * Returns logged customer. * * @throws NoSuchEntityException * @throws LocalizedException * @return CustomerInterface|null */ protected function getCustomer(): ?CustomerInterface { if (!$this->customer) { if ($this->customerSession->isLoggedIn()) { $this->customer = $this->customerRepository->getById($this->customerSession->getCustomerId()); } else { return null; } } return $this->customer; } /** * Retrieve field options from attribute configuration * * @param mixed $attributeCode * @param array $attributeConfig * @return array * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ protected function getFieldOptions($attributeCode, array $attributeConfig) { return $attributeConfig['options'] ?? []; } /** * Order country options. Move top countries to the beginning of the list. * * @param array $countryOptions * @return array * @deprecated 100.1.7 */ protected function orderCountryOptions(array $countryOptions) { if (empty($this->topCountryCodes)) { return $countryOptions; } $headOptions = []; $tailOptions = [[ 'value' => 'delimiter', 'label' => '──────────', 'disabled' => true, ]]; foreach ($countryOptions as $countryOption) { if (empty($countryOption['value']) || in_array($countryOption['value'], $this->topCountryCodes)) { $headOptions[] = $countryOption; } else { $tailOptions[] = $countryOption; } } return array_merge($headOptions, $tailOptions); } }