Magento 2 Tambahkan daftar dropdown ke metode pengiriman

16

Saya mengembangkan metode pengiriman untuk beberapa perusahaan logistik. Perusahaan ini memiliki banyak kantor di mana pelanggan dapat memperoleh pesanannya. Saya bisa mendapatkan daftar kantor dengan сity di API tetapi saya tidak tahu bagaimana sebaiknya mewakili langkah ini?

Untuk saat ini saya baru saja menetapkan baru \Magento\Quote\Model\Quote\Address\RateResult\Method untuk setiap kantor di kota, di kota besar itu menghitung> 100 dan saya pikir itu tidak terlalu baik untuk mengatur 100 baris di checkout.

Ini akan menjadi modul publik untuk desain checkout yang berbeda, jadi bagaimana saya bisa membuat dekat metode pengiriman saya memilih beberapa daftar dropdown dengan daftar kantor dan menetapkan harga dan metode setelah pengguna memilih satu.

Jamess Moriarty
sumber
@Zefiryn Saya menemukan posting ini sangat menarik, tetapi saya punya pertanyaan, jika saya harus menunjukkan di pilih bukan kantor tetapi toko-toko yang ada di dalam modul Amasty, bagaimana saya akan melakukan bagian kedua dari posting Anda? Maksud saya: di mana tempat saya memanggil helper Amasty untuk mengisi komponen xml "vendor_carrier_form"? Terima kasih
maverickk89
Jika Anda memiliki pertanyaan baru, silakan tanyakan dengan mengklik tombol Ajukan Pertanyaan . Sertakan tautan ke pertanyaan ini jika itu membantu memberikan konteks. - Dari Ulasan
Jai
ini bukan pertanyaan baru tetapi variasi cara yang digunakan oleh Zefiryn ... karena saya menggunakan bagian pertama dari pos tersebut
maverickk89

Jawaban:

17

Checkout Magento tidak mendukung segala bentuk formulir untuk data tambahan metode pengiriman. Tetapi ia menyediakan shippingAdditionalblokir dalam checkout yang dapat digunakan untuk ini. Solusi berikut akan berfungsi untuk checkout magento standar.

Pertama mari kita siapkan wadah kita di mana kita bisa meletakkan beberapa formulir. Untuk melakukan ini, buat file diview/frontend/layout/checkout_index_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="steps" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="shipping-step" xsi:type="array">
                                            <item name="children" xsi:type="array">
                                                <item name="shippingAddress" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="shippingAdditional" xsi:type="array">
                                                            <item name="component" xsi:type="string">uiComponent</item>
                                                            <item name="displayArea" xsi:type="string">shippingAdditional</item>
                                                            <item name="children" xsi:type="array">
                                                                <item name="vendor_carrier_form" xsi:type="array">
                                                                    <item name="component" xsi:type="string">Vendor_Module/js/view/checkout/shipping/form</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

Sekarang buat file di Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.jsmana akan membuat templat knockout. Isinya terlihat seperti ini

define([
    'jquery',
    'ko',
    'uiComponent',
    'Magento_Checkout/js/model/quote',
    'Magento_Checkout/js/model/shipping-service',
    'Vendor_Module/js/view/checkout/shipping/office-service',
    'mage/translate',
], function ($, ko, Component, quote, shippingService, officeService, t) {
    'use strict';

    return Component.extend({
        defaults: {
            template: 'Vendor_Module/checkout/shipping/form'
        },

        initialize: function (config) {
            this.offices = ko.observableArray();
            this.selectedOffice = ko.observable();
            this._super();
        },

        initObservable: function () {
            this._super();

            this.showOfficeSelection = ko.computed(function() {
                return this.ofices().length != 0
            }, this);

            this.selectedMethod = ko.computed(function() {
                var method = quote.shippingMethod();
                var selectedMethod = method != null ? method.carrier_code + '_' + method.method_code : null;
                return selectedMethod;
            }, this);

            quote.shippingMethod.subscribe(function(method) {
                var selectedMethod = method != null ? method.carrier_code + '_' + method.method_code : null;
                if (selectedMethod == 'carrier_method') {
                    this.reloadOffices();
                }
            }, this);

            this.selectedOffice.subscribe(function(office) {
                if (quote.shippingAddress().extensionAttributes == undefined) {
                    quote.shippingAddress().extensionAttributes = {};
                }
                quote.shippingAddress().extensionAttributes.carrier_office = office;
            });


            return this;
        },

        setOfficeList: function(list) {
            this.offices(list);
        },

        reloadOffices: function() {
            officeService.getOfficeList(quote.shippingAddress(), this);
            var defaultOffice = this.offices()[0];
            if (defaultOffice) {
                this.selectedOffice(defaultOffice);
            }
        },

        getOffice: function() {
            var office;
            if (this.selectedOffice()) {
                for (var i in this.offices()) {
                    var m = this.offices()[i];
                    if (m.name == this.selectedOffice()) {
                        office = m;
                    }
                }
            }
            else {
                office = this.offices()[0];
            }

            return office;
        },

        initSelector: function() {
            var startOffice = this.getOffice();
        }
    });
});

