Blog

Auditer Magento en quelques heures

Temps de lecture : ± 10 minutes.

Pour les plus impatients, LA commande est disponible en fin d’article pour générer les fichiers nécessaires à l’exploitation de l’audit.

Chez Occitech, nous sommes fréquemment confrontés à la reprise de projets existants, notamment de boutiques Magento. Une des premières choses importantes à réaliser, avant de pouvoir transmettre à nos clients des pistes de solutions ou estimations le cas échéant, est un audit général de Magento.

Un tel audit permet d’en dire long sur le passif du projet : nombre d’extensions installées, modifications du cœur, surcharges, qualité du thème …

Le but de cet article est de vous présenter quelques pistes pour pouvoir en quelques heures vous faire une opinion plutôt réaliste sur la dette technique d’un projet Magento. Bien entendu cela n’est pas exhaustif et nous ne nous focaliserons ici que sur les choses liées à Magento. Nous vous invitons à prolonger ces analyses par des choses plus globales sur l’interface de la boutique ou le code PHP (ressources en fin d’article).

… cadeau bonus

Cet article liste plusieurs outils pour nous faciliter la tâche. Comme nous sommes des gens gentils, nous vous avons préparé une image Docker vous permettant de les essayer et les exécuter sans avoir à les installer sur votre machine.

Vous trouverez l’image sur Docker Hub, nous l’utiliserons dans les exemples de l’article mais rien ne vous empêche de les exécuter directement … les outils sont suffisamment bien documentés pour que vous puissiez les installer indépendamment.

Actuellement l’image permet d’auditer les versions suivantes de Magento :

  • 1.6.0.2
  • 1.7.0.2
  • 1.8.1.0
  • 1.9.0.1
  • 1.9.1.0
  • 1.9.1.1
  • 1.9.2.0
  • 1.9.2.1
  • 1.9.2.2

Une prochaine modification de l’image permettra de supporter d’avantages de version de Magento 1.X.

Modifications du cœur

Do not edit the core!

Le but de cette vérification est bien entendu de s’assurer que le cœur de Magento n’a pas été touché ou alors si il l’a été, en comprendre les raisons (application d’un patch de sécurité, bug connu …).

Pour cette étape il vous faudra avoir une version « officielle » de magento sur votre machine. Vous pouvez la télécharger rapidement en adaptant la commande suivante avec la version souhaitée (au lieu de 1.7.0.2) et le chemin correct de téléchargement (ici le dossier courant) :

docker run --rm -v $(pwd):/project occitech/magento-audit download-magento 1.7.0.2 CHEMIN_DE_DESTINATION

Nous utiliserons ensuite la commande n98-magerun mpmd:corehacks fournie par le module « Magento Project Mess Detector » pour n98-magerun. Celle-ci permet de générer un rapport avec des diffs des modifications, et une liste des fichiers supprimés.

docker run --rm -v $(pwd)/src:/project -v $(pwd)/magento-orig:/magento-orig -v $(pwd)/audit:/audit occitech/magento-audit n98-magerun mpmd:corehacks /magento-orig /audit/corehacks.html

Voir un exemple de rapport généré

Surcharges locales

Pour détecter ces surcharges nous utiliserons encore une fois Magento Project Mess Detector mais cette fois-ci en utilisant la commande n98-magerun mpmd:codepooloverrides. Cette commande listera toutes les surcharges vis à vis des différents code pool.

Mais nous prêterons une attention toute particulière aux surcharges locales.

Parfois les développeurs surchargent le cœur de Magento (ou bien des extensions communautaires) pour modifier le comportement d’une méthode dans le cas ou ce n’est pas réalisable par une réécriture ou bien, le plus souvent, par méconnaissance. Ces surcharges là sont à surveiller de prêt car à la différence d’une réécriture, la surcharge fige tout une classe à une version donnée, version sur laquelle a été faite la surcharge. Or lors d’une montée en version cette surcharge posera vraisemblablement soucis si l’API de la classe a changé.

