Issue #1856556 by Berdir, andypost, das-peter: Convert user contact form into a contact category/bundle.

8.0.x
Alex Pott 2013-06-05 10:18:02 +01:00
parent ff0f94d955
commit 99861e89d4
12 changed files with 119 additions and 36 deletions

View File

@ -0,0 +1,5 @@
id: personal
label: 'Personal contact form'
recipients: []
reply: ''
weight: '0'

View File

@ -76,6 +76,7 @@ function contact_personal_page($recipient) {
$message = entity_create('contact_message', array(
'recipient' => $recipient,
'category' => 'personal',
));
return entity_get_form($message);
}

View File

@ -3,7 +3,7 @@ contact_category_delete:
defaults:
_form: '\Drupal\contact\Form\DeleteForm'
requirements:
_permission: 'administer contact forms'
_entity_access: contact_category.delete
contact_category_list:
pattern: '/admin/structure/contact'
@ -25,4 +25,4 @@ contact_category_edit:
defaults:
_entity_form: contact_category.edit
requirements:
_permission: 'administer contact forms'
_entity_access: contact_category.update

View File

@ -0,0 +1,34 @@
<?php
/**
* @file
* Contains \Drupal\contact\CategoryAccessController.
*/
namespace Drupal\contact;
use Drupal\Core\Entity\EntityAccessController;
use Drupal\Core\Entity\EntityInterface;
use Drupal\user\Plugin\Core\Entity\User;
/**
* Defines an access controller for the contact category entity.
*
* @see \Drupal\contact\Plugin\Core\Entity\Category.
*/
class CategoryAccessController extends EntityAccessController {
/**
* {@inheritdoc}
*/
public function checkAccess(EntityInterface $entity, $operation, $langcode, User $account) {
if ($operation == 'delete' || $operation == 'update') {
// Do not allow delete 'personal' category used for personal contact form.
return user_access('administer contact forms', $account) && $entity->id() !== 'personal';
}
else {
return user_access('administer contact forms', $account);
}
}
}

View File

@ -128,8 +128,7 @@ class CategoryFormController extends EntityFormController {
* Overrides Drupal\Core\Entity\EntityFormController::delete().
*/
public function delete(array $form, array &$form_state) {
$category = $this->entity;
$form_state['redirect'] = 'admin/structure/contact/manage/' . $category->id() . '/delete';
$form_state['redirect'] = 'admin/structure/contact/manage/' . $this->entity->id() . '/delete';
}
}

View File

