diff --git a/core/modules/entity/lib/Drupal/entity/EntityController.php b/core/modules/entity/lib/Drupal/entity/EntityController.php index 3ef0fcbc41217263cf14b4da2ab9fe77dc1dd0e6..3edc4ccdc9b675704990b16a79fb8d5213c07c5c 100644 --- a/core/modules/entity/lib/Drupal/entity/EntityController.php +++ b/core/modules/entity/lib/Drupal/entity/EntityController.php @@ -208,8 +208,8 @@ public function load($ids = array(), $conditions = array()) { * being loaded needs to be augmented with additional data from another * table, such as loading node type into comments or vocabulary machine name * into terms, however it can also support $conditions on different tables. - * See CommentController::buildQuery() or TaxonomyTermController::buildQuery() - * for examples. + * See Drupal\comment\CommentStorageController::buildQuery() or + * Drupal\taxonomy\TermStorageController::buildQuery() for examples. * * @param $ids * An array of entity IDs, or FALSE to load all entities. diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module index 250090f3b9c397ec73aa82b97c2cd9d3fcc7bb53..28e7f1786cb2e24a21d7033c92cb8678c5602bbf 100644 --- a/core/modules/forum/forum.module +++ b/core/modules/forum/forum.module @@ -6,6 +6,7 @@ */ use Drupal\node\Node; +use Drupal\taxonomy\Term; /** * Implements hook_help(). @@ -470,7 +471,7 @@ function forum_permission() { /** * Implements hook_taxonomy_term_delete(). */ -function forum_taxonomy_term_delete(TaxonomyTerm $term) { +function forum_taxonomy_term_delete(Term $term) { // For containers, remove the tid from the forum_containers variable. $containers = variable_get('forum_containers', array()); $key = array_search($term->tid, $containers); diff --git a/core/modules/path/path.module b/core/modules/path/path.module index 1d638ad4217bdb528946b2d91de36fdfedd1991e..d01c623d6fa8841afb67f5a5e2af4dcb6d4bf629 100644 --- a/core/modules/path/path.module +++ b/core/modules/path/path.module @@ -6,6 +6,7 @@ */ use Drupal\node\Node; +use Drupal\taxonomy\Term; /** * Implements hook_help(). @@ -268,7 +269,7 @@ function path_form_taxonomy_form_term_alter(&$form, $form_state) { /** * Implements hook_taxonomy_term_insert(). */ -function path_taxonomy_term_insert(TaxonomyTerm $term) { +function path_taxonomy_term_insert(Term $term) { if (isset($term->path)) { $path = $term->path; $path['alias'] = trim($path['alias']); @@ -285,7 +286,7 @@ function path_taxonomy_term_insert(TaxonomyTerm $term) { /** * Implements hook_taxonomy_term_update(). */ -function path_taxonomy_term_update(TaxonomyTerm $term) { +function path_taxonomy_term_update(Term $term) { if (isset($term->path)) { $path = $term->path; $path['alias'] = trim($path['alias']); @@ -306,7 +307,7 @@ function path_taxonomy_term_update(TaxonomyTerm $term) { /** * Implements hook_taxonomy_term_delete(). */ -function path_taxonomy_term_delete(TaxonomyTerm $term) { +function path_taxonomy_term_delete(Term $term) { // Delete all aliases associated with this term. path_delete(array('source' => 'taxonomy/term/' . $term->tid)); } diff --git a/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module b/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module index 72fb29d1e70223e1def8208fe9891cb3bf0e974c..0ec6da6926c50696ff01a5132fe5f071a3bb54b7 100644 --- a/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module +++ b/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module @@ -5,6 +5,8 @@ * Test module for Taxonomy hooks and functions not used in core. */ +use Drupal\taxonomy\Term; + /** * Implements hook_taxonomy_term_load(). */ @@ -20,7 +22,7 @@ function taxonomy_test_taxonomy_term_load(array $terms) { /** * Implements hook_taxonomy_term_insert(). */ -function taxonomy_test_taxonomy_term_insert(TaxonomyTerm $term) { +function taxonomy_test_taxonomy_term_insert(Term $term) { if (!empty($term->antonym)) { db_insert('taxonomy_term_antonym') ->fields(array( @@ -34,7 +36,7 @@ function taxonomy_test_taxonomy_term_insert(TaxonomyTerm $term) { /** * Implements hook_taxonomy_term_update(). */ -function taxonomy_test_taxonomy_term_update(TaxonomyTerm $term) { +function taxonomy_test_taxonomy_term_update(Term $term) { if (!empty($term->antonym)) { db_merge('taxonomy_term_antonym') ->key(array('tid' => $term->tid)) @@ -48,7 +50,7 @@ function taxonomy_test_taxonomy_term_update(TaxonomyTerm $term) { /** * Implements hook_taxonomy_term_delete(). */ -function taxonomy_test_taxonomy_term_delete(TaxonomyTerm $term) { +function taxonomy_test_taxonomy_term_delete(Term $term) { db_delete('taxonomy_term_antonym') ->condition('tid', $term->tid) ->execute(); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Term.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Term.php new file mode 100644 index 0000000000000000000000000000000000000000..323d0ddce3f937c3b85bb58e04e403168b2f345a --- /dev/null +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Term.php @@ -0,0 +1,99 @@ +<?php + +/** + * @file + * Definition of Term. + */ + +namespace Drupal\taxonomy; + +use Drupal\entity\Entity; + +/** + * Defines the taxonomy term entity. + */ +class Term extends Entity { + + /** + * The taxonomy term ID. + * + * @var integer + */ + public $tid; + + /** + * The taxonomy vocabulary ID this term belongs to. + * + * @var integer + */ + public $vid; + + /** + * Name of the term. + * + * @var string + */ + public $name; + + /** + * Description of the term. + * + * @var string + */ + public $description; + + /** + * The text format name for the term's description. + * + * @var string + */ + public $format; + + /** + * The weight of this term. + * + * This property stores the weight of this term in relation to other terms of + * the same vocabulary. + * + * @var integer + */ + public $weight = 0; + + /** + * The parent term(s) for this term. + * + * This property is not loaded, but may be used to modify the term parents via + * Term::save(). + * + * The property can be set to an array of term IDs. An entry of 0 means this + * term does not have any parents. When omitting this variable during an + * update, the existing hierarchy for the term remains unchanged. + * + * @var array + */ + public $parent; + + /** + * The machine name of the vocabulary the term is assigned to. + * + * If not given, this value will be set automatically by loading the + * vocabulary based on the $entity->vid property. + * + * @var string + */ + public $vocabulary_machine_name; + + /** + * Implements Drupal\entity\EntityInterface::id(). + */ + public function id() { + return $this->tid; + } + + /** + * Implements Drupal\entity\EntityInterface::bundle(). + */ + public function bundle() { + return $this->vocabulary_machine_name; + } +} diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorageController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorageController.php new file mode 100644 index 0000000000000000000000000000000000000000..5f511bebecc29b066e7d1e99abeb9cce44fae339 --- /dev/null +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorageController.php @@ -0,0 +1,146 @@ +<?php + +/** + * @file + * Definition of TermStorageController. + */ + +namespace Drupal\taxonomy; + +use Drupal\entity\EntityInterface; +use Drupal\entity\EntityDatabaseStorageController; + +/** + * Defines a Controller class for taxonomy terms. + */ +class TermStorageController extends EntityDatabaseStorageController { + + /** + * Overrides Drupal\entity\EntityDatabaseStorageController::create(). + * + * @param array $values + * An array of values to set, keyed by property name. A value for the + * vocabulary ID ('vid') is required. + */ + public function create(array $values) { + $entity = parent::create($values); + // Ensure the vocabulary machine name is initialized as it is used as the + // bundle key. + // @todo Move to Term::bundle() once field API has been converted + // to make use of it. + if (!isset($entity->vocabulary_machine_name)) { + $vocabulary = taxonomy_vocabulary_load($entity->vid); + $entity->vocabulary_machine_name = $vocabulary->machine_name; + } + // Save new terms with no parents by default. + if (!isset($entity->parent)) { + $entity->parent = array(0); + } + return $entity; + } + + /** + * Overrides Drupal\entity\EntityDatabaseStorageController::buildQuery(). + */ + protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) { + $query = parent::buildQuery($ids, $conditions, $revision_id); + $query->addTag('translatable'); + $query->addTag('term_access'); + // When name is passed as a condition use LIKE. + if (isset($conditions['name'])) { + $query_conditions = &$query->conditions(); + foreach ($query_conditions as $key => $condition) { + if ($condition['field'] == 'base.name') { + $query_conditions[$key]['operator'] = 'LIKE'; + $query_conditions[$key]['value'] = db_like($query_conditions[$key]['value']); + } + } + } + // Add the machine name field from the {taxonomy_vocabulary} table. + $query->innerJoin('taxonomy_vocabulary', 'v', 'base.vid = v.vid'); + $query->addField('v', 'machine_name', 'vocabulary_machine_name'); + return $query; + } + + /** + * Overrides Drupal\entity\EntityDatabaseStorageController::cacheGet(). + */ + protected function cacheGet($ids, $conditions = array()) { + $terms = parent::cacheGet($ids, $conditions); + // Name matching is case insensitive, note that with some collations + // LOWER() and drupal_strtolower() may return different results. + foreach ($terms as $term) { + if (isset($conditions['name']) && drupal_strtolower($conditions['name'] != drupal_strtolower($term->name))) { + unset($terms[$term->tid]); + } + } + return $terms; + } + + /** + * Overrides Drupal\entity\EntityDatabaseStorageController::postDelete(). + */ + protected function postDelete($entities) { + // See if any of the term's children are about to be become orphans. + $orphans = array(); + foreach (array_keys($entities) as $tid) { + if ($children = taxonomy_term_load_children($tid)) { + foreach ($children as $child) { + // If the term has multiple parents, we don't delete it. + $parents = taxonomy_term_load_parents($child->tid); + // Because the parent has already been deleted, the parent count might + // be 0. + if (count($parents) <= 1) { + $orphans[] = $child->tid; + } + } + } + } + + // Delete term hierarchy information after looking up orphans but before + // deleting them so that their children/parent information is consistent. + db_delete('taxonomy_term_hierarchy') + ->condition('tid', array_keys($entities)) + ->execute(); + + if (!empty($orphans)) { + taxonomy_term_delete_multiple($orphans); + } + } + + /** + * Overrides Drupal\entity\EntityDatabaseStorageController::postSave(). + */ + protected function postSave(EntityInterface $entity, $update) { + if (isset($entity->parent)) { + db_delete('taxonomy_term_hierarchy') + ->condition('tid', $entity->tid) + ->execute(); + + $query = db_insert('taxonomy_term_hierarchy') + ->fields(array('tid', 'parent')); + + foreach ($entity->parent as $parent) { + $query->values(array( + 'tid' => $entity->tid, + 'parent' => $parent + )); + } + $query->execute(); + } + } + + /** + * Implements Drupal\entity\EntityControllerInterface::resetCache(). + */ + public function resetCache(array $ids = NULL) { + drupal_static_reset('taxonomy_term_count_nodes'); + drupal_static_reset('taxonomy_get_tree'); + drupal_static_reset('taxonomy_get_tree:parents'); + drupal_static_reset('taxonomy_get_tree:terms'); + drupal_static_reset('taxonomy_term_load_parents'); + drupal_static_reset('taxonomy_term_load_parents_all'); + drupal_static_reset('taxonomy_term_load_children'); + parent::resetCache($ids); + } +} diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Vocabulary.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Vocabulary.php new file mode 100644 index 0000000000000000000000000000000000000000..0305f77b08ce87a539269ba30f570b6d8da6a955 --- /dev/null +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Vocabulary.php @@ -0,0 +1,70 @@ +<?php + +/** + * @file + * Definition of Vocabulary. + */ + +namespace Drupal\taxonomy; + +use Drupal\entity\Entity; + +/** + * Defines the taxonomy vocabulary entity. + */ +class Vocabulary extends Entity { + + /** + * The taxonomy vocabulary ID. + * + * @var integer + */ + public $vid; + + /** + * Name of the vocabulary. + * + * @var string + */ + public $name; + + /** + * The vocabulary machine name. + * + * @var string + */ + public $machine_name; + + /** + * Description of the vocabulary. + * + * @var string + */ + public $description; + + /** + * The type of hierarchy allowed within the vocabulary. + * + * Possible values: + * - TAXONOMY_HIERARCHY_DISABLED: No parents. + * - TAXONOMY_HIERARCHY_SINGLE: Single parent. + * - TAXONOMY_HIERARCHY_MULTIPLE: Multiple parents. + * + * @var integer + */ + public $hierarchy = TAXONOMY_HIERARCHY_DISABLED; + + /** + * The weight of this vocabulary in relation to other vocabularies. + * + * @var integer + */ + public $weight = 0; + + /** + * Implements Drupal\entity\EntityInterface::id(). + */ + public function id() { + return $this->vid; + } +} diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyStorageController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyStorageController.php new file mode 100644 index 0000000000000000000000000000000000000000..8d64467a5f3a391c6e6e74591a6e387d38c5dd9e --- /dev/null +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyStorageController.php @@ -0,0 +1,89 @@ +<?php + +/** + * @file + * Definition of VocabularyStorageController. + */ + +namespace Drupal\taxonomy; + +use Drupal\entity\EntityInterface; +use Drupal\entity\EntityDatabaseStorageController; + +/** + * Defines a controller class for taxonomy vocabularies. + */ +class VocabularyStorageController extends EntityDatabaseStorageController { + + /** + * Overrides Drupal\entity\EntityDatabaseStorageController::buildQuery(). + */ + protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) { + $query = parent::buildQuery($ids, $conditions, $revision_id); + $query->addTag('translatable'); + $query->orderBy('base.weight'); + $query->orderBy('base.name'); + return $query; + } + + /** + * Overrides Drupal\entity\EntityDatabaseStorageController::postSave(). + */ + protected function postSave(EntityInterface $entity, $update) { + if (!$update) { + field_attach_create_bundle('taxonomy_term', $entity->machine_name); + } + elseif ($entity->original->machine_name != $entity->machine_name) { + field_attach_rename_bundle('taxonomy_term', $entity->original->machine_name, $entity->machine_name); + } + } + + /** + * Overrides Drupal\entity\EntityDatabaseStorageController::preDelete(). + */ + protected function preDelete($entities) { + // Only load terms without a parent, child terms will get deleted too. + $tids = db_query('SELECT t.tid FROM {taxonomy_term_data} t INNER JOIN {taxonomy_term_hierarchy} th ON th.tid = t.tid WHERE t.vid IN (:vids) AND th.parent = 0', array(':vids' => array_keys($entities)))->fetchCol(); + taxonomy_term_delete_multiple($tids); + } + + /** + * Overrides Drupal\entity\EntityDatabaseStorageController::postDelete(). + */ + protected function postDelete($entities) { + // Load all Taxonomy module fields and delete those which use only this + // vocabulary. + $taxonomy_fields = field_read_fields(array('module' => 'taxonomy')); + foreach ($taxonomy_fields as $field_name => $taxonomy_field) { + $modified_field = FALSE; + // Term reference fields may reference terms from more than one + // vocabulary. + foreach ($taxonomy_field['settings']['allowed_values'] as $key => $allowed_value) { + foreach ($entities as $vocabulary) { + if ($allowed_value['vocabulary'] == $vocabulary->machine_name) { + unset($taxonomy_field['settings']['allowed_values'][$key]); + $modified_field = TRUE; + } + } + } + if ($modified_field) { + if (empty($taxonomy_field['settings']['allowed_values'])) { + field_delete_field($field_name); + } + else { + // Update the field definition with the new allowed values. + field_update_field($taxonomy_field); + } + } + } + } + + /** + * Implements Drupal\entity\DrupalEntityControllerInterface::resetCache(). + */ + public function resetCache(array $ids = NULL) { + drupal_static_reset('taxonomy_vocabulary_get_names'); + parent::resetCache($ids); + cache_clear_all(); + } +} diff --git a/core/modules/taxonomy/taxonomy.admin.inc b/core/modules/taxonomy/taxonomy.admin.inc index 9b230055526abcce6c3345932506c7665657095a..db83d84ae91b13528459565929d35956c6e7d7d7 100644 --- a/core/modules/taxonomy/taxonomy.admin.inc +++ b/core/modules/taxonomy/taxonomy.admin.inc @@ -5,6 +5,9 @@ * Administrative page callbacks for the taxonomy module. */ +use Drupal\taxonomy\Term; +use Drupal\taxonomy\Vocabulary; + /** * Form builder to list and manage vocabularies. * @@ -101,7 +104,7 @@ function theme_taxonomy_overview_vocabularies($variables) { /** * Form builder for the vocabulary editing form. * - * @param TaxonomyVocabulary|null $vocabulary + * @param Drupal\taxonomy\Vocabulary|null $vocabulary * (optional) The taxonomy vocabulary entity to edit. If NULL or omitted, the * form creates a new vocabulary. * @@ -109,12 +112,12 @@ function theme_taxonomy_overview_vocabularies($variables) { * @see taxonomy_form_vocabulary_submit() * @see taxonomy_form_vocabulary_validate() */ -function taxonomy_form_vocabulary($form, &$form_state, TaxonomyVocabulary $vocabulary = NULL) { +function taxonomy_form_vocabulary($form, &$form_state, Vocabulary $vocabulary = NULL) { // During initial form build, add the entity to the form state for use // during form building and processing. During a rebuild, use what is in the // form state. if (!isset($form_state['vocabulary'])) { - // Create a new TaxonomyVocabulary entity for the add form. + // Create a new Vocabulary entity for the add form. if (!isset($vocabulary)) { $vocabulary = entity_create('taxonomy_vocabulary', array( // Default the new vocabulary to the site's default language. This is @@ -241,14 +244,14 @@ function taxonomy_form_vocabulary_submit($form, &$form_state) { * Display a tree of all the terms in a vocabulary, with options to edit * each one. The form is made drag and drop by the theme function. * - * @param TaxonomyVocabulary $vocabulary + * @param Drupal\taxonomy\Vocabulary $vocabulary * The taxonomy vocabulary entity to list terms for. * * @ingroup forms * @see taxonomy_overview_terms_submit() * @see theme_taxonomy_overview_terms() */ -function taxonomy_overview_terms($form, &$form_state, TaxonomyVocabulary $vocabulary) { +function taxonomy_overview_terms($form, &$form_state, Vocabulary $vocabulary) { global $pager_page_array, $pager_total, $pager_total_items; // Check for confirmation forms. @@ -642,10 +645,10 @@ function theme_taxonomy_overview_terms($variables) { /** * Form function for the term edit form. * - * @param TaxonomyTerm|null $term + * @param Drupal\taxonomy\Term|null $term * (optional) The taxonomy term entity to edit. If NULL or omitted, the form * creates a new term. - * @param TaxonomyVocabulary|null $vocabulary + * @param Drupal\taxonomy\Vocabulary|null $vocabulary * (optional) A taxonomy vocabulary entity to create the term in. Required if * the term is omitted. * @@ -653,12 +656,12 @@ function theme_taxonomy_overview_terms($variables) { * @see taxonomy_form_term_validate() * @see taxonomy_form_term_submit() */ -function taxonomy_form_term($form, &$form_state, TaxonomyTerm $term = NULL, TaxonomyVocabulary $vocabulary = NULL) { +function taxonomy_form_term($form, &$form_state, Term $term = NULL, Vocabulary $vocabulary = NULL) { // During initial form build, add the term entity to the form state for use // during form building and processing. During a rebuild, use what is in the // form state. if (!isset($form_state['term'])) { - // Create a new TaxonomyTerm entity for the add form. + // Create a new Term entity for the add form. if (!isset($term)) { $term = entity_create('taxonomy_term', array( 'vid' => $vocabulary->vid, diff --git a/core/modules/taxonomy/taxonomy.api.php b/core/modules/taxonomy/taxonomy.api.php index 88a0ff55006051625c8cd8f55aa5ca9d1bfe8ace..5f053fb16fc1fbf4136c0ad4f9a113d862a7f0fc 100644 --- a/core/modules/taxonomy/taxonomy.api.php +++ b/core/modules/taxonomy/taxonomy.api.php @@ -32,10 +32,10 @@ function hook_taxonomy_vocabulary_load(array $vocabularies) { * Modules implementing this hook can act on the vocabulary object before it is * inserted or updated. * - * @param TaxonomyVocabulary $vocabulary + * @param Drupal\taxonomy\Vocabulary $vocabulary * A taxonomy vocabulary entity. */ -function hook_taxonomy_vocabulary_presave(TaxonomyVocabulary $vocabulary) { +function hook_taxonomy_vocabulary_presave(Drupal\taxonomy\Vocabulary $vocabulary) { $vocabulary->foo = 'bar'; } @@ -45,10 +45,10 @@ function hook_taxonomy_vocabulary_presave(TaxonomyVocabulary $vocabulary) { * Modules implementing this hook can act on the vocabulary object when saved * to the database. * - * @param TaxonomyVocabulary $vocabulary + * @param Drupal\taxonomy\Vocabulary $vocabulary * A taxonomy vocabulary entity. */ -function hook_taxonomy_vocabulary_insert(TaxonomyVocabulary $vocabulary) { +function hook_taxonomy_vocabulary_insert(Drupal\taxonomy\Vocabulary $vocabulary) { if ($vocabulary->synonyms) { variable_set('taxonomy_' . $vocabulary->vid . '_synonyms', TRUE); } @@ -59,10 +59,10 @@ function hook_taxonomy_vocabulary_insert(TaxonomyVocabulary $vocabulary) { * * Modules implementing this hook can act on the vocabulary object when updated. * - * @param TaxonomyVocabulary $vocabulary + * @param Drupal\taxonomy\Vocabulary $vocabulary * A taxonomy vocabulary entity. */ -function hook_taxonomy_vocabulary_update(TaxonomyVocabulary $vocabulary) { +function hook_taxonomy_vocabulary_update(Drupal\taxonomy\Vocabulary $vocabulary) { $status = $vocabulary->synonyms ? TRUE : FALSE; if ($vocabulary->synonyms) { variable_set('taxonomy_' . $vocabulary->vid . '_synonyms', $status); @@ -76,13 +76,13 @@ function hook_taxonomy_vocabulary_update(TaxonomyVocabulary $vocabulary) { * field_attach_delete_bundle() is called and before the vocabulary is actually * removed from the database. * - * @param TaxonomyVocabulary $vocabulary + * @param Drupal\taxonomy\Vocabulary $vocabulary * The taxonomy vocabulary entity that is about to be deleted. * * @see hook_taxonomy_vocabulary_delete() * @see taxonomy_vocabulary_delete() */ -function hook_taxonomy_vocabulary_predelete(TaxonomyVocabulary $vocabulary) { +function hook_taxonomy_vocabulary_predelete(Drupal\taxonomy\Vocabulary $vocabulary) { if (variable_get('taxonomy_' . $vocabulary->vid . '_synonyms', FALSE)) { variable_del('taxonomy_' . $vocabulary->vid . '_synonyms'); } @@ -95,13 +95,13 @@ function hook_taxonomy_vocabulary_predelete(TaxonomyVocabulary $vocabulary) { * field_attach_delete_bundle() has been called and after the vocabulary has * been removed from the database. * - * @param TaxonomyVocabulary $vocabulary + * @param Drupal\taxonomy\Vocabulary $vocabulary * The taxonomy vocabulary entity that has been deleted. * * @see hook_taxonomy_vocabulary_predelete() * @see taxonomy_vocabulary_delete() */ -function hook_taxonomy_vocabulary_delete(TaxonomyVocabulary $vocabulary) { +function hook_taxonomy_vocabulary_delete(Drupal\taxonomy\Vocabulary $vocabulary) { if (variable_get('taxonomy_' . $vocabulary->vid . '_synonyms', FALSE)) { variable_del('taxonomy_' . $vocabulary->vid . '_synonyms'); } @@ -136,10 +136,10 @@ function hook_taxonomy_term_load(array $terms) { * Modules implementing this hook can act on the term object before it is * inserted or updated. * - * @param TaxonomyTerm $term + * @param Drupal\taxonomy\Term $term * A taxonomy term entity. */ -function hook_taxonomy_term_presave(TaxonomyTerm $term) { +function hook_taxonomy_term_presave(Drupal\taxonomy\Term $term) { $term->foo = 'bar'; } @@ -149,10 +149,10 @@ function hook_taxonomy_term_presave(TaxonomyTerm $term) { * Modules implementing this hook can act on the term object when saved to * the database. * - * @param TaxonomyTerm $term + * @param Drupal\taxonomy\Term $term * A taxonomy term entity. */ -function hook_taxonomy_term_insert(TaxonomyTerm $term) { +function hook_taxonomy_term_insert(Drupal\taxonomy\Term $term) { if (!empty($term->synonyms)) { foreach (explode ("\n", str_replace("\r", '', $term->synonyms)) as $synonym) { if ($synonym) { @@ -172,10 +172,10 @@ function hook_taxonomy_term_insert(TaxonomyTerm $term) { * * Modules implementing this hook can act on the term object when updated. * - * @param TaxonomyTerm $term + * @param Drupal\taxonomy\Term $term * A taxonomy term entity. */ -function hook_taxonomy_term_update(TaxonomyTerm $term) { +function hook_taxonomy_term_update(Drupal\taxonomy\Term $term) { hook_taxonomy_term_delete($term); if (!empty($term->synonyms)) { foreach (explode ("\n", str_replace("\r", '', $term->synonyms)) as $synonym) { @@ -198,12 +198,12 @@ function hook_taxonomy_term_update(TaxonomyTerm $term) { * field_attach_delete() is called and before the term is actually removed from * the database. * - * @param TaxonomyTerm $term + * @param Drupal\taxonomy\Term $term * The taxonomy term entity that is about to be deleted. * * @see taxonomy_term_delete() */ -function hook_taxonomy_term_predelete(TaxonomyTerm $term) { +function hook_taxonomy_term_predelete(Drupal\taxonomy\Term $term) { db_delete('term_synoynm')->condition('tid', $term->tid)->execute(); } @@ -213,12 +213,12 @@ function hook_taxonomy_term_predelete(TaxonomyTerm $term) { * This hook is invoked from taxonomy_term_delete() after field_attach_delete() * has been called and after the term has been removed from the database. * - * @param TaxonomyTerm $term + * @param Drupal\taxonomy\Term $term * The taxonomy term entity that has been deleted. * * @see taxonomy_term_delete() */ -function hook_taxonomy_term_delete(TaxonomyTerm $term) { +function hook_taxonomy_term_delete(Drupal\taxonomy\Term $term) { db_delete('term_synoynm')->condition('tid', $term->tid)->execute(); } diff --git a/core/modules/taxonomy/taxonomy.entity.inc b/core/modules/taxonomy/taxonomy.entity.inc deleted file mode 100644 index 773d62b0c964b64a585e4bb05f90a0984f7a7aba..0000000000000000000000000000000000000000 --- a/core/modules/taxonomy/taxonomy.entity.inc +++ /dev/null @@ -1,369 +0,0 @@ -<?php - -/** - * @file - * Entity classes and controllers for Taxonomy module. - */ - -use Drupal\entity\Entity; -use Drupal\entity\EntityInterface; -use Drupal\entity\EntityDatabaseStorageController; - -/** - * Defines the taxonomy term entity. - */ -class TaxonomyTerm extends Entity { - - /** - * The taxonomy term ID. - * - * @var integer - */ - public $tid; - - /** - * The taxonomy vocabulary ID this term belongs to. - * - * @var integer - */ - public $vid; - - /** - * Name of the term. - * - * @var string - */ - public $name; - - /** - * (optional) Description of the term. - * - * @var string - */ - public $description; - - /** - * (optional) The text format name for the term's description. - * - * @var string - */ - public $format; - - /** - * (optional) The weight of this term in relation to other terms of the same - * vocabulary. - * - * @var integer - */ - public $weight = 0; - - /** - * (optional) The parent term(s) for this term. - * - * This property is not loaded, but may be used to modify the term parents via - * TaxonomyTerm::save(). - * - * The property can be set to an array of term IDs. An entry of 0 means this - * term does not have any parents. When omitting this variable during an - * update, the existing hierarchy for the term remains unchanged. - * - * @var array - */ - public $parent; - - /** - * (optional) The machine name of the vocabulary the term is assigned to. If - * not given, this value will be set automatically by loading the vocabulary - * based on the $entity->vid property. - * - * @var string - */ - public $vocabulary_machine_name; - - /** - * Implements EntityInterface::id(). - */ - public function id() { - return $this->tid; - } - - /** - * Implements EntityInterface::bundle(). - */ - public function bundle() { - return $this->vocabulary_machine_name; - } -} - -/** - * Controller class for taxonomy terms. - */ -class TaxonomyTermController extends EntityDatabaseStorageController { - - /** - * Overrides EntityDatabaseStorageController::create(). - * - * @param array $values - * An array of values to set, keyed by property name. A value for the - * vocabulary ID ('vid') is required. - */ - public function create(array $values) { - $entity = parent::create($values); - // Ensure the vocabulary machine name is initialized as it is used as bundle - // key. - // @todo Move to TaxonomyTerm::bundle() once field API has been converted - // to make use of it. - if (!isset($entity->vocabulary_machine_name)) { - $vocabulary = taxonomy_vocabulary_load($entity->vid); - $entity->vocabulary_machine_name = $vocabulary->machine_name; - } - // Save new terms with no parents by default. - if (!isset($entity->parent)) { - $entity->parent = array(0); - } - return $entity; - } - - /** - * Overrides EntityDatabaseStorageController::buildQuery(). - */ - protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) { - $query = parent::buildQuery($ids, $conditions, $revision_id); - $query->addTag('translatable'); - $query->addTag('term_access'); - // When name is passed as a condition use LIKE. - if (isset($conditions['name'])) { - $query_conditions = &$query->conditions(); - foreach ($query_conditions as $key => $condition) { - if ($condition['field'] == 'base.name') { - $query_conditions[$key]['operator'] = 'LIKE'; - $query_conditions[$key]['value'] = db_like($query_conditions[$key]['value']); - } - } - } - // Add the machine name field from the {taxonomy_vocabulary} table. - $query->innerJoin('taxonomy_vocabulary', 'v', 'base.vid = v.vid'); - $query->addField('v', 'machine_name', 'vocabulary_machine_name'); - return $query; - } - - /** - * Overrides EntityDatabaseStorageController::cacheGet(). - */ - protected function cacheGet($ids, $conditions = array()) { - $terms = parent::cacheGet($ids, $conditions); - // Name matching is case insensitive, note that with some collations - // LOWER() and drupal_strtolower() may return different results. - foreach ($terms as $term) { - if (isset($conditions['name']) && drupal_strtolower($conditions['name'] != drupal_strtolower($term->name))) { - unset($terms[$term->tid]); - } - } - return $terms; - } - - /** - * Overrides EntityDatabaseStorageController::postDelete(). - */ - protected function postDelete($entities) { - // See if any of the term's children are about to be become orphans. - $orphans = array(); - foreach (array_keys($entities) as $tid) { - if ($children = taxonomy_term_load_children($tid)) { - foreach ($children as $child) { - // If the term has multiple parents, we don't delete it. - $parents = taxonomy_term_load_parents($child->tid); - // Because the parent has already been deleted, the parent count might - // be 0. - if (count($parents) <= 1) { - $orphans[] = $child->tid; - } - } - } - } - - // Delete term hierarchy information after looking up orphans but before - // deleting them so that their children/parent information is consistent. - db_delete('taxonomy_term_hierarchy') - ->condition('tid', array_keys($entities)) - ->execute(); - - if (!empty($orphans)) { - taxonomy_term_delete_multiple($orphans); - } - } - - /** - * Overrides EntityDatabaseStorageController::postSave(). - */ - protected function postSave(EntityInterface $entity, $update) { - if (isset($entity->parent)) { - db_delete('taxonomy_term_hierarchy') - ->condition('tid', $entity->tid) - ->execute(); - - $query = db_insert('taxonomy_term_hierarchy') - ->fields(array('tid', 'parent')); - - foreach ($entity->parent as $parent) { - $query->values(array( - 'tid' => $entity->tid, - 'parent' => $parent - )); - } - $query->execute(); - } - } - - /** - * Implements Drupal\entity\EntityControllerInterface::resetCache(). - */ - public function resetCache(array $ids = NULL) { - drupal_static_reset('taxonomy_term_count_nodes'); - drupal_static_reset('taxonomy_get_tree'); - drupal_static_reset('taxonomy_get_tree:parents'); - drupal_static_reset('taxonomy_get_tree:terms'); - drupal_static_reset('taxonomy_term_load_parents'); - drupal_static_reset('taxonomy_term_load_parents_all'); - drupal_static_reset('taxonomy_term_load_children'); - parent::resetCache($ids); - } -} - -/** - * Defines the taxonomy vocabulary entity. - */ -class TaxonomyVocabulary extends Entity { - - /** - * The taxonomy vocabulary ID. - * - * @var integer - */ - public $vid; - - /** - * Name of the vocabulary. - * - * @var string - */ - public $name; - - /** - * The vocabulary machine name. - * - * @var string - */ - public $machine_name; - - /** - * (optional) Description of the vocabulary. - * - * @var string - */ - public $description; - - /** - * The type of hierarchy allowed within the vocabulary. - * - * Possible values: - * - TAXONOMY_HIERARCHY_DISABLED: No parents. - * - TAXONOMY_HIERARCHY_SINGLE: Single parent. - * - TAXONOMY_HIERARCHY_MULTIPLE: Multiple parents. - * - * @var integer - */ - public $hierarchy = TAXONOMY_HIERARCHY_DISABLED; - - /** - * (optional) The weight of this vocabulary in relation to other vocabularies. - * - * @var integer - */ - public $weight = 0; - - /** - * Implements EntityInterface::id(). - */ - public function id() { - return $this->vid; - } -} - -/** - * Controller class for taxonomy vocabularies. - */ -class TaxonomyVocabularyController extends EntityDatabaseStorageController { - - /** - * Overrides EntityDatabaseStorageController::buildQuery(). - */ - protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) { - $query = parent::buildQuery($ids, $conditions, $revision_id); - $query->addTag('translatable'); - $query->orderBy('base.weight'); - $query->orderBy('base.name'); - return $query; - } - - /** - * Overrides EntityDatabaseStorageController::postSave(). - */ - protected function postSave(EntityInterface $entity, $update) { - if (!$update) { - field_attach_create_bundle('taxonomy_term', $entity->machine_name); - } - elseif ($entity->original->machine_name != $entity->machine_name) { - field_attach_rename_bundle('taxonomy_term', $entity->original->machine_name, $entity->machine_name); - } - } - - /** - * Overrides EntityDatabaseStorageController::preDelete(). - */ - protected function preDelete($entities) { - // Only load terms without a parent, child terms will get deleted too. - $tids = db_query('SELECT t.tid FROM {taxonomy_term_data} t INNER JOIN {taxonomy_term_hierarchy} th ON th.tid = t.tid WHERE t.vid IN (:vids) AND th.parent = 0', array(':vids' => array_keys($entities)))->fetchCol(); - taxonomy_term_delete_multiple($tids); - } - - /** - * Overrides EntityDatabaseStorageController::postDelete(). - */ - protected function postDelete($entities) { - // Load all Taxonomy module fields and delete those which use only this - // vocabulary. - $taxonomy_fields = field_read_fields(array('module' => 'taxonomy')); - foreach ($taxonomy_fields as $field_name => $taxonomy_field) { - $modified_field = FALSE; - // Term reference fields may reference terms from more than one - // vocabulary. - foreach ($taxonomy_field['settings']['allowed_values'] as $key => $allowed_value) { - foreach ($entities as $vocabulary) { - if ($allowed_value['vocabulary'] == $vocabulary->machine_name) { - unset($taxonomy_field['settings']['allowed_values'][$key]); - $modified_field = TRUE; - } - } - } - if ($modified_field) { - if (empty($taxonomy_field['settings']['allowed_values'])) { - field_delete_field($field_name); - } - else { - // Update the field definition with the new allowed values. - field_update_field($taxonomy_field); - } - } - } - } - - /** - * Implements Drupal\entity\EntityControllerInterface::resetCache(). - */ - public function resetCache(array $ids = NULL) { - drupal_static_reset('taxonomy_vocabulary_get_names'); - parent::resetCache($ids); - cache_clear_all(); - } -} diff --git a/core/modules/taxonomy/taxonomy.info b/core/modules/taxonomy/taxonomy.info index 197a2ae347263063a4d6849aa9706f0fb4fffd71..a7992c6a092e6b904eaf36f7efe5afa0069e4e1b 100644 --- a/core/modules/taxonomy/taxonomy.info +++ b/core/modules/taxonomy/taxonomy.info @@ -5,6 +5,5 @@ version = VERSION core = 8.x dependencies[] = options dependencies[] = entity -files[] = taxonomy.entity.inc files[] = taxonomy.test configure = admin/structure/taxonomy diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index 8de8ae3f55379b52c6a007ad31f5d1a498668193..755689c479e83ef9c6a480a8db1d5825ec9ee3e3 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -6,6 +6,8 @@ */ use Drupal\node\Node; +use Drupal\taxonomy\Term; +use Drupal\taxonomy\Vocabulary; /** * Denotes that no term in the vocabulary has a parent. @@ -109,8 +111,8 @@ function taxonomy_entity_info() { $return = array( 'taxonomy_term' => array( 'label' => t('Taxonomy term'), - 'entity class' => 'TaxonomyTerm', - 'controller class' => 'TaxonomyTermController', + 'entity class' => 'Drupal\taxonomy\Term', + 'controller class' => 'Drupal\taxonomy\TermStorageController', 'base table' => 'taxonomy_term_data', 'uri callback' => 'taxonomy_term_uri', 'fieldable' => TRUE, @@ -145,8 +147,8 @@ function taxonomy_entity_info() { } $return['taxonomy_vocabulary'] = array( 'label' => t('Taxonomy vocabulary'), - 'entity class' => 'TaxonomyVocabulary', - 'controller class' => 'TaxonomyVocabularyController', + 'entity class' => 'Drupal\taxonomy\Vocabulary', + 'controller class' => 'Drupal\taxonomy\VocabularyStorageController', 'base table' => 'taxonomy_vocabulary', 'entity keys' => array( 'id' => 'vid', @@ -426,17 +428,17 @@ function taxonomy_term_access($op, $term) { /** * Return the vocabulary name given the vocabulary object. */ -function taxonomy_admin_vocabulary_title_callback(TaxonomyVocabulary $vocabulary) { +function taxonomy_admin_vocabulary_title_callback(Vocabulary $vocabulary) { return check_plain($vocabulary->name); } /** * Saves a vocabulary. * - * @param TaxonomyVocabulary $vocabulary + * @param Drupal\taxonomy\Vocabulary $vocabulary * The taxonomy vocabulary entity to be saved. */ -function taxonomy_vocabulary_save(TaxonomyVocabulary $vocabulary) { +function taxonomy_vocabulary_save(Vocabulary $vocabulary) { return $vocabulary->save(); } @@ -464,7 +466,7 @@ function taxonomy_vocabulary_delete_multiple(array $vids) { /** * Implements hook_taxonomy_vocabulary_update(). */ -function taxonomy_taxonomy_vocabulary_update(TaxonomyVocabulary $vocabulary) { +function taxonomy_taxonomy_vocabulary_update(Vocabulary $vocabulary) { // Reflect machine name changes in the definitions of existing 'taxonomy' // fields. if (!empty($vocabulary->original->machine_name) && $vocabulary->original->machine_name != $vocabulary->machine_name) { @@ -497,7 +499,7 @@ function taxonomy_taxonomy_vocabulary_update(TaxonomyVocabulary $vocabulary) { * term has multiple parents then the vocabulary will be given a hierarchy of * TAXONOMY_HIERARCHY_MULTIPLE. * - * @param TaxonomyVocabulary $vocabulary + * @param Drupal\taxonomy\Vocabulary $vocabulary * A taxonomy vocabulary entity. * @param $changed_term * An array of the term structure that was updated. @@ -505,7 +507,7 @@ function taxonomy_taxonomy_vocabulary_update(TaxonomyVocabulary $vocabulary) { * @return * An integer that represents the level of the vocabulary's hierarchy. */ -function taxonomy_check_vocabulary_hierarchy(TaxonomyVocabulary $vocabulary, $changed_term) { +function taxonomy_check_vocabulary_hierarchy(Vocabulary $vocabulary, $changed_term) { $tree = taxonomy_get_tree($vocabulary->vid); $hierarchy = TAXONOMY_HIERARCHY_DISABLED; foreach ($tree as $term) { @@ -534,7 +536,7 @@ function taxonomy_check_vocabulary_hierarchy(TaxonomyVocabulary $vocabulary, $ch /** * Saves a term object to the database. * - * @param TaxonomyTerm $term + * @param Drupal\taxonomy\Term $term * The taxonomy term entity to be saved. * * @return @@ -542,7 +544,7 @@ function taxonomy_check_vocabulary_hierarchy(TaxonomyVocabulary $vocabulary, $ch * (SAVED_UPDATED). When inserting a new term, $term->tid will contain the * term ID of the newly created term. */ -function taxonomy_term_save(TaxonomyTerm $term) { +function taxonomy_term_save(Term $term) { return $term->save(); } @@ -569,7 +571,7 @@ function taxonomy_term_delete_multiple(array $tids) { /** * Generate an array for rendering the given term. * - * @param TaxonomyTerm $term + * @param Drupal\taxonomy\Term $term * A taxonomy term entity. * @param $view_mode * View mode, e.g. 'full', 'teaser'... @@ -580,7 +582,7 @@ function taxonomy_term_delete_multiple(array $tids) { * @return * An array as expected by drupal_render(). */ -function taxonomy_term_view(TaxonomyTerm $term, $view_mode = 'full', $langcode = NULL) { +function taxonomy_term_view(Term $term, $view_mode = 'full', $langcode = NULL) { if (!isset($langcode)) { $langcode = $GLOBALS['language_content']->langcode; } @@ -655,10 +657,10 @@ function template_preprocess_taxonomy_term(&$variables) { /** * Returns whether the current page is the page of the passed-in term. * - * @param TaxonomyTerm $term + * @param Drupal\taxonomy\Term $term * A taxonomy term entity. */ -function taxonomy_term_is_page(TaxonomyTerm $term) { +function taxonomy_term_is_page(Term $term) { $page_term = menu_get_object('taxonomy_term', 2); return (!empty($page_term) ? $page_term->tid == $term->tid : FALSE); } @@ -989,7 +991,7 @@ function taxonomy_vocabulary_load_multiple($vids = array(), array $conditions = * @param int $vid * The vocabulary's ID. * - * @return TaxonomyVocabulary|false + * @return Drupal\taxonomy\Vocabulary|false * The taxonomy vocabulary entity, if exists, FALSE otherwise. Results are * statically cached. * @@ -1005,7 +1007,7 @@ function taxonomy_vocabulary_load($vid) { * @param $name * The vocabulary's machine name. * - * @return TaxonomyVocabulary|false + * @return Drupal\taxonomy\Vocabulary|false * The taxonomy vocabulary entity, if exists, FALSE otherwise. Results are * statically cached. * @@ -1022,7 +1024,7 @@ function taxonomy_vocabulary_machine_name_load($name) { * @param $tid * A term's ID * - * @return TaxonomyTerm|false + * @return Drupal\taxonomy\Term|false * A taxonomy term entity. Results are statically cached. */ function taxonomy_term_load($tid) { @@ -1035,7 +1037,7 @@ function taxonomy_term_load($tid) { /** * Helper function for array_map purposes. */ -function _taxonomy_get_tid_from_term(TaxonomyTerm $term) { +function _taxonomy_get_tid_from_term(Term $term) { return $term->tid; } @@ -1349,13 +1351,13 @@ function taxonomy_field_formatter_prepare_view($entity_type, $entities, $field, /** * Title callback for term pages. * - * @param TaxonomyTerm $term + * @param Drupal\taxonomy\Term $term * A taxonomy term entity. * * @return * The term name to be used as the page title. */ -function taxonomy_term_title(TaxonomyTerm $term) { +function taxonomy_term_title(Term $term) { return $term->name; } @@ -1649,7 +1651,7 @@ function taxonomy_delete_node_index(Node $node) { /** * Implements hook_taxonomy_term_delete(). */ -function taxonomy_taxonomy_term_delete(TaxonomyTerm $term) { +function taxonomy_taxonomy_term_delete(Term $term) { if (variable_get('taxonomy_maintain_index_table', TRUE)) { // Clean up the {taxonomy_index} table when terms are deleted. db_delete('taxonomy_index')->condition('tid', $term->tid)->execute(); diff --git a/core/modules/taxonomy/taxonomy.pages.inc b/core/modules/taxonomy/taxonomy.pages.inc index 7f4fa457b709020704402c1fd78094ea155486bc..9673f8193654d0f041ed7a60ebaedc0af45ba28c 100644 --- a/core/modules/taxonomy/taxonomy.pages.inc +++ b/core/modules/taxonomy/taxonomy.pages.inc @@ -5,13 +5,16 @@ * Page callbacks for the taxonomy module. */ +use Drupal\taxonomy\Term; +use Drupal\taxonomy\Vocabulary; + /** * Menu callback; displays all nodes associated with a term. * - * @param TaxonomyTerm $term + * @param Drupal\taxonomy\Term $term * The taxonomy term entity. */ -function taxonomy_term_page(TaxonomyTerm $term) { +function taxonomy_term_page(Term $term) { // Assign the term name as the page title. drupal_set_title($term->name); @@ -60,10 +63,10 @@ function taxonomy_term_page(TaxonomyTerm $term) { /** * Generate the content feed for a taxonomy term. * - * @param TaxonomyTerm $term + * @param Drupal\taxonomy\Term $term * The taxonomy term entity. */ -function taxonomy_term_feed(TaxonomyTerm $term) { +function taxonomy_term_feed(Term $term) { $channel['link'] = url('taxonomy/term/' . $term->tid, array('absolute' => TRUE)); $channel['title'] = variable_get('site_name', 'Drupal') . ' - ' . $term->name; // Only display the description if we have a single term, to avoid clutter and confusion.