There's a subtle bug that shows up in features_get_default() for those rare occasions when module_invoke($m, $default_hook) returns NULL.
The Features code is as follows:
if ($default_hook && module_hook($m, $default_hook)) {
$cache[$component][$m] = module_invoke($m, $default_hook);
if ($alter) {
drupal_alter($default_hook, $cache[$component][$m]);
}
}
As you can see, this takes a default hook named $default_hook, checks to see if the current module $m contains this hook, if it does it then executes that module hook implementation and stores the return as $cache[$component][$m]. Simple stuff.
As an example consider flag.module. It's implementation of hook_views_default_views() starts with the following:
function flag_views_default_views() {
// Only setup views for the "bookmarks" flag.
// If it's been deleted, don't create any views.
$flag = flag_get_flag('bookmarks');
if (!$flag) {
return;
}
In this case, if there is not a flag named 'bookmarks' available it just bails and exits the function with a NULL return. The problem with the Features
logic in features_get_default() is that it doesn't check to see if the return from the hook implementation is valid, it immediately stores it in the $cache array and tries to run drupal_alter() on it.
Then skip on down the line to your own implementation of hook_views_default_views() and the normal expectation that $views is an array no longer is true, so using e.g. if(array_key_exists('myview', $views)) starts to throw errors like this:
warning: array_key_exists() [function.array-key-exists]: The second argument should be either an array or an object in sites/all/modules/Custom/mymodule/mymodule.module on line 1726.
Views' own implementation of this code is in the _views_discover_default_views() function and verifies that the results from the hook implementation was valid before trying to process it, as follows:
$results = call_user_func($module . "_views_default_views");
if (!empty($results) && is_array($results)) {
What I suggest is:
- Verifying that the results from the module_invoke() call is an array.
- If it is an array add it to the cache array and proceed.
- If it is not an array simply
continueto the next iteration of the foreach() loop.
A patch will be forthcoming.
| Comment | File | Size | Author |
|---|---|---|---|
| #8 | features-n949224-8-d6.patch | 917 bytes | damienmckenna |
| #6 | features-default-alter-949224-6.patch | 1.19 KB | mpotter |
| #2 | features-n949224-D6-1.patch | 1.07 KB | damienmckenna |
| #2 | features-n949224-D7-1.patch | 1.09 KB | damienmckenna |
| #2 | features-n949224-D6_v1.0.patch | 896 bytes | damienmckenna |
Comments
Comment #1
damienmckennaFYI the code in the current DRUPAL-6--1 and DRUPAL-7--1 branches is as follows:
Comment #2
damienmckennaHere are patches for the DRUPAL-6--1 and DRUPAL-7--1 branches, and the v6.x-1.0 release.
Comment #3
damienmckennaComment #4
hefox commentedNoticed this before, putting on raider to test when awake
Comment #5
hefox commentedThere's some other bugs in features_get_deault and patches for them, and the patches are overlapping. Should we fix features_get_default in one issue or multiple?
1) runs alter when alter isn't relavent for that hook (hook_node_info_alter)
2) $alter argument messes with the static caching (recalling it with different $alter returns original call cause it's not caching based on alter).
3) this one
1 and 2 are covered in another issue that has conflicting patch
Comment #6
mpotter commentedThis is an old issue, but seems like it still applies. Here is the latest patch for D7. Seems pretty straight-forward so might commit it soon.
Comment #7
mpotter commentedCommitted this to ed51a64 so we can finish fixing other issues in features_get_default.
Comment #8
damienmckennaThanks for working through all these issues!
Rerolled for D6.
Comment #9
damienmckennaAny chance of having this committed? #8 still applies cleanly to the latest 6.x-1.x.
Comment #10
hefox commentedMark the issues you think are RTBC as such and I'll commit them soon.
Comment #11
damienmckennaRTBC, forgot that testbot doesn't work on D6.
Comment #12
hefox commented