In short: the workaround is to call drupal_flush_all_caches()
and drupal_static_reset()
before reverting the module containing exported features again from an install task.
In detail: The main symptom observed was that blocks (exported as fe_block_settings
components), were not correctly applied on the new site when they depended on a Views block display defined in the same features module. This remained true even after adding an additional call to features_revert_module()
in an installation task. (There were also problems at one point with variables and permissions, but these were cleared up more easily by the addition of the call to features_revert_module()
).
The problem with settings for views blocks is that Views caches all views loaded from the database in a static variable, making any views loaded or enabled for the first time during a single request or drush
command invisible to later calls to views_block_info()
. One possible (tested) workaround is the following:
views_get_all_views(TRUE);
drupal_flush_all_caches();
features_revert_module('xyz');
Supplying TRUE
for the $reset
parameter to views_get_all_views()
forces the module to discard its static cache and re-compute the list of blocks from scratch. This allows the revert of block settings to go through correctly.
Because I suspect this will not be the only problem caused by invalid static variable caches, I am trying the more drastic approach of resetting all static variables and clearing all caches before reverting the module:
drupal_static_reset();
drupal_flush_all_caches();
features_revert_module('xyz');
(Resetting all static variables does produce a few extra PHP warnings, which hopefully are spurious.)
The above lines are run as an installation task, and are combined with the approach described in https://www.drupal.org/node/1901116: i.e., remove the module with exported blocks from the dependencies[]
list, and enable it manually in hook_install()
after enabling themes for the site. The complete implementation in the profile .install
file then looks more like this, where the installation profile is named foo
, the features module is named xyz
and the site theme quux
:
/**
* Implements hook_install().
*/
function foo_install() {
// ... other setup code here ...
// Enable themes
theme_enable(array('seven', 'quux'));
variable_set('admin_theme', 'seven');
variable_set('node_admin_theme', '1');
variable_set('theme_default', 'quux');
// Enable module containing features-exported block settings
module_enable(array('xyz'));
}
/**
* Implements hook_install_tasks().
*/
function foo_install_tasks(&$install_state) {
$tasks = array(
'foo_revert_xyz' => array(
'display_name' => st('Apply all settings in "xyz" module'),
'type' => 'normal',
),
);
return $tasks;
}
function foo_revert_xyz() {
drupal_flush_all_caches();
drupal_static_reset();
features_revert_module('xyz');
}
Tracking this down was a real headache, so I hope the solution is useful to someone else.