File ini menggunakan templat knockout yang harus ditempatkan Vendor/Module/view/frontend/web/template/checkout/shipping/form.html

<div id="carrier-office-list-wrapper" data-bind="visible: selectedMethod() == 'carrier_method'">
    <p data-bind="visible: !showOfficeSelection(), i18n: 'Please provide postcode to see nearest offices'"></p>
    <div data-bind="visible: showOfficeSelection()">
        <p>
            <span data-bind="i18n: 'Select pickup office.'"></span>
        </p>
        <select id="carrier-office-list" data-bind="options: offices(),
                                            value: selectedOffice,
                                            optionsValue: 'name',
                                            optionsText: function(item){return item.location + ' (' + item.name +')';}">
        </select>
    </div>
</div>

Kami sekarang memiliki bidang pilih yang akan terlihat ketika metode kami (ditentukan oleh kodenya) akan dipilih dalam tabel metode pengiriman. Saatnya mengisinya dengan beberapa opsi. Karena nilai tergantung pada alamat, cara terbaik adalah membuat titik akhir yang akan menyediakan opsi yang tersedia. DiVendor/Module/etc/webapi.xml

<?xml version="1.0"?>

<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">

    <!-- Managing Office List on Checkout page -->
    <route url="/V1/module/get-office-list/:postcode/:city" method="GET">
        <service class="Vendor\Module\Api\OfficeManagementInterface" method="fetchOffices"/>
        <resources>
            <resource ref="anonymous" />
        </resources>
    </route>
</routes>

Sekarang tentukan antarmuka Vendor/Module/Api/OfficeManagementInterface.phpsebagai

namespace Vendor\Module\Api;

interface OfficeManagementInterface
{

    /**
     * Find offices for the customer
     *
     * @param string $postcode
     * @param string $city
     * @return \Vendor\Module\Api\Data\OfficeInterface[]
     */
    public function fetchOffices($postcode, $city);
}

Tentukan antarmuka untuk data kantor di Vendor\Module\Api\Data\OfficeInterface.php. Antarmuka ini akan digunakan oleh modul webapi untuk memfilter data untuk output sehingga Anda perlu mendefinisikan apa pun yang perlu Anda tambahkan ke dalam respons.

namespace Vendor\Module\Api\Data;

/**
 * Office Interface
 */
interface OfficeInterface
{
    /**
     * @return string
     */
    public function getName();

    /**
     * @return string
     */
    public function getLocation();
}

Saatnya kelas aktual. Mulailah dengan membuat preferensi untuk semua antarmuka diVendor/Module/etc/di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Vendor\Module\Api\OfficeManagementInterface" type="Vendor\Module\Model\OfficeManagement" />
    <preference for="Vendor\Module\Api\Data\OfficeInterface" type="Vendor\Module\Model\Office" />
</config>

Sekarang buat Vendor\Module\Model\OfficeManagement.phpkelas yang benar-benar akan melakukan logika pengambilan data.

namespace Vednor\Module\Model;

use Vednor\Module\Api\OfficeManagementInterface;
use Vednor\Module\Api\Data\OfficeInterfaceFactory;

class OfficeManagement implements OfficeManagementInterface
{
    protected $officeFactory;