docker run --rm -v $(pwd)/src:/project -v $(pwd)/magento-orig:/magento-orig -v $(pwd)/audit:/audit occitech/magento-audit n98-magerun mpmd:codepooloverrides audit/overrides.html

Voir un exemple de rapport généré

Extensions installées

Avant toute chose, un indicateur très facile à obtenir, le nombre d’extensions installées vous en dira long sur l’effort à fournir lors d’une éventuelle montée en version. Un nombre élevée d’extension vous demandera plus de temps d’analyse, de test et éventuellement de correction. Cependant il est toujours bon de vérifier que toutes les extensions installées le soient pour une bonne raison.

Vous pouvez bien sûr regarder dans le répertoire app/etc/modules/ tous les fichiers xml, mais en vue d’être efficace, nous allons donc utiliser N98-magerun une nouvelle fois avec la commande suivante n98-magerun dev:module:list qui sortira un joli tableau des extensions en précisant si elles sont actives et le cas échéant le numéro de version de l’extension.

Ci-dessous un exemple de retour de la commande dev:module:list:

+-----------+-------------------------+------------+----------+
|codePool   | Name                    | Version    | Status   |
+-----------+-------------------------+------------+----------+
| core      | Mage_Core               | 1.6.0.3    | active   |
| core      | Mage_Eav                | 1.6.0.0    | active   |
| core      | Mage_Page               | 1.6.0.0    | active   |
| core      | Mage_Install            | 0.7.0      | active   |
| core      | Mage_Admin              | 1.6.1.1    | active   |
| core      | Mage_Rule               | 1.6.0.0    | active   |
| core      | Mage_Adminhtml          | 0.7.1      | active   |
| core      | Mage_AdminNotification  | 1.6.0.0    | active   |
| core      | Mage_Cron               | 1.6.0.0    | active   |
| core      | Mage_Directory          | 1.6.0.2    | active   |
| core      | Mage_Dataflow           | 1.6.0.0    | active   |
| core      | Mage_Cms                | 1.6.0.0.1  | active   |
| core      | Mage_Index              | 1.6.0.0    | active   |
| core      | Mage_Customer           | 1.6.2.0.1  | active   |
| core      | Mage_Catalog            | 1.6.0.0.18 | active   |
| core      | Mage_CatalogRule        | 0.0.1      | active   |
| core      | Mage_CatalogIndex       | 1.6.0.0    | active   |
| core      | Mage_CatalogSearch      | 1.6.0.0    | active   |
…
| core      | Mage_Checkout           | 1.6.0.0    | active   |
| core      | Mage_XmlConnect         |            | inactive |
| local     | Amasty_Audit            | 1.5.3      | active   |
| local     | Amasty_Base             | 2.1.4      | active   |
| local     | Amasty_Geoip            | 1.0.4      | active   |
| community | Aoe_Scheduler           | 1.2.2      | active   |
| community | Cm_RedisSession         |            | inactive |
| community | Loewenstark_UrlIndexer  | 1.0.0.1    | active   |
| community | Meanbee_Tinymce5        | 0.1.1      | active   |
|           | Mage_Ogone              |            | inactive |
| community | Netresearch_OPS         | 14.10.07   | active   |
| community | Owebia_Shipping2        | 2.5.18     | active   |
| community | Phoenix_Moneybookers    | 1.6.0.0    | active   |
| community | ProxiBlue_NewRelic      | 1.0.0      | active   |
| community | Shopgo_GTM              | 1.0.4      | active   |
+-----------+-------------------------+------------+----------+

Nous distinguons évidemment les extensions actives des inactives et préconiserons une suppression pure et simple des extensions communautaires et locales inactives.

Afin d’avoir un système de notation cohérant nous utiliserons des outils tels que triplecheck.io et/ou Judge pour déterminer une note pour les extensions actives. Cela ne nous empêchera pas d’analyser l’extension afin de faire un bref résumé des fonctionnalités apportées, des potentiels bugs et points améliorables détectés, nous indiquerons également le fait que si oui ou non l’extension est impactée par le patch SUPEE-6788.

