<?php
use Drupal\node\Plugin\Core\Entity\Node;
use Drupal\taxonomy\Plugin\Core\Entity\Term;
use Drupal\taxonomy\Plugin\Core\Entity\Vocabulary;
use Drupal\Core\Entity\EntityInterface;
const TAXONOMY_HIERARCHY_DISABLED = 0;
const TAXONOMY_HIERARCHY_SINGLE = 1;
const TAXONOMY_HIERARCHY_MULTIPLE = 2;
function taxonomy_help($path, $arg) {
switch ($path) {
case 'admin/help#taxonomy':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Taxonomy module allows you to classify the content of your website. To classify content, you define <em>vocabularies</em> that contain related <em>terms</em>, and then assign the vocabularies to content types. For more information, see the online handbook entry for the <a href="@taxonomy">Taxonomy module</a>.', array(
'@taxonomy' => 'http://drupal.org/documentation/modules/taxonomy',
)) . '</p>';
$output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<dl>';
$output .= '<dt>' . t('Creating vocabularies') . '</dt>';
$output .= '<dd>' . t('Users with sufficient <a href="@perm">permissions</a> can create <em>vocabularies</em> and <em>terms</em> through the <a href="@taxo">Taxonomy page</a>. The page listing the terms provides a drag-and-drop interface for controlling the order of the terms and sub-terms within a vocabulary, in a hierarchical fashion. A <em>controlled vocabulary</em> classifying music by genre with terms and sub-terms could look as follows:', array(
'@taxo' => url('admin/structure/taxonomy'),
'@perm' => url('admin/people/permissions', array(
'fragment' => 'module-taxonomy',
)),
));
$output .= '<ul><li>' . t('<em>vocabulary</em>: Music') . '</li>';
$output .= '<ul><li>' . t('<em>term</em>: Jazz') . '</li>';
$output .= '<ul><li>' . t('<em>sub-term</em>: Swing') . '</li>';
$output .= '<li>' . t('<em>sub-term</em>: Fusion') . '</li></ul></ul>';
$output .= '<ul><li>' . t('<em>term</em>: Rock') . '</li>';
$output .= '<ul><li>' . t('<em>sub-term</em>: Country rock') . '</li>';
$output .= '<li>' . t('<em>sub-term</em>: Hard rock') . '</li></ul></ul></ul>';
$output .= t('You can assign a sub-term to multiple parent terms. For example, <em>fusion</em> can be assigned to both <em>rock</em> and <em>jazz</em>.') . '</dd>';
$output .= '<dd>' . t('Terms in a <em>free-tagging vocabulary</em> can be built gradually as you create or edit content. This is often done used for blogs or photo management applications.') . '</dd>';
$output .= '<dt>' . t('Assigning vocabularies to content types') . '</dt>';
$output .= '<dd>' . t('Before you can use a new vocabulary to classify your content, a new Taxonomy term field must be added to a <a href="@ctedit">content type</a> on its <em>manage fields</em> page. When adding a taxonomy field, you choose a <em>widget</em> to use to enter the taxonomy information on the content editing page: a select list, checkboxes, radio buttons, or an auto-complete field (to build a free-tagging vocabulary). After choosing the field type and widget, on the subsequent <em>field settings</em> page you can choose the desired vocabulary, whether one or multiple terms can be chosen from the vocabulary, and other settings. The same vocabulary can be added to multiple content types, by using the "Re-use existing field" section on the manage fields page.', array(
'@ctedit' => url('admin/structure/types'),
)) . '</dd>';
$output .= '<dt>' . t('Classifying content') . '</dt>';
$output .= '<dd>' . t('After the vocabulary is assigned to the content type, you can start classifying content. The field with terms will appear on the content editing screen when you edit or <a href="@addnode">add new content</a>.', array(
'@addnode' => url('node/add'),
)) . '</dd>';
$output .= '<dt>' . t('Viewing listings and RSS feeds by term') . '</dt>';
$output .= '<dd>' . t("Each taxonomy term automatically provides a page listing content that has its classification, and a corresponding RSS feed. For example, if the taxonomy term <em>country rock</em> has the ID 123 (you can see this by looking at the URL when hovering on the linked term, which you can click to navigate to the listing page), then you will find this list at the path <em>taxonomy/term/123</em>. The RSS feed will use the path <em>taxonomy/term/123/feed</em> (the RSS icon for this term's listing will automatically display in your browser's address bar when viewing the listing page).") . '</dd>';
$output .= '<dt>' . t('Extending Taxonomy module') . '</dt>';
$output .= '<dd>' . t('There are <a href="@taxcontrib">many contributed modules</a> that extend the behavior of the Taxonomy module for both display and organization of terms.', array(
'@taxcontrib' => 'http://drupal.org/project/modules?filters=tid:71&solrsort=sis_project_release_usage%20desc',
));
$output .= '</dl>';
return $output;
case 'admin/structure/taxonomy':
$output = '<p>' . t('Taxonomy is for categorizing content. Terms are grouped into vocabularies. For example, a vocabulary called "Fruit" would contain the terms "Apple" and "Banana".') . '</p>';
return $output;
case 'admin/structure/taxonomy/%':
$vocabulary = taxonomy_vocabulary_machine_name_load($arg[3]);
switch ($vocabulary->hierarchy) {
case TAXONOMY_HIERARCHY_DISABLED:
return '<p>' . t('You can reorganize the terms in %capital_name using their drag-and-drop handles, and group terms under a parent term by sliding them under and to the right of the parent.', array(
'%capital_name' => drupal_ucfirst($vocabulary->name),
'%name' => $vocabulary->name,
)) . '</p>';
case TAXONOMY_HIERARCHY_SINGLE:
return '<p>' . t('%capital_name contains terms grouped under parent terms. You can reorganize the terms in %capital_name using their drag-and-drop handles.', array(
'%capital_name' => drupal_ucfirst($vocabulary->name),
'%name' => $vocabulary->name,
)) . '</p>';
case TAXONOMY_HIERARCHY_MULTIPLE:
return '<p>' . t('%capital_name contains terms with multiple parents. Drag and drop of terms with multiple parents is not supported, but you can re-enable drag-and-drop support by editing each term to include only a single parent.', array(
'%capital_name' => drupal_ucfirst($vocabulary->name),
)) . '</p>';
}
}
}
function taxonomy_permission() {
$permissions = array(
'administer taxonomy' => array(
'title' => t('Administer vocabularies and terms'),
),
);
foreach (taxonomy_vocabulary_load_multiple() as $vocabulary) {
$permissions += array(
'edit terms in ' . $vocabulary->vid => array(
'title' => t('Edit terms in %vocabulary', array(
'%vocabulary' => $vocabulary->name,
)),
),
);
$permissions += array(
'delete terms in ' . $vocabulary->vid => array(
'title' => t('Delete terms from %vocabulary', array(
'%vocabulary' => $vocabulary->name,
)),
),
);
}
return $permissions;
}
function taxonomy_entity_info(&$info) {
foreach (taxonomy_vocabulary_get_names() as $machine_name => $vocabulary) {
$info['taxonomy_term']['bundles'][$machine_name] = array(
'label' => $vocabulary->name,
'admin' => array(
'path' => 'admin/structure/taxonomy/%taxonomy_vocabulary_machine_name',
'real path' => 'admin/structure/taxonomy/' . $machine_name,
'bundle argument' => 3,
'access arguments' => array(
'administer taxonomy',
),
),
);
}
}
function taxonomy_term_uri($term) {
return array(
'path' => 'taxonomy/term/' . $term->tid,
);
}
function taxonomy_field_extra_fields() {
$return = array();
$info = entity_get_info('taxonomy_term');
foreach (array_keys($info['bundles']) as $bundle) {
$return['taxonomy_term'][$bundle] = array(
'form' => array(
'name' => array(
'label' => t('Name'),
'description' => t('Term name textfield'),
'weight' => -5,
),
'description' => array(
'label' => t('Description'),
'description' => t('Term description textarea'),
'weight' => 0,
),
),
'display' => array(
'description' => array(
'label' => t('Description'),
'description' => t('Term description'),
'weight' => 0,
),
),
);
}
return $return;
}
function taxonomy_select_nodes($tid, $pager = TRUE, $limit = FALSE, $order = array(
't.sticky' => 'DESC',
't.created' => 'DESC',
)) {
if (!variable_get('taxonomy_maintain_index_table', TRUE)) {
return array();
}
$query = db_select('taxonomy_index', 't');
$query
->addTag('node_access');
$query
->addMetaData('base_table', 'taxonomy_index');
$query
->condition('tid', $tid);
if ($pager) {
$count_query = clone $query;
$count_query
->addExpression('COUNT(t.nid)');
$query = $query
->extend('Drupal\\Core\\Database\\Query\\PagerSelectExtender');
if ($limit !== FALSE) {
$query = $query
->limit($limit);
}
$query
->setCountQuery($count_query);
}
else {
if ($limit !== FALSE) {
$query
->range(0, $limit);
}
}
$query
->addField('t', 'nid');
$query
->addField('t', 'tid');
foreach ($order as $field => $direction) {
$query
->orderBy($field, $direction);
list($table_alias, $name) = explode('.', $field);
$query
->addField($table_alias, $name);
}
return $query
->execute()
->fetchCol();
}
function taxonomy_theme() {
return array(
'taxonomy_overview_vocabularies' => array(
'render element' => 'form',
),
'taxonomy_overview_terms' => array(
'render element' => 'form',
),
'taxonomy_term' => array(
'render element' => 'elements',
'template' => 'taxonomy-term',
),
);
}
function taxonomy_menu() {
$items['admin/structure/taxonomy'] = array(
'title' => 'Taxonomy',
'description' => 'Manage tagging, categorization, and classification of your content.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'taxonomy_overview_vocabularies',
),
'access arguments' => array(
'administer taxonomy',
),
'file' => 'taxonomy.admin.inc',
);
$items['admin/structure/taxonomy/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/structure/taxonomy/add'] = array(
'title' => 'Add vocabulary',
'page callback' => 'taxonomy_vocabulary_add',
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_LOCAL_ACTION,
'file' => 'taxonomy.admin.inc',
);
$items['taxonomy/term/%taxonomy_term'] = array(
'title' => 'Taxonomy term',
'title callback' => 'taxonomy_term_title',
'title arguments' => array(
2,
),
'page callback' => 'taxonomy_term_page',
'page arguments' => array(
2,
),
'access arguments' => array(
'access content',
),
'file' => 'taxonomy.pages.inc',
);
$items['taxonomy/term/%taxonomy_term/view'] = array(
'title' => 'View',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['taxonomy/term/%taxonomy_term/edit'] = array(
'title' => 'Edit',
'page callback' => 'entity_get_form',
'page arguments' => array(
2,
),
'access callback' => 'taxonomy_term_access',
'access arguments' => array(
'edit',
2,
),
'type' => MENU_LOCAL_TASK,
'weight' => 10,
'file' => 'taxonomy.admin.inc',
);
$items['taxonomy/term/%taxonomy_term/delete'] = array(
'title' => 'Delete',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'taxonomy_term_confirm_delete',
2,
),
'access callback' => 'taxonomy_term_access',
'access arguments' => array(
'delete',
2,
),
'type' => MENU_LOCAL_TASK,
'weight' => 11,
'file' => 'taxonomy.admin.inc',
);
$items['taxonomy/term/%taxonomy_term/feed'] = array(
'title' => 'Taxonomy term',
'title callback' => 'taxonomy_term_title',
'title arguments' => array(
2,
),
'page callback' => 'taxonomy_term_feed',
'page arguments' => array(
2,
),
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
'file' => 'taxonomy.pages.inc',
);
$items['taxonomy/autocomplete/%'] = array(
'title' => 'Autocomplete taxonomy',
'page callback' => 'taxonomy_autocomplete',
'page arguments' => array(
2,
),
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
'file' => 'taxonomy.pages.inc',
);
$items['admin/structure/taxonomy/%taxonomy_vocabulary_machine_name'] = array(
'title callback' => 'entity_page_label',
'title arguments' => array(
3,
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'taxonomy_overview_terms',
3,
),
'access arguments' => array(
'administer taxonomy',
),
'file' => 'taxonomy.admin.inc',
);
$items['admin/structure/taxonomy/%taxonomy_vocabulary_machine_name/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -20,
);
$items['admin/structure/taxonomy/%taxonomy_vocabulary_machine_name/edit'] = array(
'title' => 'Edit',
'page callback' => 'entity_get_form',
'page arguments' => array(
3,
),
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_LOCAL_TASK,
'weight' => -10,
'file' => 'taxonomy.admin.inc',
);
$items['admin/structure/taxonomy/%taxonomy_vocabulary_machine_name/add'] = array(
'title' => 'Add term',
'page callback' => 'taxonomy_term_add',
'page arguments' => array(
3,
),
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_LOCAL_ACTION,
'file' => 'taxonomy.admin.inc',
);
return $items;
}
function taxonomy_admin_paths() {
$paths = array(
'taxonomy/term/*/edit' => TRUE,
'taxonomy/term/*/delete' => TRUE,
'taxonomy/term/*/translations' => TRUE,
'taxonomy/term/*/translations/*' => TRUE,
);
return $paths;
}
function taxonomy_term_access($op, $term) {
if (!$term || !in_array($op, array(
'edit',
'delete',
), TRUE)) {
return FALSE;
}
return user_access("{$op} terms in {$term->vid}") || user_access('administer taxonomy');
}
function taxonomy_vocabulary_save(Vocabulary $vocabulary) {
return $vocabulary
->save();
}
function taxonomy_vocabulary_delete($vid) {
taxonomy_vocabulary_delete_multiple(array(
$vid,
));
}
function taxonomy_vocabulary_delete_multiple(array $vids) {
entity_delete_multiple('taxonomy_vocabulary', $vids);
}
function taxonomy_taxonomy_vocabulary_update(Vocabulary $vocabulary) {
if (!empty($vocabulary->original->machine_name) && $vocabulary->original->machine_name != $vocabulary->machine_name) {
$fields = field_read_fields();
foreach ($fields as $field_name => $field) {
$update = FALSE;
if ($field['type'] == 'taxonomy_term_reference') {
foreach ($field['settings']['allowed_values'] as $key => &$value) {
if ($value['vocabulary'] == $vocabulary->original->machine_name) {
$value['vocabulary'] = $vocabulary->machine_name;
$update = TRUE;
}
}
if ($update) {
field_update_field($field);
}
}
}
}
}
function taxonomy_check_vocabulary_hierarchy(Vocabulary $vocabulary, $changed_term) {
$tree = taxonomy_get_tree($vocabulary->vid);
$hierarchy = TAXONOMY_HIERARCHY_DISABLED;
foreach ($tree as $term) {
if ($term->tid == $changed_term['tid']) {
$term = (object) $changed_term;
$term->parents = $term->parent;
}
if (count($term->parents) > 1) {
$hierarchy = TAXONOMY_HIERARCHY_MULTIPLE;
break;
}
elseif (count($term->parents) == 1 && !isset($term->parents[0])) {
$hierarchy = TAXONOMY_HIERARCHY_SINGLE;
}
}
if ($hierarchy != $vocabulary->hierarchy) {
$vocabulary->hierarchy = $hierarchy;
taxonomy_vocabulary_save($vocabulary);
}
return $hierarchy;
}
function taxonomy_term_save(Term $term) {
return $term
->save();
}
function taxonomy_term_delete($tid) {
taxonomy_term_delete_multiple(array(
$tid,
));
}
function taxonomy_term_delete_multiple(array $tids) {
entity_delete_multiple('taxonomy_term', $tids);
}
function taxonomy_term_view(Term $term, $view_mode = 'full', $langcode = NULL) {
return entity_view($term, $view_mode, $langcode);
}
function taxonomy_term_view_multiple(array $terms, $view_mode = 'full', $langcode = NULL) {
return entity_view_multiple($terms, $view_mode, $langcode);
}
function template_preprocess_taxonomy_term(&$variables) {
$variables['view_mode'] = $variables['elements']['#view_mode'];
$variables['term'] = $variables['elements']['#term'];
$term = $variables['term'];
$uri = $term
->uri();
$variables['url'] = url($uri['path'], $uri['options']);
$variables['label'] = check_plain($term
->label());
$variables['page'] = $variables['view_mode'] == 'full' && taxonomy_term_is_page($term);
$variables['content'] = array();
foreach (element_children($variables['elements']) as $key) {
$variables['content'][$key] = $variables['elements'][$key];
}
field_attach_preprocess('taxonomy_term', $term, $variables['content'], $variables);
$vocabulary_name_css = str_replace('_', '-', $term->vocabulary_machine_name);
$variables['attributes']['class'][] = 'vocabulary-' . $vocabulary_name_css;
$variables['theme_hook_suggestions'][] = 'taxonomy_term__' . $term->vocabulary_machine_name;
$variables['theme_hook_suggestions'][] = 'taxonomy_term__' . $term->tid;
}
function taxonomy_term_is_page(Term $term) {
$page_term = menu_get_object('taxonomy_term', 2);
return !empty($page_term) ? $page_term->tid == $term->tid : FALSE;
}
function taxonomy_terms_static_reset() {
entity_get_controller('taxonomy_term')
->resetCache();
}
function taxonomy_vocabulary_static_reset(array $ids = NULL) {
entity_get_controller('taxonomy_vocabulary')
->resetCache($ids);
}
function taxonomy_vocabulary_get_names() {
$names =& drupal_static(__FUNCTION__);
if (!isset($names)) {
$names = db_query('SELECT name, machine_name, vid FROM {taxonomy_vocabulary}')
->fetchAllAssoc('machine_name');
}
return $names;
}
function taxonomy_term_load_parents($tid) {
$parents =& drupal_static(__FUNCTION__, array());
if ($tid && !isset($parents[$tid])) {
$query = db_select('taxonomy_term_data', 't');
$query
->join('taxonomy_term_hierarchy', 'h', 'h.parent = t.tid');
$query
->addField('t', 'tid');
$query
->condition('h.tid', $tid);
$query
->addTag('term_access');
$query
->orderBy('t.weight');
$query
->orderBy('t.name');
$tids = $query
->execute()
->fetchCol();
$parents[$tid] = taxonomy_term_load_multiple($tids);
}
return isset($parents[$tid]) ? $parents[$tid] : array();
}
function taxonomy_term_load_parents_all($tid) {
$cache =& drupal_static(__FUNCTION__, array());
if (isset($cache[$tid])) {
return $cache[$tid];
}
$parents = array();
if ($term = taxonomy_term_load($tid)) {
$parents[] = $term;
$n = 0;
while ($parent = taxonomy_term_load_parents($parents[$n]->tid)) {
$parents = array_merge($parents, $parent);
$n++;
}
}
$cache[$tid] = $parents;
return $parents;
}
function taxonomy_term_load_children($tid, $vid = 0) {
$children =& drupal_static(__FUNCTION__, array());
if ($tid && !isset($children[$tid])) {
$query = db_select('taxonomy_term_data', 't');
$query
->join('taxonomy_term_hierarchy', 'h', 'h.tid = t.tid');
$query
->addField('t', 'tid');
$query
->condition('h.parent', $tid);
if ($vid) {
$query
->condition('t.vid', $vid);
}
$query
->addTag('term_access');
$query
->orderBy('t.weight');
$query
->orderBy('t.name');
$tids = $query
->execute()
->fetchCol();
$children[$tid] = taxonomy_term_load_multiple($tids);
}
return isset($children[$tid]) ? $children[$tid] : array();
}
function taxonomy_get_tree($vid, $parent = 0, $max_depth = NULL, $load_entities = FALSE) {
$children =& drupal_static(__FUNCTION__, array());
$parents =& drupal_static(__FUNCTION__ . ':parents', array());
$terms =& drupal_static(__FUNCTION__ . ':terms', array());
if (!isset($children[$vid])) {
$children[$vid] = array();
$parents[$vid] = array();
$terms[$vid] = array();
$query = db_select('taxonomy_term_data', 't');
$query
->join('taxonomy_term_hierarchy', 'h', 'h.tid = t.tid');
$result = $query
->addTag('translatable')
->addTag('term_access')
->fields('t')
->fields('h', array(
'parent',
))
->condition('t.vid', $vid)
->orderBy('t.weight')
->orderBy('t.name')
->execute();
foreach ($result as $term) {
$children[$vid][$term->parent][] = $term->tid;
$parents[$vid][$term->tid][] = $term->parent;
$terms[$vid][$term->tid] = $term;
}
}
if ($load_entities) {
$term_entities = taxonomy_term_load_multiple(array_keys($terms[$vid]));
}
$max_depth = !isset($max_depth) ? count($children[$vid]) : $max_depth;
$tree = array();
$process_parents = array();
$process_parents[] = $parent;
while (count($process_parents)) {
$parent = array_pop($process_parents);
$depth = count($process_parents);
if ($max_depth > $depth && !empty($children[$vid][$parent])) {
$has_children = FALSE;
$child = current($children[$vid][$parent]);
do {
if (empty($child)) {
break;
}
$term = $load_entities ? $term_entities[$child] : $terms[$vid][$child];
if (isset($parents[$vid][$term->tid])) {
$term = clone $term;
}
$term->depth = $depth;
unset($term->parent);
$term->parents = $parents[$vid][$term->tid];
$tree[] = $term;
if (!empty($children[$vid][$term->tid])) {
$has_children = TRUE;
$process_parents[] = $parent;
$process_parents[] = $term->tid;
reset($children[$vid][$term->tid]);
next($children[$vid][$parent]);
break;
}
} while ($child = next($children[$vid][$parent]));
if (!$has_children) {
reset($children[$vid][$parent]);
}
}
}
return $tree;
}
function taxonomy_term_load_multiple_by_name($name, $vocabulary = NULL) {
$values = array(
'name' => trim($name),
);
if (isset($vocabulary)) {
$vocabularies = taxonomy_vocabulary_get_names();
if (isset($vocabularies[$vocabulary])) {
$values['vid'] = $vocabularies[$vocabulary]->vid;
}
else {
return array();
}
}
return entity_load_multiple_by_properties('taxonomy_term', $values);
}
function taxonomy_term_load_multiple(array $tids = NULL) {
return entity_load_multiple('taxonomy_term', $tids);
}
function taxonomy_vocabulary_load_multiple(array $vids = NULL) {
return entity_load_multiple('taxonomy_vocabulary', $vids);
}
function taxonomy_vocabulary_load($vid) {
return entity_load('taxonomy_vocabulary', $vid);
}
function taxonomy_vocabulary_machine_name_load($name) {
$result = entity_load_multiple_by_properties('taxonomy_vocabulary', array(
'machine_name' => $name,
));
return reset($result);
}
function taxonomy_term_load($tid) {
if (!is_numeric($tid)) {
return FALSE;
}
return entity_load('taxonomy_term', $tid);
}
function _taxonomy_get_tid_from_term(Term $term) {
return $term->tid;
}
function taxonomy_implode_tags($tags, $vid = NULL) {
$typed_tags = array();
foreach ($tags as $tag) {
if (!isset($vid) || $tag->vid == $vid) {
if ($tag instanceof EntityInterface && ($label = $tag
->label())) {
if (strpos($label, ',') !== FALSE || strpos($label, '"') !== FALSE) {
$typed_tags[] = '"' . str_replace('"', '""', $label) . '"';
}
else {
$typed_tags[] = $label;
}
}
}
}
return implode(', ', $typed_tags);
}
function taxonomy_field_info() {
return array(
'taxonomy_term_reference' => array(
'label' => t('Term reference'),
'description' => t('This field stores a reference to a taxonomy term.'),
'default_widget' => 'options_select',
'default_formatter' => 'taxonomy_term_reference_link',
'field item class' => 'Drupal\\taxonomy\\Type\\TaxonomyTermReferenceItem',
'settings' => array(
'allowed_values' => array(
array(
'vocabulary' => '',
'parent' => '0',
),
),
),
),
);
}
function taxonomy_field_widget_info_alter(&$info) {
$info['options_select']['field_types'][] = 'taxonomy_term_reference';
$info['options_buttons']['field_types'][] = 'taxonomy_term_reference';
}
function taxonomy_options_list($field, $instance, $entity_type, $entity) {
$function = !empty($field['settings']['options_list_callback']) ? $field['settings']['options_list_callback'] : 'taxonomy_allowed_values';
return $function($field, $instance, $entity_type, $entity);
}
function taxonomy_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
foreach ($items as $delta => $item) {
if (!empty($item['tid']) && $item['tid'] != 'autocreate') {
$tids[] = $item['tid'];
}
}
if (!empty($tids)) {
$terms = taxonomy_term_load_multiple($tids);
foreach ($items as $delta => $item) {
$validate = TRUE;
if (!empty($item['tid']) && $item['tid'] != 'autocreate') {
$validate = FALSE;
foreach ($field['settings']['allowed_values'] as $settings) {
if (isset($settings['vocabulary']) && empty($settings['parent'])) {
if ($settings['vocabulary'] == $terms[$item['tid']]->vocabulary_machine_name) {
$validate = TRUE;
break;
}
}
elseif (!empty($settings['parent'])) {
$ancestors = taxonomy_term_load_parents_all($item['tid']);
foreach ($ancestors as $ancestor) {
if ($ancestor->tid == $settings['parent']) {
$validate = TRUE;
break 2;
}
}
}
}
}
if (!$validate) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'taxonomy_term_reference_illegal_value',
'message' => t('%name: illegal value.', array(
'%name' => $instance['label'],
)),
);
}
}
}
}
function taxonomy_field_is_empty($item, $field) {
if (!is_array($item) || empty($item['tid']) && (string) $item['tid'] !== '0') {
return TRUE;
}
return FALSE;
}
function taxonomy_field_formatter_info() {
return array(
'taxonomy_term_reference_link' => array(
'label' => t('Link'),
'field types' => array(
'taxonomy_term_reference',
),
),
'taxonomy_term_reference_plain' => array(
'label' => t('Plain text'),
'field types' => array(
'taxonomy_term_reference',
),
),
'taxonomy_term_reference_rss_category' => array(
'label' => t('RSS category'),
'field types' => array(
'taxonomy_term_reference',
),
),
);
}
function taxonomy_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
switch ($display['type']) {
case 'taxonomy_term_reference_link':
foreach ($items as $delta => $item) {
if ($item['tid'] == 'autocreate') {
$element[$delta] = array(
'#markup' => check_plain($item['name']),
);
}
else {
$term = $item['taxonomy_term'];
$uri = $term
->uri();
$element[$delta] = array(
'#type' => 'link',
'#title' => $term
->label(),
'#href' => $uri['path'],
'#options' => $uri['options'],
);
}
}
break;
case 'taxonomy_term_reference_plain':
foreach ($items as $delta => $item) {
$name = $item['tid'] != 'autocreate' ? $item['taxonomy_term']
->label() : $item['name'];
$element[$delta] = array(
'#markup' => check_plain($name),
);
}
break;
case 'taxonomy_term_reference_rss_category':
foreach ($items as $delta => $item) {
$entity->rss_elements[] = array(
'key' => 'category',
'value' => $item['tid'] != 'autocreate' ? $item['taxonomy_term']
->label() : $item['name'],
'attributes' => array(
'domain' => $item['tid'] != 'autocreate' ? url('taxonomy/term/' . $item['tid'], array(
'absolute' => TRUE,
)) : '',
),
);
}
break;
}
return $element;
}
function taxonomy_allowed_values($field, $instance, $entity_type, $entity) {
$options = array();
foreach ($field['settings']['allowed_values'] as $tree) {
if ($vocabulary = taxonomy_vocabulary_machine_name_load($tree['vocabulary'])) {
if ($terms = taxonomy_get_tree($vocabulary->vid, $tree['parent'], NULL, TRUE)) {
foreach ($terms as $term) {
$options[$term->tid] = str_repeat('-', $term->depth) . $term
->label();
}
}
}
}
return $options;
}
function taxonomy_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
$tids = array();
foreach ($entities as $id => $entity) {
foreach ($items[$id] as $delta => $item) {
if ($item['tid'] != 'autocreate') {
$tids[$item['tid']] = $item['tid'];
}
}
}
if ($tids) {
$terms = taxonomy_term_load_multiple($tids);
foreach ($entities as $id => $entity) {
$rekey = FALSE;
foreach ($items[$id] as $delta => $item) {
if (isset($terms[$item['tid']])) {
$items[$id][$delta]['taxonomy_term'] = $terms[$item['tid']];
}
elseif ($item['tid'] == 'autocreate') {
}
else {
unset($items[$id][$delta]);
$rekey = TRUE;
}
}
if ($rekey) {
$items[$id] = array_values($items[$id]);
}
}
}
}
function taxonomy_term_title(Term $term) {
return $term
->label();
}
function taxonomy_autocomplete_validate($element, &$form_state) {
$typed_terms = array();
if ($tags = $element['#value']) {
$typed_terms = drupal_explode_tags($tags);
}
form_set_value($element, $typed_terms, $form_state);
}
function taxonomy_field_settings_form($field, $instance, $has_data) {
$vocabularies = taxonomy_vocabulary_load_multiple();
$options = array();
foreach ($vocabularies as $vocabulary) {
$options[$vocabulary->machine_name] = $vocabulary->name;
}
$form['allowed_values'] = array(
'#tree' => TRUE,
);
foreach ($field['settings']['allowed_values'] as $delta => $tree) {
$form['allowed_values'][$delta]['vocabulary'] = array(
'#type' => 'select',
'#title' => t('Vocabulary'),
'#default_value' => $tree['vocabulary'],
'#options' => $options,
'#required' => TRUE,
'#description' => t('The vocabulary which supplies the options for this field.'),
'#disabled' => $has_data,
);
$form['allowed_values'][$delta]['parent'] = array(
'#type' => 'value',
'#value' => $tree['parent'],
);
}
return $form;
}
function taxonomy_rdf_mapping() {
return array(
array(
'type' => 'taxonomy_term',
'bundle' => RDF_DEFAULT_BUNDLE,
'mapping' => array(
'rdftype' => array(
'skos:Concept',
),
'name' => array(
'predicates' => array(
'rdfs:label',
'skos:prefLabel',
),
),
'description' => array(
'predicates' => array(
'skos:definition',
),
),
'vid' => array(
'predicates' => array(
'skos:inScheme',
),
'type' => 'rel',
),
'parent' => array(
'predicates' => array(
'skos:broader',
),
'type' => 'rel',
),
),
),
array(
'type' => 'taxonomy_vocabulary',
'bundle' => RDF_DEFAULT_BUNDLE,
'mapping' => array(
'rdftype' => array(
'skos:ConceptScheme',
),
'name' => array(
'predicates' => array(
'dc:title',
),
),
'description' => array(
'predicates' => array(
'rdfs:comment',
),
),
),
),
);
}
function taxonomy_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
foreach ($items as $delta => $item) {
if ($item['tid'] == 'autocreate') {
unset($item['tid']);
$term = entity_create('taxonomy_term', $item);
$term->langcode = $langcode;
taxonomy_term_save($term);
$items[$delta]['tid'] = $term->tid;
}
}
}
function taxonomy_node_insert(Node $node) {
taxonomy_build_node_index($node);
}
function taxonomy_build_node_index($node) {
$status = NULL;
if (variable_get('taxonomy_maintain_index_table', TRUE)) {
if (!empty($node->original)) {
$status = (int) (!empty($node->status) || !isset($node->status) && !empty($node->original->status));
$sticky = (int) (!empty($node->sticky) || !isset($node->sticky) && !empty($node->original->sticky));
}
else {
$status = (int) (!empty($node->status));
$sticky = (int) (!empty($node->sticky));
}
}
if ($status && $node
->isDefaultRevision()) {
$tid_all = array();
foreach (field_info_instances('node', $node->type) as $instance) {
$field_name = $instance['field_name'];
$field = field_info_field($field_name);
if ($field['module'] == 'taxonomy' && $field['storage']['type'] == 'field_sql_storage') {
if (isset($node->{$field_name})) {
$items = $node->{$field_name};
}
elseif (isset($node->original->{$field_name})) {
$items = $node->original->{$field_name};
}
else {
continue;
}
foreach (field_available_languages('node', $field) as $langcode) {
if (!empty($items[$langcode])) {
foreach ($items[$langcode] as $item) {
$tid_all[$item['tid']] = $item['tid'];
}
}
}
}
}
if (!empty($tid_all)) {
$query = db_insert('taxonomy_index')
->fields(array(
'nid',
'tid',
'sticky',
'created',
));
foreach ($tid_all as $tid) {
$query
->values(array(
'nid' => $node->nid,
'tid' => $tid,
'sticky' => $sticky,
'created' => $node->created,
));
}
$query
->execute();
}
}
}
function taxonomy_node_update(Node $node) {
taxonomy_delete_node_index($node);
taxonomy_build_node_index($node);
}
function taxonomy_node_predelete(Node $node) {
taxonomy_delete_node_index($node);
}
function taxonomy_delete_node_index(Node $node) {
if (variable_get('taxonomy_maintain_index_table', TRUE)) {
db_delete('taxonomy_index')
->condition('nid', $node->nid)
->execute();
}
}
function taxonomy_taxonomy_term_delete(Term $term) {
if (variable_get('taxonomy_maintain_index_table', TRUE)) {
db_delete('taxonomy_index')
->condition('tid', $term->tid)
->execute();
}
}
function taxonomy_library_info() {
$libraries['drupal.taxonomy'] = array(
'title' => 'Taxonomy',
'version' => VERSION,
'js' => array(
drupal_get_path('module', 'taxonomy') . '/taxonomy.js' => array(),
),
'css' => array(
drupal_get_path('module', 'taxonomy') . '/taxonomy.css' => array(),
),
'dependencies' => array(
array(
'system',
'jquery',
),
array(
'system',
'drupal',
),
array(
'system',
'drupalSettings',
),
array(
'system',
'drupal.tabledrag',
),
),
);
return $libraries;
}