Jquery script issue blocking country selection in WooCommerce

空扰寡人 提交于 2020-05-17 05:45:53

问题


I got a kind of strange issue in WooCommerce: I have find out that a Javascript file that is selecting country field from checkout and choosing at the same time some plugin right field. (Like: in checkout billing country is - Switzerland and payment gateway should get billing_country field info and show available payment options by that country).

Issue probably has been made by this script (tested it, as soon as .js code deleted - WooCommerce checkout field works perfectly, but then payment gateway doesn't getting info from billing_country field and doesn't know what to chose - so shows "other").

The jQuery Code:

jQuery( document ).ready(function($) {
    const COUNTRY_SELECTION = '.country_select';

    $(COUNTRY_SELECTION).on("click", function() {
        var id, countryBilling, countryOption;

        $('.payment-countries').hide('slow');
        countryBilling = $('#billing_country');
        countryOption = countryBilling.find('option');
        if (typeof countryBilling.val() === "undefined" || countryBilling.val() === null) {
            id = countryOption.eq(1).val();
        } else {
            id = countryBilling.val().toLowerCase();
        }

        idcheck = $('#' + id).attr('class');
        if(!idcheck){
            id = 'other';
            idcheck = $('#' + id).attr('class');
            if(!idcheck) {
                id = countryOption.eq(1).val();
            }
        }

        countryOption.attr("selected", false);
        $('#paysera_country').find('option[value=\"' + id + '\"]').attr("selected", true);
        $('#' + id).show('slow');
    });

    $(document).on('change', '#paysera_country' ,function(){
        $('.payment-countries').hide('slow');
        $('#' + $('#paysera_country').val()).show('slow');
    });

    $(document).on('change', 'input[name="payment[pay_type]"]' ,function(){
        $('.payment').removeClass('activePayseraPayment');
        $(this).parent().parent().addClass('activePayseraPayment');
    });
});