Pour les extensions qui sont dans le codepool local et dont le vendor n’est pas un éditeur d’extension connu, nous analyserons manuellement chaque extension, afin de juger de la qualité, de comprendre les besoins auxquels répond l’extension.

Conflits entre extensions

Dans Magento, il n’est pas rare d’avoir des conflits entre extensions. Concrètement qu’est ce qu’un conflit, ce sont deux ou plusieurs extensions qui vont essayer de remplacer la même fonctionnalité (ou classe) de Magento. Le résultat de ce conflit c’est qu’une fonctionnalité d’une extension ne sera pas active, ça peut engendrer des problèmes difficiles à détecter…

Nous allons lister les différents rewrites existants ainsi que les éventuels conflits.
Pour cela nous allons lancer deux commandes N98-Magerun:

n98-magerun dev:module:rewrite:list
n98-magerun dev:module:rewrite:conflicts

la 1ère commande sert à lister les réécritures, la seconde sert à détecter les conflits entre différentes réécritures.

Liste des réécritures :

+----------------+--------------------------------------------------------+------------------------------------------------------------------------------+
| Type           | Class                                                  |  Rewrite                                                                     |
+----------------+--------------------------------------------------------+------------------------------------------------------------------------------+
| models         | cron/observer                                          | Aoe_Scheduler_Model_Observer                                                 |
| models         | cron/schedule                                          | Aoe_Scheduler_Model_Schedule                                                 |
| models         | cron_resource/schedule_collection                      | Aoe_Scheduler_Model_Resource_Schedule_Collection                             |
| models         | core/email                                             | Aschroder_SMTPPro_Model_Email                                                |
| models         | core/email_template                                    | Aschroder_SMTPPro_Model_Email_Template                                       |
| models         | core/email_queue                                       | Aschroder_SMTPPro_Model_Email_Queue                                          |
| models         | catalog/url                                            | Loewenstark_UrlIndexer_Model_Url                                             |
| models         | catalog_resource/url                                   | Loewenstark_UrlIndexer_Model_Resource_Url                                    |
| blocks         | customer/account_dashboard_info                        | IWD_Opc_Block_Customer_Account_Dashboard_Info                                |
| blocks         | checkout/onepage_link                                  | IWD_Opc_Block_Onepage_Link                                                   |
| blocks         | adminhtml/dashboard_diagrams                           | ProxiBlue_NewRelic_Block_Adminhtml_Dashboard_Diagrams                        |
| helpers        | catalog/category_url_rewrite                           | Loewenstark_UrlIndexer_Helper_Category_Url_Rewrite                           |
| autoload: Mage | Mage_CatalogRule_Model_Rule_Condition_Product          | Mage_CatalogRule_Model_Rule_Condition_Product                                |
| autoload: Mage | Mage_Core_Exception                                    | Mage_Core_Exception                                                          |
| autoload: Mage | Mage_Customer_Model_Address_Abstract                   | Mage_Customer_Model_Address_Abstract                                         |
| autoload: Mage | Mage_Paypal_Controller_Express_Abstract                | Mage_Paypal_Controller_Express_Abstract                                      |
| autoload: Mage | Mage_Paypal_Model_Config                               | Mage_Paypal_Model_Config                                                     |
+----------------+--------------------------------------------------------+------------------------------------------------------------------------------+

la 1ère commande sert à lister les réécritures, la seconde sert à détecter les conflits entre différentes réécritures.

Liste des conflits de réécritures :

┌────────┬──────────────────────────────┬────────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────┐
│models  │core/store                    │Vendor_Community_Model_Core_Store,                          │MyLocal_Model_Override_Core_Store                           │
│        │                              │MyLocal_Model_Override_Core_Store                           │                                                            │
├────────┼──────────────────────────────┼────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────┤
│blocks  │adminhtml/sales_order_grid    │Fianet_Core_Block_Adminhtml_Sales_Order_Grid,               │Sttl_Orderdelete_Block_Adminhtml_Sales_Order_Grid           │
│        │                              │Sttl_Orderdelete_Block_Adminhtml_Sales_Order_Grid           │                                                            │
├────────┼──────────────────────────────┼────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────┤
│helpers │checkout/cart                 │GoMage_Navigation_Helper_Checkout_Cart,                     │MyLocal_AddToCart_Helper_Data                               │
│        │                              │MyLocal_AddToCart_Helper_Data                               │                                                            │
└────────┴──────────────────────────────┴────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────┘
3 conflicts were found!