    /**
     * OfficeManagement constructor.
     * @param OfficeInterfaceFactory $officeInterfaceFactory
     */
    public function __construct(OfficeInterfaceFactory $officeInterfaceFactory)
    {
        $this->officeFactory = $officeInterfaceFactory;
    }

    /**
     * Get offices for the given postcode and city
     *
     * @param string $postcode
     * @param string $limit
     * @return \Vendor\Module\Api\Data\OfficeInterface[]
     */
    public function fetchOffices($postcode, $city)
    {
        $result = [];
        for($i = 0, $i < 4;$i++) {
            $office = $this->officeFactory->create();
            $office->setName("Office {$i}");
            $office->setLocation("Address {$i}");
            $result[] = $office;
        }

        return $result;
    }
}

Dan akhirnya kelas OfficeInterfacemasukVendor/Module/Model/Office.php

namespace Vendor\Module\Model;

use Magento\Framework\DataObject;
use Vendor\Module\Api\Data\OfficeInterface;

class Office extends DataObject implements OfficeInterface
{
    /**
     * @return string
     */
    public function getName()
    {
        return (string)$this->_getData('name');
    }

    /**
     * @return string
     */
    public function getLocation()
    {
        return (string)$this->_getData('location');
    }
}

Ini akan menampilkan bidang pilih dan memperbaruinya ketika alamat diubah. Tapi kita kehilangan satu elemen lagi untuk manipulasi frontend. Kita perlu membuat fungsi yang akan memanggil titik akhir. Panggilan untuk itu sudah termasuk dalam Vendor/Module/view/frontend/web/js/view/checkout/shipping/form.jsdan itu Vendor_Module/js/view/checkout/shipping/office-servicekelas yang harus pergi Vendor/Module/view/frontend/web/js/view/checkout/shipping/office-service.jsdengan kode berikut:

define(
    [
        'Vendor_Module/js/view/checkout/shipping/model/resource-url-manager',
        'Magento_Checkout/js/model/quote',
        'Magento_Customer/js/model/customer',
        'mage/storage',
        'Magento_Checkout/js/model/shipping-service',
        'Vendor_Module/js/view/checkout/shipping/model/office-registry',
        'Magento_Checkout/js/model/error-processor'
    ],
    function (resourceUrlManager, quote, customer, storage, shippingService, officeRegistry, errorProcessor) {
        'use strict';

        return {
            /**
             * Get nearest machine list for specified address
             * @param {Object} address
             */
            getOfficeList: function (address, form) {
                shippingService.isLoading(true);
                var cacheKey = address.getCacheKey(),
                    cache = officeRegistry.get(cacheKey),
                    serviceUrl = resourceUrlManager.getUrlForOfficeList(quote);

                if (cache) {
                    form.setOfficeList(cache);
                    shippingService.isLoading(false);
                } else {
                    storage.get(
                        serviceUrl, false
                    ).done(
                        function (result) {
                            officeRegistry.set(cacheKey, result);
                            form.setOfficeList(result);
                        }
                    ).fail(
                        function (response) {
                            errorProcessor.process(response);
                        }
                    ).always(
                        function () {
                            shippingService.isLoading(false);
                        }
                    );
                }
            }
        };
    }
);

Ini menggunakan 2 file js lebih. Vendor_Module/js/view/checkout/shipping/model/resource-url-managermembuat url ke titik akhir dan cukup sederhana

define(
    [
        'Magento_Customer/js/model/customer',
        'Magento_Checkout/js/model/quote',
        'Magento_Checkout/js/model/url-builder',
        'mageUtils'
    ],
    function(customer, quote, urlBuilder, utils) {
        "use strict";
        return {
            getUrlForOfficeList: function(quote, limit) {
                var params = {postcode: quote.shippingAddress().postcode, city: quote.shippingAddress().city};
                var urls = {
                    'default': '/module/get-office-list/:postcode/:city'
                };
                return this.getUrl(urls, params);
            },

            /** Get url for service */
            getUrl: function(urls, urlParams) {
                var url;

                if (utils.isEmpty(urls)) {
                    return 'Provided service call does not exist.';
                }

                if (!utils.isEmpty(urls['default'])) {
                    url = urls['default'];
                } else {
                    url = urls[this.getCheckoutMethod()];
                }
                return urlBuilder.createUrl(url, urlParams);
            },

            getCheckoutMethod: function() {
                return customer.isLoggedIn() ? 'customer' : 'guest';
            }
        };
    }
);

