Ghi đè lớp trừu tượng trong Magento 2


13

Trong Magento 1 tôi có thể sao chép lớp trừu tượng vào thư mục cục bộ hoặc cộng đồng và Magento đã sử dụng nó, khi tự động tải lớp này.

Có một số giải pháp để thực hiện để Magento tải lớp của tôi thay thế vendor/magento/framework/Model/AbstractModel.php?

Tùy chọn trong di.xmlcác lớp trừu tượng không hoạt động. Plugin chỉ?

Câu trả lời:


9

Plugin chỉ?

Đúng. Bạn có thể viết các plugin cho các lớp trừu tượng và các plugin nên luôn được ưu tiên hơn các tùy chọn nếu có thể.

Tùy chọn rất hữu ích nếu bạn muốn thay thế một triển khai. Tôi không thể nghĩ ra một trường hợp sử dụng để thay thế việc triển khai cho tất cả các mô hình mở rộng AbstractModel, nếu điều đó thậm chí có thể hợp lý. Vì vậy, những gì bạn có thể muốn là thêm hoặc thay đổi chức năng và đây là những gì các plugin dành cho.


1
Xin chào, làm thế nào tôi có thể ghi đè một chức năng được bảo vệ khỏi lớp trừu tượng trong trường hợp này? bạn có thể vui lòng giúp đỡ
Manashvi Birla

2
Đó là không thể. Cách tốt nhất là cố gắng tìm cách thêm plugin vào các phương thức công khai sử dụng phương thức được bảo vệ và thay đổi hành vi theo cách này, ngay cả khi nó liên quan đến nhiều mã hơn và một số sao chép.
Fabian Schmengler

1
"Tôi không thể nghĩ ra trường hợp sử dụng để thay thế việc triển khai cho tất cả các mô hình mở rộng AbstractModel" Tôi có một trường hợp sử dụng như vậy: Tôi có mô-đun thanh toán, sử dụng lớp cơ sở trừu tượng cho 4 bộ điều khiển, mỗi phương thức sử dụng một phương thức từ cơ sở để xác minh phản hồi từ cổng thanh toán. Bây giờ, phản hồi đã thay đổi và tôi sẽ phải thay đổi tất cả 3.
Tero Lahtinen

6

Giải pháp đầy đủ: bao gồm các lớp thay thế trước khi magento tự động tải chúng. Vì vậy, từng bước:

  1. Trong tập tin app/etc/NonComposerComponentRegistration.phpthêm hàng

    $pathList[] = dirname(__DIR__) . '/etc/ClassReplacer.php';
  2. Trong app/etctập tin nơi ClassReplacer.phpvới nội dung

    class ClassReplacer
    {
        public function includeReplacedFiles($src)
        {
            try {
                $replacedFiles = $this->listDir($src, false, true);
                foreach ($replacedFiles as $replacedFile) {
                    include_once $src . $replacedFile;
                }
            } catch (Exception $e) {
                return;
            }
        }
    
        protected function listDir($dir, $prependDir = false, $recursive = false, $entityRegexp = null, $currPath = '')
        {
            if (!is_dir($dir)) {
                return array();
            }
            $currPath = $prependDir ? $dir : $currPath;
            $currPath = $currPath !== '' ? rtrim($currPath, '/') . '/' : '';
            $files = array();
            foreach (scandir($dir) as $file) {
                if (in_array($file, array('.', '..'))) {
                    continue;
                }
                $entity = $currPath . $file;
                if ($recursive && is_dir("$dir/$file")) {
                    $files = array_merge($files, $this->listDir("$dir/$file", false, true, $entityRegexp, $entity . '/'));
                    continue;
                }
                if ($entityRegexp && !preg_match($entityRegexp, $entity)) continue;
                $files[] = $entity;
            }
            return $files;
        }
    }
    $replace = new ClassReplacer();
    $replace->includeReplacedFiles(dirname(__DIR__) . '/code/Magento/');
  3. Địa điểm cho app/code/Magentomột số lớp, sẽ được thay thế, ví dụapp/code/Magento/Tax/Model/Calculation/AbstractAggregateCalculator.php



1
Hack bẩn, nhưng đôi khi nó có thể hữu ích để có thể làm điều đó. M1 yêu cầu thay đổi thủ công trong các lớp lõi (vì vậy hãy sao chép vào ứng dụng / mã / cục bộ) nếu bạn muốn hóa đơn PDF trông khác đi, tôi cá là sẽ có một số trường hợp cần thiết.
Zefiryn

5

Nếu lớp trừu tượng có bất kỳ phương thức công khai hoặc được bảo vệ nào bạn muốn ghi đè, thực sự có một cách nếu bạn không thể sử dụng bổ trợ.

Tôi đã phải ghi đè phương thức _processDownloadbên trong \Magento\Downloadable\Controller\Download, thêm một số 'if-s' bên trong. (Nếu bất cứ ai có ý tưởng làm thế nào tôi có thể thêm một cái gì đó như thế này vào bên trong bằng cách sử dụng các plugin, tôi sẽ rất biết ơn). Lớp học là trừu tượng vì vậy sở thích đã không làm việc. Plugin cũng vậy, vì phương thức được bảo vệ. Điều tôi phải làm là ghi đè tất cả các lớp mở rộng từ Download, sử dụng tùy chọn. Những lớp học này:

Magento\Downloadable\Controller\Download\Link Magento\Downloadable\Controller\Download\LinkSample Magento\Downloadable\Controller\Download\Sample

Và bên trong chúng viết lại phương thức từ lớp cha (cái mà tôi muốn ghi đè). Vì vậy, thực tế mã của các phương thức được ghi đè đã được sao chép đến ba nơi và hoàn toàn giống nhau.

Nó không lý tưởng nhưng, hoạt động.


4

Bạn có thể thử sử dụng Magento Plugin để tăng cường chức năng hiện có của bất kỳ lớp Trừu tượng nào, mặc dù phạm vi của chức năng phải là Công khai. Gần đây tôi đã làm việc về cùng một vấn đề mà tôi cần loại trừ các sản phẩm có thuộc tính tùy chỉnh được gán từ danh sách sản phẩm được xem gần đây .

Tôi đã sử dụng plugin cho hàm có tên getItemsCollection từ lớp có tên Magento \ báo cáo \ Block \ Product \ Trừu tượng sản phẩm bằng cú pháp sau:

tệp: app \ code \ Gói \ Module \ etc \ frontend \ di.xml

<type name="Magento\Reports\Block\Product\AbstractProduct">
    <plugin name="Package_Module::aroundGetItemsCollection" type="Package\Module\Block\Viewed" sortOrder="20"/>
</type>

tệp: ứng dụng \ code \ Gói \ Mô-đun \ Khối \ Đã xem.php

public function afterGetItemsCollection(
    $subject, $result
) {
    $result = $result->addAttributeToFilter('skip_hire_product', [['neq' => 1], ['null' => true]], 'left');
    return $result;
}

Bạn cũng có thể sử dụng xung quanh cũng như trước các plugin. Hy vọng công việc này cho bạn.


1
Tôi đã thành công với mã trên trong một trong những yêu cầu của mình, thực sự tôi muốn thay đổi một số chức năng của phương thức lớp trừu tượng mô-đun email và Plugin đã giúp tôi đạt được điều này, cảm ơn
bhargav shastri
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.