So überschreiben Sie Core Block, Model und Controller in Magento2

49

Ich stecke in Magento2 im Überschreiben von Kernmodellen, Blöcken und Controllern. Kann mir jemand dabei helfen?

Nehmen wir als Beispiel die Listen-Symbolleiste, in der ich eine neue Sortieroption namens Nach den beliebtesten sortieren hinzufügen muss . Wie füge ich es hinzu? Ich denke, dafür müssen wir die Option in der Blockebene und die Bedingung in der List.phpSammlungsebene hinzufügen .

Pradeep Kumar
quelle
1
Das Überschreiben von Kernklassen ist eine schlechte Idee und kann auf viele verschiedene Arten erfolgen. Können Sie Ihren konkreten Fall beschreiben?
KAndy
@KAndy: - Nehmen wir ein Beispiel für eine Listen-Symbolleiste, in der ich eine neue Sortieroption mit dem Namen sort by most popular hinzufügen muss. Ich hoffe, dass wir dazu eine Option in Blockebene und Bedingung in der List.php-Sammlungsebene hinzufügen müssen.
Pradeep Kumar
Sie müssen genau nach Execute Plugin auf \ Magento \ Catalog \ Block \ Product \ ProductList \ Toolbar :: getAvailableOrders dafür verwenden. Wenn andere Plugins verwenden, erhält der Kunde alle Bestellungen. Bei der Verwendung von Rewrites treten Modulkonflikte auf und ein Modul funktioniert nicht
KAndy,
@KAndy: - Können Sie bitte geben Beispielcode i immer bin nicht Plugin Ich brauche di.xml und Plugin - PHP - Code , wie es funktioniert und wie neue Spalte für die Admin - Raster hinzufügen Plugin verwendet ex bestellen Gitter mir bitte helfen ex Code in Plugin
Pradeep Kumar
@ Kandy: - Bitte teilen Sie ein beliebiges Plugin-Codebeispiel im Produktmodell mit. Fügen Sie einen Text mit Produktname () hinzu.
Pradeep Kumar

Antworten:

30

Magento2 gab ein sehr gutes Konzept namens Plugin

Wir können alles tun, was nach und vor der Kernfunktion passiert, und wir haben eine weitere Funktion, die sowohl vor als auch nach dem Code ausgeführt wird, der alle Informationen abdeckt

Erstellen Sie eine Datei di.xml in Mymodule / etc / di.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
   <type name="Magento\Catalog\Block\Product\View">
        <plugin name="inroduct-custom-module" type="Sugarcode\Test\Block\Plugin\Product\View" sortOrder="1"/>
    </type>
    <type name="Magento\Catalog\Model\Product">
        <plugin name="getname-test-module" type="Sugarcode\Test\Model\Plugin\Product" sortOrder="10"/>
    </type>
</config>

In diesem Beispiel habe ich das Produktmodell und den Produktansichtsblock genommen

Ich habe in der Produktansicht einen Block verwendet, bei dem es sich um eine Funktion handelt, die ein Präfix enthält. Stellen Sie dann sicher, dass 2 Parameter vorhanden sind. Als erstes wird angegeben, welches Objekt Sie verwenden. Closure, das alte Rückgabeinformationen beibehält

<?php
namespace Sugarcode\Test\Block\Plugin\Product;

class View 
{ 
    public function aroundGetProduct(\Magento\Catalog\Block\Product\View $subject, \Closure $proceed)
    {

        echo 'Do Some Logic Before <br>';
        $returnValue = $proceed(); // it get you old function return value
        //$name='#'.$returnValue->getName().'#';
        //$returnValue->setName($name);
        echo 'Do Some Logic  After <br>';
        return $returnValue; // if its object make sure it return same object which you addition data
    }


}

In Modell i wird davor und danach verwendet

<?php
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Sugarcode\Test\Model\Plugin;

