This bug happens in rather spesific circumstances only. When it happens there is bunch of notices like these:
Notice: Undefined index: widget types in field_info_widget_types() (line 501 of /var/www/d7/modules/field/field.info.inc).
Notice: Undefined index: field types in field_info_field_types() (line 476 of /var/www/d7/modules/field/field.info.inc).

After some debugging I figured that the bug can be reproduced by doing these 3 steps:

  1. create a module that adds any relation type with hook_relation_default_relation_types() implementation
  2. add a dependency from that module to relation module
  3. on a clean Drupal installation enable the custom module (with Drush - I didn't test the UI way)

Step 3. will then install relation, relation_endpoint, ctools and the newly created custom module. endpoint field is added to the relation type but without the default widget.

As a work-around this bug didn't occur if relation module is enabled before enabling the module with hook_relation_default_relation_types() implementation.

Comments

mikran’s picture

Status: Active » Closed (works as designed)

Further testing showed that the issue was actually in specific relation type and not 'any relation type' as I had in bug report. What was special is that endpoint was a bundle that got created on custom_module_install and thus it wasn't available when relation was enabled and default relation types were created.

mikran’s picture

Status: Closed (works as designed) » Needs work
StatusFileSize
new3.4 KB

What I said in previous comment is totally not true. The real issue happens when defaults hook provides more than one relation type. Here is a test to prove this. Test should produce some warnings

mikran’s picture

Status: Needs work » Needs review
mikran’s picture

Status: Needs review » Needs work

Can someone test the patch locally? This is very annoying

mikran’s picture

Status: Needs work » Needs review
StatusFileSize
new3.86 KB

obviously it can't fail if it isn't run in the first place ...

Status: Needs review » Needs work

The last submitted patch, defaults_hook_fails_on_many_relation_types-1936206-5.patch, failed testing.

mikran’s picture

Status: Needs work » Needs review
StatusFileSize
new8.6 KB
new8.28 KB

I don't know why additional field_read_instance call fixes this, but here is a patch anyway.

mikran’s picture

StatusFileSize
new4.34 KB

and a patch without old patch file

naught101’s picture

Status: Needs review » Reviewed & tested by the community

WFM, although I'm kind of surprised you can get away with just one test. Guess we can add more later. Do it!

mikran’s picture

Version: 7.x-1.x-dev » 8.x-1.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

I've committed this, not sure if it's an issue in d8

mikran’s picture

Version: 8.x-1.x-dev » 7.x-1.x-dev
Status: Patch (to be ported) » Needs review
StatusFileSize
new388 bytes

I'm getting test failures from feature modules because of this. Somehow the the fields added by a feature module require the static cache set by field_info_instance. Here is a patch that changes the added field_read_instance to field_info_instance.

I have no clue how to easily create a test to reproduce the error without actually using a feature module. I'll try to return to this later if I figure out something more.

naught101’s picture

StatusFileSize
new3.48 KB

Both https://api.drupal.org/api/drupal/modules!field!field.crud.inc/function/... and https://api.drupal.org/api/drupal/modules!field!field.crud.inc/function/... say that the field_info_* version is preferred, and they return the same thing, with extra info. So how about this instead:

mikran’s picture

Status: Needs review » Reviewed & tested by the community

Looks good and works well. So we shouldn't have ever used field_read_instance here.

mikran’s picture

Issue summary: View changes
Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

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

busla’s picture

Great mikran. Thanks for committing to this issue.

It was messing up my features. I had been trying to track down this issue for a while.

jelle_s’s picture

Status: Closed (fixed) » Active

This breaks an install profile of mine that has relation types defined in code.
Here's the call stack:

[...]
relation_entity_info( ) ../module.inc:895
relation_get_types( ) ../relation.module:41
relation_type_ensure_instance( ) ../relation.module:345
field_create_instance( ) ../relation.module:303
_field_write_instance( ) ../field.crud.inc:512
field_info_max_weight( ) ../field.crud.inc:612
field_info_extra_fields( )	 ../field.info.inc:721
FieldInfo->getBundleExtraFields( ) ../field.info.inc:686
module_invoke_all( ) ../field.info.class.inc:454
call_user_func_array ( ) ../module.inc:895
entity_field_extra_fields( ) ../module.inc:895
entity_get_extra_fields_controller( ) ../entity.module:1346
EntityDefaultExtraFieldsController->__construct( ) ../entity.module:1365
entity_get_property_info( ) ../entity.info.inc:224
drupal_alter( ) ../entity.property.inc:39
relation_entity_property_info_alter( ) ../module.inc:1101
relation_get_types( ) ../relation.module:97
relation_type_ensure_instance( ) ../relation.module:345
field_create_instance( ) ../relation.module:303
_field_write_instance( ) ../field.crud.inc:512
field_info_max_weight( ) ../field.crud.inc:612
field_info_extra_fields( ) ../field.info.inc:721
FieldInfo->getBundleExtraFields( ) ../field.info.inc:686
module_invoke_all( ) ../field.info.class.inc:454
call_user_func_array ( ) ../module.inc:895
entity_field_extra_fields( ) ../module.inc:895

So basically, here's what happens:

  1. Features get enabled by the install profile
  2. Relation's hook_entity_info (relation_entity_info) is called.
  3. relation_entity_info calls relation_get_types
  4. relation_get_types calls relation_type_ensure_instance which creates the instance of the FIRST relation type
  5. When the instance is created field_info_extra_fields is called (I think by drupal core code)
  6. The entity module's hook_field_extra_fields (entity_field_extra_fields) is called.
  7. entity_field_extra_fields calls entity_get_extra_fields_controller for each entity type
  8. entity_get_extra_fields_controller looks like this:
  9.   function entity_get_extra_fields_controller($type = NULL) {
        $static = &drupal_static(__FUNCTION__);
    
        if (!isset($static[$type])) {
          $static[$type] = FALSE;
          $info = entity_get_info($type);
          if (!empty($info['extra fields controller class'])) {
            $static[$type] = new $info['extra fields controller class']($type);
          }
        }
        return $static[$type];
      }
      
  10. The 'extra fields controller class' defaults to EntityDefaultExtraFieldsController
  11. $static[$type] in entity_get_extra_fields_controller stays FALSE until EntityDefaultExtraFieldsController's constructor has finished
  12. EntityDefaultExtraFieldsController's constructor calls entity_get_property_info ($static[$type] is still FALSE)
  13. entity_get_property_info calls relation_entity_property_info_alter ($static[$type] is still FALSE)
  14. relation_entity_property_info_alter calls relation_type_ensure_instance which creates the instance of the SECOND relation type ($static[$type] is still FALSE)
  15. When the instance is created field_info_extra_fields is called (I think by drupal core code) ($static[$type] is still FALSE)
  16. The entity module's hook_field_extra_fields (entity_field_extra_fields) is called. ($static[$type] is still FALSE)
  17. entity_field_extra_fields calls entity_get_extra_fields_controller for each entity type ($static[$type] is still FALSE)
  18. Becuase $static[$type] is still FALSE entity_get_extra_fields_controller returns FALSE
  19. And because of that I get: Fatal error: Call to a member function fieldExtraFields() on a non-object

Quite a long report but I hope it helps debug and fix the issue.

mikran’s picture

Status: Active » Closed (fixed)

That's not the same bug, please reopen open a new issue and try to reduce the list of steps a bit. Also, see (and test) this #1891356: D7: Reset drupal static caches when a module is enabled or disabled..

mikran’s picture

@Jelle_S I just encountered the same problem and the patch from #1891356: D7: Reset drupal static caches when a module is enabled or disabled. was indeed a working solution to it.

mikran’s picture