Problem/Motivation
When bringing up the feature edit form for a feature that has missing configuration (configuration provided by the feature but not present in the active storage), the following error results:
Fatal error: Call to a member function getPackage() on a non-object in /path/to/site/modules/features/src/FeaturesManager.php on line 567
If this error is addressed, a subsequent error occurs:
Fatal error: Call to a member function getType() on a non-object in /path/to/site/modules/features/modules/features_ui/src/Form/FeaturesEditForm.php on line 539
Both errors result from code that loads the configuration collection (which lists items in the active configuration storage) and then attempts to load from the collection an item that is present in an extension but not on the site.
This specific error results from #2595265: Remodel configuration items in FeaturesManager::configCollection as objects, but the problem presumably predates that change.
Proposed resolution
Test whether the item exists in the configuration collection before calling its methods.
Remaining tasks
Needs tests.
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #10 | features-missing-2624542-9.patch | 742 bytes | mpotter |
| #8 | features-missing-2624542-8.patch | 5.83 KB | mpotter |
| #7 | features-missing-2624542-7.patch | 721 bytes | rjarteta |
| #3 | features-missing-2624542-3.patch | 2.36 KB | nedjo |
Comments
Comment #2
nedjoComment #3
nedjoPatch attached. Setting to "Needs work" because this should have an accompanying test.
Comment #5
nedjoI've applied this fix in order to be able to post a new alpha release. Leaving at needs work pending tests.
Comment #6
kolier commentedAdd one more line to fix this issue in FeaturesEditForm.php
// Make a map of any config specifically excluded and/or required. foreach (array('excluded', 'required') as $constraint) { $this->{$constraint} = array(); $info = !empty($this->package->getFeaturesInfo()[$constraint]) ? $this->package->getFeaturesInfo()[$constraint] : array(); foreach ($info as $item_name) { if (!in_array($item_name, $config)) continue; $item = $config[$item_name]; $this->{$constraint}[$item->getType()][$item->getShortName()] = $item->getLabel(); } }Comment #7
rjarteta commentedAdding the patch suggested by @koiler since the code works properly.
Please review PHPCS
Comment #8
mpotter commentedActually, the patch in #7 isn't correct. You don't test if $item_name is in the $config array since it's a key. You use !isset. Here is a correct patch.
(Also, Drupal coding standard doesn't allow "continue" on the same line like that I don't believe)
Comment #10
mpotter commentedAck, sorry, that got another issue mixed in. Here is the correct patch.
Comment #11
nedjoLooks good.
Comment #14
mpotter commented@nedjo: Do we know what is causing all the patches to fail testing? How do we even see the test results in D8 these days?
Comment #16
mpotter commentedOK, committed to 6de80fb