class Product
{        
    public function beforeSetName(\Magento\Catalog\Model\Product $subject, $name)
    {
        return array('(' . $name . ')');
    }

     public function afterGetName(\Magento\Catalog\Model\Product $subject, $result)
    {
        return '|' . $result . '|';
    }

}

Auf diese Weise können wir alten Code behalten. Wenn also der Magento-Kerncode morgen aktualisiert wird, haben wir sowohl neuen aktualisierten Code als auch unsere benutzerdefinierte Logik. Wenn wir den Code direkt überschreiben, haben wir den neuen aktualisierten Code dieser Funktion oder Datei verloren :-)

http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html

Pradeep Kumar
quelle
Was ist, wenn Sie einer Klasse eine neue Methode hinzufügen möchten? Welche andere Option haben wir als die Präferenz?
MagePsycho
@MagePsycho: - Wenn Sie eine neue Funktion haben, bedeutet dies, dass Sie nicht mehr mit Magento arbeiten. Wenn sein Block einen neuen Block erzeugt und vom Kern aus erweitert, aber ohne Präferenz. Wenn ein Modell dann schreiben Sequenz ich hoffe, keine andere Möglichkeit
Pradeep Kumar
19

Endlich hab ich es !!!!
Ich folge den Schritten unten, um Block, Controller und Modell zu überschreiben. Ich habe ein Beispiel für das Produktmodell und die Produktansicht Block und Controller / Aktion anzeigen genommen

Erstellen Sie eine Datei mit dem Namen di.xml in Ihrer Datei /etc/di.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Model\Product" type="Sugarcode\Test\Model\Product" />
    <preference for="Magento\Catalog\Block\Product\View" type="Sugarcode\Test\Block\Product\View" />
    <preference for="Magento\Catalog\Controller\Product\View" type="Sugarcode\Test\Controller\Product\View" />
</config>

Dann habe ich Model File in /Model/Product.php erstellt

<?php
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Sugarcode\Test\Model;

class Product extends \Magento\Catalog\Model\Product
{
    /**
     * Get product name
     *
     * @return string
     * @codeCoverageIgnoreStart
     */
    public function getName()
    {
        return $this->_getData(self::NAME).'Local';
    }    
}

Dann habe ich eine Block-Datei in /Block/Product/View.php erstellt

<?php
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Sugarcode\Test\Block\Product;
/**
 * Product View block
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class View extends \Magento\Catalog\Block\Product\View
{


    /**
     * Retrieve current product model
     *
     * @return \Magento\Catalog\Model\Product
     */
    public function getProduct()
    {
       echo 'Local Block';
       if (!$this->_coreRegistry->registry('product') && $this->getProductId()) {
            $product = $this->productRepository->getById($this->getProductId());
            $this->_coreRegistry->register('product', $product);
        }
        return $this->_coreRegistry->registry('product');
    }


}

Erstellen Sie nun den Product View Controller /Controller/Product/View.php

<?php
/**
 *
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Sugarcode\Test\Controller\Product;

class View extends \Magento\Catalog\Controller\Product\View
{

    /**
     * Product view action
     *
     * @return \Magento\Framework\Controller\Result\Forward|\Magento\Framework\Controller\Result\Redirect
     */
    public function execute()
    {
        // Get initial data from request
       echo 'I Am in Local Controller';
       $categoryId = (int) $this->getRequest()->getParam('category', false);
        $productId = (int) $this->getRequest()->getParam('id');
        $specifyOptions = $this->getRequest()->getParam('options');

        if ($this->getRequest()->isPost() && $this->getRequest()->getParam(self::PARAM_NAME_URL_ENCODED)) {
            $product = $this->_initProduct();
            if (!$product) {
                return $this->noProductRedirect();
            }
            if ($specifyOptions) {
                $notice = $product->getTypeInstance()->getSpecifyOptionMessage();
                $this->messageManager->addNotice($notice);
            }
            if ($this->getRequest()->isAjax()) {
                $this->getResponse()->representJson(
                    $this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode([
                        'backUrl' => $this->_redirect->getRedirectUrl()
                    ])
                );
                return;
            }
            $resultRedirect = $this->resultRedirectFactory->create();
            $resultRedirect->setRefererOrBaseUrl();
            return $resultRedirect;
        }

        // Prepare helper and params
        $params = new \Magento\Framework\Object();
        $params->setCategoryId($categoryId);
        $params->setSpecifyOptions($specifyOptions);

        // Render page
        try {
            $page = $this->resultPageFactory->create(false, ['isIsolated' => true]);
            $this->viewHelper->prepareAndRender($page, $productId, $this, $params);
            return $page;
        } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
            return $this->noProductRedirect();
        } catch (\Exception $e) {
            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
            $resultForward = $this->resultForwardFactory->create();
            $resultForward->forward('noroute');
            return $resultForward;
        }
    }
}

