Your IP : 216.73.216.43


Current Path : /var/www/www.indacotrentino.com/www/app/code/Amasty/Conditions/Model/Rule/Condition/
Upload File :
Current File : //var/www/www.indacotrentino.com/www/app/code/Amasty/Conditions/Model/Rule/Condition/Address.php

<?php
/**
 * @author Amasty Team
 * @copyright Copyright (c) Amasty (https://www.amasty.com)
 * @package Advanced Conditions for Magento 2
 */

namespace Amasty\Conditions\Model\Rule\Condition;

use Amasty\Conditions\Api\Data\AddressInterface;
use Amasty\Conditions\Model\AddressFactory;
use Amasty\Conditions\Model\Constants;
use Magento\Config\Model\Config\Source\Locale\Currency;
use Magento\Directory\Model\Config\Source\Country;
use Magento\Framework\App\Area;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\ProductMetadataInterface;
use Magento\Framework\App\State;
use Magento\Payment\Model\Config\Source\Allmethods;
use Magento\Quote\Model\Quote;
use Magento\Rule\Model\Condition\AbstractCondition;
use Magento\Rule\Model\Condition\Context;
use Magento\Store\Model\StoreManagerInterface;

class Address extends AbstractCondition
{
    public const CUSTOM_OPERATORS = [
        AddressInterface::SHIPPING_ADDRESS_LINE,
        AddressInterface::CITY,
        AddressInterface::CURRENCY
    ];

    public const VALUE_PARTS_FOR_CONTAINS = [
        'klarna',
        'vault'
    ];

    /**
     * @var Country
     */
    private $country;

    /**
     * @var Currency
     */
    private $currency;

    /**
     * @var ProductMetadataInterface
     */
    private $productMetadata;

    /**
     * @var Allmethods
     */
    private $allMethods;

    /**
     * @var \Amasty\Conditions\Model\Address
     */
    private $address;

    /**
     * @var AddressFactory
     */
    private $addressFactory;

    /**
     * @var StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var State
     */
    private $state;

    public function __construct(
        Context $context,
        ProductMetadataInterface $productMetadata,
        Country $country,
        Currency $currency,
        Allmethods $allMethods,
        \Amasty\Conditions\Model\Address $address,
        AddressFactory $addressFactory,
        StoreManagerInterface $storeManager,
        array $data = [],
        State $state = null // TODO move to not optional
    ) {
        $this->productMetadata = $productMetadata;
        $this->country = $country;
        $this->currency = $currency;
        $this->allMethods = $allMethods;
        $this->address = $address;
        $this->addressFactory = $addressFactory;
        $this->storeManager = $storeManager;
        $this->state = $state ?? ObjectManager::getInstance()->get(State::class);
        parent::__construct($context, $data);
    }

