Occasionally I've needed to take a closer look at exactly which block, layout or config file is being loaded by Magento. In this post I will demonstrate a "brute force" approach to checking exactly what is being processed.
Please note: Where possible, we will be using Magento's logging, the output of which will be written to the file var/log/system.log
, which also includes the rest of the system logging output. Logging must be enabled for output to be written to this file - you can enable logging in the Magento admin panel by going to System → Configuration → Developer → Log Settings and setting Enabled to True.
Blocks
The
getBlockClassName()
function inapp/code/core/Mage/Core/Model/Config.php
is responsible for translating block paths (i.e.adminhtml/sales_order
) into a filename (i.e.app/code/core/Mage/Adminhtml/Block/Sales/Order/Grid.php
or a custom block such asapp/code/local/Fontis/CustomModule/Block/Adminhtml/Sales/Order/Grid.php
). To see which block paths are getting mapped to which class files, add a logging statement:public function getBlockClassName($blockType) { if (strpos($blockType, '/')===false) { return $blockType; } // added log statement below Mage::log("$blockType mapped to ".$this->getGroupedClassName('block', $blockType)); return $this->getGroupedClassName('block', $blockType); }
The
_getBlockInstance()
function inapp/code/core/Mage/Core/Model/Layout.php
takes a block path or class name and finds the corresponding PHP file to load. Add some logging to this and you can see exactly what's getting loaded. (New lines are$orig = $block
andMage::log(...)
.)protected function _getBlockInstance($block, array $attributes=array()) { // added line below $orig = $block; if (is_string($block)) { if (strpos($block, '/')!==false) { if (!$block = Mage::getConfig()->getBlockClassName($block)) { Mage::throwException(Mage::helper('core')->__('Invalid block type: %s', $block)); } } $fileName = mageFindClassFile($block); if ($fileName!==false) { // added log statement below Mage::log("_getBlockInstance: $orig -> $fileName"); include_once ($fileName); $block = new $block($attributes); } } if (!$block instanceof Mage_Core_Block_Abstract) { Mage::throwException(Mage::helper('core')->__('Invalid block type: %s', $block)); } return $block; }
Layouts
The
fetchFileLayoutUpdates()
function inapp/code/core/Mage/Core/Model/Layout/Update.php
is where the XML layout files get loaded. Insert a logging statement to see what's getting processedpublic function fetchFileLayoutUpdates() { // ...some lines omitted here... foreach ($updateFiles as $file) { $filename = $design->getLayoutFilename($file); Mage::log("Loading layout file $filename"); if (!is_readable($filename)) { continue; } // added logging statement below Mage::log("Loading layout file $filename"); $fileStr = file_get_contents($filename); $fileStr = str_replace($this->_subst['from'], $this->_subst['to'], $fileStr); $fileXml = simplexml_load_string($fileStr, $elementClass); if (!$fileXml instanceof SimpleXMLElement) { continue; } $layoutStr .= $fileXml->innerXml(); #$layoutXml->appendChild($fileXml); } // ...some lines omitted here... }
Configuration
The
loadFile()
function inlib/Varien/Simplexml/Config.php
is what actually loads config XML files. Adding some logging statements in here will show you exactly which XML files are getting loaded, but as it's executed before the built-in Magento logging functionality, we need to use a more basic method. (New lines are betweenfopen()
andfclose()
inclusive - remember to change the path to something that makes sense for you.)public function loadFile($filePath) { if (!is_readable($filePath)) { //throw new Exception('Can not read xml file '.$filePath); return false; } // new lines added below $log = fopen("/var/www/magento/var/log/xml.log", "a"); fwrite($log, "Loading XML file: $filePath\n"); fclose($log); // end of new lines $fileData = file_get_contents($filePath); $fileData = $this->processFileData($fileData); return $this->loadString($fileData, $this->_elementClass); }
Instrumenting the core code with logging statements is certainly a down and dirty approach, but sometimes it's useful to check exactly what's getting loaded without going to the effort of firing up a debugger.