Commit 4756994e authored by alexpott's avatar alexpott

Issue #1983548 by Berdir, LukyLuke_ch, giammi, effulgentsia: Convert contact...

Issue #1983548 by Berdir, LukyLuke_ch, giammi, effulgentsia: Convert contact message entities to the new Entity Field API.
parent 2c67e901
......@@ -2,10 +2,10 @@
/**
* @file
* Contains \Drupal\email\Type\EmailItem.
* Contains \Drupal\Core\Entity\Field\Type\EmailItem.
*/
namespace Drupal\email\Type;
namespace Drupal\Core\Entity\Field\Type;
use Drupal\Core\Entity\Field\FieldItemBase;
......
......@@ -188,12 +188,13 @@ function contact_field_extra_fields() {
'description' => t('E-mail'),
'weight' => -40,
);
// @todo Recipient only makes sense if user contact form is a bundle/category.
$fields['contact_message'][$bundle]['form']['recipient'] = array(
'label' => t('Recipient user name'),
'description' => t('User'),
'weight' => -30,
);
if ($bundle == 'personal') {
$fields['contact_message'][$bundle]['form']['recipient'] = array(
'label' => t('Recipient user name'),
'description' => t('User'),
'weight' => -30,
);
}
$fields['contact_message'][$bundle]['form']['subject'] = array(
'label' => t('Subject'),
'description' => t('Text'),
......@@ -263,8 +264,8 @@ function contact_mail($key, &$message, $params) {
$variables = array(
'!site-name' => config('system.site')->get('name'),
'!subject' => $contact_message->subject,
'!category' => isset($params['contact_category']) ? $params['contact_category']->label() : NULL,
'!subject' => $contact_message->getSubject(),
'!category' => !empty($params['contact_category']) ? $params['contact_category']->label() : NULL,
'!form-url' => url(current_path(), array('absolute' => TRUE, 'language' => $language)),
'!sender-name' => user_format_name($sender),
);
......@@ -302,8 +303,8 @@ function contact_mail($key, &$message, $params) {
$message['body'][] = t('Hello !recipient-name,', $variables, $options);
$message['body'][] = t("!sender-name (!sender-url) has sent you a message via your contact form at !site-name.", $variables, $options);
$message['body'][] = t("If you don't want to receive such e-mails, you can change your settings at !recipient-edit-url.", $variables, $options);
$message['body'][] = t('Message:', array(), $options);
$message['body'][] = $contact_message->message;
$build = entity_view($contact_message, 'mail', $language->langcode);
$message['body'][] = drupal_render($build);
break;
}
}
......
......@@ -45,6 +45,9 @@ function contact_site_page(Category $category = NULL) {
}
}
}
else if ($category->id() == 'personal') {
throw new NotFoundHttpException();
}
$message = entity_create('contact_message', array(
'category' => $category->id(),
));
......
......@@ -19,6 +19,22 @@ class CategoryListController extends ConfigEntityListController {
*/
public function getOperations(EntityInterface $entity) {
$operations = parent::getOperations($entity);
if ($this->moduleHandler->moduleExists('field_ui')) {
$uri = $entity->uri();
$operations['manage-fields'] = array(
'title' => t('Manage fields'),
'href' => $uri['path'] . '/fields',
'options' => $uri['options'],
'weight' => 11,
);
$operations['manage-display'] = array(
'title' => t('Manage display'),
'href' => $uri['path'] . '/display',
'options' => $uri['options'],
'weight' => 12,
);
}
if (!$entity->access('delete')) {
unset($operations['delete']);
}
......
......@@ -7,14 +7,14 @@
namespace Drupal\contact;
use Drupal\Core\Entity\EntityFormController;
use Drupal\Core\Entity\EntityFormControllerNG;
use Drupal\Core\Language\Language;
use Drupal\user\UserInterface;
/**
* Form controller for contact message forms.
*/
class MessageFormController extends EntityFormController {
class MessageFormController extends EntityFormControllerNG {
/**
* Overrides Drupal\Core\Entity\EntityFormController::form().
......@@ -67,19 +67,13 @@ public function form(array $form, array &$form_state) {
$form['recipient'] = array(
'#type' => 'item',
'#title' => t('To'),
'#value' => $message->recipient,
'#value' => $message->getPersonalRecipient()->id(),
'name' => array(
'#theme' => 'username',
'#account' => $message->recipient,
'#account' => $message->getPersonalRecipient(),
),
);
}
else {
$form['category'] = array(
'#type' => 'value',
'#value' => $message->category,
);
}
$form['subject'] = array(
'#type' => 'textfield',
......@@ -146,13 +140,13 @@ public function save(array $form, array &$form_state) {
if (!$user->uid) {
// At this point, $sender contains drupal_anonymous_user(), so we need to
// take over the submitted form values.
$sender->name = $message->name;
$sender->mail = $message->mail;
$sender->name = $message->getSenderName();
$sender->mail = $message->getSenderMail();
// Save the anonymous user information to a cookie for reuse.
user_cookie_save(array('name' => $message->name, 'mail' => $message->mail));
user_cookie_save(array('name' => $message->getSenderName(), 'mail' => $message->getSenderMail()));
// For the e-mail message, clarify that the sender name is not verified; it
// could potentially clash with a username on this site.
$sender->name = t('!name (not verified)', array('!name' => $message->name));
$sender->name = t('!name (not verified)', array('!name' => $message->getSenderName()));
}
// Build e-mail parameters.
......@@ -161,27 +155,29 @@ public function save(array $form, array &$form_state) {
if (!$message->isPersonal()) {
// Send to the category recipient(s), using the site's default language.
$category = entity_load('contact_category', $message->category);
$category = $message->getCategory();
$params['contact_category'] = $category;
$to = implode(', ', $category->recipients);
$recipient_langcode = language_default()->langcode;
}
elseif ($message->recipient instanceof UserInterface) {
elseif ($recipient = $message->getPersonalRecipient()) {
// Send to the user in the user's preferred language.
$to = $message->recipient->mail;
$recipient_langcode = user_preferred_langcode($message->recipient);
$to = $recipient->mail->value;
$recipient_langcode = user_preferred_langcode($recipient);
$params['recipient'] = $recipient->getBCEntity();
}
else {
throw new \RuntimeException(t('Unable to determine message recipient.'));
}
// Send e-mail to the recipient(s).
drupal_mail('contact', 'page_mail', $to, $recipient_langcode, $params, $sender->mail);
$key_prefix = $message->isPersonal() ? 'user' : 'page';
drupal_mail('contact', $key_prefix . '_mail', $to, $recipient_langcode, $params, $sender->mail);
// If requested, send a copy to the user, using the current language.
if ($message->copy) {
drupal_mail('contact', 'page_copy', $sender->mail, $language_interface->langcode, $params, $sender->mail);
if ($message->copySender()) {
drupal_mail('contact', $key_prefix . '_copy', $sender->mail, $language_interface->langcode, $params, $sender->mail);
}
// If configured, send an auto-reply, using the current language.
......@@ -211,8 +207,8 @@ public function save(array $form, array &$form_state) {
// To avoid false error messages caused by flood control, redirect away from
// the contact form; either to the contacted user account or the front page.
if ($message->recipient instanceof UserInterface && user_access('access user profiles')) {
$uri = $message->recipient->uri();
if ($message->isPersonal() && user_access('access user profiles')) {
$uri = $message->getPersonalRecipient()->uri();
$form_state['redirect'] = array($uri['path'], $uri['options']);
}
else {
......
......@@ -15,11 +15,107 @@
interface MessageInterface extends EntityInterface {
/**
* Return TRUE if this is the personal contact form.
* Returns the category this contact message belongs to.
*
* @return \Drupal\contact\CategoryInterface
* The contact category entity.
*/
public function getCategory();
/**
* Returns the name of the sender.
*
* @return string
* The name of the message sender.
*/
public function getSenderName();
/**
* Sets the name of the message sender.
*
* @param string $sender_name
* The name of the message sender.
*/
public function setSenderName($sender_name);
/**
* Returns the e-mail address of the sender.
*
* @return string
* The e-mail address of the message sender.
*/
public function getSenderMail();
/**
* Sets the e-mail address of the sender.
*
* @param string $sender_mail
* The e-mail address of the message sender.
*/
public function setSenderMail($sender_mail);
/**
* Returns the message subject.
*
* @return string
* The message subject.
*/
public function getSubject();
/**
* Sets the subject for the e-mail.
*
* @param string $subject
* The message subject.
*/
public function setSubject($subject);
/**
* Returns the message body.
*
* @return string
* The message body.
*/
public function getMessage();
/**
* Sets the e-mail message to send.
*
* @param string $message
* The message body.
*/
public function setMessage($message);
/**
* Returns TRUE if a copy should be sent to the sender.
*
* @return bool
* TRUE if a copy should be sent, FALSE if not.
*/
public function copySender();
/**
* Sets if the sender should receive a copy of this e-mail or not.
*
* @param bool $inform
* TRUE if a copy should be sent, FALSE if not.
*/
public function setCopySender($inform);
/**
* Returns TRUE if this is the personal contact form.
*
* @return bool
* TRUE if the message bundle is personal.
*/
public function isPersonal();
/**
* Returns the user this message is being sent to.
*
* @return \Drupal\user\UserInterface
* The user entity of the recipent, NULL if this is not a personal message.
*/
public function getPersonalRecipient();
}
......@@ -24,11 +24,11 @@ public function buildContent(array $entities, array $displays, $view_mode, $lang
foreach ($entities as $entity) {
// Add the message extra field, if enabled.
$display = $displays[$entity->bundle()];
if (!empty($entity->message) && $display->getComponent('message')) {
if ($entity->getMessage() && $display->getComponent('message')) {
$entity->content['message'] = array(
'#type' => 'item',
'#title' => t('Message'),
'#markup' => check_plain($entity->message),
'#markup' => check_plain($entity->getMessage()),
);
}
}
......
<?php
/**
* @file
* Contains \Drupal\contact\MessageStorageController.
*/
namespace Drupal\contact;
use Drupal\Core\Entity\DatabaseStorageControllerNG;
/**
* Defines the controller class for the contact message entity.
*/
class MessageStorageController extends DatabaseStorageControllerNG {
/**
* {@inheritdoc}
*/
public function baseFieldDefinitions() {
$fields['category'] = array(
'label' => t('Category ID'),
'description' => t('The ID of the associated category.'),
'type' => 'entity_reference_field',
'settings' => array('target_type' => 'contact_category'),
'required' => TRUE,
);
$fields['name'] = array(
'label' => t("The sender's name"),
'description' => t('The name of the person that is sending the contact message.'),
'type' => 'string_field',
);
$fields['mail'] = array(
'label' => t("The sender's e-mail"),
'description' => t('The e-mail of the person that is sending the contact message.'),
'type' => 'email_field',
);
$fields['subject'] = array(
'label' => t('The message subject'),
'description' => t('The subject of the contact message.'),
'type' => 'string_field',
);
$fields['message'] = array(
'label' => t('The message text'),
'description' => t('The text of the contact message.'),
'type' => 'string_field',
);
$fields['copy'] = array(
'label' => t('Copy'),
'description' => t('Whether to send a copy of the message to the sender.'),
'type' => 'boolean_field',
);
$fields['recipient'] = array(
'label' => t('Recipient ID'),
'description' => t('The ID of the recipient user for personal contact messages.'),
'type' => 'entity_reference_field',
'settings' => array('target_type' => 'user'),
);
return $fields;
}
}
......@@ -9,7 +9,7 @@
use Drupal\Core\Entity\Annotation\EntityType;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Entity\Entity;
use Drupal\Core\Entity\EntityNG;
use Drupal\contact\MessageInterface;
/**
......@@ -20,7 +20,7 @@
* label = @Translation("Contact message"),
* module = "contact",
* controllers = {
* "storage" = "Drupal\Core\Entity\DatabaseStorageController",
* "storage" = "Drupal\contact\MessageStorageController",
* "render" = "Drupal\contact\MessageRenderController",
* "form" = {
* "default" = "Drupal\contact\MessageFormController"
......@@ -29,93 +29,113 @@
* entity_keys = {
* "bundle" = "category"
* },
* route_base_path = "admin/structure/contact/manage/{bundle}",
* fieldable = TRUE,
* bundle_keys = {
* "bundle" = "id"
* }
* )
*/
class Message extends Entity implements MessageInterface {
class Message extends EntityNG implements MessageInterface {
/**
* The contact category ID of this message.
*
* @var string
* Overrides Drupal\Core\Entity\Entity::id().
*/
public $category;
public function id() {
return NULL;
}
/**
* The sender's name.
*
* @var string
* {@inheritdoc}
*/
public $name;
public function isPersonal() {
return $this->bundle() == 'personal';
}
/**
* The sender's e-mail address.
*
* @var string
* {@inheritdoc}
*/
public $mail;
public function getCategory() {
return $this->get('category')->entity;
}
/**
* The user account object of the message recipient.
*
* Only applies to the user contact form. For a site contact form category,
* multiple recipients can be configured. The existence of a $recipient
* triggers user contact form specific processing in the contact message form
* controller.
*
* @see Drupal\contact\MessageFormController::form()
* @see Drupal\contact\MessageFormController::save()
*
* @todo Replace Category::$recipients with the user account's e-mail address
* upon Entity::create().
*
* @var Drupal\user\Plugin\Core\Entity\User
* {@inheritdoc}
*/
public $recipient;
public function getSenderName() {
return $this->get('name')->value;
}
/**
* The message subject.
*
* @var string
* {@inheritdoc}
*/
public $subject;
public function setSenderName($sender_name) {
$this->set('name', $sender_name);
}
/**
* The message text.
*
* @var string
* {@inheritdoc}
*/
public $message;
public function getSenderMail() {
return $this->get('mail')->value;
}
/**
* Whether to send a copy of the message to the sender.
*
* @var bool
* {@inheritdoc}
*/
public $copy;
public function setSenderMail($sender_mail) {
$this->set('mail', $sender_mail);
}
/**
* Overrides Drupal\Core\Entity\Entity::id().
* {@inheritdoc}
*/
public function id() {
return NULL;
public function getSubject() {
return $this->get('subject')->value;
}
/**
* Overrides Drupal\Core\Entity\Entity::bundle().
* {@inheritdoc}
*/
public function bundle() {
return $this->category;
public function setSubject($subject) {
$this->set('subject', $subject);
}
/**
* {@inheritdoc}
*/
public function isPersonal() {
return $this->bundle() == 'personal';
public function getMessage() {
return $this->get('message')->value;
}
/**
* {@inheritdoc}
*/
public function setMessage($message) {
$this->set('message', $message);
}
/**
* {@inheritdoc}
*/
public function copySender() {
return (bool)$this->get('copy')->value;
}
/**
* {@inheritdoc}
*/
public function setCopySender($inform) {
$this->set('copy', (bool) $inform);
}
/**
* {@inheritdoc}
*/
public function getPersonalRecipient() {
if ($this->isPersonal()) {
return $this->get('recipient')->entity;
}
}
}
......@@ -74,8 +74,16 @@ function testSendPersonalContactMessage() {
$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.');
$this->assertEqual($mail['key'], 'user_mail');
$variables = array(
'!site-name' => config('system.site')->get('name'),
'!subject' => $message['subject'],
'!recipient-name' => $this->contact_user->name,
);
$this->assertEqual($mail['subject'], t('[!site-name] !subject', $variables), 'Subject is in sent message.');
$this->assertTrue(strpos($mail['body'], t('Hello !recipient-name,', $variables)) !== FALSE, 'Recipient name is in sent message.');
$this->assertTrue(strpos($mail['body'], $this->web_user->name) !== FALSE, 'Sender name is in sent message.');
$this->assertTrue(strpos($mail['body'], $message['message']) !== FALSE, 'Message body is in sent message.');
}
/**
......
......@@ -7,6 +7,7 @@
namespace Drupal\contact\Tests;
use Drupal\Component\Utility\Unicode;
use Drupal\simpletest\WebTestBase;
/**
......@@ -19,7 +20,7 @@ class ContactSitewideTest extends WebTestBase {
*
* @var array
*/
public static $modules = array('contact');
public static $modules = array('contact', 'field_ui');
public static function getInfo() {
return array(
......@@ -34,7 +35,12 @@ public static function getInfo() {
*/
function testSiteWideContact() {
// Create and login administrative user.
$admin_user = $this->drupalCreateUser(array('access site-wide contact form', 'administer contact forms', 'administer users'));
$admin_user = $this->drupalCreateUser(array(
'access site-wide contact form',
'administer contact forms',
'administer users',
'administer contact_message fields',
));
$this->drupalLogin($admin_user);
$flood_limit = 3;
......@@ -53,10 +59,14 @@ function testSiteWideContact() {
// Default category exists.
$this->assertLinkByHref('admin/structure/contact/manage/feedback/delete');
// User category could not be changed or deleted.
// Cannot use assertNoLinkByHref() as it does partial URL matching.
$edit_href = 'admin/structure/contact/manage/personal';
$edit_link = $this->xpath('//a[@href=:href]', array(':href' => url($edit_href)));
$this->assertTrue(empty($edit_link), format_string('No link containing href %href found.', array('%href' => $edit_href)));
// Cannot use ::assertNoLinkByHref as it does partial url matching and with
// field_ui enabled admin/structure/contact/manage/personal/fields exists.
$edit_link = $this->xpath('//a[@href=:href]', array(