Tuesday, December 8, 2015

Disable all community and local (non-core) modules in Magento

Sometimes when something is not working properly on a Magento shop, it is very useful to disable some modules, to see if one of them is causing the problem. Magento has a standard feature, that allows you to disable all the local modules, editing the local.xml, finding "<disable_local_modules>false</disable_local_modules>" and replacing false with true.

This feature is nice, but it doesn't help in two situations:
  • when you want to deactivate community modules also. In this case, you can use something as described in this blog post.
  • when you want to disable all the modules but then re-enable a few of them.
For the second situation, I wrote a simple shell script that creates a "modules deactivator" under app/etc/modules, which disables all the non-core modules. After the script finishes, you can go to this "modules deactivator" XML, and enable the modules you want, so you can test each module individually.

The script consists of two files: a bash script, and a PHP script, used to get the modules that should be deactivated.

This is the bash script:
#!/bin/sh
MODULES_DEACTIVATOR_FILE=app/etc/modules/zzzzz_DisableModules.xml
SCRIPT_FOLDER="`dirname ${BASH_SOURCE[0]}`"
PHP_BIN=php
echo "<?xml version=\"1.0\"?>" > $MODULES_DEACTIVATOR_FILE
echo "<config>" >> $MODULES_DEACTIVATOR_FILE
echo " <modules>" >> $MODULES_DEACTIVATOR_FILE
for m in $($PHP_BIN $SCRIPT_FOLDER/active_non_core_modules.php)
do
echo " <$m>" >> $MODULES_DEACTIVATOR_FILE
echo " <active>false</active>" >> $MODULES_DEACTIVATOR_FILE
echo " </$m>" >> $MODULES_DEACTIVATOR_FILE
done
echo " </modules>" >> $MODULES_DEACTIVATOR_FILE
echo "</config>" >> $MODULES_DEACTIVATOR_FILE

And this is the PHP script:
<?php
require_once('app/Mage.php');
$modules = Mage::app()->getConfig()->getNode('modules')->asCanonicalArray();
$modules = array_filter($modules, function ($module) {
return $module['codePool'] != 'core' && $module['active'] === 'true';
});
echo(implode(PHP_EOL, array_keys($modules)));

To use them, just save the two scripts in the same folder (the PHP script must be named active_non_core_modules.php), and then run the bash script, from the Magento root folder.

Tuesday, October 13, 2015

Download modules from Magento Connect with a single click

If you are a developer and work with Magento, it is very likely that you don't use Magento Connect to download modules. Magento Connect was made to simplify the process of installing modules for people that don't have a solid background on development, which makes it potentially harmful.

There are a few websites which allow you to download a module through them, entering the extension key, or searching through a list of modules like these:

I read this article that explains how to download a module, manually generating the URL of the module package, based on the data found on the module page. Using this information I wrote this small script, that when executed on a Magento Connect module page, opens a new window that causes the module package download to start:

var lastVersion = jQuery(".extension-version li")
    .first().contents().last()
    .text().trim();

jQuery("#button-purchase-input").click();
jQuery("#connect-version-id").val(2);
jQuery("#licence-agreement-checkbox").click();
jQuery("#get-extension-button-free").click();

var magentoConnectKey = jQuery("#extension-key-input").val();
var moduleName = magentoConnectKey.replace(/.*\/([^/]*)/, "$1");

window.open(
    magentoConnectKey + "/" +
    lastVersion + "/" +
    moduleName + "-" +
    lastVersion + ".tgz");

What the code does is quite clear: it just clicks on some elements, gets the last version and the module key from the page, generates the URL and opens it on a new window.

I added this code to my favorites, and now, all I have to do to download a module is to go to the module page on Magento Connect and click the favorites button on the browser.

To add the script to the browser favorites you need to add the prefix "javascript:", so the browser interprets whatever comes next as a JavaScript code. Here is a minified vesion ready to paste:

javascript:(function(){var e=jQuery(".extension-version li").first().contents().last().text().trim();jQuery("#button-purchase-input").click(),jQuery("#connect-version-id").val(2),jQuery("#licence-agreement-checkbox").click(),jQuery("#get-extension-button-free").click();var n=jQuery("#extension-key-input").val(),t=n.replace(/.*\/([^/]*)/,"$1");window.open(n+"/"+e+"/"+t+"-"+e+".tgz")})();