Projet

Général

Profil

Paste
Télécharger (6,49 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / entityreference / plugins / behavior / EntityReferenceBehavior_TaxonomyIndex.class.php @ 651307cd

1
<?php
2

    
3
/**
4
 * @file
5
 * CTools plugin class for the taxonomy-index behavior.
6
 */
7

    
8
/**
9
 * Extends an entityreference field to maintain its references to taxonomy terms
10
 * in the {taxonomy_index} table.
11
 *
12
 * Note, unlike entityPostInsert() and entityPostUpdate(), entityDelete()
13
 * is not needed as cleanup is performed by taxonomy module in
14
 * taxonomy_delete_node_index().
15
 */
16
class EntityReferenceBehavior_TaxonomyIndex extends EntityReference_BehaviorHandler_Abstract {
17

    
18
  /**
19
   * Overrides EntityReference_BehaviorHandler_Abstract::access().
20
   *
21
   * Ensure that it is only enabled for ER instances on nodes targeting
22
   * terms, and the core variable to maintain index is enabled.
23
   */
24
  public function access($field, $instance) {
25
    if ($instance['entity_type'] != 'node' || $field['settings']['target_type'] != 'taxonomy_term') {
26
      return;
27
    }
28

    
29
    if ($field['storage']['type'] !== 'field_sql_storage') {
30
      // Field doesn't use SQL storage.
31
      return;
32
    }
33

    
34
    return variable_get('taxonomy_maintain_index_table', TRUE);
35
  }
36

    
37
  /**
38
   * Overrides EntityReference_BehaviorHandler_Abstract::entityPostInsert().
39
   *
40
   * Runs after hook_node_insert() used by taxonomy module.
41
   */
42
  public function entityPostInsert($entity_type, $entity, $field, $instance) {
43
    if ($entity_type != 'node') {
44
      return;
45
    }
46

    
47
    $this->buildNodeIndex($entity);
48
  }
49

    
50
  /**
51
   * Overrides EntityReference_BehaviorHandler_Abstract::entityPostUpdate().
52
   *
53
   * Runs after hook_node_update() used by taxonomy module.
54
   */
55
  public function entityPostUpdate($entity_type, $entity, $field, $instance) {
56
    if ($entity_type != 'node') {
57
      return;
58
    }
59

    
60
    $this->buildNodeIndex($entity);
61
  }
62

    
63
  /**
64
   * Builds and inserts taxonomy index entries for a given node.
65
   *
66
   * The index lists all terms that are related to a given node entity, and is
67
   * therefore maintained at the entity level.
68
   *
69
   * @param $node
70
   *   The node object.
71
   *
72
   * @see taxonomy_build_node_index()
73
   */
74
  protected function buildNodeIndex($node) {
75
    // We maintain a denormalized table of term/node relationships, containing
76
    // only data for current, published nodes.
77
    $status = NULL;
78
    if (variable_get('taxonomy_maintain_index_table', TRUE)) {
79
      // If a node property is not set in the node object when node_save() is
80
      // called, the old value from $node->original is used.
81
      if (!empty($node->original)) {
82
        $status = (int)(!empty($node->status) || (!isset($node->status) && !empty($node->original->status)));
83
        $sticky = (int)(!empty($node->sticky) || (!isset($node->sticky) && !empty($node->original->sticky)));
84
      }
85
      else {
86
        $status = (int)(!empty($node->status));
87
        $sticky = (int)(!empty($node->sticky));
88
      }
89
    }
90
    // We only maintain the taxonomy index for published nodes.
91
    if ($status) {
92
      // Collect a unique list of all the term IDs from all node fields.
93
      $tid_all = array();
94
      foreach (field_info_instances('node', $node->type) as $instance) {
95
        $field_name = $instance['field_name'];
96
        $field = field_info_field($field_name);
97
        if (!empty($field['settings']['target_type']) && $field['settings']['target_type'] == 'taxonomy_term' && $field['storage']['type'] == 'field_sql_storage') {
98
          // If a field value is not set in the node object when node_save() is
99
          // called, the old value from $node->original is used.
100
          if (isset($node->{$field_name})) {
101
            $items = $node->{$field_name};
102
          }
103
          elseif (isset($node->original->{$field_name})) {
104
            $items = $node->original->{$field_name};
105
          }
106
          else {
107
            continue;
108
          }
109
          foreach (field_available_languages('node', $field) as $langcode) {
110
            if (!empty($items[$langcode])) {
111
              foreach ($items[$langcode] as $item) {
112
                $tid_all[$item['target_id']] = $item['target_id'];
113
              }
114
            }
115
          }
116
        }
117

    
118
        // Re-calculate the terms added in taxonomy_build_node_index() so
119
        // we can optimize database queries.
120
        $original_tid_all = array();
121
        if ($field['module'] == 'taxonomy' && $field['storage']['type'] == 'field_sql_storage') {
122
          // If a field value is not set in the node object when node_save() is
123
          // called, the old value from $node->original is used.
124
          if (isset($node->{$field_name})) {
125
            $items = $node->{$field_name};
126
          }
127
          elseif (isset($node->original->{$field_name})) {
128
            $items = $node->original->{$field_name};
129
          }
130
          else {
131
            continue;
132
          }
133
          foreach (field_available_languages('node', $field) as $langcode) {
134
            if (!empty($items[$langcode])) {
135
              foreach ($items[$langcode] as $item) {
136
                $original_tid_all[$item['tid']] = $item['tid'];
137
              }
138
            }
139
          }
140
        }
141
      }
142

    
143
      // Insert index entries for all the node's terms, that were not
144
      // already inserted in taxonomy_build_node_index().
145
      $tid_all = array_diff($tid_all, $original_tid_all);
146

    
147
      // Insert index entries for all the node's terms, preventing duplicates.
148
      if (!empty($tid_all)) {
149
        foreach ($tid_all as $tid) {
150
          $row = array(
151
            'nid' => $node->nid,
152
            'tid' => $tid,
153
            'sticky' => $sticky,
154
            'created' => $node->created,
155
          );
156
          $query = db_merge('taxonomy_index')
157
            ->key($row)
158
            ->fields($row);
159
          $query->execute();
160
        }
161
      }
162
    }
163
  }
164

    
165
  /**
166
   * Overrides EntityReference_BehaviorHandler_Abstract::settingsForm().
167
   */
168
  public function settingsForm($field, $instance) {
169
    $form = array();
170
    $target = $field['settings']['target_type'];
171
    if ($target != 'taxonomy_term') {
172
      $form['ti-on-terms'] = array(
173
        '#markup' => t('This behavior can only be set when the target type is taxonomy_term, but the target of this field is %target.', array('%target' => $target)),
174
      );
175
    }
176

    
177
    $entity_type = $instance['entity_type'];
178
    if ($entity_type != 'node') {
179
      $form['ti-on-nodes'] = array(
180
        '#markup' => t('This behavior can only be set when the entity type is node, but the entity type of this instance is %type.', array('%type' => $entity_type)),
181
      );
182
    }
183

    
184
    if (!variable_get('taxonomy_maintain_index_table', TRUE)) {
185
      $form['ti-disabled'] = array(
186
        '#markup' => t('This core variable "taxonomy_maintain_index_table" is disabled.'),
187
      );
188
    }
189
    return $form;
190
  }
191
}