diff --git a/core/lib/Drupal/Core/Entity/EntityConfirmFormBase.php b/core/lib/Drupal/Core/Entity/EntityConfirmFormBase.php index 565514d..7cd6ea7 100644 --- a/core/lib/Drupal/Core/Entity/EntityConfirmFormBase.php +++ b/core/lib/Drupal/Core/Entity/EntityConfirmFormBase.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Entity; use Drupal\Component\Utility\Url; +use Drupal\Core\Form\ConfirmFormHelper; use Drupal\Core\Form\ConfirmFormInterface; use Symfony\Component\HttpFoundation\Request; @@ -85,25 +86,21 @@ protected function actions(array $form, array &$form_state) { $actions['submit']['#value'] = $this->getConfirmText(); unset($actions['delete']); - $path = $this->getCancelPath(); // Prepare cancel link. - $query = $this->getRequest()->query; - if ($query->has('destination')) { - $options = Url::parse($query->get('destination')); - } - elseif (is_array($path)) { - $options = $path; - } - else { - $options = array('path' => $path); - } - $actions['cancel'] = array( - '#type' => 'link', - '#title' => $this->getCancelText(), - '#href' => $options['path'], - '#options' => $options, - ); + $actions['cancel'] = ConfirmFormHelper::buildCancelLink($this, $this->getRequest()); return $actions; } + /** + * {@inheritdoc} + */ + public function getCancelPath() { + } + + /** + * {@inheritdoc} + */ + public function getCancelRoute() { + } + } diff --git a/core/lib/Drupal/Core/Entity/EntityNGConfirmFormBase.php b/core/lib/Drupal/Core/Entity/EntityNGConfirmFormBase.php index 742e379..8b4528f 100644 --- a/core/lib/Drupal/Core/Entity/EntityNGConfirmFormBase.php +++ b/core/lib/Drupal/Core/Entity/EntityNGConfirmFormBase.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Entity; use Drupal\Component\Utility\Url; +use Drupal\Core\Form\ConfirmFormHelper; use Drupal\Core\Form\ConfirmFormInterface; /** @@ -92,25 +93,22 @@ protected function actions(array $form, array &$form_state) { $actions['submit']['#value'] = $this->getConfirmText(); unset($actions['delete']); - $path = $this->getCancelPath(); // Prepare cancel link. - $query = $this->getRequest()->query; - if ($query->has('destination')) { - $options = Url::parse($query->get('destination')); - } - elseif (is_array($path)) { - $options = $path; - } - else { - $options = array('path' => $path); - } - $actions['cancel'] = array( - '#type' => 'link', - '#title' => $this->getCancelText(), - '#href' => $options['path'], - '#options' => $options, - ); + $actions['cancel'] = ConfirmFormHelper::buildCancelLink($this, $this->getRequest()); + return $actions; } + /** + * {@inheritdoc} + */ + public function getCancelPath() { + } + + /** + * {@inheritdoc} + */ + public function getCancelRoute() { + } + } diff --git a/core/lib/Drupal/Core/Form/ConfirmFormBase.php b/core/lib/Drupal/Core/Form/ConfirmFormBase.php index 89e3ab7..36ace9a 100644 --- a/core/lib/Drupal/Core/Form/ConfirmFormBase.php +++ b/core/lib/Drupal/Core/Form/ConfirmFormBase.php @@ -46,19 +46,6 @@ public function getFormName() { * {@inheritdoc} */ public function buildForm(array $form, array &$form_state) { - $path = $this->getCancelPath(); - // Prepare cancel link. - $query = $this->getRequest()->query; - if ($query->has('destination')) { - $options = Url::parse($query->get('destination')); - } - elseif (is_array($path)) { - $options = $path; - } - else { - $options = array('path' => $path); - } - drupal_set_title($this->getQuestion(), PASS_THROUGH); $form['#attributes']['class'][] = 'confirmation'; @@ -70,12 +57,9 @@ public function buildForm(array $form, array &$form_state) { '#type' => 'submit', '#value' => $this->getConfirmText(), ); - $form['actions']['cancel'] = array( - '#type' => 'link', - '#title' => $this->getCancelText(), - '#href' => $options['path'], - '#options' => $options, - ); + + $form['actions']['cancel'] = ConfirmFormHelper::buildCancelLink($this, $this->getRequest()); + // By default, render the form using theme_confirm_form(). if (!isset($form['#theme'])) { $form['#theme'] = 'confirm_form'; @@ -83,4 +67,16 @@ public function buildForm(array $form, array &$form_state) { return $form; } + /** + * {@inheritdoc} + */ + public function getCancelPath() { + } + + /** + * {@inheritdoc} + */ + public function getCancelRoute() { + } + } diff --git a/core/lib/Drupal/Core/Form/ConfirmFormHelper.php b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php new file mode 100644 index 0000000..73d0391 --- /dev/null +++ b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php @@ -0,0 +1,83 @@ +query; + // If a destination is specified, that serves as the cancel link. + if ($query->has('destination')) { + $options = Url::parse($query->get('destination')); + $link = array( + '#href' => $options['path'], + '#options' => $options, + ); + } + // Check for a route-based cancel link. + elseif ($route = $form->getCancelRoute()) { + if (empty($route['name'])) { + throw new \UnexpectedValueException(String::format('Missing route name in !class::getCancelRoute().', array('!class' => get_class($form)))); + } + // Ensure there is something to pass as the params and options. + $route += array( + 'parameters' => array(), + 'options' => array(), + ); + $link = array( + '#route_name' => $route['name'], + '#route_parameters' => $route['parameters'], + '#options' => $route['options'], + ); + } + // Check for a path-based cancel link. + // @todo Remove when all forms use route-based cancel links. + else { + $path = $form->getCancelPath(); + if (is_array($path)) { + $link = array( + '#href' => $path['path'], + '#options' => $path, + ); + } + else { + $link = array( + '#href' => $path, + ); + } + } + + $link['#type'] = 'link'; + $link['#title'] = $form->getCancelText(); + return $link; + } + +} diff --git a/core/lib/Drupal/Core/Form/ConfirmFormInterface.php b/core/lib/Drupal/Core/Form/ConfirmFormInterface.php index 5c34f9a..51b8528 100644 --- a/core/lib/Drupal/Core/Form/ConfirmFormInterface.php +++ b/core/lib/Drupal/Core/Form/ConfirmFormInterface.php @@ -30,10 +30,26 @@ public function getQuestion(); * passed as the $options parameter to l(). * If the 'destination' query parameter is set in the URL when viewing a * confirmation form, that value will be used instead of this path. + * + * @deprecated Use self::getCancelRoute() instead. */ public function getCancelPath(); /** + * Returns the route to go to if the user cancels the action. + * + * @return array + * An associative array with the following keys: + * - name: The name of the route. + * - parameters: (optional) An associative array of parameter names and + * values. + * - options: (optional) An associative array of additional options. See + * \Drupal\Core\Routing\UrlGeneratorInterface::generateFromRoute() for + * comprehensive documentation. + */ + public function getCancelRoute(); + + /** * Returns additional text to display as a description. * * @return string diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Form/VocabularyDeleteForm.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Form/VocabularyDeleteForm.php index 7ec0aa7..a0cb3ae 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Form/VocabularyDeleteForm.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Form/VocabularyDeleteForm.php @@ -32,8 +32,10 @@ public function getQuestion() { /** * {@inheritdoc} */ - public function getCancelPath() { - return 'admin/structure/taxonomy'; + public function getCancelRoute() { + return array( + 'name' => 'taxonomy_vocabulary_list', + ); } /** diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Form/VocabularyResetForm.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Form/VocabularyResetForm.php index 4f0740f..7f7bc5c 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Form/VocabularyResetForm.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Form/VocabularyResetForm.php @@ -56,8 +56,13 @@ public function getQuestion() { /** * {@inheritdoc} */ - public function getCancelPath() { - return 'admin/structure/taxonomy/manage/' . $this->entity->id(); + public function getCancelRoute() { + return array( + 'name' => 'taxonomy_overview_terms', + 'parameters' => array( + 'taxonomy_vocabulary' => $this->entity->id(), + ), + ); } /** diff --git a/core/tests/Drupal/Tests/Core/Form/ConfirmFormHelperTest.php b/core/tests/Drupal/Tests/Core/Form/ConfirmFormHelperTest.php new file mode 100644 index 0000000..07950de --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Form/ConfirmFormHelperTest.php @@ -0,0 +1,138 @@ + 'Confirm form helper test', + 'description' => 'Tests the confirm form helper class.', + 'group' => 'Form API', + ); + } + + /** + * Tests the cancel link title. + */ + public function testCancelLinkTitle() { + $cancel_text = 'Cancel text'; + $form = $this->getMock('Drupal\Core\Form\ConfirmFormInterface'); + $form->expects($this->any()) + ->method('getCancelText') + ->will($this->returnValue($cancel_text)); + + $link = ConfirmFormHelper::buildCancelLink($form, new Request()); + $this->assertSame($cancel_text, $link['#title']); + } + + /** + * Tests a cancel link path as an array. + */ + public function testCancelLinkArray() { + $cancel_array = array( + 'path' => 'foo/bar', + 'query' => array( + 'destination' => 'baz', + ), + ); + $form = $this->getMock('Drupal\Core\Form\ConfirmFormInterface'); + $form->expects($this->any()) + ->method('getCancelPath') + ->will($this->returnValue($cancel_array)); + $link = ConfirmFormHelper::buildCancelLink($form, new Request()); + $this->assertSame($cancel_array['path'], $link['#href']); + $this->assertSame($cancel_array['query'], $link['#options']['query']); + } + + /** + * Tests a cancel link path. + */ + public function testCancelLinkPath() { + $cancel_path = 'foo/bar'; + $form = $this->getMock('Drupal\Core\Form\ConfirmFormInterface'); + $form->expects($this->any()) + ->method('getCancelPath') + ->will($this->returnValue($cancel_path)); + $link = ConfirmFormHelper::buildCancelLink($form, new Request()); + $this->assertSame($cancel_path, $link['#href']); + } + + /** + * Tests a cancel link route. + */ + public function testCancelLinkRoute() { + $cancel_route = array( + 'name' => 'foo_bar', + ); + $form = $this->getMock('Drupal\Core\Form\ConfirmFormInterface'); + $form->expects($this->any()) + ->method('getCancelRoute') + ->will($this->returnValue($cancel_route)); + $link = ConfirmFormHelper::buildCancelLink($form, new Request()); + $this->assertSame($cancel_route['name'], $link['#route_name']); + } + + /** + * Tests a cancel link route with parameters. + */ + public function testCancelLinkRouteWithParams() { + $cancel_route = array( + 'name' => 'foo_bar/{baz}', + 'parameters' => array( + 'baz' => 'banana', + ), + 'options' => array( + 'html' => TRUE, + ), + ); + $form = $this->getMock('Drupal\Core\Form\ConfirmFormInterface'); + $form->expects($this->any()) + ->method('getCancelRoute') + ->will($this->returnValue($cancel_route)); + $link = ConfirmFormHelper::buildCancelLink($form, new Request()); + $this->assertSame($cancel_route['name'], $link['#route_name']); + $this->assertSame($cancel_route['parameters'], $link['#route_parameters']); + $this->assertSame($cancel_route['options'], $link['#options']); + } + + /** + * Tests an invalid cancel link route. + * + * @expectedException \UnexpectedValueException + */ + public function testCancelLinkInvalidRoute() { + $form = $this->getMock('Drupal\Core\Form\ConfirmFormInterface'); + $form->expects($this->any()) + ->method('getCancelRoute') + ->will($this->returnValue(array('invalid' => 'foo_bar'))); + ConfirmFormHelper::buildCancelLink($form, new Request()); + } + + /** + * Tests a cancel link provided by the destination. + */ + public function testCancelLinkDestination() { + $query = array('destination' => 'baz'); + $form = $this->getMock('Drupal\Core\Form\ConfirmFormInterface'); + $link = ConfirmFormHelper::buildCancelLink($form, new Request($query)); + $this->assertSame($query['destination'], $link['#href']); + } + +}