@ -34,6 +34,13 @@ class CategoryListController extends ConfigEntityListController {
'weight' => 12,
);
}
if (!$entity->access('delete')) {
unset($operations['delete']);
}
if (!$entity->access('update')) {
unset($operations['edit']);
}
return $operations;
}
@ -53,9 +60,16 @@ class CategoryListController extends ConfigEntityListController {
*/
public function buildRow(EntityInterface $entity) {
$row['category'] = check_plain($entity->label());
$row['recipients'] = check_plain(implode(', ', $entity->recipients));
$default_category = config('contact.settings')->get('default_category');
$row['selected'] = ($default_category == $entity->id() ? t('Yes') : t('No'));
// Special case the personal category.
if ($entity->id() == 'personal') {
$row['recipients'] = t('Selected user');
$row['selected'] = t('No');
}
else {
$row['recipients'] = check_plain(implode(', ', $entity->recipients));
$default_category = config('contact.settings')->get('default_category');
$row['selected'] = ($default_category == $entity->id() ? t('Yes') : t('No'));
}
$row['operations']['data'] = $this->buildOperations($entity);
return $row;
}

View File

@ -62,9 +62,8 @@ class MessageFormController extends EntityFormController {
$form['mail']['#markup'] = check_plain($user->mail);
}
// The user contact form only has a recipient, not a category.
// @todo Convert user contact form into a locked contact category.
if ($message->recipient instanceof User) {
// The user contact form has a preset recipient.
if ($message->isPersonal()) {
$form['recipient'] = array(
'#type' => 'item',
'#title' => t('To'),
@ -160,7 +159,7 @@ class MessageFormController extends EntityFormController {
$params['contact_message'] = $message;
$params['sender'] = $sender;
if ($message->category) {
if (!$message->isPersonal()) {
// Send to the category recipient(s), using the site's default language.
$category = entity_load('contact_category', $message->category);
$params['contact_category'] = $category;
@ -186,14 +185,14 @@ class MessageFormController extends EntityFormController {
}
// If configured, send an auto-reply, using the current language.
if ($message->category && $category->reply) {
if (!$message->isPersonal() && $category->reply) {
// User contact forms do not support an auto-reply message, so this
// message always originates from the site.
drupal_mail('contact', 'page_autoreply', $sender->mail, $language_interface->langcode, $params);
}
\Drupal::service('flood')->register('contact', config('contact.settings')->get('flood.interval'));
if ($message->category) {
if (!$message->isPersonal()) {
watchdog('contact', '%sender-name (@sender-from) sent an e-mail regarding %category.', array(
'%sender-name' => $sender->name,
'@sender-from' => $sender->mail,

View File

@ -14,4 +14,12 @@ use Drupal\Core\Entity\EntityInterface;
*/
interface MessageInterface extends EntityInterface {
/**
* Return TRUE if this is the personal contact form.
*
* @return bool
* TRUE if the message bundle is personal.
*/
public function isPersonal();
}

View File

@ -21,6 +21,7 @@ use Drupal\contact\CategoryInterface;
* module = "contact",
* controllers = {
* "storage" = "Drupal\contact\CategoryStorageController",
* "access" = "Drupal\contact\CategoryAccessController",
* "list" = "Drupal\contact\CategoryListController",
* "form" = {
* "add" = "Drupal\contact\CategoryFormController",

View File

@ -69,9 +69,8 @@ class Message extends Entity implements MessageInterface {
* @see Drupal\contact\MessageFormController::form()
* @see Drupal\contact\MessageFormController::save()
*
* @todo Convert user contact form into a locked contact category, and replace
* Category::$recipients with the user account's e-mail address upon
* Entity::create().
* @todo Replace Category::$recipients with the user account's e-mail address
* upon Entity::create().
*
* @var Drupal\user\Plugin\Core\Entity\User
*/
@ -113,17 +112,10 @@ class Message extends Entity implements MessageInterface {
}
/**
* Overrides Drupal\Core\Entity\Entity::entityInfo().
* {@inheritdoc}
*/
public function entityInfo() {
// The user contact form is not a category/bundle currently, so it is not
// fieldable. Prevent EntityFormController from calling into Field Attach
// functions, since those will throw errors without a bundle name.
$info = entity_get_info($this->entityType);
if (isset($this->recipient)) {
$info['fieldable'] = FALSE;
}
return $info;
public function isPersonal() {
return $this->bundle() == 'personal';
}
}

View File

@ -62,6 +62,22 @@ class ContactPersonalTest extends WebTestBase {
$this->contact_user = $this->drupalCreateUser();
}
/**
* Tests that mails for contact messages are correctly sent.
*/
function testSendPersonalContactMessage() {
$this->drupalLogin($this->web_user);
$message = $this->submitPersonalContact($this->contact_user);
$mails = $this->drupalGetMails();
$this->assertEqual(1, count($mails));
$mail = $mails[0];
$this->assertEqual($mail['to'], $this->contact_user->mail);
$this->assertEqual($mail['from'], $this->web_user->mail);
$this->assertTrue(strpos($mail['subject'], $message['subject']) !== FALSE, 'Subject is in sent message.');
$this->assertTrue(strpos($mail['body'], $message['message']) !== FALSE, 'Subject is in sent message.');
}
/**
* Tests access to the personal contact form.
*/
@ -188,5 +204,6 @@ class ContactPersonalTest extends WebTestBase {
'message' => $this->randomName(64),
);
$this->drupalPost('user/' . $account->uid . '/contact', $message, t('Send message'));
return $message;
}
}

View File

@ -49,8 +49,21 @@ class ContactSitewideTest extends WebTestBase {
$this->drupalPost('admin/config/people/accounts', $edit, t('Save configuration'));
$this->assertText(t('The configuration options have been saved.'));
$this->drupalGet('admin/structure/contact');
// Default category exists.
$this->assertLinkByHref('admin/structure/contact/manage/feedback/delete');
// User category could not be changed or deleted.
$this->assertNoLinkByHref('admin/structure/contact/manage/personal');
$this->assertNoLinkByHref('admin/structure/contact/manage/personal/delete');
$this->drupalGet('admin/structure/contact/manage/personal');
$this->assertResponse(403);
// Delete old categories to ensure that new categories are used.
$this->deleteCategories();
$this->drupalGet('admin/structure/contact');
$this->assertText('Personal', 'Personal category was not deleted');
$this->assertNoLinkByHref('admin/structure/contact/manage/feedback');
// Ensure that the contact form won't be shown without categories.
user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access site-wide contact form'));
@ -139,9 +152,6 @@ class ContactSitewideTest extends WebTestBase {
$this->assertResponse(200);
// Submit contact form with invalid values.
$categories = entity_load_multiple('contact_category');
$id = key($categories);
$this->submitContact('', $recipients[0], $this->randomName(16), $id, $this->randomName(64));
$this->assertText(t('Your name field is required.'));
@ -179,10 +189,6 @@ class ContactSitewideTest extends WebTestBase {
$this->drupalGet('contact');
$this->assertResponse(403);
$this->assertRaw(t('You cannot send more than %number messages in @interval. Try again later.', array('%number' => config('contact.settings')->get('flood.limit'), '@interval' => format_interval(600))));
// Delete created categories.
$this->drupalLogin($admin_user);
$this->deleteCategories();
}
/**
@ -313,9 +319,16 @@ class ContactSitewideTest extends WebTestBase {
function deleteCategories() {
$categories = entity_load_multiple('contact_category');
foreach ($categories as $id => $category) {
$this->drupalPost("admin/structure/contact/manage/$id/delete", array(), t('Delete'));
$this->assertRaw(t('Category %label has been deleted.', array('%label' => $category->label())));
$this->assertFalse(entity_load('contact_category', $id), format_string('Category %category not found', array('%category' => $category->label())));
if ($id == 'personal') {
// Personal category could not be deleted.
$this->drupalGet("admin/structure/contact/manage/$id/delete");
$this->assertResponse(403);
}
else {
$this->drupalPost("admin/structure/contact/manage/$id/delete", array(), t('Delete'));
$this->assertRaw(t('Category %label has been deleted.', array('%label' => $category->label())));
$this->assertFalse(entity_load('contact_category', $id), format_string('Category %category not found', array('%category' => $category->label())));
}
}
}