Issue #1588422 by andypost, disasm, sun, dawehner, vasi1186, alexpott, tim.plunkett, larowlan, Gábor Hojtsy: Convert contact categories to configuration system.

8.0.x
webchick 2012-10-18 01:55:55 -07:00
parent 3088640cc2
commit f63cdc388b
9 changed files with 505 additions and 388 deletions

View File

@ -0,0 +1,5 @@
id: feedback
label: Website feedback
recipients: []
reply: ''
weight: '0'

View File

@ -5,220 +5,47 @@
* Admin page callbacks for the Contact module.
*/
use Drupal\contact\Category;
/**
* Page callback: Lists contact categories.
*
* @see contact_menu()
*/
function contact_category_list() {
$header = array(
t('Category'),
t('Recipients'),
t('Selected'),
t('Operations'),
);
$rows = array();
// Get all the contact categories from the database.
$categories = db_select('contact', 'c')
->addTag('translatable')
->fields('c', array('cid', 'category', 'recipients', 'selected'))
->orderBy('weight')
->orderBy('category')
->execute()
->fetchAll();
// Loop through the categories and add them to the table.
foreach ($categories as $category) {
$row = array();
$row[] = check_plain($category->category);
$row[] = check_plain($category->recipients);
$row[] = ($category->selected ? t('Yes') : t('No'));
$links = array();
$links['edit'] = array(
'title' => t('Edit'),
'href' => 'admin/structure/contact/edit/' . $category->cid,
);
$links['delete'] = array(
'title' => t('Delete'),
'href' => 'admin/structure/contact/delete/' . $category->cid,
);
$row[] = array(
'data' => array(
'#type' => 'operations',
'#links' => $links,
),
);
$rows[] = $row;
}
if (!$rows) {
$rows[] = array(array(
'data' => t('No categories available.'),
'colspan' => 5,
));
}
$build['category_table'] = array(
'#theme' => 'table',
'#header' => $header,
'#rows' => $rows,
);
return $build;
return entity_list_controller('contact_category')->render();
}
/**
* Form constructor for the category edit form.
*
* @param $category
* An array describing the category to be edited. May be empty for new
* categories. Recognized array keys are:
* - category: The name of the category.
* - recipients: A comma-separated list of recipients.
* - reply: (optional) The body of the auto-reply message.
* - weight: The weight of the category.
* - selected: Boolean indicating whether the category should be selected by
* default.
* - cid: The category ID for which the form is to be displayed.
*
* @see contact_menu()
* @see contact_category_edit_form_validate()
* @see contact_category_edit_form_submit()
* @ingroup forms
* Page callback: provides the category creation form.
*/
function contact_category_edit_form($form, &$form_state, array $category = array()) {
// If this is a new category, add the default values.
$category += array(
'category' => '',
'recipients' => '',
'reply' => '',
'weight' => 0,
'selected' => 0,
'cid' => NULL,
);
$form['category'] = array(
'#type' => 'textfield',
'#title' => t('Category'),
'#maxlength' => 255,
'#default_value' => $category['category'],
'#description' => t("Example: 'website feedback' or 'product information'."),
'#required' => TRUE,
);
$form['recipients'] = array(
'#type' => 'textarea',
'#title' => t('Recipients'),
'#default_value' => $category['recipients'],
'#description' => t("Example: 'webmaster@example.com' or 'sales@example.com,support@example.com' . To specify multiple recipients, separate each e-mail address with a comma."),
'#required' => TRUE,
);
$form['reply'] = array(
'#type' => 'textarea',
'#title' => t('Auto-reply'),
'#default_value' => $category['reply'],
'#description' => t('Optional auto-reply. Leave empty if you do not want to send the user an auto-reply message.'),
);
$form['weight'] = array(
'#type' => 'weight',
'#title' => t('Weight'),
'#default_value' => $category['weight'],
'#description' => t('When listing categories, those with lighter (smaller) weights get listed before categories with heavier (larger) weights. Categories with equal weights are sorted alphabetically.'),
);
$form['selected'] = array(
'#type' => 'checkbox',
'#title' => t('Make this the default category.'),
'#default_value' => $category['selected'],
);
$form['cid'] = array(
'#type' => 'value',
'#value' => $category['cid'],
);
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
/**
* Form validation handler for contact_category_edit_form().
*
* @see contact_category_edit_form_submit()
*/
function contact_category_edit_form_validate($form, &$form_state) {
// Validate and each e-mail recipient.
$recipients = explode(',', $form_state['values']['recipients']);
// When creating a new contact form, or renaming the category on an existing
// contact form, make sure that the given category is unique.
$category = $form_state['values']['category'];
$query = db_select('contact', 'c')->condition('c.category', $category, '=');
if (!empty($form_state['values']['cid'])) {
$query->condition('c.cid', $form_state['values']['cid'], '<>');
}
if ($query->countQuery()->execute()->fetchField()) {
form_set_error('category', t('A contact form with category %category already exists.', array('%category' => $category)));
}
foreach ($recipients as &$recipient) {
$recipient = trim($recipient);
if (!valid_email_address($recipient)) {
form_set_error('recipients', t('%recipient is an invalid e-mail address.', array('%recipient' => $recipient)));
}
}
$form_state['values']['recipients'] = implode(',', $recipients);
}
/**
* Form submission handler for contact_category_edit_form().
*
* @see contact_category_edit_form_validate()
*/
function contact_category_edit_form_submit($form, &$form_state) {
if ($form_state['values']['selected']) {
// Unselect all other contact categories.
db_update('contact')
->fields(array('selected' => '0'))
->execute();
}
if (empty($form_state['values']['cid'])) {
drupal_write_record('contact', $form_state['values']);
}
else {
drupal_write_record('contact', $form_state['values'], array('cid'));
}
drupal_set_message(t('Category %category has been saved.', array('%category' => $form_state['values']['category'])));
watchdog('contact', 'Category %category has been saved.', array('%category' => $form_state['values']['category']), WATCHDOG_NOTICE, l(t('Edit'), 'admin/structure/contact/edit/' . $form_state['values']['cid']));
$form_state['redirect'] = 'admin/structure/contact';
function contact_category_add() {
$category = entity_create('contact_category', array());
return entity_get_form($category);
}
/**
* Form constructor for the contact category deletion form.
*
* @param $contact
* Array describing the contact category to be deleted. See the documentation
* of contact_category_edit_form() for the recognized keys.
* @param Drupal\contact\Category $category
* The contact category to be deleted.
*
* @see contact_menu()
* @see contact_category_delete_form_submit()
*/
function contact_category_delete_form($form, &$form_state, array $contact) {
$form['contact'] = array(
function contact_category_delete_form($form, &$form_state, Category $category) {
$form_state['contact_category'] = $category;
$form['id'] = array(
'#type' => 'value',
'#value' => $contact,
'#value' => $category->id(),
);
return confirm_form(
$form,
t('Are you sure you want to delete %category?', array('%category' => $contact['category'])),
t('Are you sure you want to delete %label?', array('%label' => $category->label())),
'admin/structure/contact',
t('This action cannot be undone.'),
t('Delete'),
t('Cancel')
t('Delete')
);
}
@ -226,14 +53,11 @@ function contact_category_delete_form($form, &$form_state, array $contact) {
* Form submission handler for contact_category_delete_form().
*/
function contact_category_delete_form_submit($form, &$form_state) {
$contact = $form['contact']['#value'];
$category = $form_state['contact_category'];
$category->delete();
db_delete('contact')
->condition('cid', $contact['cid'])
->execute();
drupal_set_message(t('Category %category has been deleted.', array('%category' => $contact['category'])));
watchdog('contact', 'Category %category has been deleted.', array('%category' => $contact['category']), WATCHDOG_NOTICE);
drupal_set_message(t('Category %label has been deleted.', array('%label' => $category->label())));
watchdog('contact', 'Category %label has been deleted.', array('%label' => $category->label()), WATCHDOG_NOTICE);
$form_state['redirect'] = 'admin/structure/contact';
}

View File

@ -5,65 +5,6 @@
* Install, update and uninstall functions for the contact module.
*/
/**
* Implements hook_schema().
*/
function contact_schema() {
$schema['contact'] = array(
'description' => 'Contact form category settings.',
'fields' => array(
'cid' => array(
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
'description' => 'Primary Key: Unique category ID.',
),
'category' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
'description' => 'Category name.',
'translatable' => TRUE,
),
'recipients' => array(
'type' => 'text',
'not null' => TRUE,
'size' => 'big',
'description' => 'Comma-separated list of recipient e-mail addresses.',
),
'reply' => array(
'type' => 'text',
'not null' => TRUE,
'size' => 'big',
'description' => 'Text of the auto-reply message.',
),
'weight' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'description' => "The category's weight.",
),
'selected' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'size' => 'tiny',
'description' => 'Flag to indicate whether or not category is selected by default. (1 = Yes, 0 = No)',
),
),
'primary key' => array('cid'),
'unique keys' => array(
'category' => array('category'),
),
'indexes' => array(
'list' => array('weight', 'category'),
),
);
return $schema;
}
/**
* Implements hook_install().
*/
@ -72,17 +13,14 @@ function contact_install() {
if (empty($site_mail)) {
$site_mail = ini_get('sendmail_from');
}
// Insert a default contact category.
db_insert('contact')
->fields(array(
'category' => 'Website feedback',
'recipients' => $site_mail,
'selected' => 1,
'reply' => '',
))
->execute();
config('contact.category.feedback')->set('recipients', array($site_mail))->save();
}
/**
* @addtogroup updates-7.x-to-8.x
* @{
*/
/**
* Moves contact setting from variable to config.
*
@ -95,3 +33,42 @@ function contact_update_8000() {
'contact_threshold_window' => 'flood.interval',
));
}
/**
* Migrate contact categories into configuration.
*
* @ingroup config_upgrade
*/
function contact_update_8001() {
$result = db_query('SELECT * FROM {contact}');
foreach ($result as $category) {
// Take over the category's serial ID as new machine name.
$category->id = $category->cid;
// Save default category setting.
if ($category->selected) {
config('contact.settings')
->set('default_category', $category->id)
->save();
}
// Save the config object.
config('contact.category.' . $category->id)
->set('id', $category->id)
->set('label', $category->category)
->set('recipients', explode(',', $category->recipients))
->set('reply', $category->reply)
->set('weight', $category->weight)
->save();
}
}
/**
* Drop the {contact} table.
*/
function contact_update_8002() {
db_drop_table('contact');
}
/**
* @} End of "defgroup updates-7.x-to-8.x".
* The next series of updates should start at 9000.
*/

View File

@ -5,6 +5,8 @@
* Enables the use of personal and site-wide contact forms.
*/
use Drupal\contact\Category;
/**
* Implements hook_help().
*/
@ -64,22 +66,20 @@ function contact_menu() {
);
$items['admin/structure/contact/add'] = array(
'title' => 'Add category',
'page callback' => 'drupal_get_form',
'page arguments' => array('contact_category_edit_form'),
'page callback' => 'contact_category_add',
'access arguments' => array('administer contact forms'),
'type' => MENU_LOCAL_ACTION,
'weight' => 1,
'file' => 'contact.admin.inc',
);
$items['admin/structure/contact/edit/%contact'] = array(
$items['admin/structure/contact/manage/%contact_category/edit'] = array(
'title' => 'Edit contact category',
'page callback' => 'drupal_get_form',
'page arguments' => array('contact_category_edit_form', 4),
'page callback' => 'entity_get_form',
'page arguments' => array(4),
'access arguments' => array('administer contact forms'),
'file' => 'contact.admin.inc',
);
$items['admin/structure/contact/delete/%contact'] = array(
'title' => 'Delete contact',
$items['admin/structure/contact/manage/%contact_category/delete'] = array(
'title' => 'Delete contact category',
'page callback' => 'drupal_get_form',
'page arguments' => array('contact_category_delete_form', 4),
'access arguments' => array('administer contact forms'),
@ -146,22 +146,105 @@ function _contact_personal_tab_access($account) {
return user_access('access user contact forms');
}
/**
* Implements MODULE_config_import_create().
*/
function contact_config_import_create($name, $new_config, $old_config) {
if (strpos($name, 'contact.category.') !== 0) {
return FALSE;
}
$category = entity_create('contact_category', $new_config->get());
$category->save();
return TRUE;
}
/**
* Implements MODULE_config_import_change().
*/
function contact_config_import_change($name, $new_config, $old_config) {
if (strpos($name, 'contact.category.') !== 0) {
return FALSE;
}
list(, , $id) = explode('.', $name);
$category = entity_load('contact_category', $id);
$category->original = clone $category;
foreach ($old_config->get() as $property => $value) {
$category->original->$property = $value;
}
foreach ($new_config->get() as $property => $value) {
$category->$property = $value;
}
$category->save();
return TRUE;
}
/**
* Implements MODULE_config_import_delete().
*/
function contact_config_import_delete($name, $new_config, $old_config) {
if (strpos($name, 'contact.category.') !== 0) {
return FALSE;
}
list(, , $id) = explode('.', $name);
entity_delete_multiple('contact_category', array($id));
return TRUE;
}
/**
* Implements hook_entity_info().
*/
function contact_entity_info() {
$types['contact_category'] = array(
'label' => 'Category',
'entity class' => 'Drupal\contact\Category',
'controller class' => 'Drupal\Core\Config\Entity\ConfigStorageController',
'list controller class' => 'Drupal\contact\CategoryListController',
'form controller class' => array(
'default' => 'Drupal\contact\CategoryFormController',
),
'uri callback' => 'contact_category_uri',
'config prefix' => 'contact.category',
'entity keys' => array(
'id' => 'id',
'label' => 'label',
'uuid' => 'uuid',
),
);
return $types;
}
/**
* Loads a contact category.
*
* @param $cid
* The contact category ID.
* @param $id
* The ID of the contact category to load.
*
* @return
* An array with the contact category's data.
* @return Drupal\contact\Category|false
* A Category object or FALSE if the requested $id does not exist.
*/
function contact_load($cid) {
return db_select('contact', 'c')
->addTag('translatable')
->fields('c')
->condition('cid', $cid)
->execute()
->fetchAssoc();
function contact_category_load($id) {
return entity_load('contact_category', $id);
}
/**
* Entity URI callback.
*
* @param Drupal\category\Category $category
* A contact category entity.
*
* @return array
* An array with 'path' as the key and the path to the category as the value.
*/
function contact_category_uri(Category $category) {
return array(
'path' => 'admin/structure/contact/manage/' . $category->id(),
);
}
/**
@ -172,7 +255,7 @@ function contact_mail($key, &$message, $params) {
$variables = array(
'!site-name' => config('system.site')->get('name'),
'!subject' => $params['subject'],
'!category' => isset($params['category']['category']) ? $params['category']['category'] : '',
'!category' => isset($params['category']) ? $params['category']->label() : '',
'!form-url' => url(current_path(), array('absolute' => TRUE, 'language' => $language)),
'!sender-name' => user_format_name($params['sender']),
'!sender-url' => $params['sender']->uid ? url('user/' . $params['sender']->uid, array('absolute' => TRUE, 'language' => $language)) : $params['sender']->mail,
@ -188,7 +271,7 @@ function contact_mail($key, &$message, $params) {
case 'page_autoreply':
$message['subject'] .= t('[!category] !subject', $variables, array('langcode' => $language->langcode));
$message['body'][] = $params['category']['reply'];
$message['body'][] = $params['category']->reply;
break;
case 'user_mail':

View File

@ -12,7 +12,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* Form constructor for the site-wide contact form.
*
* @see contact_menu()
* @see contact_site_form_validate()
* @see contact_site_form_submit()
* @ingroup forms
*/
@ -29,14 +28,7 @@ function contact_site_form($form, &$form_state) {
}
// Get an array of the categories and the current default category.
$categories = db_select('contact', 'c')
->addTag('translatable')
->fields('c', array('cid', 'category'))
->orderBy('weight')
->orderBy('category')
->execute()
->fetchAllKeyed();
$default_category = db_query("SELECT cid FROM {contact} WHERE selected = 1")->fetchField();
$categories = entity_load_multiple('contact_category');
// If there are no categories, do not display the form.
if (!$categories) {
@ -48,15 +40,18 @@ function contact_site_form($form, &$form_state) {
}
}
// Prepare array for select options.
uasort($categories, 'Drupal\Core\Config\Entity\ConfigEntityBase::sort');
$options = array();
foreach ($categories as $category) {
$options[$category->id()] = $category->label();
}
// If there is more than one category available and no default category has
// been selected, prepend a default placeholder value.
$default_category = $config->get('default_category');
if (!$default_category) {
if (count($categories) > 1) {
$categories = array(0 => t('- Please choose -')) + $categories;
}
else {
$default_category = key($categories);
}
$default_category = !empty($categories) ? key($categories) : NULL;
}
if (!$user->uid) {
@ -102,11 +97,12 @@ function contact_site_form($form, &$form_state) {
'#maxlength' => 255,
'#required' => TRUE,
);
$form['cid'] = array(
$form['category'] = array(
'#type' => 'select',
'#title' => t('Category'),
'#default_value' => $default_category,
'#options' => $categories,
'#options' => $options,
'#empty_value' => 0,
'#required' => TRUE,
'#access' => count($categories) > 1,
);
@ -131,17 +127,6 @@ function contact_site_form($form, &$form_state) {
return $form;
}
/**
* Form validation handler for contact_site_form().
*
* @see contact_site_form_submit()
*/
function contact_site_form_validate($form, &$form_state) {
if (!$form_state['values']['cid']) {
form_set_error('cid', t('You must select a valid category.'));
}
}
/**
* Form submission handler for contact_site_form().
*
@ -155,7 +140,7 @@ function contact_site_form_submit($form, &$form_state) {
$values['sender'] = $user;
$values['sender']->name = $values['name'];
$values['sender']->mail = $values['mail'];
$values['category'] = contact_load($values['cid']);
$values['category'] = entity_load('contact_category', $values['category']);
if (!$user->uid) {
$values['sender']->name .= ' (' . t('not verified') . ')';
@ -164,7 +149,7 @@ function contact_site_form_submit($form, &$form_state) {
}
// Get the to and from e-mail addresses.
$to = $values['category']['recipients'];
$to = implode(', ', $values['category']->recipients);
$from = $values['sender']->mail;
// Send the e-mail to the recipients using the site default language.
@ -176,12 +161,12 @@ function contact_site_form_submit($form, &$form_state) {
}
// Send an auto-reply if necessary using the current language.
if ($values['category']['reply']) {
if ($values['category']->reply) {
drupal_mail('contact', 'page_autoreply', $from, $language_interface->langcode, $values, $to);
}
flood_register_event('contact', config('contact.settings')->get('flood.interval'));
watchdog('mail', '%sender-name (@sender-from) sent an e-mail regarding %category.', array('%sender-name' => $values['name'], '@sender-from' => $from, '%category' => $values['category']['category']));
watchdog('mail', '%sender-name (@sender-from) sent an e-mail regarding %category.', array('%sender-name' => $values['name'], '@sender-from' => $from, '%category' => $values['category']->label()));
// Jump to home page rather than back to contact page to avoid
// contradictory messages if flood control has been activated.

View File

@ -0,0 +1,59 @@
<?php
/**
* @file
* Definition of Drupal\contact\Category.
*/
namespace Drupal\contact;
use Drupal\Core\Config\Entity\ConfigEntityBase;
/**
* Defines the contact category entity.
*/
class Category extends ConfigEntityBase {
/**
* The category ID.
*
* @var string
*/
public $id;
/**
* The category UUID.
*
* @var string
*/
public $uuid;
/**
* The category label.
*
* @var string
*/
public $label;
/**
* List of recipient e-mail addresses.
*
* @var array
*/
public $recipients = array();
/**
* An auto-reply message to send to the message author.
*
* @var string
*/
public $reply = '';
/**
* Weight of this category (used for sorting).
*
* @var int
*/
public $weight = 0;
}

View File

@ -0,0 +1,148 @@
<?php
/**
* @file
* Definition of Drupal\contact\CategoryFormController.
*/
namespace Drupal\contact;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityFormController;
/**
* Base form controller for category edit forms.
*/
class CategoryFormController extends EntityFormController {
/**
* Overrides Drupal\Core\Entity\EntityFormController::form().
*/
public function form(array $form, array &$form_state, EntityInterface $category) {
$form = parent::form($form, $form_state, $category);
$default_category = config('contact.settings')->get('default_category');
$form['label'] = array(
'#type' => 'textfield',
'#title' => t('Label'),
'#maxlength' => 255,
'#default_value' => $category->label(),
'#description' => t("Example: 'website feedback' or 'product information'."),
'#required' => TRUE,
);
$form['id'] = array(
'#type' => 'machine_name',
'#default_value' => $category->id(),
'#machine_name' => array(
'exists' => 'contact_category_load',
'source' => array('label'),
),
'#disabled' => !$category->isNew(),
);
$form['recipients'] = array(
'#type' => 'textarea',
'#title' => t('Recipients'),
'#default_value' => implode(', ', $category->recipients),
'#description' => t("Example: 'webmaster@example.com' or 'sales@example.com,support@example.com' . To specify multiple recipients, separate each e-mail address with a comma."),
'#required' => TRUE,
);
$form['reply'] = array(
'#type' => 'textarea',
'#title' => t('Auto-reply'),
'#default_value' => $category->reply,
'#description' => t('Optional auto-reply. Leave empty if you do not want to send the user an auto-reply message.'),
);
$form['weight'] = array(
'#type' => 'weight',
'#title' => t('Weight'),
'#default_value' => $category->weight,
'#description' => t('When listing categories, those with lighter (smaller) weights get listed before categories with heavier (larger) weights. Categories with equal weights are sorted alphabetically.'),
);
$form['selected'] = array(
'#type' => 'checkbox',
'#title' => t('Make this the default category.'),
'#default_value' => $default_category === $category->id(),
);
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
/**
* Overrides Drupal\Core\Entity\EntityFormController::validate().
*/
public function validate(array $form, array &$form_state) {
parent::validate($form, $form_state);
// Validate and each e-mail recipient.
$recipients = explode(',', $form_state['values']['recipients']);
foreach ($recipients as &$recipient) {
$recipient = trim($recipient);
if (!valid_email_address($recipient)) {
form_set_error('recipients', t('%recipient is an invalid e-mail address.', array('%recipient' => $recipient)));
}
}
$form_state['values']['recipients'] = $recipients;
}
/**
* Overrides Drupal\Core\Entity\EntityFormController::submit().
*/
public function submit(array $form, array &$form_state) {
// @todo We should not be calling contact_category_delete_form() from
// within the form builder.
if ($form_state['triggering_element']['#value'] == t('Delete')) {
// Rebuild the form to confirm category deletion.
$form_state['redirect'] = 'admin/structure/contact/manage/' . $form_state['values']['id'] . '/delete';
return NULL;
}
return parent::submit($form, $form_state);
}
/**
* Overrides Drupal\Core\Entity\EntityFormController::save().
*/
public function save(array $form, array &$form_state) {
$category = $this->getEntity($form_state);
// Property enforceIsNew is not supported by config entity. So this is only
// way to make sure that entity is not saved.
$is_new = !$category->getOriginalID();
$category->save();
$id = $category->id();
if ($is_new) {
drupal_set_message(t('Category %label has been added.', array('%label' => $category->label())));
watchdog('contact', 'Category %label has been added.', array('%label' => $category->label()), WATCHDOG_NOTICE, l(t('Edit'), 'admin/structure/contact/manage/' . $id . '/edit'));
}
else {
drupal_set_message(t('Category %label has been updated.', array('%label' => $category->label())));
watchdog('contact', 'Category %label has been updated.', array('%label' => $category->label()), WATCHDOG_NOTICE, l(t('Edit'), 'admin/structure/contact/manage/' . $id . '/edit'));
}
// Update the default category.
$contact_config = config('contact.settings');
if ($form_state['values']['selected']) {
$contact_config
->set('default_category', $id)
->save();
}
// If it was the default category, empty out the setting.
elseif ($contact_config->get('default_category') == $id) {
$contact_config
->clear('default_category')
->save();
}
// Remove the 'selected' value, which is not part of the Category.
unset($form_state['values']['selected']);
$form_state['redirect'] = 'admin/structure/contact';
}
}

View File

@ -0,0 +1,40 @@
<?php
/**
* Definition of Drupal\contact\CategoryListController.
*/
namespace Drupal\contact;
use Drupal\Core\Config\Entity\ConfigEntityListController;
use Drupal\Core\Entity\EntityInterface;
/**
* Provides a listing of contact categories.
*/
class CategoryListController extends ConfigEntityListController {
/**
* Overrides Drupal\Core\Entity\EntityListController::buildHeader().
*/
public function buildHeader() {
$row['category'] = t('Category');
$row['recipients'] = t('Recipients');
$row['selected'] = t('Selected');
$row['operations'] = t('Operations');
return $row;
}
/**
* Overrides Drupal\Core\Entity\EntityListController::buildRow().
*/
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'));
$row['operations']['data'] = $this->buildOperations($entity);
return $row;
}
}

View File

@ -66,32 +66,32 @@ class ContactSitewideTest extends WebTestBase {
// Test invalid recipients.
$invalid_recipients = array('invalid', 'invalid@', 'invalid@site.', '@site.', '@site.com');
foreach ($invalid_recipients as $invalid_recipient) {
$this->addCategory($this->randomName(16), $invalid_recipient, '', FALSE);
$this->addCategory($this->randomName(16), $this->randomName(16), $invalid_recipient, '', FALSE);
$this->assertRaw(t('%recipient is an invalid e-mail address.', array('%recipient' => $invalid_recipient)), format_string('Caught invalid recipient (@invalid_recipient)', array('@invalid_recipient' => $invalid_recipient)));
}
// Test validation of empty category and recipients fields.
$this->addCategory($category = '', '', '', TRUE);
$this->assertText(t('Category field is required.'), 'Caught empty category field');
$this->addCategory('', '', '', '', TRUE);
$this->assertText(t('Label field is required.'), 'Caught empty category label field');
$this->assertText(t('Machine-readable name field is required.'), 'Caught empty category name field');
$this->assertText(t('Recipients field is required.'), 'Caught empty recipients field.');
// Create first valid category.
$recipients = array('simpletest@example.com', 'simpletest2@example.com', 'simpletest3@example.com');
$this->addCategory($category = $this->randomName(16), implode(',', array($recipients[0])), '', TRUE);
$this->assertRaw(t('Category %category has been saved.', array('%category' => $category)), 'Category successfully saved.');
$this->addCategory($id = drupal_strtolower($this->randomName(16)), $label = $this->randomName(16), implode(',', array($recipients[0])), '', TRUE);
$this->assertRaw(t('Category %label has been added.', array('%label' => $label)), 'Category successfully added.');
// Make sure the newly created category is included in the list of categories.
$this->assertNoUniqueText($category, 'New category included in categories list.');
$this->assertNoUniqueText($label, 'New category included in categories list.');
// Test update contact form category.
$categories = $this->getCategories();
$category_id = $this->updateCategory($categories, $category = $this->randomName(16), $recipients_str = implode(',', array($recipients[0], $recipients[1])), $reply = $this->randomName(30), FALSE);
$category_array = db_query("SELECT category, recipients, reply, selected FROM {contact} WHERE cid = :cid", array(':cid' => $category_id))->fetchAssoc();
$this->assertEqual($category_array['category'], $category);
$this->assertEqual($category_array['recipients'], $recipients_str);
$this->assertEqual($category_array['reply'], $reply);
$this->assertFalse($category_array['selected']);
$this->assertRaw(t('Category %category has been saved.', array('%category' => $category)), 'Category successfully saved.');
$this->updateCategory($id, $label = $this->randomName(16), $recipients_str = implode(',', array($recipients[0], $recipients[1])), $reply = $this->randomName(30), FALSE);
$config = config('contact.category.' . $id)->get();
$this->assertEqual($config['label'], $label);
$this->assertEqual($config['recipients'], array($recipients[0], $recipients[1]));
$this->assertEqual($config['reply'], $reply);
$this->assertNotEqual($id, config('contact.settings')->get('default_category'));
$this->assertRaw(t('Category %label has been updated.', array('%label' => $label)), 'Category successfully updated.');
// Ensure that the contact form is shown without a category selection input.
user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access site-wide contact form'));
@ -102,16 +102,16 @@ class ContactSitewideTest extends WebTestBase {
$this->drupalLogin($admin_user);
// Add more categories.
$this->addCategory($category = $this->randomName(16), implode(',', array($recipients[0], $recipients[1])), '', FALSE);
$this->assertRaw(t('Category %category has been saved.', array('%category' => $category)), 'Category successfully saved.');
$this->addCategory(drupal_strtolower($this->randomName(16)), $label = $this->randomName(16), implode(',', array($recipients[0], $recipients[1])), '', FALSE);
$this->assertRaw(t('Category %label has been added.', array('%label' => $label)), 'Category successfully added.');
$this->addCategory($category = $this->randomName(16), implode(',', array($recipients[0], $recipients[1], $recipients[2])), '', FALSE);
$this->assertRaw(t('Category %category has been saved.', array('%category' => $category)), 'Category successfully saved.');
$this->addCategory($name = drupal_strtolower($this->randomName(16)), $label = $this->randomName(16), implode(',', array($recipients[0], $recipients[1], $recipients[2])), '', FALSE);
$this->assertRaw(t('Category %label has been added.', array('%label' => $label)), 'Category successfully added.');
// Try adding a category that already exists.
$this->addCategory($category, '', '', FALSE);
$this->assertNoRaw(t('Category %category has been saved.', array('%category' => $category)), 'Category not saved.');
$this->assertRaw(t('A contact form with category %category already exists.', array('%category' => $category)), 'Duplicate category error found.');
$this->addCategory($name, $label, '', '', FALSE);
$this->assertNoRaw(t('Category %label has been saved.', array('%label' => $label)), 'Category not saved.');
$this->assertRaw(t('The machine-readable name is already in use. It must be unique.'), 'Duplicate category error found.');
// Clear flood table in preparation for flood test and allow other checks to complete.
db_delete('flood')->execute();
@ -130,35 +130,38 @@ class ContactSitewideTest extends WebTestBase {
$this->assertResponse(200, 'Access granted to anonymous user with permission.');
// Submit contact form with invalid values.
$this->submitContact('', $recipients[0], $this->randomName(16), $categories[0], $this->randomName(64));
$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.'), 'Name required.');
$this->submitContact($this->randomName(16), '', $this->randomName(16), $categories[0], $this->randomName(64));
$this->submitContact($this->randomName(16), '', $this->randomName(16), $id, $this->randomName(64));
$this->assertText(t('Your e-mail address field is required.'), 'E-mail required.');
$this->submitContact($this->randomName(16), $invalid_recipients[0], $this->randomName(16), $categories[0], $this->randomName(64));
$this->submitContact($this->randomName(16), $invalid_recipients[0], $this->randomName(16), $id, $this->randomName(64));
$this->assertRaw(t('The e-mail address %mail is not valid.', array('%mail' => 'invalid')), 'Valid e-mail required.');
$this->submitContact($this->randomName(16), $recipients[0], '', $categories[0], $this->randomName(64));
$this->submitContact($this->randomName(16), $recipients[0], '', $id, $this->randomName(64));
$this->assertText(t('Subject field is required.'), 'Subject required.');
$this->submitContact($this->randomName(16), $recipients[0], $this->randomName(16), $categories[0], '');
$this->submitContact($this->randomName(16), $recipients[0], $this->randomName(16), $id, '');
$this->assertText(t('Message field is required.'), 'Message required.');
// Test contact form with no default category selected.
db_update('contact')
->fields(array('selected' => 0))
->execute();
config('contact.settings')
->set('default_category', '')
->save();
$this->drupalGet('contact');
$this->assertRaw(t('- Please choose -'), 'Without selected categories the visitor is asked to chose a category.');
$this->assertRaw(t('- Select -'), 'Without selected categories the visitor is asked to chose a category.');
// Submit contact form with invalid category id (cid 0).
$this->submitContact($this->randomName(16), $recipients[0], $this->randomName(16), 0, '');
$this->assertText(t('You must select a valid category.'), 'Valid category required.');
$this->assertText(t('Category field is required.'), 'Valid category required.');
// Submit contact form with correct values and check flood interval.
for ($i = 0; $i < $flood_limit; $i++) {
$this->submitContact($this->randomName(16), $recipients[0], $this->randomName(16), $categories[0], $this->randomName(64));
$this->submitContact($this->randomName(16), $recipients[0], $this->randomName(16), $id, $this->randomName(64));
$this->assertText(t('Your message has been sent.'), 'Message sent.');
}
// Submit contact form one over limit.
@ -182,9 +185,9 @@ class ContactSitewideTest extends WebTestBase {
// Set up three categories, 2 with an auto-reply and one without.
$foo_autoreply = $this->randomName(40);
$bar_autoreply = $this->randomName(40);
$this->addCategory('foo', 'foo@example.com', $foo_autoreply, FALSE);
$this->addCategory('bar', 'bar@example.com', $bar_autoreply, FALSE);
$this->addCategory('no_autoreply', 'bar@example.com', '', FALSE);
$this->addCategory('foo', 'foo', 'foo@example.com', $foo_autoreply, FALSE);
$this->addCategory('bar', 'bar', 'bar@example.com', $bar_autoreply, FALSE);
$this->addCategory('no_autoreply', 'no_autoreply', 'bar@example.com', '', FALSE);
// Log the current user out in order to test the name and e-mail fields.
$this->drupalLogout();
@ -193,34 +196,36 @@ class ContactSitewideTest extends WebTestBase {
// Test the auto-reply for category 'foo'.
$email = $this->randomName(32) . '@example.com';
$subject = $this->randomName(64);
$this->submitContact($this->randomName(16), $email, $subject, 2, $this->randomString(128));
$this->submitContact($this->randomName(16), $email, $subject, 'foo', $this->randomString(128));
// We are testing the auto-reply, so there should be one e-mail going to the sender.
$captured_emails = $this->drupalGetMails(array('id' => 'contact_page_autoreply', 'to' => $email, 'from' => 'foo@example.com'));
$this->assertEqual(count($captured_emails), 1, t('Auto-reply e-mail was sent to the sender for category "foo".'), 'Contact');
$this->assertEqual($captured_emails[0]['body'], drupal_html_to_text($foo_autoreply), t('Auto-reply e-mail body is correct for category "foo".'), 'Contact');
$this->assertEqual(count($captured_emails), 1);
$this->assertEqual($captured_emails[0]['body'], drupal_html_to_text($foo_autoreply));
// Test the auto-reply for category 'bar'.
$email = $this->randomName(32) . '@example.com';
$this->submitContact($this->randomName(16), $email, $this->randomString(64), 3, $this->randomString(128));
$this->submitContact($this->randomName(16), $email, $this->randomString(64), 'bar', $this->randomString(128));
// Auto-reply for category 'bar' should result in one auto-reply e-mail to the sender.
$captured_emails = $this->drupalGetMails(array('id' => 'contact_page_autoreply', 'to' => $email, 'from' => 'bar@example.com'));
$this->assertEqual(count($captured_emails), 1, t('Auto-reply e-mail was sent to the sender for category "bar".'), 'Contact');
$this->assertEqual($captured_emails[0]['body'], drupal_html_to_text($bar_autoreply), t('Auto-reply e-mail body is correct for category "bar".'), 'Contact');
$this->assertEqual(count($captured_emails), 1);
$this->assertEqual($captured_emails[0]['body'], drupal_html_to_text($bar_autoreply));
// Verify that no auto-reply is sent when the auto-reply field is left blank.
$email = $this->randomName(32) . '@example.com';
$this->submitContact($this->randomName(16), $email, $this->randomString(64), 4, $this->randomString(128));
$this->submitContact($this->randomName(16), $email, $this->randomString(64), 'no_autoreply', $this->randomString(128));
$captured_emails = $this->drupalGetMails(array('id' => 'contact_page_autoreply', 'to' => $email, 'from' => 'no_autoreply@example.com'));
$this->assertEqual(count($captured_emails), 0, t('No auto-reply e-mail was sent to the sender for category "no-autoreply".'), 'Contact');
$this->assertEqual(count($captured_emails), 0);
}
/**
* Adds a category.
*
* @param string $category
* The category name.
* @param string $id
* The category machine name.
* @param string $label
* The category label.
* @param string $recipients
* The list of recipient e-mail addresses.
* @param string $reply
@ -229,9 +234,10 @@ class ContactSitewideTest extends WebTestBase {
* @param boolean $selected
* Boolean indicating whether the category should be selected by default.
*/
function addCategory($category, $recipients, $reply, $selected) {
function addCategory($id, $label, $recipients, $reply, $selected) {
$edit = array();
$edit['category'] = $category;
$edit['label'] = $label;
$edit['id'] = $id;
$edit['recipients'] = $recipients;
$edit['reply'] = $reply;
$edit['selected'] = ($selected ? TRUE : FALSE);
@ -241,8 +247,10 @@ class ContactSitewideTest extends WebTestBase {
/**
* Updates a category.
*
* @param string $category
* The category name.
* @param string $id
* The category machine name.
* @param string $label
* The category label.
* @param string $recipients
* The list of recipient e-mail addresses.
* @param string $reply
@ -251,15 +259,13 @@ class ContactSitewideTest extends WebTestBase {
* @param boolean $selected
* Boolean indicating whether the category should be selected by default.
*/
function updateCategory($categories, $category, $recipients, $reply, $selected) {
$category_id = $categories[array_rand($categories)];
function updateCategory($id, $label, $recipients, $reply, $selected) {
$edit = array();
$edit['category'] = $category;
$edit['label'] = $label;
$edit['recipients'] = $recipients;
$edit['reply'] = $reply;
$edit['selected'] = ($selected ? TRUE : FALSE);
$this->drupalPost('admin/structure/contact/edit/' . $category_id, $edit, t('Save'));
return ($category_id);
$this->drupalPost("admin/structure/contact/manage/$id/edit", $edit, t('Save'));
}
/**
@ -271,17 +277,17 @@ class ContactSitewideTest extends WebTestBase {
* The e-mail address of the sender.
* @param string $subject
* The subject of the message.
* @param integer $cid
* @param string $id
* The category ID of the message.
* @param string $message
* The message body.
*/
function submitContact($name, $mail, $subject, $cid, $message) {
function submitContact($name, $mail, $subject, $id, $message) {
$edit = array();
$edit['name'] = $name;
$edit['mail'] = $mail;
$edit['subject'] = $subject;
$edit['cid'] = $cid;
$edit['category'] = $id;
$edit['message'] = $message;
$this->drupalPost('contact', $edit, t('Send message'));
}
@ -290,22 +296,12 @@ class ContactSitewideTest extends WebTestBase {
* Deletes all categories.
*/
function deleteCategories() {
$categories = $this->getCategories();
foreach ($categories as $category) {
$category_name = db_query("SELECT category FROM {contact} WHERE cid = :cid", array(':cid' => $category))->fetchField();
$this->drupalPost('admin/structure/contact/delete/' . $category, array(), t('Delete'));
$this->assertRaw(t('Category %category has been deleted.', array('%category' => $category_name)), 'Category deleted successfully.');
$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())), 'Category deleted successfully.');
$this->assertFalse(entity_load('contact_category', $id), format_string('Category %category not found', array('%category' => $category->label())));
}
}
/**
* Gets a list of all category IDs.
*
* @return array
* A list of the category IDs.
*/
function getCategories() {
$categories = db_query('SELECT cid FROM {contact}')->fetchCol();
return $categories;
}
}