root / drupal7 / sites / all / modules / entityreference / plugins / behavior / EntityReferenceBehavior_TaxonomyIndex.class.php @ b1ab1c0c
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 |
} |