Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
I'm trying to use Metatag with Commerce Product entities, translated with Entity Translation.
When loading an entity with existing translations, the metatag structure looks like:
array(
'en' => array('keywords' => array('value' => 'product')),
'es' => array('keywords' => array('value' => 'producto')),
);
But if I try to update the keywords for the English version via commerce_product_save()
, next time I end up with:
array(
'en' => array(
'en' => array('keywords' => array('value' => 'product, updated')),
'es' => array('keywords' => array('value' => 'producto')),
),
'es' => array('keywords' => array('value' => 'producto')),
);
...The 'en' language record gets populated with the values of all other languages!
Comment | File | Size | Author |
---|---|---|---|
#49 | metatag-n2186155-49.patch | 5.53 KB | DamienMcKenna |
#46 | metatag-n2186155-44-46_interdiff.txt | 2.6 KB | DamienMcKenna |
#46 | metatag-n2186155-46.patch | 21 KB | DamienMcKenna |
#19 | metatag-corrupted_when-2186155-19.patch | 6.12 KB | grahamC |
#17 | interdiff.txt | 618 bytes | JeroenT |
Comments
Comment #1
DamienMcKennaWhen was the last time you updated Metatag? Can you please provide the exact version number you're using?
Comment #2
grahamCFirst discovered the problem in 1.0beta7, but it's still here in current Git HEAD.
I've just been trying to reproduce it with nodes, and I can see that it all works correctly when you update the keywords through the UI.
The problem comes if you try to
node_load()
thennode_save()
a node with multiple languages. Without even trying to update anything on the node object, all the translations are saved under the key of the current language, as described above.Comment #3
grahamCThis looks to have been broken by the fix at #1859136-33: Feeds Integration
Comment #4
DamienMcKennaOr, more to the point, the Feeds integration wasn't updated to handle recent API changes.
Comment #5
DamienMcKennaCould you please test this with the current -dev release? Thanks.
Comment #6
DamienMcKennaNeed confirmation that the problem persists with the current -dev codebase. Thanks.
Comment #7
JeroenTI also have this problem using version 7.x-1.0-rc2 of 2014-aug-05.
To test this i added the following code in a hook_init(). :
I think it has something todo with the following code in the function metatag_metatags_load_multiple :
When you save the entity an array with e.g. nl as language will be serialized. The next time you load the metatags it will be the data will already contain nl and the language is added again.
Edit:
When you save a node using the node form the entity that will be saved is :
The language is not added here.
Comment #8
DamienMcKennaI'll take a look at this today, thanks.
Comment #9
DamienMcKennaI'm going to hammer on this a little bit, I don't want 1.0 going out with a data-corruption bug like this.
Comment #10
DamienMcKennaData corruption = critical.
Comment #11
DamienMcKennaCan you please install the Devel module and try this:
Add that to a php file in your home directory. Create a node with multiple translations, and update the $nid in the code snippet to that node. Verify that you can go through the normal edit processes and everything works fine. Then run the new PHP script and confirm that the data structures are borked again.
Now try applying the enclosed patch and go through all of the steps again with a new node, it should all work correctly now.
Comment #12
DamienMcKennaDoh! The file!
Comment #13
DamienMcKennaComment #14
DamienMcKennaPS this is the last remaining bug before we can release 1.0, any help testing it would be greatly appreciated!
Comment #15
grahamCStill a problem here I'm afraid...
Drupal allows custom language definitions, which may have codes longer than two characters. The site I'm testing on has 'en-gb' as the default language, for example. When I run node_save(), the structure still gets borked under 'en-gb'.
Comment #16
DamienMcKenna@grahamC: Thanks for pointing that out. So instead of checking to see if the array keys have a length of 2 (e.g. "fr") it needs to specifically load the list of available languages and work from that.
Comment #17
JeroenT@DamienMcKenna,
I think it should be something like this. Patch attached.
Comment #18
DamienMcKenna@JeroenT: Thanks, you beat me to it :)
Comment #19
grahamCThe language codes are the keys rather than the values in
$languages
...This version works OK here now.
Bit weird that if you do:
it only deletes the metatags for the current language - is that a bug?
EDIT: Whoops, Interdiff is backwards ... you get the idea though.
Comment #20
DamienMcKenna@grahamC: Ugh. Yeah, that's a tricky one, because metatag_metatags_save() isn't going to know whether the $metatags array was empty because your code manually set $entity->metatags = array(), which should blank out values for all languages, or if there are no values passed from the entity edit form which would only delete the record for the requested language.
Comment #21
DamienMcKennaHow about "solving" this problem with documentation?
Comment #22
DamienMcKennaI've updated the patch with a note in the developer section of the README.txt file to note the issue.
Comment #23
DamienMcKennaAnyone have any feedback on the latest patch? And would a disclaimer in the README.txt be sufficient guard against confusion for people directly manipulating the entity meta tags?
Comment #24
grahamC@DamienMcKenna: I could imagine someone testing on a single-language site where it does the right thing, but unknowingly leaving it broken for multilingual sites... I think the documentation route is reasonable though, given that we're only talking about developers specifically interacting with metatags now.
Comment #25
JeroenTI tested the following situations as suggested in #11:
About directly manipulating the entity meta tags, I don't think if there is another solution to fix this.
Comment #26
Dave ReidWithout reading any of the history here and considering that this workflow is contrary to how field values are saved, I find this incredibly confusing.
Comment #27
DamienMcKenna@Dave: Any recommendations would be greatly appreciated.
Comment #28
DamienMcKenna@Dave: So instead of re-saving all languages, I should maybe just use the same language-check but then only save the current language, matching the effect of submitting an entity through the normal entity edit form?
Comment #29
DamienMcKennaThis version just saves the submitted language.
Comment #30
grahamC@DamienMcKenna:
I'm pretty sure that's the exact opposite of what Dave meant...
node_save() should always persist the current state of the $node object, regardless of the current site language. For example, this is perfectly OK with fields:
Or,
$node->body = array();
for that matter, which deletes the body in both languages.Trying to detect whether the data is in one format or another seems a bit daft - I would expect e.g. a form submit handler to marshall the values into the correct language key, so then you'll always be operating on the nested structure in the generic save function.
Comment #31
DamienMcKennaI just checked - when you do a node_load() on a node which has content in multiple languages (via Entity_Translation) it does indeed contain multiple language values for each field all contained within the one $node object, just like grahamC said. I need to test how the data submission works for fields and then see what it'd take to make Metatag work the same way. Argh.
Comment #32
DamienMcKennaFood for thought. This restructures the form fields to use a nested structure per language, similar to the Form API way of doing it. I've tested it with nodes, users and terms and it appeared to work correctly. When using node_save() it will update the values if they exist, e.g. $node->metatags['en'] will be updated, but just having $node->metatags equal to an empty array will not make any changes. Is this acceptable?
Comment #34
DamienMcKennaLets see if this makes the tests compete.
Comment #35
JeroenTGo testbot!
Comment #37
DamienMcKennaClosed a duplicate: #2332259: Conflict with Scheduler module
Comment #38
DamienMcKennaArgh, the submodules all need to be updated.
Comment #39
DamienMcKennaSome updates to the Metatag:Context module so a) it still works, b) is backwards compatible with previous configurations, c) THE TESTS PASS (at least locally)!!1!
Comment #40
JeroenTGo testbot! :-p
Comment #41
DamienMcKennaActually it needs further work to make integration with the Context UI work, right now just the By Path ui works.
Comment #42
DamienMcKennaThis seems to resolve the context_ui problems too.
Comment #43
DamienMcKennaThere isn't as much funny stuff going on in metatag_panels or metatag_views as metatag_context, so I think they'll be ok.
Comment #44
DamienMcKennaThis version properly handles the scenario where $entity->metatags is an empty array, i.e. all meta tags for that id/revision combination are deleted.
Comment #45
DamienMcKennaWould one (or several) of you here please test out my latest patch to let me know if it works for you? This is the last blocker for 1.0 and I'd like someone else looking over my shoulder so I don't accidentally mess it up (again). Thanks!
Comment #46
DamienMcKennaThis version resolves a problem when creating an entity that the metatag values were not set to the correct language. I also changed the tests to the "Metatag" group, to make it easier to run all tests (drush test-run Metatag).
Comment #48
DamienMcKennaI've tested the patch in #46 rather extensively and have committed it as-is. I'm going to test it tomorrow a little more with a few additional test sites, if there are no problems then I'll release 1.0. Thanks all for the help!
Comment #49
DamienMcKennaI spoke too soon. There were several scenarios which were incorrectly handled by the code committed previously:
This patch resolves these issues.
Comment #51
DamienMcKennaI've tested the latest patch a bunch more times on different entity types, and it all seemed to be working ok, so I'm committing it!
Comment #52
seaarg CreditAttribution: seaarg commentedStill corrupted (description and abstract are the keywords I tested) using
Feeds -dev
Metatags -dev
I did a quick & dirty fix by updating like this on metatag.feeds.inc and it worked.
The node form generated metatags array has 'und' as first level element of the array and the value that comes from feeds is an array on my case
Comment #53
Leeteq CreditAttribution: Leeteq commentedComment #54
DamienMcKennaLets handle the Feeds integration in a new issue: #2347193: Feeds integration borken in 1.0