Use a custom domain name as a way to secure your Magento administrative panel

After this year 2015 full of security issues (SUPEE-6482, SUPEE-6285,SUPEE-6237, SUPEE-5994, SUPEE-5344) we have seen that there is many websites which only use the custom routing to hide the administrative panel; it means, back-offices are available from the front webservers with a string in URL as element to identify you wants to access to the admin panel.

And by default this string is admin, a not very difficult element to find :).

In this case, we are not very far from default behaviour, and everyone can access from your website to your back-office login form. And if you do not have admin accounts automatic locking (like the community edition does) you encounter risks of brute force logging attempts. And if someone earn back-office access, he will:

  • delete your customers accounts?
  • close your websites?
  • Spam your customers?
  • Install an incompatible module from Magento connect which will break your site?

All these can affect your brand image.

But there is some ways to make more secure the Magento admin panel. One of them, its to use a custom domain name for your back-office: it has the main advantage to allow you to customize security rules.

Just a few of configuration are required. You’ll find them bellow.

This article expect that

  • Your Magento webserver is hosted on a unix debian like operating system.
  • Your webserver is Apache.
  • Your Magento website is defined in the /etc/apache2/site-available/magento.conf file
  • Your back-office is available on the HTTP protocol.
  • For now, you access to your back-office from the www.mywebsite.com/customadminpath URL.
  • You wants to move it to the URL admin.mywebsite.com/customadminpath

The Magento configuration inherit mechanism

Before talking about the procedure to switch your back-office to a custom admin URL, just few words about how Magento manage URLs.

Magento come with it’s own concepts, and one of them is the ability to manage multiples websites and their internationalization within stores views.

When you display a page on Magento, you are in a store view. If you try to load a configuration value from this view, Magento first check if you have defined something for this store view. If yes, it use this value. If not, it check if you have defined something for the related website. If not, it’ll use the value set for the global scope. A concept you probably already know if you use Magento.

Back-office is a particularity of this concept: even if back-office is a store view, there is no hierarchy: the configuration used by the back-office view are the values defined for the global scope.

Magento URLs are completely included in this configuration management:

  • admin URL is the URL defined on the scope default.
  • Your websites and stores views are the specificities defined for the related configurations levels.

So Magento configuration inherit mechanism offer everything to define a custom URL for your back-office. It should be a shame to do not use it. How can we migrate this configuration?

Configure a custom admin URL for your Magento back-office

Step 1: Ensure that your Magento front-office stores URLs does not use the configuration inherit mechanism

This step is required because if you still use the configuration inherit mechanism (eg: have just define the URLs on the global scope), when we’ll update the back-office URL your front office URLs will also be updated. it could be problematic ūüôā

The configuration of the Magento URLs is managed differently for secure (http) and unsecure (https) part of your website. We start with the unsecure part.

1.1 – Ensure that your Magento unsecure store URL(s) does not use inherit configuration

1.1.1: Go to the Magento administrative panel which manage URLs configuration

This configuration panel is located in the System > Configuration > General > Web > Unsecure URL tab. You should see something like this:

Screenshot of the interface in the Magento administrative panel which allow to manage URLs of your websites and stores

1.1.2: Iterate on each store view configuration

On the top left of the page, you have the store view selector (the select box which allow to define on which store view you are currently editing the configuration). on my Magento, I have:
Screenshot of the selectbox which allow to choose on which scope we work

1.1.3: Uncheck the configuration values for your URLs

Check for each store views from this selectbox the configuration of your unsecure URLs: make sure that the “Use website” is unchecked like in the screenshot bellow.
Screenshot of the Magento admnistrative panel: checkbox allow to customize the scope you are updating
If not, uncheck it and save configuration.

Repeat this step for each of the store views available (in my case, en_uk, en_us, fr_fr and the french store view for the b2b website).

To check if everything is ok, flush the cache block from the administrative panel System > Cache Management and browse with your web browser all of your stores: your(s) catalog(s) must be still available(s).

Your websites and store views use now a dedicated configuration value for the unsecure URL.

1.2 – Ensure your secure store URLs does not inherit configuration

