- <?php
-  * @file
-  * Enables the organization of content into categories.
-  */
- 
-  * Denotes that no term in the vocabulary has a parent.
-  */
- define('TAXONOMY_HIERARCHY_DISABLED', 0);
- 
-  * Denotes that one or more terms in the vocabulary has a single parent.
-  */
- define('TAXONOMY_HIERARCHY_SINGLE', 1);
- 
-  * Denotes that one or more terms in the vocabulary have multiple parents.
-  */
- define('TAXONOMY_HIERARCHY_MULTIPLE', 2);
- 
-  * Denotes that language is disabled on vocabulary.
-  */
- define('TAXONOMY_LANGUAGE_DISABLED', 0);
- 
-  * Denotes that language is enabled on vocabulary and terms can be assigned
-  * language.
-  */
- define('TAXONOMY_LANGUAGE_ENABLED', 1);
- 
-  * Users can create new terms in a free-tagging vocabulary when
-  * submitting a taxonomy_autocomplete_widget. We store a term object
-  * whose tid is 'autocreate' as a field data item during widget
-  * validation and then actually create the term if/when that field
-  * data item makes it to taxonomy_field_insert/update().
-  */
- 
-  * Implements hook_permission().
-  */
- function taxonomy_permission() {
-   $permissions = array(
-     'administer taxonomy' => array(
-       'title' => t('Administer vocabularies and terms'),
-     ),
-   );
-   foreach (taxonomy_vocabulary_load_multiple(FALSE) as $vocabulary) {
-     $permissions += taxonomy_vocabulary_list_permissions($vocabulary);
-   }
- 
-   return $permissions;
- }
- 
-  * Helper function to generate standard permission list for a vocabulary.
-  *
-  * @param $vocabulary
-  *   Fully loaded TaxonomyVocabulary object.
-  *
-  * @return array
-  *   An array of permission names and descriptions.
-  */
- function taxonomy_vocabulary_list_permissions($vocabulary) {
-   $permissions = array(
-     'create terms in ' . $vocabulary->machine_name => array(
-       'title' => t('%vocabulary: Create terms', array('%vocabulary' => $vocabulary->name)),
-     ),
-     'edit terms in ' . $vocabulary->machine_name => array(
-       'title' => t('%vocabulary: Edit terms', array('%vocabulary' => $vocabulary->name)),
-     ),
-     'delete terms in ' . $vocabulary->machine_name => array(
-       'title' => t('%vocabulary: Delete terms', array('%vocabulary' => $vocabulary->name)),
-     ),
-   );
- 
-   return $permissions;
- }
- 
-  * Implements hook_entity_info().
-  */
- function taxonomy_entity_info() {
-   $entity_info = array(
-     'taxonomy_term' => array(
-       'label' => t('Taxonomy term'),
-       'bundle label' => t('Vocabulary'),
-       'entity class' => 'TaxonomyTerm',
-       'controller class' => 'TaxonomyTermController',
-       'base table' => 'taxonomy_term_data',
-       'token type' => 'term',
-       'fieldable' => TRUE,
-       'redirect support' => TRUE,
-       'entity keys' => array(
-         'id' => 'tid',
-         'bundle' => 'vocabulary',
-         'label' => 'name',
-       ),
-       'bundle keys' => array(
-         'bundle' => 'machine_name',
-       ),
-       'bundles' => array(),
-       'view modes' => array(
-         
-         'full' => array(
-           'label' => t('Taxonomy term page'),
-           'custom settings' => FALSE,
-         ),
-         'token' => array(
-           'label' => t('Tokens'),
-           'custom settings' => FALSE,
-         ),
-       ),
-     ),
-   );
- 
-   
-   if (db_table_exists('cache_entity_taxonomy_term')) {
-     $entity_info['taxonomy_term']['entity cache'] = TRUE;
-     $entity_info['taxonomy_term']['field cache'] = FALSE;
-   }
- 
-   foreach (taxonomy_vocabulary_load_multiple(FALSE) as $machine_name => $vocabulary) {
-     $entity_info['taxonomy_term']['bundles'][$machine_name] = array(
-       'label' => $vocabulary->name,
-       'admin' => array(
-         'path' => 'admin/structure/taxonomy/%taxonomy_vocabulary',
-         'real path' => 'admin/structure/taxonomy/' . $machine_name,
-         'bundle argument' => 3,
-         'access arguments' => array('administer taxonomy'),
-       ),
-     );
-   }
- 
-   return $entity_info;
- }
- 
-  * Implements hook_layout_context_info().
-  */
- function taxonomy_layout_context_info() {
-   $info['taxonomy_term'] = array(
-     'title' => t('Taxonomy Term'),
-     
-     'class' => 'EntityLayoutContext',
-     
-     'menu paths' => array(
-       'taxonomy/term/%taxonomy_term',
-       'taxonomy/term/%taxonomy_term/view',
-       'taxonomy/term/%taxonomy_term/edit',
-     ),
-     
-     
-     'path placeholder' => '%taxonomy_term',
-     
-     
-     'load callback' => 'taxonomy_term_load',
-   );
-   return $info;
- }
- 
-  * Implements hook_views_api().
-  */
- function taxonomy_views_api() {
-   return array(
-     'api' => '3.0',
-     'path' => backdrop_get_path('module', 'taxonomy') . '/views',
-   );
- }
- 
-  * Implements hook_field_extra_fields().
-  */
- 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,
-         ),
-       ),
-     );
- 
-     
-     
-     $vocabulary = taxonomy_vocabulary_load($bundle);
-     if (module_exists('language') && $vocabulary->language == TAXONOMY_LANGUAGE_ENABLED) {
-       $return['taxonomy_term'][$bundle]['form'] += array(
-         'langcode' => array(
-           'label' => t('Language'),
-           'description' => t('Term language'),
-           'weight' => 0,
-         ),
-       );
-       $return['taxonomy_term'][$bundle]['display'] += array(
-         'langcode' => array(
-           'label' => t('Language'),
-           'description' => t('Term language'),
-           'weight' => 0,
-         ),
-       );
-     }
-   }
- 
-   return $return;
- }
- 
-  * Return nodes attached to a term across all field instances.
-  *
-  * This function requires taxonomy module to be maintaining its own tables,
-  * and will return an empty array if it is not. If using other field storage
-  * methods alternatives methods for listing terms will need to be used.
-  *
-  * @param $tid
-  *   The term ID.
-  * @param $pager
-  *   Boolean to indicate whether a pager should be used.
-  * @param $limit
-  *   Integer. The maximum number of nodes to find.
-  *   Set to FALSE for no limit.
-  * @param $order
-  *   An array of fields and directions.
-  *
-  * @return
-  *   An array of nids matching the query.
-  */
- function taxonomy_select_nodes($tid, $pager = TRUE, $limit = FALSE, $order = array('t.sticky' => 'DESC', 't.created' => 'DESC')) {
-   if (!config_get('taxonomy.settings', 'maintain_index_table')) {
-     return array();
-   }
-   $query = db_select('taxonomy_index', 't');
-   $query->addTag('node_access');
-   $query->condition('t.tid', $tid);
-   if ($pager) {
-     $count_query = clone $query;
-     $count_query->addExpression('COUNT(t.nid)');
- 
-     $query = $query->extend('PagerDefault');
-     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();
- }
- 
-  * Implements hook_theme().
-  */
- function taxonomy_theme() {
-   $base = array(
-     'file' => 'taxonomy.theme.inc',
-   );
- 
-   return array(
-     'taxonomy_vocabulary_name' => array(
-       'variables' => array('vocabulary' => NULL),
-     ) + $base,
-     'taxonomy_vocabulary_description' => array(
-       'variables' => array('vocabulary' => NULL),
-     ) + $base,
-     'taxonomy_overview_terms' => array(
-       'render element' => 'form',
-     ) + $base,
-     'taxonomy_term' => array(
-       'render element' => 'elements',
-       'template' => 'templates/taxonomy-term',
-     ) + $base,
-     'taxonomy_vocabulary_form_permissions' => array(
-       'render element' => 'form',
-       'function' => 'theme_user_admin_permissions',
-     ),
-   );
- }
- 
-  * Implements hook_menu().
-  */
- function taxonomy_menu() {
-   $items['admin/structure/taxonomy'] = array(
-     'title' => 'Taxonomy',
-     'description' => 'Manage tagging, categorization, and classification of your content.',
-     'page callback' => 'taxonomy_overview_vocabularies',
-     'access callback' => 'taxonomy_vocabulary_overview_access',
-     'file' => 'taxonomy.admin.inc',
-   );
-   $items['admin/structure/taxonomy/list'] = array(
-     'title' => 'List vocabularies',
-     'type' => MENU_DEFAULT_LOCAL_TASK,
-     'weight' => -10,
-   );
-   $items['admin/structure/taxonomy/add'] = array(
-     'title' => 'Add vocabulary',
-     'page callback' => 'backdrop_get_form',
-     'page arguments' => array('taxonomy_form_vocabulary'),
-     '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' => 'backdrop_get_form',
-     
-     
-     'page arguments' => array('taxonomy_form_term', 2, NULL),
-     'access callback' => 'taxonomy_term_access',
-     'access arguments' => array('update', 2),
-     'type' => MENU_LOCAL_TASK,
-     'weight' => 10,
-     'file' => 'taxonomy.admin.inc',
-   );
-   $items['taxonomy/term/%taxonomy_term/delete'] = array(
-     'title' => 'Delete',
-     'page callback' => 'backdrop_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',
-     
-     'delivery callback' => 'backdrop_deliver_html_page',
-   );
-   $items['taxonomy/autocomplete'] = array(
-     'title' => 'Autocomplete taxonomy',
-     'page callback' => 'taxonomy_autocomplete',
-     'delivery callback' => 'backdrop_json_deliver',
-     'access arguments' => array('access content'),
-     'type' => MENU_CALLBACK,
-     'file' => 'taxonomy.pages.inc',
-   );
- 
-   $items['admin/structure/taxonomy/%taxonomy_vocabulary'] = array(
-     'title callback' => 'taxonomy_vocabulary_title',
-     'title arguments' => array(3),
-     'page callback' => 'backdrop_get_form',
-     'page arguments' => array('taxonomy_overview_terms', 3),
-     'access callback' => 'taxonomy_vocabulary_access',
-     'access arguments' => array(FALSE, 3),
-     'file' => 'taxonomy.admin.inc',
-   );
-   $items['admin/structure/taxonomy/%taxonomy_vocabulary/list'] = array(
-     'title' => 'List terms',
-     'type' => MENU_DEFAULT_LOCAL_TASK,
-     'weight' => -20,
-   );
-   $items['admin/structure/taxonomy/%taxonomy_vocabulary/configure'] = array(
-     'title' => 'Configure',
-     'page callback' => 'backdrop_get_form',
-     'page arguments' => array('taxonomy_form_vocabulary', 3),
-     'access arguments' => array('administer taxonomy'),
-     'type' => MENU_LOCAL_TASK,
-     'weight' => -10,
-     'file' => 'taxonomy.admin.inc',
-   );
- 
-   $items['admin/structure/taxonomy/%taxonomy_vocabulary/add'] = array(
-     'title' => 'Add term',
-     'page callback' => 'backdrop_get_form',
-     'page arguments' => array('taxonomy_form_term', NULL, 3),
-     'access callback' => 'taxonomy_vocabulary_access',
-     'access arguments' => array('create', 3),
-     'type' => MENU_LOCAL_ACTION,
-     'file' => 'taxonomy.admin.inc',
-   );
- 
-   $items['admin/structure/taxonomy/%taxonomy_vocabulary/delete'] = array(
-     'title' => 'Delete',
-     'page callback' => 'backdrop_get_form',
-     'page arguments' => array('taxonomy_vocabulary_confirm_delete', 3),
-     'access callback' => 'taxonomy_vocabulary_access',
-     'access arguments' => array(FALSE, 3),
-     'type' => MENU_CALLBACK,
-     'file' => 'taxonomy.admin.inc',
-   );
- 
-   return $items;
- }
- 
-  * Implements hook_admin_paths().
-  */
- function taxonomy_admin_paths() {
-   $paths = array(
-     'taxonomy/term/*/edit' => TRUE,
-     'taxonomy/term/*/delete' => TRUE,
-   );
-   return $paths;
- }
- 
-  * Access callback: Checks if a user has permission to view the vocabulary
-  * overview page. This is anyone who can create/update/delete terms in any
-  * existing vocabulary.
-  *
-  * @return
-  *   TRUE if the user has access, FALSE otherwise.
-  *
-  * @see taxonomy_menu()
-  */
- function taxonomy_vocabulary_overview_access() {
-   
-   if (user_access('administer taxonomy')) {
-     return TRUE;
-   }
- 
-   
-   
-   $vocabularies = taxonomy_vocabulary_load_multiple(FALSE);
-   $operations = array('create', 'edit', 'delete');
-   foreach ($vocabularies as $vocabulary) {
-     foreach ($operations as $operation) {
-       if (user_access("$operation terms in $vocabulary->machine_name")) {
-         return TRUE;
-       }
-     }
-   }
- 
-   
-   return FALSE;
- }
- 
-  * Access callback: Checks a user's permission for performing operations on
-  * taxonomy terms in a vocabulary.
-  *
-  * @param $op
-  *   The operation to be performed on taxonomy terms in the vocabulary, or FALSE
-  *   to check access for any operation.
-  * @param TaxonomyVocabulary $vocabulary
-  *   The $vocabulary object that contains the terms on which the operation is to
-  *   be performed.
-  *
-  * @return
-  *   TRUE if the user has access, FALSE otherwise.
-  *
-  * @see taxonomy_menu()
-  *
-  * @since 1.13.0 The "edit" $op option is deprecated. Use "update" instead.
-  */
- function taxonomy_vocabulary_access($op, $vocabulary) {
-   
-   if (!$vocabulary) {
-     return FALSE;
-   }
- 
-   
-   if (user_access('administer taxonomy')) {
-     return TRUE;
-   }
- 
-   
-   
-   if ($op == 'edit') {
-     $message = 'The function taxonomy_vocabulary_access() was called with the operation <em>edit</em>. This operation is now named <em>update</em>. The <em>edit</em> operation will be removed in the next major release of Backdrop.';
-     $variables = array();
-     watchdog('taxonomy', $message, $variables, WATCHDOG_DEPRECATED);
-   } elseif ($op == 'update') {
-     return user_access("edit terms in $vocabulary->machine_name");
-   }
- 
-   if ($op !== FALSE) {
-     return user_access("$op terms in $vocabulary->machine_name");
-   }
-   else {
-     
-     
-     $operations = array('create', 'edit', 'delete');
-     foreach ($operations as $operation) {
-       if (user_access("$operation terms in $vocabulary->machine_name")) {
-         return TRUE;
-       }
-     }
- 
-     
-     return FALSE;
-   }
- }
- 
-  * Access callback: Checks a user's permission for performing a taxonomy term operation.
-  *
-  * @param string $op
-  *   The operation to be performed on the taxonomy term. Possible values are:
-  *   - create
-  *   - view
-  *   - update
-  *   - delete
-  * @param TaxonomyTerm|string $term
-  *   The $term object on which the operation is to be performed, or the
-  *   vocabulary for the 'create' operation.
-  *
-  * @return
-  *   TRUE if the operation may be performed, FALSE otherwise.
-  *
-  * @see taxonomy_menu()
-  *
-  * @since 1.13.0 The "create" and "view" $op options were added.
-  * @since 1.13.0 The "edit" $op option is deprecated. Use "update" instead.
-  */
- function taxonomy_term_access($op, $term) {
-   if ($op == 'edit') {
-     
-     $op = 'update';
-     
-     $message = 'The function taxonomy_term_access() was called with the operation <em>edit</em>. This operation is now named <em>update</em>. The <em>edit</em> operation will be removed in the next major release of Backdrop.';
-     $variables = array();
-     watchdog('taxonomy', $message, $variables, WATCHDOG_DEPRECATED);
-   }
- 
-   if ($op == 'create') {
-     
-     
-     if (is_string($term)) {
-       $bundle = $term;
-     }
-     else {
-       $bundle = $term->bundle();
-     }
-     return TaxonomyTerm::createAccess($bundle);
-   }
-   elseif ($term instanceof TaxonomyTerm) {
-     return $term->access($op);
-   }
-   return FALSE;
- }
- 
-  * Returns the title of a vocabulary.
-  */
- function taxonomy_vocabulary_title(TaxonomyVocabulary $vocabulary) {
-   return $vocabulary->name;
- }
- 
-  * Saves a new or updated taxonomy vocabulary.
-  *
-  * @param TaxonomyVocabulary $vocabulary
-  *   The taxonomy vocabulary entity to be saved.
-  *
-  * @return int
-  *   Either SAVED_NEW or SAVED_UPDATED depending on the operation performed.
-  */
- function taxonomy_vocabulary_save(TaxonomyVocabulary $vocabulary) {
-   return $vocabulary->save();
- }
- 
-  * Deletes a vocabulary.
-  *
-  * This will update all Taxonomy fields so that they don't reference the
-  * deleted vocabulary. It also will delete fields that have no remaining
-  * vocabulary references. All taxonomy terms of the deleted vocabulary
-  * will be deleted as well.
-  */
- function taxonomy_vocabulary_delete($vocabulary_name) {
-   $vocabulary = taxonomy_vocabulary_load($vocabulary_name);
-   $vocabulary->delete();
- }
- 
-  * Deletes vocabularies.
-  *
-  * @param array $vocabulary_names
-  *   The vocabulary machine names.
-  */
- function taxonomy_vocabulary_delete_multiple(array $vocabulary_names) {
-   foreach ($vocabulary_names as $vocabulary_name) {
-     taxonomy_vocabulary_delete($vocabulary_name);
-   }
- }
- 
-  * Implements hook_taxonomy_vocabulary_update().
-  */
- function taxonomy_taxonomy_vocabulary_update(TaxonomyVocabulary $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);
-         }
-       }
-     }
-   }
- }
- 
-  * Checks and updates the hierarchy flag of a vocabulary.
-  *
-  * Checks the current parents of all terms in a vocabulary and updates the
-  * vocabulary's hierarchy setting to the lowest possible level. If no term
-  * has parent terms then the vocabulary will be given a hierarchy of
-  * TAXONOMY_HIERARCHY_DISABLED. If any term has a single parent then the
-  * vocabulary will be given a hierarchy of TAXONOMY_HIERARCHY_SINGLE. If any
-  * term has multiple parents then the vocabulary will be given a hierarchy of
-  * TAXONOMY_HIERARCHY_MULTIPLE.
-  *
-  * @param TaxonomyVocabulary $vocabulary
-  *   A taxonomy vocabulary entity.
-  * @param $changed_term
-  *   An array of the term structure that was updated.
-  *
-  * @return
-  *   An integer that represents the level of the vocabulary's hierarchy.
-  */
- function taxonomy_check_vocabulary_hierarchy(TaxonomyVocabulary $vocabulary, $changed_term) {
-   $tree = taxonomy_get_tree($vocabulary->machine_name);
-   $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;
- }
- 
-  * Saves a new or updated taxonomy term.
-  *
-  * @param TaxonomyTerm $term
-  *   The taxonomy term entity to be saved.
-  *
-  * @return int
-  *   Either SAVED_NEW or SAVED_UPDATED depending on the operation performed.
-  */
- function taxonomy_term_save(TaxonomyTerm $term) {
-   return $term->save();
- }
- 
-  * Deletes a term.
-  *
-  * @param $tid
-  *   The term ID.
-  */
- function taxonomy_term_delete($tid) {
-   taxonomy_term_delete_multiple(array($tid));
- }
- 
-  * Deletes taxonomy terms.
-  *
-  * @param $tids
-  *   The term ids to be deleted.
-  */
- function taxonomy_term_delete_multiple(array $tids) {
-   entity_delete_multiple('taxonomy_term', $tids);
- }
- 
-  * Generates an array which displays a term detail page.
-  *
-  * @param term
-  *   A taxonomy term object.
-  * @return
-  *   A $page element suitable for use by backdrop_render().
-  */
- function taxonomy_term_show($term) {
-   return taxonomy_term_view_multiple(array($term->tid => $term), 'full');
- }
- 
-  * Constructs a backdrop_render() style array from an array of loaded terms.
-  *
-  * @param $terms
-  *   An array of taxonomy terms as returned by taxonomy_term_load_multiple().
-  * @param $view_mode
-  *   (optional) Display mode, e.g. 'full' or 'teaser'. Defaults to 'teaser'.
-  * @param $weight
-  *   (optional) An integer representing the weight of the first taxonomy term.
-  * @param $langcode
-  *   (optional) A language code to use for rendering. Defaults to the global
-  *   content language of the current request.
-  *
-  * @return
-  *   An array in the format expected by backdrop_render().
-  */
- function taxonomy_term_view_multiple($terms, $view_mode = 'teaser', $weight = 0, $langcode = NULL) {
-   $build = array();
-   $entities_by_view_mode = entity_view_mode_prepare('taxonomy_term', $terms, $view_mode, $langcode);
-   foreach ($entities_by_view_mode as $entity_view_mode => $entities) {
-     field_attach_prepare_view('taxonomy_term', $entities, $entity_view_mode, $langcode);
-     entity_prepare_view('taxonomy_term', $entities, $langcode);
- 
-     foreach ($entities as $entity) {
-       $build['taxonomy_terms'][$entity->tid] = taxonomy_term_view($entity, $entity_view_mode, $langcode);
-     }
-   }
- 
-   foreach ($terms as $term) {
-     $build['taxonomy_terms'][$term->tid]['#weight'] = $weight;
-     $weight++;
-   }
-   
-   
-   backdrop_sort($build['taxonomy_terms'], array('#weight'));
-   $build['taxonomy_terms']['#sorted'] = TRUE;
- 
-   return $build;
- }
- 
-  * Builds a structured array representing the term's content.
-  *
-  * The content built for the taxonomy term (field values, file attachments or
-  * other term components) will vary depending on the $view_mode parameter.
-  *
-  * Backdrop core defines the following display modes for terms, with the
-  * following default use cases:
-  *   - full (default): term is displayed on its own page (taxonomy/term/123)
-  * Contributed modules might define additional display modes, or use existing
-  * display modes in additional contexts.
-  *
-  * @param $term
-  *   A taxonomy term object.
-  * @param $view_mode
-  *   (optional) Display mode, e.g. 'full' or 'teaser'. Defaults to 'full'.
-  * @param $langcode
-  *   (optional) A language code to use for rendering. Defaults to the global
-  *   content language of the current request.
-  */
- function taxonomy_term_build_content($term, $view_mode = 'full', $langcode = NULL) {
-   $term->buildContent($view_mode, $langcode);
- }
- 
-  * Generate an array for rendering the given term.
-  *
-  * @param TaxonomyTerm $term
-  *   A taxonomy term entity.
-  * @param $view_mode
-  *   (optional) Display mode, e.g. 'full' or 'teaser'. Defaults to 'full'.
-  * @param $langcode
-  *   (optional) A language code to use for rendering. Defaults to the global
-  *   content language of the current request.
-  *
-  * @return
-  *   An array as expected by backdrop_render().
-  */
- function taxonomy_term_view(TaxonomyTerm $term, $view_mode = 'full', $langcode = NULL) {
-   return $term->view($view_mode, $langcode);
- }
- 
-  * Returns whether the current page is the page of the passed-in term.
-  *
-  * @param TaxonomyTerm $term
-  *   A taxonomy term entity.
-  */
- function taxonomy_term_is_page(TaxonomyTerm $term) {
-   $page_term = menu_get_object('taxonomy_term', 2);
-   return (!empty($page_term) ? $page_term->tid == $term->tid : FALSE);
- }
- 
-  * Clear all static cache variables for terms.
-  */
- function taxonomy_terms_static_reset() {
-   entity_get_controller('taxonomy_term')->resetCache();
- }
- 
-  * Clear all static cache variables for vocabularies.
-  *
-  * @param array|null $ids
-  *   An array of ids to reset in entity controller cache.
-  */
- function taxonomy_vocabulary_static_reset(?array $ids = NULL) {
-   entity_get_controller('taxonomy_vocabulary')->resetCache($ids);
- }
- 
-  * Get names for all taxonomy vocabularies.
-  *
-  * This function previously queried the database for a list of vocabulary names,
-  * but now is unnecessary as vocabulary names are stored exclusively in
-  * configuration. The return value is compatible with that of loading the
-  * full vocabularies through taxonomy_vocabulary_load_multiple().
-  *
-  * @return
-  *   An associative array of objects keyed by vocabulary machine name with
-  *   information about taxonomy vocabularies. Each object has properties:
-  *   - name: The vocabulary name.
-  *   - machine_name: The machine name.
-  *
-  * @deprecated since 1.0
-  * @see taxonomy_vocabulary_load_multiple()
-  */
- function taxonomy_vocabulary_get_names() {
-   watchdog_deprecated_function('taxonomy', __FUNCTION__);
-   return taxonomy_vocabulary_load_multiple(FALSE);
- }
- 
-  * Finds all parents of a given term ID.
-  *
-  * @param $tid
-  *   A taxonomy term ID.
-  *
-  * @return
-  *   An array of term objects which are the parents of the term $tid, or an
-  *   empty array if parents are not found.
-  */
- function taxonomy_term_load_parents($tid) {
-   $parents = &backdrop_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('taxonomy_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();
- }
- 
-  * Find all ancestors of a given term ID.
-  */
- function taxonomy_term_load_parents_all($tid) {
-   $cache = &backdrop_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;
- }
- 
-  * Finds all children of a term ID.
-  *
-  * @param $tid
-  *   A taxonomy term ID.
-  * @param $vocabulary_name
-  *   An optional vocabulary name to restrict the child search.
-  *
-  * @return
-  *   An array of term objects that are the children of the term $tid, or an
-  *   empty array when no children exist.
-  */
- function taxonomy_term_load_children($tid, $vocabulary_name = NULL) {
-   $children = &backdrop_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 ($vocabulary_name) {
-       $query->condition('t.vocabulary', $vocabulary_name);
-     }
-     $query->addTag('taxonomy_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();
- }
- 
-  * Create a hierarchical representation of a vocabulary.
-  *
-  * @param string $vocabulary_name
-  *   The vocabulary for which to generate the tree.
-  * @param int $parent
-  *   The term ID under which to generate the tree. If 0, generate the tree
-  *   for the entire vocabulary.
-  * @param int $max_depth
-  *   The number of levels of the tree to return. Leave NULL to return all levels.
-  * @param bool $load_entities
-  *   If TRUE, a full entity load will occur on the term objects. Otherwise they
-  *   are partial objects queried directly from the {taxonomy_term_data} table to
-  *   save execution time and memory consumption when listing large numbers of
-  *   terms. Defaults to FALSE.
-  *
-  * @return
-  *   An array of all term objects in the tree. Each term object is extended
-  *   to have "depth" and "parents" attributes in addition to its normal ones.
-  *   Results are statically cached. Term objects will be partial or complete
-  *   depending on the $load_entities parameter.
-  */
- function taxonomy_get_tree($vocabulary_name, $parent = 0, $max_depth = NULL, $load_entities = FALSE) {
-   $children = &backdrop_static(__FUNCTION__, array());
-   $parents = &backdrop_static(__FUNCTION__ . ':parents', array());
-   $terms = &backdrop_static(__FUNCTION__ . ':terms', array());
- 
-   
-   
-   if (!isset($children[$vocabulary_name])) {
-     $children[$vocabulary_name] = array();
-     $parents[$vocabulary_name] = array();
-     $terms[$vocabulary_name] = array();
- 
-     $query = db_select('taxonomy_term_data', 't');
-     $query->join('taxonomy_term_hierarchy', 'h', 'h.tid = t.tid');
-     $result = $query
-       ->addTag('translatable')
-       ->addTag('taxonomy_term_access')
-       ->fields('t')
-       ->fields('h', array('parent'))
-       ->condition('t.vocabulary', $vocabulary_name)
-       ->orderBy('t.weight')
-       ->orderBy('t.name')
-       ->execute();
- 
-     foreach ($result as $term) {
-       $children[$vocabulary_name][$term->parent][] = $term->tid;
-       $parents[$vocabulary_name][$term->tid][] = $term->parent;
-       $terms[$vocabulary_name][$term->tid] = $term;
-     }
-   }
- 
-   
-   
-   if ($load_entities) {
-     $term_entities = taxonomy_term_load_multiple(array_keys($terms[$vocabulary_name]));
-   }
- 
-   $max_depth = (!isset($max_depth)) ? count($children[$vocabulary_name]) : $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[$vocabulary_name][$parent])) {
-       $has_children = FALSE;
-       $child = current($children[$vocabulary_name][$parent]);
-       do {
-         if (empty($child)) {
-           break;
-         }
-         $term = $load_entities ? $term_entities[$child] : $terms[$vocabulary_name][$child];
-         if (isset($parents[$vocabulary_name][$term->tid])) {
-           
-           
-           $term = clone $term;
-         }
-         $term->depth = $depth;
-         unset($term->parent);
-         $term->parents = $parents[$vocabulary_name][$term->tid];
-         $tree[] = $term;
-         if (!empty($children[$vocabulary_name][$term->tid])) {
-           $has_children = TRUE;
- 
-           
-           $process_parents[] = $parent;
-           
-           $process_parents[] = $term->tid;
- 
-           
-           
-           reset($children[$vocabulary_name][$term->tid]);
-           
-           next($children[$vocabulary_name][$parent]);
-           break;
-         }
-       } while ($child = next($children[$vocabulary_name][$parent]));
- 
-       if (!$has_children) {
-         
-         
-         reset($children[$vocabulary_name][$parent]);
-       }
-     }
-   }
- 
-   return $tree;
- }
- 
-  * Try to map a string to an existing term, as for glossary use.
-  *
-  * Provides a case-insensitive and trimmed mapping, to maximize the
-  * likelihood of a successful match.
-  *
-  * @param $name
-  *   Name of the term to search for.
-  * @param $vocabulary_name
-  *   (optional) Vocabulary machine name to limit the search. Defaults to NULL.
-  *
-  * @return
-  *   An array of matching term objects.
-  */
- function taxonomy_term_load_multiple_by_name($name, $vocabulary_name = NULL) {
-   $conditions = array('name' => trim($name));
-   if (isset($vocabulary_name)) {
-     $conditions['vocabulary'] = $vocabulary_name;
-   }
-   return taxonomy_term_load_multiple(array(), $conditions);
- }
- 
-  * Implements hook_autoload_info().
-  */
- function taxonomy_autoload_info() {
-   return array(
-     'TaxonomyTerm' => 'taxonomy.entity.inc',
-     'TaxonomyTermController' => 'taxonomy.entity.inc',
-     'TaxonomyVocabulary' => 'taxonomy_vocabulary.class.inc',
-     
-     'TaxonomyTermDepthLayoutAccess' => 'layout/taxonomy_term_depth_access.inc',
-     
-     'views_handler_argument_taxonomy' => 'views/views_handler_argument_taxonomy.inc',
-     'views_handler_argument_term_node_tid' => 'views/views_handler_argument_term_node_tid.inc',
-     'views_handler_argument_term_node_tid_depth' => 'views/views_handler_argument_term_node_tid_depth.inc',
-     'views_handler_argument_term_node_tid_depth_modifier' => 'views/views_handler_argument_term_node_tid_depth_modifier.inc',
-     'views_handler_argument_vocabulary' => 'views/views_handler_argument_vocabulary.inc',
-     'views_handler_argument_term_language' => 'views/views_handler_argument_term_language.inc',
-     'views_handler_field_taxonomy' => 'views/views_handler_field_taxonomy.inc',
-     'views_handler_field_term_node_tid' => 'views/views_handler_field_term_node_tid.inc',
-     'views_handler_field_term_path' => 'views/views_handler_field_term_path.inc',
-     'views_handler_field_term_link_edit' => 'views/views_handler_field_term_link_edit.inc',
-     'views_handler_field_vocabulary' => 'views/views_handler_field_vocabulary.inc',
-     'views_handler_filter_term_node_tid' => 'views/views_handler_filter_term_node_tid.inc',
-     'views_handler_filter_term_node_tid_depth' => 'views/views_handler_filter_term_node_tid_depth.inc',
-     'views_handler_filter_vocabulary' => 'views/views_handler_filter_vocabulary.inc',
-     'views_handler_relationship_node_term_data' => 'views/views_handler_relationship_node_term_data.inc',
-     'views_plugin_argument_validate_taxonomy_term' => 'views/views_plugin_argument_validate_taxonomy_term.inc',
-     'views_plugin_argument_default_taxonomy_tid' => 'views/views_plugin_argument_default_taxonomy_tid.inc',
-   );
- }
- 
-  * Implements hook_layout_access_info().
-  */
- function taxonomy_layout_access_info() {
-   $info['taxonomy_term_depth'] = array(
-     'title' => t('Taxonomy term: Depth'),
-     'description' => t('Control access by how deep your term is nested.'),
-     'class' => 'TaxonomyTermDepthLayoutAccess',
-     'required contexts' => array(
-       'taxonomy_term' => 'taxonomy_term',
-     ),
-   );
-   return $info;
- }
- 
-  * Load multiple taxonomy terms based on certain conditions.
-  *
-  * This function should be used whenever you need to load more than one term
-  * from the database. Terms are loaded into memory and will not require
-  * database access if loaded again during the same page request.
-  *
-  * @see entity_load()
-  * @see EntityFieldQuery
-  *
-  * @param $tids
-  *   An array of taxonomy term IDs.
-  * @param $conditions
-  *   (deprecated) An associative array of conditions on the {taxonomy_term}
-  *   table, where the keys are the database fields and the values are the
-  *   values those fields must have. Instead, it is preferable to use
-  *   EntityFieldQuery to retrieve a list of entity IDs loadable by
-  *   this function.
-  *
-  * @return TaxonomyTerm[]
-  *   An array of taxonomy term entities, indexed by tid. When no results are
-  *   found, an empty array is returned.
-  */
- function taxonomy_term_load_multiple($tids = array(), $conditions = array()) {
-   return entity_load('taxonomy_term', $tids, $conditions);
- }
- 
-  * Load multiple taxonomy vocabularies based on certain conditions.
-  *
-  * This function should be used whenever you need to load more than one
-  * vocabulary from the database. Terms are loaded into memory and will not
-  * require database access if loaded again during the same page request.
-  *
-  * @see entity_load()
-  *
-  * @param $machine_names
-  *  An array of taxonomy vocabulary machine names, or FALSE to load all
-  *  vocabularies.
-  *
-  * @return
-  *  An array of vocabulary objects, indexed by machine name.
-  */
- function taxonomy_vocabulary_load_multiple($machine_names = array()) {
-   $static = &backdrop_static(__FUNCTION__, array(
-     'vocabularies' => array(),
-     'machine_names' => NULL,
-   ));
- 
-   
-   if ($machine_names === FALSE) {
-     if (isset($static['machine_names'])) {
-       $machine_names = $static['machine_names'];
-     }
-     else {
-       $machine_names = array();
-       $config_names = config_get_names_with_prefix('taxonomy.vocabulary.');
-       foreach ($config_names as $config_name) {
-         $machine_names[] = str_replace('taxonomy.vocabulary.', '', $config_name);
-       }
-       $static['machine_names'] = $machine_names;
-     }
-   }
- 
-   
-   $new_vocabularies = array();
-   foreach ($machine_names as $machine_name) {
-     if (!isset($static['vocabularies'][$machine_name])) {
-       $config = config('taxonomy.vocabulary.' . $machine_name);
-       $data = $config->get();
-       $new_vocabularies[$machine_name] = $data ? new TaxonomyVocabulary($data) : FALSE;
-     }
-   }
- 
-   
-   foreach (module_implements('taxonomy_vocabulary_load') as $module) {
-     $function = $module . '_taxonomy_vocabulary_load';
-     $function($new_vocabularies);
-   }
- 
-   
-   $static['vocabularies'] += $new_vocabularies;
- 
-   
-   $return = array();
-   foreach ($machine_names as $machine_name) {
-     if (isset($static['vocabularies'][$machine_name])) {
-       $return[$machine_name] = $static['vocabularies'][$machine_name];
-     }
-     else {
-       $return[$machine_name] = FALSE;
-     }
-   }
- 
-   
-   uasort($return, function($a, $b) {
-     if ($a->weight != $b->weight) {
-       return $a->weight < $b->weight ? -1 : 1;
-     }
-   });
- 
-   return $return;
- }
- 
-  * Return the taxonomy vocabulary entity matching a vocabulary ID.
-  *
-  * @param $machine_name
-  *   The vocabulary's machine name.
-  *
-  * @return TaxonomyVocabulary|false
-  *   The taxonomy vocabulary, if it exists, FALSE otherwise. Results are
-  *   statically cached.
-  *
-  * @see taxonomy_vocabulary_machine_name_load()
-  */
- function taxonomy_vocabulary_load($machine_name) {
-   $vocabularies = taxonomy_vocabulary_load_multiple(array($machine_name));
-   return reset($vocabularies);
- }
- 
-  * Legacy wrapper to return the vocabulary object matching a machine name.
-  *
-  * This function is no longer necessary, as all vocabularies are always loaded
-  * by machine name. Simply call taxonomy_vocabulary_load() directly.
-  *
-  * @deprecated since 1.0.0
-  * @see taxonomy_vocabulary_load()
-  */
- function taxonomy_vocabulary_machine_name_load($machine_name) {
-   watchdog_deprecated_function('taxonomy', __FUNCTION__);
-   return taxonomy_vocabulary_load($machine_name);
- }
- 
-  * Legacy wrapper to return the parents of a term by TID.
-  *
-  * Do not call this function, use taxonomy_term_load_parents() instead.
-  *
-  * @deprecated since 1.0.0
-  * @see taxonomy_term_load_parents()
-  * @see https://docs.backdropcms.org/node/41635
-  */
- function taxonomy_get_parents($tid) {
-   watchdog_deprecated_function('taxonomy', __FUNCTION__);
-   return taxonomy_term_load_parents($tid);
- }
- 
-  * Legacy wrapper to load all the parents of a term by TID.
-  *
-  * Do not call this function, use taxonomy_term_load_parents_all() instead.
-  *
-  * @deprecated since 1.0.0
-  * @see taxonomy_term_load_parents_all()
-  * @see https://docs.backdropcms.org/node/41635
-  */
- function taxonomy_get_parents_all($tid) {
-   watchdog_deprecated_function('taxonomy', __FUNCTION__);
-   return taxonomy_term_load_parents_all($tid);
- }
- 
-  * Legacy wrapper to load the children of a TID.
-  *
-  * Do not call this function, use taxonomy_term_load_children() instead.
-  *
-  * @deprecated since 1.0.0
-  * @see taxonomy_term_load_children()
-  * @see https://docs.backdropcms.org/node/41635
-  */
- function taxonomy_get_children($tid, $vid = 0) {
-   watchdog_deprecated_function('taxonomy', __FUNCTION__);
-   return taxonomy_term_load_children($tid, $vid = 0);
- }
- 
-  * Legacy wrapper to try to map a string to an existing term.
-  *
-  * Do not call this function, use taxonomy_term_load_multiple_by_name() instead.
-  *
-  * @deprecated since 1.0.0
-  * @see taxonomy_term_load_multiple_by_name()
-  * @see https://docs.backdropcms.org/node/41635
-  */
- function taxonomy_get_term_by_name($name, $vocabulary = NULL)  {
-   watchdog_deprecated_function('taxonomy', __FUNCTION__);
-   return taxonomy_term_load_multiple_by_name($name, $vocabulary = NULL);
- }
- 
-  * Load all Taxonomy vocabularies.
-  */
- function taxonomy_get_vocabularies() {
-   return taxonomy_vocabulary_load_multiple(FALSE);
- }
- 
-  * Return the taxonomy term entity matching a term ID.
-  *
-  * @param $tid
-  *   A term's ID
-  *
-  * @return TaxonomyTerm|false
-  *   A taxonomy term entity or FALSE if the term was not found. Results are
-  *   statically cached.
-  */
- function taxonomy_term_load($tid) {
-   if (!is_numeric($tid)) {
-     return FALSE;
-   }
-   $term = taxonomy_term_load_multiple(array($tid), array());
-   return $term ? $term[$tid] : FALSE;
- }
- 
-  * Helper function for array_map purposes.
-  */
- function _taxonomy_get_tid_from_term(TaxonomyTerm $term) {
-   return $term->tid;
- }
- 
-  * Implodes a list of tags of a certain vocabulary into a string.
-  *
-  * @see backdrop_explode_tags()
-  */
- function taxonomy_implode_tags($tags, $vocabulary_name = NULL) {
-   $typed_tags = array();
-   foreach ($tags as $tag) {
-     
-     if (!isset($vocabulary_name) || $tag->vocabulary == $vocabulary_name) {
-       
-       if (isset($tag->name)) {
-         
-         if (strpos($tag->name, ',') !== FALSE || strpos($tag->name, '"') !== FALSE) {
-           $typed_tags[] = '"' . str_replace('"', '""', $tag->name) . '"';
-         }
-         else {
-           $typed_tags[] = $tag->name;
-         }
-       }
-     }
-   }
-   return implode(', ', $typed_tags);
- }
- 
-  * Implements hook_field_info().
-  *
-  * Field settings:
-  * - allowed_values: a list array of one or more vocabulary trees:
-  *   - vocabulary: a vocabulary machine name.
-  *   - parent: a term ID of a term whose children are allowed. This should be
-  *     '0' if all terms in a vocabulary are allowed. The allowed values do not
-  *     include the parent term.
-  *
-  */
- 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',
-       'default_token_formatter' => 'taxonomy_term_reference_plain',
-       'settings' => array(
-         'allowed_values' => array(
-           array(
-             'vocabulary' => '',
-             'parent' => '0',
-           ),
-         ),
-       ),
-     ),
-   );
- }
- 
-  * Implements hook_field_widget_info().
-  */
- function taxonomy_field_widget_info() {
-   return array(
-     'taxonomy_autocomplete' => array(
-       'label' => t('Autocomplete term widget (tagging)'),
-       'field types' => array('taxonomy_term_reference'),
-       'settings' => array(
-         'size' => 60,
-         'autocomplete_path' => 'taxonomy/autocomplete',
-         'follow_content_language' => TRUE,
- 
-       ),
-       'behaviors' => array(
-         'multiple values' => FIELD_BEHAVIOR_CUSTOM,
-       ),
-     ),
-   );
- }
- 
-  * Implements hook_field_widget_info_alter().
-  */
- function taxonomy_field_widget_info_alter(&$info) {
-   $info['options_select']['field types'][] = 'taxonomy_term_reference';
-   $info['options_buttons']['field types'][] = 'taxonomy_term_reference';
- }
- 
-  * Implements hook_menu_local_tasks_alter().
-  */
- function taxonomy_menu_local_tasks_alter(&$data, $router_item, $root_path) {
-   
-   
-   if (module_exists('language')) {
-     if ($root_path == 'admin/structure/taxonomy/%') {
-       foreach ($data['actions']['output'] as $key => $action_link) {
-         if ($action_link['#link']['path'] === 'admin/structure/taxonomy/%/add') {
-           $default_langcode = isset($_GET['langcode_term']) ? $_GET['langcode_term'] : LANGUAGE_NONE;
-           $query['langcode_term'] = $default_langcode;
-           $data['actions']['output'][$key]['#link']['localized_options'] = array('query' => $query);
-         }
-       }
-     }
-   }
- }
- 
-  * Implements hook_options_list().
-  */
- 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);
- }
- 
-  * Implements hook_field_validate().
-  *
-  * Taxonomy field settings allow for either a single vocabulary ID, multiple
-  * vocabulary IDs, or sub-trees of a vocabulary to be specified as allowed
-  * values, although only the first of these is supported via the field UI.
-  * Confirm that terms entered as values meet at least one of these conditions.
-  *
-  * Possible error codes:
-  * - 'taxonomy_term_illegal_value': The value is not part of the list of allowed values.
-  */
- 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) {
-               $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'])),
-         );
-       }
-     }
-   }
- }
- 
-  * Implements hook_field_is_empty().
-  */
- function taxonomy_field_is_empty($item, $field) {
-   if (!is_array($item) || (empty($item['tid']) && (string) $item['tid'] !== '0')) {
-     return TRUE;
-   }
-   return FALSE;
- }
- 
-  * Implements hook_field_formatter_info().
-  */
- 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'),
-     ),
-     'taxonomy_term_reference_rendered' => array(
-       'label' => t('Rendered term'),
-       'description' => t('Display the referenced term in a specific display mode'),
-       'field types' => array('taxonomy_term_reference'),
-       'settings' => array('view_mode' => 'default'),
-     ),
-   );
- }
- 
-  * Implements hook_field_formatter_view().
-  */
- function taxonomy_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
-   $element = array();
-   $settings = $display['settings'];
- 
-   
-   
-   
- 
-   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 = entity_uri('taxonomy_term', $term);
-           $element[$delta] = array(
-             '#type' => 'link',
-             '#title' => $term->name,
-             '#href' => $uri['path'],
-             '#options' => $uri['options'],
-           );
-         }
-       }
-       break;
- 
-     case 'taxonomy_term_reference_plain':
-       foreach ($items as $delta => $item) {
-         $name = ($item['tid'] != 'autocreate' ? $item['taxonomy_term']->name : $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']->name : $item['name'],
-           'attributes' => array(
-             'domain' => $item['tid'] != 'autocreate' ? url('taxonomy/term/' . $item['tid'], array('absolute' => TRUE)) : '',
-           ),
-         );
-       }
-       break;
- 
-     case 'taxonomy_term_reference_rendered':
-       
-       
-       $recursion_queue = &backdrop_static(__FUNCTION__, array());
- 
-       
-       
-       if (!isset($entity->referencing_entity)) {
-         $recursion_queue = array();
-       }
- 
-       
-       if (in_array($entity_type, array('taxonomy_term'))) {
-         $recursion_queue[$entity->id()] = $entity->id();
-       }
- 
-       
-       
-       $terms_display = array();
-       foreach ($items as $delta => $item) {
-         if (!isset($recursion_queue[$item['tid']])) {
-           $terms_display[$item['tid']] = $item['taxonomy_term'];
-         }
-       }
- 
-       
-       if ($terms_display) {
-         foreach ($terms_display as $tid => $term) {
-           $terms_display[$tid]->referencing_entity = $entity;
-           $terms_display[$tid]->referencing_field = $field['field_name'];
-         }
-         $terms_built = taxonomy_term_view_multiple($terms_display, $settings['view_mode']);
-       }
- 
-       
-       foreach ($items as $delta => $item) {
-         if (isset($terms_display[$item['tid']])) {
-           $element[$delta] = $terms_built['taxonomy_terms'][$item['tid']];
-         }
-         else {
-           $term = $item['taxonomy_term'];
-           $label = entity_label('taxonomy_term', $term);
-           $uri = entity_uri('taxonomy_term', $term);
-           $element[$delta] = array(
-             '#type' => 'link',
-             '#title' => $label,
-             '#href' => $uri['path'],
-             '#options' => $uri['options'],
-           );
-         }
-       }
- 
-       break;
-   }
- 
-   return $element;
- }
- 
-  * Implements hook_field_formatter_settings_form().
-  */
- function taxonomy_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
-   $display = $instance['display'][$view_mode];
-   $settings = $display['settings'];
- 
-   $element = array();
- 
-   switch ($display['type']) {
-     case 'taxonomy_term_reference_rendered':
-       $entity_info = entity_get_info('taxonomy_term');
-       $modes = $entity_info['view modes'];
-       $options = array('default' => t("Default"));
-       foreach ($modes as $name => $mode) {
-         $options[$name] = $mode['label'];
-       }
-       $element['view_mode'] = array(
-         '#title' => t('Display mode'),
-         '#type' => 'select',
-         '#options' => $options,
-         '#default_value' => $settings['view_mode'],
-         
-       );
-       break;
-   }
-   return $element;
- }
- 
-  * Implements hook_field_formatter_settings_summary().
-  */
- function taxonomy_field_formatter_settings_summary($field, $instance, $view_mode) {
-   $display = $instance['display'][$view_mode];
-   $settings = $display['settings'];
-   $summary = array();
- 
-   switch ($display['type']) {
-     case 'taxonomy_term_reference_rendered':
-       $entity_info = entity_get_info('taxonomy_term');
-       $modes = $entity_info['view modes'];
-       $mode = $settings['view_mode'];
-       if (!empty($modes[$settings['view_mode']]['label'])) {
-         $mode = $modes[$settings['view_mode']]['label'];
-       }
-       if ($settings['view_mode'] == 'default') {
-         $mode = t("Default");
-       }
-       $summary[] = t('Display mode: %mode', array('%mode' => $mode));
-       break;
-   }
- 
-   return implode('<br />', $summary);
- }
- 
-  * Returns the set of valid terms for a taxonomy field.
-  *
-  * @param array $field
-  *   The field definition.
-  *
-  * @return array
-  *   The array of valid terms for this field, keyed by term id.
-  */
- function taxonomy_allowed_values(array $field) {
-   $options = array();
-   foreach ($field['settings']['allowed_values'] as $tree) {
-     if ($vocabulary = taxonomy_vocabulary_load($tree['vocabulary'])) {
-       if ($terms = taxonomy_get_tree($vocabulary->machine_name, $tree['parent'])) {
-         foreach ($terms as $term) {
-           $options[$term->tid] = $term->name;
-         }
-       }
-     }
-   }
-   return $options;
- }
- 
-  * Implements hook_field_formatter_prepare_view().
-  *
-  * This preloads all taxonomy terms for multiple loaded objects at once and
-  * unsets values for invalid terms that do not exist.
-  */
- 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]);
-       }
-     }
-   }
- }
- 
-  * Title callback: Returns the title of the taxonomy term.
-  *
-  * @param TaxonomyTerm $term
-  *   A taxonomy term entity.
-  *
-  * @return
-  *   An unsanitized string that is the title of the taxonomy term.
-  *
-  * @see taxonomy_menu()
-  */
- function taxonomy_term_title(TaxonomyTerm $term) {
-   return $term->name;
- }
- 
-  * Implements hook_field_widget_form().
-  */
- function taxonomy_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
-   $tags = array();
-   foreach ($items as $item) {
-     $tags[$item['tid']] = isset($item['taxonomy_term']) ? $item['taxonomy_term'] : taxonomy_term_load($item['tid']);
-   }
- 
-   $element += array(
-     '#type' => 'textfield',
-     '#default_value' => taxonomy_implode_tags($tags),
-     '#autocomplete_path' => $instance['widget']['settings']['autocomplete_path'] . '/' . $field['field_name'],
-     '#size' => $instance['widget']['settings']['size'],
-     '#maxlength' => 1024,
-     '#element_validate' => array('taxonomy_autocomplete_validate'),
-   );
- 
-   return $element;
- }
- 
-  * Implements hook_field_widget_form_alter().
-  */
- function taxonomy_field_widget_form_alter(&$element, &$form_state, $context) {
-   $field = $context['field'];
-   $widget_type = $context['instance']['widget']['type'];
-   if ($field['type'] == 'taxonomy_term_reference' && in_array($widget_type, array('options_buttons', 'options_select'))) {
-     foreach ($field['settings']['allowed_values'] as $tree) {
-       if ($vocabulary = taxonomy_vocabulary_load($tree['vocabulary'])) {
-         if ($terms = taxonomy_get_tree($vocabulary->machine_name, $tree['parent'])) {
-           foreach ($terms as $term) {
-             if (isset($element['#options'][$term->tid])) {
-               $element[$term->tid] = array('#indentation' => $term->depth);
-             }
-           }
-         }
-       }
-     }
-   }
- }
- 
-  * Form element validate handler for taxonomy term autocomplete element.
-  */
- function taxonomy_autocomplete_validate($element, &$form_state) {
-   $langcode = LANGUAGE_NONE;
-   if (isset($form_state['values']['langcode'])) {
-     $langcode = $form_state['values']['langcode'];
-   }
-   
-   
-   $value = array();
-   if ($tags = $element['#value']) {
-     
-     $field = field_widget_field($element, $form_state);
-     $instance = field_widget_instance($element, $form_state);
-     $vocabularies = array();
-     foreach ($field['settings']['allowed_values'] as $tree) {
-       if ($vocabulary = taxonomy_vocabulary_load($tree['vocabulary'])) {
-         $vocabularies[$vocabulary->machine_name] = $vocabulary;
-       }
-     }
- 
-     
-     $typed_terms = backdrop_explode_tags($tags);
-     foreach ($typed_terms as $typed_term) {
-       
-       
-       if ($possibilities = taxonomy_term_load_multiple(array(), array('name' => trim($typed_term), 'vocabulary' => array_keys($vocabularies)))) {
-         $term = array_pop($possibilities);
-       }
-       else {
-         $vocabulary = reset($vocabularies);
-         $term = array(
-           'tid' => 'autocreate',
-           'name' => $typed_term,
-           'vocabulary' => $vocabulary->machine_name,
-           'langcode' => LANGUAGE_NONE,
-         );
-         if (module_exists('language') && $vocabulary->language == TAXONOMY_LANGUAGE_ENABLED  && $instance['widget']['settings']['follow_content_language']) {
-           $term['langcode'] = $langcode;
-         }
-       }
-       $value[] = (array)$term;
-     }
-   }
- 
-   form_set_value($element, $value, $form_state);
- }
- 
-  * Implements hook_field_widget_error().
-  */
- function taxonomy_field_widget_error($element, $error, $form, &$form_state) {
-   form_error($element, $error['message']);
- }
-  * Implements hook_field_settings_form().
-  */
- function taxonomy_field_settings_form($field, $instance, $has_data) {
-   
-   $vocabularies = taxonomy_vocabulary_load_multiple(FALSE);
-   $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;
- }
- 
-  * Implements hook_field_widget_settings_form().
-  */
- function taxonomy_field_widget_settings_form($field, $instance) {
-   $element = array(
-     'follow_content_language' => array(
-       '#type' => 'checkbox',
-       '#title' => t('Follow content language'),
-       '#default_value' => isset($instance['widget']['settings']['follow_content_language']) ? $instance['widget']['settings']['follow_content_language'] : TRUE,
-       '#description' => t('If enabled, and if the selected vocabulary has multilingual support enabled, terms will be added in the language of the content.'),
-       '#access' => (module_exists('language') && $instance['widget']['type'] == 'taxonomy_autocomplete'),
-     ),
-   );
- 
-   return $element;
- }
- 
-  * Implements hook_language_delete().
-  */
- function taxonomy_language_delete($language) {
-   
-   db_update('taxonomy_term_data')
-     ->fields(array('langcode' => ''))
-     ->condition('langcode', $language->langcode)
-     ->execute();
- }
- 
-  * @defgroup taxonomy_index Taxonomy indexing
-  * @{
-  * Functions to maintain taxonomy indexing.
-  *
-  * Taxonomy uses default field storage to store canonical relationships
-  * between terms and fieldable entities. However its most common use case
-  * requires listing all content associated with a term or group of terms
-  * sorted by creation date. To avoid slow queries due to joining across
-  * multiple node and field tables with various conditions and order by criteria,
-  * we maintain a denormalized table with all relationships between terms,
-  * published nodes and common sort criteria such as sticky and created.
-  * This is used as a lookup table by taxonomy_select_nodes(). When using other
-  * field storage engines or alternative methods of denormalizing this data
-  * you should set the config option 'maintain_index_table' to FALSE in the
-  * taxonomy.settings.json configuration file to avoid unnecessary writes in SQL.
-  */
- 
-  * Implements hook_field_presave().
-  *
-  * Create any new terms defined in a free-tagging vocabulary.
-  */
- function taxonomy_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
-   foreach ($items as $delta => $item) {
-     if ($item['tid'] == 'autocreate') {
-       
-       $term = entity_create('taxonomy_term', $item);
-       unset($term->tid);
-       taxonomy_term_save($term);
-       $items[$delta]['tid'] = $term->tid;
-     }
-   }
- }
- 
-  * Implements hook_node_insert().
-  */
- function taxonomy_node_insert(Node $node) {
-   
-   taxonomy_build_node_index($node);
- }
- 
-  * Builds and inserts taxonomy index entries for a given node.
-  *
-  * The index lists all terms that are related to a given node entity, and is
-  * therefore maintained at the entity level.
-  *
-  * @param Node $node
-  *   The node entity.
-  */
- function taxonomy_build_node_index(Node $node) {
-   
-   
-   $status = NULL;
-   if (config_get('taxonomy.settings', 'maintain_index_table')) {
-     
-     
-     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->isActiveRevision()) {
-     
-     $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) {
-         if (!empty($tid)) {
-           $query->values(array(
-             'nid' => $node->nid,
-             'tid' => $tid,
-             'sticky' => $sticky,
-             'created' => $node->created,
-           ));
-         }
-       }
-       $query->execute();
-     }
-   }
- }
- 
-  * Implements hook_node_update().
-  */
- function taxonomy_node_update(Node $node) {
-   
-   taxonomy_delete_node_index($node);
-   taxonomy_build_node_index($node);
- }
- 
-  * Implements hook_node_predelete().
-  */
- function taxonomy_node_predelete(Node $node) {
-   
-   taxonomy_delete_node_index($node);
- }
- 
-  * Deletes taxonomy index entries for a given node.
-  *
-  * @param Node $node
-  *   The node entity.
-  */
- function taxonomy_delete_node_index(Node $node) {
-   if (config_get('taxonomy.settings', 'maintain_index_table')) {
-     db_delete('taxonomy_index')->condition('nid', $node->nid)->execute();
-   }
- }
- 
-  * Implements hook_taxonomy_term_delete().
-  */
- function taxonomy_taxonomy_term_delete(TaxonomyTerm $term) {
-   if (config_get('taxonomy.settings', 'maintain_index_table')) {
-     
-     db_delete('taxonomy_index')->condition('tid', $term->tid)->execute();
-   }
- }
- 
-  * Implements hook_taxonomy_config_info().
-  */
- function taxonomy_config_info() {
-   $prefixes['taxonomy.settings'] = array(
-     'label' => t('Taxonomy settings'),
-     'group' => t('Configuration'),
-   );
-   $prefixes['taxonomy.vocabulary'] = array(
-     'name_key' => 'machine_name',
-     'label_key' => 'name',
-     'group' => t('Vocabularies'),
-   );
-   return $prefixes;
- }
- 
-  * Implements hook_config_create_validate().
-  */
- function taxonomy_config_create_validate(Config $staging_config, $all_changes) {
-   $config_name = $staging_config->getName();
- 
-   
-   
-   if (strpos($config_name, 'field.instance.taxonomy_term.') === 0) {
-     list($vocabulary_name, $field_name) = explode('.', str_replace('field.instance.taxonomy_term.', '', $config_name));
- 
-     
-     $vocabulary_exists = (bool) taxonomy_vocabulary_load($vocabulary_name);
-     $vocabulary_created = isset($all_changes['taxonomy.vocabulary.' . $vocabulary_name]);
-     if (!$vocabulary_exists && !$vocabulary_created) {
-       throw new ConfigValidateException(t('The field "@name" cannot be added because the vocabulary "@vocabulary" does not exist.', array('@name' => $field_name, '@vocabulary' => $vocabulary_name)));
-     }
-   }
- }
- 
-  * @} End of "defgroup taxonomy_index".
-  */