Analyser la qualité du thème Front et Admin

On passera outre le markup pas valide et autres tableaux des années 1990. Ce qui nous intéresse ici, c’est bel et bien la constitution même du thème.

Le thème permet-il des surcharges ? En d’autre mot : Se situe-il dans default/ou non ?

Combien de fichiers de template ont été modifiés ? Un nombre élevé est annonciateur de difficultés à venir lors de la mise à niveau de Magento: FormKey manquantes, fichiers de template renommés, etc … .

Parmis ces fichiers y-a-t’il des chargements de model (dans des boucles ou non), des requêtes SQL dans les vues, des includes de fichiers de templates … En bref est-ce que des mauvaises pratiques de développement sont détectées dans le thème.

Est-ce que les fichiers de layout du thème original ont été dupliqués ? Si oui, ça va être problématique en vue d’une mise à jour de Magento par exemple, des anciennes versions de fichiers de layout peuvent faire appel à des blocs obsolètes ou inexistants dans les dernières versions de Magento.

Ça rend également plus difficile la détection de personnalisation du thème contrairement à regrouper toutes les modifications dans un fichier de layout local.xml.

On en profitera lors de cette phase d’analyse d’utiliser un outil bien pratique: ICDIff. Cette outil permet de facilement voir les différences entre deux fichiers.

Exemple de commande : icdiff base/default/template/sales/order/recent.phtml default/custom/template/sales/order/recent.phtml --highlight

Pendant cette phase d’analyse on en essaiera de comprendre les modifications faites au niveau du thème, et de noter les points améliorables.

Vous pouvez également utiliser un plugin n98-magerun pour automatiser la partie recherche de différence : Magerun-Addons (Ce plugin sera prochainement ajouté à notre image Docker) via la commande suivante :

n98-magerun diff:theme THEME_A_ANALYSER/default default/base

Pensez à modifier THEME_A_ANALYSER par le thème courant.

À la recherche des mauvaises pratiques Magento

Que cela soit dans les templates, extensions tierces ou extensions spécifiques je trouve toujours intéressant d’exécuter quelques vérifications de base pour identifier les extensions / parties de l’application potentiellement de moindre qualité. Bizarrement c’est souvent là qu’une montée en version va causer le plus de problèmes, ou que des problèmes de performance se font sentir.

Pour cela voici quelques exemples de recherches à effectuer :

  • Accès direct à `$_GET` et `$_POST`
  • Utilisations de `Mage::getModel()` dans les templates
  • Utilisation d’`include`ou `require_once`pour injecter du template ou charger des classes

L’outil ECG Magento Code Sniffer Coding Standard ou Magniffer vous pouvez ajouter vos propres règles à ces outils d’après votre propre expérience.

Les outils ne font pas tout

Il y a encore plusieurs points assez simples à vérifier, mais qui sont plus subjectifs et pour lequel je ne connais pas d’outils spécifiques. En bon artisan il faut savoir utiliser les outils universels à notre disposition … un bon vieux coup de ack-grep peut en dire très long sur le code à analyser !

Base de données

Avant toute choses nous allons récupérer le poids total de la base de données avec la requête SQL suivante :

SELECT table_schema "DATABASE NAME", sum( data_length + index_length ) / 1024 / 1024 "Data Base Size in MB" 
FROM information_schema.TABLES GROUP BY table_schema ; 

La base de données de Magento contenant beaucoup de tables, nous allons nous concentrer sur les tables volumineuses (en les listant par taille décroissant)

SELECT 
    table_name AS `Table`, 
    round(((data_length + index_length) / 1024 / 1024), 2) `Size in MB` 
FROM information_schema.TABLES 
WHERE table_schema = "DATABASE NAME"
ORDER BY (data_length + index_length) DESC;

