Problem/Motivation

Summary

(from #1054162-30: Taxonomy bundles not supported by EntityFieldQuery (followup))

@tim.plunkett has discovered that #1361232: Make the taxonomy entities classed objects causes a regression with taxonomy entity field queries such that they now cause warnings and notices. An automated test that exposes this bug is attached.

Details

  • A basic EFQ using the taxonomy type seems to work, but causes multiple errors, beginning with array_flip(): Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load(). See http://qa.drupal.org/pifr/test/262368 for details.
  • This bug did not exist prior to the taxonomy entity conversion. The automated test passes prior to that commit.
  • This bug was introduced by the taxonomy entity conversion. The test fails when applied to that commit.

Steps to reproduce

  1. git show 5a8e7bd
    

    (This is the commit from #1361232: Make the taxonomy entities classed objects.)

  2. git checkout -b temp 5a8e7bd^
    

    (Check out the last commit before then.)

  3. git apply --index taxonomy-efq-test-5a8e7bd-do-not-test.patch
    git commit -am "Taxonomy EFQ bug."
    

    (The current test patch does not apply to this commit, so I've attached a version to apply there for convenience.)

  4. Run the Taxonomy EntityFieldQuery test. Test passes.

  5. git rebase 5a8e7bd
    

    (Move the same test up on top of the taxonomy entity conversion commit.)

  6. Run the Taxonomy EntityFieldQuery test. Test assertions pass, but there are lots of exceptions reported.

  7. git rebase origin/8.x
    

    (Move the same test up on top of 8.x HEAD.)

  8. Same result; lots of exceptions.

Comments

xjm’s picture

Status: Active » Needs review

Sending to the bot.

xjm’s picture

Note that, just to be sure, I tested with the fix from #1054162-23: Taxonomy bundles not supported by EntityFieldQuery (followup) and confirmed that it does not resolve this.

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Note that I haven't debugged this yet other than to confirm the regression Tim found.

@Berdir also suggested that we should see if there are similar exceptions for users, comments, or nodes with EFQ.

Status: Needs review » Needs work

The last submitted patch, taxonomy-efq-test.patch, failed testing.

Anonymous’s picture

Issue summary: View changes

Updated issue summary.

berdir’s picture

Is it possible that this is also related to the entity_load() rename. Something is passing invalid arguments to entity_load_multiple(). Try adding a "debug(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS))" right before the test exception happens, that should lead you right to place where this is happening.

Anonymous’s picture

so the flow before the asplode is:

call_user_func_array --> system_batch_page --> _batch_page --> _batch_do --> _batch_process --> call_user_func_array --> _simpletest_batch_operation --> DrupalTestCase::run --> TaxonomyEFQTestCase::testTaxonomyEFQ --> EntityFieldQuery::execute --> call_user_func --> EntityFieldQuery::propertyQuery --> EntityFieldQuery::finishQuery --> entity_create_stub_entity --> entity_create --> TaxonomyTermController::create --> taxonomy_vocabulary_load:

the key brokenosity seems to be that we pass this to TaxonomyTermController::create():

Array
(
    [0] => taxonomy_term
    [1] => Array
        (
            [tid] => 4
        )

)

this is then passed to EntityDatabaseStorageController::create() --> TaxonomyTerm::__construct().

problem is that TaxonomyTerm just doesn't work without also passing in 'vid'. we don't validate that when creating the object, instead we just blow up somewhere down the road a bit.

not sure what the right fix is amongst all those chained calls, but hopefully this will help whoever does know.

xjm’s picture

@Berdir, the patch fails on commit g5a8e7bd and passes before it, so it's definitely related to the entity conversion, because this is before the entity_load() rename. I'll update the summary to make this clear.

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Title: Regression: Taxonomy entity conversion causes exceptions in EFQ for taxonomy entities » Regression: Following taxonomy entity conversion, Taxonomy EFQ causes warnings and notices

Clarifying title (I hope).

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Issue summary: View changes

Updated issue summary.

tim.plunkett’s picture

An interesting note, if you debug($results); in the working state (before the entity conversion), the result is an array of stdClass objects with only tid set.

Currently in 8.x, EFQ still only returns the tid, but it now returns an array of TaxonomyTerm objects. And since it only passes in the tid to the constructor, vital things like vid and vocabulary_machine_name are set to NULL.

tim.plunkett’s picture

Issue summary: View changes

Updated issue summary.

tim.plunkett’s picture

Status: Needs work » Needs review
StatusFileSize
new2.46 KB

There is NO WAY we should do this.
Just proving that it works.

tim.plunkett’s picture

StatusFileSize
new2.57 KB

This reverts entity_create_stub_entity to the D7 version of it, aka before #1184944: Make entities classed objects, introduce CRUD support.

tim.plunkett’s picture

Hm, this seems like it might even be the right fix.

For the entity types that have been converted (everything except file), EFQ gives completely different results than D7.

Given

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node');
$query->range(0, 1);
$result = $query->execute();
var_dump($result);

Here is the result of D7:

array(1) {
  ["node"]=>
  array(1) {
    [101]=>
    object(stdClass)#62 (3) {
      ["nid"]=>
      string(3) "101"
      ["vid"]=>
      string(3) "101"
      ["type"]=>
      string(4) "page"
    }
  }
}

And here is D8:

array(1) {
  ["node"]=>
  array(1) {
    [352]=>
    object(Drupal\node\Node)#48 (18) {
      ["nid"]=>
      string(3) "352"
      ["vid"]=>
      string(3) "352"
      ["type"]=>
      string(5) "event"
      ["langcode"]=>
      string(3) "und"
      ["title"]=>
      NULL
      ["uid"]=>
      NULL
      ["status"]=>
      NULL
      ["created"]=>
      int(1335542356)
      ["changed"]=>
      NULL
      ["comment"]=>
      NULL
      ["promote"]=>
      NULL
      ["sticky"]=>
      NULL
      ["tnid"]=>
      NULL
      ["translate"]=>
      NULL
      ["revision_timestamp"]=>
      NULL
      ["revision_uid"]=>
      NULL
      ["entityType":protected]=>
      string(4) "node"
      ["enforceIsNew":protected]=>
      NULL
    }
  }
}

At least in D7 it was clear this was a stub entity. In D8 its not the case, because it's run through entity_create first. Not doing that and just having a stub entity be a stdClass actually seems more correct to me.

tim.plunkett’s picture

+++ b/core/modules/taxonomy/taxonomy.testundefined
@@ -1913,3 +1913,40 @@ class TaxonomyThemeTestCase extends TaxonomyWebTestCase {
+    ksort($result);

This should be asort(), I'll reroll after someone looks at this.

berdir’s picture

Status: Needs review » Needs work
+++ b/core/modules/entity/entity.moduleundefined
@@ -177,17 +177,16 @@ function entity_extract_ids($entity_type, $entity) {
-  // @todo Once all entities are converted, just rely on entity_create().

Looking at the todo here, it looks like this function is supposed to be removed in favor of entity_create() once all classes have been commited and now it's just File that's missing.

So I'd argue that we should fix the usage of this funciton, not revert it.

tim.plunkett’s picture

Status: Needs work » Needs review

Well when I think about what a stub entity is, I don't think it SHOULD be run through entity_create.

The return value says "An entity object, initialized with the IDs provided."
Not "A classed entity object, initialized with the IDs provided and everything else set to NULL."

You have the entity_type and enough info to load the full entity yourself.

berdir’s picture

Status: Needs review » Reviewed & tested by the community

Ok, discussed this with timplunkett in IRC and we came to an agreement. To quote myself:

(20:42:21) Berdir: timplunkett: ok. I think I'm beginning to agree :) Let's revert the stub function . This is a temporary measure to not unecessarly break BC *yet* without gaining anything through that. Open a follow-up to discuss the EntityStub idea and vid/vocabulary_machine_name mess should be fixed elsewhere as well.
(20:44:47) Berdir: timplunkett: my reasoning was that we are in D8 and do not need bandaid fixes. But the function *is* a bandaid already so it doesn't matter and we can improve it without having a critical sitting on our head :)

The entity stub follow-up is at #1551140: Remove stub entities, replace entity_create_stub_entity(), more detailed explanation of the idea can be found there.

I haven't found an issue for cleaning up the vocabulary_machine_name/vid mess, surprisingly. Does one exist?

sun’s picture

Issue tags: +Entity system, +Regression

Looks good to me. Thanks for debugging this!

And no, we need to create an issue for the vocabulary_machine_name/vid mess. (great simplification ahead)

tim.plunkett’s picture

StatusFileSize
new586 bytes
new2.57 KB

As I mentioned in #13, that ksort should have been asort. Leaving at RTBC.

xjm’s picture

Kickass work! The whole stdClass thing is weird but I am down with handling it in #1551140: Remove stub entities, replace entity_create_stub_entity(). +1 on the RTBC.

Can we clarify what the "vocabulary machine name/vid mess" is? Does this mean getting bundles working with EFQ? (That would be #1054162: Taxonomy bundles not supported by EntityFieldQuery (followup).) Otherwise, all we have are these:
http://drupal.org/project/issues/search/drupal?text=machine+name&status%...

So if appropriate, could we get that followup filed with details of what should happen? Is it "use machine name everywhere in the API?" Also we should add said issue at #1347542: [META] Taxonomy API improvements. :)

berdir’s picture

#1054162: Taxonomy bundles not supported by EntityFieldQuery (followup) is a backportable fix for EFQ. A prober solution would not require this fix in the first place. The current situation with vid/machine_name is the same as if the node_type table had an auto-increment key and nodes would reference that and not the machine_name. If we fix that then we can either revert that fix if it has been commited by then or move it down to 7.x.

Created an issue #1551774: Replace taxonomy_term_data.vid with vocabulary_machine_name

webchick’s picture

I think this is the kind of patch I can commit to 8.x in order to fix brokenness, but the last couple of comments have me confused about whether this is actually RTBC.

berdir’s picture

#18 is RTBC. the discussion in the last two comments is not about this patch but how to continue in follow-up issues.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Follow-ups look fine to me. Committed/pushed this one to 8.x.

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

Anonymous’s picture

Issue summary: View changes

Updated issue summary.