Repeat the steps 1.1.1, 1.1.2, and 1.1.3 for your secure URLs configuration (available from System > Configuration > General > Web > secure URL tab).

When you’ll finished, you can validate with your web browser (after flushing cache block cache mangement) that for each of your store views the customer accounts and checkouts are still available.

Step 2: Ensure that your Magento cookie policy is able to handle a new admin URL

Ok, now you do not use anymore the inherit mechanism for both http and https URLs. But it’s not yet finish with the configuration: for now, your cookie policy is able to handle both your front and back-office queries. But if we update our back-office domain name and leave the cookie policy as it, back-office could be unavailable. Wrong not?

We have to also update this domain name cookie configuration

This step is only required if you have for some of your store view(s) or website(s) defined a custom cookie domain. But by default, the cookie domain accept everything. If you have not updated it, you can go directly to step 3 but I think it’s however interesting to take time to check this configuration.

2.1 – Ensure that configuration for cookie domain for your front-office store views does not depends of the default cookie domain configuration

Go now in the menu System > Configuration > General > Web > Cookie Management and make sure that the value set for each store is like we have done for the URL management: For each store, uncheck the “use website” checkbox and save configuration.

Use a custom cookie domain for session cookie

We are now sure that our configuration for our front office store views is specific.

2.2 – Ensure that the cookie domain configuration for the admin is able to handle both new and current domain names

For the back-office scope (scope default), make sure to select a cookie domain value which is acceptable by both your new admin URL and your current URL: since we’ve not updated the admin configuration URL, we need to be able to browse back-office. And when we’ll update it, we must also be able to do it. If not, when we’ll update the admin URL, we won’t be able to connect to the back-office because session will not be available.

Cookie domain is configurable from the administrative panel on the fieldset General > Web > Session Cookie Management. Ensure that you’ll update configuration value for the default scope!

in this example we should set something like .mywebsite.com, witch match both admin.mywebsite.com and www.mywebsite.com.

If there is no shared domain name between current and the future back-office URL, you must set . as cookie domain. This is less secure, but it’ll work in each case.

After updating this configuration value, log out from back-office, close your browser, and log in a second time. You should still be able to browse back-office.

Step 3: Update Apache configuration to define your custom admin back-office URL

Now Magento is ready to accept a new URL for the back-office. Before setting this new value in Magento back-office, we have to update Apache configuration: if not, when we send a request to our webserver with the new URL admin.mywebsite.com, we’ll try to access to a webserver unknown by Apache and we have an unexpected answer.

A good starting point could be to copy your current front-office configuration file to a new one to define the specificities to the admin server:

root@your_web_server:~$ cp /etc/apache/sites-enabled/magento.conf /etc/apache/sites-available/magentoadmin.conf && sed "s|ServerName *www.mywebsite.com|ServerName admin.mywebsite.com|g" --in-place='.bak' /etc/apache/sites-available/magentoadmin.conf && ln -s /etc/apache2/sites-available/magentoadmin.conf /etc/apache2/sites-enabled

The file /etc/apache2/sites-enabled/magentoadmin.conf should contains something like this:

<Virtualhost XXX.YYY.ZZZ.TTT:80>
      ServerName admin.mywebsite.com
      DocumentRoot /a/path
      <Directory /a/path>
           # your magento configuration here
      </Directory>
</VirtualHost>

You should force Magento to load the admin panel when a request is sent to admin.mywebsite.com by using the following server variables in this file:

<Virtualhost XXX.YYY.ZZZ.TTT:80>
      ServerName admin.mywebsite.com
      DocumentRoot /a/path
      <Directory /a/path>
      # your magento configuration here
      # force loading the admin store
      setEnv MAGE_RUN_CODE admin
      setEnv MAGE_RUN_TYPE store
      </Directory>
</VirtualHost>

Don’t forget to check if everything is ok in your apache configuration with the following command:

user@your_web_server:~$ apache2ctl configtest

If the output is ok, restart apache with the following command:

root@your_web_server:~$ apache2ctl restart

Now, Your apache webserver know what to do if it receive a request for admin.mywebsite.com

Step 4: Resolve your new Magento administrative panel domain name

