سؤال

Is there a way to list all rewrites and maybe other potential conflicts besides reviewing all configuration files? I have to analyse some projects with lots of extensions and custom modifications and would like to automate as much as possible of this.

The most important thing is to detect extensions that rewrite the same class, but I'd like to have a list of all rewrites in place too, to keep an overview. At the moment I maintain this list manually in a spreadsheet.

I found this extension ("Extension Conflict") on Magento Connect but judging by the reviews and release notes it seems to be outdated.

هل كانت مفيدة؟

المحلول

Have a look at the n98-magerun utility:

Rewrite List

Lists all registered class rewrites:

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

Rewrite Conflicts

Lists all duplicated rewrites and tells you which class is loaded by Magento. The command checks class inheritance in order of your module dependencies. n98-magerun.phar dev:module:rewrite:conflicts [--log-junit="..."]

If a filename with --log-junit option is set the tool generates an XML file and no output to stdout.

You can also log the conflicts to a JUnit Style XML file for further analysis, for example on a continues integration server.

Disclaimer: semi-self-link / I am involved in that project

نصائح أخرى

Here a small one-liner that gives you all active rewrites:

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

To limit it by object type, add models, blocks, or helpers to the xpath respectively.
For example:

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

here is a small script I use to check if any models, blocks or helpers are overwritten. Unfortunately it does not work for controllers and it takes into account the disabled modules also. But from my point of view this is no big deal.

The main idea is to parse the config files and look for the <rewrite> tag. Create a php file on the same level as index.php. Let's call it rewrites.php, with this content:

<?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);

when calling it in a browser you should see something like this:

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] => ...

)

this means that the model 'core/layout' is overwritten by Namespace_Module_Model_Core_Layout

If you have 2 or more values in the array ['core/layout'] it means there is a conflict.

And you can easily identify the module that overwrites something based on Namespace and Module

i have combined both the answer and got a nice solution

$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;

Maybe bit overhead but it's nice to to work with varien data collection ... code from 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)
                    )
                )
            );
        }
    }
}

For output you can use ...

foreach ($collection as $rewrite) {
    var_dump($rewrite->getData());
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى magento.stackexchange
scroll top