Es funktioniert gut für mich :-)

Pradeep Kumar
quelle
6

Es gibt zwei Schritte, um die Block-, Modell- und Controller-Datei zu überschreiben

1) Präferenz in di.xml hinzufügen

2) Erstellen Sie eine Block-, Modell- und Steuerungsdatei in Ihrem Modul

Namensraum: Prinz

Modulname: Helloworld

Zum Beispiel, um den ListProduct-Block des Katalogprodukts zu überschreiben

1) Erstellen Sie die Datei di.xml im OrdnerPrince/Helloworld/etc

<?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="Magento\Catalog\Model\Product" type="Prince\Helloworld\Model\Rewrite\Catalog\Product" />
</config>

2) Erstellen Sie ListProduct.php im OrdnerPrince/Helloworld/Block/Rewrite/Product

<?php
    namespace Prince\Helloworld\Block\Rewrite\Product;

    class ListProduct extends \Magento\Catalog\Block\Product\ListProduct
    {
        public function _getProductCollection()
        {
            // Do your code here
        }
    }

Zum Beispiel, um das Katalogproduktmodell zu überschreiben.

1) Fügen Sie Präferenz in di.xml bei hinzuPrince/Helloworld/etc

<preference for="Magento\Catalog\Model\Product" type="Prince\Helloworld\Model\Rewrite\Catalog\Product" /> 

2) Erstellen Sie die Model-Datei Product.php im Ordner Prince/Helloworld/Model/Rewrite/Catalog

<?php
namespace Prince\Helloworld\Model\Rewrite\Catalog;

class Product extends \Magento\Catalog\Model\Product
{
    public function isSalable()
    {
        // Do your code here

        return parent::isSalable();
    }

}

Controller überschreiben

1) Fügen Sie Präferenz in di.xml bei hinzuPrince/Helloworld/etc

<preference for="Magento\Catalog\Controller\Product\View" type="Prince\Helloworld\Controller\Rewrite\Product\View" />

2) Erstellen Sie View.php im OrdnerPrince/Helloworld/Controller/Rewrite/Product

class View extends \Magento\Catalog\Controller\Product\View
{
    public function execute()
    {
        // Do your stuff here
        return parent::execute();
    }
}

Sie können andere Bausteine, Modelle und Steuerungen auf dieselbe Weise überschreiben.

Prinz Patel
quelle
Müssen wir nach Controller, Model & Block ein Rewrite hinzufügen? Bei mir hat das ohne umschreiben auch geklappt.
Sagar Sapkota
@sagarsapkota Ja, Sie können Controller, Model & Block direkt verwenden, ohne den Ordner neu zu schreiben.
Prinz Patel
4

