Magento 2의 추상 클래스 재정의


13

Magento 1에서 추상 클래스를 로컬 또는 커뮤니티 디렉토리에 복사 할 수 있었고 Magento는이 클래스를 자동로드 할 때 사용했습니다.

Magento가 내 클래스를 대신로드 할 수있는 솔루션이 vendor/magento/framework/Model/AbstractModel.php있습니까?

di.xml추상 클래스의 환경 설정이 작동하지 않습니다. 플러그인 만?

답변:


9

플러그인 만?

예. 추상 클래스를위한 플러그인을 작성할 수 있으며 가능하면 환경 설정보다 항상 플러그인을 선호해야합니다.

환경 설정은 구현 을 바꾸려 는 경우에 유용합니다 . AbstractModel논리적으로 가능하다면 확장되는 모든 모델의 구현을 대체하는 유스 케이스를 생각할 수 없습니다 . 아마도 당신이 원하는 것은 기능추가하거나 변경 하는 것입니다. 이것이 플러그인을위한 것입니다.


1
안녕하세요,이 경우 추상 클래스에서 보호 된 함수를 어떻게 재정의 할 수 있습니까? 당신은 도움을 주시기 바랍니다 수
Manashvi 비를 라

2
그건 불가능하다. 가장 좋은 방법은 보호 된 메소드를 사용하는 공용 메소드에 플러그인을 추가하고 더 많은 코드와 일부 중복이있는 경우에도 이러한 방식으로 동작을 변경하는 방법을 찾는 것입니다.
Fabian Schmengler 2016 년

1
"AbstractModel을 확장하는 모든 모델의 구현을 대체하는 유스 케이스를 생각할 수 없습니다."그런 유스 케이스가 있습니다. 지불 모듈이 있습니다.이 모듈은 4 개의 컨트롤러에 대해 추상 기본 클래스를 사용합니다. 결제 게이트웨이의 응답 이제 응답이 변경되었습니다 나는 모든 3. 변경해야 할 것입니다
테로 Lahtinen

6

전체 솔루션 : magento가 자동로드하기 전에 교체 된 클래스를 포함하십시오. 단계별로 :

  1. 파일에서 app/etc/NonComposerComponentRegistration.php행 추가

    $pathList[] = dirname(__DIR__) . '/etc/ClassReplacer.php';
  2. 에서 app/etc장소 파일 ClassReplacer.php내용

    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. 에 배치 app/code/Magento대체 몇 가지 클래스, 예를 들어,app/code/Magento/Tax/Model/Calculation/AbstractAggregateCalculator.php



1
더러운 해킹이지만 때로는 그렇게하는 것이 도움이 될 수 있습니다. 송장 PDF를 다르게 보이게하려면 M1에서 핵심 클래스의 수동 변경 (따라서 앱 / 코드 / 로컬로 복사)이 필요했습니다. 필요한 경우가있을 것입니다.
Zefiryn

5

abstract 클래스에 재정의하려는 public 또는 protected 메소드가있는 경우 실제로 플러그인을 사용할 수없는 방법이 있습니다.

_processDownload안에 \Magento\Downloadable\Controller\Download'if-s'를 추가하여 inside 메소드를 재정의해야했습니다 . (누구든지 플러그인을 사용하여 메소드 내에 이와 같은 것을 추가하는 방법을 알고 있다면 기뻐할 것입니다). 수업은 추상적이므로 선호도가 작동하지 않았습니다. 메소드가 보호되어 있으므로 플러그인도 있습니다. 내가해야 할 일은 Download환경 설정을 사용하여 에서 확장하는 모든 클래스를 재정의하는 것 입니다. 이 수업은 :

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

그리고 내부에서 부모 클래스의 메소드를 다시 작성합니다 (내가 재정의해야했던 클래스). 따라서 실제로 재정의 된 메서드 코드는 세 곳으로 복사되었으며 정확히 동일했습니다.

이상적이지는 않지만 작동합니다.


4

함수의 범위는 공용이어야하지만 Abstract 클래스의 기존 기능을 향상시키기 위해 Magento 플러그인을 사용해 볼 수 있습니다. 최근에 최근에 본 제품 목록 에서 사용자 지정 속성이 할당 된 제품을 제외해야하는 동일한 문제에 대해 작업했습니다 .

다음 구문을 사용하여 Magento \ Reports \ Block \ Product \ AbstractProduct 라는 클래스에서 getItemsCollection 이라는 함수에 플러그인을 사용했습니다.

파일 : app \ code \ Package \ 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>

파일 : app \ code \ Package \ Module \ Block \ Viewed.php

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

플러그인 이전뿐만 아니라 주변에서도 사용할 수 있습니다. 이 작업이 당신에게 도움이 되길 바랍니다.


1
내 요구 사항 중 하나에서 위의 코드로 성공했습니다. 실제로 전자 메일 모듈 추상 클래스 메서드의 일부 기능을 변경하고 싶었고 플러그인 덕분에이를 달성 할 수
있었습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.