Magento 2: yeniden yazma denetleyicisi


17

Magento 2'de bir denetleyiciyi (aslında bir eylem) nasıl yeniden yazabilirim?
Denedim, burada talimat verildiği gibi:

Namespace_ModuleBir di.xmldosya ile adlandırılan kendi modülüm var , bu dikkate alınır, çünkü aynı sistem modellerde ve bloklarda çalışır
Örnek:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <!-- this one doesn't work for a controller action -->
    <preference for="Magento\Backend\Controller\Adminhtml\Dashboard\RefreshStatistics" 
         type="Namespace\Module\Controller\Adminhtml\Dashboard\RefreshStatistics" />
    <!-- this one works for a model -->
    <preference for="Magento\Customer\Model\Resource\GroupRepository" 
        type="Namespace\Module\Model\Resource\Customer\GroupRepository" />
     <!-- this one works also for a block -->
    <preference for="Magento\Backend\Block\Dashboard" 
        type="Namespace\Module\Block\Backend\Dashboard" />
</config>

Gösterge tablosu yenileme istatistiklerini kendi işlemimle değiştirmeye çalışıyorum. Yukarıdaki gibi yapmak execute, orijinal sınıftaki yöntem hala benim değil, çağrılır.
var/cacheve var/generationtemizlendi.



1
@TimHallman. Teşekkürler, ama sadece bunun için bir yönlendirici yazmak istemiyorum. Eminim bunu yapmanın daha temiz bir yolu vardır.
Marius

Yanıtlar:


16

Buldum.
Aslında soruda gönderdiğim şey, bir denetleyiciyi yeniden yazmanın doğru yoludur.

<preference for="Magento\Backend\Controller\Adminhtml\Dashboard\RefreshStatistics" 
     type="Namespace\Module\Controller\Adminhtml\Dashboard\RefreshStatistics" />

güzel çalışıyor.
Benim için sorun buydu. Bazı modülleri Magento2'yi kaldırdığımı ve bunların arasında modül olduğunu belirtmeyi unuttum Reports. Soruda belirtmedim çünkü önemli olduğunu düşünmedim.
Denetleyicileri (ve belki de diğer sınıfları) yeniden yazmak için yukarıdaki yöntem, değiştirmeye çalıştığınız tüm sınıflar ve tüm üst sınıfları da varsa çalışır.
Yani orijinal Magento\Backend\Controller\Adminhtml\Dashboard\RefreshStatisticsuzanır Magento\Reports\Controller\Adminhtml\Report\StatisticsBen çıkardığını.
Magento 2'de, Controllertüm etkin modüller için klasörler klasörleri taranarak rotalar toplanır ve bir dizide toplanır.
Çok uzak çok iyi.
Sonunda diğerleri arasında bu çizgiyle karşılaşıyorum:

[magento\backend\controller\adminhtml\dashboard\refreshstatistics] => Magento\Backend\Controller\Adminhtml\Dashboard\RefreshStatistics

Sonra istek rota ile eşleştirilir magento\backend\controller\adminhtml\dashboard\refreshstatisticsve Magento o yola karşılık gelen sınıfın alt sınıf olup olmadığını kontrol eder Magento\Framework\App\ActionInterface. Sınıfım tanımlanmadan ve somutlaştırılmadan önce rotalar toplandığından, eski sınıf kendim yerine doğrulanır. Ve sınıfın üst sınıfı Magento\Backend\Controller\Adminhtml\Dashboard\RefreshStatisticsmevcut değildir.

Raporlar modülünü devre dışı bırakmaya devam eden ancak yine de çalışmasını sağlayan bir çözüm, tüm rotaları okuyan ve yukarıda belirtilen rotayı değiştiren yöntem için bir önleyici oluşturmaktır.

Ben de bunu di.xml

<type name="Magento\Framework\App\Router\ActionList\Reader">
    <plugin name="namespace-module-route" type="Namespace\Module\Model\Plugin\ActionListReader" sortOrder="100" />
</type>

ve eklentim şöyle görünüyor:

<?php
namespace Namespace\Module\Model\Plugin;

class ActionListReader
{
    public function afterRead(\Magento\Framework\App\Router\ActionList\Reader\Interceptor $subject, $actions)
    {
        $actions['magento\backend\controller\adminhtml\dashboard\refreshstatistics'] = 'Namespace\Module\Controller\Adminhtml\Dashboard\RefreshStatistics';
        return $actions;
    }
}

: - uzatmak için nasıl bir satıcı \ magento \ Model \ PriceCurrency.php convertAndRound (), burada ben bu durumda tercihini kullanır beni zorla eklentisi nasıl kullanılacağını bu durumda, değişim hassasiyet gerekir \ modül-dizin
Pradeep Kumar

6

di.xml içindeki herhangi bir çekirdek modülü genişletmek için tercih kullanma eklentisini kullanmayın

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

ve Product.php içinde

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'deki Core Block, Model ve denetleyiciyi geçersiz kılma