Kleine Korrektur aber große nützlich, wir müssen keine n Anzahl von Dateien für jede Funktion im Plugin-Konzept erstellen. Für ein Modul ist eine Plugin-Datei ausreichend, damit Sie alle Module, alle Modelle und Blöcke sowie den Controller von Magento selbst erweitern können

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">

    <type name="Magento\Catalog\Block\Product\View">
        <plugin name="inroduct-custom-module" type="Sugarcode\Test\Model\Plugin\Product" sortOrder="1"/>
    </type>
    <type name="Magento\Catalog\Model\Product">
        <plugin name="getname-test-module" type="Sugarcode\Test\Model\Plugin\Product" sortOrder="10"/>
    </type>
    <type name="Magento\Catalog\Controller\Product\View">
        <plugin name="product-cont-test-module" type="Sugarcode\Test\Model\Plugin\Product" sortOrder="10"/>
    </type>
</config>

und im Plugin PHP-Datei

<?php
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Sugarcode\Test\Model\Plugin;

class Product
{        
    public function beforeSetName(\Magento\Catalog\Model\Product $subject, $name)
    {
        return array('(' . $name . ')');
    }

     public function afterGetName(\Magento\Catalog\Model\Product $subject, $result)
    {
        return '|' . $result . '|';
    } 
    public function aroundGetProduct(\Magento\Catalog\Block\Product\View $subject, \Closure $proceed)
    {

        echo 'Do Some Logic Before <br>';
        $returnValue = $proceed(); // it get you old function return value
        $name='#'.$returnValue->getName().'#';
        $returnValue->setName($name);
        echo 'Do Some Logic  After <br>';
        return $returnValue;// if its object make sure it return same object which you addition data
    }
    public function aroundExecute(\Magento\Catalog\Controller\Product\View $subject, \Closure $proceed)
    {
        echo 'I Am in Local Controller Before <br>';
        $returnValue = $proceed(); // it get you old function return value
        //$name='#'.$returnValue->getName().'#';
        //$returnValue->setName($name);
        echo 'I Am in Local Controller  After <br>';
        return $returnValue;// if its object make sure it return same object which you addition data
    }
}

Magento2 Rocks

Pradeep Kumar
quelle
Hallo Pradeep - Sie haben auf diese Frage drei Antworten geschrieben - es wahrscheinlich lohnen würde man sie in eine einzige Antwort kombiniert
Robbie Averill
Ich habe versucht , mit dieser Antwort, Its zeigt Fehler Uncaught Error: Call to undefined method Magento\\Backend\\Model\\View\\Result\\Redirect\\Interceptor::getEntityId()Hier \Clousure $proceedbekommen obejct ausMagento\\Backend\\Model\\View\\Result\\Redirect\\Interceptor
Praful Rajput
3

Sie können die Block- oder Controller-Klasse von magento in Ihrem benutzerdefinierten Block oder Controller direkt erweitern. Wenn Sie beispielsweise das PDF-Rechnungsmodell in meinem benutzerdefinierten Modul erweitern, um das Logo des PDF-Rechnungsgenerators zu ändern, können Sie Block oder Controller auf dieselbe Weise überschreiben um eine di.xml-Datei zu erstellen und keine Einstellungen vornehmen zu müssen.

class Invoice extends \Magento\Sales\Model\Order\Pdf\Invoice
{


