Magento 2'de soyut sınıfı geçersiz kılma


13

Magento 1'de, soyut sınıfı yerel veya topluluk dizinine kopyalayabilirim ve Magento, bu sınıfı otomatik yüklendiğinde kullandı.

Bunun yerine sınıfımı Magento'ya yüklemenin bir yolu var vendor/magento/framework/Model/AbstractModel.phpmı?

di.xmlSoyut sınıflar için tercihler çalışmaz. Yalnızca eklentiler mi?

Yanıtlar:


9

Yalnızca eklentiler mi?

Evet. Soyut sınıflar için eklentiler yazabilirsiniz ve mümkünse eklentiler her zaman tercihlere göre tercih edilmelidir.

Bir uygulamayı değiştirmek istiyorsanız tercihler yararlıdır . AbstractModelMantıksal olarak mümkün olsa bile, genişleyen tüm modeller için uygulamayı değiştirmek için bir kullanım durumu düşünemiyorum . Muhtemelen istediğiniz şey işlevsellik eklemek veya değiştirmek ve bu eklentiler içindir.


1
Merhaba, bu durumda soyut bir sınıftan korumalı bir işlevi nasıl geçersiz kılabilirim? yardımcı olabilir misiniz
Manashvi Birla

2
Bu mümkün değil. En iyisi, korunan yöntemi kullanan genel yöntemlere eklentiler eklemenin bir yolunu bulmaya çalışmak ve daha fazla kod ve bazı çoğaltma içeriyor olsa bile davranışı bu şekilde değiştirmek.
Fabian Schmengler

1
"AbstractModel genişletmek tüm modeller için uygulama yerine bir kullanım vakası düşünemiyorum" Böyle bir kullanım vakası var: Ben her biri doğrulamak için tabandan bir yöntem kullanarak 4 denetleyicileri için soyut temel sınıf kullanan ödeme modülü var ödeme ağ geçidinden gelen yanıt. Şimdi, yanıt değişti ve 3'ü de değiştirmek zorunda kalacağım.
Tero Lahtinen

6

Tam çözüm: Magento otomatik yüklemeden önce değiştirilen sınıfları ekleyin. Adım adım:

  1. Dosya app/etc/NonComposerComponentRegistration.phpekleme satırında

    $pathList[] = dirname(__DIR__) . '/etc/ClassReplacer.php';
  2. Yerinde içerikli app/etcdosyaClassReplacer.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. Place app/code/Magentodeğiştirilecektir bazı sınıfın, örneğinapp/code/Magento/Tax/Model/Calculation/AbstractAggregateCalculator.php



1
Kirli kesmek, ancak bazen bunu yapabilmek yararlı olabilir. M1, fatura PDF'sinin farklı görünmesini istiyorsanız çekirdek sınıflarda manuel değişiklikler gerektirdi (bu yüzden app / code / local'a kopyalayın), bunun gerekli olacağı bazı durumlar olacağına bahse girerim.
Zefiryn

5

Abstract sınıfının geçersiz kılmak istediğiniz herhangi bir genel veya korumalı yöntemi varsa, aslında eklentileri kullanamamanızın bir yolu vardır.

_processDownloadİçindeki yöntemi geçersiz kılmak zorunda kaldım, içine \Magento\Downloadable\Controller\Download'if-s' ekledi. (Herkes nasıl eklentileri kullanarak yöntemi içine böyle bir şey ekleyebilirim fikrimi varsa ben minnettar olacağım). Sınıf soyuttur, bu yüzden tercih işe yaramadı. Eklenti de, yöntem olarak korunur. Yapmam gereken şey, tüm sınıfları Download, tercihi kullanarak geçersiz kılmaktı. Bu sınıflar:

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

Ve onların içinde ebeveyn sınıfından yöntemi yeniden yazma yöntemi (geçersiz kılmak zorunda olduğum). Aslında geçersiz kılınan yöntemlerin kodu üç yere kopyalandı ve tamamen aynıydı.

İdeal değil, işe yarıyor.


4

Herhangi bir Abstract sınıfının mevcut işlevselliğini geliştirmek için Magento Eklentisini kullanmayı deneyebilirsiniz, ancak işlevin kapsamı Genel olmalıdır. Son zamanlarda, Son görüntülenen ürün listesinden atanmış özel bir özelliğe sahip ürünleri hariç tutmam gereken aynı sorun üzerinde çalıştım .

Aşağıdaki sözdizimini kullanarak Magento \ Reports \ Block \ Product \ AbstractProduct adlı sınıftan getItemsCollection adlı işlev için eklenti kullandım:

dosya: 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>

dosya: app \ code \ Package \ Module \ Block \ Görüntülenen.php

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

Etrafınızda ve eklentilerden önce de kullanabilirsiniz. Umarım bu iş senin için.


1
benim ihtiyacım birinde yukarıdaki kodu ile başarı var, aslında ben e-posta modülü soyut sınıf yöntemi bazı işlevselliğini değiştirmek istedim ve Plugin bu, teşekkürler elde etmek için bana yardımcı oldu
bhargav shastri
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.