2
evet, bu en iyi yöntem. Ama benim durumumda, geçersiz kılmaya çalıştığım denetleyici tarafından genişletilen bir sınıfı içeren modülü kaldırdım. Yani aroundbenim için işe yaramaz. Orijinal denetleyicinin davranışını tamamen değiştirmek istedim.
Marius

Tam davranışı değiştirmek istiyorsanız, daha sonra yeni bir eylem oluşturun ve daha sonra ihtiyacınız olan her zaman URL'yi değiştirin, umarım bu iyi bir fikir olacaktır
Pradeep Kumar

2

İnceleme modeli için yeniden yazma denetleyicim var. composer.json dosyası:

{
        "name": "apple/module-review",
        "description": "N/A",
        "require": {
            "php": "~5.5.0|~5.6.0|~7.0.0",
            "magento/framework": "100.0.*"
        },
        "type": "magento2-module",
        "version": "100.0.2",
        "license": [
            "OSL-3.0",
            "AFL-3.0"
        ],
        "autoload": {
            "files": [
                "registration.php"
            ],
            "psr-4": {
                "Apple\\Review\\": ""
            }
        }
    }

registration.php dosyası

    \Magento\Framework\Component\ComponentRegistrar::register(
        \Magento\Framework\Component\ComponentRegistrar::MODULE,
        'Apple_Review',
        __DIR__
    );

app / code / Apple / Review / etc / module.xml dosyası:

    app/code/Apple/Review/etc/di.xml file for override review controller.
    <?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="urn:magento:framework:ObjectManager/etc/config.xsd">
        <preference for="Magento\Review\Controller\Product\Post" type="Apple\Review\Controller\Post" />   
    </config>

İnceleme modeli için denetleyici dosyasında,

Uygulamanın / kod / Apple / İnceleme / Kontrolör / Post.php

    use Magento\Review\Controller\Product as ProductController;
    use Magento\Framework\Controller\ResultFactory;
    use Magento\Review\Model\Review;

    class Post extends \Magento\Review\Controller\Product\Post
    {
        public function execute()
        {
           $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
            if (!$this->formKeyValidator->validate($this->getRequest())) {
                $resultRedirect->setUrl($this->_redirect->getRefererUrl());
                return $resultRedirect;
            }

            $data = $this->reviewSession->getFormData(true);
            if ($data) {
                $rating = [];
                if (isset($data['ratings']) && is_array($data['ratings'])) {
                    $rating = $data['ratings'];
                }
            } else {
                $data = $this->getRequest()->getPostValue();
                $rating = $this->getRequest()->getParam('ratings', []);
            }

            if (($product = $this->initProduct()) && !empty($data)) {
                /** @var \Magento\Review\Model\Review $review */
                $review = $this->reviewFactory->create()->setData($data);

                $validate = $review->validate();
                if ($validate === true) {
                    try {
                        $review->setEntityId($review->getEntityIdByCode(Review::ENTITY_PRODUCT_CODE))
                            ->setEntityPkValue($product->getId())
                            ->setStatusId(Review::STATUS_PENDING)
                            ->setCustomerId($this->customerSession->getCustomerId())
                            ->setStoreId($this->storeManager->getStore()->getId())
                            ->setStores([$this->storeManager->getStore()->getId()])
                            ->save();

                        foreach ($rating as $ratingId => $optionId) {
                            $this->ratingFactory->create()
                                ->setRatingId($ratingId)
                                ->setReviewId($review->getId())
                                ->setCustomerId($this->customerSession->getCustomerId())
                                ->addOptionVote($optionId, $product->getId());
                        }

                        $review->aggregate();
                        $this->messageManager->addSuccess(__('You submitted your review for moderation.Thanks'));
                    } catch (\Exception $e) {
                        $this->reviewSession->setFormData($data);
                        $this->messageManager->addError(__('We can\'t post your review right now.'));
                    }
                } else {
                    $this->reviewSession->setFormData($data);
                    if (is_array($validate)) {
                        foreach ($validate as $errorMessage) {
                            $this->messageManager->addError($errorMessage);
                        }
                    } else {
                        $this->messageManager->addError(__('We can\'t post your review right now.'));
                    }
                }
            }
            $redirectUrl = $this->reviewSession->getRedirectUrl(true);
            $resultRedirect->setUrl($redirectUrl ?: $this->_redirect->getRedirectUrl());
            return $resultRedirect;
        }
    }

Bu magento2 inceleme inceleme geçersiz kılma için çalışma kodu. Teşekkürler.


: - tercihi kullanmak genişletmek için iyi bir yol değil, eklenti konseptini kullanın
Pradeep Kumar

@PradeepKumar, eklentileri kullanmanın neden tercih edilmeyi tercih ettiğini açıklayabilir misiniz?
Robbie Averill

@robbie: - orijinal veya çekirdek işlevselliğini korur, örneğin magneto2 yükseltildiyse ve aynı işlevde bazı değişiklikler olursa, bu kısmı kaybedeceğiz, bu yüzden eklentiye gidin, çekirdek logi tutmaya devam edin
Pradeep Kumar

Eklenti karşılıklı olarak münhasırdır, ancak tercih yeniden yazmadır - bu doğru @PradeepKumar mı?
Robbie Averill
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.