    /**
     * Return PDF document
     *
     * @param array|Collection $invoices
     * @return \Zend_Pdf
     */
    public function getPdf($invoices = [])
    {

        $this->_beforeGetPdf();
        $this->_initRenderer('invoice');

        $pdf = new \Zend_Pdf();
        $this->_setPdf($pdf);
        $style = new \Zend_Pdf_Style();
        $this->_setFontBold($style, 10);

        foreach ($invoices as $invoice) {
            if ($invoice->getStoreId()) {
                $this->_localeResolver->emulate($invoice->getStoreId());
                $this->_storeManager->setCurrentStore($invoice->getStoreId());
            }
            $page = $this->newPage();
            $order = $invoice->getOrder();
            /* Add image */
            $this->insertCustomLogo($page, $invoice->getStore());
            /* Add address */
            $this->insertCustomAddress($page, $invoice->getStore());
            /* Add head */

            $this->insertOrder(
                $page,
                $order,
                $this->_scopeConfig->isSetFlag(
                    self::XML_PATH_SALES_PDF_INVOICE_PUT_ORDER_ID,
                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
                    $order->getStoreId()

                )
            );

            /* Add document text and number */
            $this->insertDocumentNumber($page, __('Invoice # ') . $invoice->getIncrementId());
            /* Add table */

            $this->_drawHeader($page);
            /* Add body */

            foreach ($invoice->getAllItems() as $item) {
                if ($item->getOrderItem()->getParentItem()) {
                    continue;
                }

                /* Draw item */
                $this->_drawItem($item, $page, $order);

                $page = end($pdf->pages);
            }

            /* Add totals */
            $this->insertTotals($page, $invoice);
            if ($invoice->getStoreId()) {
                $this->_localeResolver->revert();
            }
        }

        $this->_afterGetPdf();
        return $pdf;
    } 

   protected function insertCustomLogo(&$page, $store = null)
   {

     $image='demo.png'

     if ($image) {
        $imagePath = '/logo/' . $image;
        if ($this->_mediaDirectory->isFile($imagePath)) {
            $image = \Zend_Pdf_Image::imageWithPath($this->_mediaDirectory->getAbsolutePath($imagePath));
            $top = 830;
            //top border of the page
            $widthLimit = 270;
            //half of the page width
            $heightLimit = 270;
            //assuming the image is not a "skyscraper"
            $width = $image->getPixelWidth();
            $height = $image->getPixelHeight();

            //preserving aspect ratio (proportions)
            $ratio = $width / $height;
            if ($ratio > 1 && $width > $widthLimit) {
                $width = $widthLimit;
                $height = $width / $ratio;
            } elseif ($ratio < 1 && $height > $heightLimit) {
                $height = $heightLimit;
                $width = $height * $ratio;
            } elseif ($ratio == 1 && $height > $heightLimit) {
                $height = $heightLimit;
                $width = $widthLimit;
            }

            $y1 = $top - $height;
            $y2 = $top;
            $x1 = 25;
            $x2 = $x1 + $width;

            //coordinates after transformation are rounded by Zend
            $page->drawImage($image, $x1, $y1, $x2, $y2);

            $this->y = $y1 - 10;
        }
    }
}

}

Nidhi
quelle
Ist das wirklich der richtige Weg in M2?
Max
Der Trick in Magento 2 besteht darin, eine Präferenz in der zu definieren di.xml. Ich vermisse diesen wichtigen Teil in Ihrer Antwort ...
7ochem
3
  • Entwickler / Helloworld / registration.php

    
    \Magento\Framework\Component\ComponentRegistrar::register(
        \Magento\Framework\Component\ComponentRegistrar::MODULE,
        'Developer_Helloworld',
        __DIR__
    );
  • Entwickler / Helloworld / etc / module.xml

    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="Developer_Helloworld" setup_version="1.0.0">
        </module>
    </config>

  • Entwickler / Helloworld / etc / di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">    
    <preference for="Magento\Catalog\Controller\Product\View" type="Developer\Helloworld\Controller\Catalog\Product\View" />
</config>

  • Entwickler / Helloworld / Controller / Katalog / Produkt / View.php

    namespace Developer\Helloworld\Controller\Catalog\Product;
    class View extends \Magento\Catalog\Controller\Product\View
    {
        public function execute(){
            echo '__TEST__';exit;
        }
    }
hoffe das ist hilfreich
Shubham Khunt
quelle
2

Eine Aktionsklasse kann auf die gleiche Weise wie in Magento 1 umgeschrieben werden. In Magento 1 hatten wir beforeAttribute um Tags<routers>..<args><modules><... before="Mage_Catalog">Namespace_MyModule ..

In [module path]/etc/[nothing|adminhtml|frontend]/routes.xml:

