Commit 750a1d84 authored by alexpott's avatar alexpott

Issue #216064 by Xano, idflood, drifter, Artusamak, ygerasimov, sun,...

Issue #216064 by Xano, idflood, drifter, Artusamak, ygerasimov, sun, ParisLiakos, Cottser, TravisCarden, marcingy, floretan, catch, tedbow: Entity form "Delete" button triggers server-side + HTML5 form validation; change "Delete" button to a link.
parent 93e77491
...@@ -189,7 +189,6 @@ protected function actionsElement(array $form, array &$form_state) { ...@@ -189,7 +189,6 @@ protected function actionsElement(array $form, array &$form_state) {
$count = 0; $count = 0;
foreach (Element::children($element) as $action) { foreach (Element::children($element) as $action) {
$element[$action] += array( $element[$action] += array(
'#type' => 'submit',
'#weight' => ++$count * 5, '#weight' => ++$count * 5,
); );
} }
...@@ -203,30 +202,42 @@ protected function actionsElement(array $form, array &$form_state) { ...@@ -203,30 +202,42 @@ protected function actionsElement(array $form, array &$form_state) {
/** /**
* Returns an array of supported actions for the current entity form. * Returns an array of supported actions for the current entity form.
*
* @todo Consider introducing a 'preview' action here, since it is used by
* many entity types.
*/ */
protected function actions(array $form, array &$form_state) { protected function actions(array $form, array &$form_state) {
return array( // @todo Rename the action key from submit to save.
// @todo Rename the action key from submit to save. $actions['submit'] = array(
'submit' => array( '#type' => 'submit',
'#value' => $this->t('Save'), '#value' => $this->t('Save'),
'#validate' => array( '#validate' => array(
array($this, 'validate'), array($this, 'validate'),
),
'#submit' => array(
array($this, 'submit'),
array($this, 'save'),
),
), ),
'delete' => array( '#submit' => array(
'#value' => $this->t('Delete'), array($this, 'submit'),
// No need to validate the form when deleting the entity. array($this, 'save'),
'#submit' => array(
array($this, 'delete'),
),
), ),
// @todo Consider introducing a 'preview' action here, since it is used by
// many entity types.
); );
if (!$this->entity->isNew() && $this->entity->hasLinkTemplate('delete-form')) {
$route_info = $this->entity->urlInfo('delete-form');
if ($this->getRequest()->query->has('destination')) {
$query = $route_info->getOption('query');
$query['destination'] = $this->getRequest()->query->get('destination');
$route_info->setOption('query', $query);
}
$actions['delete'] = array(
'#type' => 'link',
'#title' => $this->t('Delete'),
'#attributes' => array(
'class' => array('button', 'button--danger'),
),
);
$actions['delete'] += $route_info->toRenderArray();
}
return $actions;
} }
/** /**
...@@ -273,28 +284,6 @@ public function save(array $form, array &$form_state) { ...@@ -273,28 +284,6 @@ public function save(array $form, array &$form_state) {
// @todo Perform common save operations. // @todo Perform common save operations.
} }
/**
* Form submission handler for the 'delete' action.
*
* @param array $form
* An associative array containing the structure of the form.
* @param array $form_state
* A reference to a keyed array containing the current state of the form.
*/
public function delete(array $form, array &$form_state) {
if ($this->entity->hasLinkTemplate('delete-form')) {
$form_state['redirect_route'] = $this->entity->urlInfo('delete-form');
$query = $this->getRequest()->query;
if ($query->has('destination')) {
$redirect_query = $form_state['redirect_route']->getOption('query') ?: array();
$redirect_query['destination'] = $query->get('destination');
$form_state['redirect_route']->setOption('query', $redirect_query);
$query->remove('destination');
}
}
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
......
...@@ -70,7 +70,7 @@ public function testPageEdit() { ...@@ -70,7 +70,7 @@ public function testPageEdit() {
// Test deleting the block. // Test deleting the block.
$this->drupalGet("block/" . $revised_block->id()); $this->drupalGet("block/" . $revised_block->id());
$this->drupalPostForm(NULL, array(), t('Delete')); $this->clickLink(t('Delete'));
$this->assertText(format_string('Are you sure you want to delete !label?', array('!label' => $revised_block->label()))); $this->assertText(format_string('Are you sure you want to delete !label?', array('!label' => $revised_block->label())));
} }
......
...@@ -139,7 +139,7 @@ function testBlock() { ...@@ -139,7 +139,7 @@ function testBlock() {
// Test deleting the block from the edit form. // Test deleting the block from the edit form.
$this->drupalGet('admin/structure/block/manage/' . $block['id']); $this->drupalGet('admin/structure/block/manage/' . $block['id']);
$this->drupalPostForm(NULL, array(), t('Delete')); $this->clickLink(t('Delete'));
$this->assertRaw(t('Are you sure you want to delete the block %name?', array('%name' => $block['settings[label]']))); $this->assertRaw(t('Are you sure you want to delete the block %name?', array('%name' => $block['settings[label]'])));
$this->drupalPostForm(NULL, array(), t('Delete')); $this->drupalPostForm(NULL, array(), t('Delete'));
$this->assertRaw(t('The block %name has been removed.', array('%name' => $block['settings[label]']))); $this->assertRaw(t('The block %name has been removed.', array('%name' => $block['settings[label]'])));
...@@ -147,7 +147,7 @@ function testBlock() { ...@@ -147,7 +147,7 @@ function testBlock() {
// Test deleting a block via "Configure block" link. // Test deleting a block via "Configure block" link.
$block = $this->drupalPlaceBlock('system_powered_by_block'); $block = $this->drupalPlaceBlock('system_powered_by_block');
$this->drupalGet('admin/structure/block/manage/' . $block->id(), array('query' => array('destination' => 'admin'))); $this->drupalGet('admin/structure/block/manage/' . $block->id(), array('query' => array('destination' => 'admin')));
$this->drupalPostForm(NULL, array(), t('Delete')); $this->clickLink(t('Delete'));
$this->assertRaw(t('Are you sure you want to delete the block %name?', array('%name' => $block->label()))); $this->assertRaw(t('Are you sure you want to delete the block %name?', array('%name' => $block->label())));
$this->drupalPostForm(NULL, array(), t('Delete')); $this->drupalPostForm(NULL, array(), t('Delete'));
$this->assertRaw(t('The block %name has been removed.', array('%name' => $block->label()))); $this->assertRaw(t('The block %name has been removed.', array('%name' => $block->label())));
......
...@@ -272,7 +272,7 @@ function testCRUDUI() { ...@@ -272,7 +272,7 @@ function testCRUDUI() {
// Delete the configuration entity. // Delete the configuration entity.
$this->drupalGet("admin/structure/config_test/manage/$id"); $this->drupalGet("admin/structure/config_test/manage/$id");
$this->drupalPostForm(NULL, array(), 'Delete'); $this->clickLink(t('Delete'));
$this->assertUrl("admin/structure/config_test/manage/$id/delete"); $this->assertUrl("admin/structure/config_test/manage/$id/delete");
$this->drupalPostForm(NULL, array(), 'Delete'); $this->drupalPostForm(NULL, array(), 'Delete');
$this->assertUrl('admin/structure/config_test'); $this->assertUrl('admin/structure/config_test');
......
...@@ -69,7 +69,7 @@ public function testEntityViewModeUI() { ...@@ -69,7 +69,7 @@ public function testEntityViewModeUI() {
$this->drupalGet('admin/structure/display-modes/view/manage/entity_test.' . $edit['id']); $this->drupalGet('admin/structure/display-modes/view/manage/entity_test.' . $edit['id']);
// Test deleting the view mode. // Test deleting the view mode.
$this->drupalPostForm(NULL, NULL, t('Delete')); $this->clickLink(t('Delete'));
$this->assertRaw(t('Are you sure you want to delete the %label view mode?', array('%label' => $edit['label']))); $this->assertRaw(t('Are you sure you want to delete the %label view mode?', array('%label' => $edit['label'])));
$this->drupalPostForm(NULL, NULL, t('Delete')); $this->drupalPostForm(NULL, NULL, t('Delete'));
$this->assertRaw(t('Deleted the %label view mode.', array('%label' => $edit['label']))); $this->assertRaw(t('Deleted the %label view mode.', array('%label' => $edit['label'])));
...@@ -115,7 +115,7 @@ public function testEntityFormModeUI() { ...@@ -115,7 +115,7 @@ public function testEntityFormModeUI() {
$this->drupalGet('admin/structure/display-modes/form/manage/entity_test.' . $edit['id']); $this->drupalGet('admin/structure/display-modes/form/manage/entity_test.' . $edit['id']);
// Test deleting the form mode. // Test deleting the form mode.
$this->drupalPostForm(NULL, NULL, t('Delete')); $this->clickLink(t('Delete'));
$this->assertRaw(t('Are you sure you want to delete the %label form mode?', array('%label' => $edit['label']))); $this->assertRaw(t('Are you sure you want to delete the %label form mode?', array('%label' => $edit['label'])));
$this->drupalPostForm(NULL, NULL, t('Delete')); $this->drupalPostForm(NULL, NULL, t('Delete'));
$this->assertRaw(t('Deleted the %label form mode.', array('%label' => $edit['label']))); $this->assertRaw(t('Deleted the %label form mode.', array('%label' => $edit['label'])));
......
...@@ -101,16 +101,20 @@ public function save(array $form, array &$form_state) { ...@@ -101,16 +101,20 @@ public function save(array $form, array &$form_state) {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function delete(array $form, array &$form_state) { protected function actions(array $form, array &$form_state) {
$form_state['redirect_route'] = $this->entity->urlInfo('forum-delete-form'); $actions = parent::actions($form, $form_state);
$query = $this->getRequest()->query; if (!$this->entity->isNew() && $this->entity->hasLinkTemplate('forum-delete-form')) {
if ($query->has('destination')) { $route_info = $this->entity->urlInfo('forum-delete-form');
$redirect_query = $form_state['redirect_route']->getOption('query') ?: array(); $actions['delete']['#options'] = $route_info->getOptions();
$redirect_query['destination'] = $query->get('destination'); $actions['delete']['#route_name'] = $route_info->getRouteName();
$form_state['redirect_route']->setOption('query', $redirect_query); $actions['delete']['#route_parameters'] = $route_info->getRouteParameters();
$query->remove('destination');
} }
else {
unset($actions['delete']);
}
return $actions;
} }
/** /**
......
...@@ -307,7 +307,7 @@ private function doAdminTests($user) { ...@@ -307,7 +307,7 @@ private function doAdminTests($user) {
// Test tags vocabulary form is not affected. // Test tags vocabulary form is not affected.
$this->drupalGet('admin/structure/taxonomy/manage/tags'); $this->drupalGet('admin/structure/taxonomy/manage/tags');
$this->assertFieldByName('op', t('Save'), 'Save button found.'); $this->assertFieldByName('op', t('Save'), 'Save button found.');
$this->assertFieldByName('op', t('Delete'), 'Delete button found.'); $this->assertLink(t('Delete'));
// Test tags vocabulary term form is not affected. // Test tags vocabulary term form is not affected.
$this->drupalGet('admin/structure/taxonomy/manage/tags/add'); $this->drupalGet('admin/structure/taxonomy/manage/tags/add');
$this->assertField('parent[]', 'Parent field found.'); $this->assertField('parent[]', 'Parent field found.');
...@@ -408,7 +408,8 @@ function createForum($type, $parent = 0) { ...@@ -408,7 +408,8 @@ function createForum($type, $parent = 0) {
*/ */
function deleteForum($tid) { function deleteForum($tid) {
// Delete the forum. // Delete the forum.
$this->drupalPostForm('admin/structure/forum/edit/forum/' . $tid, array(), t('Delete')); $this->drupalGet('admin/structure/forum/edit/forum/' . $tid);
$this->clickLink(t('Delete'));
$this->assertText('Are you sure you want to delete the forum'); $this->assertText('Are you sure you want to delete the forum');
$this->assertNoText('Add forum'); $this->assertNoText('Add forum');
$this->assertNoText('Add forum container'); $this->assertNoText('Add forum container');
......
...@@ -279,6 +279,7 @@ protected function actions(array $form, array &$form_state) { ...@@ -279,6 +279,7 @@ protected function actions(array $form, array &$form_state) {
} }
$element['preview'] = array( $element['preview'] = array(
'#type' => 'submit',
'#access' => $preview_mode != DRUPAL_DISABLED && ($node->access('create') || $node->access('update')), '#access' => $preview_mode != DRUPAL_DISABLED && ($node->access('create') || $node->access('update')),
'#value' => t('Preview'), '#value' => t('Preview'),
'#weight' => 20, '#weight' => 20,
......
...@@ -91,25 +91,6 @@ public function form(array $form, array &$form_state) { ...@@ -91,25 +91,6 @@ public function form(array $form, array &$form_state) {
return parent::form($form, $form_state, $responsive_image_mapping); return parent::form($form, $form_state, $responsive_image_mapping);
} }
/**
* Overrides Drupal\Core\Entity\EntityFormController::actions().
*/
protected function actions(array $form, array &$form_state) {
// Only includes a Save action for the entity, no direct Delete button.
return array(
'submit' => array(
'#value' => $this->t('Save'),
'#validate' => array(
array($this, 'validate'),
),
'#submit' => array(
array($this, 'submit'),
array($this, 'save'),
),
),
);
}
/** /**
* Overrides Drupal\Core\Entity\EntityFormController::validate(). * Overrides Drupal\Core\Entity\EntityFormController::validate().
*/ */
......
...@@ -84,7 +84,9 @@ protected function assertFormCRUD($entity_type) { ...@@ -84,7 +84,9 @@ protected function assertFormCRUD($entity_type) {
$this->assertTrue($entity, format_string('%entity_type: Modified entity found in the database.', array('%entity_type' => $entity_type))); $this->assertTrue($entity, format_string('%entity_type: Modified entity found in the database.', array('%entity_type' => $entity_type)));
$this->assertNotEqual($entity->name->value, $name1, format_string('%entity_type: The entity name has been modified.', array('%entity_type' => $entity_type))); $this->assertNotEqual($entity->name->value, $name1, format_string('%entity_type: The entity name has been modified.', array('%entity_type' => $entity_type)));
$this->drupalPostForm($entity_type . '/manage/' . $entity->id(), array(), t('Delete')); $this->drupalGet($entity_type . '/manage/' . $entity->id());
$this->clickLink(t('Delete'));
$this->drupalPostForm(NULL, array(), t('Confirm'));
$entity = $this->loadEntityByName($entity_type, $name2); $entity = $this->loadEntityByName($entity_type, $name2);
$this->assertFalse($entity, format_string('%entity_type: Entity not found in the database.', array('%entity_type' => $entity_type))); $this->assertFalse($entity, format_string('%entity_type: Entity not found in the database.', array('%entity_type' => $entity_type)));
} }
......
...@@ -5,6 +5,34 @@ entity_test.render: ...@@ -5,6 +5,34 @@ entity_test.render:
requirements: requirements:
_access: 'TRUE' _access: 'TRUE'
entity_test.delete_entity_test:
path: '/entity_test/delete/entity_test/{entity_test}'
defaults:
_entity_form: entity_test.delete
requirements:
_access: 'TRUE'
entity_test.delete_entity_test_mul:
path: '/entity_test/delete/entity_test_mul/{entity_test_mul}'
defaults:
_entity_form: entity_test_mul.delete
requirements:
_access: 'TRUE'
entity_test.delete_entity_test_mulrev:
path: '/entity_test/delete/entity_test_mulrev/{entity_test_mulrev}'
defaults:
_entity_form: entity_test_mulrev.delete
requirements:
_access: 'TRUE'
entity_test.delete_entity_test_rev:
path: '/entity_test/delete/entity_test_rev/{entity_test_rev}'
defaults:
_entity_form: entity_test_rev.delete
requirements:
_access: 'TRUE'
entity_test.render_options: entity_test.render_options:
path: '/entity_test_converter/{foo}' path: '/entity_test_converter/{foo}'
options: options:
......
...@@ -25,7 +25,8 @@ ...@@ -25,7 +25,8 @@
* "view_builder" = "Drupal\entity_test\EntityTestViewBuilder", * "view_builder" = "Drupal\entity_test\EntityTestViewBuilder",
* "access" = "Drupal\entity_test\EntityTestAccessController", * "access" = "Drupal\entity_test\EntityTestAccessController",
* "form" = { * "form" = {
* "default" = "Drupal\entity_test\EntityTestFormController" * "default" = "Drupal\entity_test\EntityTestFormController",
* "delete" = "Drupal\entity_test\EntityTestDeleteFormController"
* }, * },
* "translation" = "Drupal\content_translation\ContentTranslationHandler" * "translation" = "Drupal\content_translation\ContentTranslationHandler"
* }, * },
...@@ -41,6 +42,7 @@ ...@@ -41,6 +42,7 @@
* links = { * links = {
* "canonical" = "entity_test.render", * "canonical" = "entity_test.render",
* "edit-form" = "entity_test.edit_entity_test", * "edit-form" = "entity_test.edit_entity_test",
* "delete-form" = "entity_test.delete_entity_test",
* "admin-form" = "entity_test.admin_entity_test" * "admin-form" = "entity_test.admin_entity_test"
* } * }
* ) * )
......
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
* "view_builder" = "Drupal\entity_test\EntityTestViewBuilder", * "view_builder" = "Drupal\entity_test\EntityTestViewBuilder",
* "access" = "Drupal\entity_test\EntityTestAccessController", * "access" = "Drupal\entity_test\EntityTestAccessController",
* "form" = { * "form" = {
* "default" = "Drupal\entity_test\EntityTestFormController" * "default" = "Drupal\entity_test\EntityTestFormController",
* "delete" = "Drupal\entity_test\EntityTestDeleteFormController"
* }, * },
* "translation" = "Drupal\content_translation\ContentTranslationHandler" * "translation" = "Drupal\content_translation\ContentTranslationHandler"
* }, * },
...@@ -38,6 +39,7 @@ ...@@ -38,6 +39,7 @@
* links = { * links = {
* "canonical" = "entity_test.edit_entity_test_mul", * "canonical" = "entity_test.edit_entity_test_mul",
* "edit-form" = "entity_test.edit_entity_test_mul", * "edit-form" = "entity_test.edit_entity_test_mul",
* "delete-form" = "entity_test.delete_entity_test_mul",
* "admin-form" = "entity_test.admin_entity_test_mul" * "admin-form" = "entity_test.admin_entity_test_mul"
* } * }
* ) * )
......
...@@ -20,7 +20,8 @@ ...@@ -20,7 +20,8 @@
* controllers = { * controllers = {
* "access" = "Drupal\entity_test\EntityTestAccessController", * "access" = "Drupal\entity_test\EntityTestAccessController",
* "form" = { * "form" = {
* "default" = "Drupal\entity_test\EntityTestFormController" * "default" = "Drupal\entity_test\EntityTestFormController",
* "delete" = "Drupal\entity_test\EntityTestDeleteFormController"
* }, * },
* "translation" = "Drupal\content_translation\ContentTranslationHandler" * "translation" = "Drupal\content_translation\ContentTranslationHandler"
* }, * },
...@@ -38,6 +39,7 @@ ...@@ -38,6 +39,7 @@
* }, * },
* links = { * links = {
* "canonical" = "entity_test.edit_entity_test_mulrev", * "canonical" = "entity_test.edit_entity_test_mulrev",
* "delete-form" = "entity_test.delete_entity_test_mulrev",
* "edit-form" = "entity_test.edit_entity_test_mulrev" * "edit-form" = "entity_test.edit_entity_test_mulrev"
* } * }
* ) * )
......
...@@ -20,7 +20,8 @@ ...@@ -20,7 +20,8 @@
* controllers = { * controllers = {
* "access" = "Drupal\entity_test\EntityTestAccessController", * "access" = "Drupal\entity_test\EntityTestAccessController",
* "form" = { * "form" = {
* "default" = "Drupal\entity_test\EntityTestFormController" * "default" = "Drupal\entity_test\EntityTestFormController",
* "delete" = "Drupal\entity_test\EntityTestDeleteFormController"
* }, * },
* "translation" = "Drupal\content_translation\ContentTranslationHandler" * "translation" = "Drupal\content_translation\ContentTranslationHandler"
* }, * },
...@@ -36,6 +37,7 @@ ...@@ -36,6 +37,7 @@
* }, * },
* links = { * links = {
* "canonical" = "entity_test.edit_entity_test_rev", * "canonical" = "entity_test.edit_entity_test_rev",
* "delete-form" = "entity_test.delete_entity_test_rev",
* "edit-form" = "entity_test.edit_entity_test_rev" * "edit-form" = "entity_test.edit_entity_test_rev"
* } * }
* ) * )
......
<?php
/**
* @file
* Contains \Drupal\entity_test\EntityTestDeleteFormController.
*/
namespace Drupal\entity_test;
use Drupal\Core\Entity\ContentEntityConfirmFormBase;
/**
* Provides the entity_test delete form.
*/
class EntityTestDeleteFormController extends ContentEntityConfirmFormBase {
/**
* {@inheritdoc}
*/
public function getCancelRoute() {
return array(
'route_name' => '<front>',
);
}
/**
* {@inheritdoc}
*/
public function getQuestion() {
$entity_type = $this->entity->getEntityType();
return t('Are you sure you want to delete the %label @entity-type?', array('%label' => $this->entity->label(), '@entity-type' => $entity_type->getLowercaseLabel()));
}
/**
* {@inheritdoc}
*/
public function submit(array $form, array &$form_state) {
parent::submit($form, $form_state);
$entity = $this->entity;
$entity->delete();
drupal_set_message(t('%entity_type @id has been deleted.', array('@id' => $entity->id(), '%entity_type' => $entity->getEntityTypeId())));
$form_state['redirect_route']['route_name'] = '<front>';
}
}
...@@ -106,14 +106,4 @@ public function save(array $form, array &$form_state) { ...@@ -106,14 +106,4 @@ public function save(array $form, array &$form_state) {
$form_state['rebuild'] = TRUE; $form_state['rebuild'] = TRUE;
} }
} }
/**
* Overrides Drupal\Core\Entity\EntityFormController::delete().
*/
public function delete(array $form, array &$form_state) {
$entity = $this->entity;
$entity->delete();
drupal_set_message(t('%entity_type @id has been deleted.', array('@id' => $entity->id(), '%entity_type' => $entity->getEntityTypeId())));
$form_state['redirect_route']['route_name'] = '<front>';
}
} }
...@@ -202,11 +202,13 @@ function testNodeTermCreationAndDeletion() { ...@@ -202,11 +202,13 @@ function testNodeTermCreationAndDeletion() {
} }
// Delete term 1 from the term edit page. // Delete term 1 from the term edit page.
$this->drupalPostForm('taxonomy/term/' . $term_objects['term1']->id() . '/edit', array(), t('Delete')); $this->drupalGet('taxonomy/term/' . $term_objects['term1']->id() . '/edit');
$this->clickLink(t('Delete'));
$this->drupalPostForm(NULL, NULL, t('Delete')); $this->drupalPostForm(NULL, NULL, t('Delete'));
// Delete term 2 from the term delete page. // Delete term 2 from the term delete page.
$this->drupalPostForm('taxonomy/term/' . $term_objects['term2']->id() . '/delete', array(), t('Delete')); $this->drupalGet('taxonomy/term/' . $term_objects['term2']->id() . '/delete');
$this->drupalPostForm(NULL, array(), t('Delete'));
$term_names = array($term_objects['term3']->getName(), $term_objects['term4']->getName()); $term_names = array($term_objects['term3']->getName(), $term_objects['term4']->getName());
// Get the node. // Get the node.
...@@ -366,7 +368,8