code4business Software GmbH - Magento Associate

Update auf Magento Enterprise Edition 1.13.0.2

(the English translation is in the bottom)

Wir haben kürzlich eine umfangreich modifizierte Magento Enterprise Edition 1.12 Instanz auf 1.13.0.2 upgedatet und sind auf einige Stolpersteine gestoßen, die vor dem Update bekannt sein sollten:

  1. Geänderte API bei partieller Indizierung
  2. Eindeutige URL keys
  3. shell_exec Abhängigkeit in Cronjob

Geänderte API bei partieller Indizierung

Die offensichtlichste Änderung in EE 1.13 ist das neue Indexing-System. Wir haben besonderes Augenmerk darauf gelegt, da wir den partiellen Indexer in einem eigenen Import-Skript triggern, um nahtlose Imports im Laufe des Tages zu ermöglichen. Die Umstellung lief erstaunlich gut, es gab nur eine Stelle im Code, die für das neue Indexer API angepasst werden musste.

Bisher nutzten wir die processEntityAction() Methode, um den Indexer für einzelne Produkte zu triggern. Diese wurde durch logEvent(), mit den folgenden Parametern, ersetzt:

Mage::getSingleton('index/indexer')->logEvent(
  new Varien_Object(array(
    'id' => $product->getId(),
    'store_id' => $product->getStoreId(),
    'rule' => $product->getData('rule'),
    'from_date' => $product->getData('from_date'),
    'to_date' => $product->getData('to_date')
  )),
  Enterprise_TargetRule_Model_Index::ENTITY_PRODUCT,
  Enterprise_TargetRule_Model_Index::EVENT_TYPE_REINDEX_PRODUCTS
);

Eindeutige Produkt-URL-Keys

Die Neuerung mit der größten Auwirkung war für uns, dass es nun einen UNIQUE index auf dem URL Key in der URL Rewrite Tabelle gibt. Das gilt im übrigen auch für Magento CE 1.8. Wenn man nun, wie wir, mehrere Store Views hat und beim Import der Produkte für jeden Store View der URL Key gespeichert wird, hat man zwangläufig Duplikate. Das Update-Skript behandelt diese so, dass sie umbenannt werden, was dann wie folgt aussehen kann:

  • http://de.example.com/someproduct.html
  • http://en.example.com/someproduct1.html
  • http://nl.example.com/someproduct2.html

Um dieses Umbenennen zu vermeiden, müssen die URL Rewrites vor dem Update so präpariert werden, dass es nur einen Rewrite pro Produkt und URL Key gibt, und die Store Views „Standard verwenden“ nutzen. Wir haben dazu folgende SQL Query vor dem Update verwendet:

DELETE nondefault
FROM catalog_product_entity_varchar AS nondefault
INNER JOIN catalog_product_entity_varchar AS def ON def.value = nondefault.value
AND def.entity_id = nondefault.entity_id
WHERE def.attribute_id =86
AND nondefault.attribute_id =86
AND nondefault.store_id <>0
AND def.store_id =0

Man beachte, dass 86 hier die ID des URL Key Attributs ist. Hat man das Update bereits laufen lassen, ohne diese Query auszuführen, müssen vorher noch die falsch erstellten URL Keys gelöscht werden. Das kann mit der folgenden Query erledigt werden:

DELETE url_table
FROM  catalog_product_entity_url_key url_table
INNER JOIN catalog_product_entity_varchar old_url_table ON url_table.store_id = old_url_table.store_id
AND url_table.store_id <>0
AND old_url_table.store_id <>0
AND url_table.attribute_id = old_url_table.attribute_id
AND url_table.entity_id = old_url_table.entity_id;

Wie wir später herausgefunden haben, werden mit dem Update auch zwei Skripte geliefert, die sich in /shell verstecken und dieselbe Thematik behandeln:

  • url_migration_to_1_13.php
  • url_migration_from_1_13_0_0_to_1_13_0_2.php

Darüber wie gut diese funktionieren, haben wir allerdings noch keine Erfahrungswerte. Kommentare dazu sind willkommen!

shell_exec Abhängigkeit in Cronjob