    /**
     * @return $this
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function loadAttributeOptions()
    {
        $attributes = [
            AddressInterface::BILLING_ADDRESS_COUNTRY => __('Billing Address Country'),
            AddressInterface::PAYMENT_METHOD => __('Payment Method'),
            AddressInterface::SHIPPING_ADDRESS_LINE => __('Shipping Address Line'),
            AddressInterface::CITY => __('City')
        ];

        if (version_compare($this->productMetadata->getVersion(), '2.3.0', '>=')) {
            $attributes[AddressInterface::CURRENCY] = __('Storeview currency');
        }

        $this->setAttributeOption($attributes);

        return $this;
    }

    /**
     * @return array
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getOperatorSelectOptions()
    {
        if (in_array($this->getAttribute(), self::CUSTOM_OPERATORS)) {
            $operators = $this->getOperators();
            $type = $this->getInputType();
            $result = [];
            $operatorByType = $this->getOperatorByInputType();
            foreach ($operators as $operatorKey => $operatorValue) {
                if (!$operatorByType || in_array($operatorKey, $operatorByType[$type])) {
                    $result[] = ['value' => $operatorKey, 'label' => $operatorValue];
                }
            }

            return $result;
        }

        return parent::getOperatorSelectOptions();
    }

    /**
     * @return array
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    private function getOperators()
    {
        switch ($this->getAttribute()) {
            case AddressInterface::SHIPPING_ADDRESS_LINE:
                $result = [
                    '{}' => __('contains'),
                    '!{}' => __('does not contain')
                ];
                break;

            case AddressInterface::CITY:
                $result = [
                    '{}' => __('contains'),
                    '!{}' => __('does not contain'),
                    '==' => __('is'),
                    '!=' => __('is not'),
                    '()' => __('is one of'),
                    '!()' => __('is not one of')
                ];
                break;

            case AddressInterface::CURRENCY:
                $result = [
                    '()' => __('is one of'),
                    '!()' => __('is not one of')
                ];
                break;

            default:
                $result = [];
        }

        return $result;
    }

    /**
     * @return $this
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getAttributeElement()
    {
        $element = parent::getAttributeElement();
        $element->setShowAsText(true);

        return $element;
    }

    /**
     * @return string
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getInputType()
    {
        switch ($this->getAttribute()) {
            case AddressInterface::SHIPPING_ADDRESS_LINE:
            case AddressInterface::CITY:
                $result = 'string';
                break;

            case AddressInterface::CURRENCY:
                $result = 'multiselect';
                break;

            default:
                $result = 'select';
        }

        return $result;
    }

    /**
     * @return string
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getValueElementType()
    {
        switch ($this->getAttribute()) {
            case AddressInterface::SHIPPING_ADDRESS_LINE:
            case AddressInterface::CITY:
                $result = 'text';
                break;

            case AddressInterface::CURRENCY:
                $result = 'multiselect';
                break;

            default:
                $result = 'select';
        }

        return $result;
    }

    /**
     * @return array|mixed
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getValueSelectOptions()
    {
        if (!$this->hasData(Constants::VALUE_SELECT_OPTIONS)) {
            switch ($this->getAttribute()) {
                case AddressInterface::BILLING_ADDRESS_COUNTRY:
                    $options = $this->country->toOptionArray();
                    break;

                case AddressInterface::PAYMENT_METHOD:
                    $options = $this->allMethods->toOptionArray();
                    break;

                case AddressInterface::CURRENCY:
                    $options = $this->currency->toOptionArray();
                    break;

                default:
                    $options = [];
            }
            $this->setData(Constants::VALUE_SELECT_OPTIONS, $options);
        }

        return $this->getData(Constants::VALUE_SELECT_OPTIONS);
    }

    /**
     * @param \Magento\Framework\Model\AbstractModel $model
     *
     * @return bool
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function validate(\Magento\Framework\Model\AbstractModel $model)
    {
        $address = $model;
        if (!$address instanceof \Magento\Quote\Model\Quote\Address) {
            $address = $address->getQuote()->isVirtual()
                ? $address->getQuote()->getBillingAddress()
                : $address->getQuote()->getShippingAddress();
        }

        $attrValue = $this->getAttributeValue($address);
        if (!$attrValue) {
            try {
                $attrValue = $this->getDefaultAttrValue($address);
            } catch (\Exception $e) {
                $attrValue = null;
            }
        }

        return parent::validateAttribute(trim((string)$attrValue));
    }

    /**
     * @param \Magento\Quote\Model\Quote\Address $address
     *
     * @return string
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    private function getDefaultAttrValue(\Magento\Quote\Model\Quote\Address $address)
    {
        $attrValue = null;
        switch ($this->getAttribute()) {
            case AddressInterface::BILLING_ADDRESS_COUNTRY:
                $attrValue = $address->getCountryId();
                break;

            case AddressInterface::PAYMENT_METHOD:
                $attrValue = $address->getQuote()->getPayment()->getMethod();
                break;

            case AddressInterface::SHIPPING_ADDRESS_LINE:
                $attrValue = $address->getStreetFull();
                break;

            case AddressInterface::CITY:
                $attrValue = $address->getCity();
                break;

            case AddressInterface::CURRENCY:
                $attrValue = $address->getCurrency();
                break;
        }

        return $attrValue;
    }

    /**
     * @param \Magento\Quote\Model\Quote\Address $address
     *
     * @return int|mixed|null|string
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    private function getAttributeValue(\Magento\Quote\Model\Quote\Address $address)
    {
        $attrValue = null;
        if (!$this->address->isAdvancedConditions($address)) {
            $this->resolveAdvancedConditions($address);
        }

        if ($this->address->isAdvancedConditions($address)) {
            $advConditions = $address->getExtensionAttributes()->getAdvancedConditions();

            switch ($this->getAttribute()) {
                case AddressInterface::BILLING_ADDRESS_COUNTRY:
                case \Magento\Quote\Api\Data\AddressInterface::KEY_COUNTRY_ID:
                    $attrValue = $advConditions->getBillingAddressCountry();
                    break;

                case AddressInterface::PAYMENT_METHOD:
                    $attrValue = $advConditions->getPaymentMethod();
                    break;

                case AddressInterface::SHIPPING_ADDRESS_LINE:
                    $attrValue = $this->getStreetFull($advConditions->getAddressLine());
                    break;

                case AddressInterface::CITY:
                    $attrValue = $advConditions->getCity();
                    break;

                case AddressInterface::CURRENCY:
                    $attrValue = $advConditions->getCurrency();
                    break;
            }
        }

        return $attrValue;
    }

    /**
     * @param $address
     *
     * @return mixed|string
     */
    private function getStreetFull($address)
    {
        return is_array($address) ? implode("\n", $address) : $address;
    }