Vendor_Module/js/view/checkout/shipping/model/office-registryadalah cara menjaga hasil penyimpanan lokal. Kodenya adalah:

define(
    [],
    function() {
        "use strict";
        var cache = [];
        return {
            get: function(addressKey) {
                if (cache[addressKey]) {
                    return cache[addressKey];
                }
                return false;
            },
            set: function(addressKey, data) {
                cache[addressKey] = data;
            }
        };
    }
);

Ok, jadi kita semua harus bekerja di frontend. Tapi sekarang ada masalah lain untuk diselesaikan. Karena checkout tidak tahu apa-apa tentang formulir ini, ia tidak akan mengirim hasil seleksi ke backend. Untuk mewujudkannya, kita perlu menggunakan extension_attributesfitur. Ini adalah cara di magento2 untuk menginformasikan sistem bahwa beberapa data tambahan diharapkan ada dalam panggilan lainnya. Tanpanya magento akan menyaring data itu dan mereka tidak akan pernah mencapai kode.

Jadi yang pertama di Vendor/Module/etc/extension_attributes.xmldefinisikan:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Quote\Api\Data\AddressInterface">
        <attribute code="carrier_office" type="string"/>
    </extension_attributes>
</config>

Nilai ini sudah dimasukkan dalam permintaan form.jsmenurut this.selectedOffice.subscribe()definisi. Jadi konfigurasi di atas hanya akan melewatinya di pintu masuk. Untuk mengambilnya di dalam kode, buat plugin diVendor/Module/etc/di.xml

<type name="Magento\Quote\Model\Quote\Address">
    <plugin name="inpost-address" type="Vendor\Module\Quote\AddressPlugin" sortOrder="1" disabled="false"/>
</type>

Di dalam kelas itu

namespace Vendor\Module\Plugin\Quote;

use Magento\Quote\Model\Quote\Address;
use Vendor\Module\Model\Carrier;

class AddressPlugin
{
    /**
     * Hook into setShippingMethod.
     * As this is magic function processed by __call method we need to hook around __call
     * to get the name of the called method. after__call does not provide this information.
     *
     * @param Address $subject
     * @param callable $proceed
     * @param string $method
     * @param mixed $vars
     * @return Address
     */
    public function around__call($subject, $proceed, $method, $vars)
    {
        $result = $proceed($method, $vars);
        if ($method == 'setShippingMethod'
            && $vars[0] == Carrier::CARRIER_CODE.'_'.Carrier::METHOD_CODE
            && $subject->getExtensionAttributes()
            && $subject->getExtensionAttributes()->getCarrierOffice()
        ) {
            $subject->setCarrierOffice($subject->getExtensionAttributes()->getCarrierOffice());
        }
        elseif (
            $method == 'setShippingMethod'
            && $vars[0] != Carrier::CARRIER_CODE.'_'.Carrier::METHOD_CODE
        ) {
            //reset office when changing shipping method
            $subject->getCarrierOffice(null);
        }
        return $result;
    }
}

Tentu saja di mana Anda akan menghemat nilai sepenuhnya tergantung pada kebutuhan Anda. Kode di atas akan membutuhkan pembuatan kolom tambahan carrier_officedi quote_addressdan sales_addresstabel dan acara (dalam Vendor/Module/etc/events.xml)

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_model_service_quote_submit_before">
        <observer name="copy_carrier_office" instance="Vendor\Module\Observer\Model\Order" />
    </event>
</config>

Itu akan menyalin data yang disimpan dalam alamat penawaran ke alamat penjualan.

Saya menulis ini untuk modul saya untuk carrier Polandia InPost jadi saya mengubah beberapa nama yang mungkin memecahkan kode tapi saya harap ini akan memberi Anda apa yang Anda butuhkan.

[EDIT]

Model pembawa ditanyakan oleh @sangan

namespace Vendor\Module\Model;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Phrase;
use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Carrier\AbstractCarrier;
use Magento\Shipping\Model\Carrier\CarrierInterface;
use Magento\Shipping\Model\Simplexml\ElementFactory;