Eine weitere kleinere kniffelige Sache war, dass cron.php ein neues Feature hat, das parallele Ausführung erlaubt. Das Skript versucht, ein Shell Skript cron.sh als Hintergrundprozess zu starten, das wiederum cron.php ausführt. Leider funktioniert die Erkennung, ob shell_exec() aktiv ist, nicht zuverlässig. Die möglichen Lösungen sind:

  1. Sicherstellen, dass shell_exec nicht auf der Liste der disabled functions in der PHP Konfiguration steht ODER
  2. Entfernen aller Whitespaces im disabled_functions Wert ODER
  3. Ändern der cron.php und setzen von $isShellDisabled auf true.

English translation

We recently had to update Magento EE 1.12 to 1.13.0.2 on a extensively customized site of a customer and encountered a few pitfalls that you should be aware of, before updating:

  1. API change for partial indexing
  2. Unique product url keys
  3. shell_exec dependency in cronjob

API change for partial indexing

The most obvious change in EE 1.13 is the new indexing system. We paid special attention to this, since we are triggering the partial indexer in a custom import script to allow seamless imports over the day. But this went surprisingly well, there was only one point in the code that had to be adjusted for the new indexer API.

Before the update, we used the processEntityAction() method to trigger the indexer for a single product. This has now been replaced with logEvent() and the following parameters:

Mage::getSingleton('index/indexer')->logEvent(
  new Varien_Object(array(
    'id' => $product->getId(),
    'store_id' => $product->getStoreId(),
    'rule' => $product->getData('rule'),
    'from_date' => $product->getData('from_date'),
    'to_date' => $product->getData('to_date')
  )),
  Enterprise_TargetRule_Model_Index::ENTITY_PRODUCT,
  Enterprise_TargetRule_Model_Index::EVENT_TYPE_REINDEX_PRODUCTS
);

Unique product URL keys

The biggest impact on our system was made by the new UNIQUE index which changed the URL keys in the URL rewrite table. This is also true for Magento CE 1.8. Now, if like us, you have multiple store views and import your products so that for each store view the URL key is saved, you automatically have duplicated keys. The update script is smart enough to not just throw an error but to rename all the keys so you’ll end up with something like:

  • http://de.example.com/someproduct.html
  • http://en.example.com/someproduct1.html
  • http://nl.example.com/someproduct2.html

To avoid that, the URL rewrites have to be fixed before the update, so that there is one rewrite per product and URL key, and the store views use “Use default”. We managed that with a single SQL query before the update:

DELETE nondefault
FROM catalog_product_entity_varchar AS nondefault
INNER JOIN catalog_product_entity_varchar AS def ON def.value = nondefault.value
AND def.entity_id = nondefault.entity_id
WHERE def.attribute_id =86
AND nondefault.attribute_id =86
AND nondefault.store_id <>0
AND def.store_id =0

Note that 86 is the ID of the URL key attribute. If you already have updated your system without running this query first, you have to remove the wrongly created URL keys first, this can be done with the following query:

DELETE url_table
FROM catalog_product_entity_url_key url_table
INNER JOIN catalog_product_entity_varchar old_url_table ON url_table.store_id = old_url_table.store_id
AND url_table.store_id <>0
AND old_url_table.store_id <>0
AND url_table.attribute_id = old_url_table.attribute_id
AND url_table.entity_id = old_url_table.entity_id;

As we found out later, the update also contains two scripts hidden in /shell which address the same topic:

  • url_migration_to_1_13.php
  • url_migration_from_1_13_0_0_to_1_13_0_2.php

But we do not have any empirical values on how they perform, yet. Comments on this are much appreciated!

shell_exec dependency in cronjob

Another minor tricky thing was the new cron.php feature which allows parallel execution. It tries to run the shell script cron.sh as a background process with shell_exec(), which again runs cron.php. Unfortunately, the detection if shell_exec() is active does not work reliably. The possible solutions are:

  1. Make sure that shell_exec is not on the list of disabled functions in your PHP configuration OR
  2. Remove any whitespace in the disabled functions configuration value OR
  3. Change cron.php and manually set $isShellDisabled to true

Antwort hinterlassen