Project

General

Profile

Paste
Download (9.58 KB) Statistics
| Branch: | Revision:

root / drupal7 / sites / all / modules / ctools / plugins / relationships / entity_from_field.inc @ 6e3ce7c2

1
<?php
2

    
3
/**
4
 * @file
5
 * Plugin to provide an relationship handler for an entity from a field.
6
 */
7

    
8
/**
9
 * Plugins are described by creating a $plugin array which will be used
10
 * by the system that includes this file.
11
 */
12
$plugin = array(
13
  'title' => t('Entity'),
14
  'description' => t('Creates an entity context from a foreign key on a field.'),
15
  'context' => 'ctools_entity_from_field_context',
16
  'edit form' => 'ctools_entity_from_field_edit_form',
17
  'get child' => 'ctools_entity_from_field_get_child',
18
  'get children' => 'ctools_entity_from_field_get_children',
19
  'defaults' => array('delta' => 0),
20
);
21

    
22
function ctools_entity_from_field_get_child($plugin, $parent, $child) {
23
  $plugins = ctools_entity_from_field_get_children($plugin, $parent);
24
  return $plugins[$parent . ':' . $child];
25
}
26

    
27
function ctools_entity_from_field_get_children($parent_plugin, $parent) {
28
  $cid = $parent_plugin['name'] . ':' . $parent;
29
  $cache = &drupal_static(__FUNCTION__);
30
  if (!empty($cache[$cid])) {
31
    return $cache[$cid];
32
  }
33

    
34
  ctools_include('fields');
35
  $entities = entity_get_info();
36
  $plugins = array();
37
  $context_types = array();
38

    
39
  // Get the schema information for every field.
40
  $fields_info = field_info_fields();
41
  foreach ($fields_info as $field_name => $field) {
42
    foreach ($field['bundles'] as $from_entity => $bundles) {
43
      foreach ($bundles as $bundle) {
44
        // There might be fields attached to bundles that are disabled (e.g. a
45
        // module that declared a node's content type, is now disabled), but the
46
        // field instance is still shown.
47
        if (!empty($entities[$from_entity]['bundles'][$bundle])) {
48
          $foreign_keys = ctools_field_foreign_keys($field_name);
49

    
50
          foreach ($foreign_keys as $key => $info) {
51
            if (isset($info['table'])) {
52
              foreach ($entities as $to_entity => $to_entity_info) {
53
                $from_entity_info = $entities[$from_entity];
54
                // If somehow the bundle doesn't exist on the to-entity,
55
                // skip.
56
                if (!isset($from_entity_info['bundles'][$bundle])) {
57
                  continue;
58
                }
59

    
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'])) {
61
                  $name = $field_name . '-' . $from_entity . '-' . $to_entity;
62
                  $plugin_id = $parent . ':' . $name;
63

    
64
                  // Record the bundle for later.
65
                  $context_types[$plugin_id]['types'][$bundle] = $from_entity_info['bundles'][$bundle]['label'];
66

    
67
                  // We check for every bundle; this plugin may already have
68
                  // been created, so don't recreate it.
69
                  if (!isset($plugins[$plugin_id])) {
70
                    $plugin = $parent_plugin;
71
                    $replacements = array(
72
                      '@to_entity' => $to_entity_info['label'],
73
                      '@from_entity' => $from_entity_info['label'],
74
                      '@field_name' => $field_name,
75
                      '@field_label' => ctools_field_label($field_name),
76
                    );
77
                    $plugin['title'] = t('@to_entity from @from_entity (on @from_entity: @field_label [@field_name])', $replacements);
78
                    $plugin['keyword'] = $to_entity;
79
                    $plugin['context name'] = $name;
80
                    $plugin['name'] = $plugin_id;
81
                    $plugin['description'] = t('Creates a @to_entity context from @from_entity using the @field_name field on @from_entity.', $replacements);
82
                    $plugin['from entity'] = $from_entity;
83
                    $plugin['to entity'] = $to_entity;
84
                    $plugin['field name'] = $field_name;
85
                    $plugin['join key'] = $key;
86
                    $plugin['source key'] = current(array_keys($info['columns']));
87
                    $plugin['parent'] = $parent;
88

    
89
                    $plugins[$plugin_id] = $plugin;
90

    
91
/*
92
-- commented out until I figure out how to actually load the reverse properly.
93
                    // Build the reverse
94
                    $plugin = $parent_plugin;
95
                    $name = $field_name . '-' . $from_entity . '-' . $to_entity . '-reverse';
96
                    $plugin_id = $parent . ':' . $name;
97

    
98
                    $plugin['title'] = t('@from_entity from @to_entity (on @from_entity: @field_name)', $replacements);
99
                    $plugin['keyword'] = $to_entity;
100
                    $plugin['context name'] = $name;
101
                    $plugin['name'] = $plugin_id;
102
                    $plugin['description'] = t('Creates a @from_entity context from @to_entity using the @field_name field on @from_entity.', $replacements);
103

    
104
                    $plugin['from entity'] = $from_entity;
105
                    $plugin['to entity'] = $to_entity;
106
                    $plugin['field name'] = $field_name;
107
                    $plugin['reverse'] = TRUE;
108
                    $plugin['parent'] = $parent;
109

    
110
                    // Since we can't apply restrictions on the reverse relationship
111
                    // we just add the required context here.
112
                    $plugin['required context'] = new ctools_context_required($to_entity_info['label'], $to_entity);
113

    
114
                    $plugin_entities = array(
115
                      'to' => array($from_entity => $from_entity_info),
116
                      'from' => array($to_entity => $to_entity_info)
117
                    );
118
                    drupal_alter('ctools_entity_context', $plugin, $plugin_entities, $plugin_id);
119

    
120
                    $plugins[$plugin_id] = $plugin;
121
*/
122
                  }
123
                }
124
              }
125
            }
126
          }
127
        }
128
      }
129
    }
130
  }
