Як отримати список усіх переписувачів класу?


23

Чи є спосіб перерахувати всі переписування та, можливо, інші потенційні конфлікти, окрім перегляду всіх файлів конфігурації? Я маю проаналізувати деякі проекти з великою кількістю розширень та спеціальних модифікацій, і я хотів би максимально автоматизувати це.

Найголовніше - це виявити розширення, які переписують той самий клас, але я також хотів би мати список усіх переписувачів, щоб зберегти огляд. На даний момент я підтримую цей список вручну в електронній таблиці.

Я знайшов це розширення ("Конфлікт розширення") на Magento Connect, але, судячи з оглядів та приміток до випуску, воно здається застарілим.


Не можете просто скористатисяgrep
Бен Лессані - Сонассі

Відповіді:


28

Погляньте на утиліту n98-magerun :

Перепишіть список

Списки всіх зареєстрованих класів переписує:

$ n98-magerun.phar dev:module:rewrite:list

Перепишіть конфлікти

Перераховує всі повторювані переписування та повідомляє, який клас завантажується Magento. Команда перевіряє успадкування класів у порядку залежності вашого модуля. n98-magerun.phar dev:module:rewrite:conflicts [--log-junit="..."]

Якщо встановлено ім'я файлу з параметром --log-junit, інструмент генерує XML-файл і не має виводу для stdout.

Ви також можете записати конфлікти у файл XML стилю JUnit Style для подальшого аналізу, наприклад, на сервері тривалої інтеграції.

Відмова від відповідальності: напівзв'язок / я причетний до цього проекту


27

Ось невеличкий однокласник, який дає всі активні переписування:

print_r(Mage::getConfig()->getNode()->xpath('//global//rewrite'));

Щоб обмежити його за типом об'єкта, додайте моделі, блоки чи помічники до xpath відповідно.
Наприклад:

Mage::getConfig()->getNode()->xpath('//global/models//rewrite')

У чому проблема з magento.SE? У будь-якому випадку мені подобається рішення, просте і просте. Повинен був би подумати про це сам… Данке, Віней!
Фабіан Шменглер

2
Це працює з невеликим питанням. Якщо у вас є два розширення, що переписують ту саму модель, ви її не побачите, оскільки Magento об'єднує конфігураційні файли. Ви побачите лише "останній". Але це швидкий і простий спосіб зрозуміти, чи щось переписано
Маріус

Так, це показує лише активні переписування, це правда. Якщо ви хочете більш досконалої аналітики, вам потрібно перевірити кожен активний модуль etc / config.xml окремо, (або просто використовувати n98-magerun)
Vinai

Привіт @ Vinai, Чи можемо ми отримати цей конфлікт у magento2 за цим кодом?
akgola

Ні, ви не можете конфігурація DI працює зовсім по-іншому в Magento 2.
Vinai

22

ось невеликий сценарій, який я використовую, щоб перевірити, чи перезаписані якісь моделі, блоки чи помічники. На жаль, це не працює для контролерів, а також враховує відключені модулі. Але з моєї точки зору це не велика справа.

Основна ідея - розібрати конфігураційні файли та шукати <rewrite>тег. Створіть файл php на тому ж рівні, що і index.php. Давайте назвемо його за rewrites.phpдопомогою цього вмісту:

<?php 
$folders = array('app/code/local/', 'app/code/community/');//folders to parse
$configFiles = array();
foreach ($folders as $folder){
    $files = glob($folder.'*/*/etc/config.xml');//get all config.xml files in the specified folder
    $configFiles = array_merge($configFiles, $files);//merge with the rest of the config files
}
$rewrites = array();//list of all rewrites

foreach ($configFiles as $file){
    $dom = new DOMDocument;
    $dom->loadXML(file_get_contents($file));
    $xpath = new DOMXPath($dom);
        $path = '//rewrite/*';//search for tags named 'rewrite'
        $text = $xpath->query($path);
        foreach ($text as $rewriteElement){
            $type = $rewriteElement->parentNode->parentNode->parentNode->tagName;//what is overwritten (model, block, helper)
            $parent = $rewriteElement->parentNode->parentNode->tagName;//module identifier that is being rewritten (core, catalog, sales, ...)
            $name = $rewriteElement->tagName;//element that is rewritten (layout, product, category, order)
            foreach ($rewriteElement->childNodes as $element){
                $rewrites[$type][$parent.'/'.$name][] = $element->textContent;//class that rewrites it
            }
        }
}
echo "<pre>";print_r($rewrites);

