2002-04-14 20:46:41 +00:00
< ? php
2002-04-20 11:52:50 +00:00
2004-08-21 06:42:38 +00:00
/**
* @ file
* Enables the organization of content into categories .
*/
2013-09-01 06:20:08 +00:00
use Drupal\Core\Entity\EntityInterface ;
SA-CORE-2016-005 by larowlan, xjm, David_Rothstein, Dave Reid, Crell, cilefen, alexpott, mlhess, catch, pwolanin, YesCT, dawehner, quicksketch, Heine, znerol, charlotte.b, jnicola, ezraw
(cherry picked from commit c5da97f9e7e8f145541c5422e3ccde6a8b5ae680)
2016-11-16 18:45:27 +00:00
use Drupal\Core\Entity\Sql\SqlContentEntityStorage ;
2014-03-31 17:37:55 +00:00
use Drupal\Core\Render\Element ;
2014-06-30 03:33:08 +00:00
use Drupal\Core\Routing\RouteMatchInterface ;
2014-03-28 23:07:00 +00:00
use Drupal\Core\Url ;
2013-08-18 21:16:19 +00:00
use Drupal\taxonomy\Entity\Term ;
2011-12-23 03:42:04 +00:00
2009-12-02 07:42:43 +00:00
/**
2009-12-04 16:49:48 +00:00
* Implements hook_help () .
2009-12-02 07:42:43 +00:00
*/
2014-06-30 03:33:08 +00:00
function taxonomy_help ( $route_name , RouteMatchInterface $route_match ) {
2014-05-07 02:04:53 +00:00
switch ( $route_name ) {
case 'help.page.taxonomy' :
2019-04-16 05:38:27 +00:00
$field_ui_url = \Drupal :: moduleHandler () -> moduleExists ( 'field_ui' ) ? Url :: fromRoute ( 'help.page' , [ 'name' => 'field_ui' ]) -> toString () : '#' ;
2009-12-02 07:42:43 +00:00
$output = '' ;
$output .= '<h3>' . t ( 'About' ) . '</h3>' ;
2021-10-18 12:08:44 +00:00
$output .= '<p>' . t ( 'The Taxonomy module allows users who have permission to create and edit content to categorize (tag) content of that type. Users who have the <em>Administer vocabularies and terms</em> <a href=":permissions" title="Taxonomy module permissions">permission</a> can add <em>vocabularies</em> that contain a set of related <em>terms</em>. The terms in a vocabulary can either be pre-set by an administrator or built gradually as content is added and edited. Terms may be organized hierarchically if desired.' , [ ':permissions' => Url :: fromRoute ( 'user.admin_permissions.module' , [ 'modules' => 'taxonomy' ]) -> toString ()]) . '</p>' ;
2017-03-04 01:20:24 +00:00
$output .= '<p>' . t ( 'For more information, see the <a href=":taxonomy">online documentation for the Taxonomy module</a>.' , [ ':taxonomy' => 'https://www.drupal.org/documentation/modules/taxonomy/' ]) . '</p>' ;
2009-12-02 07:42:43 +00:00
$output .= '<h3>' . t ( 'Uses' ) . '</h3>' ;
$output .= '<dl>' ;
2015-02-16 23:24:30 +00:00
$output .= '<dt>' . t ( 'Managing vocabularies' ) . '</dt>' ;
2019-04-16 05:38:27 +00:00
$output .= '<dd>' . t ( 'Users who have the <em>Administer vocabularies and terms</em> permission can add and edit vocabularies from the <a href=":taxonomy_admin">Taxonomy administration page</a>. Vocabularies can be deleted from their <em>Edit vocabulary</em> page. Users with the <em>Taxonomy term: Administer fields</em> permission may add additional fields for terms in that vocabulary using the <a href=":field_ui">Field UI module</a>.' , [ ':taxonomy_admin' => Url :: fromRoute ( 'entity.taxonomy_vocabulary.collection' ) -> toString (), ':field_ui' => $field_ui_url ]) . '</dd>' ;
2015-02-16 23:24:30 +00:00
$output .= '<dt>' . t ( 'Managing terms' ) . '</dt>' ;
2019-04-16 05:38:27 +00:00
$output .= '<dd>' . t ( 'Users who have the <em>Administer vocabularies and terms</em> permission or the <em>Edit terms</em> permission for a particular vocabulary can add, edit, and organize the terms in a vocabulary from a vocabulary\'s term listing page, which can be accessed by going to the <a href=":taxonomy_admin">Taxonomy administration page</a> and clicking <em>List terms</em> in the <em>Operations</em> column. Users must have the <em>Administer vocabularies and terms</em> permission or the <em>Delete terms</em> permission for a particular vocabulary to delete terms.' , [ ':taxonomy_admin' => Url :: fromRoute ( 'entity.taxonomy_vocabulary.collection' ) -> toString ()]) . ' </dd>' ;
2015-02-16 23:24:30 +00:00
$output .= '<dt>' . t ( 'Classifying entity content' ) . '</dt>' ;
2019-04-16 05:38:27 +00:00
$output .= '<dd>' . t ( 'A user with the <em>Administer fields</em> permission for a certain entity type may add <em>Taxonomy term</em> reference fields to the entity type, which will allow entities to be classified using taxonomy terms. See the <a href=":entity_reference">Entity Reference help</a> for more information about reference fields. See the <a href=":field">Field module help</a> and the <a href=":field_ui">Field UI help</a> pages for general information on fields and how to create and manage them.' , [ ':field_ui' => $field_ui_url , ':field' => Url :: fromRoute ( 'help.page' , [ 'name' => 'field' ]) -> toString (), ':entity_reference' => Url :: fromRoute ( 'help.page' , [ 'name' => 'entity_reference' ]) -> toString ()]) . '</dd>' ;
2015-02-16 23:24:30 +00:00
$output .= '<dt>' . t ( 'Adding new terms during content creation' ) . '</dt>' ;
2017-09-14 02:47:52 +00:00
$output .= '<dd>' . t ( " Allowing users to add new terms gradually builds a vocabulary as content is added and edited. Users can add new terms if either of the two <em>Autocomplete</em> widgets is chosen for the Taxonomy term reference field in the <em>Manage form display</em> page for the field. You will also need to enable the <em>Create referenced entities if they don't already exist</em> option, and restrict the field to one vocabulary. " ) . '</dd>' ;
Issue #1847596 by amateescu, amitaibu, YesCT, Berdir, David_Rothstein, xjm, rteijeiro, ParisLiakos, webchick, Wim Leers, yched, jhodgdon, Bojhan: Remove Taxonomy term reference field in favor of Entity reference
2015-03-27 21:53:41 +00:00
$output .= '<dt>' . t ( 'Configuring displays and form displays' ) . '</dt>' ;
2019-04-16 05:38:27 +00:00
$output .= '<dd>' . t ( 'See the <a href=":entity_reference">Entity Reference help</a> page for the field widgets and formatters that can be configured for any reference field on the <em>Manage display</em> and <em>Manage form display</em> pages. Taxonomy additionally provides an <em>RSS category</em> formatter that displays nothing when the entity item is displayed as HTML, but displays an RSS category instead of a list when the entity item is displayed in an RSS feed.' , [ ':entity_reference' => Url :: fromRoute ( 'help.page' , [ 'name' => 'entity_reference' ]) -> toString ()]) . '</li>' ;
2015-02-16 23:24:30 +00:00
$output .= '</ul>' ;
$output .= '</dd>' ;
2009-12-02 07:42:43 +00:00
$output .= '</dl>' ;
return $output ;
2014-05-07 02:04:53 +00:00
2015-01-19 09:37:11 +00:00
case 'entity.taxonomy_vocabulary.collection' :
2010-01-10 21:26:30 +00:00
$output = '<p>' . t ( 'Taxonomy is for categorizing content. Terms are grouped into vocabularies. For example, a vocabulary called "Fruit" would contain the terms "Apple" and "Banana".' ) . '</p>' ;
2009-12-02 07:42:43 +00:00
return $output ;
}
}
2007-04-06 13:27:23 +00:00
/**
2009-12-04 16:49:48 +00:00
* Implements hook_theme () .
2007-04-06 13:27:23 +00:00
*/
function taxonomy_theme () {
2017-03-04 01:20:24 +00:00
return [
'taxonomy_term' => [
2010-02-10 06:28:10 +00:00
'render element' => 'elements' ,
2017-03-04 01:20:24 +00:00
],
];
2007-04-06 13:27:23 +00:00
}
2013-09-29 07:19:59 +00:00
/**
* Implements hook_theme_suggestions_HOOK () .
*/
function taxonomy_theme_suggestions_taxonomy_term ( array $variables ) {
2017-03-04 01:20:24 +00:00
$suggestions = [];
2013-09-29 07:19:59 +00:00
2014-02-04 16:02:26 +00:00
/** @var \Drupal\taxonomy\TermInterface $term */
$term = $variables [ 'elements' ][ '#taxonomy_term' ];
2013-09-29 07:19:59 +00:00
$suggestions [] = 'taxonomy_term__' . $term -> bundle ();
$suggestions [] = 'taxonomy_term__' . $term -> id ();
return $suggestions ;
}
2010-02-10 06:28:10 +00:00
/**
Issue #1898460 by pixelmord, bstoppel, steveoliver, jenlampton, johnnygamba, jastraat, Cottser, lbainbridge, myke, thedavidmeister, c4rl, joelpittet, ezeedub: Convert taxonomy module to Twig.
2013-05-24 16:52:00 +00:00
* Prepares variables for taxonomy term templates .
*
* Default template : taxonomy - term . html . twig .
*
2019-11-05 10:25:27 +00:00
* By default this function performs special preprocessing to move the name
* base field out of the elements array into a separate variable . This
* preprocessing is skipped if :
* - a module makes the field ' s display configurable via the field UI by means
* of BaseFieldDefinition :: setDisplayConfigurable ()
* - AND the additional entity type property
* 'enable_base_field_custom_preprocess_skipping' has been set using
* hook_entity_type_build () .
*
Issue #1898460 by pixelmord, bstoppel, steveoliver, jenlampton, johnnygamba, jastraat, Cottser, lbainbridge, myke, thedavidmeister, c4rl, joelpittet, ezeedub: Convert taxonomy module to Twig.
2013-05-24 16:52:00 +00:00
* @ param array $variables
* An associative array containing :
* - elements : An associative array containing the taxonomy term and any
* fields attached to the term . Properties used :
2014-02-04 16:02:26 +00:00
* - #taxonomy_term: A \Drupal\taxonomy\TermInterface object.
Issue #1898460 by pixelmord, bstoppel, steveoliver, jenlampton, johnnygamba, jastraat, Cottser, lbainbridge, myke, thedavidmeister, c4rl, joelpittet, ezeedub: Convert taxonomy module to Twig.
2013-05-24 16:52:00 +00:00
* - #view_mode: The current view mode for this taxonomy term, e.g.
* 'full' or 'teaser' .
* - attributes : HTML attributes for the containing element .
2010-02-10 06:28:10 +00:00
*/
function template_preprocess_taxonomy_term ( & $variables ) {
$variables [ 'view_mode' ] = $variables [ 'elements' ][ '#view_mode' ];
2014-02-04 16:02:26 +00:00
$variables [ 'term' ] = $variables [ 'elements' ][ '#taxonomy_term' ];
/** @var \Drupal\taxonomy\TermInterface $term */
2010-02-10 06:28:10 +00:00
$term = $variables [ 'term' ];
2020-02-27 21:50:06 +00:00
$variables [ 'url' ] = ! $term -> isNew () ? $term -> toUrl () -> toString () : NULL ;
2019-11-05 10:25:27 +00:00
// Make name field available separately. Skip this custom preprocessing if
// the field display is configurable and skipping has been enabled.
// @todo https://www.drupal.org/project/drupal/issues/3015623
// Eventually delete this code and matching template lines. Using
// $variables['content'] is more flexible and consistent.
$skip_custom_preprocessing = $term -> getEntityType () -> get ( 'enable_base_field_custom_preprocess_skipping' );
if ( ! $skip_custom_preprocessing || ! $term -> getFieldDefinition ( 'name' ) -> isDisplayConfigurable ( 'view' )) {
// We use name here because that is what appears in the UI.
$variables [ 'name' ] = $variables [ 'elements' ][ 'name' ];
unset ( $variables [ 'elements' ][ 'name' ]);
}
Issue #1898460 by pixelmord, bstoppel, steveoliver, jenlampton, johnnygamba, jastraat, Cottser, lbainbridge, myke, thedavidmeister, c4rl, joelpittet, ezeedub: Convert taxonomy module to Twig.
2013-05-24 16:52:00 +00:00
$variables [ 'page' ] = $variables [ 'view_mode' ] == 'full' && taxonomy_term_is_page ( $term );
2010-02-10 06:28:10 +00:00
// Helpful $content variable for templates.
2017-03-04 01:20:24 +00:00
$variables [ 'content' ] = [];
2014-03-31 17:37:55 +00:00
foreach ( Element :: children ( $variables [ 'elements' ]) as $key ) {
2010-02-10 06:28:10 +00:00
$variables [ 'content' ][ $key ] = $variables [ 'elements' ][ $key ];
}
}
2023-10-10 08:56:49 +00:00
/**
* Implements hook_entity_operation () .
*/
function taxonomy_entity_operation ( EntityInterface $term ) {
$operations = [];
if ( $term instanceof Term && $term -> access ( 'create' )) {
$operations [ 'add-child' ] = [
'title' => t ( 'Add child' ),
'weight' => 10 ,
'url' => Url :: fromRoute (
'entity.taxonomy_term.add_form' ,
[ 'taxonomy_vocabulary' => $term -> bundle ()],
[ 'query' => [ 'parent' => $term -> id ()]],
),
];
}
return $operations ;
}
2010-02-10 06:28:10 +00:00
/**
2011-04-12 20:54:16 +00:00
* Returns whether the current page is the page of the passed - in term .
2010-02-10 06:28:10 +00:00
*
2013-10-03 11:26:25 +00:00
* @ param \Drupal\taxonomy\Entity\Term $term
2012-04-02 02:55:32 +00:00
* A taxonomy term entity .
2010-02-10 06:28:10 +00:00
*/
2012-05-17 01:53:35 +00:00
function taxonomy_term_is_page ( Term $term ) {
Issue #1857256 by dawehner, xjm, tim.plunkett, jibran, ParisLiakos, hussainweb, pcambra, ekes, InternetDevels, rhabbachi, rdrh555, tstoeckler, oadaeh, Gábor Hojtsy, vijaycs85: Fixed Convert the taxonomy listing and feed at /taxonomy/term/%term to Views.
2014-09-15 09:17:06 +00:00
if ( \Drupal :: routeMatch () -> getRouteName () == 'entity.taxonomy_term.canonical' && $page_term_id = \Drupal :: routeMatch () -> getRawParameter ( 'taxonomy_term' )) {
return $page_term_id == $term -> id ();
2013-09-25 00:17:27 +00:00
}
return FALSE ;
2010-02-10 06:28:10 +00:00
}
2009-10-08 07:58:47 +00:00
/**
2011-01-03 18:03:54 +00:00
* @ defgroup taxonomy_index Taxonomy indexing
2011-01-02 17:26:40 +00:00
* @ {
* Functions to maintain taxonomy indexing .
2009-10-08 07:58:47 +00:00
*
* 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 ,
2015-01-20 12:50:25 +00:00
* published nodes and common sort criteria such as status , sticky and created .
* When using other field storage engines or alternative methods of
* denormalizing this data you should set the
* taxonomy . settings : maintain_index_table to '0' to avoid unnecessary writes in
* SQL .
2009-10-08 07:58:47 +00:00
*/
/**
2014-07-11 12:04:53 +00:00
* Implements hook_ENTITY_TYPE_insert () for node entities .
2009-10-08 07:58:47 +00:00
*/
2013-03-10 19:05:24 +00:00
function taxonomy_node_insert ( EntityInterface $node ) {
2011-12-08 03:52:37 +00:00
// Add taxonomy index entries for the node.
taxonomy_build_node_index ( $node );
2009-10-08 07:58:47 +00:00
}
/**
2011-12-08 03:52:37 +00:00
* 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 .
*
2013-08-18 21:16:19 +00:00
* @ param \Drupal\node\Entity\Node $node
2012-04-26 16:44:37 +00:00
* The node entity .
2009-10-08 07:58:47 +00:00
*/
2011-12-08 03:52:37 +00:00
function taxonomy_build_node_index ( $node ) {
// We maintain a denormalized table of term/node relationships, containing
// only data for current, published nodes.
2019-05-24 06:44:36 +00:00
if ( ! \Drupal :: config ( 'taxonomy.settings' ) -> get ( 'maintain_index_table' ) || ! ( \Drupal :: entityTypeManager () -> getStorage ( 'node' ) instanceof SqlContentEntityStorage )) {
2013-09-01 06:20:08 +00:00
return ;
2011-12-08 03:52:37 +00:00
}
2013-09-01 06:20:08 +00:00
$status = $node -> isPublished ();
$sticky = ( int ) $node -> isSticky ();
2011-12-08 03:52:37 +00:00
// We only maintain the taxonomy index for published nodes.
2012-09-06 20:32:19 +00:00
if ( $status && $node -> isDefaultRevision ()) {
2011-12-08 03:52:37 +00:00
// Collect a unique list of all the term IDs from all node fields.
2017-03-04 01:20:24 +00:00
$tid_all = [];
2015-10-06 11:02:22 +00:00
$entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem' ;
2014-04-11 16:01:24 +00:00
foreach ( $node -> getFieldDefinitions () as $field ) {
2013-12-09 23:19:58 +00:00
$field_name = $field -> getName ();
2015-10-06 11:02:22 +00:00
$class = $field -> getItemDefinition () -> getClass ();
$is_entity_reference_class = ( $class === $entity_reference_class ) || is_subclass_of ( $class , $entity_reference_class );
if ( $is_entity_reference_class && $field -> getSetting ( 'target_type' ) == 'taxonomy_term' ) {
2013-08-27 10:36:16 +00:00
foreach ( $node -> getTranslationLanguages () as $language ) {
2014-10-13 09:10:32 +00:00
foreach ( $node -> getTranslation ( $language -> getId ()) -> $field_name as $item ) {
2013-08-27 10:36:16 +00:00
if ( ! $item -> isEmpty ()) {
$tid_all [ $item -> target_id ] = $item -> target_id ;
2011-12-08 03:52:37 +00:00
}
}
}
}
}
// Insert index entries for all the node's terms.
if ( ! empty ( $tid_all )) {
Issue #2848952 by voleger, andypost, mondrake, jeetendrakumar, pk188, hgunicamp, piggito, JayKandari, daffie, shashikant_chauhan, xjm, cilefen, chiranjeeb, Pavan B S: Replace all calls to db_merge(), which is deprecated
2018-08-24 00:21:59 +00:00
$connection = \Drupal :: database ();
2011-12-08 03:52:37 +00:00
foreach ( $tid_all as $tid ) {
Issue #2848952 by voleger, andypost, mondrake, jeetendrakumar, pk188, hgunicamp, piggito, JayKandari, daffie, shashikant_chauhan, xjm, cilefen, chiranjeeb, Pavan B S: Replace all calls to db_merge(), which is deprecated
2018-08-24 00:21:59 +00:00
$connection -> merge ( 'taxonomy_index' )
2023-09-30 19:20:39 +00:00
-> keys ([ 'nid' => $node -> id (), 'tid' => $tid , 'status' => $node -> isPublished ()])
2017-03-04 01:20:24 +00:00
-> fields ([ 'sticky' => $sticky , 'created' => $node -> getCreatedTime ()])
2014-04-15 10:46:45 +00:00
-> execute ();
2009-10-08 07:58:47 +00:00
}
}
}
}
2011-12-08 03:52:37 +00:00
/**
2014-07-11 12:04:53 +00:00
* Implements hook_ENTITY_TYPE_update () for node entities .
2011-12-08 03:52:37 +00:00
*/
2013-03-10 19:05:24 +00:00
function taxonomy_node_update ( EntityInterface $node ) {
2016-06-23 21:31:25 +00:00
// If we're not dealing with the default revision of the node, do not make any
// change to the taxonomy index.
if ( ! $node -> isDefaultRevision ()) {
return ;
}
2011-12-08 03:52:37 +00:00
taxonomy_delete_node_index ( $node );
taxonomy_build_node_index ( $node );
}
2009-10-08 07:58:47 +00:00
/**
2014-07-11 12:04:53 +00:00
* Implements hook_ENTITY_TYPE_predelete () for node entities .
2009-10-08 07:58:47 +00:00
*/
2013-03-10 19:05:24 +00:00
function taxonomy_node_predelete ( EntityInterface $node ) {
2011-12-08 03:52:37 +00:00
// Clean up the {taxonomy_index} table when nodes are deleted.
taxonomy_delete_node_index ( $node );
}
/**
* Deletes taxonomy index entries for a given node .
*
2013-03-10 19:05:24 +00:00
* @ param \Drupal\Core\Entity\EntityInterface $node
2012-04-26 16:44:37 +00:00
* The node entity .
2011-12-08 03:52:37 +00:00
*/
2013-03-10 19:05:24 +00:00
function taxonomy_delete_node_index ( EntityInterface $node ) {
2013-09-16 03:58:06 +00:00
if ( \Drupal :: config ( 'taxonomy.settings' ) -> get ( 'maintain_index_table' )) {
2018-08-31 01:15:01 +00:00
\Drupal :: database () -> delete ( 'taxonomy_index' ) -> condition ( 'nid' , $node -> id ()) -> execute ();
2009-10-08 07:58:47 +00:00
}
}
/**
2014-07-11 12:04:53 +00:00
* Implements hook_ENTITY_TYPE_delete () for taxonomy_term entities .
2009-10-08 07:58:47 +00:00
*/
2012-05-17 01:53:35 +00:00
function taxonomy_taxonomy_term_delete ( Term $term ) {
2013-09-16 03:58:06 +00:00
if ( \Drupal :: config ( 'taxonomy.settings' ) -> get ( 'maintain_index_table' )) {
2009-10-08 07:58:47 +00:00
// Clean up the {taxonomy_index} table when terms are deleted.
2018-08-31 01:15:01 +00:00
\Drupal :: database () -> delete ( 'taxonomy_index' ) -> condition ( 'tid' , $term -> id ()) -> execute ();
2009-10-08 07:58:47 +00:00
}
}
/**
2012-05-17 12:58:49 +00:00
* @ } End of " defgroup taxonomy_index " .
2009-10-08 07:58:47 +00:00
*/