Hi,
I came across to a bug causing PHP Fatal error during install of custom installation profile using drush. The issue is combination of the usage of Entity API, Rules, Internationalization and the Rules Translation modules and the use of static cache in all those modules.
Drupal: 7.37
Rules: 7.x-2.9
Rules translation: 7.x-2.9
Entity: 7.x-1.6
Entity Tokens: 7.x-1.6
String translation (i18n_string): 7.x-1.13
Internationalization (i18n): 7.x-1.13
Here is the output of the error:
drush --locale=en --site-name="Website" --account-pass=1234 --strict='0' --nocolor --root=/var/www/website --uri=website --yes site-install website
You are about to DROP all tables in your 'website' database. Do you want to continue? (y/n): y
No tables to drop. [ok]
Starting Drupal installation. This takes a few seconds ... [ok]
PHP Fatal error: Class name must be a valid object or a string in /var/www/website/sites/all/modules/contrib/i18n/i18n_string/i18n_string.module on line 343
PHP Stack trace:
PHP 1. {main}() /usr/local/Cellar/drush-6.6.0/drush.php:0
PHP 2. drush_main() /usr/local/Cellar/drush-6.6.0/drush.php:16
PHP 3. _drush_bootstrap_and_dispatch() /usr/local/Cellar/drush-6.6.0/drush.php:61
PHP 4. drush_dispatch() /usr/local/Cellar/drush-6.6.0/drush.php:92
PHP 5. call_user_func_array:{/usr/local/Cellar/drush-6.6.0/includes/command.inc:182}() /usr/local/Cellar/drush-6.6.0/includes/command.inc:182
PHP 6. drush_command() /usr/local/Cellar/drush-6.6.0/includes/command.inc:182
PHP 7. _drush_invoke_hooks() /usr/local/Cellar/drush-6.6.0/includes/command.inc:214
PHP 8. call_user_func_array:{/usr/local/Cellar/drush-6.6.0/includes/command.inc:362}() /usr/local/Cellar/drush-6.6.0/includes/command.inc:362
PHP 9. drush_core_site_install() /usr/local/Cellar/drush-6.6.0/includes/command.inc:362
PHP 10. drush_core_site_install_version() /usr/local/Cellar/drush-6.6.0/commands/core/site_install.drush.inc:191
PHP 11. drush_op() /usr/local/Cellar/drush-6.6.0/commands/core/drupal/site_install.inc:59
PHP 12. drush_call_user_func_array() /usr/local/Cellar/drush-6.6.0/includes/drush.inc:682
PHP 13. install_drupal() /usr/local/Cellar/drush-6.6.0/includes/drush.inc:691
PHP 14. install_run_tasks() /var/www/website/includes/install.core.inc:77
PHP 15. install_run_task() /var/www/website/includes/install.core.inc:339
PHP 16. batch_process() /var/www/website/includes/install.core.inc:444
PHP 17. _batch_process() /var/www/website/includes/form.inc:4629
PHP 18. _batch_finished() /var/www/website/includes/batch.inc:368
PHP 19. _install_profile_modules_finished() /var/www/website/includes/batch.inc:466
PHP 20. drupal_flush_all_caches() /var/www/website/includes/install.core.inc:1611
PHP 21. module_invoke_all() /var/www/website/includes/common.inc:7592
PHP 22. call_user_func_array:{/var/www/website/includes/module.inc:895}() /var/www/website/includes/module.inc:895
PHP 23. entity_flush_caches() /var/www/website/includes/module.inc:895
PHP 24. entity_defaults_rebuild() /var/www/website/sites/all/modules/contrib/entity/entity.module:1080
PHP 25. _entity_defaults_rebuild() /var/www/website/sites/all/modules/contrib/entity/entity.module:853
PHP 26. module_invoke_all() /var/www/website/sites/all/modules/contrib/entity/entity.module:948
PHP 27. call_user_func_array:{/var/www/website/includes/module.inc:895}() /var/www/website/includes/module.inc:895
PHP 28. rules_i18n_rules_config_defaults_rebuild() /var/www/website/includes/module.inc:895
PHP 29. rules_i18n_rules_config_update() /var/www/website/sites/all/modules/contrib/rules/rules_i18n/rules_i18n.module:129
PHP 30. i18n_string_object_wrapper->get_strings() /var/www/website/sites/all/modules/contrib/rules/rules_i18n/rules_i18n.module:95
PHP 31. i18n_string_textgroup() /var/www/website/sites/all/modules/contrib/i18n/i18n_string/i18n_string.inc:1124
The function throwing the error is i18n_string_textgroup($textgroup) (i18n_string module), but we end up to it from that piece of code (rules_i18n module):
// i18n_object() uses a static cache per config, so bypass it to wrap the
// original entity.
$object_key = i18n_object_key('rules_config', $original);
$old_i18n_object = new RulesI18nStringObjectWrapper('rules_config', $object_key, $original);
$old_strings = $old_i18n_object->get_strings(array('empty' => TRUE));
Tracking it down I found out the following:
1. Entity API defines the rules_config entity. Rules i18n is using entity_info_alter hook to add "i18n controller class" to the rules_config entity.
2. In order to be able to build the correct properties i18n_string needs to call get the string info by calling the i18n_object_info() function.
3. This one invokes all i18n_object_info hooks and i18n_object_info_alter-s. It is using a drupal_static cache.
4. The Entity API implements entity_i18n_object_info() where it iterates to get all entity_i18n_controllers through the entity_i18n_controller() function
5. The entity_i18n_controller() function calls the entity_get_info() one. entity_i18n_controller() is using drupal_static cache.
6. Once the entity_i18n_controller() get the entity info in checks for the "i18n controller class".
7. In entity_get_info() static and drupal_static are used.
Now, I could not say 100% why that happens, but for some reason when using drush to install profile and the i18n set of modules are used together with the rules_i18n, the PHP fatal error occurs.
Looking for similar issues I bumped into a thread on the Internationalization module, where they have a patch to reset the drupal_static for the i18n_object_info. This is the thread #1681414: Enabling i18n modules fail in install profile
However their patch is made only for the i18n set of modules. Thus, it appeared to me that the reason has something to do with the cache.
My guess is that when the entity info is build in the entity_get_info() function (commons.inc) there is a static and drupal_static usage and when the install runs the first time we enter the function the cache is set and the entity info for the 'rules_config' does not have information about the "i18n controller class". When the rules_i18n module is then enabled the cache is not cleared and thus the "rules_config" still lacks the information (at least until the cache is cleaned).
So what I did was to implement hook_install() and clean the:
- i18n_object_info cache;
- entity_get_info cache;
- entity_i18n_controller cache;
That made the job. I will add the patch I made below.
The only thing I am not sure is whether I need to clean all the above mentioned 3 caches or just the i18n_object_info will be enough. Looking through the code and following the function I think its best to clean all three.
Regards,
Lachezar
Comment | File | Size | Author |
---|---|---|---|
#3 | rules-rules_i18n_fatal-2495599-2.patch | 577 bytes | lachezar.valchev |
Comments
Comment #1
lachezar.valchev CreditAttribution: lachezar.valchev commentedHi,
Here is the patch.
Credits should also go @skek, who helped me in tracking down the issue.
Regards,
Lachezar
Comment #3
lachezar.valchev CreditAttribution: lachezar.valchev at FFW commentedHi,
Not sure what is wrong with the previous one, but adding new one for re-test.
Comment #4
lachezar.valchev CreditAttribution: lachezar.valchev commentedI think I understood what is the problem with the patch. I am changing the version of the module in the issue from 7.x-2.9 to 7.x-2.x-dev.
BTW, why the dev version of Rules modules is older than the stable?
Regards,
Lachezar
Comment #7
lachezar.valchev CreditAttribution: lachezar.valchev commentedObviously the problem was in my first patch. Version returned to 7.x-2.9
Regards,
Lachezar
Comment #8
rossb89 CreditAttribution: rossb89 at ComputerMinds commentedI have just encountered the same issue as this, using drush to install the profile as detailed in the original post causes the error to occur.
Patch appears to fix the issue for myself, thanks!
Comment #9
adoltole CreditAttribution: adoltole commentedI had the same problem with my own installation profile.
Patch appears to solve this issue.
Comment #10
lachezar.valchev CreditAttribution: lachezar.valchev at FFW commentedComment #11
ndobromirov CreditAttribution: ndobromirov commentedThis was causing issues in the Opigno LMS distribution install.
Moving to critical, as this is blocking site installs from drush (aegir).
The patch in #3 fixed it, so +1 for RTBC.
Hiding the patch in 1.
Comment #12
GoZ CreditAttribution: GoZ at Centarro commentedTesting this patch in a custom profil installation.
Fix the issue for both drush and UI installation.
+1 RTBC
Comment #13
carstenG CreditAttribution: carstenG at FFW commentedthx lacho...also fixed my problem. greetz from Berlin ;-)
Comment #15
fago