<config>
    <router id="[admin|standard|]">
        <route id="catalog" frontName="catalog">
            <module name="Namespace_MyModule" before="Magento_Catalog"/>
        </route>
    </router>
</config>

Und die Actionklasse \Namespace\MyModule\Controller\[same path of action as in core module]\SameActionName.phpwoclass SameActionName.php extends \Magento\Catalog\...\SameActionName

Dies ist das Magento_Catalog-Modul, Magento\Catalog\etc\adminhtml\routes.xmldas eine neue Route in admin registriert:

<router id="admin">
    <route id="catalog" frontName="catalog">
        <module name="Magento_Catalog" before="Magento_Backend" />
    </route>
</router>

http://devdocs.magento.com/guides/v2.1/extension-dev-guide/routing.html

Um die Controller-Aktion in einer Route durch eine benutzerdefinierte zu ersetzen, fügen Sie die benutzerdefinierte Controller-Klasse vor dem ursprünglichen Controller hinzu.

Der benutzerdefinierte Controller und die Aktion sollten dieselben Namen wie die ursprünglichen haben.

Das System verarbeitet den benutzerdefinierten Controller vor dem Original, während eine Route dieselbe bleibt.

Wenn Sie eine Route und einen Entwurf zurücksetzen müssen, leiten Sie die Anforderungsverarbeitung an eine andere Route weiter:

$this->_forward('other/controller/action')

Um die Controller-Aktion zu entfernen, leiten Sie sie an noroute weiter, zum Beispiel in app / code / Company / SomeExtension / Controller / Account.php:

Ich glaube nicht, dass Einstellungen oder Plugins für Action-Klassen eine gute Idee für Magento-Best Practices sind. Und vielleicht steckt noch mehr dahinter.

obskur
quelle
0

Um eine Klasse direkt zu überschreiben, müssen Sie Einstellungen verwenden. Weitere Informationen zu dev docs finden Sie unter: https://devdocs.magento.com/guides/v2.0/extension-dev-guide/build/di-xml-file.html#abstraction-implementation-mappings
Für die meiste Zeit verwenden wir Interceptors (Plugins), da dies die beste Vorgehensweise ist, um einen Teil Ihrer Änderungen neu zu schreiben oder hinzuzufügen. Siehe dev docs: https://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html

Indem Sie Ihr Beispiel für das Sortieren von Listenelementen beibehalten, indem Sie die neue Sortierreihenfolge "Am beliebtesten" hinzufügen, die ich Ihnen zur Verfügung stelle die beste Art, das Ergebnis zu verändern.
Erstellen Sie ein benutzerdefiniertes Modul und erstellen Sie die Konfiguration app/code/Arsal/SortOption/etc/module.xml:

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
   <module name="Arsal_SortOption" setup_version="1.0.0" />
</config> 

Registrieren Sie jetzt Ihr Modul app/code/Arsal/SortOption/registration.php:

<?php
 \Magento\Framework\Component\ComponentRegistrar::register(
     \Magento\Framework\Component\ComponentRegistrar::MODULE,
     'Arsal_SortOption',
      __DIR__
 );

Jetzt erstelle di.xml app/code/Arsal/SortOption/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">
    <type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
       <plugin name="toolbar_instance" type="Arsal\SortOption\Block\Product\ProductList\Toolbar" />
    </type>
</config>

Erstellen Sie nun eine Blockklasse Arsal\SortOption\Block\Product\ProductListToolbar.php:

<?php
namespace Arsal\SortOption\Block\Product\ProductList;

class Toolbar {

    public function afterGetAvailableOrders (
        \Magento\Catalog\Block\Product\ProductList\Toolbar $subject, $result
    ) {
        $result ['most_popular'] = 'most popular';
        return $result;
    }

Dadurch wird der Liste der Sortierreihenfolgen eine benutzerdefinierte Sortierreihenfolge hinzugefügt. Bildbeschreibung hier eingeben }

Arsalan
quelle