Magento Project Mess Detector (for n98-magerun)
Author: Fabrizio Branca (fbrnc.net / @fbrnc) Some additional commands for the excellent n98-magerun Magento command-line tool that will help you find out how messed up a Magento instance is :)
…There are a few options. You can check out the different options in the MageRun docs.
Here's the easiest:
Install n98-magerun if you haven't already. Find the instructions on the n98-magerun wiki.
Create ~/.n98-magerun/modules/ if it doesn't already exist. (or /usr/local/share/n98-magerun/modules or put your modules inside your Magento instance in lib/n98-magerun/modules if you prefer that)
mkdir -p ~/.n98-magerun/modules/git clone https://github.com/AOEpeople/mpmd.git ~/.n98-magerun/modules/mpmdn98-magerun.phar | grep mpmdmpmd:corehacksUsage:
mpmd:corehacks [--format[="..."]] pathToVanillaCore [htmlReportOutputPath] [skipDirectories]
Arguments:
pathToVanillaCore Path to Vanilla Core used for comparison
htmlReportOutputPath Path to where the HTML report will be written
skipDirectories ':'-separated list of directories that will not be considered (defaults to '.svn:.git')This command requires a vanilla version of Magento (same version and edition! Run n98-magerun.phar sys:info for more details) to be present somewhere in the filesystem.
It will then traverse all project files and compare them with the original files.
This command will also be able to tell the difference between whitespace or code comments changes and real code changes.
It will generate a HTML report that also includes the diffs.
$ cd /var/www/magento/htdocs
$ n98-magerun.phar mpmd:corehacks /path/to/vanilla/magento /path/to/report.html
Comparing project files in 'var/www/magento/htdocs' to vanilla Magento code in '/path/to/vanilla/magento'...
+----------------------+-------+
| Type | Count |
+----------------------+-------+
| differentFileContent | 2 |
| identicalFiles | 16049 |
| fileMissingInB | 1 |
| sameFileButComments | 0 |
+----------------------+-------+
Generating detailed HTML ReportReport preview:
mpmd:codepooloverridesUsage:
mpmd:codepooloverrides [--format[="..."]] [htmlReportOutputPath] [skipDirectories]
Arguments:
htmlReportOutputPath Path to where the HTML report will be written
skipDirectories ':'-separated list of directories that will not be considered (defaults to '.svn:.git')This command will compare all code pools with each other and detect files that are overriding each other. It will show identical files (What's the point of these? But yes, seen projects where this happened), copied files with changes in comments and whitespace only, and real changes. Of course with diff...
Report preview:
The dependency checker parses one or more files or directories and detects PHP classes that are being "used" there.
The dependency checker is a "semi" static code analysis tool. That means it does the job without actually executing any of the PHP code you're pointing it to, but it does need that module to be installed correctly and it will invoke the Magento framework to resolve classpaths (catalog/product -> Mage_Catalog_Model_Product)
While tools like pdepend exist those tools don't know anything about Magento in general, Magento's special classpaths and where they are being used. Also sometimes the numbers generated by pdepend are a little overwhelming and after all what are you going to do knowing that you're module has an avarage cyclomatic complexity of x?
The mpmd:dependencychecker will
The dependency checker comes with two different parsers (and allows you to add new ones:)
| Parser | Will process | How it works |
|---|---|---|
| Tokenizer | *.php, *.phtml | The tokenizer parser will split the PHP file into tokens and traverses them. Handlers can subscribe to token to detect various class usages. |
| Xpath | *.xml | The xpath parser will read the file into a SimpleXMLElement object and will pass this to all the subscribed handlers |
Add a new parser via n98-magerun's YAML configuration
commands:
Mpmd\Magento\DependencyCheckCommand:
parsers:
- Mpmd\DependencyChecker\Parser\Tokenizer
- Mpmd\DependencyChecker\Parser\Xpath
- (... add your parser here ...)All parsers need to implement Mpmd\DependencyChecker\Parser\ParserInterface. Also checkout the AbstractParser that implements that interface and might be a good starting point.
Every parser comes with a number of handlers. Here's the list of default handlers that come with the dependency checker:
| Parser | Handler | Will process | What it does |
|---|---|---|---|
| Tokenizer | Interfaces | T_IMPLEMENTS |
Finds interfaces: class A implements B {} |
| Tokenizer | WhitespaceString | T_NEW, T_EXTENDS, T_CLASS |
Finds classes instantiated with 'new': $a = new B(); |
Finds extended classes: class A extends B {} |
|||
| Tokenizer | StaticCalls | T_DOUBLE_COLON |
Finds static calls: A::B and A::B() |
| Tokenizer | TypeHints | T_FUNCTION |
Finds type hints: function a (B $b) {} |
| Tokenizer | MagentoFactoryMethods | T_STRING for specific keywords |
Finds classes instantiated with one of Magento's factory methods and resolves them to real PHP classes not taking rewrites into account: |
Mage::getModel() |
|||
Mage::getSingleton() |
|||
Mage::getResourceModel() |
|||
Mage::getResourceSingleton() |
|||
$this->getLayout()->createBlock() |
|||
Mage::getBlockSingleton() |
|||
Mage::helper() |
|||
Mage::getResourceHelper() |
|||
Mage::getControllerInstance() |
|
| Xpath | LayoutXml | All xml files | Finds blocks and resolves them into real PHP classes: `` |
| Xpath | SystemXml | All xml files | Finds references to models in system.xml files:
adminhtml/system_config_form_field_notification
adminhtml/system_config_source_yesno
adminhtml/system_config_backend_store |
Note: MagentoFactoryMethods, LayoutXml and SystemXml need to resolve Magento classpaths into real PHP classes. The challenge hereby is NOT to take rewrites into account since rewriting a class is a mechanism that was introduced to ALLOW decoupling without dependending on each other. In order to leverage Magento and it's configuration to resolve the class paths but not take the rewrite into accounts
Mage_Core_Model_Config having access to the same data but doing things slightly differently. Mpmd\Util\MagentoFactory takes care of that and provides access to some of the original functions like getModelClassName() and getBlockClassName()...Add a new handler via n98-magerun's YAML configuration (also checkout n98-magerun's documentation for custom commands)
commands:
Mpmd\Magento\DependencyCheckCommand:
Mpmd\DependencyChecker\Parser\Tokenizer:
handlers:
- Mpmd\DependencyChecker\Parser\Tokenizer\Handler\WhitespaceString
- Mpmd\DependencyChecker\Parser\Tokenizer\Handler\Interfaces
- (... add your tokenizer handler here ...)
:
handlers:
- (... add your handler here ...)
``No open issues yet, or sync has not completed.