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.phpis responsible for translating block paths (i.e.adminhtml/sales_order) into a filename (i.e.app/code/core/Mage/Adminhtml/Block/Sales/Order/Grid.phpor 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.phptakes 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 = $blockandMage::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.phpis 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.phpis 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.