diff --git a/core/modules/contact/contact.install b/core/modules/contact/contact.install
index c3802e7..cd60e7d 100644
--- a/core/modules/contact/contact.install
+++ b/core/modules/contact/contact.install
@@ -29,7 +29,7 @@ function contact_install() {
function contact_update_dependencies() {
// Migrate users.data after User module prepared the tables.
$dependencies['contact'][8003] = array(
- 'user' => 8011,
+ 'user' => 8016,
);
return $dependencies;
}
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
index ca31aae..890f3b5 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php
@@ -264,6 +264,13 @@ function testNonInitializedFields() {
* Tests hiding the view modes fieldset when there's only one available.
*/
function testSingleViewMode() {
+ // Create a test field.
+ $edit = array(
+ 'fields[_add_new_field][label]' => 'Test',
+ 'fields[_add_new_field][field_name]' => 'test',
+ );
+ $this->fieldUIAddNewField('admin/structure/taxonomy/manage/' . $this->vocabulary, $edit);
+
$this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary . '/display');
$this->assertNoText('Use custom display settings for the following view modes', 'Custom display settings fieldset found.');
diff --git a/core/modules/forum/forum.admin.inc b/core/modules/forum/forum.admin.inc
new file mode 100644
index 0000000..85fc9e1
--- /dev/null
+++ b/core/modules/forum/forum.admin.inc
@@ -0,0 +1,300 @@
+ config('forum.settings')->get('vocabulary')));
+ }
+
+ switch ($type) {
+ case 'forum':
+ return drupal_get_form('forum_form_forum', $term);
+ break;
+ case 'container':
+ return drupal_get_form('forum_form_container', $term);
+ break;
+ }
+}
+
+/**
+ * Form constructor for adding and editing a forum.
+ *
+ * @param \Drupal\taxonomy\Plugin\Core\Entity\Term $term
+ * A forum term to be edited.
+ *
+ * @see forum_form_submit()
+ * @ingroup forms
+ */
+function forum_form_forum($form, &$form_state, Term $term) {
+ $form['name'] = array('#type' => 'textfield',
+ '#title' => t('Forum name'),
+ '#default_value' => $term->name->value,
+ '#maxlength' => 255,
+ '#description' => t('Short but meaningful name for this collection of threaded discussions.'),
+ '#required' => TRUE,
+ );
+
+ $form['parent']['#tree'] = TRUE;
+ $form['parent'][0] = _forum_parent_select($term->id(), t('Parent'), 'forum');
+ $form['weight'] = array('#type' => 'weight',
+ '#title' => t('Weight'),
+ '#default_value' => $term->weight->value,
+ '#description' => t('Forums are displayed in ascending order by weight (forums with equal weights are displayed alphabetically).'),
+ );
+
+ $form['vid'] = array('#type' => 'hidden', '#value' => config('forum.settings')->get('vocabulary'));
+ $form['actions'] = array('#type' => 'actions');
+ $form['actions']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save'),
+ '#button_type' => 'primary',
+ '#submit' => array('forum_form_submit')
+ );
+ if (!$term->isNew()) {
+ $form['actions']['delete'] = array(
+ '#type' => 'submit',
+ '#value' => t('Delete'),
+ '#submit' => array('forum_forum_delete'),
+ );
+ $form['tid'] = array('#type' => 'value', '#value' => $term->id());
+ }
+ $form['#theme'] = 'forum_form';
+
+ return $form;
+}
+
+/**
+ * Form submission handler for forum_form_forum() and forum_form_container().
+ */
+function forum_form_submit($form, &$form_state) {
+ $config = config('forum.settings');
+ if ($form['form_id']['#value'] == 'forum_form_container') {
+ $container = TRUE;
+ $type = t('forum container');
+ }
+ else {
+ $container = FALSE;
+ $type = t('forum');
+ }
+
+ // @todo Set explicit entity properties instead of arbitrary form values.
+ form_state_values_clean($form_state);
+ $term = entity_create('taxonomy_term', $form_state['values']);
+ $status = $term->save();
+ switch ($status) {
+ case SAVED_NEW:
+ if ($container) {
+ $containers = $config->get('containers');
+ $containers[] = $term->id();
+ $config->set('containers', $containers)->save();
+ }
+ $form_state['values']['tid'] = $term->id();
+ drupal_set_message(t('Created new @type %term.', array('%term' => $form_state['values']['name'], '@type' => $type)));
+ break;
+ case SAVED_UPDATED:
+ drupal_set_message(t('The @type %term has been updated.', array('%term' => $form_state['values']['name'], '@type' => $type)));
+ // Clear the page and block caches to avoid stale data.
+ cache_invalidate_tags(array('content' => TRUE));
+ break;
+ }
+ $form_state['redirect'] = 'admin/structure/forum';
+}
+
+/**
+ * Returns HTML for a forum form.
+ *
+ * By default this does not alter the appearance of a form at all, but is
+ * provided as a convenience for themers.
+ *
+ * @param $variables
+ * An associative array containing:
+ * - form: A render element representing the form.
+ *
+ * @ingroup themeable
+ */
+function theme_forum_form($variables) {
+ return drupal_render_children($variables['form']);
+}
+
+/**
+ * Form constructor for adding and editing forum containers.
+ *
+ * @param \Drupal\taxonomy\Plugin\Core\Entity\Term $term
+ * A container term to be edited.
+ *
+ * @see forum_form_submit()
+ * @ingroup forms
+ */
+function forum_form_container($form, &$form_state, Term $term) {
+ $config = config('forum.settings');
+ // Handle a delete operation.
+ $form['name'] = array(
+ '#title' => t('Container name'),
+ '#type' => 'textfield',
+ '#default_value' => $term->name->value,
+ '#maxlength' => 255,
+ '#description' => t('Short but meaningful name for this collection of related forums.'),
+ '#required' => TRUE
+ );
+ $form['parent']['#tree'] = TRUE;
+ $form['parent'][0] = _forum_parent_select($term->id(), t('Parent'), 'container');
+ $form['weight'] = array(
+ '#type' => 'weight',
+ '#title' => t('Weight'),
+ '#default_value' => $term->weight->value,
+ '#description' => t('Containers are displayed in ascending order by weight (containers with equal weights are displayed alphabetically).')
+ );
+
+ $form['vid'] = array(
+ '#type' => 'hidden',
+ '#value' => $config->get('vocabulary'),
+ );
+ $form['actions'] = array('#type' => 'actions');
+ $form['actions']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save'),
+ '#button_type' => 'primary',
+ '#submit' => array('forum_form_submit'),
+ );
+ if (!$term->isNew()) {
+ $form['actions']['delete'] = array(
+ '#type' => 'submit',
+ '#value' => t('Delete'),
+ '#submit' => array('forum_forum_delete'),
+ );
+ $form['tid'] = array('#type' => 'value', '#value' => $term->id());
+ }
+ $form['#theme'] = 'forum_form';
+
+ return $form;
+}
+
+/**
+ * Form submission handler for forum_form_forum() and forum_form_container().
+ *
+ * Handler for when 'delete' is clicked.
+ *
+ * @see \Drupal\forum\Form\DeleteForm
+ */
+function forum_forum_delete($form, &$form_state) {
+ $form_state['redirect'] = 'admin/structure/forum/delete/forum/' . $form_state['values']['tid'];
+}
+
+/**
+ * Form constructor for the forum overview form.
+ *
+ * Returns a form for controlling the hierarchy of existing forums and
+ * containers.
+ *
+ * @see forum_menu()
+ * @ingroup forms
+ */
+function forum_overview($form, &$form_state) {
+ module_load_include('inc', 'taxonomy', 'taxonomy.admin');
+ $config = config('forum.settings');
+
+ $vid = $config->get('vocabulary');
+ $vocabulary = taxonomy_vocabulary_load($vid);
+ $form = taxonomy_overview_terms($form, $form_state, $vocabulary);
+
+ foreach (element_children($form['terms']) as $key) {
+ if (isset($form['terms'][$key]['#term'])) {
+ $term = $form['terms'][$key]['#term'];
+ $form['terms'][$key]['term']['#href'] = 'forum/' . $term->id();
+ unset($form['terms'][$key]['operations']['#links']['delete']);
+ if (in_array($form['terms'][$key]['#term']->id(), $config->get('containers'))) {
+ $form['terms'][$key]['operations']['#links']['edit']['title'] = t('edit container');
+ $form['terms'][$key]['operations']['#links']['edit']['href'] = 'admin/structure/forum/edit/container/' . $term->id();
+ // We don't want the redirect from the link so we can redirect the
+ // delete action.
+ unset($form['terms'][$key]['operations']['#links']['edit']['query']['destination']);
+ }
+ else {
+ $form['terms'][$key]['operations']['#links']['edit']['title'] = t('edit forum');
+ $form['terms'][$key]['operations']['#links']['edit']['href'] = 'admin/structure/forum/edit/forum/' . $term->id();
+ // We don't want the redirect from the link so we can redirect the
+ // delete action.
+ unset($form['terms'][$key]['operations']['#links']['edit']['query']['destination']);
+ }
+ }
+ }
+
+ // Remove the alphabetical reset.
+ unset($form['actions']['reset_alphabetical']);
+
+ // The form needs to have submit and validate handlers set explicitly.
+ $form['#submit'] = array('taxonomy_overview_terms_submit'); // Use the existing taxonomy overview submit handler.
+ $form['terms']['#empty'] = t('No containers or forums available. Add container or Add forum.', array('@container' => url('admin/structure/forum/add/container'), '@forum' => url('admin/structure/forum/add/forum')));
+ return $form;
+}
+
+/**
+ * Returns a select box for available parent terms.
+ *
+ * @param $tid
+ * ID of the term that is being added or edited.
+ * @param $title
+ * Title for the select box.
+ * @param $child_type
+ * Whether the child is a forum or a container.
+ *
+ * @return
+ * A select form element.
+ */
+function _forum_parent_select($tid, $title, $child_type) {
+
+ $parents = taxonomy_term_load_parents($tid);
+ if ($parents) {
+ $parent = array_shift($parents);
+ $parent = $parent->id();
+ }
+ else {
+ $parent = 0;
+ }
+
+ $vid = config('forum.settings')->get('vocabulary');
+ $children = taxonomy_get_tree($vid, $tid, NULL, TRUE);
+
+ // A term can't be the child of itself, nor of its children.
+ foreach ($children as $child) {
+ $exclude[] = $child->id();
+ }
+ $exclude[] = $tid;
+
+ $tree = taxonomy_get_tree($vid, 0, NULL, TRUE);
+ $options[0] = '<' . t('root') . '>';
+ if ($tree) {
+ foreach ($tree as $term) {
+ if (!in_array($term->id(), $exclude)) {
+ $options[$term->id()] = str_repeat(' -- ', $term->depth) . $term->label();
+ }
+ }
+ }
+ if ($child_type == 'container') {
+ $description = t('Containers are usually placed at the top (root) level, but may also be placed inside another container or forum.');
+ }
+ elseif ($child_type == 'forum') {
+ $description = t('Forums may be placed at the top (root) level, or inside another container or forum.');
+ }
+
+ return array('#type' => 'select', '#title' => $title, '#default_value' => $parent, '#options' => $options, '#description' => $description, '#required' => TRUE);
+}
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index 1d30fcb..0e05408 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -675,7 +675,6 @@ function template_preprocess_forum_list(&$variables) {
$row = 0;
// Sanitize each forum so that the template can safely print the data.
foreach ($variables['forums'] as $id => $forum) {
- $variables['forums'][$id]->description = filter_xss_admin($forum->description->value);
$variables['forums'][$id]->link = url("forum/" . $forum->id());
$variables['forums'][$id]->name = check_plain($forum->label());
$variables['forums'][$id]->is_container = !empty($forum->forum_container->value);
diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
index 81d8d82..c2c3bef 100644
--- a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
+++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
@@ -360,13 +360,11 @@ function editForumVocabulary() {
* The created taxonomy term data.
*/
function createForum($type, $parent = 0) {
- // Generate a random name/description.
+ // Generate a random name.
$name = $this->randomName(10);
- $description = $this->randomName(100);
$edit = array(
'name' => $name,
- 'description[value]' => $description,
'parent[0]' => $parent,
'weight' => '0',
);
@@ -384,7 +382,7 @@ function createForum($type, $parent = 0) {
);
// Verify forum.
- $term = db_query("SELECT * FROM {taxonomy_term_data} t WHERE t.vid = :vid AND t.name = :name AND t.description = :desc", array(':vid' => \Drupal::config('forum.settings')->get('vocabulary'), ':name' => $name, ':desc' => $description))->fetchAssoc();
+ $term = db_query("SELECT * FROM {taxonomy_term_data} t WHERE t.vid = :vid AND t.name = :name", array(':vid' => \Drupal::config('forum.settings')->get('vocabulary'), ':name' => $name))->fetchAssoc();
$this->assertTrue(!empty($term), 'The ' . $type . ' exists in the database');
// Verify forum hierarchy.
diff --git a/core/modules/forum/templates/forum-list.html.twig b/core/modules/forum/templates/forum-list.html.twig
index 5b41f6a..fa49dbe 100644
--- a/core/modules/forum/templates/forum-list.html.twig
+++ b/core/modules/forum/templates/forum-list.html.twig
@@ -15,8 +15,6 @@
* - icon_title: Text alternative for the forum icon.
* - name: The name of the forum.
* - link: The URL to link to this forum.
- * - description: The description field for the forum, containing:
- * - value: The descriptive text for the forum.
* - new_topics: A flag indicating if the forum contains unread posts.
* - new_url: A URL to the forum's unread posts.
* - new_text: Text for the above URL, which tells how many new posts.
@@ -59,9 +57,6 @@
{{ forum.icon_title }}
- {% if forum.description.value %}
- {{ forum.description.value }}
- {% endif %}
{% for i in 1..forum.depth if forum.depth > 0 %}{% endfor %}
{% if forum.is_container == false %}
diff --git a/core/modules/path/lib/Drupal/path/Tests/PathTaxonomyTermTest.php b/core/modules/path/lib/Drupal/path/Tests/PathTaxonomyTermTest.php
index c483d9e..fb448b3 100644
--- a/core/modules/path/lib/Drupal/path/Tests/PathTaxonomyTermTest.php
+++ b/core/modules/path/lib/Drupal/path/Tests/PathTaxonomyTermTest.php
@@ -48,10 +48,8 @@ function setUp() {
function testTermAlias() {
// Create a term in the default 'Tags' vocabulary with URL alias.
$vocabulary = entity_load('taxonomy_vocabulary', 'tags');
- $description = $this->randomName();
$edit = array(
'name' => $this->randomName(),
- 'description[value]' => $description,
'path[alias]' => $this->randomName(),
);
$this->drupalPostForm('admin/structure/taxonomy/manage/' . $vocabulary->id() . '/add', $edit, t('Save'));
@@ -59,7 +57,7 @@ function testTermAlias() {
// Confirm that the alias works.
$this->drupalGet($edit['path[alias]']);
- $this->assertText($description, 'Term can be accessed on URL alias.');
+ $this->assertText($edit['name'], 'Term can be accessed on URL alias.');
// Confirm the 'canonical' and 'shortlink' URLs.
$elements = $this->xpath("//link[contains(@rel, 'canonical') and contains(@href, '" . $edit['path[alias]'] . "')]");
@@ -74,11 +72,11 @@ function testTermAlias() {
// Confirm that the changed alias works.
$this->drupalGet($edit2['path[alias]']);
- $this->assertText($description, 'Term can be accessed on changed URL alias.');
+ $this->assertText($edit['name'], 'Term can be accessed on changed URL alias.');
// Confirm that the old alias no longer works.
$this->drupalGet($edit['path[alias]']);
- $this->assertNoText($description, 'Old URL alias has been removed after altering.');
+ $this->assertNoText($edit['name'], 'Old URL alias has been removed after altering.');
$this->assertResponse(404, 'Old URL alias returns 404.');
// Remove the term's URL alias.
@@ -88,7 +86,7 @@ function testTermAlias() {
// Confirm that the alias no longer works.
$this->drupalGet($edit2['path[alias]']);
- $this->assertNoText($description, 'Old URL alias has been removed after altering.');
+ $this->assertNoText($edit['name'], 'Old URL alias has been removed after altering.');
$this->assertResponse(404, 'Old URL alias returns 404.');
}
}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/TaxonomyUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/TaxonomyUpgradePathTest.php
new file mode 100644
index 0000000..ebe8ac8
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/TaxonomyUpgradePathTest.php
@@ -0,0 +1,62 @@
+ 'Taxonomy upgrade test',
+ 'description' => 'Taxonomy vocabulary and term upgrade tests.',
+ 'group' => 'Upgrade path',
+ );
+ }
+
+ public function setUp() {
+ $this->databaseDumpFiles = array(
+ drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.bare.standard_all.database.php.gz',
+ drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.taxonomy.database.php',
+ );
+ parent::setUp();
+ }
+
+ /**
+ * Tests expected role ID conversions after a successful upgrade.
+ */
+ public function testRoleUpgrade() {
+ $this->assertTrue($this->performUpgrade(), 'The upgrade was completed successfully.');
+
+ // Check the tags vocabulary.
+ $vocabulary = taxonomy_vocabulary_load('tags');
+ $this->assertEqual($vocabulary->label(), 'Tags');
+ $this->assertEqual($vocabulary->description, 'Use tags to group articles on similar topics into categories.');
+ $this->assertTrue($vocabulary->uuid());
+
+ // Load the two prepared terms and assert them.
+ $term1 = taxonomy_term_load(5);
+ $this->assertEqual($term1->label(), 'A tag');
+ $this->assertEqual($term1->vid->value, 'tags');
+ $this->assertEqual($term1->bundle(), 'tags');
+ $this->assertEqual($term1->taxonomy_term_description->value, 'Description of a tag');
+ $this->assertEqual($term1->taxonomy_term_description->format, 'plain_text');
+
+ $term2 = taxonomy_term_load(6);
+ $this->assertEqual($term2->label(), 'Another tag');
+ $this->assertEqual($term2->vid->value, 'tags');
+ $this->assertEqual($term2->bundle(), 'tags');
+ $this->assertEqual($term2->taxonomy_term_description->value, 'HTML Description');
+ $this->assertEqual($term2->taxonomy_term_description->format, 'filtered_html');
+ }
+
+}
diff --git a/core/modules/system/tests/upgrade/drupal-7.taxonomy.database.php b/core/modules/system/tests/upgrade/drupal-7.taxonomy.database.php
new file mode 100644
index 0000000..e22261c
--- /dev/null
+++ b/core/modules/system/tests/upgrade/drupal-7.taxonomy.database.php
@@ -0,0 +1,32 @@
+fields(array('tid', 'vid', 'name', 'description', 'format', 'weight'))
+ ->values(array(
+ 'tid' => 5,
+ 'vid' => 1,
+ 'name' => 'A tag',
+ 'description' => 'Description of a tag',
+ 'format' => 'plain_text',
+ 'weight' => 10,
+ ))
+ ->values(array(
+ 'tid' => 6,
+ 'vid' => 1,
+ 'name' => 'Another tag',
+ 'description' => 'HTML Description',
+ 'format' => 'filtered_html',
+ 'weight' => 20,
+ ))
+ ->execute();
diff --git a/core/modules/taxonomy/css/taxonomy.module.css b/core/modules/taxonomy/css/taxonomy.module.css
index 1f80d52..543666a 100644
--- a/core/modules/taxonomy/css/taxonomy.module.css
+++ b/core/modules/taxonomy/css/taxonomy.module.css
@@ -8,6 +8,3 @@
.taxonomy-term-divider-bottom {
border-top: 1px dotted #ccc;
}
-.taxonomy-term-description {
- margin: 5px 0 20px;
-}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php
new file mode 100644
index 0000000..884e07c
--- /dev/null
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php
@@ -0,0 +1,135 @@
+ array(Language::LANGCODE_DEFAULT => array(0 => array('value' => Language::LANGCODE_NOT_SPECIFIED))),
+ 'weight' => array(Language::LANGCODE_DEFAULT => array(0 => array('value' => 0))),
+ );
+
+ /**
+ * Implements Drupal\Core\Entity\EntityInterface::id().
+ */
+ public function id() {
+ return $this->get('tid')->value;
+ }
+
+ /**
+ * Overides \Drupal\Core\Entity\EntityNG::init().
+ */
+ protected function init() {
+ parent::init();
+ unset($this->tid);
+ unset($this->uuid);
+ unset($this->vid);
+ unset($this->name);
+ unset($this->weight);
+ unset($this->format);
+ unset($this->parent);
+ }
+}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
index 8821b09..72745d8 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
@@ -75,13 +75,6 @@ public function form(array $form, array &$form_state) {
'#weight' => -5,
);
- $form['description'] = array(
- '#type' => 'text_format',
- '#title' => $this->t('Description'),
- '#default_value' => $term->description->value,
- '#format' => $term->format->value,
- '#weight' => 0,
- );
$language_configuration = $this->moduleHandler->moduleExists('language') ? language_get_default_configuration('taxonomy_term', $vocabulary->id()) : FALSE;
$form['langcode'] = array(
'#type' => 'language_select',
@@ -179,12 +172,6 @@ public function buildEntity(array $form, array &$form_state) {
// Prevent leading and trailing spaces in term names.
$term->name->value = trim($term->name->value);
- // Convert text_format field into values expected by
- // \Drupal\Core\Entity\Entity::save() method.
- $description = $form_state['values']['description'];
- $term->description->value = $description['value'];
- $term->format->value = $description['format'];
-
// Assign parents with proper delta values starting from 0.
$term->parent = array_keys($form_state['values']['parent']);
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorageController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorageController.php
index 1a47334..3af6b2e 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorageController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorageController.php
@@ -82,4 +82,49 @@ public function updateTermHierarchy(EntityInterface $term) {
$query->execute();
}
+ /**
+ * {@inheritdoc}
+ */
+ public function baseFieldDefinitions() {
+ $properties['tid'] = array(
+ 'label' => t('Term ID'),
+ 'description' => t('The term ID.'),
+ 'type' => 'integer_field',
+ 'read-only' => TRUE,
+ );
+ $properties['uuid'] = array(
+ 'label' => t('UUID'),
+ 'description' => t('The term UUID.'),
+ 'type' => 'string_field',
+ 'read-only' => TRUE,
+ );
+ $properties['vid'] = array(
+ 'label' => t('Vocabulary ID'),
+ 'description' => t('The ID of the vocabulary to which the term is assigned.'),
+ 'type' => 'string_field',
+ );
+ $properties['langcode'] = array(
+ 'label' => t('Language code'),
+ 'description' => t('The term language code.'),
+ 'type' => 'language_field',
+ );
+ $properties['name'] = array(
+ 'label' => t('Name'),
+ 'description' => t('The term name.'),
+ 'type' => 'string_field',
+ );
+ $properties['weight'] = array(
+ 'label' => t('Weight'),
+ 'description' => t('The weight of this term in relation to other terms.'),
+ 'type' => 'integer_field',
+ );
+ $properties['parent'] = array(
+ 'label' => t('Term Parents'),
+ 'description' => t('The parents of this term.'),
+ 'type' => 'integer_field',
+ 'computed' => TRUE,
+ );
+ return $properties;
+ }
+
}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermViewBuilder.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermViewBuilder.php
index 6e91524..2d910dc 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermViewBuilder.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermViewBuilder.php
@@ -18,25 +18,7 @@ class TermViewBuilder extends EntityViewBuilder {
/**
* {@inheritdoc}
- */
- public function buildContent(array $entities, array $displays, $view_mode, $langcode = NULL) {
- parent::buildContent($entities, $displays, $view_mode, $langcode);
-
- foreach ($entities as $entity) {
- // Add the description if enabled.
- $display = $displays[$entity->bundle()];
- if (!empty($entity->description->value) && $display->getComponent('description')) {
- $entity->content['description'] = array(
- '#markup' => check_markup($entity->description->value, $entity->format->value, '', TRUE),
- '#prefix' => '',
- '#suffix' => '
',
- );
- }
- }
- }
-
- /**
- * {@inheritdoc}
+ * Overrides \Drupal\Core\Entity\EntityViewBuilder::getBuildDefaults().
*/
protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langcode) {
$return = parent::getBuildDefaults($entity, $view_mode, $langcode);
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTestBase.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTestBase.php
index 4ae4823..0e380ee 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTestBase.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTestBase.php
@@ -51,13 +51,8 @@ function createVocabulary() {
* Returns a new term with random properties in vocabulary $vid.
*/
function createTerm($vocabulary) {
- $filter_formats = filter_formats();
- $format = array_pop($filter_formats);
$term = entity_create('taxonomy_term', array(
'name' => $this->randomName(),
- 'description' => $this->randomName(),
- // Use the first available text format.
- 'format' => $format->format,
'vid' => $vocabulary->id(),
'langcode' => Language::LANGCODE_NOT_SPECIFIED,
));
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
index 26f04ad..e35c4e9 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
@@ -291,7 +291,6 @@ function testTermAutocompletion() {
function testTermInterface() {
$edit = array(
'name' => $this->randomName(12),
- 'description[value]' => $this->randomName(100),
);
// Explicitly set the parents field to 'root', to ensure that
// TermFormController::save() handles the invalid term ID correctly.
@@ -313,11 +312,9 @@ function testTermInterface() {
$this->clickLink(t('edit'));
$this->assertRaw($edit['name'], 'The randomly generated term name is present.');
- $this->assertText($edit['description[value]'], 'The randomly generated term description is present.');
$edit = array(
'name' => $this->randomName(14),
- 'description[value]' => $this->randomName(102),
);
// Edit the term.
@@ -335,15 +332,6 @@ function testTermInterface() {
// View the term and check that it is correct.
$this->drupalGet('taxonomy/term/' . $term->id());
$this->assertText($edit['name'], 'The randomly generated term name is present.');
- $this->assertText($edit['description[value]'], 'The randomly generated term description is present.');
-
- // Did this page request display a 'term-listing-heading'?
- $this->assertPattern('|class="taxonomy-term-description"|', 'Term page displayed the term description element.');
- // Check that it does NOT show a description when description is blank.
- $term->description = '';
- $term->save();
- $this->drupalGet('taxonomy/term/' . $term->id());
- $this->assertNoPattern('|class="taxonomy-term-description"|', 'Term page did not display the term description when description was blank.');
// Check that the term feed page is working.
$this->drupalGet('taxonomy/term/' . $term->id() . '/feed');
@@ -426,7 +414,6 @@ function testTermMultipleParentsInterface() {
// Add a new term with multiple parents.
$edit = array(
'name' => $this->randomName(12),
- 'description[value]' => $this->randomName(100),
'parent[]' => array(0, $parent->id()),
);
// Save the new term.
@@ -437,7 +424,6 @@ function testTermMultipleParentsInterface() {
$term = reset($terms);
$this->assertNotNull($term, 'Term found in database.');
$this->assertEqual($edit['name'], $term->label(), 'Term name was successfully saved.');
- $this->assertEqual($edit['description[value]'], $term->description->value, 'Term description was successfully saved.');
// Check that the parent tid is still there. The other parent () is
// not added by taxonomy_term_load_parents().
$parents = taxonomy_term_load_parents($term->id());
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
index be4ed53..5ceb4f0 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
@@ -88,7 +88,6 @@ function testTaxonomyTokenReplacement() {
$tests = array();
$tests['[term:tid]'] = $term1->id();
$tests['[term:name]'] = check_plain($term1->name->value);
- $tests['[term:description]'] = check_markup($term1->description->value, $term1->format->value);
$tests['[term:url]'] = url('taxonomy/term/' . $term1->id(), array('absolute' => TRUE));
$tests['[term:node-count]'] = 0;
$tests['[term:parent:name]'] = '[term:parent:name]';
@@ -103,7 +102,6 @@ function testTaxonomyTokenReplacement() {
$tests = array();
$tests['[term:tid]'] = $term2->id();
$tests['[term:name]'] = check_plain($term2->name->value);
- $tests['[term:description]'] = check_markup($term2->description->value, $term2->format->value);
$tests['[term:url]'] = url('taxonomy/term/' . $term2->id(), array('absolute' => TRUE));
$tests['[term:node-count]'] = 1;
$tests['[term:parent:name]'] = check_plain($term1->name->value);
@@ -121,7 +119,6 @@ function testTaxonomyTokenReplacement() {
// Generate and test unsanitized tokens.
$tests['[term:name]'] = $term2->name->value;
- $tests['[term:description]'] = $term2->description->value;
$tests['[term:parent:name]'] = $term1->name->value;
$tests['[term:vocabulary:name]'] = $this->vocabulary->name;
diff --git a/core/modules/taxonomy/taxonomy.install b/core/modules/taxonomy/taxonomy.install
index 845a44e..74a9126 100644
--- a/core/modules/taxonomy/taxonomy.install
+++ b/core/modules/taxonomy/taxonomy.install
@@ -7,6 +7,20 @@
use Drupal\Core\Entity\FieldableDatabaseStorageController;
use Drupal\field\Entity\Field;
+use Drupal\Component\Uuid\Uuid;
+use Drupal\Core\Language\Language;
+
+/**
+ * Implements hook_uninstall().
+ */
+function taxonomy_uninstall() {
+ // Remove taxonomy_term bundles.
+ $config_names = config_get_storage_names_with_prefix('taxonomy.vocabulary.');
+ foreach ($config_names as $config_name) {
+ $vid = substr($config_name, strlen('taxonomy.vocabulary.'));
+ entity_invoke_bundle_hook('delete', 'taxonomy_term', $vid);
+ }
+}
/**
* Implements hook_schema().
@@ -48,18 +62,6 @@ function taxonomy_schema() {
'default' => '',
'description' => 'The term name.',
),
- 'description' => array(
- 'type' => 'text',
- 'not null' => FALSE,
- 'size' => 'big',
- 'description' => 'A description of the term.',
- ),
- 'format' => array(
- 'type' => 'varchar',
- 'length' => 255,
- 'not null' => FALSE,
- 'description' => 'The filter format ID of the description.',
- ),
'weight' => array(
'type' => 'int',
'not null' => TRUE,
@@ -192,11 +194,16 @@ function taxonomy_field_schema($field) {
* Implements hook_update_dependencies().
*/
function taxonomy_update_dependencies() {
+
// Convert the 'tid' column of the taxonomy reference field to 'target_id'
// after the field tables have been reorganized.
$dependencies['taxonomy'][8007] = array(
'field' => 8006,
);
+ // Convert term description to a field before fields are convert to config.
+ $dependencies['field'][8003] = array(
+ 'taxonomy' => 8011,
+ );
return $dependencies;
}
@@ -396,3 +403,109 @@ function taxonomy_update_8008() {
);
db_add_field('taxonomy_term_data', 'changed', $spec);
}
+
+/**
+ * Create new field for term descriptions.
+ */
+function taxonomy_update_8009() {
+ $vocabularies = config_get_storage_names_with_prefix('taxonomy.vocabulary.');
+ if (count($vocabularies)) {
+ // Create a new term description field.
+ $field = array(
+ 'id' => 'taxonomy_term_description',
+ 'module' => 'text',
+ 'type' => 'text_long',
+ 'cardinality' => 1,
+ 'locked' => FALSE,
+ 'storage' => array(
+ 'type' => 'field_sql_storage',
+ 'settings' => array(),
+ ),
+ );
+ _update_8003_field_create_field($field);
+
+ // Create instances for existing vocabularies.
+ foreach ($vocabularies as $vocabulary) {
+ $vocabulary = substr($vocabulary, drupal_strlen('taxonomy.vocabulary.'));
+ // Attaches the description field to each bundle.
+ $instance = array(
+ 'id' => 'taxonomy_term_description',
+ 'label' => 'Description',
+ 'description' => '',
+ 'entity_type' => 'taxonomy_term',
+ 'bundle' => $vocabulary,
+ 'required' => FALSE,
+ 'settings' => array('text_processing' => 1),
+ 'widget' => array(
+ 'type' => 'text_textarea',
+ 'module' => 'text',
+ 'settings' => array(
+ 'rows' => 5,
+ ),
+ ),
+ 'display' => array(
+ 'default' => array(
+ 'label' => 'hidden',
+ 'type' => 'text_default',
+ ),
+ ),
+ );
+ _update_8003_field_create_instance($field, $instance);
+ }
+ }
+}
+
+/**
+ * Move term descriptions in {term_data}.description into new field.
+ */
+function taxonomy_update_8010(&$sandbox) {
+ if (!isset($sandbox['progress'])) {
+ $sandbox['progress'] = 0;
+ $sandbox['current_tid'] = 0;
+ $sandbox['max'] = db_query('SELECT COUNT(DISTINCT tid) FROM {taxonomy_term_data} WHERE vid > 0')->fetchField();
+ }
+
+ $terms = db_query_range('SELECT t.tid, t.description, t.format, t.vid FROM {taxonomy_term_data} t WHERE tid > :tid ORDER BY tid ASC', 0, 100, array(':tid' => $sandbox['current_tid']));
+
+ $data = db_insert('field_data_taxonomy_term_description')
+ ->fields(array('entity_type', 'bundle', 'entity_id', 'revision_id', 'langcode', 'delta', 'taxonomy_term_description_value', 'taxonomy_term_description_format'));
+ $revision = db_insert('field_revision_taxonomy_term_description')
+ ->fields(array('entity_type', 'bundle', 'entity_id', 'revision_id', 'langcode', 'delta', 'taxonomy_term_description_value', 'taxonomy_term_description_format'));
+ foreach ($terms as $term) {
+ $data->values(array(
+ 'entity_type' => 'taxonomy_term',
+ 'bundle' => $term->vid,
+ 'entity_id' => $term->tid,
+ 'revision_id' => $term->tid,
+ 'langcode' => Language::LANGCODE_NOT_SPECIFIED,
+ 'delta' => 0,
+ 'taxonomy_term_description_value' => $term->description,
+ 'taxonomy_term_description_format' => $term->format,
+ ));
+ $revision->fields(array(
+ 'entity_type' => 'taxonomy_term',
+ 'bundle' => $term->vid,
+ 'entity_id' => $term->tid,
+ 'revision_id' => $term->tid,
+ 'langcode' => Language::LANGCODE_NOT_SPECIFIED,
+ 'delta' => 0,
+ 'taxonomy_term_description_value' => $term->description,
+ 'taxonomy_term_description_format' => $term->format,
+ ));
+ $sandbox['progress']++;
+ $sandbox['current_tid'] = $term->tid;
+ }
+
+ $data->execute();
+ $revision->execute();
+
+ $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);
+}
+
+/**
+ * Remove {term_data}.description and {term_data}.format.
+ */
+function taxonomy_update_8011() {
+ db_drop_field('taxonomy_term_data', 'description');
+ db_drop_field('taxonomy_term_data', 'format');
+}
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index 9c89610..927ca62 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -145,18 +145,6 @@ function taxonomy_field_extra_fields() {
'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,
- ),
),
);
}
diff --git a/core/modules/taxonomy/taxonomy.pages.inc b/core/modules/taxonomy/taxonomy.pages.inc
index fb88184..d3574b3 100644
--- a/core/modules/taxonomy/taxonomy.pages.inc
+++ b/core/modules/taxonomy/taxonomy.pages.inc
@@ -62,9 +62,6 @@ function taxonomy_term_page(Term $term) {
function taxonomy_term_feed(Term $term) {
$channel['link'] = url('taxonomy/term/' . $term->id(), array('absolute' => TRUE));
$channel['title'] = \Drupal::config('system.site')->get('name') . ' - ' . $term->label();
- // Only display the description if we have a single term, to avoid clutter and confusion.
- // HTML will be removed from feed description.
- $channel['description'] = check_markup($term->description->value, $term->format->value, '', TRUE);
$nids = taxonomy_select_nodes($term->id(), FALSE, \Drupal::config('system.rss')->get('items.limit'));
return node_feed($nids, $channel);
diff --git a/core/modules/taxonomy/taxonomy.tokens.inc b/core/modules/taxonomy/taxonomy.tokens.inc
index ec94447..e2e1e41 100644
--- a/core/modules/taxonomy/taxonomy.tokens.inc
+++ b/core/modules/taxonomy/taxonomy.tokens.inc
@@ -29,10 +29,6 @@ function taxonomy_token_info() {
'name' => t("Name"),
'description' => t("The name of the taxonomy term."),
);
- $term['description'] = array(
- 'name' => t("Description"),
- 'description' => t("The optional description of the taxonomy term."),
- );
$term['node-count'] = array(
'name' => t("Node count"),
'description' => t("The number of nodes tagged with the taxonomy term."),
@@ -107,10 +103,6 @@ function taxonomy_tokens($type, $tokens, array $data = array(), array $options =
$replacements[$original] = $sanitize ? check_plain($term->name->value) : $term->name->value;
break;
- case 'description':
- $replacements[$original] = $sanitize ? check_markup($term->description->value, $term->format->value, '', TRUE) : $term->description->value;
- break;
-
case 'url':
$uri = $term->uri();
$replacements[$original] = url($uri['path'], array_merge($uri['options'], array('absolute' => TRUE)));
diff --git a/core/modules/taxonomy/taxonomy.views.inc b/core/modules/taxonomy/taxonomy.views.inc
index 001c125..53e5c37 100644
--- a/core/modules/taxonomy/taxonomy.views.inc
+++ b/core/modules/taxonomy/taxonomy.views.inc
@@ -129,20 +129,6 @@ function taxonomy_views_data() {
),
);
- // Term description
- $data['taxonomy_term_data']['description'] = array(
- 'title' => t('Term description'),
- 'help' => t('The description associated with a taxonomy term.'),
- 'field' => array(
- 'id' => 'markup',
- 'format' => array('field' => 'format'),
- 'click sortable' => FALSE,
- ),
- 'filter' => array(
- 'id' => 'string',
- ),
- );
-
// Term vocabulary
$data['taxonomy_term_data']['vid'] = array(
'title' => t('Vocabulary'),
diff --git a/core/modules/taxonomy/templates/taxonomy-term.html.twig b/core/modules/taxonomy/templates/taxonomy-term.html.twig
index a3986fa..1113de5 100644
--- a/core/modules/taxonomy/templates/taxonomy-term.html.twig
+++ b/core/modules/taxonomy/templates/taxonomy-term.html.twig
@@ -6,12 +6,12 @@
* Available variables:
* - url: URL of the current term.
* - name: Name of the current term.
- * - content: Items for the content of the term (fields and description).
+ * - content: Items for the content of the term fields.
* Use 'content' to print them all, or print a subset such as
- * 'content.description'. Use the following code to temporarily suppress the
+ * 'content.taxonomy_term_description'. Use the following code to temporarily suppress the
* printing of a given element:
* @code
- * {% hide(content.description) %}
+ * {% hide(content.taxonomy_term_description) %}
* @endcode
* - attributes: HTML attributes for the wrapper. The 'class' attribute
* contains the following classes by default:
diff --git a/core/modules/taxonomy/templates/taxonomy-term.tpl.php b/core/modules/taxonomy/templates/taxonomy-term.tpl.php
new file mode 100644
index 0000000..d230a50
--- /dev/null
+++ b/core/modules/taxonomy/templates/taxonomy-term.tpl.php
@@ -0,0 +1,48 @@
+
+>
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index 0aa4d17..e127a83 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -343,6 +343,11 @@ function user_update_dependencies() {
$dependencies['user'][8011] = array(
'field' => 8006,
);
+ // Make sure that the uuid column is added to {file_managed} before the
+ // user picture default image is added.
+ $dependencies['user'][8011] = array(
+ 'system' => 8015,
+ );
return $dependencies;
}
diff --git a/core/profiles/standard/config/field.field.taxonomy_term_description.yml b/core/profiles/standard/config/field.field.taxonomy_term_description.yml
new file mode 100644
index 0000000..379861d
--- /dev/null
+++ b/core/profiles/standard/config/field.field.taxonomy_term_description.yml
@@ -0,0 +1,19 @@
+id: taxonomy_term.taxonomy_term_description
+name: taxonomy_term_description
+entity_type: taxonomy_term
+type: text_long
+module: text
+active: '1'
+settings: { }
+storage:
+ type: field_sql_storage
+ settings: { }
+ module: field_sql_storage
+ active: '1'
+locked: '0'
+cardinality: '1'
+translatable: '0'
+entity_types: { }
+indexes: { }
+status: 1
+langcode: und
diff --git a/core/profiles/standard/config/field.instance.taxonomy_term.tags.taxonomy_term_description.yml b/core/profiles/standard/config/field.instance.taxonomy_term.tags.taxonomy_term_description.yml
new file mode 100644
index 0000000..94afbf0
--- /dev/null
+++ b/core/profiles/standard/config/field.instance.taxonomy_term.tags.taxonomy_term_description.yml
@@ -0,0 +1,22 @@
+id: taxonomy_term.tags.taxonomy_term_description
+field_name: taxonomy_term_description
+entity_type: taxonomy_term
+bundle: tags
+label: Description
+description: ''
+required: false
+default_value: ''
+default_value_function: ''
+settings:
+ text_processing: '1'
+ user_register_form: '0'
+widget:
+ weight: '-4'
+ type: text_textarea
+ settings:
+ rows: '5'
+ placeholder: ''
+ module: text
+field_type: text_long
+status: 1
+langcode: und
diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install
index 5aa1dd7..082a619 100644
--- a/core/profiles/standard/standard.install
+++ b/core/profiles/standard/standard.install
@@ -86,4 +86,11 @@ function standard_install() {
theme_enable(array('seven'));
\Drupal::config('system.theme')->set('admin', 'seven')->save();
\Drupal::config('node.settings')->set('use_admin_theme', '1')->save();
+
+ // Configure the widget for the taxonomy term description field.
+ entity_get_form_display('taxonomy_term', 'tags', 'default')
+ ->setComponent('taxonomy_term_description', array(
+ 'type' => 'text_textarea',
+ ))
+ ->save();
}
diff --git a/core/scripts/generate-d7-content.sh b/core/scripts/generate-d7-content.sh
index bd24300..b007505 100644
--- a/core/scripts/generate-d7-content.sh
+++ b/core/scripts/generate-d7-content.sh
@@ -141,6 +141,7 @@
for ($j = 0; $j < $vocabulary->hierarchy + 1; $j++) {
++$term_id;
$term = entity_create('taxonomy_term', array(
+ 'vid' => $voc_id,
'vocabulary_machine_name' => $vocabulary->machine_name,
// For multiple parent vocabularies, omit the t0-t1 relation, otherwise
// every parent in the vocabulary is a parent.