- <?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',
- ),
- '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 $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".
- */