diff --git a/core/modules/forum/forum.admin.inc b/core/modules/forum/forum.admin.inc
index 2a8a50d..b3accfb 100644
--- a/core/modules/forum/forum.admin.inc
+++ b/core/modules/forum/forum.admin.inc
@@ -8,209 +8,6 @@
use Drupal\taxonomy\Plugin\Core\Entity\Term;
/**
- * Page callback: Returns a form for creating a new forum or container.
- *
- * @param $type
- * What is being added. Possible values are 'forum' and 'container'.
- * @param \Drupal\taxonomy\Plugin\Core\Entity\Term $term
- * (optional) A forum or container term to be edited. Defaults to NULL.
- *
- * @return
- * A form for creating a new forum or container.
- *
- * @see forum_menu()
- */
-function forum_form_main($type, Term $term = NULL) {
- if (!$term) {
- $term = entity_create('taxonomy_term', array('vid' => 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['description'] = array('#type' => 'textarea',
- '#title' => t('Description'),
- '#default_value' => $term->description->value,
- '#description' => t('Description and guidelines for discussions within this forum.'),
- );
- $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['description'] = array(
- '#type' => 'textarea',
- '#title' => t('Description'),
- '#default_value' => $term->description->value,
- '#description' => t('Description and guidelines for forums within this container.')
- );
- $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
@@ -257,55 +54,3 @@ function forum_overview($form, &$form_state) {
$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 c06edde..f4e9035 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -120,21 +120,13 @@ function forum_menu() {
);
$items['admin/structure/forum/add/container'] = array(
'title' => 'Add container',
- 'page callback' => 'forum_form_main',
- 'page arguments' => array('container'),
- 'access arguments' => array('administer forums'),
- 'type' => MENU_LOCAL_ACTION,
- 'parent' => 'admin/structure/forum',
- 'file' => 'forum.admin.inc',
+ 'tab_parent' => 'admin/structure/forum',
+ 'route_name' => 'forum_add_container',
);
$items['admin/structure/forum/add/forum'] = array(
+ 'tab_parent' => 'admin/structure/forum',
'title' => 'Add forum',
- 'page callback' => 'forum_form_main',
- 'page arguments' => array('forum'),
- 'access arguments' => array('administer forums'),
- 'type' => MENU_LOCAL_ACTION,
- 'parent' => 'admin/structure/forum',
- 'file' => 'forum.admin.inc',
+ 'route_name' => 'forum_add_forum',
);
$items['admin/structure/forum/settings'] = array(
'title' => 'Settings',
@@ -145,17 +137,11 @@ function forum_menu() {
);
$items['admin/structure/forum/edit/container/%taxonomy_term'] = array(
'title' => 'Edit container',
- 'page callback' => 'forum_form_main',
- 'page arguments' => array('container', 5),
- 'access arguments' => array('administer forums'),
- 'file' => 'forum.admin.inc',
+ 'route_name' => 'forum_edit_container',
);
$items['admin/structure/forum/edit/forum/%taxonomy_term'] = array(
'title' => 'Edit forum',
- 'page callback' => 'forum_form_main',
- 'page arguments' => array('forum', 5),
- 'access arguments' => array('administer forums'),
- 'file' => 'forum.admin.inc',
+ 'route_name' => 'forum_edit_forum',
);
return $items;
}
@@ -226,6 +212,15 @@ function forum_menu_local_tasks_alter(&$data, $router_item, $root_path) {
}
/**
+ * Implements hook_entity_info().
+ */
+function forum_entity_info(&$info) {
+ // Register forum specific form controllers.
+ $info['taxonomy_term']['controllers']['form']['forum'] = 'Drupal\forum\Form\ForumFormController';
+ $info['taxonomy_term']['controllers']['form']['container'] = 'Drupal\forum\Form\ContainerFormController';
+}
+
+/**
* Implements hook_entity_bundle_info_alter().
*/
function forum_entity_bundle_info_alter(&$bundles) {
@@ -238,7 +233,7 @@ function forum_entity_bundle_info_alter(&$bundles) {
}
/**
- * Entity URI callback used in forum_entity_info_alter().
+ * Entity URI callback used in forum_entity_bundle_info_alter().
*/
function forum_uri($forum) {
return array(
@@ -1338,3 +1333,19 @@ function forum_rdf_mapping() {
),
);
}
+
+/**
+ * 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']);
+}
diff --git a/core/modules/forum/forum.routing.yml b/core/modules/forum/forum.routing.yml
index f7d90f8..fe816f0 100644
--- a/core/modules/forum/forum.routing.yml
+++ b/core/modules/forum/forum.routing.yml
@@ -10,3 +10,27 @@ forum_settings:
_form: '\Drupal\forum\ForumSettingsForm'
requirements:
_permission: 'administer forums'
+forum_add_container:
+ pattern: 'admin/structure/forum/add/container'
+ defaults:
+ _content: 'Drupal\forum\Controller\ForumController::addContainer'
+ requirements:
+ _permission: 'administer forums'
+forum_add_forum:
+ pattern: 'admin/structure/forum/add/forum'
+ defaults:
+ _content: 'Drupal\forum\Controller\ForumController::addForum'
+ requirements:
+ _permission: 'administer forums'
+forum_edit_container:
+ pattern: 'admin/structure/forum/edit/container/{taxonomy_term}'
+ defaults:
+ _entity_form: 'taxonomy_term.container'
+ requirements:
+ _permission: 'administer forums'
+forum_edit_forum:
+ pattern: 'admin/structure/forum/edit/forum/{taxonomy_term}'
+ defaults:
+ _entity_form: 'taxonomy_term.forum'
+ requirements:
+ _permission: 'administer forums'
diff --git a/core/modules/forum/lib/Drupal/forum/Controller/ForumController.php b/core/modules/forum/lib/Drupal/forum/Controller/ForumController.php
new file mode 100644
index 0000000..51747fd
--- /dev/null
+++ b/core/modules/forum/lib/Drupal/forum/Controller/ForumController.php
@@ -0,0 +1,97 @@
+get('plugin.manager.entity'),
+ $container->get('config.factory'),
+ $container->get('plugin.manager.entity')->getStorageController('taxonomy_term')
+ );
+ }
+
+ /**
+ * Constructs a ForumController object.
+ *
+ * @param \Drupal\Core\Entity\EntityManager $entity_manager
+ * The entity manager service.
+ * @param \Drupal\Core\Config\ConfigFactory $config_factory
+ * The factory for configuration objects.
+ * @param \Drupal\taxonomy\TermStorageControllerInterface $storage_controller
+ * The term storage controller.
+ */
+ public function __construct(EntityManager $entity_manager, ConfigFactory $config_factory, TermStorageControllerInterface $storage_controller) {
+ $this->entityManager = $entity_manager;
+ $this->config = $config_factory->get('forum.settings');
+ $this->storageController = $storage_controller;
+ }
+
+ /**
+ * Returns add forum entity form.
+ *
+ * @return array
+ * Render array for the add form.
+ */
+ public function addForum() {
+ $vid = $this->config->get('vocabulary');
+ $taxonomy_term = $this->storageController->create(array(
+ 'vid' => $vid,
+ ));
+ return $this->entityManager->getForm($taxonomy_term, 'forum');
+ }
+
+ /**
+ * Returns add container entity form.
+ *
+ * @return array
+ * Render array for the add form.
+ */
+ public function addContainer() {
+ $vid = $this->config->get('vocabulary');
+ $taxonomy_term = $this->storageController->create(array(
+ 'vid' => $vid,
+ ));
+ return $this->entityManager->getForm($taxonomy_term, 'container');
+ }
+
+}
diff --git a/core/modules/forum/lib/Drupal/forum/Form/ContainerFormController.php b/core/modules/forum/lib/Drupal/forum/Form/ContainerFormController.php
new file mode 100644
index 0000000..a40c83b
--- /dev/null
+++ b/core/modules/forum/lib/Drupal/forum/Form/ContainerFormController.php
@@ -0,0 +1,54 @@
+entity;
+ // Build the bulk of the form from the parent forum form.
+ $form = parent::form($form, $form_state, $taxonomy_term);
+
+ // Set the title and description of the name field.
+ $form['name']['#title'] = t('Container name');
+ $form['name']['#description'] = t('Short but meaningful name for this collection of related forums.');
+
+ // Alternate description for the container parent.
+ $form['parent'][0]['#description'] = t('Containers are usually placed at the top (root) level, but may also be placed inside another container or forum.');
+ $this->forumFormType = t('forum container');
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save(array $form, array &$form_state) {
+ $is_new = $this->entity->isNew();
+ $term = parent::save($form, $form_state);
+ if ($is_new) {
+ // Update config item to track the container terms.
+ $containers = $this->config->get('containers');
+ $containers[] = $term->id();
+ $this->config->set('containers', $containers)->save();
+ }
+ }
+
+}
diff --git a/core/modules/forum/lib/Drupal/forum/Form/ForumFormController.php b/core/modules/forum/lib/Drupal/forum/Form/ForumFormController.php
new file mode 100644
index 0000000..ea985ee
--- /dev/null
+++ b/core/modules/forum/lib/Drupal/forum/Form/ForumFormController.php
@@ -0,0 +1,228 @@
+config = $config_factory->get('forum.settings');
+ $this->request = $request;
+ $this->storageController = $storage_controller;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info, $operation = NULL) {
+ return new static(
+ $operation,
+ $container->get('config.factory'),
+ $container->get('request'),
+ $container->get('plugin.manager.entity')->getStorageController('taxonomy_term')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function form(array $form, array &$form_state) {
+ $taxonomy_term = $this->entity;
+ // Build the bulk of the form from the parent taxonomy term form.
+ $form = parent::form($form, $form_state, $taxonomy_term);
+
+ // Set the title and description of the name field.
+ $form['name']['#title'] = t('Forum name');
+ $form['name']['#description'] = t('Short but meaningful name for this collection of threaded discussions.');
+
+ // Change the description.
+ $form['description']['#description'] = t('Description and guidelines for discussions within this forum.');
+
+ // Re-use the weight field.
+ $form['weight'] = $form['relations']['weight'];
+
+ // Remove the remaining relations fields.
+ unset($form['relations']);
+
+ // Our parent field is different to the taxonomy term.
+ $form['parent']['#tree'] = TRUE;
+ $form['parent'][0] = $this->forumParentSelect($taxonomy_term->id(), t('Parent'));
+
+ $form['#theme'] = 'forum_form';
+ $this->forumFormType = t('forum');
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildEntity(array $form, array &$form_state) {
+ $term = parent::buildEntity($form, $form_state);
+
+ // Assign parents from forum parent select field.
+ $term->parent = array($form_state['values']['parent'][0]);
+
+ return $term;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save(array $form, array &$form_state) {
+ $term = $this->entity;
+
+ $status = $this->storageController->save($term);
+ switch ($status) {
+ case SAVED_NEW:
+ drupal_set_message(t('Created new @type %term.', array('%term' => $term->label(), '@type' => $this->forumFormType)));
+ watchdog('forum', 'Created new @type %term.', array('%term' => $term->label(), '@type' => $this->forumFormType), WATCHDOG_NOTICE, l(t('edit'), 'admin/structure/forum/edit/' . $this->urlStub . '/' . $term->id()));
+ $form_state['values']['tid'] = $term->id();
+ break;
+
+ case SAVED_UPDATED:
+ drupal_set_message(t('The @type %term has been updated.', array('%term' => $term->label(), '@type' => $this->forumFormType)));
+ watchdog('taxonomy', 'Updated @type %term.', array('%term' => $term->label(), '@type' => $this->forumFormType), WATCHDOG_NOTICE, l(t('edit'), 'admin/structure/forum/edit/' . $this->urlStub . '/' . $term->id()));
+ // Clear the page and block caches to avoid stale data.
+ Cache::invalidateTags(array('content' => TRUE));
+ break;
+ }
+
+ $form_state['redirect'] = 'admin/structure/forum';
+ return $term;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete(array $form, array &$form_state) {
+ $destination = array();
+ if ($this->request->query->get('destination')) {
+ $destination = drupal_get_destination();
+ $this->request->query->remove('destination');
+ }
+ $term = $this->getEntity($form_state);
+ $form_state['redirect'] = array(
+ 'admin/structure/forum/delete/forum/' . $term->id(),
+ array('query' => $destination)
+ );
+ }
+
+ /**
+ * Returns a select box for available parent terms.
+ *
+ * @param int $tid
+ * ID of the term that is being added or edited.
+ * @param string $title
+ * Title for the select box.
+ *
+ * @return array
+ * A select form element.
+ */
+ protected function forumParentSelect($tid, $title) {
+ // @todo Inject a taxonomy service when one exists.
+ $parents = taxonomy_term_load_parents($tid);
+ if ($parents) {
+ $parent = array_shift($parents);
+ $parent = $parent->id();
+ }
+ else {
+ $parent = 0;
+ }
+
+ $vid = $this->config->get('vocabulary');
+ // @todo Inject a taxonomy service when one exists.
+ $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->tid;
+ }
+ $exclude[] = $tid;
+
+ // @todo Inject a taxonomy service when one exists.
+ $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();
+ }
+ }
+ }
+
+ $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/lib/Drupal/forum/Tests/ForumTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
index c28b1dc..7acb9d2 100644
--- a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
+++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
@@ -388,7 +388,7 @@ function createForum($type, $parent = 0) {
$edit = array(
'name' => $name,
- 'description' => $description,
+ 'description[value]' => $description,
'parent[0]' => $parent,
'weight' => '0',
);