при виклику в браузері ви повинні побачити щось подібне:

Array
(
    [models] => Array
        (
            [core/layout] => Array
                (
                    [0] => Namespace_Module_Model_Core_Layout
                    [1] => Namespace1_Module1_Model_Core_Layout //if the second element is present it means there is a possible conflict
                )
            [...] => ....

        )
    [blocks] => ...
    [helpers] => ...

)

це означає, що модель 'core/layout'перезаписанаNamespace_Module_Model_Core_Layout

Якщо у масиві ['core / layout'] є 2 або більше значень, це означає, що існує конфлікт.

І ви можете легко визначити модуль, який перезаписує щось на основі NamespaceтаModule


1
Привіт, дякую за сценарій. Я використав це в одному зі своїх проектів і виявив, що перевірка модулів спільноти не працює. Щоб він працював, ми додамо "/" до кінця "app / code / community", тому воно стане "app / code / community /"
ceckoslab

@ceckoslab. Так. Ти правий. Я відредагував відповідь. Спасибі.
Маріус

3

Я поєднав обидві відповіді і отримав гарне рішення

$text = Mage::getConfig()->getNode()->xpath('//global//rewrite');
foreach ($text as $rewriteElement) {
    if ($rewriteElement->getParent()->getParent()) {
        # what is overwritten (model, block, helper)
        $type = $rewriteElement->getParent()->getParent()->getName();
        # module identifier that is being rewritten (core, catalog, sales, ...)
        $parent = $rewriteElement->getParent()->getName();
        # element that is rewritten (layout, product, category, order)
        $name = $rewriteElement->getName();
        foreach ($rewriteElement->children() as $element) {
            # class that rewrites it
            $rewrites[$type][$parent.'/'.$name][] = $element;
        }
    }
}
print_r($rewrites);
die;

0

Можливо, трохи накладні, але приємно працювати з варіантом збору даних ... код з https://github.com/firegento/firegento-debug

$collection = new Varien_Data_Collection();

$fileName = 'config.xml';
$modules = Mage::getConfig()->getNode('modules')->children();

$rewrites = array();
foreach ($modules as $modName => $module) {
    if ($module->is('active')) {
        $configFile = Mage::getConfig()->getModuleDir('etc', $modName) . DS . $fileName;
        if (file_exists($configFile)) {
            $xml = file_get_contents($configFile);
            $xml = simplexml_load_string($xml);

            if ($xml instanceof SimpleXMLElement) {
                $rewrites[$modName] = $xml->xpath('//rewrite');
            }
        }
    }
}

foreach ($rewrites as $rewriteNodes) {
    foreach ($rewriteNodes as $n) {
        $nParent = $n->xpath('..');
        $module = (string)$nParent[0]->getName();
        $nSubParent = $nParent[0]->xpath('..');
        $component = (string)$nSubParent[0]->getName();

        if (!in_array($component, array('blocks', 'helpers', 'models'))) {
            continue;
        }

        $pathNodes = $n->children();
        foreach ($pathNodes as $pathNode) {
            $path = (string)$pathNode->getName();
            $completePath = $module . '/' . $path;

            $rewriteClassName = (string)$pathNode;

            $instance = Mage::getConfig()->getGroupedClassName(
                substr($component, 0, -1),
                $completePath
            );

            $collection->addItem(
                new Varien_Object(
                    array(
                        'path'          => $completePath,
                        'rewrite_class' => $rewriteClassName,
                        'active_class'  => $instance,
                        'status'        => ($instance == $rewriteClassName)
                    )
                )
            );
        }
    }
}

Для виводу ви можете використовувати ...

foreach ($collection as $rewrite) {
    var_dump($rewrite->getData());
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.