Same payment plugin payment methods classes (If I'm getting right: this is related with JS):

<?php
defined('ABSPATH') or exit;

if(!class_exists('Wc_Paysera_Html_Form')) {
    require_once 'class-wc-paysera-html-form.php';
}

/**
 * Build Paysera payment methods list
 */
class Wc_Paysera_Payment_Methods
{
    /**
     * Code used for empty fields
     */
    const EMPTY_CODE = '';

    /**
     * HTML NewLine break
     */
    const LINE_BREAK = '<div style="clear:both"><br /></div>';

    /**
     * Min. number of countries in list
     */
    const COUNTRY_SELECT_MIN = 1;

    /**
     * Default language if not in the list
     */
    const DEFAULT_LANG = 'en';

    /**
     * Default bool answer
     */
    const DEFAULT_ANSWER = false;

    /**
     * Default total
     */
    const DEFAULT_TOTAL = 0;

    /**
     * Default currency
     */
    const DEFAULT_CURRENCY = 'EUR';

    /**
     * Default project id
     */
    const DEFAULT_PROJECT_ID = 0;

    /**
     * @var int
     */
    protected $projectID;

    /**
     * @var string
     */
    protected $billingCountry;

    /**
     * @var string
     */
    protected $lang;

    /**
     * @var boolean
     */
    protected $displayList;

    /**
     * @var array
     */
    protected $countriesSelected;

    /**
     * @var boolean
     */
    protected $gridView;

    /**
     * @var string
     */
    protected $description;

    /**
     * @var double
     */
    protected $cartTotal;

    /**
     * @var string
     */
    protected $cartCurrency;

    /**
     * Available languages of payments
     */
    protected $availableLang;

    /**
     * @return self
     */
    static public function create()
    {
        return new self();
    }

    /**
     * Wc_Paysera_Payment_Methods constructor
     */
    public function __construct() {
        $this->projectID         = $this::DEFAULT_PROJECT_ID;
        $this->lang              = $this::DEFAULT_LANG;
        $this->billingCountry    = $this::EMPTY_CODE;
        $this->displayList       = $this::DEFAULT_ANSWER;
        $this->countriesSelected = $this::EMPTY_CODE;
        $this->gridView          = $this::DEFAULT_ANSWER;
        $this->description       = $this::DEFAULT_ANSWER;
        $this->cartTotal         = $this::DEFAULT_TOTAL;
        $this->cartCurrency      = $this::DEFAULT_CURRENCY;
    }

    /**
     * @param boolean [Optional] $print
     *
     * @return boolean|string
     */
    public function build($print = true)
    {
        $buildHtml = Wc_Paysera_Html_Form::create();

        if ($this->isDisplayList()) {
            $payseraCountries = $this->getPayseraCountries(
                $this->getProjectID(),
                $this->getCartTotal(),
                $this->getCartCurrency(),
                $this->listLang()
            );

            $countries = $this->getCountriesList($payseraCountries);

            if (count($countries) > $this::COUNTRY_SELECT_MIN) {
                $paymentsHtml = $buildHtml->buildCountriesList(
                    $countries,
                    $this->getBillingCountry()
                );
                $paymentsHtml .= $this::LINE_BREAK;
            } else {
                $paymentsHtml = $this::EMPTY_CODE;
            }

            $paymentsHtml .= $buildHtml->buildPaymentsList(
                $countries,
                $this->isGridView(),
                $this->getBillingCountry()
            );
            $paymentsHtml .= $this::LINE_BREAK;
        } else {
            $paymentsHtml = $this->getDescription();
        }

        if ($print) {
            print_r($paymentsHtml);
            return $print;
        } else {
            return $paymentsHtml;
        }
    }

    /**
     * @param integer $project
     * @param string  $currency
     * @param string  $lang
     *
     * @return WebToPay_PaymentMethodCountry[]
     */
    protected function getPayseraCountries($project, $amount, $currency, $lang)
    {
        $countries = WebToPay::getPaymentMethodList(
            $project,
            $currency
        )->filterForAmount(
            $amount,
            $currency
        )->setDefaultLanguage(
            $lang
        )->getCountries();

        return $countries;
    }

    /**
     * @param array $countries
     *
     * @return array
     */
    protected function getCountriesList($countries)
    {
        $countriesList = [];
        $showSelectedCountries = is_array($this->getCountriesSelected());
        $selectedCountriesCodes = $this->getCountriesSelected();

        foreach ($countries as $country) {
            $checkForCountry = true;
            if ($showSelectedCountries) {
                $checkForCountry = in_array($country->getCode(), $selectedCountriesCodes);
            }

            if ($checkForCountry) {
                $countriesList[] = [
                    'code'   => $country->getCode(),
                    'title'  => $country->getTitle(),
                    'groups' => $country->getGroups()
                ];
            }
        }

        return $countriesList;
    }

    /**
     * @return string
     */
    protected function listLang()
    {
        if (in_array($this->getLang(), $this->getAvailableLang())) {
            $listLang = $this->getLang();
        } else {
            $listLang = $this::DEFAULT_LANG;
        }

        return $listLang;
    }

    /**
     * @return string
     */
    public function getBillingCountry()
    {
        return $this->billingCountry;
    }


    /**
     * @param string $billingCountry
     *
     * @return self
     */
    public function setBillingCountry($billingCountry)
    {
        $this->billingCountry = $billingCountry;
        return $this;
    }

    /**
     * @return string
     */
    public function getLang()
    {
        return $this->lang;
    }

    /**
     * @param string $lang
     *
     * @return self
     */
    public function setLang($lang)
    {
        $this->lang = $lang;
        return $this;
    }

    /**
     * @return boolean
     */
    public function isDisplayList()
    {
        return $this->displayList;
    }

    /**
     * @param boolean $displayList
     *
     * @return self
     */
    public function setDisplayList($displayList)
    {
        $this->displayList = $displayList;
        return $this;
    }

    /**
     * @return array
     */
    public function getCountriesSelected()
    {
        return $this->countriesSelected;
    }

    /**
     * @param array $countriesSelected
     *
     * @return self
     */
    public function setCountriesSelected($countriesSelected)
    {
        $this->countriesSelected = $countriesSelected;
        return $this;
    }

    /**
     * @return boolean
     */
    public function isGridView()
    {
        return $this->gridView;
    }

    /**
     * @param boolean $gridView
     *
     * @return self
     */
    public function setGridView($gridView)
    {
        $this->gridView = $gridView;
        return $this;
    }

    /**
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * @param string $description
     *
     * @return self
     */
    public function setDescription($description)
    {
        $this->description = $description;
        return $this;
    }

    /**
     * @return double
     */
    public function getCartTotal()
    {
        return $this->cartTotal;
    }

    /**
     * @param double $cartTotal
     *
     * @return self
     */
    public function setCartTotal($cartTotal)
    {
        $this->cartTotal = $cartTotal;
        return $this;
    }

    /**
     * @return string
     */
    public function getCartCurrency()
    {
        return $this->cartCurrency;
    }

    /**
     * @param string $cartCurrency
     *
     * @return self
     */
    public function setCartCurrency($cartCurrency)
    {
        $this->cartCurrency = $cartCurrency;
        return $this;
    }

    /**
     * @return int
     */
    public function getProjectID()
    {
        return $this->projectID;
    }

    /**
     * @param int $projectID
     *
     * @return self
     */
    public function setProjectID($projectID)
    {
        $this->projectID = $projectID;
        return $this;
    }

    /**
     * @return array
     */
    public function getAvailableLang()
    {
        return $this->availableLang;
    }

    /**
     * @param array $availableLang
     *
     * @return self
     */
    public function setAvailableLang($availableLang)
    {
        $this->availableLang = $availableLang;
        return $this;
    }
}

HTML form code (which is included in payment-methods.php)

<?php
defined('ABSPATH') or exit;

/**
 * Build HTML code for Paysera Payments
 */
class Wc_Paysera_Html_Form
{
    /**
     * Code used for empty fields
     */
    const EMPTY_CODE     = '';

    /**
     * Selected field name
     */
    const FIELD_SELECTED = 'selected';

    /**
     * ID of other payments group
     */
    const CODE_OTHER     = 'other';

    /**
     * @return self
     */
    static public function create()
    {
        return new self();
    }

    /**
     * @param array  $countries
     * @param string $billingCountryCode
     *
     * @return string
     */
    public function buildCountriesList(
        $countries,
        $billingCountryCode
    ) {
        $defaultLangCode = $this->getDefaultLangCode(
            $countries,
            $billingCountryCode
        );

        $selectionField = '<select id="paysera_country" 
                                   class="payment-country-select" >';

        foreach ($countries as $country) {
            if ($country['code'] == $defaultLangCode) {
                $selected = $this::FIELD_SELECTED;
            } else {
                $selected = $this::EMPTY_CODE;
            }

            $selectionField .= '<option value="'
                . $country['code'] . '" '
                . $selected
                . '>';
            $selectionField .= $country['title'];
            $selectionField .= '</option>';
        }

        $selectionField     .= '</select>';

        return $selectionField;
    }

    /**
     * @param array   $countries
     * @param boolean $gridViewIsActive
     * @param string  $billingCountryCode
     *
     * @return string
     */
    public function buildPaymentsList(
        $countries,
        $gridViewIsActive,
        $billingCountryCode
    ) {
        $paymentsCode = $this::EMPTY_CODE;

        $defaultLangCode = $this->getDefaultLangCode(
            $countries,
            $billingCountryCode
        );

        foreach ($countries as $country) {
            $paymentsCode     .= '<div id="' . $country['code'] . '"';
            if ($gridViewIsActive) {
                $paymentsCode .= ' class="payment-countries paysera-payments grid"';
            } else {
                $paymentsCode .= ' class="payment-countries paysera-payments"';
            }
            $paymentsCode     .= ' style="display:';
            if (($country['code'] == $defaultLangCode)) {
                $paymentsCode .= 'block';
            } else {
                $paymentsCode .= 'none';
            }
            $paymentsCode     .= '">';

            $paymentsCode     .= $this->buildGroupList(
                $country['groups'],
                $country['code']
            );

            $paymentsCode     .= '</div>';
        }

        return $paymentsCode;
    }

    /**
     * @param array  $methods
     * @param string $countryCode
     *
     * @return string
     */
    protected function buildMethodsList(
        $methods,
        $countryCode
    ) {
        $paymentMethodCode = $this::EMPTY_CODE;
        foreach ($methods as $method) {
            $paymentMethodCode .= '<div id="' . $method->getKey() . '" class="payment">';

            $paymentMethodCode .= '<label>';
            $paymentMethodCode .= '<input class="rd_pay" ';
            $paymentMethodCode .= 'type="radio" ';
            $paymentMethodCode .= 'rel="r' . $countryCode . $method->getKey() . '" ';
            $paymentMethodCode .= 'name="payment[pay_type]" ';
            $paymentMethodCode .= 'value="' . $method->getKey() . '" /> ';

            $paymentMethodCode .= '<span class="paysera-text">';
            $paymentMethodCode .= $method->getTitle();
            $paymentMethodCode .= '</span>';

            $paymentMethodCode .= '<div class="paysera-image">';
            $paymentMethodCode .= '<img src="' . $method->getLogoUrl() . '" ';
            $paymentMethodCode .= 'alt="' . $method->getTitle() . '" />';
            $paymentMethodCode .= '</div>';

            $paymentMethodCode .= '</label>';
            $paymentMethodCode .= '</div>';
        }

        return $paymentMethodCode;
    }

    /**
     * @param array  $groups
     * @param string $countryCode
     *
     * @return string
     */
    protected function buildGroupList(
        $groups,
        $countryCode
    ) {
        $paymentGroupCode = $this::EMPTY_CODE;
        foreach ($groups as $group) {
            $paymentGroupCode .= '<div class="payment-group-wrapper">';

            $paymentGroupCode .= '<div class="payment-group-title">';
            $paymentGroupCode .= $group->getTitle();
            $paymentGroupCode .= '</div>';

            $paymentGroupCode .= $this->buildMethodsList(
                $group->getPaymentMethods(),
                $countryCode
            );
            $paymentGroupCode .= '</div>';
        }

        return $paymentGroupCode;
    }

    /**
     * @param array  $countries
     * @param string $countryCode
     *
     * @return string
     */
    protected function getDefaultLangCode(
        $countries,
        $countryCode
    ) {
        $countryCodes = [];

        foreach ($countries as $country) {
            $countryCodes[] = $country['code'];
        }

        if (in_array($countryCode, $countryCodes)) {
            $defaultLang = $countryCode;
        } elseif (in_array($this::CODE_OTHER, $countryCodes)) {
            $defaultLang = $this::CODE_OTHER;
        } else {
            $defaultLang = reset($countries)['code'];
        }

        return $defaultLang;
    }
}

Part of payment-gateway main class (pasting part which is related with billing_country)

 public function payment_fields()
    {
        if(!class_exists('Wc_Paysera_Payment_Methods')) {
            require_once 'class-wc-paysera-payment-methods.php';
        }

        $localLang = $this->getLocalLang($this::LANG_DELIMITER);
        $billingCountry = WC()->customer->get_billing_country();
        $cartTotal = round(WC()->cart->total * 100);
        $currency = get_woocommerce_currency();

        $htmlFields = Wc_Paysera_Payment_Methods::create()
            ->setProjectID($this->getProjectID())
            ->setLang($localLang)
            ->setBillingCountry(strtolower($billingCountry))
            ->setDisplayList($this->getPaymentType())
            ->setCountriesSelected($this->getCountriesSelected())
            ->setGridView($this->getGridView())
            ->setDescription($this->getDescription())
            ->setCartTotal($cartTotal)
            ->setCartCurrency($currency)
            ->setAvailableLang(array('lt', 'lv', 'ru', 'en', 'pl', 'bg', 'et'))
        ;

        $htmlFields->build(true);

        wp_enqueue_style(
            'custom-frontend-style',
            WCGatewayPayseraPluginUrl.$this::PAYSERA_STYLESHEET
        );

        wp_enqueue_script(
            'custom-frontend-script',
            WCGatewayPayseraPluginUrl.$this::PAYSERA_FRONTEND_ACTION_JS,
            array('jquery')
        );
    }

I've noticed, after this part of jQuery call - main issue appears:

wp_enqueue_script(
        'custom-frontend-script',
        WCGatewayPayseraPluginUrl.$this::PAYSERA_FRONTEND_ACTION_JS,
        array('jquery')
    );

If I'm removing this part - plugin doesn't recognize which country is selected in billing_country and doesn't know which country to show in payment gateway country list.

I tried some JS code checkers (few different) some of them show all good, some of them shows "undefined" jQuery variable and etc.

来源:https://stackoverflow.com/questions/61509094/jquery-script-issue-blocking-country-selection-in-woocommerce

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!