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

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

lachezar.valchev’s picture

Status: Active » Needs review
FileSize
591 bytes

Hi,

Here is the patch.

Credits should also go @skek, who helped me in tracking down the issue.

Regards,
Lachezar

Status: Needs review » Needs work

The last submitted patch, 1: rules-rules_i18n_fatal-2495599-1.patch, failed testing.

lachezar.valchev’s picture

Status: Needs work » Needs review
FileSize
577 bytes

Hi,

Not sure what is wrong with the previous one, but adding new one for re-test.

lachezar.valchev’s picture

Version: 7.x-2.9 » 7.x-2.x-dev

I 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

The last submitted patch, 1: rules-rules_i18n_fatal-2495599-1.patch, failed testing.

lachezar.valchev’s picture

Version: 7.x-2.x-dev » 7.x-2.9
Issue summary: View changes

Obviously the problem was in my first patch. Version returned to 7.x-2.9

Regards,
Lachezar

rossb89’s picture

I 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!

adoltole’s picture

I had the same problem with my own installation profile.
Patch appears to solve this issue.

lachezar.valchev’s picture

Status: Needs review » Reviewed & tested by the community
ndobromirov’s picture

Assigned: lachezar.valchev » Unassigned
Priority: Normal » Critical

This 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.

GoZ’s picture

Testing this patch in a custom profil installation.
Fix the issue for both drush and UI installation.

+1 RTBC

carstenG’s picture

thx lacho...also fixed my problem. greetz from Berlin ;-)

  • fago committed bc20d53 on 7.x-2.x authored by lachezar.valchev
    Issue #2495599 by lachezar.valchev: PHP Fatal error:  Class name must be...
fago’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.