The final preparation step is to explain to your desktop or all required back-office users that http://admin.mywebsite.com must be managed by your webserver. If not, your browser can ask http://admin.mywebsite.com but don’t know where going to find the appropriate answer.

4.1 – Check that domain resolution for your future admin webserver is not fine enough

I’ll give you two methods to check if your Magento admin domain name resolution is able to handle your admin configuration domain name yet:

  • by ping command
  • using your browser.
4.1.1: Check your future admin domain name resolution using the ping command

Open a terminal from your computer, and ping your new admin hostname with the following command:

user@your_web_server: ping admin.mywebsite.com

If you have an output like this:

ping: unknown host admin.mywebsite.com

You have to configure a DNS resolution for your admin.

4.1.2: Check your future admin domain name resolution with your browser

You can also check if your browser is able to resolve it by opening a new window (or tab) and open the URL http://admin.mywebsite.com

If your browser tell you that it cannot resolve it, you’ll have to made the DNS resolution

Screenshot of chrome browser output when domain name resolution is not found

Screenshot of firefox browser output when domain name resolution is not found

4.2 – Set up your domain name resolution for your Magento future administrative panel

it can be done:

  • For you current desktop:
    • In your %windows_folder%/System32/Drivers/etc/hosts file if you are on windows.
    • In your /etc/hosts file if you are on Linux based distribution.
    • For MAC users, my bank loan have been refused, I don’t have MAC ūüôā (but I suppose it’s also in /etc/hosts file).
  • For different users:
    • In your DNS record.

After that, a

user@your_web_server: ping admin.mywebsite.com

must answer something like this:

PING admin.mywebsite.com (XXX.YYY.ZZZ.TTT) 56(84) bytes of data.
64 bytes from admin.mywebsite.com (XXX.YYY.ZZZ.TTT): icmp_seq=1 ttl=64 time=0.024 ms
64 bytes from admin.mywebsite.com (XXX.YYY.ZZZ.TTT): icmp_seq=2 ttl=64 time=0.029 ms
64 bytes from admin.mywebsite.com (XXX.YYY.ZZZ.TTT): icmp_seq=3 ttl=64 time=0.029 ms
64 bytes from admin.mywebsite.com (XXX.YYY.ZZZ.TTT): icmp_seq=4 ttl=64 time=0.029 ms

and opening URL http://admin.mywebsite.com/customadminpath in your favorite browser should display the Magento login form

Now everything is ready!. Let’s go and update our back-office URL

Step 5: Update Magento configuration to set the new back-office URL

So go in your current back-office and open the System > Configuration > General > Web > Unsecure URL tab: replace now in scope default the web unsecure URL by http://admin.mywebsite.com/. (Don’t forget to add the trailing / add the end of the URL).

Save config

Log out from the back-office

And open the http://admin.mywebsite.com/ URL. You should set the login form

Secure your back-office URL

Does your back-office is secured now?

It’s a shame but no:

  • Login form is still available from http://www.mywebsite.com/customadminpath
  • Everyone able to access to http://admin.mywebsite.com will be able to view the Magento login form.

Try it: open your old admin URL http://www.mywebsite.com/customadminpath/ you’ll still view the login form :(. The only thing we have done for now is to redirect people which provide valid login credentials to http://admin.mywebsite.com/customadminpath

Add the following rewrite rule in the Apache configuration file of the website virtualhost /etc/apache2/sites-available/magento.conf will redirect each user who try to access to admin from http://www.mywebsite.com/customadminpath/ to the admin domain name http://admin.mywebsite.com/:

<Virtualhost XXX.YYY.ZZZ.TTT:80>
      ServerName www.mywebsite.com
      DocumentRoot /a/path
      # redirect users to admin domain name if they try to access for login from website
      <IfModule mod_rewrite.c>
                RewriteEngine On
                RewriteCond %{HTTP_HOST} www.mywebsite.com [NC]
                # replace customadminpath by your own admin query string
                RewriteCond %{REQUEST_URI} ^.*/customadminpath/.*$
                RewriteRule ^(.*)$ http://admin.mywebsite.com/ [R=302,L]
      </IfModule>
      <Directory /a/path>
            # your magento configuration here
      </Directory>