131

    
132
  foreach ($context_types as $key => $context) {
133
    list($parent, $plugin_name) = explode(':', $key);
134
    list($field_name, $from_entity, $to_entity) = explode('-', $plugin_name);
135

    
136
    $from_entity_info = $entities[$from_entity];
137
    $to_entity_info = $entities[$to_entity];
138

    
139
    $plugins[$key]['required context'] = new ctools_context_required($from_entity_info['label'], $from_entity, array('type' => array_keys($context['types'])));
140

    
141
    $plugin_entities = array(
142
      'to' => array($to_entity => $to_entity_info),
143
      'from' => array($from_entity => $from_entity_info),
144
    );
145
    drupal_alter('ctools_entity_context', $plugins[$key], $plugin_entities, $key);
146
  }
147
  drupal_alter('ctools_entity_contexts', $plugins);
148

    
149
  $cache[$cid] = $plugins;
150
  return $plugins;
151
}
152

    
153
/**
154
 * Return a new context based on an existing context.
155
 */
156
function ctools_entity_from_field_context($context, $conf) {
157
  // Perform access check on current logged in user.
158
  global $user;
159
  // Clone user object so account can be passed by value to access callback.
160
  $account = clone $user;
161

    
162
  $delta = !empty($conf['delta']) ? intval($conf['delta']) : 0;
163
  $plugin = $conf['name'];
164
  list($plugin, $plugin_name) = explode(':', $plugin);
165
  list($field_name, $from_entity, $to_entity) = explode('-', $plugin_name);
166
  // If unset it wants a generic, unfilled context, which is just NULL.
167
  $entity_info = entity_get_info($from_entity);
168
  if (empty($context->data) || !isset($context->data->{$entity_info['entity keys']['id']})) {
169
    return ctools_context_create_empty('entity:' . $to_entity, NULL);
170
  }
171

    
172
  if (isset($context->data->{$entity_info['entity keys']['id']})) {
173
    // Load the entity.
174
    $id = $context->data->{$entity_info['entity keys']['id']};
175
    $entity = entity_load($from_entity, array($id));
176
    $entity = $entity[$id];
177
    if ($items = field_get_items($from_entity, $entity, $field_name)) {
178
      if (isset($items[$delta])) {
179
        ctools_include('fields');
180
        $to_entity_info = entity_get_info($to_entity);
181

    
182
        $plugin_info = ctools_get_relationship($conf['name']);
183
        $to_entity_id = $items[$delta][$plugin_info['source key']];
184
        $loaded_to_entity = entity_load($to_entity, array($to_entity_id));
185
        $loaded_to_entity = array_shift($loaded_to_entity);
186

    
187
        // Pass current user account and entity type to access callback.
188
        if (isset($to_entity_info['access callback']) && function_exists($to_entity_info['access callback']) && !call_user_func($to_entity_info['access callback'], 'view', $loaded_to_entity, $account, $to_entity)) {
189
          return ctools_context_create_empty('entity:' . $to_entity, NULL);
190
        }
191
        else {
192
          // Send it to ctools.
193
          return ctools_context_create('entity:' . $to_entity, $to_entity_id);
194
        }
195
      }
196
      else {
197
        // In case that delta was empty.
198
        return ctools_context_create_empty('entity:' . $to_entity, NULL);
199
      }
200
    }
201
  }
202
}
203

    
204
function ctools_entity_from_field_edit_form($form, &$form_state) {
205
  $field = field_info_field($form_state['plugin']['field name']);
206
  $conf = $form_state['conf'];
207

    
208
  if ($field && $field['cardinality'] != 1) {
209
    if ($field['cardinality'] == -1) {
210
      $form['delta'] = array(
211
        '#type' => 'textfield',
212
        '#title' => t('Delta'),
213
        '#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.'),
214
        '#default_value' => !empty($conf['delta']) ? $conf['delta'] : 0,
215
      );
216
    }
217
    else {
218
      $form['delta'] = array(
219
        '#type' => 'select',
220
        '#title' => t('Delta'),
221
        '#description' => t('The relationship can only create one context, but multiple items can be related. Please select which one.'),
222
        '#options' => range(1, $field['cardinality']),
223
        '#default_value' => !empty($conf['delta']) ? $conf['delta'] : 0,
224
      );
225
    }
226
  }
227

    
228
  return $form;
229
}