Révision 98a362c2
Ajouté par Assos Assos il y a plus de 6 ans
drupal7/sites/all/modules/shs/shs.module | ||
---|---|---|
28 | 28 |
* Implements hook_js(). |
29 | 29 |
*/ |
30 | 30 |
function shs_js() { |
31 |
return array(
|
|
31 |
$settings = array(
|
|
32 | 32 |
'json' => array( |
33 | 33 |
'callback' => 'shs_json', |
34 |
'access callback' => 'user_access',
|
|
34 |
'access callback' => 'user_access', |
|
35 | 35 |
'access arguments' => array('access content'), |
36 |
'dependencies' => array('taxonomy'), |
|
36 |
'includes' => array('path'), |
|
37 |
'dependencies' => array('taxonomy', 'field', 'field_sql_storage'), |
|
37 | 38 |
), |
38 | 39 |
); |
40 |
drupal_alter('shs_js_info', $settings); |
|
41 |
return $settings; |
|
42 |
} |
|
43 |
|
|
44 |
/** |
|
45 |
* Implements hook_requirements(). |
|
46 |
*/ |
|
47 |
function shs_requirements($phase) { |
|
48 |
$requirements = array(); |
|
49 |
$t = get_t(); |
|
50 |
|
|
51 |
if ($phase !== 'runtime' || !module_exists('chosen')) { |
|
52 |
return $requirements; |
|
53 |
} |
|
54 |
if (($info = drupal_get_library('chosen', 'chosen')) === FALSE) { |
|
55 |
return $requirements; |
|
56 |
} |
|
57 |
// Chosen version should be at least 1.0. |
|
58 |
if (version_compare($info['version'], '1.1.0') < 0) { |
|
59 |
$requirements['shs'] = array( |
|
60 |
'title' => $t('Simple hierarchical select: chosen integration'), |
|
61 |
'description' => $t('If you would like to use chosen with Simple hierarchical select you need to install at least version 1.1.0 of !chosen_library.', array('!chosen_library' => l('Chosen', 'http://harvesthq.github.io/chosen/'))), |
|
62 |
'severity' => REQUIREMENT_WARNING, |
|
63 |
'value' => $t('Chosen library too old (installed version is !version)', array('!version' => $info['version'])), |
|
64 |
); |
|
65 |
} |
|
66 |
|
|
67 |
return $requirements; |
|
39 | 68 |
} |
40 | 69 |
|
41 | 70 |
/** |
... | ... | |
80 | 109 |
'shs_json_term_get_children' => array( |
81 | 110 |
'callback' => 'shs_json_term_get_children', |
82 | 111 |
'arguments' => array( |
83 |
'vid' => 'is_numeric',
|
|
112 |
'vid' => 'shs_json_validation_vocabulary_identifier',
|
|
84 | 113 |
'parent' => 'is_array', |
85 | 114 |
'settings' => 'is_array', |
115 |
'field' => 'is_string', |
|
86 | 116 |
), |
87 | 117 |
), |
88 | 118 |
'shs_json_term_add' => array( |
89 | 119 |
'callback' => 'shs_json_term_add', |
90 | 120 |
'arguments' => array( |
91 |
'vid' => 'is_numeric',
|
|
121 |
'vid' => 'shs_json_validation_vocabulary_identifier',
|
|
92 | 122 |
'parent' => 'is_numeric', |
93 | 123 |
'name' => 'is_string', |
124 |
'field' => 'is_string', |
|
94 | 125 |
), |
95 | 126 |
), |
96 | 127 |
); |
... | ... | |
116 | 147 |
// Get arguments from callback definition. |
117 | 148 |
$callback_arguments = $callback['arguments']; |
118 | 149 |
foreach ($arguments as $key => $value) { |
119 |
if (isset($callback_arguments[$key])) { |
|
120 |
$argument_valid = TRUE; |
|
121 |
if ((($validation_function = $callback_arguments[$key]) !== FALSE) && function_exists($validation_function)) { |
|
122 |
// Validate argument. |
|
123 |
$argument_valid = $validation_function($value); |
|
124 |
} |
|
125 |
if ($argument_valid) { |
|
126 |
// Add argument and its value to the result list. |
|
127 |
$result[$key] = $value; |
|
128 |
} |
|
150 |
if (!isset($callback_arguments[$key])) { |
|
151 |
continue; |
|
152 |
} |
|
153 |
$argument_valid = TRUE; |
|
154 |
if ((($validation_function = $callback_arguments[$key]) !== FALSE) && function_exists($validation_function)) { |
|
155 |
// Validate argument. |
|
156 |
$argument_valid = $validation_function($value); |
|
157 |
} |
|
158 |
if ($argument_valid) { |
|
159 |
// Add argument and its value to the result list. |
|
160 |
$result[$key] = $value; |
|
129 | 161 |
} |
130 | 162 |
} |
131 | 163 |
return $result; |
... | ... | |
135 | 167 |
* Implements hook_views_data_alter(). |
136 | 168 |
*/ |
137 | 169 |
function shs_views_data_alter(&$data) { |
138 |
// Get a list of all field instances with widget type "taxonomy_shs". |
|
139 |
$instances = _shs_get_instances('node'); |
|
140 |
foreach ($instances as $field_instances) { |
|
141 |
foreach ($field_instances as $field_name => $instance) { |
|
142 |
// Replace filter handler for this field. |
|
143 |
if (!empty($data["field_data_{$field_name}"]["{$field_name}_tid"]['filter']['handler'])) { |
|
144 |
$data["field_data_{$field_name}"]["{$field_name}_tid"]['filter']['handler'] = 'shs_handler_filter_term_node_tid'; |
|
145 |
} |
|
146 |
} |
|
147 |
} |
|
148 |
|
|
149 | 170 |
// Add filter handler for term ID with depth. |
150 | 171 |
$data['node']['shs_term_node_tid_depth'] = array( |
151 | 172 |
'help' => t('Display content if it has the selected taxonomy terms, or children of the selected terms. Due to additional complexity, this has fewer options than the versions without depth. Optionally the filter will use a simple hierarchical select for the selection of terms.'), |
152 | 173 |
'real field' => 'nid', |
153 | 174 |
'filter' => array( |
154 |
'title' => t('Has taxonomy terms (with depth; %type)', array('%type' => 'Simple hierarchical select')),
|
|
175 |
'title' => t('Has taxonomy terms (with depth; @type)', array('@type' => 'Simple hierarchical select')),
|
|
155 | 176 |
'handler' => 'shs_handler_filter_term_node_tid_depth', |
156 | 177 |
), |
157 | 178 |
); |
158 | 179 |
} |
159 | 180 |
|
181 |
/** |
|
182 |
* Implements hook_field_views_data_alter(). |
|
183 |
*/ |
|
184 |
function shs_field_views_data_alter(&$result, &$field, $module) { |
|
185 |
if (empty($field['columns']) || !in_array($field['type'], array('taxonomy_term_reference', 'entityreference'))) { |
|
186 |
return; |
|
187 |
} |
|
188 |
if ($field['type'] == 'entityreference' && (empty($field['settings']['target_type']) || $field['settings']['target_type'] != 'taxonomy_term')) { |
|
189 |
// Do not change entityreference fields that do not reference terms. |
|
190 |
return; |
|
191 |
} |
|
192 |
$field_column = key($field['columns']); |
|
193 |
foreach ($result as $key => $group) { |
|
194 |
$field_identifier = sprintf('%s_%s', $field['field_name'], $field_column); |
|
195 |
if (empty($group[$field_identifier]) || empty($group[$field_identifier]['filter']['handler'])) { |
|
196 |
// Only modify field definitions for the primary column. |
|
197 |
continue; |
|
198 |
} |
|
199 |
// Replace handler. |
|
200 |
$result[$key][$field_identifier]['filter']['handler'] = ($field['type'] == 'entityreference') ? 'shs_handler_filter_entityreference' : 'shs_handler_filter_term_node_tid'; |
|
201 |
} |
|
202 |
} |
|
203 |
|
|
204 |
/** |
|
205 |
* Implements hook_conditional_fields_states_handlers_alter(). |
|
206 |
*/ |
|
207 |
function shs_conditional_fields_states_handlers_alter(&$handlers) { |
|
208 |
$handlers += array( |
|
209 |
'shs_conditional_fields_states_handler_shs' => array( |
|
210 |
array( |
|
211 |
'tid' => array( |
|
212 |
'#type' => 'select', |
|
213 |
), |
|
214 |
), |
|
215 |
), |
|
216 |
); |
|
217 |
} |
|
218 |
|
|
219 |
/** |
|
220 |
* States handler for simple hierarchical selects. |
|
221 |
*/ |
|
222 |
function shs_conditional_fields_states_handler_shs($field, $field_info, &$options, &$state) { |
|
223 |
switch ($options['values_set']) { |
|
224 |
case CONDITIONAL_FIELDS_DEPENDENCY_VALUES_WIDGET: |
|
225 |
case CONDITIONAL_FIELDS_DEPENDENCY_VALUES_AND: |
|
226 |
if (empty($state[$options['state']][$options['selector']])) { |
|
227 |
return; |
|
228 |
} |
|
229 |
$old_state = $state[$options['state']][$options['selector']]; |
|
230 |
if (isset($old_state['value'][0]['tid'])) { |
|
231 |
// Completly remove old state. |
|
232 |
unset($state[$options['state']][$options['selector']]); |
|
233 |
$options['selector'] .= '-0-tid'; |
|
234 |
$state[$options['state']][$options['selector']] = $old_state; |
|
235 |
$state[$options['state']][$options['selector']]['value'] = $old_state['value'][0]['tid']; |
|
236 |
} |
|
237 |
return; |
|
238 |
|
|
239 |
case CONDITIONAL_FIELDS_DEPENDENCY_VALUES_XOR: |
|
240 |
$select_states[$options['state']][] = 'xor'; |
|
241 |
|
|
242 |
case CONDITIONAL_FIELDS_DEPENDENCY_VALUES_REGEX: |
|
243 |
$regex = TRUE; |
|
244 |
case CONDITIONAL_FIELDS_DEPENDENCY_VALUES_NOT: |
|
245 |
case CONDITIONAL_FIELDS_DEPENDENCY_VALUES_OR: |
|
246 |
foreach ($options['values'] as $value) { |
|
247 |
$select_states[$options['state']][] = array( |
|
248 |
$options['selector'] => array( |
|
249 |
$options['condition'] => empty($regex) ? array($value) : $options['value'], |
|
250 |
), |
|
251 |
); |
|
252 |
} |
|
253 |
break; |
|
254 |
} |
|
255 |
|
|
256 |
$state = $select_states; |
|
257 |
} |
|
258 |
|
|
160 | 259 |
/** |
161 | 260 |
* Implements hook_field_widget_info(). |
162 | 261 |
*/ |
... | ... | |
164 | 263 |
return array( |
165 | 264 |
'taxonomy_shs' => array( |
166 | 265 |
'label' => t('Simple hierarchical select'), |
167 |
'field types' => array('taxonomy_term_reference'), |
|
266 |
'field types' => array('taxonomy_term_reference', 'entityreference'),
|
|
168 | 267 |
'settings' => array( |
169 | 268 |
'shs' => array( |
170 |
'node_count' => FALSE, |
|
171 | 269 |
'create_new_terms' => FALSE, |
172 | 270 |
'create_new_levels' => FALSE, |
173 | 271 |
'force_deepest' => FALSE, |
... | ... | |
178 | 276 |
} |
179 | 277 |
|
180 | 278 |
/** |
181 |
* Implements hook__field_widget_settings_form(). |
|
279 |
* Implements hook_form_FORM_ID_alter(). |
|
280 |
*/ |
|
281 |
function shs_form_field_ui_field_settings_form_alter(&$form, &$form_state, $form_id) { |
|
282 |
if (module_exists('entityreference') && $form['field']['type']['#value'] == 'entityreference' && $form['field']['settings']['#instance']['widget']['type'] == 'taxonomy_shs') { |
|
283 |
$form['field']['settings']['#field']['settings']['target_type'] = 'taxonomy_term'; |
|
284 |
$form['field']['settings']['#process'][] = 'shs_entityreference_field_settings_process'; |
|
285 |
} |
|
286 |
} |
|
287 |
|
|
288 |
/** |
|
289 |
* Implements hook_form_FORM_ID_alter(). |
|
290 |
*/ |
|
291 |
function shs_form_field_ui_field_edit_form_alter(&$form, &$form_state, $form_id) { |
|
292 |
if (module_exists('entityreference') && $form['#field']['type'] == 'entityreference' && $form['#instance']['widget']['type'] == 'taxonomy_shs') { |
|
293 |
$form['#field']['settings']['target_type'] = 'taxonomy_term'; |
|
294 |
$form['field']['settings']['#process'][] = 'shs_entityreference_field_settings_process'; |
|
295 |
} |
|
296 |
} |
|
297 |
|
|
298 |
/** |
|
299 |
* Additional processing function for the entityreference field settings form. |
|
300 |
* |
|
301 |
* @param array $form |
|
302 |
* Form structure to process. |
|
303 |
* @param array $form_state |
|
304 |
* Current form state. |
|
305 |
* |
|
306 |
* @return array |
|
307 |
* Processed form structure. |
|
308 |
*/ |
|
309 |
function shs_entityreference_field_settings_process($form, $form_state) { |
|
310 |
if (!empty($form['target_type'])) { |
|
311 |
// Reduce list of available target types to taxonomy terms. |
|
312 |
$form['target_type']['#options'] = array( |
|
313 |
'taxonomy_term' => t('Taxonomy term'), |
|
314 |
); |
|
315 |
} |
|
316 |
return $form; |
|
317 |
} |
|
318 |
|
|
319 |
/** |
|
320 |
* Implements hook_field_widget_settings_form(). |
|
182 | 321 |
*/ |
183 | 322 |
function shs_field_widget_settings_form($field, $instance) { |
184 | 323 |
$widget = $instance['widget']; |
... | ... | |
193 | 332 |
'#collapsed' => FALSE, |
194 | 333 |
'#tree' => TRUE, |
195 | 334 |
); |
196 |
$form['shs']['node_count'] = array( |
|
197 |
'#type' => 'checkbox', |
|
198 |
'#title' => t('Display number of nodes'), |
|
199 |
'#description' => t('Display the number of nodes associated with the term.'), |
|
200 |
'#default_value' => empty($settings['shs']['node_count']) ? FALSE : $settings['shs']['node_count'], |
|
201 |
); |
|
202 |
$form['shs']['create_new_terms'] = array( |
|
203 |
'#type' => 'checkbox', |
|
204 |
'#title' => t('Allow creating new terms'), |
|
205 |
'#description' => t('If checked the user will be able to create new terms (permission to edit terms in this vocabulary must be set).'), |
|
206 |
'#default_value' => empty($settings['shs']['create_new_terms']) ? FALSE : $settings['shs']['create_new_terms'], |
|
207 |
); |
|
208 |
$form['shs']['create_new_levels'] = array( |
|
209 |
'#type' => 'checkbox', |
|
210 |
'#title' => t('Allow creating new levels'), |
|
211 |
'#description' => t('If checked the user will be able to create new children for items which do not have any children yet (permission to edit terms in this vocabulary must be set).'), |
|
212 |
'#default_value' => empty($settings['shs']['create_new_levels']) ? FALSE : $settings['shs']['create_new_levels'], |
|
213 |
'#states' => array( |
|
214 |
'visible' => array( |
|
215 |
':input[name="instance[widget][settings][shs][create_new_terms]"]' => array('checked' => TRUE), |
|
335 |
|
|
336 |
if ($field['type'] != 'entityreference' || ($field['type'] == 'entityreference' && !empty($field['settings']['handler_settings']['target_bundles']) && count($field['settings']['handler_settings']['target_bundles']) == 1)) { |
|
337 |
$form['shs']['create_new_terms'] = array( |
|
338 |
'#type' => 'checkbox', |
|
339 |
'#title' => t('Allow creating new terms'), |
|
340 |
'#description' => t('If checked the user will be able to create new terms (permission to edit terms in this vocabulary must be set).'), |
|
341 |
'#default_value' => empty($settings['shs']['create_new_terms']) ? FALSE : $settings['shs']['create_new_terms'], |
|
342 |
); |
|
343 |
$form['shs']['create_new_levels'] = array( |
|
344 |
'#type' => 'checkbox', |
|
345 |
'#title' => t('Allow creating new levels'), |
|
346 |
'#description' => t('If checked the user will be able to create new children for items which do not have any children yet (permission to edit terms in this vocabulary must be set).'), |
|
347 |
'#default_value' => empty($settings['shs']['create_new_levels']) ? FALSE : $settings['shs']['create_new_levels'], |
|
348 |
'#states' => array( |
|
349 |
'visible' => array( |
|
350 |
':input[name="instance[widget][settings][shs][create_new_terms]"]' => array('checked' => TRUE), |
|
351 |
), |
|
216 | 352 |
), |
217 |
),
|
|
218 |
);
|
|
353 |
);
|
|
354 |
}
|
|
219 | 355 |
$form['shs']['force_deepest'] = array( |
220 | 356 |
'#type' => 'checkbox', |
221 | 357 |
'#title' => t('Force selection of deepest level'), |
... | ... | |
252 | 388 |
* Implements hook_field_widget_form(). |
253 | 389 |
*/ |
254 | 390 |
function shs_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { |
391 |
$field_column = key($field['columns']); |
|
255 | 392 |
// Get value. |
256 | 393 |
$element_value = NULL; |
257 |
if (!empty($items[$delta]['tid'])) { |
|
394 |
$submitted_value = NULL; |
|
395 |
if (!empty($form_state['values']) && !empty($element['#parents'])) { |
|
396 |
$submitted_value = drupal_array_get_nested_value($form_state['values'], $element['#parents']); |
|
397 |
} |
|
398 |
if (!empty($items[$delta][$field_column])) { |
|
258 | 399 |
// Use saved value from database or cache. |
259 |
$element_value = $items[$delta]['tid'];
|
|
400 |
$element_value = $items[$delta][$field_column];
|
|
260 | 401 |
} |
261 |
elseif (!empty($form_state['values'][$element['#field_name']][$element['#language']][$delta]['tid'])) {
|
|
402 |
elseif (!empty($submitted_value)) {
|
|
262 | 403 |
// Use value from form_state (for example for fields with cardinality = -1). |
263 |
$element_value = $form_state['values'][$element['#field_name']][$element['#language']][$delta]['tid'];
|
|
404 |
$element_value = array('tid' => $submitted_value);
|
|
264 | 405 |
} |
265 | 406 |
|
266 |
// Get vocabulary. |
|
267 |
$allowed_values = reset($field['settings']['allowed_values']); |
|
268 |
if (empty($allowed_values['vocabulary']) || ($vocabulary = taxonomy_vocabulary_machine_name_load($allowed_values['vocabulary'])) === FALSE) { |
|
269 |
// No vocabulary selected yet or vocabulary not found. |
|
407 |
// Get vocabulary names from allowed values. |
|
408 |
if ($field['type'] == 'entityreference') { |
|
409 |
if ('views' === $field['settings']['handler']) { |
|
410 |
$vocabulary_names = array(); |
|
411 |
$view_settings = $field['settings']['handler_settings']['view']; |
|
412 |
// Try to load vocabularies from view filter. |
|
413 |
$vocabulary_names = _shs_entityreference_views_get_vocabularies($view_settings['view_name'], $view_settings['display_name']); |
|
414 |
} |
|
415 |
else { |
|
416 |
$vocabulary_names = $field['settings']['handler_settings']['target_bundles']; |
|
417 |
} |
|
418 |
} |
|
419 |
else { |
|
420 |
$allowed_values = reset($field['settings']['allowed_values']); |
|
421 |
$vocabulary_names = empty($allowed_values['vocabulary']) ? FALSE : $allowed_values['vocabulary']; |
|
422 |
} |
|
423 |
if (empty($vocabulary_names) && (empty($field['settings']['handler']) || ('views' !== $field['settings']['handler']))) { |
|
424 |
// No vocabulary selected yet. |
|
270 | 425 |
return array(); |
271 | 426 |
} |
427 |
if (!is_array($vocabulary_names)) { |
|
428 |
$vocabulary_names = array($vocabulary_names); |
|
429 |
} |
|
430 |
$vocabularies = array(); |
|
431 |
foreach ($vocabulary_names as $vocabulary_name) { |
|
432 |
if (($vocabulary = taxonomy_vocabulary_machine_name_load($vocabulary_name)) === FALSE) { |
|
433 |
// Vocabulary not found. Stop here. |
|
434 |
return array(); |
|
435 |
} |
|
436 |
$vocabularies[] = $vocabulary; |
|
437 |
} |
|
272 | 438 |
|
273 |
// Check if term exists (may be deleted).
|
|
439 |
// Check if term exists (the term could probably be deleted meanwhile).
|
|
274 | 440 |
if ($element_value && (($term = taxonomy_term_load($element_value)) === FALSE)) { |
275 | 441 |
$element_value = 0; |
276 | 442 |
} |
277 | 443 |
|
278 |
if (!user_access('edit terms in ' . $vocabulary->vid)) { |
|
279 |
// Update setting based on permission. |
|
444 |
if (count($vocabularies) > 1 || !isset($vocabulary) || (isset($vocabulary) && !user_access('edit terms in ' . $vocabulary->vid))) { |
|
445 |
// Creating new terms is allowed only with proper permission and if only one |
|
446 |
// vocabulary is selected as source. |
|
280 | 447 |
$instance['widget']['settings']['shs']['create_new_terms'] = FALSE; |
281 | 448 |
} |
449 |
$instance['widget']['settings']['shs']['test_create_new_terms'] = module_implements('shs_add_term_access'); |
|
282 | 450 |
$instance['widget']['settings']['shs']['required'] = $element['#required']; |
283 | 451 |
|
284 |
// Element is required and there is no initial value. |
|
285 |
if (empty($element_value) && $element['#required']) { |
|
286 |
// Load list of options. |
|
287 |
$options = shs_term_get_children($vocabulary->vid, 0); |
|
288 |
if (count($options)) { |
|
289 |
// Set element value to first available option. |
|
290 |
$option_keys = array_keys($options); |
|
291 |
$element_value = reset($option_keys); |
|
452 |
// Prepare the list of options. |
|
453 |
if ($field['type'] == 'entityreference') { |
|
454 |
// Get current selection handler. |
|
455 |
$handler = entityreference_get_selection_handler($field, $instance, $element['#entity_type'], $element['#entity']); |
|
456 |
$referencable_entities = $handler->getReferencableEntities(); |
|
457 |
$options = array( |
|
458 |
'_none' => empty($element['#required']) ? t('- None -', array(), array('context' => 'shs')) : t('- Select a value -', array(), array('context' => 'shs')), |
|
459 |
); |
|
460 |
foreach ($referencable_entities as $v_name => $terms) { |
|
461 |
$options += $terms; |
|
292 | 462 |
} |
293 | 463 |
} |
294 |
|
|
464 |
else { |
|
465 |
$properties = _options_properties('select', FALSE, $element['#required'], !empty($element_value)); |
|
466 |
$options = _options_get_options($field, $instance, $properties, $element['#entity_type'], $element['#entity']); |
|
467 |
} |
|
295 | 468 |
// Create element. |
296 | 469 |
$element += array( |
297 |
'#type' => 'textfield',
|
|
470 |
'#type' => 'select',
|
|
298 | 471 |
'#default_value' => empty($element_value) ? NULL : $element_value, |
472 |
'#options' => $options, |
|
299 | 473 |
'#attributes' => array( |
300 | 474 |
'class' => array('shs-enabled'), |
301 | 475 |
), |
... | ... | |
304 | 478 |
'#element_validate' => array('shs_field_widget_validate'), |
305 | 479 |
'#after_build' => array('shs_field_widget_afterbuild'), |
306 | 480 |
'#shs_settings' => $instance['widget']['settings']['shs'], |
307 |
'#shs_vocabulary' => $vocabulary,
|
|
481 |
'#shs_vocabularies' => $vocabularies,
|
|
308 | 482 |
); |
309 | 483 |
|
310 |
return array('tid' => $element); |
|
484 |
$return = array($field_column => $element); |
|
485 |
if (!empty($element['#title'])) { |
|
486 |
// Set title to "parent" element to enable label translation. |
|
487 |
$return['#title'] = $element['#title']; |
|
488 |
} |
|
489 |
return $return; |
|
311 | 490 |
} |
312 | 491 |
|
313 | 492 |
/** |
... | ... | |
324 | 503 |
} |
325 | 504 |
|
326 | 505 |
$parents = array(); |
327 |
// Get value from element. |
|
328 |
if (!empty($form_state['values'][$element['#field_name']][$element['#language']][$element['#delta']]['tid'])) { |
|
506 |
// Get default value from form state and set it to element. |
|
507 |
$default_value = drupal_array_get_nested_value($form_state['values'], $element['#parents']); |
|
508 |
if (!empty($default_value)) { |
|
329 | 509 |
// Use value from form_state (for example for fields with cardinality = -1). |
330 |
$element['#default_value'] = $form_state['values'][$element['#field_name']][$element['#language']][$element['#delta']];
|
|
510 |
$element['#default_value'] = $default_value;
|
|
331 | 511 |
} |
332 | 512 |
|
333 | 513 |
// Add main Javascript behavior and style only once. |
... | ... | |
341 | 521 |
// Create Javascript settings for the element only if it hasn't been added |
342 | 522 |
// before. |
343 | 523 |
if (empty($js_added[$element['#name']][$js_hash])) { |
344 |
$element_value = $element['#default_value']['tid'];
|
|
524 |
$element_value = $element['#default_value']; |
|
345 | 525 |
|
346 |
if (empty($element_value)) { |
|
347 |
// Add fake parent for new items. |
|
526 |
// Ensure field is rendered if it is required but not selected. |
|
527 |
if (empty($element_value) || $element_value == '_none') { |
|
528 |
// Add fake parent for new items or field required submit fail. |
|
348 | 529 |
$parents[] = array('tid' => 0); |
349 | 530 |
} |
350 | 531 |
else { |
... | ... | |
355 | 536 |
} |
356 | 537 |
} |
357 | 538 |
|
539 |
$vocabularies = $element['#shs_vocabularies']; |
|
540 |
$vocabulary_identifier = NULL; |
|
541 |
if (count($vocabularies) == 1) { |
|
542 |
// Get ID from first (and only) vocabulary. |
|
543 |
$vocabulary_identifier = $vocabularies[0]->vid; |
|
544 |
} |
|
545 |
else { |
|
546 |
$vocabulary_identifier = array( |
|
547 |
'field_name' => $element['#field_name'], |
|
548 |
); |
|
549 |
} |
|
550 |
|
|
358 | 551 |
// Create settings needed for our js magic. |
359 | 552 |
$settings_js = array( |
360 | 553 |
'shs' => array( |
361 | 554 |
"{$element['#name']}" => array( |
362 | 555 |
$js_hash => array( |
363 |
'vid' => $element['#shs_vocabulary']->vid,
|
|
556 |
'vid' => $vocabulary_identifier,
|
|
364 | 557 |
'settings' => $element['#shs_settings'], |
365 | 558 |
'default_value' => $element['#default_value'], |
366 | 559 |
'parents' => array_reverse($parents), |
560 |
'any_label' => empty($element['#required']) ? t('- None -', array(), array('context' => 'shs')) : t('- Select a value -', array(), array('context' => 'shs')), |
|
561 |
'any_value' => '_none', |
|
367 | 562 |
), |
368 | 563 |
), |
369 | 564 |
), |
370 | 565 |
); |
566 |
// Allow other modules to alter these settings. |
|
567 |
drupal_alter(array('shs_js_settings', "shs_{$element['#field_name']}_js_settings"), $settings_js, $element['#field_name'], $vocabulary_identifier); |
|
371 | 568 |
|
372 | 569 |
// Add settings. |
373 | 570 |
drupal_add_js($settings_js, 'setting'); |
... | ... | |
378 | 575 |
$js_added[$element['#name']][$js_hash] = TRUE; |
379 | 576 |
} |
380 | 577 |
|
578 |
unset($element['#needs_validation']); |
|
381 | 579 |
return $element; |
382 | 580 |
} |
383 | 581 |
|
... | ... | |
386 | 584 |
*/ |
387 | 585 |
function shs_field_widget_validate($element, &$form_state, $form) { |
388 | 586 |
$field_name = $element['#field_name']; |
389 |
$field_language = $element['#language'];
|
|
587 |
$instance = field_widget_instance($element, $form_state);
|
|
390 | 588 |
|
391 |
if (empty($form_state['field'][$field_name][$field_language]['instance']['widget'])) {
|
|
589 |
if (empty($instance['widget'])) {
|
|
392 | 590 |
return; |
393 | 591 |
} |
394 |
$field = $form_state['field'][$field_name][$field_language]; |
|
395 |
$instance = $field['instance']; |
|
396 |
$settings = empty($instance['widget']['settings']['shs']) ? array() : $instance['widget']['settings']['shs']; |
|
397 | 592 |
|
593 |
// Load default settings. |
|
594 |
$settings = empty($instance['widget']['settings']['shs']) ? array() : $instance['widget']['settings']['shs']; |
|
595 |
if (!empty($element['#shs_settings'])) { |
|
596 |
// Use settings directly applied to widget (possibly overridden in |
|
597 |
// hook_field_widget_form_alter() or |
|
598 |
// hook_field_widget_WIDGET_TYPE_form_alter()). |
|
599 |
$settings = $element['#shs_settings']; |
|
600 |
} |
|
398 | 601 |
// Do we want to force the user to select terms from the deepest level? |
399 | 602 |
$force_deepest_level = empty($settings['force_deepest']) ? FALSE : $settings['force_deepest']; |
400 |
$value = empty($element['#value']) ? 0 : $element['#value']; |
|
603 |
$field = field_widget_field($element, $form_state); |
|
604 |
|
|
605 |
$value = empty($element['#value']) ? '_none' : $element['#value']; |
|
606 |
if ($value == '_none') { |
|
607 |
unset($element['#value']); |
|
608 |
form_set_value($element, NULL, $form_state); |
|
609 |
} |
|
610 |
if ($element['#required'] && $value == '_none') { |
|
611 |
$element_name = empty($element['#title']) ? $instance['label'] : $element['#title']; |
|
612 |
form_error($element, t('!name field is required.', array('!name' => $element_name))); |
|
613 |
return; |
|
614 |
} |
|
401 | 615 |
if ($force_deepest_level && $value) { |
402 |
// Get vocabulary. |
|
403 |
$allowed_values = reset($field['field']['settings']['allowed_values']); |
|
404 |
if (empty($allowed_values['vocabulary']) || ($vocabulary = taxonomy_vocabulary_machine_name_load($allowed_values['vocabulary'])) === FALSE) { |
|
405 |
// No vocabulary selected yet or vocabulary not found. |
|
406 |
form_error($element, t('Vocabulary %machine_name is configured as source for field %field_name but could not be found.', array('%machine_name' => $allowed_values['vocabulary'], '%field_name' => $field_name))); |
|
616 |
// Get vocabulary names from allowed values. |
|
617 |
if ($field['type'] == 'entityreference') { |
|
618 |
$vocabulary_names = $field['settings']['handler_settings']['target_bundles']; |
|
407 | 619 |
} |
408 |
// Does the selected term has any children? |
|
409 |
$children = shs_term_get_children($vocabulary->vid, $value); |
|
410 |
if (count($children)) { |
|
411 |
form_error($element, t('You need to select a term from the deepest level.')); |
|
620 |
else { |
|
621 |
$allowed_values = reset($field['settings']['allowed_values']); |
|
622 |
$vocabulary_names = empty($allowed_values['vocabulary']) ? FALSE : $allowed_values['vocabulary']; |
|
623 |
} |
|
624 |
if (empty($vocabulary_names)) { |
|
625 |
// No vocabulary selected yet. |
|
626 |
form_error($element, t('No vocabulary is configured as source for field %field_name.', array('%field_name' => $instance['label'], '%field_machine_name' => $field_name))); |
|
627 |
} |
|
628 |
if (!is_array($vocabulary_names)) { |
|
629 |
$vocabulary_names = array($vocabulary_names); |
|
630 |
} |
|
631 |
foreach ($vocabulary_names as $vocabulary_name) { |
|
632 |
if (($vocabulary = taxonomy_vocabulary_machine_name_load($vocabulary_name)) === FALSE) { |
|
633 |
// Vocabulary not found. Stop here. |
|
634 |
form_error($element, t('Vocabulary %machine_name is configured as source for field %field_name but could not be found.', array('%machine_name' => $vocabulary_name, '%field_name' => $instance['label'], '%field_machine_name' => $field_name))); |
|
635 |
return; |
|
636 |
} |
|
637 |
// Does the selected term has any children? |
|
638 |
$children = shs_term_get_children($vocabulary->vid, $value); |
|
639 |
if (count($children)) { |
|
640 |
form_error($element, t('You need to select a term from the deepest level in field %field_name.', array('%field_name' => $instance['label'], '%field_machine_name' => $field_name))); |
|
641 |
return; |
|
642 |
} |
|
412 | 643 |
} |
413 | 644 |
} |
414 | 645 |
} |
... | ... | |
420 | 651 |
return array( |
421 | 652 |
'shs_default' => array( |
422 | 653 |
'label' => t('Simple hierarchy'), |
423 |
'field types' => array('taxonomy_term_reference'), |
|
654 |
'field types' => array('taxonomy_term_reference', 'entityreference'),
|
|
424 | 655 |
'settings' => array( |
425 | 656 |
'linked' => FALSE, |
426 | 657 |
), |
... | ... | |
468 | 699 |
* Implements hook_field_formatter_prepare_view(). |
469 | 700 |
*/ |
470 | 701 |
function shs_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) { |
702 |
$field_column = key($field['columns']); |
|
471 | 703 |
foreach ($entities as $entity_id => $entity) { |
704 |
if (empty($instances[$entity_id]['widget']['type']) || $instances[$entity_id]['widget']['type'] != 'taxonomy_shs') { |
|
705 |
return; |
|
706 |
} |
|
472 | 707 |
foreach ($items[$entity_id] as $delta => $item) { |
473 | 708 |
$items[$entity_id][$delta]['parents'] = array(); |
474 | 709 |
// Load list of parent terms. |
475 |
$parents = taxonomy_get_parents_all($item['tid']);
|
|
710 |
$parents = taxonomy_get_parents_all($item[$field_column]);
|
|
476 | 711 |
// Remove current term from list. |
477 | 712 |
array_shift($parents); |
713 |
if (module_exists('i18n_taxonomy')) { |
|
714 |
// Localize terms. |
|
715 |
$parents = i18n_taxonomy_localize_terms($parents); |
|
716 |
} |
|
478 | 717 |
foreach (array_reverse($parents) as $parent) { |
479 | 718 |
$items[$entity_id][$delta]['parents'][$parent->tid] = $parent; |
480 | 719 |
} |
481 | 720 |
// Load term. |
482 |
$items[$entity_id][$delta]['term'] = taxonomy_term_load($item['tid']); |
|
721 |
$term_current = taxonomy_term_load($item[$field_column]); |
|
722 |
if (module_exists('i18n_taxonomy')) { |
|
723 |
// Localize current term. |
|
724 |
$term_current = i18n_taxonomy_localize_terms($term_current); |
|
725 |
} |
|
726 |
$items[$entity_id][$delta]['term'] = $term_current; |
|
483 | 727 |
} |
484 | 728 |
} |
485 | 729 |
} |
... | ... | |
491 | 735 |
$elements = array(); |
492 | 736 |
$settings = $display['settings']; |
493 | 737 |
|
738 |
if (empty($items) || $instance['widget']['type'] != 'taxonomy_shs') { |
|
739 |
return $elements; |
|
740 |
} |
|
741 |
|
|
494 | 742 |
switch ($display['type']) { |
495 | 743 |
case 'shs_default': |
496 | 744 |
foreach ($items as $delta => $item) { |
497 |
if (empty($item['tid'])) {
|
|
745 |
if (empty($item['term'])) {
|
|
498 | 746 |
continue; |
499 | 747 |
} |
500 | 748 |
$list_items = array(); |
... | ... | |
533 | 781 |
* The structure is stored in the database cache as well as in drupal_static(). |
534 | 782 |
* Cache has the following structure: |
535 | 783 |
* <code> |
536 |
* [$parent] => array( |
|
537 |
* [0] => array(tid1, tid2, tid3), // !$node_count. |
|
538 |
* [1] => array('tid1 (x)', 'tid2 (x)', 'tid3 (x)'), // $node_count. |
|
539 |
* ), |
|
784 |
* [$parent] => array(), |
|
540 | 785 |
* </code> |
541 | 786 |
* |
542 |
* @param <int> $vid |
|
543 |
* ID of vocabulary the term is associated to. |
|
787 |
* @param <mixed> $identifier |
|
788 |
* Either a vocabulary ID or an array with the following keys: |
|
789 |
* - field_name: Name of field which sends the request. |
|
544 | 790 |
* @param <int> $parent |
545 | 791 |
* ID of parent term. |
546 | 792 |
* @param <array> $settings |
547 |
* Additional settings (for example "display node count").
|
|
793 |
* Additional settings (for example "language", etc.,).
|
|
548 | 794 |
* @param <boolean> $reset |
549 | 795 |
* If TRUE, rebuild the cache for the given $vid and $parent. |
550 | 796 |
* |
551 | 797 |
* @return <array> |
552 | 798 |
* List of child terms keyed by term id. |
553 | 799 |
*/ |
554 |
function shs_term_get_children($vid, $parent = 0, $settings = array(), $reset = FALSE) { |
|
800 |
function shs_term_get_children($identifier, $parent = 0, $settings = array(), $reset = FALSE) { |
|
801 |
global $language; |
|
802 |
$langcode = $language->language; |
|
803 |
if (empty($settings['language']->language)) { |
|
804 |
$settings['language'] = $language; |
|
805 |
} |
|
806 |
else { |
|
807 |
$langcode = $settings['language']->language; |
|
808 |
} |
|
809 |
|
|
810 |
$vocabularies = array(); |
|
811 |
$vocabulary_cache_key = NULL; |
|
812 |
if (is_numeric($identifier)) { |
|
813 |
$vocabulary_cache_key = $identifier; |
|
814 |
if (($vocabulary = taxonomy_vocabulary_load($identifier)) === FALSE) { |
|
815 |
watchdog('Simple hierarchical select', 'Unknown vocabulary with ID !vid used to get terms.', array('!vid' => $identifier)); |
|
816 |
return array(); |
|
817 |
} |
|
818 |
$vocabularies[$vocabulary->machine_name] = $identifier; |
|
819 |
} |
|
820 |
elseif (is_array($identifier) && !empty($identifier['field_name'])) { |
|
821 |
$vocabulary_cache_key = $identifier['field_name']; |
|
822 |
} |
|
823 |
|
|
555 | 824 |
$terms = &drupal_static(__FUNCTION__, array()); |
556 |
$node_count = !empty($settings['node_count']) && variable_get('taxonomy_maintain_index_table', TRUE); |
|
557 | 825 |
|
558 |
if ($reset || ($vid && empty($terms[$vid][$parent][$node_count]))) {
|
|
826 |
if ($reset || ($vocabulary_cache_key && empty($terms[$vocabulary_cache_key][$langcode][$parent]))) {
|
|
559 | 827 |
// Initialize list. |
560 |
$terms[$vid][$parent] = array( |
|
561 |
0 => array(), |
|
562 |
1 => array(), |
|
563 |
); |
|
564 |
$cache_key = "shs:{$vid}"; |
|
828 |
$terms[$vocabulary_cache_key][$langcode][$parent] = array(); |
|
829 |
$cache_key = "shs:{$vocabulary_cache_key}"; |
|
565 | 830 |
// Get cached values. |
566 | 831 |
$cache = cache_get($cache_key); |
567 |
if ($reset || !$cache || ($cache->expire && time() > $cache->expire) || empty($cache->data[$parent][$node_count])) {
|
|
832 |
if ($reset || !$cache || ($cache->expire && time() > $cache->expire) || empty($cache->data[$langcode][$parent])) {
|
|
568 | 833 |
// Cache is empty or data has become outdated or the parent is not cached. |
569 | 834 |
if ($cache) { |
570 | 835 |
// Cache exists and is not yet expired but $parent is missing. |
571 |
$terms[$vid] = $cache->data;
|
|
836 |
$terms[$vocabulary_cache_key] = $cache->data;
|
|
572 | 837 |
} |
573 | 838 |
if ($reset) { |
574 |
$terms[$vid][$parent] = array( |
|
575 |
0 => array(), |
|
576 |
1 => array(), |
|
577 |
); |
|
839 |
$terms[$vocabulary_cache_key][$langcode][$parent] = array(); |
|
578 | 840 |
} |
579 |
// Get term children (only first level). |
|
580 |
$tree = taxonomy_get_tree($vid, $parent, 1); |
|
581 |
foreach ($tree as $term) { |
|
582 |
$terms[$vid][$parent][0][$term->tid] = $term->name; |
|
583 |
if ($node_count) { |
|
584 |
// Count nodes associated to this term (and its children). |
|
585 |
$num_nodes = _shs_term_get_node_count($term, TRUE); |
|
586 |
// Update term label. |
|
587 |
$terms[$vid][$parent][1][$term->tid] = t('!term_name (!node_count)', array('!term_name' => $term->name, '!node_count' => $num_nodes)); |
|
841 |
|
|
842 |
if (!is_numeric($vocabulary_cache_key) && is_array($identifier)) { |
|
843 |
// Get list of vocabularies from field configuration. |
|
844 |
$field = field_info_field($identifier['field_name']); |
|
845 |
if (!empty($field['settings']['handler_settings']['target_bundles'])) { |
|
846 |
foreach ($field['settings']['handler_settings']['target_bundles'] as $vocabulary_name) { |
|
847 |
if (($vocabulary = taxonomy_vocabulary_machine_name_load($vocabulary_name)) !== FALSE) { |
|
848 |
$vocabularies[$vocabulary_name] = $vocabulary->vid; |
|
849 |
} |
|
850 |
} |
|
851 |
} |
|
852 |
} |
|
853 |
|
|
854 |
foreach ($vocabularies as $name => $vid) { |
|
855 |
// Get term children (only first level). |
|
856 |
// Only load entities if i18n_taxonomy or entity_translation is |
|
857 |
// installed. |
|
858 |
$load_entities = module_exists('i18n_taxonomy') || module_exists('entity_translation'); |
|
859 |
$tree = taxonomy_get_tree($vid, $parent, 1, $load_entities); |
|
860 |
foreach ($tree as $term) { |
|
861 |
$term_name = $term->name; |
|
862 |
if (module_exists('i18n_taxonomy')) { |
|
863 |
$term_name = i18n_taxonomy_term_name($term, $langcode); |
|
864 |
} |
|
865 |
else if (module_exists('entity_translation')) { |
|
866 |
$term_name = entity_label('taxonomy_term', $term); |
|
867 |
} |
|
868 |
$terms[$vocabulary_cache_key][$langcode][$parent][$term->tid] = $term_name; |
|
588 | 869 |
} |
589 | 870 |
} |
590 | 871 |
// Set cached data. |
591 |
cache_set($cache_key, $terms[$vid], 'cache', CACHE_PERMANENT);
|
|
872 |
cache_set($cache_key, $terms[$vocabulary_cache_key], 'cache', CACHE_PERMANENT);
|
|
592 | 873 |
} |
593 | 874 |
else { |
594 | 875 |
// Use cached data. |
595 |
$terms[$vid] = $cache->data;
|
|
876 |
$terms[$vocabulary_cache_key] = $cache->data;
|
|
596 | 877 |
} |
597 | 878 |
} |
598 | 879 |
// Allow other module to modify the list of terms. |
599 | 880 |
$alter_options = array( |
600 |
'vid' => $vid,
|
|
881 |
'vid' => $vocabulary_cache_key,
|
|
601 | 882 |
'parent' => $parent, |
602 | 883 |
'settings' => $settings, |
603 | 884 |
); |
604 | 885 |
drupal_alter('shs_term_get_children', $terms, $alter_options); |
605 | 886 |
|
606 |
return empty($terms[$vid][$parent][$node_count]) ? array() : $terms[$vid][$parent][$node_count];
|
|
887 |
return empty($terms[$vocabulary_cache_key][$langcode][$parent]) ? array() : $terms[$vocabulary_cache_key][$langcode][$parent];
|
|
607 | 888 |
} |
608 | 889 |
|
609 | 890 |
/** |
610 | 891 |
* JSON callback to get the list of children of a term. |
611 | 892 |
* |
612 |
* @param <int> $vid
|
|
893 |
* @param int $vid
|
|
613 | 894 |
* ID of vocabulary the term is associated to. |
614 |
* @param <int> $parent
|
|
615 |
* ID of parent term.
|
|
616 |
* @param <array> $settings
|
|
895 |
* @param array $parent
|
|
896 |
* List of parent terms.
|
|
897 |
* @param array $settings
|
|
617 | 898 |
* Additional settings (for example "display node count"). |
899 |
* @param string $field |
|
900 |
* Name of field requesting the term list (DOM element name). |
|
618 | 901 |
* |
619 |
* @return <array>
|
|
902 |
* @return array
|
|
620 | 903 |
* Associative list of child terms. |
621 | 904 |
* |
622 | 905 |
* @see shs_term_get_children() |
623 | 906 |
*/ |
624 |
function shs_json_term_get_children($vid, $parent = array(), $settings = array()) { |
|
907 |
function shs_json_term_get_children($vid, $parent = array(), $settings = array(), $field = NULL) {
|
|
625 | 908 |
$scope = $result = array(); |
626 | 909 |
foreach ($parent as $tid) { |
627 | 910 |
$scope[] = shs_term_get_children($vid, $tid, $settings); |
911 |
if (shs_add_term_access($vid, $tid, $field)) { |
|
912 |
$result[] = array( |
|
913 |
'vid' => $vid, |
|
914 |
); |
|
915 |
} |
|
628 | 916 |
} |
629 | 917 |
|
630 | 918 |
// Rewrite result set to preserve original sort of terms through JSON request. |
... | ... | |
633 | 921 |
$result[] = array( |
634 | 922 |
'tid' => $tid, |
635 | 923 |
'label' => $label, |
924 |
'has_children' => shs_term_has_children($tid, $vid), |
|
636 | 925 |
); |
637 | 926 |
} |
638 | 927 |
} |
639 | 928 |
|
640 | 929 |
return $result; |
641 | 930 |
} |
931 |
|
|
932 |
/** |
|
933 |
* Check if a term has any children. |
|
934 |
* |
|
935 |
* Copied from taxonomy_get_children() but just checks existence instead of |
|
936 |
* loading terms. |
|
937 |
*/ |
|
938 |
function shs_term_has_children($tid, $vid) { |
|
939 |
$query = db_select('taxonomy_term_data', 't'); |
|
940 |
$query->addExpression(1); |
|
941 |
$query->join('taxonomy_term_hierarchy', 'h', 'h.tid = t.tid'); |
|
942 |
$query->condition('h.parent', $tid); |
|
943 |
if ($vid) { |
|
944 |
$query->condition('t.vid', $vid); |
|
945 |
} |
|
946 |
$query->range(0, 1); |
|
947 |
|
|
948 |
return (bool) $query->execute()->fetchField(); |
|
949 |
} |
|
950 |
|
|
951 |
/** |
|
952 |
* Return access to create new terms. |
|
953 |
* |
|
954 |
* @param int $vid |
|
955 |
* ID of vocabulary to create the term in. |
|
956 |
* @param int $parent |
|
957 |
* ID of parent term (0 for top level). |
|
958 |
* @param string $field |
|
959 |
* Name of field requesting the term list (DOM element name). |
|
960 |
* @param object $account |
|
961 |
* The user to check access for. |
|
962 |
* |
|
963 |
* @return bool |
|
964 |
* TRUE or FALSE based on if user can create a term. |
|
965 |
*/ |
|
966 |
function shs_add_term_access($vid, $parent = NULL, $field = NULL, $account = NULL) { |
|
967 |
global $user; |
|
968 |
if (!$account) { |
|
969 |
$account = $user; |
|
970 |
} |
|
971 |
$access = module_invoke_all('shs_add_term_access', $vid, $parent, $field, $account); |
|
972 |
return !in_array(FALSE, $access, TRUE) && (user_access('edit terms in ' . $vid, $account) || in_array(TRUE, $access)); |
|
973 |
} |
|
974 |
|
|
642 | 975 |
/** |
643 | 976 |
* Adds a term with ajax. |
644 | 977 |
* |
645 |
* @param <int> $vid
|
|
978 |
* @param int $vid
|
|
646 | 979 |
* ID of vocabulary to create the term in. |
647 |
* @param <int> $parent
|
|
980 |
* @param int $parent
|
|
648 | 981 |
* ID of parent term (0 for top level). |
649 |
* @param <string> $term_name
|
|
982 |
* @param string $term_name
|
|
650 | 983 |
* Name of new term. |
984 |
* @param string $field |
|
985 |
* Name of field requesting the term list (DOM element name). |
|
651 | 986 |
* |
652 |
* @return <mixed>
|
|
987 |
* @return mixed
|
|
653 | 988 |
* Array with tid and name or FALSE on error. |
654 | 989 |
*/ |
655 |
function shs_json_term_add($vid, $parent, $term_name) { |
|
656 |
if (!user_access('edit terms in ' . $vid)) { |
|
990 |
function shs_json_term_add($vid, $parent, $term_name, $field = NULL) { |
|
991 |
global $language_content; |
|
992 |
if (!shs_add_term_access($vid, $parent, $field)) { |
|
657 | 993 |
// Sorry, but this user may not add a term to this vocabulary. |
658 | 994 |
return FALSE; |
659 | 995 |
} |
660 | 996 |
|
661 | 997 |
$term = (object) array( |
662 |
'vid' => $vid, |
|
663 |
'parent' => $parent, |
|
664 |
'name' => check_plain(filter_xss($term_name)), |
|
998 |
'vid' => $vid, |
|
999 |
'parent' => $parent, |
|
1000 |
'name' => str_replace('&', '&', filter_xss($term_name)), |
|
1001 |
'language' => $language_content->language, |
|
665 | 1002 |
); |
666 | 1003 |
// Save term. |
667 | 1004 |
$status = taxonomy_term_save($term); |
... | ... | |
674 | 1011 |
* Implements hook_hook_taxonomy_term_insert(). |
675 | 1012 |
*/ |
676 | 1013 |
function shs_taxonomy_term_insert($term) { |
677 |
// Update vocabulary cache for the terms parents. |
|
678 |
foreach ($term->parent as $parent) { |
|
679 |
shs_term_get_children($term->vid, $parent, array('node_count' => TRUE), TRUE); |
|
1014 |
if (empty($term->parent)) { |
|
1015 |
return; |
|
680 | 1016 |
} |
1017 |
// Clear shs cache for current vocabulary. |
|
1018 |
cache_clear_all("shs:{$term->vid}", 'cache'); |
|
681 | 1019 |
} |
682 | 1020 |
|
683 | 1021 |
/** |
684 | 1022 |
* Implements hook_hook_taxonomy_term_update(). |
685 | 1023 |
*/ |
686 | 1024 |
function shs_taxonomy_term_update($term) { |
687 |
// Update vocabulary cache for the terms parents. |
|
688 |
foreach ($term->parent as $parent) { |
|
689 |
shs_term_get_children($term->vid, $parent, array('node_count' => TRUE), TRUE); |
|
1025 |
if (empty($term->parent)) { |
|
1026 |
return; |
|
690 | 1027 |
} |
1028 |
// Clear shs cache for current vocabulary. |
|
1029 |
cache_clear_all("shs:{$term->vid}", 'cache'); |
|
691 | 1030 |
} |
692 | 1031 |
|
693 | 1032 |
/** |
... | ... | |
701 | 1040 |
* Implements hook_hook_taxonomy_term_delete(). |
702 | 1041 |
*/ |
703 | 1042 |
function shs_form_taxonomy_overview_terms_submit(&$form, &$form_state) { |
704 |
// Update vocabulary cache for the terms parents. |
|
705 |
shs_term_get_children($form_state['complete form']['#vocabulary']->vid, 0, array('node_count' => TRUE), TRUE); |
|
1043 |
if (empty($form_state['complete form']['#vocabulary']->vid)) { |
|
1044 |
return; |
|
1045 |
} |
|
1046 |
// Clear shs cache for current vocabulary. |
|
1047 |
cache_clear_all("shs:{$form_state['complete form']['#vocabulary']->vid}", 'cache'); |
|
706 | 1048 |
} |
707 | 1049 |
|
708 | 1050 |
/** |
... | ... | |
716 | 1058 |
} |
717 | 1059 |
|
718 | 1060 |
/** |
719 |
* Implements hook_hook_taxonomy_term_delete().
|
|
1061 |
* Submit callback for term form.
|
|
720 | 1062 |
*/ |
721 | 1063 |
function shs_form_taxonomy_form_term_submit(&$form, &$form_state) { |
722 |
// Update vocabulary cache for the terms parents. |
|
723 |
$parents = db_select('taxonomy_term_hierarchy', 'tth') |
|
724 |
->fields('tth', array('parent')) |
|
725 |
->condition('tid', $form_state['term']->tid) |
|
726 |
->execute() |
|
727 |
->fetchAll(); |
|
728 |
if ($parents) { |
|
729 |
// Update vocabulary cache for the terms parents. |
|
730 |
foreach ($parents as $parent) { |
|
731 |
shs_term_get_children($form_state['term']->vid, $parent->parent, array('node_count' => TRUE), TRUE); |
|
732 |
} |
|
733 |
} |
|
1064 |
// Clear shs cache for current vocabulary. |
|
1065 |
cache_clear_all("shs:{$form_state['term']->vid}", 'cache'); |
|
734 | 1066 |
} |
735 | 1067 |
|
736 | 1068 |
/** |
... | ... | |
767 | 1099 |
return $instances; |
768 | 1100 |
} |
769 | 1101 |
|
770 |
/** |
|
771 |
* Helper function to count number of nodes associated to a term. |
|
772 |
* |
|
773 |
* @param <object> $term |
|
774 |
* The term object. |
|
775 |
* @param <boolean> $count_children |
|
776 |
* If set to TRUE, nodes in child terms are counted also. |
|
777 |
* |
|
778 |
* @return <int> |
|
779 |
* Number of nodes within the term. |
|
780 |
*/ |
|
781 |
function _shs_term_get_node_count($term, $count_children = FALSE) { |
|
782 |
$num_nodes = &drupal_static(__FUNCTION__, array()); |
|
783 |
|
|
784 |
// Maybe this needs some more caching and value-updates on node_save()/ |
|
785 |
// _update()/delete(). |
|
786 |
if (empty($num_nodes["{$term->tid}:{$count_children}"])) { |
|
787 |
// Count nodes associated to this term. |
|
788 |
$num_nodes["{$term->tid}:{$count_children}"] = db_select('taxonomy_index', 'ti') |
|
789 |
->fields('ti') |
|
790 |
->condition('tid', $term->tid) |
|
791 |
->execute() |
|
792 |
->rowCount(); |
|
793 |
|
|
794 |
if ($count_children) { |
|
795 |
$tids = array(); |
|
796 |
$tree = taxonomy_get_tree($term->vid, $term->tid); |
|
797 |
foreach ($tree as $child_term) { |
|
798 |
$tids[] = $child_term->tid; |
|
799 |
} |
|
800 |
if (count($tids)) { |
|
801 |
$num_nodes["{$term->tid}:{$count_children}"] += db_select('taxonomy_index', 'ti') |
|
802 |
->fields('ti') |
|
803 |
->condition('tid', $tids, 'IN') |
|
804 |
->execute() |
|
805 |
->rowCount(); |
|
806 |
} |
|
807 |
} |
|
808 |
} |
|
809 |
|
|
810 |
return isset($num_nodes["{$term->tid}:{$count_children}"]) ? $num_nodes["{$term->tid}:{$count_children}"] : 0; |
|
811 |
} |
|
812 |
|
|
813 | 1102 |
/** |
814 | 1103 |
* Helper function to create a pseudo hash needed for javascript settings. |
815 | 1104 |
* |
... | ... | |
830 | 1119 |
} |
831 | 1120 |
return $hash; |
832 | 1121 |
} |
1122 |
|
|
1123 |
/** |
|
1124 |
* Helper function to validate the vocabulary identifier coming from JSON. |
|
1125 |
* |
|
1126 |
* @param mixed $identifier |
|
1127 |
* Either a vocabulary ID or an array with the following keys: |
|
1128 |
* - field_name: Name of field which sends the request. |
|
1129 |
* |
|
1130 |
* @return boolean |
|
1131 |
* TRUE if validation passes, otherwise FALSE. |
|
1132 |
*/ |
|
1133 |
function shs_json_validation_vocabulary_identifier($identifier) { |
|
1134 |
return TRUE; |
|
1135 |
} |
|
1136 |
|
|
1137 |
/** |
|
1138 |
* Helper function to get the vocabularies used as filter in entityreference |
|
1139 |
* views. |
|
1140 |
* |
|
1141 |
* @param string $view_name |
|
1142 |
* Name of view. |
|
1143 |
* @param string $display_id |
|
1144 |
* Name of display. |
|
1145 |
* |
|
1146 |
* return string[] |
|
1147 |
* List of vocabulary identifiers. |
|
1148 |
*/ |
|
1149 |
function _shs_entityreference_views_get_vocabularies($view_name, $display_id) { |
|
1150 |
$view = views_get_view($view_name); |
|
1151 |
if (empty($view)) { |
|
1152 |
// Failed to load view. |
|
1153 |
return array(); |
|
1154 |
} |
|
1155 |
$filters = $view->get_items('filter', $display_id); |
|
1156 |
$vocabularies = array(); |
|
1157 |
foreach ($filters as $key => $filter) { |
|
1158 |
if (('taxonomy_vocabulary' !== $filter['table']) || ('machine_name' !== $key)) { |
|
1159 |
continue; |
|
1160 |
} |
|
1161 |
$vocabularies = array_keys($filter['value']) + $vocabularies; |
|
1162 |
} |
|
1163 |
|
|
1164 |
return $vocabularies; |
|
1165 |
} |
Formats disponibles : Unified diff
Weekly update of contrib modules