annotate sites/all/modules/ctools/plugins/relationships/entity_from_field.inc @ 0:ff03f76ab3fe

initial version
author danieleb <danielebarchiesi@me.com>
date Wed, 21 Aug 2013 18:51:11 +0100
parents
children
rev   line source
danielebarchiesi@0 1 <?php
danielebarchiesi@0 2
danielebarchiesi@0 3 /**
danielebarchiesi@0 4 * @file
danielebarchiesi@0 5 * Plugin to provide an relationship handler for an entity from a field.
danielebarchiesi@0 6 */
danielebarchiesi@0 7
danielebarchiesi@0 8 /**
danielebarchiesi@0 9 * Plugins are described by creating a $plugin array which will be used
danielebarchiesi@0 10 * by the system that includes this file.
danielebarchiesi@0 11 */
danielebarchiesi@0 12 $plugin = array(
danielebarchiesi@0 13 'title' => t('Entity'),
danielebarchiesi@0 14 'description' => t('Creates an entity context from a foreign key on a field.'),
danielebarchiesi@0 15 'context' => 'ctools_entity_from_field_context',
danielebarchiesi@0 16 'edit form' => 'ctools_entity_from_field_edit_form',
danielebarchiesi@0 17 'get child' => 'ctools_entity_from_field_get_child',
danielebarchiesi@0 18 'get children' => 'ctools_entity_from_field_get_children',
danielebarchiesi@0 19 'defaults' => array('delta' => 0),
danielebarchiesi@0 20 );
danielebarchiesi@0 21
danielebarchiesi@0 22 function ctools_entity_from_field_get_child($plugin, $parent, $child) {
danielebarchiesi@0 23 $plugins = ctools_entity_from_field_get_children($plugin, $parent);
danielebarchiesi@0 24 return $plugins[$parent . ':' . $child];
danielebarchiesi@0 25 }
danielebarchiesi@0 26
danielebarchiesi@0 27 function ctools_entity_from_field_get_children($parent_plugin, $parent) {
danielebarchiesi@0 28 $cid = $parent_plugin['name'] . ':' . $parent;
danielebarchiesi@0 29 $cache = &drupal_static(__FUNCTION__);
danielebarchiesi@0 30 if (!empty($cache[$cid])) {
danielebarchiesi@0 31 return $cache[$cid];
danielebarchiesi@0 32 }
danielebarchiesi@0 33
danielebarchiesi@0 34 ctools_include('fields');
danielebarchiesi@0 35 $entities = entity_get_info();
danielebarchiesi@0 36 $plugins = array();
danielebarchiesi@0 37 $context_types = array();
danielebarchiesi@0 38
danielebarchiesi@0 39 // Get the schema information for every field.
danielebarchiesi@0 40 $fields_info = field_info_fields();
danielebarchiesi@0 41 foreach ($fields_info as $field_name => $field) {
danielebarchiesi@0 42 foreach ($field['bundles'] as $from_entity => $bundles) {
danielebarchiesi@0 43 foreach ($bundles as $bundle) {
danielebarchiesi@0 44 // There might be fields attached to bundles that are disabled (e.g. a
danielebarchiesi@0 45 // module that declared a node's content type, is now disabled), but the
danielebarchiesi@0 46 // field instance is still shown.
danielebarchiesi@0 47 if (!empty($entities[$from_entity]['bundles'][$bundle])) {
danielebarchiesi@0 48 $foreign_keys = ctools_field_foreign_keys($field_name);
danielebarchiesi@0 49
danielebarchiesi@0 50 foreach ($foreign_keys as $key => $info) {
danielebarchiesi@0 51 if (isset($info['table'])) {
danielebarchiesi@0 52 foreach ($entities as $to_entity => $to_entity_info) {
danielebarchiesi@0 53 $from_entity_info = $entities[$from_entity];
danielebarchiesi@0 54 // If somehow the bundle doesn't exist on the to-entity,
danielebarchiesi@0 55 // skip.
danielebarchiesi@0 56 if (!isset($from_entity_info['bundles'][$bundle])) {
danielebarchiesi@0 57 continue;
danielebarchiesi@0 58 }
danielebarchiesi@0 59
danielebarchiesi@0 60 if (isset($to_entity_info['base table']) && $to_entity_info['base table'] == $info['table'] && array_keys($info['columns'], $to_entity_info['entity keys']['id'])) {
danielebarchiesi@0 61 $name = $field_name . '-' . $from_entity . '-' . $to_entity;
danielebarchiesi@0 62 $plugin_id = $parent . ':' . $name;
danielebarchiesi@0 63
danielebarchiesi@0 64 // Record the bundle for later.
danielebarchiesi@0 65 $context_types[$plugin_id]['types'][$bundle] = $from_entity_info['bundles'][$bundle]['label'];
danielebarchiesi@0 66
danielebarchiesi@0 67 // We check for every bundle; this plugin may already have
danielebarchiesi@0 68 // been created, so don't recreate it.
danielebarchiesi@0 69 if (!isset($plugins[$plugin_id])) {
danielebarchiesi@0 70 $plugin = $parent_plugin;
danielebarchiesi@0 71 $replacements = array(
danielebarchiesi@0 72 '@to_entity' => $to_entity_info['label'],
danielebarchiesi@0 73 '@from_entity' => $from_entity_info['label'],
danielebarchiesi@0 74 '@field_name' => $field_name,
danielebarchiesi@0 75 '@field_label' => ctools_field_label($field_name),
danielebarchiesi@0 76 );
danielebarchiesi@0 77 $plugin['title'] = t('@to_entity from @from_entity (on @from_entity: @field_label [@field_name])', $replacements);
danielebarchiesi@0 78 $plugin['keyword'] = $to_entity;
danielebarchiesi@0 79 $plugin['context name'] = $name;
danielebarchiesi@0 80 $plugin['name'] = $plugin_id;
danielebarchiesi@0 81 $plugin['description'] = t('Creates a @to_entity context from @from_entity using the @field_name field on @from_entity.', $replacements);
danielebarchiesi@0 82 $plugin['from entity'] = $from_entity;
danielebarchiesi@0 83 $plugin['to entity'] = $to_entity;
danielebarchiesi@0 84 $plugin['field name'] = $field_name;
danielebarchiesi@0 85 $plugin['join key'] = $key;
danielebarchiesi@0 86 $plugin['source key'] = current(array_keys($info['columns']));
danielebarchiesi@0 87 $plugin['parent'] = $parent;
danielebarchiesi@0 88
danielebarchiesi@0 89 $plugins[$plugin_id] = $plugin;
danielebarchiesi@0 90
danielebarchiesi@0 91 /*
danielebarchiesi@0 92 -- commented out until I figure out how to actually load the reverse properly.
danielebarchiesi@0 93 // Build the reverse
danielebarchiesi@0 94 $plugin = $parent_plugin;
danielebarchiesi@0 95 $name = $field_name . '-' . $from_entity . '-' . $to_entity . '-reverse';
danielebarchiesi@0 96 $plugin_id = $parent . ':' . $name;
danielebarchiesi@0 97
danielebarchiesi@0 98 $plugin['title'] = t('@from_entity from @to_entity (on @from_entity: @field_name)', $replacements);
danielebarchiesi@0 99 $plugin['keyword'] = $to_entity;
danielebarchiesi@0 100 $plugin['context name'] = $name;
danielebarchiesi@0 101 $plugin['name'] = $plugin_id;
danielebarchiesi@0 102 $plugin['description'] = t('Creates a @from_entity context from @to_entity using the @field_name field on @from_entity.', $replacements);
danielebarchiesi@0 103
danielebarchiesi@0 104 $plugin['from entity'] = $from_entity;
danielebarchiesi@0 105 $plugin['to entity'] = $to_entity;
danielebarchiesi@0 106 $plugin['field name'] = $field_name;
danielebarchiesi@0 107 $plugin['reverse'] = TRUE;
danielebarchiesi@0 108 $plugin['parent'] = $parent;
danielebarchiesi@0 109
danielebarchiesi@0 110 // Since we can't apply restrictions on the reverse relationship
danielebarchiesi@0 111 // we just add the required context here.
danielebarchiesi@0 112 $plugin['required context'] = new ctools_context_required($to_entity_info['label'], $to_entity);
danielebarchiesi@0 113
danielebarchiesi@0 114 $plugin_entities = array(
danielebarchiesi@0 115 'to' => array($from_entity => $from_entity_info),
danielebarchiesi@0 116 'from' => array($to_entity => $to_entity_info)
danielebarchiesi@0 117 );
danielebarchiesi@0 118 drupal_alter('ctools_entity_context', $plugin, $plugin_entities, $plugin_id);
danielebarchiesi@0 119
danielebarchiesi@0 120 $plugins[$plugin_id] = $plugin;
danielebarchiesi@0 121 */
danielebarchiesi@0 122 }
danielebarchiesi@0 123 }
danielebarchiesi@0 124 }
danielebarchiesi@0 125 }
danielebarchiesi@0 126 }
danielebarchiesi@0 127 }
danielebarchiesi@0 128 }
danielebarchiesi@0 129 }
danielebarchiesi@0 130 }
danielebarchiesi@0 131
danielebarchiesi@0 132 foreach ($context_types as $key => $context) {
danielebarchiesi@0 133 list($parent, $plugin_name) = explode(':', $key);
danielebarchiesi@0 134 list($field_name, $from_entity, $to_entity) = explode('-', $plugin_name);
danielebarchiesi@0 135
danielebarchiesi@0 136 $from_entity_info = $entities[$from_entity];
danielebarchiesi@0 137 $to_entity_info = $entities[$to_entity];
danielebarchiesi@0 138
danielebarchiesi@0 139 $plugins[$key]['required context'] = new ctools_context_required($from_entity_info['label'], $from_entity, array('type' => array_keys($context['types'])));
danielebarchiesi@0 140
danielebarchiesi@0 141 $plugin_entities = array(
danielebarchiesi@0 142 'to' => array($to_entity => $to_entity_info),
danielebarchiesi@0 143 'from' => array($from_entity => $from_entity_info)
danielebarchiesi@0 144 );
danielebarchiesi@0 145 drupal_alter('ctools_entity_context', $plugins[$key], $plugin_entities, $key);
danielebarchiesi@0 146 }
danielebarchiesi@0 147 drupal_alter('ctools_entity_contexts', $plugins);
danielebarchiesi@0 148
danielebarchiesi@0 149 $cache[$cid] = $plugins;
danielebarchiesi@0 150 return $plugins;
danielebarchiesi@0 151 }
danielebarchiesi@0 152
danielebarchiesi@0 153 /**
danielebarchiesi@0 154 * Return a new context based on an existing context.
danielebarchiesi@0 155 */
danielebarchiesi@0 156 function ctools_entity_from_field_context($context, $conf) {
danielebarchiesi@0 157 $delta = !empty($conf['delta']) ? intval($conf['delta']) : 0;
danielebarchiesi@0 158 $plugin = $conf['name'];
danielebarchiesi@0 159 list($plugin, $plugin_name) = explode(':', $plugin);
danielebarchiesi@0 160 list($field_name, $from_entity, $to_entity) = explode('-', $plugin_name);
danielebarchiesi@0 161 // If unset it wants a generic, unfilled context, which is just NULL.
danielebarchiesi@0 162 $entity_info = entity_get_info($from_entity);
danielebarchiesi@0 163 if (empty($context->data) || !isset($context->data->{$entity_info['entity keys']['id']})) {
danielebarchiesi@0 164 return ctools_context_create_empty('entity:' . $to_entity, NULL);
danielebarchiesi@0 165 }
danielebarchiesi@0 166
danielebarchiesi@0 167 if (isset($context->data->{$entity_info['entity keys']['id']})) {
danielebarchiesi@0 168 // Load the entity.
danielebarchiesi@0 169 $id = $context->data->{$entity_info['entity keys']['id']};
danielebarchiesi@0 170 $entity = entity_load($from_entity, array($id));
danielebarchiesi@0 171 $entity = $entity[$id];
danielebarchiesi@0 172 if ($items = field_get_items($from_entity, $entity, $field_name)) {
danielebarchiesi@0 173 if (isset($items[$delta])) {
danielebarchiesi@0 174 ctools_include('fields');
danielebarchiesi@0 175 $to_entity_info = entity_get_info($to_entity);
danielebarchiesi@0 176 $plugin_info = ctools_get_relationship($conf['name']);
danielebarchiesi@0 177 $to_entity_id = $items[$delta][$plugin_info['source key']];
danielebarchiesi@0 178
danielebarchiesi@0 179 // Send it to ctools.
danielebarchiesi@0 180 return ctools_context_create('entity:' . $to_entity, $to_entity_id);
danielebarchiesi@0 181 }
danielebarchiesi@0 182 else {
danielebarchiesi@0 183 // In case that delta was empty.
danielebarchiesi@0 184 return ctools_context_create_empty('entity:' . $to_entity, NULL);
danielebarchiesi@0 185 }
danielebarchiesi@0 186 }
danielebarchiesi@0 187 }
danielebarchiesi@0 188 }
danielebarchiesi@0 189
danielebarchiesi@0 190 function ctools_entity_from_field_edit_form($form, &$form_state) {
danielebarchiesi@0 191 $field = field_info_field($form_state['plugin']['field name']);
danielebarchiesi@0 192 $conf = $form_state['conf'];
danielebarchiesi@0 193
danielebarchiesi@0 194 if ($field && $field['cardinality'] != 1) {
danielebarchiesi@0 195 if ($field['cardinality'] == -1) {
danielebarchiesi@0 196 $form['delta'] = array(
danielebarchiesi@0 197 '#type' => 'textfield',
danielebarchiesi@0 198 '#title' => t('Delta'),
danielebarchiesi@0 199 '#description' => t('The relationship can only create one context, but multiple items can be related. Please select which one. Since this can have unlimited items, type in the number you want. The first one will be 0.'),
danielebarchiesi@0 200 '#default_value' => !empty($conf['delta']) ? $conf['delta'] : 0,
danielebarchiesi@0 201 );
danielebarchiesi@0 202 }
danielebarchiesi@0 203 else {
danielebarchiesi@0 204 $form['delta'] = array(
danielebarchiesi@0 205 '#type' => 'select',
danielebarchiesi@0 206 '#title' => t('Delta'),
danielebarchiesi@0 207 '#description' => t('The relationship can only create one context, but multiple items can be related. Please select which one.'),
danielebarchiesi@0 208 '#options' => range(1, $field['cardinality']),
danielebarchiesi@0 209 '#default_value' => !empty($conf['delta']) ? $conf['delta'] : 0,
danielebarchiesi@0 210 );
danielebarchiesi@0 211 }
danielebarchiesi@0 212 }
danielebarchiesi@0 213
danielebarchiesi@0 214 return $form;
danielebarchiesi@0 215 }