Server side validation for configuration values in Magento with backend: an how-to

I wrote few times ago a tutorial which explains that we can validate configuration values in Magento from the client side

But as you know, (and it’s not valid only for Magento) even if you validate the format from client side, you must also validate data from server side: this is the only way to be sure that expected data has been provided

The model provided by Magento to validate data is the backend

What is a backend?

Backend introduction

A backend is a model object used to do treatments from server side.

The common usage for these backends is to make post treatments when saving configurations values or attributes

Default structure for Magento backend configuration

In Magento, backends are models and so, are called with getModel instruction. This is done by the following instruction in Mage_Adminhtml_Block_System_Config_Form class:

So as you can see in the source code screenshot, backend models used for configuration values must be instances of Mage_Core_Model_Config_Data

Ok, it’s fine, but what are their roles?

Common Magento backend configuration usage

Magento backend has two majors roles. All is based on the fact that Mage_Core_Model_Config_Data class extends Varien_Object class, and so, can have the common method structures _beforeX and _afterX. Here’s their common usage:

Validate data: the _beforeSave Event

This step is launched on the _beforeSave method: you make your controls on this event, and if the value is not the expected one, you throw an Exception. It will be catched in higher level, and will be displayed in configuration form

Data won’t be saved if there is an error on this event

Prepare data: the _beforeSave Event

The _beforeSave method can also be useful to format data

Data won’t be saved if there is an error on this event

Do post treatment: the afterSave Event

Post treatments will be done after data has been saved. In configuration values, they are realized after configuration is recorded in core_config_data table

If you throw an error in this step, configuration value is already saved

Other possibles Magento backend usage

Mage_Core_Model_Config_Data extends Varien_Object and so, all the events availables on this class can also be used on a defined backend model. But for now, I haven’t seen their usage. Do you?

Ok, nice, backend seems really fine. But how can we define our own backends models?

How to define a backend for a configuration value in Magento?

This is very easy with Magento API for configuration values: we have only to define a node backend_model for our field structure. All is done in your system.xml module file

Here’s an example of backend_model definition:

For this field frequency, we will define our backend model MExplained_Criteo_Model_System_Config_Backend_Criteo_Cron

If backend_model node is not defined in system.xml field, there is no backend defined for our configuration field, and so, no treatment made server-side

Conclusion on Magento backend models

Backend models are classes which allow you to make pre and post treatments from server side. This is the only secure way to ensure that expected data has been provided!

I’ve used the Configuration API as example because I’ve found this API very simple and a good example for backend usage. But all functionnalities provided for backend configuration data is also available for attributes. Take a look at the eav_attribute table and you’ll see that you can also provide your own backend models for your attributes (except that they do not extend the same class)

Backend models are Magento models and so, can also be overwritten like other magento classes

With client-side validation, you’ll have a complete toolkit to validate configuration values. And as you can see, validating these data from server side and client side should not be more than half an hour. So it’s a shame to see that numbers of modules do not use these validations. For example, Owebia_Shipping module, a shipping module requires to set up a json configuration value. If this module had a backend usage to validate that configuration value provided is a valid json string, perhaps many of you would have gained time. That’s what you call  quality of service, no?

No packages listed in Magento connect manager, what’s wrong?

If you go into your Magento connect administrative panel, perhaps there is no packages listed in. Why?

This post will explain why there is no package in, if this is really a problem and which solutions you have to update your Magento

How does the Magento connect administrative panel works?

First, take a look at how this administrative panel works

In first releases, Magento installer was based upon pear installer. In 1.5 kernel and above, it’s been replaced with a specific mage installer. In this post, we’ll first study pear case and afterwards mage installer case

Magento connect packages list for pear installers (Magento CE below 1.5 and below Magento Enterprise Edition 1.10)

In these Magento versions the pear installer is in the Magento root directory

This file is a shell script which provides many functionnalities to deploy packages; all availables functions from this shell scripts are runned by a PEAR php script called pear

Here’s the detail of available commands

Commands:
build      Build an Extension From C Source
bundle      Unpacks a Pecl Package
channel-add      Add a Channel
channel-alias      Specify an alias to a channel name
channel-delete      Remove a Channel From the List
channel-discover      Initialize a Channel from its server
channel-info      Retrieve Information on a Channel
channel-update      Update an Existing Channel
clear-cache      Clear Web Services Cache
config-create      Create a Default configuration file
config-get      Show One Setting
config-help      Show Information About Setting
config-set      Change Setting
config-show      Show All Settings
convert      Convert a package.xml 1.0 to package.xml 2.0 format
cvsdiff      Run a "cvs diff" for all files in a package
cvstag      Set CVS Release Tag
download      Download Package
download-all      Downloads each available package from the default channel
info      Display information about a package
install      Install Package
list      List Installed Packages In The Default Channel
list-all      List All Packages
list-categories      List All Categories
list-category      List All Packages of a Category
list-channels      List Available Channels
list-files      List Files In Installed Package
list-packages      List All Packages of a Channel
list-upgrades      List Available Upgrades
login      Connects and authenticates to remote server
logout      Logs out from the remote server
mage-package      Build Magento Package
makerpm      Builds an RPM spec file from a PEAR package
package      Build Package
package-dependencies      Show package dependencies
package-validate      Validate Package Consistency
pickle      Build PECL Package
remote-info      Information About Remote Packages
remote-install      Install Package
remote-list      List Remote Packages
remote-uninstall      Un-install Package
remote-upgrade      Upgrade Package
remote-upgrade-all      Upgrade All Packages
run-scripts      Run Post-Install Scripts bundled with a package
run-tests      Run Regression Tests
search      Search remote package database
shell-test      Shell Script Test
sign      Sign a package distribution file
uninstall      Un-install Package
update-channels      Update the Channel List
upgrade      Upgrade Package
upgrade-all      Upgrade All Packages
Usage: pear [options] command [command-options] Type "pear help options" to list all options.
Type "pear help shortcuts" to list all command shortcuts.
Type "pear help <command></command>" to get the help for the specified command.

By default, this PHP script is located in downloader/pearlib folder

This is this script which installs, upgrades, removes your modules coming from magento connect

How does  the PEAR installer script run to install a module coming from magento connect?

First, It could be interesting to make a quick reminder about pear channels.

Pear channels

What is a pear channel?

A pear channel is a repository where to look for packages. Magento use two pear channels, one for core and one for the community modules

In Magento connect administrative panel we have the details of which package is installed and from which channel it comes from :

What happens when you install a module from the Magento connect administrative panel?

When you provide a module key in Magento connect manager interface, it’ll provide the install command to the pear installer. Running this command will download a copy of the package, intall the package, but also keep a record of the installed packages in local to be able to know what is installed in

These traces are kept in the folder downloader/pearlib/php/.registry/%channelname%/%module_identifier%.reg

These registry files contain changelog, descriptives data for installed module

Here’s an example of generated registry file for Translation module fr_FR

