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.
For example, I have a complex field (field_multiple_nids) that contains two columns, reference_a and reference_b that both contain referenced node IDs. The code in ctools_entity_from_field only supports the first unique-by-entity-type relationship column found:
// Get the schema information for every field.
$fields_info = field_info_fields();
foreach ($fields_info as $field_name => $field) {
...
$foreign_keys = ctools_field_foreign_keys($field_name);
foreach ($foreign_keys as $key => $info) {
if (isset($info['table'])) {
foreach ($entities as $to_entity => $to_entity_info) {
$from_entity_info = $entities[$from_entity];
...
if (isset($to_entity_info['base table']) && $to_entity_info['base table'] == $info['table'] && array_keys($info['columns'], $to_entity_info['entity keys']['id'])) {
$name = $field_name . '-' . $from_entity . '-' . $to_entity;
$plugin_id = $parent . ':' . $name;
...
// We check for every bundle; this plugin may already have
// been created, so don't recreate it.
if (!isset($plugins[$plugin_id])) {
$plugin = $parent_plugin;
$replacements = array(
'@to_entity' => $to_entity_info['label'],
'@from_entity' => $from_entity_info['label'],
'@field_name' => $field_name,
'@field_label' => ctools_field_label($field_name),
);
$plugin['title'] = t('@to_entity from @from_entity (on @from_entity: @field_label [@field_name])', $replacements);
$plugin['keyword'] = $to_entity;
$plugin['context name'] = $name;
$plugin['name'] = $plugin_id;
$plugin['description'] = t('Creates a @to_entity context from @from_entity using the @field_name field on @from_entity.', $replacements);
$plugin['from entity'] = $from_entity;
$plugin['to entity'] = $to_entity;
$plugin['field name'] = $field_name;
$plugin['join key'] = $key;
$plugin['source key'] = current(array_keys($info['columns']));
...
The above code means that the $name for both columns would both be entity_from_field:field_multiple_nids-node-node and the first column wins (since $plugin['source key'] == 'column_a'
), and the second column loses, and does not get a relationship handler. But it should.
Comment | File | Size | Author |
---|---|---|---|
#7 | multicol_field_relationships-2382127-7.patch | 4.5 KB | KeyboardCowboy |
Comments
Comment #1
Dave ReidI'm just not understanding at all why the actual column names weren't used in the plugin ID. Because now I have no idea how this could be fixed without breaking existing installs.
Comment #2
KeyboardCowboyTook a stab at this one. Basically, if a given foreign key has multiple columns, create a child plugin for each one. Otherwise, proceed as normal.
I used a vertical bar to append the column key name to the field name for plugin id purposes.
Early regression testing passed. Definitely needs another set of eyes, but looks promising.
Comment #3
Dave Reid@KeyboardCowboy: This would still break existing relationships for fields though? If my field had more than one column referring to the same entity type, it now has a changed $name value.
I think for the *first* column that refers to a specific entity type:
$name = $field_name . '|' . $column . '-' . $from_entity . '-' . $to_entity;
But for any remaining columns that refer to the same entity type:
$name = $field_name . '|' . $column . '-' . $from_entity . '-' . $to_entity . '-' . $column;
Or maybe we just leave the existing support for
$name = $field_name . '|' . $column . '-' . $from_entity . '-' . $to_entity;
plugins, but also add each column as$name = $field_name . '|' . $column . '-' . $from_entity . '-' . $to_entity . '-' . $column;
as separate plugins. This would allow us to "deprecate" the existing plugins assuming we could hide them from selection, but still allow them to work.Comment #4
KeyboardCowboy@davereid I think I like the third option. Let me see if I have this correct.
Given:
Custom field schema
The current implementation would provide a plugin named
entity_from_field-node-node
which joined onrel_a
only. The label would look likeNode from Node (on Node: My Multi Field [field_my_multi_field])
.You're suggesting we keep that plugin as is but also add the derivatives, leaving us with, in this example, 4 plugins:
entity_from_field-node-node
=>Node from Node (on Node: My Multi Field [field_my_multi_field])
entity_from_field|rel_a-node-node
=>Node from Node (on Node: My Multi Field [field_my_multi_field:rel_a])
entity_from_field|rel_b-node-node
=>Node from Node (on Node: My Multi Field [field_my_multi_field:rel_b])
entity_from_field|rel_c-node-node
=>Node from Node (on Node: My Multi Field [field_my_multi_field:rel_c])
This way we keep the existing relationships intact but still provide support for the multiple columns. Is that right?
Comment #5
KeyboardCowboyHere's a patch for #4. I'm not sure if there is a good way to remove the deprecated item from the dropdown list (or whether it should be) so it simply marks it as deprecated.
Comment #6
KeyboardCowboyComment #7
KeyboardCowboyCleaning up white space in patch.
Comment #9
Chris Matthews CreditAttribution: Chris Matthews commentedThe 4 year old patch in #7 to entity_from_field.inc still applies cleanly to the latest 7.x-1.x-dev, but still needs to be reviewed & tested.
Applied patch plugins/relationships/entity_from_field.inc cleanly.