</VirtualHost>

After an Apache restart, your login form is only available from http://admin.mywebsite.com

This is not the object of this post, but many things can be done to improve the ACL of your back-office. For example:

Is there an interest to use a custom domain name if you use the default behavior? I mean yes, and quickly.

Is there an interest to use a custom domain name if you already use something different than admin as suffix to access to your back-office? I mean yes. For sure, it’s quite more difficult to find it, but security issues have shown that it’s easily to find these “hidden” back-offices: Security through obscurity is not security. it’s just security for some times.

Don’t forget app/design/adminhtml/base/default folder when adding customs elements to Magento back-office

From the beginning of Magento until today (eg Community edition 1.7 and Enterprise Edition 1.12), Magento admin design folder has always been located in the app/design/adminhtml/default/default folder.

This folder contains all the required files to build adminhtml pages:

  • layouts to define adminhtml pages structure
  • templates used by theses layouts

So, If you need to provide specific back-office interfaces, where will you put them? in this app/design/adminhtml/default/default folder?

Magento page structure loading file API

Adminhtml is managed like the same loading API used in the front office; this API has been reviewed in Magento CE 14 and related Enterprises editions to load content in the following order:

  • Custom package / Custom theme folder
  • Custom package / default theme folder
  • Base package / default theme folder

I have previously explained the aim of this rule and what you can do with it

But the question is: adminhtml default default folder is: base package or custom package?

app/design/admintml/base/default as a default package folder

Yes it is. The folder app/design/admintml/default/default is not a default one, but the the default theme for the adminhtml default package; folder app/design/admintml/base/default can also exists even if it’s not embedded with magento sources.

So for sure, this is not an error to enhance this default package, but it does not respect the role of this loading api.

So it could be interesting to use app/design/adminhtml/base/default as folder for your new back-office interfaces

Conclusion

app/design/adminhtml/base/default folder does not exist in Magento sources but you can create it as you wish.
In a dream world, back-office updates should be managed as this:

  • Move app/design/adminhtml/default/default folder to app/design/adminhtml/base/default folder: we ensure this way that we have the default magento design for back-office
  • Use a custom package for the back-office updates of the existing interfaces
  • Provide new back-office interfaces in the adminhtml/base/default folder

Do you have already created the app/design/adminhtml/base/default folder for your own back-office interfaces or you do not take care of this case?

Magento guide: the three concepts of a Magento website context

Magento embeds a native multistore model that allows to configure multiple e-commerce models on the same magento source. If you are a Magento beginner, perhaps you are quite a bit lost with these stores, websites and views context. Each one has a dedicated role, and you should respect them, otherwise you would have to modify deep Magento’s working layer which would be quite difficult.

Screenshot of the stores management administrative panel available through the Magento administrative panel System > Stores Management

The magento websites are used to define your way of working :

  • Define a sales catalog
  • Configure the price rules management
  • Configure how customer accounts are shared between all yours stores

Define a sales catalog in a Magento website

Your catalog is manageable through the administrative panel catalog > Manage products. You can define there all your products data: name, description, price, etc

But this is not because you have enabled a product in this administrative panel that it will be salable: it needs to be part of a sales catalog: what do you want to sell on your store? All your products? Only some elements of your work?

For example, take a look at the LVMH group. This group owns Dior fragrance, Louis Vuitton bags, etc… Imagine they want to build a Magento to sell all their catalog (and if you want, you can contact me :)), they would want to sell each dedicated brand products in a dedicated store. To do that, they need two things:

  • They will first describe all their products in Magento back-office: product’s names, reference in their informatic system, etc. Afterthat products are editable, but not salable

  • Secondly, they’ll have to publish them in their sales catalog to ensure that only fragrance will be published in the Dior dedicated store, and only bags will be sold through the Louis Vuitton online store

To do that, products need to be linked to a website. This is available through the product sheet website tab

Checking the website checkbox will publish your product in the related sales catalog

So you should have at least one website per sales catalog

Are your sure? I’m not LVMH group, have only one online store, and I never do that, and I’ve not the website tab …