a:21:{s:7:"attribs";a:6:{s:15:"packagerversion";s:5:"1.7.1";s:7:"version";s:3:"2.0";s:5:"xmlns";s:35:"http://pear.php.net/dtd/package-2.0";s:11:"xmlns:tasks";s:33:"http://pear.php.net/dtd/tasks-1.0";s:9:"xmlns:xsi";s:41:"http://www.w3.org/2001/XMLSchema-instance";s:18:"xsi:schemaLocation";s:159:"http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd";}s:4:"name";s:27:"Locale_Mage_community_fr_FR";s:7:"channel";s:37:"connect.magentocommerce.com/community";s:7:"summary";s:57:"Magento Community Modules - French (France) Language Pack";s:11:"description";s:156:"Magento Community Modules - French (France) Language Pack</code><code>
Ce pack contient les fichiers de traductions française de Magento ainsi que les emails traduits.";s:4:"lead";a:4:{s:4:"name";s:3:"SeL";s:4:"user";s:10:"seb.lepers";s:5:"email";s:20:"seb.lepers@gmail.com";s:6:"active";s:3:"yes";}s:4:"date";s:10:"2010-08-24";s:4:"time";s:8:"13:18:09";s:7:"version";a:2:{s:7:"release";s:7:"1.4.1.1";s:3:"api";s:7:"1.4.1.0";}s:9:"stability";a:2:{s:7:"release";s:6:"stable";s:3:"api";s:6:"stable";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:47:"http://www.opensource.org/licenses/academic.php";}s:8:"_content";s:8:"AFL v3.0";}s:5:"notes";s:1512:"v1.4.1.1 :
- Correction du bug BO : produits téléchargeables.
- Correction du bug BO : Instance de widgets.v1.4.1.0 :
- Mise à jour pour Magento CE v1.4.1v1.4.0.0 :
- Mise à jour pour Magento CE v1.4v1.3.0.4 :
- Pas de modifications. Extension repackagée suite à des pbs sur Magento Connect

v1.3.0.1 Ã v1.3.0.3 :
- Ajout de libellés manquants

v1.3.0 :
- Mise à jour pour Magento v1.3.0
- Ajout de libellés manquants

v1.2.0.2 :
- Correction de l'erreur de manip de la v1.2.0.1.1. Retour à la v1.2.0.1.

v1.2.0.1.1 :
- Erreur de publication à l'aide des outils Varien

v1.2.0.1 :
- Ajout de libellés manquants (merci à Arnaud)

v1.2.0 :
- Ajout des nouveaux libellés de la v1.2.x de Magento (merci à Benoît et Kiwii)

v1.1.7 :
- Correction d'un libellé qui provoque une erreur javascript : "Saisissez une liste d\'adresses email valides, séparées par des virgules. Par exemple, jeandupond@domaine.com, martindupond@domaine.com"

v1.1.6 :
- Mise à jour pour la v1.1.7
- Correction du bug des produits bundle et des options personnalisables.
- Ajout de la traduction de plusieurs termes non traduits auparavant

v1.1.5 :
- Suppression d'un fichier inutile.

v1.1.4 :
- Mise à jour du libellé "Quantité définie par l\'utilisateur" dans Mage_Bundle.csv qui cause un bug javascript.

v1.1.3 :
- Attention, les emails contenus dans cette publication ne sont pas compatibles avec la version 1.0 de Magento.
Les fichiers csv de traduction sont compatibles avec la v1.0.";s:8:"contents";a:1:{s:3:"dir";a:2:{s:7:"attribs";a:1:{s:4:"name";s:1:"/";}s:4:"file";a:95:{i:0;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"71d633d3ddbb70b4c544649fcc44341e";s:4:"name";s:52:"adminhtml/default/default/locale/fr_FR/translate.csv";s:4:"role";s:10:"magedesign";}}i:1;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"a984775727bdca41c5bbef44db2fae2a";s:4:"name";s:49:"frontend/default/blank/locale/fr_FR/translate.csv";s:4:"role";s:10:"magedesign";}}i:2;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"a984775727bdca41c5bbef44db2fae2a";s:4:"name";s:51:"frontend/default/default/locale/fr_FR/translate.csv";s:4:"role";s:10:"magedesign";}}i:3;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"a984775727bdca41c5bbef44db2fae2a";s:4:"name";s:50:"frontend/default/iphone/locale/fr_FR/translate.csv";s:4:"role";s:10:"magedesign";}}i:4;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"a984775727bdca41c5bbef44db2fae2a";s:4:"name";s:50:"frontend/default/modern/locale/fr_FR/translate.csv";s:4:"role";s:10:"magedesign";}}i:5;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"792ccb1d53f6d27a81a37be9063d66df";s:4:"name";s:46:"fr_FR/template/email/sales/creditmemo_new.html";s:4:"role";s:10:"magelocale";}}i:6;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"a009dd9012612dcee37ff548239db582";s:4:"name";s:52:"fr_FR/template/email/sales/creditmemo_new_guest.html";s:4:"role";s:10:"magelocale";}}i:7;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"2dd40d3298287fa89cf5dad6712cdbd4";s:4:"name";s:49:"fr_FR/template/email/sales/creditmemo_update.html";s:4:"role";s:10:"magelocale";}}i:8;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"3c02aab13fca7c62eb873aa86dfff145";s:4:"name";s:55:"fr_FR/template/email/sales/creditmemo_update_guest.html";s:4:"role";s:10:"magelocale";}}i:9;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"d7dc60810af4d0f181f82edc2ba13942";s:4:"name";s:43:"fr_FR/template/email/sales/invoice_new.html";s:4:"role";s:10:"magelocale";}}i:10;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"80a94334d74588e257e31ec4089062a9";s:4:"name";s:49:"fr_FR/template/email/sales/invoice_new_guest.html";s:4:"role";s:10:"magelocale";}}i:11;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"ebc47b689c6bd0725d3609f43f3dac09";s:4:"name";s:46:"fr_FR/template/email/sales/invoice_update.html";s:4:"role";s:10:"magelocale";}}i:12;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"5fb0662dce045b7eda2dfeada45c9aea";s:4:"name";s:52:"fr_FR/template/email/sales/invoice_update_guest.html";s:4:"role";s:10:"magelocale";}}i:13;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"8e8d6ebd430eb14574734261c376c6a1";s:4:"name";s:41:"fr_FR/template/email/sales/order_new.html";s:4:"role";s:10:"magelocale";}}i:14;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"7537a662ab07b8bc9948a8263815a006";s:4:"name";s:47:"fr_FR/template/email/sales/order_new_guest.html";s:4:"role";s:10:"magelocale";}}i:15;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"729b18a769fe25b2c17a30bd51c9bb64";s:4:"name";s:44:"fr_FR/template/email/sales/order_update.html";s:4:"role";s:10:"magelocale";}}i:16;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"7aaac07e52adcd00222dc911e12b8827";s:4:"name";s:50:"fr_FR/template/email/sales/order_update_guest.html";s:4:"role";s:10:"magelocale";}}i:17;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"3382d035e3eb0c5ec1e87a9ceea8b58e";s:4:"name";s:44:"fr_FR/template/email/sales/shipment_new.html";s:4:"role";s:10:"magelocale";}}i:18;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"c54b4d6859037d40047ce35aa492bd30";s:4:"name";s:50:"fr_FR/template/email/sales/shipment_new_guest.html";s:4:"role";s:10:"magelocale";}}i:19;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"6b3c50ccea978c779a28d6cf47a03cdd";s:4:"name";s:47:"fr_FR/template/email/sales/shipment_update.html";s:4:"role";s:10:"magelocale";}}i:20;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"0e2b813f34d32eab2e42f3da6e6f4a19";s:4:"name";s:53:"fr_FR/template/email/sales/shipment_update_guest.html";s:4:"role";s:10:"magelocale";}}i:21;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"66aab6382880363b7e690586dbc3d091";s:4:"name";s:37:"fr_FR/template/email/account_new.html";s:4:"role";s:10:"magelocale";}}i:22;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"67f5ff30cf27cf4c8048121f828635e3";s:4:"name";s:50:"fr_FR/template/email/account_new_confirmation.html";s:4:"role";s:10:"magelocale";}}i:23;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"440d40ebe9888624c74c2c40f9ec9d9b";s:4:"name";s:47:"fr_FR/template/email/account_new_confirmed.html";s:4:"role";s:10:"magelocale";}}i:24;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"b2e4fa1fbd64b1c3a3cf758cbc5ae748";s:4:"name";s:44:"fr_FR/template/email/admin_password_new.html";s:4:"role";s:10:"magelocale";}}i:25;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"9a5af8f947771c5825abfdb644cf7da9";s:4:"name";s:38:"fr_FR/template/email/contact_form.html";s:4:"role";s:10:"magelocale";}}i:26;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"b817ac36358b1152c8277c89553e9b7e";s:4:"name";s:49:"fr_FR/template/email/currency_update_warning.html";s:4:"role";s:10:"magelocale";}}i:27;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"fb309621970d1e38b3ed24d257c57d73";s:4:"name";s:43:"fr_FR/template/email/log_clean_warning.html";s:4:"role";s:10:"magelocale";}}i:28;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"d813d9b665c4b9cb0b38066967e0d498";s:4:"name";s:52:"fr_FR/template/email/moneybookers_activateemail.html";s:4:"role";s:10:"magelocale";}}i:29;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"1118bb0453dd56d8945ed6a72e079e5e";s:4:"name";s:51:"fr_FR/template/email/newsletter_subscr_confirm.html";s:4:"role";s:10:"magelocale";}}i:30;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"da140e1409bf1b7a0ed4403a6fed8cc3";s:4:"name";s:51:"fr_FR/template/email/newsletter_subscr_success.html";s:4:"role";s:10:"magelocale";}}i:31;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"e6f63f91c4753f6be980a0295cef0e5c";s:4:"name";s:50:"fr_FR/template/email/newsletter_unsub_success.html";s:4:"role";s:10:"magelocale";}}i:32;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"1f9c73cf005de7659b0a14606ab25989";s:4:"name";s:38:"fr_FR/template/email/password_new.html";s:4:"role";s:10:"magelocale";}}i:33;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"7a5b527e33f74e7eb800b329e54067d2";s:4:"name";s:40:"fr_FR/template/email/payment_failed.html";s:4:"role";s:10:"magelocale";}}i:34;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"398cd111d4225bf1ca1149c955f984b0";s:4:"name";s:50:"fr_FR/template/email/product_alert_cron_error.html";s:4:"role";s:10:"magelocale";}}i:35;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"dc747aff89368d8ae1c22e630dbc4688";s:4:"name";s:45:"fr_FR/template/email/product_price_alert.html";s:4:"role";s:10:"magelocale";}}i:36;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"be0de6147d5fe21b79f7df3180246f80";s:4:"name";s:39:"fr_FR/template/email/product_share.html";s:4:"role";s:10:"magelocale";}}i:37;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"53d7720b16c28b8b579cb53eec685516";s:4:"name";s:45:"fr_FR/template/email/product_stock_alert.html";s:4:"role";s:10:"magelocale";}}i:38;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"d34453bb8fb40d9226056e659901c55a";s:4:"name";s:50:"fr_FR/template/email/sitemap_generate_warning.html";s:4:"role";s:10:"magelocale";}}i:39;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"7a483d164d9340407a8af1730cd15247";s:4:"name";s:40:"fr_FR/template/email/wishlist_share.html";s:4:"role";s:10:"magelocale";}}i:40;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"36a1d8ada9e41f93b356124ff116b627";s:4:"name";s:24:"fr_FR/Mage_Adminhtml.csv";s:4:"role";s:10:"magelocale";}}i:41;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"77b702483b37b9eb7ca00c45e7bbe103";s:4:"name";s:32:"fr_FR/Mage_AdminNotification.csv";s:4:"role";s:10:"magelocale";}}i:42;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"f4603badcb22ba590e57b0f8f3c82996";s:4:"name";s:18:"fr_FR/Mage_Api.csv";s:4:"role";s:10:"magelocale";}}i:43;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"a4d4d2f1cb5034fe3426f8b5b6545ad4";s:4:"name";s:21:"fr_FR/Mage_Backup.csv";s:4:"role";s:10:"magelocale";}}i:44;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"59306efa4e25ab71f43df17cc242c16f";s:4:"name";s:21:"fr_FR/Mage_Bundle.csv";s:4:"role";s:10:"magelocale";}}i:45;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"ff6ed52c6b455b0f08e99d19aceae8a1";s:4:"name";s:22:"fr_FR/Mage_Catalog.csv";s:4:"role";s:10:"magelocale";}}i:46;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"f897cfb97e995bb0cf97484d2ea795df";s:4:"name";s:31:"fr_FR/Mage_CatalogInventory.csv";s:4:"role";s:10:"magelocale";}}i:47;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"52eb0a351ad219b3ad85854af6e2b4f2";s:4:"name";s:26:"fr_FR/Mage_CatalogRule.csv";s:4:"role";s:10:"magelocale";}}i:48;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"796e9b439592eba0eaed5d72d57b26a5";s:4:"name";s:28:"fr_FR/Mage_CatalogSearch.csv";s:4:"role";s:10:"magelocale";}}i:49;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"60c62ea73f02b27f149712de5e2cc371";s:4:"name";s:23:"fr_FR/Mage_Centinel.csv";s:4:"role";s:10:"magelocale";}}i:50;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"735cbcac3f8eefb820421d04cf8ad704";s:4:"name";s:23:"fr_FR/Mage_Checkout.csv";s:4:"role";s:10:"magelocale";}}i:51;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"d760742b71f9774d418e6bdd599a6599";s:4:"name";s:18:"fr_FR/Mage_Cms.csv";s:4:"role";s:10:"magelocale";}}i:52;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"e5f394fe8c96de83bb9d4c2537bde548";s:4:"name";s:23:"fr_FR/Mage_Compiler.csv";s:4:"role";s:10:"magelocale";}}i:53;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"fe4895a407f015be43d3300d9302978b";s:4:"name";s:23:"fr_FR/Mage_Contacts.csv";s:4:"role";s:10:"magelocale";}}i:54;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"65164a911bd38a3f86e03a3471f2d68d";s:4:"name";s:19:"fr_FR/Mage_Core.csv";s:4:"role";s:10:"magelocale";}}i:55;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"3a9f1ce181ad4cbc789106b6c290edbf";s:4:"name";s:19:"fr_FR/Mage_Cron.csv";s:4:"role";s:10:"magelocale";}}i:56;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"19f1d85bda27632fab31fc2b1097cd13";s:4:"name";s:23:"fr_FR/Mage_Customer.csv";s:4:"role";s:10:"magelocale";}}i:57;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"ae1d6dbbf6279998090ed3dd1c707696";s:4:"name";s:23:"fr_FR/Mage_Dataflow.csv";s:4:"role";s:10:"magelocale";}}i:58;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"27097055468249f4f1d2c3e4cfd10130";s:4:"name";s:24:"fr_FR/Mage_Directory.csv";s:4:"role";s:10:"magelocale";}}i:59;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"086db5ecd25d482e4a23236d4bf22d9c";s:4:"name";s:27:"fr_FR/Mage_Downloadable.csv";s:4:"role";s:10:"magelocale";}}i:60;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"d805015d6b3a155cc5ba24e3919976af";s:4:"name";s:18:"fr_FR/Mage_Eav.csv";s:4:"role";s:10:"magelocale";}}i:61;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"1ed8e393a4db6b1899978b640840b6cf";s:4:"name";s:26:"fr_FR/Mage_GiftMessage.csv";s:4:"role";s:10:"magelocale";}}i:62;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"edaef8b5d210beeab93bc752d7b26254";s:4:"name";s:30:"fr_FR/Mage_GoogleAnalytics.csv";s:4:"role";s:10:"magelocale";}}i:63;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"c802be6385758a4fb6f70b46c061ae0d";s:4:"name";s:25:"fr_FR/Mage_GoogleBase.csv";s:4:"role";s:10:"magelocale";}}i:64;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"b9470c3b8445a01cbbb335de9bbda6cf";s:4:"name";s:29:"fr_FR/Mage_GoogleCheckout.csv";s:4:"role";s:10:"magelocale";}}i:65;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"91cdedabe192b4573cdd2883766fdf0a";s:4:"name";s:30:"fr_FR/Mage_GoogleOptimizer.csv";s:4:"role";s:10:"magelocale";}}i:66;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"100eec3ba3a98a63ae77b150cb798345";s:4:"name";s:20:"fr_FR/Mage_Index.csv";s:4:"role";s:10:"magelocale";}}i:67;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"72fde788987e968851c14f3b28891caf";s:4:"name";s:22:"fr_FR/Mage_Install.csv";s:4:"role";s:10:"magelocale";}}i:68;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"8610c95597116b7d818f4483230f7a17";s:4:"name";s:18:"fr_FR/Mage_Log.csv";s:4:"role";s:10:"magelocale";}}i:69;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"f7d048dd697a615089d420e8a2c76b4f";s:4:"name";s:20:"fr_FR/Mage_Media.csv";s:4:"role";s:10:"magelocale";}}i:70;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"29c1a4759ae106df3c3f81744c995ad1";s:4:"name";s:25:"fr_FR/Mage_Newsletter.csv";s:4:"role";s:10:"magelocale";}}i:71;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"fb5fae25d8b694262cd7ac148cbfed56";s:4:"name";s:19:"fr_FR/Mage_Page.csv";s:4:"role";s:10:"magelocale";}}i:72;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"d0870552a3bb44ab3797d3f89db9fc7c";s:4:"name";s:22:"fr_FR/Mage_Paygate.csv";s:4:"role";s:10:"magelocale";}}i:73;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"2a5c518366644f189e9f085fe645d794";s:4:"name";s:22:"fr_FR/Mage_Payment.csv";s:4:"role";s:10:"magelocale";}}i:74;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"3b8b3f56296752f91097425e39ab1092";s:4:"name";s:21:"fr_FR/Mage_Paypal.csv";s:4:"role";s:10:"magelocale";}}i:75;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"0aee9869770127ea5d8b7a049041b8f3";s:4:"name";s:23:"fr_FR/Mage_PaypalUk.csv";s:4:"role";s:10:"magelocale";}}i:76;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"9d8a8c5e0da3259a91af36ceebfa82a8";s:4:"name";s:19:"fr_FR/Mage_Poll.csv";s:4:"role";s:10:"magelocale";}}i:77;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"175bbcc33a9c3b59d5911bb367694d3f";s:4:"name";s:27:"fr_FR/Mage_ProductAlert.csv";s:4:"role";s:10:"magelocale";}}i:78;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"ceed8548dde1b0205a373283e6c46d85";s:4:"name";s:21:"fr_FR/Mage_Rating.csv";s:4:"role";s:10:"magelocale";}}i:79;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"0c5e9f9dc39ef748894beaec9ea0ffa7";s:4:"name";s:22:"fr_FR/Mage_Reports.csv";s:4:"role";s:10:"magelocale";}}i:80;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"6d4074dc5d64a8eee8446bcc2c06cf22";s:4:"name";s:21:"fr_FR/Mage_Review.csv";s:4:"role";s:10:"magelocale";}}i:81;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"fe1bfa122ac746edd334aa5de08a7279";s:4:"name";s:18:"fr_FR/Mage_Rss.csv";s:4:"role";s:10:"magelocale";}}i:82;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"2a4a52e5ebed88f2f5add6ade208044b";s:4:"name";s:19:"fr_FR/Mage_Rule.csv";s:4:"role";s:10:"magelocale";}}i:83;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"2d8c32fb9872b77814ea4b0cd837b721";s:4:"name";s:20:"fr_FR/Mage_Sales.csv";s:4:"role";s:10:"magelocale";}}i:84;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"fc66733173a21596821c27ffd01c7878";s:4:"name";s:24:"fr_FR/Mage_SalesRule.csv";s:4:"role";s:10:"magelocale";}}i:85;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"ccc16c9c1ff3450a1f47dd8243e5f8c9";s:4:"name";s:25:"fr_FR/Mage_Sendfriend.csv";s:4:"role";s:10:"magelocale";}}i:86;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"8eae9b7888e05f7c0d60bd54e9a78c0c";s:4:"name";s:23:"fr_FR/Mage_Shipping.csv";s:4:"role";s:10:"magelocale";}}i:87;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"e45ae637f371b0b53ca40c68b99b2aea";s:4:"name";s:22:"fr_FR/Mage_Sitemap.csv";s:4:"role";s:10:"magelocale";}}i:88;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"71b385de7c06e476b29cfefddda42146";s:4:"name";s:18:"fr_FR/Mage_Tag.csv";s:4:"role";s:10:"magelocale";}}i:89;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"16707ad526f2838c05d05fd827f18c69";s:4:"name";s:18:"fr_FR/Mage_Tax.csv";s:4:"role";s:10:"magelocale";}}i:90;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"c57ce596baa5166f4fdf2c55e591919d";s:4:"name";s:18:"fr_FR/Mage_Usa.csv";s:4:"role";s:10:"magelocale";}}i:91;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"de391887b77e01b1e935aa927da0bbab";s:4:"name";s:19:"fr_FR/Mage_Weee.csv";s:4:"role";s:10:"magelocale";}}i:92;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"dcee841112b3c60585e70736d6100288";s:4:"name";s:21:"fr_FR/Mage_Widget.csv";s:4:"role";s:10:"magelocale";}}i:93;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"64605b672a312e930aaf84c44bf6e8aa";s:4:"name";s:23:"fr_FR/Mage_Wishlist.csv";s:4:"role";s:10:"magelocale";}}i:94;a:1:{s:7:"attribs";a:3:{s:6:"md5sum";s:32:"bf0b66670c52d8921d9c52f39580be35";s:4:"name";s:30:"fr_FR/Phoenix_Moneybookers.csv";s:4:"role";s:10:"magelocale";}}}}}s:12:"dependencies";a:1:{s:8:"required";a:2:{s:3:"php";a:2:{s:3:"min";s:5:"5.2.0";s:3:"max";s:5:"6.0.0";}s:13:"pearinstaller";a:1:{s:3:"min";s:5:"1.6.2";}}}s:10:"phprelease";s:0:"";s:8:"filelist";a:95:{s:52:"adminhtml/default/default/locale/fr_FR/translate.csv";a:4:{s:6:"md5sum";s:32:"71d633d3ddbb70b4c544649fcc44341e";s:4:"name";s:52:"adminhtml/default/default/locale/fr_FR/translate.csv";s:4:"role";s:10:"magedesign";s:12:"installed_as";s:65:"./app/design/adminhtml/default/default/locale/fr_FR/translate.csv";}s:49:"frontend/default/blank/locale/fr_FR/translate.csv";a:4:{s:6:"md5sum";s:32:"a984775727bdca41c5bbef44db2fae2a";s:4:"name";s:49:"frontend/default/blank/locale/fr_FR/translate.csv";s:4:"role";s:10:"magedesign";s:12:"installed_as";s:62:"./app/design/frontend/default/blank/locale/fr_FR/translate.csv";}s:51:"frontend/default/default/locale/fr_FR/translate.csv";a:4:{s:6:"md5sum";s:32:"a984775727bdca41c5bbef44db2fae2a";s:4:"name";s:51:"frontend/default/default/locale/fr_FR/translate.csv";s:4:"role";s:10:"magedesign";s:12:"installed_as";s:64:"./app/design/frontend/default/default/locale/fr_FR/translate.csv";}s:50:"frontend/default/iphone/locale/fr_FR/translate.csv";a:4:{s:6:"md5sum";s:32:"a984775727bdca41c5bbef44db2fae2a";s:4:"name";s:50:"frontend/default/iphone/locale/fr_FR/translate.csv";s:4:"role";s:10:"magedesign";s:12:"installed_as";s:63:"./app/design/frontend/default/iphone/locale/fr_FR/translate.csv";}s:50:"frontend/default/modern/locale/fr_FR/translate.csv";a:4:{s:6:"md5sum";s:32:"a984775727bdca41c5bbef44db2fae2a";s:4:"name";s:50:"frontend/default/modern/locale/fr_FR/translate.csv";s:4:"role";s:10:"magedesign";s:12:"installed_as";s:63:"./app/design/frontend/default/modern/locale/fr_FR/translate.csv";}s:46:"fr_FR/template/email/sales/creditmemo_new.html";a:4:{s:6:"md5sum";s:32:"792ccb1d53f6d27a81a37be9063d66df";s:4:"name";s:46:"fr_FR/template/email/sales/creditmemo_new.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:59:"./app/locale/fr_FR/template/email/sales/creditmemo_new.html";}s:52:"fr_FR/template/email/sales/creditmemo_new_guest.html";a:4:{s:6:"md5sum";s:32:"a009dd9012612dcee37ff548239db582";s:4:"name";s:52:"fr_FR/template/email/sales/creditmemo_new_guest.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:65:"./app/locale/fr_FR/template/email/sales/creditmemo_new_guest.html";}s:49:"fr_FR/template/email/sales/creditmemo_update.html";a:4:{s:6:"md5sum";s:32:"2dd40d3298287fa89cf5dad6712cdbd4";s:4:"name";s:49:"fr_FR/template/email/sales/creditmemo_update.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:62:"./app/locale/fr_FR/template/email/sales/creditmemo_update.html";}s:55:"fr_FR/template/email/sales/creditmemo_update_guest.html";a:4:{s:6:"md5sum";s:32:"3c02aab13fca7c62eb873aa86dfff145";s:4:"name";s:55:"fr_FR/template/email/sales/creditmemo_update_guest.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:68:"./app/locale/fr_FR/template/email/sales/creditmemo_update_guest.html";}s:43:"fr_FR/template/email/sales/invoice_new.html";a:4:{s:6:"md5sum";s:32:"d7dc60810af4d0f181f82edc2ba13942";s:4:"name";s:43:"fr_FR/template/email/sales/invoice_new.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:56:"./app/locale/fr_FR/template/email/sales/invoice_new.html";}s:49:"fr_FR/template/email/sales/invoice_new_guest.html";a:4:{s:6:"md5sum";s:32:"80a94334d74588e257e31ec4089062a9";s:4:"name";s:49:"fr_FR/template/email/sales/invoice_new_guest.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:62:"./app/locale/fr_FR/template/email/sales/invoice_new_guest.html";}s:46:"fr_FR/template/email/sales/invoice_update.html";a:4:{s:6:"md5sum";s:32:"ebc47b689c6bd0725d3609f43f3dac09";s:4:"name";s:46:"fr_FR/template/email/sales/invoice_update.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:59:"./app/locale/fr_FR/template/email/sales/invoice_update.html";}s:52:"fr_FR/template/email/sales/invoice_update_guest.html";a:4:{s:6:"md5sum";s:32:"5fb0662dce045b7eda2dfeada45c9aea";s:4:"name";s:52:"fr_FR/template/email/sales/invoice_update_guest.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:65:"./app/locale/fr_FR/template/email/sales/invoice_update_guest.html";}s:41:"fr_FR/template/email/sales/order_new.html";a:4:{s:6:"md5sum";s:32:"8e8d6ebd430eb14574734261c376c6a1";s:4:"name";s:41:"fr_FR/template/email/sales/order_new.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:54:"./app/locale/fr_FR/template/email/sales/order_new.html";}s:47:"fr_FR/template/email/sales/order_new_guest.html";a:4:{s:6:"md5sum";s:32:"7537a662ab07b8bc9948a8263815a006";s:4:"name";s:47:"fr_FR/template/email/sales/order_new_guest.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:60:"./app/locale/fr_FR/template/email/sales/order_new_guest.html";}s:44:"fr_FR/template/email/sales/order_update.html";a:4:{s:6:"md5sum";s:32:"729b18a769fe25b2c17a30bd51c9bb64";s:4:"name";s:44:"fr_FR/template/email/sales/order_update.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:57:"./app/locale/fr_FR/template/email/sales/order_update.html";}s:50:"fr_FR/template/email/sales/order_update_guest.html";a:4:{s:6:"md5sum";s:32:"7aaac07e52adcd00222dc911e12b8827";s:4:"name";s:50:"fr_FR/template/email/sales/order_update_guest.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:63:"./app/locale/fr_FR/template/email/sales/order_update_guest.html";}s:44:"fr_FR/template/email/sales/shipment_new.html";a:4:{s:6:"md5sum";s:32:"3382d035e3eb0c5ec1e87a9ceea8b58e";s:4:"name";s:44:"fr_FR/template/email/sales/shipment_new.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:57:"./app/locale/fr_FR/template/email/sales/shipment_new.html";}s:50:"fr_FR/template/email/sales/shipment_new_guest.html";a:4:{s:6:"md5sum";s:32:"c54b4d6859037d40047ce35aa492bd30";s:4:"name";s:50:"fr_FR/template/email/sales/shipment_new_guest.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:63:"./app/locale/fr_FR/template/email/sales/shipment_new_guest.html";}s:47:"fr_FR/template/email/sales/shipment_update.html";a:4:{s:6:"md5sum";s:32:"6b3c50ccea978c779a28d6cf47a03cdd";s:4:"name";s:47:"fr_FR/template/email/sales/shipment_update.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:60:"./app/locale/fr_FR/template/email/sales/shipment_update.html";}s:53:"fr_FR/template/email/sales/shipment_update_guest.html";a:4:{s:6:"md5sum";s:32:"0e2b813f34d32eab2e42f3da6e6f4a19";s:4:"name";s:53:"fr_FR/template/email/sales/shipment_update_guest.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:66:"./app/locale/fr_FR/template/email/sales/shipment_update_guest.html";}s:37:"fr_FR/template/email/account_new.html";a:4:{s:6:"md5sum";s:32:"66aab6382880363b7e690586dbc3d091";s:4:"name";s:37:"fr_FR/template/email/account_new.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:50:"./app/locale/fr_FR/template/email/account_new.html";}s:50:"fr_FR/template/email/account_new_confirmation.html";a:4:{s:6:"md5sum";s:32:"67f5ff30cf27cf4c8048121f828635e3";s:4:"name";s:50:"fr_FR/template/email/account_new_confirmation.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:63:"./app/locale/fr_FR/template/email/account_new_confirmation.html";}s:47:"fr_FR/template/email/account_new_confirmed.html";a:4:{s:6:"md5sum";s:32:"440d40ebe9888624c74c2c40f9ec9d9b";s:4:"name";s:47:"fr_FR/template/email/account_new_confirmed.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:60:"./app/locale/fr_FR/template/email/account_new_confirmed.html";}s:44:"fr_FR/template/email/admin_password_new.html";a:4:{s:6:"md5sum";s:32:"b2e4fa1fbd64b1c3a3cf758cbc5ae748";s:4:"name";s:44:"fr_FR/template/email/admin_password_new.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:57:"./app/locale/fr_FR/template/email/admin_password_new.html";}s:38:"fr_FR/template/email/contact_form.html";a:4:{s:6:"md5sum";s:32:"9a5af8f947771c5825abfdb644cf7da9";s:4:"name";s:38:"fr_FR/template/email/contact_form.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:51:"./app/locale/fr_FR/template/email/contact_form.html";}s:49:"fr_FR/template/email/currency_update_warning.html";a:4:{s:6:"md5sum";s:32:"b817ac36358b1152c8277c89553e9b7e";s:4:"name";s:49:"fr_FR/template/email/currency_update_warning.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:62:"./app/locale/fr_FR/template/email/currency_update_warning.html";}s:43:"fr_FR/template/email/log_clean_warning.html";a:4:{s:6:"md5sum";s:32:"fb309621970d1e38b3ed24d257c57d73";s:4:"name";s:43:"fr_FR/template/email/log_clean_warning.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:56:"./app/locale/fr_FR/template/email/log_clean_warning.html";}s:52:"fr_FR/template/email/moneybookers_activateemail.html";a:4:{s:6:"md5sum";s:32:"d813d9b665c4b9cb0b38066967e0d498";s:4:"name";s:52:"fr_FR/template/email/moneybookers_activateemail.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:65:"./app/locale/fr_FR/template/email/moneybookers_activateemail.html";}s:51:"fr_FR/template/email/newsletter_subscr_confirm.html";a:4:{s:6:"md5sum";s:32:"1118bb0453dd56d8945ed6a72e079e5e";s:4:"name";s:51:"fr_FR/template/email/newsletter_subscr_confirm.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:64:"./app/locale/fr_FR/template/email/newsletter_subscr_confirm.html";}s:51:"fr_FR/template/email/newsletter_subscr_success.html";a:4:{s:6:"md5sum";s:32:"da140e1409bf1b7a0ed4403a6fed8cc3";s:4:"name";s:51:"fr_FR/template/email/newsletter_subscr_success.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:64:"./app/locale/fr_FR/template/email/newsletter_subscr_success.html";}s:50:"fr_FR/template/email/newsletter_unsub_success.html";a:4:{s:6:"md5sum";s:32:"e6f63f91c4753f6be980a0295cef0e5c";s:4:"name";s:50:"fr_FR/template/email/newsletter_unsub_success.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:63:"./app/locale/fr_FR/template/email/newsletter_unsub_success.html";}s:38:"fr_FR/template/email/password_new.html";a:4:{s:6:"md5sum";s:32:"1f9c73cf005de7659b0a14606ab25989";s:4:"name";s:38:"fr_FR/template/email/password_new.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:51:"./app/locale/fr_FR/template/email/password_new.html";}s:40:"fr_FR/template/email/payment_failed.html";a:4:{s:6:"md5sum";s:32:"7a5b527e33f74e7eb800b329e54067d2";s:4:"name";s:40:"fr_FR/template/email/payment_failed.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:53:"./app/locale/fr_FR/template/email/payment_failed.html";}s:50:"fr_FR/template/email/product_alert_cron_error.html";a:4:{s:6:"md5sum";s:32:"398cd111d4225bf1ca1149c955f984b0";s:4:"name";s:50:"fr_FR/template/email/product_alert_cron_error.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:63:"./app/locale/fr_FR/template/email/product_alert_cron_error.html";}s:45:"fr_FR/template/email/product_price_alert.html";a:4:{s:6:"md5sum";s:32:"dc747aff89368d8ae1c22e630dbc4688";s:4:"name";s:45:"fr_FR/template/email/product_price_alert.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:58:"./app/locale/fr_FR/template/email/product_price_alert.html";}s:39:"fr_FR/template/email/product_share.html";a:4:{s:6:"md5sum";s:32:"be0de6147d5fe21b79f7df3180246f80";s:4:"name";s:39:"fr_FR/template/email/product_share.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:52:"./app/locale/fr_FR/template/email/product_share.html";}s:45:"fr_FR/template/email/product_stock_alert.html";a:4:{s:6:"md5sum";s:32:"53d7720b16c28b8b579cb53eec685516";s:4:"name";s:45:"fr_FR/template/email/product_stock_alert.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:58:"./app/locale/fr_FR/template/email/product_stock_alert.html";}s:50:"fr_FR/template/email/sitemap_generate_warning.html";a:4:{s:6:"md5sum";s:32:"d34453bb8fb40d9226056e659901c55a";s:4:"name";s:50:"fr_FR/template/email/sitemap_generate_warning.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:63:"./app/locale/fr_FR/template/email/sitemap_generate_warning.html";}s:40:"fr_FR/template/email/wishlist_share.html";a:4:{s:6:"md5sum";s:32:"7a483d164d9340407a8af1730cd15247";s:4:"name";s:40:"fr_FR/template/email/wishlist_share.html";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:53:"./app/locale/fr_FR/template/email/wishlist_share.html";}s:24:"fr_FR/Mage_Adminhtml.csv";a:4:{s:6:"md5sum";s:32:"36a1d8ada9e41f93b356124ff116b627";s:4:"name";s:24:"fr_FR/Mage_Adminhtml.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:37:"./app/locale/fr_FR/Mage_Adminhtml.csv";}s:32:"fr_FR/Mage_AdminNotification.csv";a:4:{s:6:"md5sum";s:32:"77b702483b37b9eb7ca00c45e7bbe103";s:4:"name";s:32:"fr_FR/Mage_AdminNotification.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:45:"./app/locale/fr_FR/Mage_AdminNotification.csv";}s:18:"fr_FR/Mage_Api.csv";a:4:{s:6:"md5sum";s:32:"f4603badcb22ba590e57b0f8f3c82996";s:4:"name";s:18:"fr_FR/Mage_Api.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:31:"./app/locale/fr_FR/Mage_Api.csv";}s:21:"fr_FR/Mage_Backup.csv";a:4:{s:6:"md5sum";s:32:"a4d4d2f1cb5034fe3426f8b5b6545ad4";s:4:"name";s:21:"fr_FR/Mage_Backup.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:34:"./app/locale/fr_FR/Mage_Backup.csv";}s:21:"fr_FR/Mage_Bundle.csv";a:4:{s:6:"md5sum";s:32:"59306efa4e25ab71f43df17cc242c16f";s:4:"name";s:21:"fr_FR/Mage_Bundle.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:34:"./app/locale/fr_FR/Mage_Bundle.csv";}s:22:"fr_FR/Mage_Catalog.csv";a:4:{s:6:"md5sum";s:32:"ff6ed52c6b455b0f08e99d19aceae8a1";s:4:"name";s:22:"fr_FR/Mage_Catalog.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:35:"./app/locale/fr_FR/Mage_Catalog.csv";}s:31:"fr_FR/Mage_CatalogInventory.csv";a:4:{s:6:"md5sum";s:32:"f897cfb97e995bb0cf97484d2ea795df";s:4:"name";s:31:"fr_FR/Mage_CatalogInventory.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:44:"./app/locale/fr_FR/Mage_CatalogInventory.csv";}s:26:"fr_FR/Mage_CatalogRule.csv";a:4:{s:6:"md5sum";s:32:"52eb0a351ad219b3ad85854af6e2b4f2";s:4:"name";s:26:"fr_FR/Mage_CatalogRule.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:39:"./app/locale/fr_FR/Mage_CatalogRule.csv";}s:28:"fr_FR/Mage_CatalogSearch.csv";a:4:{s:6:"md5sum";s:32:"796e9b439592eba0eaed5d72d57b26a5";s:4:"name";s:28:"fr_FR/Mage_CatalogSearch.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:41:"./app/locale/fr_FR/Mage_CatalogSearch.csv";}s:23:"fr_FR/Mage_Centinel.csv";a:4:{s:6:"md5sum";s:32:"60c62ea73f02b27f149712de5e2cc371";s:4:"name";s:23:"fr_FR/Mage_Centinel.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:36:"./app/locale/fr_FR/Mage_Centinel.csv";}s:23:"fr_FR/Mage_Checkout.csv";a:4:{s:6:"md5sum";s:32:"735cbcac3f8eefb820421d04cf8ad704";s:4:"name";s:23:"fr_FR/Mage_Checkout.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:36:"./app/locale/fr_FR/Mage_Checkout.csv";}s:18:"fr_FR/Mage_Cms.csv";a:4:{s:6:"md5sum";s:32:"d760742b71f9774d418e6bdd599a6599";s:4:"name";s:18:"fr_FR/Mage_Cms.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:31:"./app/locale/fr_FR/Mage_Cms.csv";}s:23:"fr_FR/Mage_Compiler.csv";a:4:{s:6:"md5sum";s:32:"e5f394fe8c96de83bb9d4c2537bde548";s:4:"name";s:23:"fr_FR/Mage_Compiler.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:36:"./app/locale/fr_FR/Mage_Compiler.csv";}s:23:"fr_FR/Mage_Contacts.csv";a:4:{s:6:"md5sum";s:32:"fe4895a407f015be43d3300d9302978b";s:4:"name";s:23:"fr_FR/Mage_Contacts.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:36:"./app/locale/fr_FR/Mage_Contacts.csv";}s:19:"fr_FR/Mage_Core.csv";a:4:{s:6:"md5sum";s:32:"65164a911bd38a3f86e03a3471f2d68d";s:4:"name";s:19:"fr_FR/Mage_Core.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:32:"./app/locale/fr_FR/Mage_Core.csv";}s:19:"fr_FR/Mage_Cron.csv";a:4:{s:6:"md5sum";s:32:"3a9f1ce181ad4cbc789106b6c290edbf";s:4:"name";s:19:"fr_FR/Mage_Cron.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:32:"./app/locale/fr_FR/Mage_Cron.csv";}s:23:"fr_FR/Mage_Customer.csv";a:4:{s:6:"md5sum";s:32:"19f1d85bda27632fab31fc2b1097cd13";s:4:"name";s:23:"fr_FR/Mage_Customer.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:36:"./app/locale/fr_FR/Mage_Customer.csv";}s:23:"fr_FR/Mage_Dataflow.csv";a:4:{s:6:"md5sum";s:32:"ae1d6dbbf6279998090ed3dd1c707696";s:4:"name";s:23:"fr_FR/Mage_Dataflow.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:36:"./app/locale/fr_FR/Mage_Dataflow.csv";}s:24:"fr_FR/Mage_Directory.csv";a:4:{s:6:"md5sum";s:32:"27097055468249f4f1d2c3e4cfd10130";s:4:"name";s:24:"fr_FR/Mage_Directory.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:37:"./app/locale/fr_FR/Mage_Directory.csv";}s:27:"fr_FR/Mage_Downloadable.csv";a:4:{s:6:"md5sum";s:32:"086db5ecd25d482e4a23236d4bf22d9c";s:4:"name";s:27:"fr_FR/Mage_Downloadable.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:40:"./app/locale/fr_FR/Mage_Downloadable.csv";}s:18:"fr_FR/Mage_Eav.csv";a:4:{s:6:"md5sum";s:32:"d805015d6b3a155cc5ba24e3919976af";s:4:"name";s:18:"fr_FR/Mage_Eav.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:31:"./app/locale/fr_FR/Mage_Eav.csv";}s:26:"fr_FR/Mage_GiftMessage.csv";a:4:{s:6:"md5sum";s:32:"1ed8e393a4db6b1899978b640840b6cf";s:4:"name";s:26:"fr_FR/Mage_GiftMessage.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:39:"./app/locale/fr_FR/Mage_GiftMessage.csv";}s:30:"fr_FR/Mage_GoogleAnalytics.csv";a:4:{s:6:"md5sum";s:32:"edaef8b5d210beeab93bc752d7b26254";s:4:"name";s:30:"fr_FR/Mage_GoogleAnalytics.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:43:"./app/locale/fr_FR/Mage_GoogleAnalytics.csv";}s:25:"fr_FR/Mage_GoogleBase.csv";a:4:{s:6:"md5sum";s:32:"c802be6385758a4fb6f70b46c061ae0d";s:4:"name";s:25:"fr_FR/Mage_GoogleBase.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:38:"./app/locale/fr_FR/Mage_GoogleBase.csv";}s:29:"fr_FR/Mage_GoogleCheckout.csv";a:4:{s:6:"md5sum";s:32:"b9470c3b8445a01cbbb335de9bbda6cf";s:4:"name";s:29:"fr_FR/Mage_GoogleCheckout.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:42:"./app/locale/fr_FR/Mage_GoogleCheckout.csv";}s:30:"fr_FR/Mage_GoogleOptimizer.csv";a:4:{s:6:"md5sum";s:32:"91cdedabe192b4573cdd2883766fdf0a";s:4:"name";s:30:"fr_FR/Mage_GoogleOptimizer.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:43:"./app/locale/fr_FR/Mage_GoogleOptimizer.csv";}s:20:"fr_FR/Mage_Index.csv";a:4:{s:6:"md5sum";s:32:"100eec3ba3a98a63ae77b150cb798345";s:4:"name";s:20:"fr_FR/Mage_Index.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:33:"./app/locale/fr_FR/Mage_Index.csv";}s:22:"fr_FR/Mage_Install.csv";a:4:{s:6:"md5sum";s:32:"72fde788987e968851c14f3b28891caf";s:4:"name";s:22:"fr_FR/Mage_Install.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:35:"./app/locale/fr_FR/Mage_Install.csv";}s:18:"fr_FR/Mage_Log.csv";a:4:{s:6:"md5sum";s:32:"8610c95597116b7d818f4483230f7a17";s:4:"name";s:18:"fr_FR/Mage_Log.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:31:"./app/locale/fr_FR/Mage_Log.csv";}s:20:"fr_FR/Mage_Media.csv";a:4:{s:6:"md5sum";s:32:"f7d048dd697a615089d420e8a2c76b4f";s:4:"name";s:20:"fr_FR/Mage_Media.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:33:"./app/locale/fr_FR/Mage_Media.csv";}s:25:"fr_FR/Mage_Newsletter.csv";a:4:{s:6:"md5sum";s:32:"29c1a4759ae106df3c3f81744c995ad1";s:4:"name";s:25:"fr_FR/Mage_Newsletter.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:38:"./app/locale/fr_FR/Mage_Newsletter.csv";}s:19:"fr_FR/Mage_Page.csv";a:4:{s:6:"md5sum";s:32:"fb5fae25d8b694262cd7ac148cbfed56";s:4:"name";s:19:"fr_FR/Mage_Page.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:32:"./app/locale/fr_FR/Mage_Page.csv";}s:22:"fr_FR/Mage_Paygate.csv";a:4:{s:6:"md5sum";s:32:"d0870552a3bb44ab3797d3f89db9fc7c";s:4:"name";s:22:"fr_FR/Mage_Paygate.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:35:"./app/locale/fr_FR/Mage_Paygate.csv";}s:22:"fr_FR/Mage_Payment.csv";a:4:{s:6:"md5sum";s:32:"2a5c518366644f189e9f085fe645d794";s:4:"name";s:22:"fr_FR/Mage_Payment.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:35:"./app/locale/fr_FR/Mage_Payment.csv";}s:21:"fr_FR/Mage_Paypal.csv";a:4:{s:6:"md5sum";s:32:"3b8b3f56296752f91097425e39ab1092";s:4:"name";s:21:"fr_FR/Mage_Paypal.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:34:"./app/locale/fr_FR/Mage_Paypal.csv";}s:23:"fr_FR/Mage_PaypalUk.csv";a:4:{s:6:"md5sum";s:32:"0aee9869770127ea5d8b7a049041b8f3";s:4:"name";s:23:"fr_FR/Mage_PaypalUk.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:36:"./app/locale/fr_FR/Mage_PaypalUk.csv";}s:19:"fr_FR/Mage_Poll.csv";a:4:{s:6:"md5sum";s:32:"9d8a8c5e0da3259a91af36ceebfa82a8";s:4:"name";s:19:"fr_FR/Mage_Poll.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:32:"./app/locale/fr_FR/Mage_Poll.csv";}s:27:"fr_FR/Mage_ProductAlert.csv";a:4:{s:6:"md5sum";s:32:"175bbcc33a9c3b59d5911bb367694d3f";s:4:"name";s:27:"fr_FR/Mage_ProductAlert.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:40:"./app/locale/fr_FR/Mage_ProductAlert.csv";}s:21:"fr_FR/Mage_Rating.csv";a:4:{s:6:"md5sum";s:32:"ceed8548dde1b0205a373283e6c46d85";s:4:"name";s:21:"fr_FR/Mage_Rating.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:34:"./app/locale/fr_FR/Mage_Rating.csv";}s:22:"fr_FR/Mage_Reports.csv";a:4:{s:6:"md5sum";s:32:"0c5e9f9dc39ef748894beaec9ea0ffa7";s:4:"name";s:22:"fr_FR/Mage_Reports.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:35:"./app/locale/fr_FR/Mage_Reports.csv";}s:21:"fr_FR/Mage_Review.csv";a:4:{s:6:"md5sum";s:32:"6d4074dc5d64a8eee8446bcc2c06cf22";s:4:"name";s:21:"fr_FR/Mage_Review.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:34:"./app/locale/fr_FR/Mage_Review.csv";}s:18:"fr_FR/Mage_Rss.csv";a:4:{s:6:"md5sum";s:32:"fe1bfa122ac746edd334aa5de08a7279";s:4:"name";s:18:"fr_FR/Mage_Rss.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:31:"./app/locale/fr_FR/Mage_Rss.csv";}s:19:"fr_FR/Mage_Rule.csv";a:4:{s:6:"md5sum";s:32:"2a4a52e5ebed88f2f5add6ade208044b";s:4:"name";s:19:"fr_FR/Mage_Rule.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:32:"./app/locale/fr_FR/Mage_Rule.csv";}s:20:"fr_FR/Mage_Sales.csv";a:4:{s:6:"md5sum";s:32:"2d8c32fb9872b77814ea4b0cd837b721";s:4:"name";s:20:"fr_FR/Mage_Sales.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:33:"./app/locale/fr_FR/Mage_Sales.csv";}s:24:"fr_FR/Mage_SalesRule.csv";a:4:{s:6:"md5sum";s:32:"fc66733173a21596821c27ffd01c7878";s:4:"name";s:24:"fr_FR/Mage_SalesRule.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:37:"./app/locale/fr_FR/Mage_SalesRule.csv";}s:25:"fr_FR/Mage_Sendfriend.csv";a:4:{s:6:"md5sum";s:32:"ccc16c9c1ff3450a1f47dd8243e5f8c9";s:4:"name";s:25:"fr_FR/Mage_Sendfriend.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:38:"./app/locale/fr_FR/Mage_Sendfriend.csv";}s:23:"fr_FR/Mage_Shipping.csv";a:4:{s:6:"md5sum";s:32:"8eae9b7888e05f7c0d60bd54e9a78c0c";s:4:"name";s:23:"fr_FR/Mage_Shipping.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:36:"./app/locale/fr_FR/Mage_Shipping.csv";}s:22:"fr_FR/Mage_Sitemap.csv";a:4:{s:6:"md5sum";s:32:"e45ae637f371b0b53ca40c68b99b2aea";s:4:"name";s:22:"fr_FR/Mage_Sitemap.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:35:"./app/locale/fr_FR/Mage_Sitemap.csv";}s:18:"fr_FR/Mage_Tag.csv";a:4:{s:6:"md5sum";s:32:"71b385de7c06e476b29cfefddda42146";s:4:"name";s:18:"fr_FR/Mage_Tag.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:31:"./app/locale/fr_FR/Mage_Tag.csv";}s:18:"fr_FR/Mage_Tax.csv";a:4:{s:6:"md5sum";s:32:"16707ad526f2838c05d05fd827f18c69";s:4:"name";s:18:"fr_FR/Mage_Tax.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:31:"./app/locale/fr_FR/Mage_Tax.csv";}s:18:"fr_FR/Mage_Usa.csv";a:4:{s:6:"md5sum";s:32:"c57ce596baa5166f4fdf2c55e591919d";s:4:"name";s:18:"fr_FR/Mage_Usa.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:31:"./app/locale/fr_FR/Mage_Usa.csv";}s:19:"fr_FR/Mage_Weee.csv";a:4:{s:6:"md5sum";s:32:"de391887b77e01b1e935aa927da0bbab";s:4:"name";s:19:"fr_FR/Mage_Weee.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:32:"./app/locale/fr_FR/Mage_Weee.csv";}s:21:"fr_FR/Mage_Widget.csv";a:4:{s:6:"md5sum";s:32:"dcee841112b3c60585e70736d6100288";s:4:"name";s:21:"fr_FR/Mage_Widget.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:34:"./app/locale/fr_FR/Mage_Widget.csv";}s:23:"fr_FR/Mage_Wishlist.csv";a:4:{s:6:"md5sum";s:32:"64605b672a312e930aaf84c44bf6e8aa";s:4:"name";s:23:"fr_FR/Mage_Wishlist.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:36:"./app/locale/fr_FR/Mage_Wishlist.csv";}s:30:"fr_FR/Phoenix_Moneybookers.csv";a:4:{s:6:"md5sum";s:32:"bf0b66670c52d8921d9c52f39580be35";s:4:"name";s:30:"fr_FR/Phoenix_Moneybookers.csv";s:4:"role";s:10:"magelocale";s:12:"installed_as";s:43:"./app/locale/fr_FR/Phoenix_Moneybookers.csv";}}s:12:"_lastversion";N;s:7:"dirtree";a:23:{s:51:"./app/design/adminhtml/default/default/locale/fr_FR";b:1;s:45:"./app/design/adminhtml/default/default/locale";b:1;s:38:"./app/design/adminhtml/default/default";b:1;s:30:"./app/design/adminhtml/default";b:1;s:22:"./app/design/adminhtml";b:1;s:48:"./app/design/frontend/default/blank/locale/fr_FR";b:1;s:42:"./app/design/frontend/default/blank/locale";b:1;s:35:"./app/design/frontend/default/blank";b:1;s:29:"./app/design/frontend/default";b:1;s:21:"./app/design/frontend";b:1;s:50:"./app/design/frontend/default/default/locale/fr_FR";b:1;s:44:"./app/design/frontend/default/default/locale";b:1;s:37:"./app/design/frontend/default/default";b:1;s:49:"./app/design/frontend/default/iphone/locale/fr_FR";b:1;s:43:"./app/design/frontend/default/iphone/locale";b:1;s:36:"./app/design/frontend/default/iphone";b:1;s:49:"./app/design/frontend/default/modern/locale/fr_FR";b:1;s:43:"./app/design/frontend/default/modern/locale";b:1;s:36:"./app/design/frontend/default/modern";b:1;s:39:"./app/locale/fr_FR/template/email/sales";b:1;s:33:"./app/locale/fr_FR/template/email";b:1;s:27:"./app/locale/fr_FR/template";b:1;s:18:"./app/locale/fr_FR";b:1;}s:3:"old";a:7:{s:7:"version";s:7:"1.4.1.1";s:12:"release_date";s:10:"2010-08-24";s:13:"release_state";s:6:"stable";s:15:"release_license";s:8:"AFL v3.0";s:13:"release_notes";s:1512:"v1.4.1.1 :
- Correction du bug BO : produits téléchargeables.
- Correction du bug BO : Instance de widgets.

v1.4.1.0 :
- Mise à jour pour Magento CE v1.4.1

v1.4.0.0 :
- Mise à jour pour Magento CE v1.4

v1.3.0.4 :
- Pas de modifications. Extension repackagée suite à des pbs sur Magento Connect

v1.3.0.1 Ã v1.3.0.3 :
- Ajout de libellés manquants

v1.3.0 :
- Mise à jour pour Magento v1.3.0
- Ajout de libellés manquants

v1.2.0.2 :
- Correction de l'erreur de manip de la v1.2.0.1.1. Retour à la v1.2.0.1.

v1.2.0.1.1 :
- Erreur de publication à l'aide des outils Varien

v1.2.0.1 :
- Ajout de libellés manquants (merci à Arnaud)

v1.2.0 :
- Ajout des nouveaux libellés de la v1.2.x de Magento (merci à Benoît et Kiwii)

v1.1.7 :
- Correction d'un libellé qui provoque une erreur javascript : "Saisissez une liste d\'adresses email valides, séparées par des virgules. Par exemple, jeandupond@domaine.com, martindupond@domaine.com"

v1.1.6 :
- Mise à jour pour la v1.1.7
- Correction du bug des produits bundle et des options personnalisables.
- Ajout de la traduction de plusieurs termes non traduits auparavant

v1.1.5 :
- Suppression d'un fichier inutile.

v1.1.4 :
- Mise à jour du libellé "Quantité définie par l\'utilisateur" dans Mage_Bundle.csv qui cause un bug javascript.

v1.1.3 :
- Attention, les emails contenus dans cette publication ne sont pas compatibles avec la version 1.0 de Magento.
Les fichiers csv de traduction sont compatibles avec la v1.0.";s:12:"release_deps";a:3:{i:0;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"le";s:7:"version";s:5:"6.0.0";s:8:"optional";s:2:"no";}i:1;a:4:{s:4:"type";s:3:"php";s:3:"rel";s:2:"ge";s:7:"version";s:5:"5.2.0";s:8:"optional";s:2:"no";}i:2;a:6:{s:4:"type";s:3:"pkg";s:7:"channel";s:12:"pear.php.net";s:4:"name";s:4:"PEAR";s:3:"rel";s:2:"ge";s:7:"version";s:5:"1.6.2";s:8:"optional";s:2:"no";}}s:11:"maintainers";a:1:{i:0;a:5:{s:4:"name";s:3:"SeL";s:5:"email";s:20:"seb.lepers@gmail.com";s:6:"active";s:3:"yes";s:6:"handle";s:10:"seb.lepers";s:4:"role";s:4:"lead";}}}s:10:"xsdversion";s:3:"2.0";s:13:"_lastmodified";i:1296329840;}

For this example file, the registry file is the following one: downloader/pearlib/php/.registry/.channel.connect.magentocommerce.com_community/locale_mage_community_fr_fr.reg

So the answer of your question is as followed :

If the Magento connect registry file does not exist, the module won't be listed in Magento connect administrative panel

Hum, ok, but I'm under 1.5, Is it the same process?

Magento connect packages list for mage installers (Magento CE above 1.5, Magento Enterprise Edition 1.9)

In these versions, pear installer has been replaced by a magento dedicated installer, mage

Mage installer script

This mage installer script is also located in the root folder of your Magento

Like in the pear install, this mage installer is in charge of the following setup tasks


Connect commands available:
===========================
channel-add      Add a Channel
channel-alias      Specify an alias to a channel name
channel-delete      Remove a Channel From the List
channel-info      Retrieve Information on a Channel
channel-login      Connects and authenticates to remote channel server
channel-logout      Logs out from the remote channel server
clear-cache      Clear Web Services Cache
config-get      Show One Setting
config-help      Show Information About Setting
config-set      Change Setting
config-show      Show All Settings
convert      Convert old magento PEAR package to new format
download      Download Package
info      Display information about a package
install      Install Package
install-file      Install Package Archive File
list-available      List Available Packages
list-channels      List Available Channels
list-files      List Files In Installed Package
list-installed      List Installed Packages In The Default Channel
list-upgrades      List Available Upgrades
package      Build Package
package-dependencies      Show package dependencies
package-prepare      Show installation information of package
sync      Synchronize Manually Installed Packages
sync-pear      Synchronize already Installed Packages by pear
uninstall      Un-install Package
upgrade      Upgrade Package
upgrade-all      Upgrade All Packages

When you manage installed packages from magento connect manager, this is one of these command which is run

Registry with mage installer

There is also in these versions a registry process, but less explicit than the pear's one: All is managed in only one configuration file, cache.cfg, located in downloader folder.

So for these Magento versions, If this file does not exist, your magento installed modules won't be listed

Which reasons can explain that registry files doesn't exist anymore in Magento downloader?

Reasons could be numerous:

  • You've deleted this / these file(s)
  • You've removed the downloader folder from your Magento sources
  • When you have delivered the application sources, you did not provide theses files
  • File is excluded from your versionning system
  • You work with a fresh Magento install coming from Magento website: this reason requires an explain. In availables downloadable versions, there is no registry informations. It's normal, for the community modules, but not for the Magento core's one.
  • You have no write access in the registry folder
  • etc...

Yes, but is it a problem not having these files?

What consequences have these missing registry files in Magento upgrade process and what solutions do we have?

We'll first examine the case of community modules, and then the core modules

Consequences for Magento community modules

It' a shame, but without these registry files, you cannot upgrade theses modules manually. You must rebuild these registry files. But building them manually is a very difficult task. The most relayable are the following ones:

  • Reinstall the module coming from Magento connect
  • Reinstall the module from the package archive

Reinstall a module coming from magento conenct

It's possible to reinstall an already installed magento from your Magento connect manager administrative panel: pear does not control that installed files already exists and so reinstall it will replace existing files and rebuild the registry file

The conditions to be able to do that are:

  • You have not updated the sources files of this package; otherwise, your updates will be overrides
  • Your installed version is the same as in magento connect: if not, I strongly encourage you to test the install on a non-production location
  • You have write access to downloader folder and its subfolders

This is not the cleanest way because it contains somes risks to change how your Magento works, but it's the quickiest way

Reinstall a module from its package backup

If you have not cleaned the downloader package, there is still the downloaded archive in downloader folder

Pear users

You can find the locale download folder by using the following command for pear users:

./pear config-get download_dir

By default, the download temp folder is downloader/pearlib/download

Your packages are located in? Fine, we just have to reinstall it. To do that, you must run the following command:

./pear install %path_to_module_archive.tgz%

for example, with de_DE translation, we have to run:

./pear install downloader/pearlib/download/Locale_Mage_community_de_DE-1.4.1.1.tgz
Mage users

In theses versions, downloader folder is by default downloader/.cache

In this version, it's not as simple as in the pear one: mage installer checks if the file already exists before installing it, but we have the advantage to be able to use the new archive format which contains exactly the same directory tree than in Magento

So we have to remove manually all files found in directory tree, and reinstall module. It can be done with the following command lines:

#!/bin/bash
#
# reinstall script for Magento mage installers versions
# just edit the variables ARCHIVE_NAME and DOWNLOADER_TMP_FOLDER if required
# @author Matthieu MARY
#
# edit the following configuration values
DOWNLOADER_TMP_FOLDER=./downloader/.cache/
ARCHIVE_NAME=Locale_Mage_community_fr_FR-1.5.0.2.tgz
# do not touch these variables !
FILE_TO_INSTALL=$DOWNLOADER_TMP_FOLDER"community/"$ARCHIVE_NAME;
CWD=`pwd`
TMP_LIST=/tmp/list.tmp;
#
# run
#
# we should have the download temp folder
if [ ! -d $DOWNLOADER_TMP_FOLDER ]; then
echo "Downloader folder $DOWNLOADER_TMP_FOLDER does not exists";
exit 1;
fi
cd $DOWNLOADER_TMP_FOLDER;
# we work for community
if [ ! -d community ]; then
echo "Invalid $DOWNLOADER_TMP_FOLDER: subfolder community doesn't exists";
exit 3;
fi
cd community
# check if module archive file exists
if [ ! -f $ARCHIVE_NAME ]; then
echo "Archive file $ARCHIVE_NAME does not exists, check the script configuration";
exit 2;
fi
# create a temp folder to extract the archive
if [ ! -d current_extract ]; then
mkdir current_extract
fi
cp $ARCHIVE_NAME current_extract
cd current_extract
# extract archive
tar xzf $ARCHIVE_NAME;
rm $ARCHIVE_NAME;
rm package.xml;
`find . -type f > $TMP_LIST`;
cd $CWD;
echo "Starting to remove from the archives files found";
for i in `cat $TMP_LIST`; do
if [ -f $i ]; then
rm $i;
fi
done;
echo "Launch mage installer for our $FILE_TO_INSTALL";
./mage install-file $FILE_TO_INSTALL;

If all is ok, you should have the following output

With this method, you are sure that you reinstall the same versions of your installed packages, so there is no risk to install a more recent version than yours. But these method also requires that you do not have modifid source code for this module

Consequences for Magento core modules

It seems that Varien do not update the repository, and so I do not advice to upgrade your Magento from this source: it's more secure to upgrade source from availables packages in magento website download section; in this case, you'll lost the possible file deletion Varien can do in sources, but for now, I haven't seen this case.

Configure how web crawler will index your Magento website

ROBOTS.txt is a standard which provides instructions for web crawlers that index your website. We'll see in this post how Magento allows us to manage robots.txt, and how we can extend its work.

Robots.txt, a quick overview

What is robots.txt ?

W3c explains us that robots.txt is a standard way integrated in HTML to tell search engines bots how you want them to index your website:

  • Do you want to allow them to index the page content?
  • Do you want to allow them to follow internal links to search new pages to index?

All these actions can be controlled by the following instructions:

  • index / noindex: manage your wish to index the current page content
  • follow / nofollow: manage your wish if you want that bots can search for links in current page

Hum, interesting, how we can set up these values?

Where do I set up robots.txt?

There is two ways to set up robots informations:

Robots.txt file

By default, web crawlers will search in your document root directory for a file named robots.txt. In this file, we will define to web crawler our global indexation policy.

If this file does not exist, web crawler will check in the page header

With the ROBOTS meta header

We also have the choice to manage the robots informations directly in page headers

In this case, we send in the page header a meta name "ROBOTS" which provides our indexation preferences. Here's an example of possible header sent

<meta name="ROBOTS" content="NOINDEX,NOFOLLOW" />

What's the interest of setting a good robots.txt policy?

Interest of these method is that you can control how indexers work:

  • I suppose that you wish to index your catalog pages
  • Do you really require that checkout page was indexed?
  • Do the links provided in cart page require an indexation?

Ok, I'm convinced. But Magento does not provides a mechanism to set up robots values?

How Magento manage robots ?

Magento provides a mechanism to configure robots values in header. This administrative panel is available in the System > Configuration > Design > HTML Head. Here's a screenshot:

As you can see, we can define the index / follow property but only in a global context: all pages will have the same meta ROBOTS values: so for now we are unable to provide differents robots instructions for our pages. Furthermore, if you do not set up a configuration value in the adminstrative panel, default applied is *; in this case it's the robot that decides to index your content!

Ok, but how can we set up differents values for our pages?

Setting differents robots values in Magento

There is a solution: we will use the layout structure of our pages: In these layouts, we can reference our block Mage_Page_Block_Html_Head which is responsible for displaying the robots instructions in our page. If we check the block class, it extends Varien_Object (so it's a classic Magento object), and have a method getRobots defined as this:

As you can see, robots values are stored in the _data property, under index 'robots'. So we just have to call setRobots method on your block, and it will update the related _data property, and so our robots values for our page.

Here's an example of layout robots definition:

Conclusion

With this method, we do not have to make an overload. Magento layout allows to define easily our robots preferences. Now we are able to restrict indexation in checkout, do not follow links in customer account, etc.

If you embed these instructions in some reuse module, you can now have your common robots policy set up in 5 min for each of your projects

This configuration will only works for crawlers that take care of the robots instructions. Some of them does not use them and index everything. For these ones, we have to find another way 🙂

Magento: protect you from XSS

Few time ago, NBS System, a french Magento hosting, has published a reporting about some XSS issues available on Magento

My curiousity led me to check some references on Magento, and It’s a shame, but there are many which are vulnerable.

  • Is it a lack of sensibility to this issue in web agencies ?
  • A maintenance too weak or not proactive enough ?

Some of these websites are online for many years. It’s a shame that web application security was not considered better.

Decrease time to search customers in Magento back-office

Yes, it’s possible!

I know, you have many customer accounts in your Magento and your customer service claim that you do something to reduce duration to search a customer in: “10, 15s, we are bored. Can you do something please???” (one girl says, desperated)

Why customer search is so long in back-office?

SQL query generated in grid to search customer is involved! In back-office, when you filter some fields in grid, by default filters are applyed with a “%value_to_filter%”

Here’s an example of a genered query to search John DOE:

SELECT `e`.*,
`_table_prefix`.`value` AS `prefix`,
`_table_firstname`.`value` AS `firstname`,
`_table_middlename`.`value` AS `middlename`,
`_table_lastname`.`value` AS `lastname`,
`_table_suffix`.`value` AS `suffix`,
CONCAT(IF(_table_prefix.value IS NOT NULL AND _table_prefix.value != "", CONCAT(TRIM(_table_prefix.value)," "), ""),TRIM(_table_firstname.value),IF(_table_middlename.value IS NOT NULL AND _table_middlename.value != "", CONCAT(" ",TRIM(_table_middlename.value)), "")," ",TRIM(_table_lastname.value),IF(_table_suffix.value IS NOT NULL AND _table_suffix.value != "", CONCAT(" ",TRIM(_table_suffix.value)), "")) AS `name`,
`_table_default_billing`.`value` AS `default_billing`,
`_table_billing_postcode`.`value` AS `billing_postcode`,
`_table_billing_city`.`value` AS `billing_city`,
`_table_billing_telephone`.`value` AS `billing_telephone`,
`_table_billing_region`.`value` AS `billing_region`,
`_table_billing_country_id`.`value` AS `billing_country_id`
FROM `customer_entity` AS `e`
LEFT JOIN `customer_entity_varchar` AS `_table_prefix` ON (_table_prefix.entity_id = e.entity_id) AND (_table_prefix.attribute_id='4')
LEFT JOIN `customer_entity_varchar` AS `_table_firstname` ON (_table_firstname.entity_id = e.entity_id) AND (_table_firstname.attribute_id='5')
LEFT JOIN `customer_entity_varchar` AS `_table_middlename` ON (_table_middlename.entity_id = e.entity_id) AND (_table_middlename.attribute_id='6')
LEFT JOIN `customer_entity_varchar` AS `_table_lastname` ON (_table_lastname.entity_id = e.entity_id) AND (_table_lastname.attribute_id='7')
LEFT JOIN `customer_entity_varchar` AS `_table_suffix` ON (_table_suffix.entity_id = e.entity_id) AND (_table_suffix.attribute_id='8')
LEFT JOIN `customer_entity_int` AS `_table_default_billing` ON (_table_default_billing.entity_id = e.entity_id) AND (_table_default_billing.attribute_id='13')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_postcode` ON (_table_billing_postcode.entity_id = _table_default_billing.value) AND (_table_billing_postcode.attribute_id='29')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_city` ON (_table_billing_city.entity_id = _table_default_billing.value) AND (_table_billing_city.attribute_id='25')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_telephone` ON (_table_billing_telephone.entity_id = _table_default_billing.value) AND (_table_billing_telephone.attribute_id='30')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_region` ON (_table_billing_region.entity_id = _table_default_billing.value) AND (_table_billing_region.attribute_id='27')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_country_id` ON (_table_billing_country_id.entity_id = _table_default_billing.value) AND (_table_billing_country_id.attribute_id='26')
WHERE (e.entity_type_id = '1') AND
(CONCAT(IF(_table_prefix.value IS NOT NULL AND _table_prefix.value != "", CONCAT(TRIM(_table_prefix.value)," "), ""),TRIM(_table_firstname.value),IF(_table_middlename.value IS NOT NULL AND _table_middlename.value != "", CONCAT(" ",TRIM(_table_middlename.value)), "")," ",TRIM(_table_lastname.value),IF(_table_suffix.value IS NOT NULL AND _table_suffix.value != "", CONCAT(" ",TRIM(_table_suffix.value)), "")) like '%John Doe%')
ORDER BY `e`.`entity_id` desc, `e`.`entity_id` desc
LIMIT 20

As you can see, customer lastname, middlename and firstname are concatenated with Mysql CONCAT method to generate the name value

And Yes, it does a full scan in your customer data… If you have 350k customer acccount, you should have at least 1,8G records in customer_entity_varchar table and so, each record is analyzed. This is the first reason why when you search John Doe in back-office, it’s so long.

“But mister, How can we reduce time for this query?”

Preamble: keep native search on all concatenated fields or create new columns for firstname and lastname?

Well, for those who know me, you know that I don’t like to break existing usage: ok, there is a filter field you don’t like, is it a reason to destroy this existing functionnality? If Varien change its function in futures releases, it’s more interesting to be able to also use it, instead of remove the overload we have done, no?

So the following article will study the case of creating two new filter fields in customer grid, name and firstname, instead of update the name filter. We’ll see in conclusion that MySQL also prefer this solution

And it’s fine, the girl of the customer service agrees with that 🙂

First step: avoid full scan table of customer_entity_varchar table

After creating our new columns, we will define our own filter applied when query is made and so, how is requested customer_entity_varchar table. We will see that it’s not the only solution, but a first step to reduce our load.

How can we do that?

Add our name and firstname column in grid

I’m sure you know how we can do that 🙂

Change how customer name filter box works

This is very easy with Magento native API: in a grid, when you add our column, you can also define how is managed the search for this field: with filter data. Filter model defined is the model used to build the SQL condition to apply when you enter something in the filter box:

How to set up our own filter model for our name column?

Filter is one parameter when you define your column in grid _prepareColumn method. We just need to provide our own filter for our new columns. With a grid overload we can add our filter

It could be something like this

Ok, with a complete overload, we can load our filter. But how can it be designed?

Design our own Magento customer name filter

Customer name filter should extend Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Abstract

if you look at this class, you’ll see an interesting method, getCondition: This is this method which is called to define the filter condition to apply on our filter

So we can design our filter like this:

Ok it’s fine?

Now our query made is the following one:

SELECT `e`.*,
`_table_prefix`.`value` AS `prefix`,
`_table_firstname`.`value` AS `firstname`,
`_table_middlename`.`value` AS `middlename`,
`_table_lastname`.`value` AS `lastname`,
`_table_suffix`.`value` AS `suffix`,
CONCAT(IF(_table_prefix.value IS NOT NULL AND _table_prefix.value != "", CONCAT(TRIM(_table_prefix.value)," "), ""),TRIM(_table_firstname.value),IF(_table_middlename.value IS NOT NULL AND _table_middlename.value != "", CONCAT(" ",TRIM(_table_middlename.value)), "")," ",TRIM(_table_lastname.value),IF(_table_suffix.value IS NOT NULL AND _table_suffix.value != "", CONCAT(" ",TRIM(_table_suffix.value)), "")) AS `name`,
`_table_default_billing`.`value` AS `default_billing`,
`_table_billing_postcode`.`value` AS `billing_postcode`,
`_table_billing_city`.`value` AS `billing_city`,
`_table_billing_telephone`.`value` AS `billing_telephone`,
`_table_billing_region`.`value` AS `billing_region`,
`_table_billing_country_id`.`value` AS `billing_country_id`
FROM `customer_entity` AS `e`
LEFT JOIN `customer_entity_varchar` AS `_table_prefix` ON (_table_prefix.entity_id = e.entity_id) AND (_table_prefix.attribute_id='4')
LEFT JOIN `customer_entity_varchar` AS `_table_firstname` ON (_table_firstname.entity_id = e.entity_id) AND (_table_firstname.attribute_id='5')
LEFT JOIN `customer_entity_varchar` AS `_table_middlename` ON (_table_middlename.entity_id = e.entity_id) AND (_table_middlename.attribute_id='6')
LEFT JOIN `customer_entity_varchar` AS `_table_lastname` ON (_table_lastname.entity_id = e.entity_id) AND (_table_lastname.attribute_id='7')
LEFT JOIN `customer_entity_varchar` AS `_table_suffix` ON (_table_suffix.entity_id = e.entity_id) AND (_table_suffix.attribute_id='8')
LEFT JOIN `customer_entity_int` AS `_table_default_billing` ON (_table_default_billing.entity_id = e.entity_id) AND (_table_default_billing.attribute_id='13')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_postcode` ON (_table_billing_postcode.entity_id = _table_default_billing.value) AND (_table_billing_postcode.attribute_id='29')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_city` ON (_table_billing_city.entity_id = _table_default_billing.value) AND (_table_billing_city.attribute_id='25')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_telephone` ON (_table_billing_telephone.entity_id = _table_default_billing.value) AND (_table_billing_telephone.attribute_id='30')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_region` ON (_table_billing_region.entity_id = _table_default_billing.value) AND (_table_billing_region.attribute_id='27')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_country_id` ON (_table_billing_country_id.entity_id = _table_default_billing.value) AND (_table_billing_country_id.attribute_id='26')
WHERE
(e.entity_type_id = '1') AND
(_table_firstname.value like 'John%') AND
(_table_lastname.value like 'Doe%')
ORDER BY `e`.`entity_id` desc, `e`.`entity_id` desc
LIMIT 20

“But I don’t understand mister, you told me that this solution was THE solution and I don’t earn any time… (she still seems desperate)”

First using this syntax require less time to read data, so it earns time, but ok, this is not significant. And ok, read the remaining step before you think that we have done the overload for anything

Second step: move attributes to entity model

Well, ok, Database expert has surely noticed the problem: I should be more clear, reduce SQL full scan is interesting only on key fields. And for now, value field in customer_entity_varchar table is only part of a multiple key

Ok, we must add an index on this “value” field?!

Don’t change the customer_entity_varchar index model

Sorry, no it’s not that simple: value field in customer_entity_varchar is already part of a multiple index, but in the last position. For those who know how multiple indexes works, you know that in our context, index won’t be used

So we have to add an unique index on this field?

Also in this case, it’s not the solution: if we do that, all customer_entity_varchar fields will be indexes, and so, we loose the interest of using index

So, we don’t change index mode for customer_entity_varchar table; the solution is to move the search field on customer_entity table

Change storage model for name and firstname fields

Oh my god, he plans to change the database storage model (This is not the girl of the customer service who speaks here)

Hum, yes, it’s possible…. We have to do four things:

Create the two new fields (firstname, lastname) in customer_entity table

Do you really require my help for this point? Don’t forget to index them

Change attribute storage model in eav_attribute table

With that, we inform Magento that it should not search for name and firstname in customer_entity_varchar table but in customer_entity table

You must have the following result

Copy the exiting name and firstname values in the new fields

DROP TABLE IF EXISTS customer_entity_temp_name;
CREATE TABLE IF NOT EXISTS `customer_entity_temp_name` (
`entity_id` int(10) unsigned NOT NULL,
`lastname` varchar(255) NOT NULL,
`firstname` varchar(255) NOT NULL,
UNIQUE KEY `entity_id` (`entity_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO customer_entity_temp_name
SELECT `e`.entity_id,
`_table_lastname`.`value` AS `lastname`,
`_table_firstname`.`value` AS `firstname`
FROM `customer_entity` AS `e`
LEFT JOIN `customer_entity_varchar` AS `_table_firstname` ON (_table_firstname.entity_id = e.entity_id) AND (_table_firstname.attribute_id='5')
LEFT JOIN `customer_entity_varchar` AS `_table_lastname` ON (_table_lastname.entity_id = e.entity_id) AND (_table_lastname.attribute_id='7');UPDATE customer_entity AS e, customer_entity_temp_name AS n
SET e.firstname = n.firstname, e.lastname = n.lastname
WHERE e.entity_id = n.entity_id;DROP TABLE customer_entity_temp_name;

Conclusion

Our request look like that now:

SELECT `e`.*, `_table_prefix`.`value` AS `prefix`, `_table_middlename`.`value` AS `middlename`, `_table_suffix`.`value` AS `suffix`, CONCAT(IF(_table_prefix.value IS NOT NULL AND _table_prefix.value != "", CONCAT(_table_prefix.value," "), ""),e.firstname,IF(_table_middlename.value IS NOT NULL AND _table_middlename.value != "", CONCAT(" ",_table_middlename.value), "")," ",e.lastname,IF(_table_suffix.value IS NOT NULL AND _table_suffix.value != "", CONCAT(" ",_table_suffix.value), "")) AS `name`, `_table_default_billing`.`value` AS `default_billing`, `_table_billing_postcode`.`value` AS `billing_postcode`, `_table_billing_city`.`value` AS `billing_city`, `_table_billing_telephone`.`value` AS `billing_telephone`, `_table_billing_region`.`value` AS `billing_region`, `_table_billing_country_id`.`value` AS `billing_country_id` FROM `customer_entity` AS `e`
LEFT JOIN `customer_entity_varchar` AS `_table_prefix` ON (_table_prefix.entity_id = e.entity_id) AND (_table_prefix.attribute_id='4')
LEFT JOIN `customer_entity_varchar` AS `_table_middlename` ON (_table_middlename.entity_id = e.entity_id) AND (_table_middlename.attribute_id='6')
LEFT JOIN `customer_entity_varchar` AS `_table_suffix` ON (_table_suffix.entity_id = e.entity_id) AND (_table_suffix.attribute_id='8')
LEFT JOIN `customer_entity_int` AS `_table_default_billing` ON (_table_default_billing.entity_id = e.entity_id) AND (_table_default_billing.attribute_id='13')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_postcode` ON (_table_billing_postcode.entity_id = _table_default_billing.value) AND (_table_billing_postcode.attribute_id='28')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_city` ON (_table_billing_city.entity_id = _table_default_billing.value) AND (_table_billing_city.attribute_id='24')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_telephone` ON (_table_billing_telephone.entity_id = _table_default_billing.value) AND (_table_billing_telephone.attribute_id='29')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_region` ON (_table_billing_region.entity_id = _table_default_billing.value) AND (_table_billing_region.attribute_id='26')
LEFT JOIN `customer_address_entity_varchar` AS `_table_billing_country_id` ON (_table_billing_country_id.entity_id = _table_default_billing.value) AND (_table_billing_country_id.attribute_id='25') WHERE (e.entity_type_id = '1') AND (e.firstname like 'Doe%') AND (e.lastname like 'John%') ORDER BY `e`.`entity_id` desc, `e`.`entity_id` desc LIMIT 20

On a customer database which countains above 900k records, we reduce to 39 rows analyzed whereas we analyzed with native search 440k records: Results are now displayed immediatly

Well, we have earned many seconds to scan our customer database and probably a thank you!!! (phone number???) from the pretty girl of the customer service 🙂

This option has only the interest on a big customer database; I have no stats to provide, but if you think that when you search a customer, you are loosing time, perhaps this solution could help you

And if you are good and be able to capitalize, you can earn many phone number in different customer services 🙂

A new Magento connect version is coming

I was really impatient to see what is coming behind this new version!

Yesteday, I was very excited when I received a mail from Varien with title “Magento Connect Redesign“: a PDF which contains numerous pages which explain what is changing. Great.

But after reading the 22 pages of this PDF, it seems that it’s only look and feel which’ll change: you won’t be able to add css in package description now, but be able to add icons, update developers informations, etc.

Change will be applied on October 12th, at the Innovate developper conference

So let’s wait and see what this “new” magento connect will contain 🙂

For those who want to read the new Magento connect guidelines, you can find it here