On fera le ratio de la taille de la table / taille total de la base de données afin de donner un ordre de grandeur.

Généralement les tables que nous surveillons sont les tables de logs (log_url_info, log_visitor, etc…) ainsi que la table core_url_rewrite qui aura tendance à grossir du fait d’un « bug » du cœur de Magento. Si cette table atteint une taille assez significative (700M ou +) nous dresserons la listes des urls dupliquées via la requête SQL suivante:

SELECT entity_id, catalog_product_entity_varchar.value FROM catalog_product_entity_varchar
INNER JOIN (
    SELECT value FROM catalog_product_entity_varchar
    WHERE attribute_id=URL_KEY_ATTRIBUTE_ID AND store_id = 0
    GROUP BY value HAVING count(value_id) > 1
) dup ON catalog_product_entity_varchar.value = dup.value
ORDER BY value

Bien sûr changer : les variables DATABASE_NAME et URL_KEY_ATTRIBUTE_ID dans les requêtes.

Nous vérifierons également la présence de traductions en ligne dans la table core_translate et préconiserons de les extraire dans des fichiers de traductions.

Analyse des fichiers de logs

Pensez également à analyser les fichiers de logs qui sont une mine d’information sur les erreurs récurrentes dans le code de la boutique.
Je ne connais pas d’outils propres à l’exploitation des logs de Magento et fais en règle générale appel aux bonnes vieilles recettes : grep, R ou même une stack ELK.

Analyses complémentaires

En plus de l’analyse technique de la boutique, nous intégrons, généralement, à notre audit des analyses sur les WebPerfs et sur la sécurité. Pour cela nous nous appuyons principalement sur deux services:

MageReport permet de lister avant même d’avoir récupérer les sources, les patchs de sécurités appliqués, si l’administration a été renommée, si des dossiers critiques sont accessibles, etc…. À noter toutefois que MageReport peut remonter des faux positifs quant il est confronté à un .htaccess.

DareBoost permet d’avoir une vision des points d’améliorations en termes de WebPerfs. Il affichera diverses métriques (TTFB, Premier affichage, et Chargement total), ainsi que diverses préconisations aux problématiques qu’il mettra en exergue. Pensez à analyser au moins la page d’accueil, une page de catégorie et une page produit afin d’avoir une vision « réaliste » des WebPerfs du site.

Autres points

Les étapes et points analysés ne sont pas exhaustifs et peuvent être largement améliorables.

On pourra par exemple vérifier la présence :

  • D’un texte légal sur l’utilisation des cookies
  • De la présence de Microdata, de Google Analytics

Nous pouvons également analyser les templates d’emails afin de voir

  • le masquage du mot de passe dans l’email de confirmation de mot de passe
  • le logo email est bien personnalisé

Écueils à éviter

Le moment venu de l’audit, si vous avez les accès au serveur, vérifiez bien que le code est celui de la production, penser donc à faire un rsync pour récupérer les dernières modifications du code qui se seraient glissées par inadvertance (Idem pour le dump de la base de données).

ProTips™:

  • Essayer d’avoir une vision pour l’audit, par exemple si l’audit est en vue d’une mise à niveau de Magento, ou bien une adaptation responsive du thème. Cette vision influera sur les parties à analyser de manière plus poussée.
  • Ne partez pas dans une analyse détaillée dès le début, essayez d’acquérir une vision globale du projet en survolant le code lors des différentes étapes de l’audit
  • Faîtes l’audit en plusieurs étapes pour éviter toute distraction ou pertes de concentration
  • N’hésitez pas à faire relire l’audit par d’autres personnes

Le mot de la fin

Un audit est généralement la première prestation qu’effectue l’entreprise pour un nouveau client. N’hésitez pas à joindre un compte-rendu compréhensible pour un profane résumant les principaux points forts et faibles soulignés dans l’audit.

La commande de la fin