class Carrier extends AbstractCarrier implements CarrierInterface
{
    const CARRIER_CODE = 'mycarier';

    const METHOD_CODE = 'mymethod';

    /** @var string */
    protected $_code = self::CARRIER_CODE;

    /** @var bool */
    protected $_isFixed = true;

    /**
     * Prepare stores to show on frontend
     *
     * @param RateRequest $request
     * @return \Magento\Framework\DataObject|bool|null
     */
    public function collectRates(RateRequest $request)
    {
        if (!$this->getConfigData('active')) {
            return false;
        }

        /** @var \Magento\Shipping\Model\Rate\Result $result */
        $result = $this->_rateFactory->create();

        /** @var \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
        $method = $this->_rateMethodFactory->create();
        $method->setCarrier($this->_code);
        $method->setCarrierTitle($this->getConfigData('title'));

        $price = $this->getFinalPriceWithHandlingFee(0);
        $method->setMethod(self::METHOD_CODE);
        $method->setMethodTitle(new Phrase('MyMethod'));
        $method->setPrice($price);
        $method->setCost($price);
        $result->append($method);;

        return $result;
    }


    /**
     * @return array
     */
    public function getAllowedMethods()
    {
        $methods = [
            'mymethod' => new Phrase('MyMethod')
        ];
        return $methods;
    }
}
Zefiryn
sumber
Terima kasih atas balasan Anda yang diperpanjang, saya akan mencoba menyelesaikan masalah saya menggunakan metode Anda dan akan membalas dengan hasilnya hari ini.
Siarhey Uchukhlebau
@Zefiryn Saya telah membuat metode pengiriman kustom, di bawahnya akan ditampilkan dropdown yang memiliki nomor akun pengiriman pelanggan (ada atribut pelanggan kustom dibuat) jadi jika saya harus menampilkan dropdown ini berapa persen dari kode Anda akan membantu? Apa yang harus saya ambil dari kode yang Anda berikan?
Shireen N
@shireen saya akan mengatakan sekitar 70%. Anda perlu mengubah bagian di mana ia mengambil mesin ke nomor akun. Jadi definisi api akan sedikit berbeda dan menjadi bagian darinya
Zefiryn
Saya telah mencoba modul ini ... tetapi tidak menunjukkan perubahan, jadi silakan berbagi module.if yang berfungsi
sangan
setelah menambahkan modul yang berhasil .. di checkout ajax memuat terus menerus .. dalam konsol error yang menunjukkan seperti di bawah ini: need.js: 166 Uncaught Error: Script error untuk: Vendor_Module / js / view / checkout / pengiriman / model / office-registry. requireejs.org/docs/errors.html#scripterror
sangan
2

Saya menambahkan jawaban baru untuk memperluas apa yang sudah disediakan sebelumnya tetapi tanpa merusaknya.

Ini adalah rute yang QuoteAddressPluginmenghubungkan ke:

1. Magento\Checkout\Api\ShippingInformationManagementInterface::saveAddressInformation()
2. Magento\Quote\Model\QuoteRepository::save() 
3. Magento\Quote\Model\QuoteRepository\SaveHandler::save() 
4. Magento\Quote\Model\QuoteRepository\SaveHandler::processShippingAssignment() 
5. Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister::save()
6. Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentProcessor::save()
7. Magento\Quote\Model\Quote\ShippingAssignment\ShippingProcessor::save()
8. Magento\Quote\Model\ShippingMethodManagement::apply() 

Metode terakhir adalah panggilan Magento\Quote\Model\Quote\Address::setShippingMethod()yang sebenarnya adalah panggilan Magento\Quote\Model\Quote\Address::__call()yang saya gunakan. Saat ini saya menemukan tempat yang lebih baik untuk plugin, itu adalah Magento\Quote\Model\ShippingAssignment::setShipping()metode. Jadi bagian plugin dapat ditulis ulang menjadi:

<type name="Magento\Quote\Model\ShippingAssignment">
    <plugin name="carrier-office-plugin" type="Vendor\Module\Plugin\Quote\ShippingAssignmentPlugin" sortOrder="1" disabled="false"/>
</type>

dan plugin itu sendiri:

namespace Vednor\Module\Plugin\Quote;

use Magento\Quote\Api\Data\AddressInterface;
use Magento\Quote\Api\Data\ShippingInterface;
use Magento\Quote\Model\ShippingAssignment;
use Vendor\Module\Model\Carrier;

/**
 * ShippingAssignmentPlugin
 */
class ShippingAssignmentPlugin
{
    /**
     * Hook into setShipping.
     *
     * @param ShippingAssignment $subject
     * @param ShippingInterface $value
     * @return Address
     */
    public function beforeSetShipping($subject, ShippingInterface $value)
    {
        $method = $value->getMethod();
        /** @var AddressInterface $address */
        $address = $value->getAddress();
        if ($method === Carrier::CARRIER_CODE.'_'.Carrier::METHOD_CODE
            && $address->getExtensionAttributes()
            && $address->getExtensionAttributes()->getCarrierOffice()
        ) {
            $address->setCarrierOffice($address->getExtensionAttributes()->getCarrierOffice());
        }
        elseif ($method !== Carrier::CARRIER_CODE.'_'.Carrier::METHOD_CODE) {
            //reset inpost machine when changing shipping method
            $address->setCarrierOffice(null);
        }
        return [$value];
    }
}
Zefiryn
sumber
1

@Zefiryn, saya menemukan masalah dengan: quote.shippingAddress().extensionAttributes.carrier_office = office;

Ketika saya masuk ke checkout pertama kali (jendela pribadi baru) sebagai tamu (tetapi hal yang sama terjadi dengan klien terdaftar) kantor atribut tidak disimpan ke dalam basis data setelah "Next" pertama. Meskipun di konsol saya melihat output yang benar untuk:console.log(quote.shippingAddress().extensionAttributes.carrier_office);

Ketika saya kembali ke halaman checkout pertama dan memilih kantor lagi kemudian disimpan. Apa yang bisa menjadi alasan perilaku ini?

Saya mencoba menggunakan: address.trigger_reload = new Date().getTime(); rateRegistry.set(address.getKey(), null); rateRegistry.set(address.getCacheKey(), null); quote.shippingAddress(address);

tetapi tanpa hasil ...

pengguna2089098
sumber
0

@Zefiryn, Dapatkah Anda menjelaskan dalam beberapa kata bagaimana cara kerja plugin Anda di atas? Saya sedikit bingung karena saya tahu metode __call dijalankan jika kita mencoba menjalankan metode yang tidak ada untuk objek tertentu. Tampaknya benar karena dalam aplikasi / kode / Magento / Kutipan / Model / Kutipan / Address.php Saya tidak melihat metode seperti itu - hanya komentar:

/** * Sales Quote address model ... * @method Address setShippingMethod(string $value)

  1. Mengapa Anda menggunakan sekitar intersepsi ketika tidak ada implementasi metode?
  2. Selanjutnya saya melihat $subject->setInpostMachinedan $subject->getCarrierOffice(null);Apakah itu berarti bahwa metode plugin di atas akan dieksekusi lagi karena tidak ada metode setInpostMachine () dan getCarrierOffice () di Adress Class? Sepertinya loop ke saya.
  3. Dari mana Magento mengeksekusi setShippingMethod()? Bagaimana biasanya metode ini digunakan? Saya tidak dapat menemukan intersepsi simillar dalam kode Magento.
pengguna2089098
sumber
Ok, jadi saya menyiapkan jawaban berdasarkan modul yang saya tulis untuk pengujian, menggunakan bidang inpost_machine, jadi yang ini tidak diubah dengan benar menjadi carrier_office di tempat ini. Kedua, pada saat saya sedang mengembangkan modul ini saya belum menemukan tempat di mana saya bisa mendapatkan operator dan alamat yang dipilih dengan atribut ekstensi yang dikirim kecuali setShippingMethodmemanggil AddressInterfaceobjek dan karena tidak ada metode seperti itu maka saya harus menggunakan around__call untuk melihat apakah setShippingMethoddipanggil atau bidang sihir lainnya. Saat ini saya telah menemukan tempat yang lebih baik dan saya akan mempostingnya di balasan baru.
Zefiryn