diff --git a/core/modules/contact/config/contact.category.feedback.yml b/core/modules/contact/config/contact.category.feedback.yml new file mode 100644 index 0000000..7d3c686 --- /dev/null +++ b/core/modules/contact/config/contact.category.feedback.yml @@ -0,0 +1,5 @@ +id: feedback +label: Website feedback +recipients: [] +reply: '' +weight: '0' diff --git a/core/modules/contact/contact.admin.inc b/core/modules/contact/contact.admin.inc index f6835f9..3dae818 100644 --- a/core/modules/contact/contact.admin.inc +++ b/core/modules/contact/contact.admin.inc @@ -5,6 +5,8 @@ * Admin page callbacks for the Contact module. */ +use Drupal\contact\Category; + /** * Page callback: Lists contact categories. * @@ -19,23 +21,18 @@ function contact_category_list() { ); $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(); + $categories = entity_load_multiple('contact_category'); + uasort($categories, 'Drupal\config\ConfigurableBase::sort'); + $default_category = config('contact.settings')->get('default_category'); // Loop through the categories and add them to the table. foreach ($categories as $category) { $rows[] = array( - check_plain($category->category), - check_plain($category->recipients), - ($category->selected ? t('Yes') : t('No')), - l(t('Edit'), 'admin/structure/contact/edit/' . $category->cid), - l(t('Delete'), 'admin/structure/contact/delete/' . $category->cid), + check_plain($category->label()), + check_plain(implode(', ', $category->recipients)), + ($default_category == $category->id() ? t('Yes') : t('No')), + l(t('Edit'), 'admin/structure/contact/manage/' . $category->id()), + l(t('Delete'), 'admin/structure/contact/manage/' . $category->id() . '/delete'), ); } @@ -57,68 +54,70 @@ function contact_category_list() { /** * 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. + * @param Drupal\contact\Category $category + * (optional) The contact category to be edited. * * @see contact_menu() * @see contact_category_edit_form_validate() * @see contact_category_edit_form_submit() * @ingroup forms */ -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, - ); +function contact_category_edit_form($form, &$form_state, Category $category = NULL) { + // During initial form build, add the entity to the form state for use + // during form building and processing. During a rebuild, use what is in the + // form state. + if (!isset($form_state['contact_category'])) { + if (!isset($category)) { + $category = entity_create('contact_category', array()); + } + $form_state['contact_category'] = $category; + } + else { + $category = $form_state['contact_category']; + } - $form['category'] = array( + $default_category = config('contact.settings')->get('default_category'); + + $form['label'] = array( '#type' => 'textfield', - '#title' => t('Category'), + '#title' => t('Label'), '#maxlength' => 255, - '#default_value' => $category['category'], + '#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' => (bool) $category->id(), + ); $form['recipients'] = array( '#type' => 'textarea', '#title' => t('Recipients'), - '#default_value' => $category['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'], + '#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'], + '#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'], + '#default_value' => $default_category === $category->id(), ); $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array( @@ -138,24 +137,13 @@ 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_state['values']['recipients'] = $recipients; } /** @@ -164,48 +152,57 @@ function contact_category_edit_form_validate($form, &$form_state) { * @see contact_category_edit_form_validate() */ function contact_category_edit_form_submit($form, &$form_state) { + // Update the default category. + $contact_config = config('contact.settings'); if ($form_state['values']['selected']) { - // Unselect all other contact categories. - db_update('contact') - ->fields(array('selected' => '0')) - ->execute(); + $contact_config + ->set('default_category', $form_state['values']['id']) + ->save(); } - - if (empty($form_state['values']['cid'])) { - drupal_write_record('contact', $form_state['values']); - } - else { - drupal_write_record('contact', $form_state['values'], array('cid')); + // If it was the default category, empty out the setting. + elseif ($contact_config->get('default_category') == $form_state['values']['id']) { + $contact_config + ->clear('default_category') + ->save(); } - 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'])); + // Remove the 'selected' value, which is not part of the Category. + unset($form_state['values']['selected']); + form_state_values_clean($form_state); + + $category = $form_state['contact_category']; + entity_form_submit_build_entity('contact_category', $category, $form, $form_state); + + $category->save(); + + drupal_set_message(t('Category %label has been saved.', array('%label' => $category->label()))); + watchdog('contact', 'Category %label has been saved.', array('%label' => $category->label()), WATCHDOG_NOTICE, l(t('Edit'), 'admin/structure/contact/manage/' . $category->id())); + $form_state['redirect'] = 'admin/structure/contact'; } /** * 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') ); } @@ -213,14 +210,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']; - - db_delete('contact') - ->condition('cid', $contact['cid']) - ->execute(); + $category = $form_state['contact_category']; + $category->delete(); - 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'; } diff --git a/core/modules/contact/contact.info b/core/modules/contact/contact.info index eff6d33..b04cd1d 100644 --- a/core/modules/contact/contact.info +++ b/core/modules/contact/contact.info @@ -4,3 +4,4 @@ package = Core version = VERSION core = 8.x configure = admin/structure/contact +dependencies[] = config diff --git a/core/modules/contact/contact.install b/core/modules/contact/contact.install index f956242..ee83410 100644 --- a/core/modules/contact/contact.install +++ b/core/modules/contact/contact.install @@ -6,65 +6,6 @@ */ /** - * 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(). */ function contact_install() { @@ -72,18 +13,15 @@ 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. * * @ingroup config_upgrade @@ -95,3 +33,49 @@ 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) { + // Generate machine readable names. + if ($category->category == 'Website feedback') { + // Use default id for unchanged category. + $category->id = 'feedback'; + } + else { + $category->id = drupal_strtolower($category->category); + $category->id = preg_replace('@[^a-z0-9]@', '_', $category->id); + } + // 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. + */ diff --git a/core/modules/contact/contact.module b/core/modules/contact/contact.module index 1ba70b9..34678f7 100644 --- a/core/modules/contact/contact.module +++ b/core/modules/contact/contact.module @@ -5,6 +5,8 @@ * Enables the use of personal and site-wide contact forms. */ +use Drupal\contact\Category; + /** * Implements hook_help(). */ @@ -71,15 +73,15 @@ function contact_menu() { 'weight' => 1, 'file' => 'contact.admin.inc', ); - $items['admin/structure/contact/edit/%contact'] = array( + $items['admin/structure/contact/manage/%contact_category'] = array( 'title' => 'Edit contact category', 'page callback' => 'drupal_get_form', 'page arguments' => array('contact_category_edit_form', 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'), @@ -147,21 +149,84 @@ function _contact_personal_tab_access($account) { } /** + * 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', + 'controller class' => 'Drupal\config\ConfigStorageController', + 'entity class' => 'Drupal\contact\Category', + '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); } /** @@ -172,7 +237,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 +253,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': diff --git a/core/modules/contact/contact.pages.inc b/core/modules/contact/contact.pages.inc index 92d73bc..0d2415f 100644 --- a/core/modules/contact/contact.pages.inc +++ b/core/modules/contact/contact.pages.inc @@ -12,7 +12,6 @@ * 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\config\ConfigurableBase::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) { @@ -103,11 +98,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, ); @@ -133,17 +129,6 @@ function contact_site_form($form, &$form_state) { } /** - * 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(). * * @see contact_site_form_validate() @@ -156,7 +141,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'] = contact_category_load($values['category']); // Save the anonymous user information to a cookie for reuse. if (!$user->uid) { @@ -165,7 +150,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. @@ -177,12 +162,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, $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. diff --git a/core/modules/contact/lib/Drupal/contact/Category.php b/core/modules/contact/lib/Drupal/contact/Category.php new file mode 100644 index 0000000..70d2742 --- /dev/null +++ b/core/modules/contact/lib/Drupal/contact/Category.php @@ -0,0 +1,59 @@ +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)), t('Caught invalid recipient (' . $invalid_recipient . ').')); } // Test validation of empty category and recipients fields. - $this->addCategory($category = '', '', '', TRUE); - $this->assertText(t('Category field is required.'), t('Caught empty category field')); + $this->addCategory('', '', '', '', TRUE); + $this->assertText(t('Label field is required.'), t('Caught empty category field')); $this->assertText(t('Recipients field is required.'), t('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)), t('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 saved.', array('%label' => $label)), t('Category successfully saved.')); // Make sure the newly created category is included in the list of categories. - $this->assertNoUniqueText($category, t('New category included in categories list.')); + $this->assertNoUniqueText($label, t('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)), t('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 saved.', array('%label' => $label)), t('Category successfully saved.')); // 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 +101,16 @@ function testSiteWideContact() { $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)), t('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 saved.', array('%label' => $label)), t('Category successfully saved.')); - $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)), t('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 saved.', array('%label' => $label)), t('Category successfully saved.')); // Try adding a category that already exists. - $this->addCategory($category, '', '', FALSE); - $this->assertNoRaw(t('Category %category has been saved.', array('%category' => $category)), t('Category not saved.')); - $this->assertRaw(t('A contact form with category %category already exists.', array('%category' => $category)), t('Duplicate category error found.')); + $this->addCategory($name, $label, '', '', FALSE); + $this->assertNoRaw(t('Category %label has been saved.', array('%label' => $label)), t('Category not saved.')); + $this->assertRaw(t('The machine-readable name is already in use. It must be unique.'), t('Duplicate category error found.')); // Clear flood table in preparation for flood test and allow other checks to complete. db_delete('flood')->execute(); @@ -130,36 +129,39 @@ function testSiteWideContact() { $this->assertResponse(200, t('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.'), t('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.'), t('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.'), t('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.'), t('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 -'), t('Without selected categories the visitor is asked to chose a category.')); + $this->assertRaw(t('- Select -'), t('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.'), t('Valid category required.')); + $this->assertText('Category field is 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->assertText(t('Your message has been sent.'), t('Message sent.')); + $this->submitContact($this->randomName(16), $recipients[0], $this->randomName(16), $id, $this->randomName(64)); + $this->assertText(t('Your message has been sent.')); } // Submit contact form one over limit. $this->drupalGet('contact'); @@ -182,9 +184,9 @@ function testAutoReply() { // 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 +195,36 @@ function testAutoReply() { // 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".'), t('Contact')); - $this->assertEqual($captured_emails[0]['body'], drupal_html_to_text($foo_autoreply), t('Auto-reply e-mail body is correct for category "foo".'), t('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".'), t('Contact')); - $this->assertEqual($captured_emails[0]['body'], drupal_html_to_text($bar_autoreply), t('Auto-reply e-mail body is correct for category "bar".'), t('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".'), t('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 +233,10 @@ function testAutoReply() { * @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 +246,10 @@ function addCategory($category, $recipients, $reply, $selected) { /** * 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 +258,13 @@ function addCategory($category, $recipients, $reply, $selected) { * @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, t('Save')); } /** @@ -271,17 +276,17 @@ function updateCategory($categories, $category, $recipients, $reply, $selected) * 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 +295,11 @@ function submitContact($name, $mail, $subject, $cid, $message) { * 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)), t('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())), t('Category deleted successfully.')); } } - /** - * 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; - } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Module/ModuleApiTest.php b/core/modules/system/lib/Drupal/system/Tests/Module/ModuleApiTest.php index 8468185..8177165 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Module/ModuleApiTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Module/ModuleApiTest.php @@ -45,6 +45,8 @@ function testModuleList() { // Try to install a new module. module_enable(array('contact')); $module_list[] = 'contact'; + // Contact module requires config. + $module_list[] = 'config'; sort($module_list); $this->assertModuleList($module_list, t('After adding a module'));