La commande magique permettant de générer les fichiers à exploiter pour l’audit :

 docker run --rm --link={CONTENEUR_MYSQL_CONTENANT_LA_BDD}:db \
    -v $(pwd)/htdocs:/project \
    -v $(pwd)/magento_src:/magento_src \
    -v $(pwd)/audit:/audit \
    occitech/magento-audit do-audit {VERSION_DE_MAGENTO}

La commande do-audit exécute les étapes suivantes de l’audit :

  • Téléchargement de la version de Magento
  • Analyse de Magento pour trouver d’éventuels modification du cœur
  • Analyse des surcharges locales
  • Analyse des extensions
  • Analyse des réécritures et conflits
  • Récupération de statistiques additionnelles (Nombre de clients / produits, date d’installation, nombre de catégories, etc …)

Le placeholder {CONTENEUR_MYSQL_CONTENANT_LA_BDD} doit être remplacé par le nom du conteneur mysql contenant le dump de la base de données du Magento à auditer.
Le placeholder {VERSION_DE_MAGENTO} doit être remplacé par … la version de magento.

Il faudra également penser à modifier le fichier local.xml avec les informations du conteneur de base de données, afin que n98-magerun puisse communiquer avec cette dernière.

Pour aller plus loin

Pour aller plus loin nous vous invitons dans ce type d’audits n’oubliez pas que des outils permettent également d’analyser la qualité de code des languages utilisés (PHP, JS, CSS), la sécurité de votre Magento, ou bien les webeprfs.. Jetez donc un oeil aux projets suivants qui vous permettront d’affiner vos audits :

  • Jolicode/phaudit : une image Docker vous permettant d’exécuter la plupart des outils d’analyse de code PHP sur votre projet sans avoir à vous soucier de leur installation
  • Sitespeed.io : un outil pour analyser et synthétiser rapidement la vitesse et les performances d’un site (bonnes pratiques frontend également) – Dareboost Service similaire à Sitespeed.io
  • Userium : votre propre checklist des bonnes pratiques d’UX pour un projet
  • CSSStats : générez rapidement des métriques sur les styles CSS de manière à avoir un aperçu sur plusieurs points de l’organisation / maintenabilité des styles (les utilisateurs non avertis devront prendre le temps de comprendre l’intérêt de chaque métrique)
  • DoIUse… : un outil permettant d’avoir un aperçu des règles CSS utilisées incompatibles avec certains navigateurs
  • Git Stats : si vous avez la chance de récupérer le repository du projet. En dit long sur l’activité du projet et les contributeurs (voici une courte vidéo vous donnant un exemple dans la bonne humeur des informations qu’on peut extrapoler :)).
  • Magereport

Et enfin, un petit rappel : une boutique Magento qui tourne bien, ça commence par un bon hébergement. C’est un point qui ressort souvent de nos audits : l’hébergement n’est pas au point et limite les performances du site, même parfois sur des installations qui tutoient les 1000 € HT / mois. Certes Magento peut être gourmand, mais il n’est plus nécessaire d’envisager un serveur dédié pour faire fonctionner son site avec des temps excellents. Il faut une infrastructure basée sur des disques SSD et suffisamment de RAM. Nous proposons un excellent service d’hébergement Magento, avec 30 jours d’essai gratuit !

1 Comment

  1. Magento points de vigilance | Pearltrees

    […] Auditer Magento en quelques heures-Occitech studio d'innovation. Temps de lecture : ± 10 minutes. Pour les plus impatients, LA commande est disponible en fin d’article pour générer les fichiers nécessaires à l’exploitation de l’audit. Chez Occitech, nous sommes fréquemment confrontés à la reprise de projets existants, notamment de boutiques Magento. Une des premières choses importantes à réaliser, avant de pouvoir transmettre à nos clients des pistes de solutions ou estimations le cas échéant, est un audit général de Magento. Un tel audit permet d’en dire long sur le passif du projet : nombre d’extensions installées, modifications du cœur, surcharges, qualité du thème … Le but de cet article est de vous présenter quelques pistes pour pouvoir en quelques heures vous faire une opinion plutôt réaliste sur la dette technique d’un projet Magento. . … cadeau bonus Cet article liste plusieurs outils pour nous faciliter la tâche. […]