23

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.

1
  • Can't you just use grep Commented Mar 26, 2013 at 8:51

5 Answers 5

28

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

27

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')
5
  • What's the problem with magento.SE? Anyways I like the solution, simple and straightforward. Should have thought about it myself... Danke, Vinai! Commented Mar 26, 2013 at 11:52
  • 2
    This works with a small issue. If you have 2 extensions rewriting the same model you won't see it, because Magento merges the config files. You will only see the "last" one. But it's a quick and simple way to see if something is rewritten
    – Marius
    Commented Mar 26, 2013 at 14:04
  • Yes, it only shows the active rewrites, that is true. If you want more advanced analytics you need to check each active modules etc/config.xml individually, (or just use n98-magerun)
    – Vinai
    Commented Mar 26, 2013 at 23:44
  • Hello @Vinai,Can we get all conflict in magento2 by this code?
    – akgola
    Commented Sep 12, 2017 at 10:19
  • Nope, you can't the DI configuration works quite differently in Magento 2.
    – Vinai
    Commented Sep 14, 2017 at 4:42
22

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

2
  • 1
    Hi, thanks for the script. I used it in one of my project and found, that the check for community modules doesn't work. To make it works we have add a "/" to the end of 'app/code/community', so it will become 'app/code/community/'
    – ceckoslab
    Commented Nov 20, 2013 at 15:49
  • @ceckoslab. Yep. You are right. I've edited the answer. Thanks.
    – Marius
    Commented Nov 20, 2013 at 15:55
3

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

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());
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.