When you are in a single website context, all is done in background without any action

Define the scope of your prices in Magento through website

At this point you should know how to define your sales catalog

Now imagine that your business model will propose two different prices for the same product: a discount store and a normal one for example. If your prices rules are not managed with conversion rates, you should configure the price rule scope as website instead of global

This configuration value is available though the administrative panel system > configuration > catalog > prices > Catalog price scope

Magento adminstrative panel which allow to configure the price scope in a multistore context

You can with this rule apply a specific price for an article in a dedicated sales catalog

Configure how customer accounts are shared between websites

Websites allow also to configure the visibility scope of your customers account.

Suppose now that Amazon would migrate to Magento. (Yes perhaps you need to do a benchmark for other solutions, but it’s another problem ūüôā ). Do they want the customer accounts to be shared between amazon.co.uk, amazon.com, and amazon.de? Sharing same shipping address, same customer email account, etc? If so if you update your customer account on amazon.com, data will be also updated on amazon.de.

Customer accounts scope is a configuration value available through the system > configuration > Customers > Account sharing scope.

Screenshot of the account sharing option available through the administrative panel System > Configuration > Customer configuration

This option value will define how your customer accounts will be shared between each website

Why is it so important to well define the store model on your Magento?

As you can see, website define deep main work of your client and for this reason website are probably the most important degree of organization in the Magento multistore model. Updating a store model during a Magento project life is not an easy task, and for this reason, you should well define it at the beginning of your project. So be sure to ask yourself the revelant questions

how to solve Magento message “Your web server is configured incorrectly. As a result, configuration files with sensitive information are accessible from the outside. Please contact your hosting provider.”

If you have this message when you are logged in your back-office, it’s because there is a misconfiguration in your Magento host. There are multiple reasons to have this message, and multiple ways to fix it

Why do I have this message displayed?

Since 1.4.2 version, back-office check from back-office if file app/etc/local.xml can be read through a browser (If the response code is a Apache 200 response code; This control is made by a CURL request on your unsecure_base_url/app/etc/local.xml URI) It’s very important not to be able to read this file from a webbrowser, because it contains your database parameters, cache and session configuration.

All files and folders in app folder are protected by a .htaccess file which denies access from everyone since it browses your Magento directory tree starting from the app folder:

Order deny,allow
Deny from all

this directive is applied starting from .htaccess path and covers also subfolders, and so, local.xml file

Origins of the problem

.htaccess usage can be disturbed for three major reasons:

htaccess file doesn’t exist

For sure, if htaccess file does not exist, there is no restriction on who can read the local.xml file, and so, the security warning is displayed

htaccess files are not the access filename

By default in Apache configuration, the AccessFilename is set to .htaccess. It can be updated with the AccessFilename directive in webserver or virtual host configurations files.

So if value has been updated, .htaccess will not be read, and so ACL is not used

But if this is your study case, you should have more complex problems with your Magento ūüôā

Cannot override the directories acccess control list

Apache configuration allows also to define which rules can be overrided in AccessFilename with AllowOverride directive

If you are a hosting provider, perhaps you don’t want that your clients can update in their AccessFilename some security directives. It can be done with the AllowOverride directive

Have a look at the official documentation to see the possible values for this directive

In this case, if AllowOverride directive is not well set, the .htaccess file is read, but the ACL defined is not used, and so, we can have access to your local.xml file

Because this directive is applied only to <Directory;> instruction, you must be able to edit the vhost configuration file to fix this issue. Ask your hosting provider if you cannot

Specifics rewriting rules

For one client, we encounter this case: we have updated some elements of the Magento directory tree and define some specific rewriting rules. local.xml file was not available, but CURL test receive a 200 error code because of a rewriting rule.

In this case, this is the test which is involved, not your security policy

Conclusion

Configuration is checked on the app/etc/local.xml file, but other sensibles informations can be fetch from your app directory

It’s a shame that everybody doesn’t take care of this security issue. Take a look at the google results, you’ll be surprised

If your configuration is well set, when you request the app/etc/local.xml file on your Magento, you should have the following error displayed

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 ūüôā

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 ūüôā