    /**
     * @param \Magento\Quote\Model\Quote\Address $address
     */
    private function resolveAdvancedConditions(\Magento\Quote\Model\Quote\Address $address)
    {
        $quote = $address->getQuote();
        if ($extensionAttributes = $address->getExtensionAttributes()) {
            $addressModel = $this->addressFactory->create();
            $address = $quote->getShippingAddress();
            if (!$address) {
                $address = $quote->getBillingAddress();
            }
            $advancedConditionData = [
                'payment_method' => $quote->getPaymentMethod(),
                'city' => $address->getCity(),
                'shipping_address_line' => $address->getStreet(),
                'custom_attributes' => $address->getCustomAttributes(),
                'billing_address_country' => $quote->getBillingAddress()->getCountryId(),
                'currency' => $this->getCurrencyCode($quote)
            ];
            $addressModel->setData($advancedConditionData);

            $extensionAttributes->setAdvancedConditions($addressModel);
        }
    }

    private function getCurrencyCode(Quote $quote): string
    {
        if ($this->state->getAreaCode() === Area::AREA_ADMINHTML) {
            return $quote->getQuoteCurrencyCode() ?: $this->storeManager->getStore()->getCurrentCurrency()->getCode();
        }

        return $this->storeManager->getStore()->getCurrentCurrency()->getCode();
    }

    /**
     * Fix for klarna
     * @return string
     */
    public function getValueParsed()
    {
        $valueParsed = parent::getValueParsed();
        if ($this->getAttribute() == AddressInterface::PAYMENT_METHOD && $valueParsed == 'klarna_kp') {
            $valueParsed = 'klarna_';
        }
        return $valueParsed;
    }

    /**
     * Fix for vault methods: for example - braintree called braintree_cc_vault_1 instead of braintree_cc_vault
     * @return string
     */
    public function getOperatorForValidate()
    {
        $operator = parent::getOperatorForValidate();

        $operatorsForReplace = [
            '==' => '{}',
            '!=' => '!{}'
        ];

        $replaceOperator = false;
        $valueParsed = $this->getValueParsed();

        if (is_array($valueParsed)) {
            $valueParsed = implode(',', $valueParsed);
        }

        foreach (self::VALUE_PARTS_FOR_CONTAINS as $valuePart) {
            if (strpos($valueParsed, $valuePart) !== false) {
                $replaceOperator = true;
                break;
            }
        }

        if ($this->getAttribute() == AddressInterface::PAYMENT_METHOD
            && isset($operatorsForReplace[$operator])
            && $replaceOperator
        ) {
            $operator = $operatorsForReplace[$operator];
        }
        return $operator;
    }
}