diff --git a/core/modules/contact/config/contact.category.feedback.xml b/core/modules/contact/config/contact.category.feedback.xml new file mode 100644 index 0000000..4328711 --- /dev/null +++ b/core/modules/contact/config/contact.category.feedback.xml @@ -0,0 +1,7 @@ + + + feedback + Website feedback + test@example.com + 0 + diff --git a/core/modules/contact/config/contact.default_category.xml b/core/modules/contact/config/contact.default_category.xml new file mode 100644 index 0000000..e8a659e --- /dev/null +++ b/core/modules/contact/config/contact.default_category.xml @@ -0,0 +1,4 @@ + + + feedback + diff --git a/core/modules/contact/contact.admin.inc b/core/modules/contact/contact.admin.inc index 7b1c90b..52e14da 100644 --- a/core/modules/contact/contact.admin.inc +++ b/core/modules/contact/contact.admin.inc @@ -20,22 +20,21 @@ 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(); + // @todo: Translatables. + $categories = config_get_storage_names_with_prefix('contact.category'); + $default_category = config('contact.default_category')->get('name'); // Loop through the categories and add them to the table. - foreach ($categories as $category) { + + foreach ($categories as $name) { + // @todo: Figure out how to not call config() forreach categories. + $category = config($name)->get(); $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['category']), + check_plain($category['recipients']), + ($default_category == $category['name'] ? t('Yes') : t('No')), + l(t('Edit'), 'admin/structure/contact/edit/' . $category['name']), + l(t('Delete'), 'admin/structure/contact/delete/' . $category['name']), ); } @@ -80,10 +79,11 @@ function contact_category_edit_form($form, &$form_state, array $category = array 'recipients' => '', 'reply' => '', 'weight' => 0, - 'selected' => 0, 'cid' => NULL, ); + $default_category = config('contact.default_category')->get('name'); + $form['category'] = array( '#type' => 'textfield', '#title' => t('Category'), @@ -92,6 +92,23 @@ function contact_category_edit_form($form, &$form_state, array $category = array '#description' => t("Example: 'website feedback' or 'product information'."), '#required' => TRUE, ); + $form['name'] = array( + '#type' => 'machine_name', + '#required' => TRUE, + '#default_value' => isset($category['name']) ? $category['name'] : '', + '#maxlength' => 255, + '#machine_name' => array( + 'exists' => 'contact_category_exists', + 'source' => array('category'), + ), + '#disabled' => !empty($category['name']), + ); + + $form['is_new'] = array( + '#type' => 'value', + '#value' => !isset($category['name']), + ); + $form['recipients'] = array( '#type' => 'textarea', '#title' => t('Recipients'), @@ -118,7 +135,7 @@ function contact_category_edit_form($form, &$form_state, array $category = array 0 => t('No'), 1 => t('Yes'), ), - '#default_value' => $category['selected'], + '#default_value' => isset($category['name']) && $default_category == $category['name'], '#description' => t('Set this to Yes if you would like this category to be selected by default.'), ); $form['cid'] = array( @@ -143,15 +160,10 @@ 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))); + // When creating a new contact form make sure that the given category is unique. + $name = $form_state['values']['name']; + if ($form_state['values']['is_new'] && contact_category_exists($name)) { + form_set_error('category', t('A contact form with name %name already exists.', array('%name' => $name))); } foreach ($recipients as &$recipient) { @@ -164,24 +176,48 @@ function contact_category_edit_form_validate($form, &$form_state) { } /** + * Checks whether a contact category with a certain name already exists. + * + * @param string $name + * The machine name of the category. + * + * @return bool + * Returns TRUE if the contact category exists. + */ +function contact_category_exists($name) { + $config = config('contact.category.' . $name)->get(); + return !empty($config); +} + +/** * Form submission handler for contact_category_edit_form(). * * @see contact_category_edit_form_validate() */ function contact_category_edit_form_submit($form, &$form_state) { + $default_category = config('contact.default_category')->get('name'); if ($form_state['values']['selected']) { - // Unselect all other contact categories. - db_update('contact') - ->fields(array('selected' => '0')) - ->execute(); + // Update new default category. + $default_category_config = config('contact.default_category')->set('name', $form_state['values']['name']); + $default_category_config->save(); } - - if (empty($form_state['values']['cid'])) { - drupal_write_record('contact', $form_state['values']); + elseif ($default_category == $form_state['values']['name']) { + config('contact.default_category')->delete(); } - else { - drupal_write_record('contact', $form_state['values'], array('cid')); + + $name = $form_state['values']['name']; + $category_config = array( + 'name' => $name, + 'category' => $form_state['values']['category'], + 'recipients' => $form_state['values']['recipients'], + 'reply' => $form_state['values']['reply'], + 'weight' => $form_state['values']['weight'], + ); + $config = config('contact.category.' . $name); + foreach ($category_config as $key => $value) { + $config->set($key, $value); } + $config->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'])); @@ -220,9 +256,7 @@ function contact_category_delete_form($form, &$form_state, array $contact) { function contact_category_delete_form_submit($form, &$form_state) { $contact = $form['contact']['#value']; - db_delete('contact') - ->condition('cid', $contact['cid']) - ->execute(); + config('config.category.' . $contact['name'])->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); diff --git a/core/modules/contact/contact.install b/core/modules/contact/contact.install index 7ddea45..ed232c5 100644 --- a/core/modules/contact/contact.install +++ b/core/modules/contact/contact.install @@ -6,80 +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() { - // Insert a default contact category. - db_insert('contact') - ->fields(array( - 'category' => 'Website feedback', - 'recipients' => variable_get('site_mail', ini_get('sendmail_from')), - 'selected' => 1, - 'reply' => '', - )) - ->execute(); -} - -/** * Implements hook_uninstall(). */ function contact_uninstall() { diff --git a/core/modules/contact/contact.module b/core/modules/contact/contact.module index 48c12d9..58831b0 100644 --- a/core/modules/contact/contact.module +++ b/core/modules/contact/contact.module @@ -149,19 +149,15 @@ function _contact_personal_tab_access($account) { /** * Loads a contact category. * - * @param $cid - * The contact category ID. + * @param $name + * The contact category name. * * @return * An array with the contact category's data. */ -function contact_load($cid) { - return db_select('contact', 'c') - ->addTag('translatable') - ->fields('c') - ->condition('cid', $cid) - ->execute() - ->fetchAssoc(); +function contact_load($name) { + // @todo: What about translatable? + return config('contact.category.' . $name)->get(); } /** diff --git a/core/modules/contact/contact.pages.inc b/core/modules/contact/contact.pages.inc index bf096a7..9421bf6 100644 --- a/core/modules/contact/contact.pages.inc +++ b/core/modules/contact/contact.pages.inc @@ -26,14 +26,14 @@ 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(); + // @todo: Fix translatable. + $categories_names = config_get_storage_names_with_prefix('contact.category'); + $categories = array(); + foreach ($categories_names as $config_name) { + $category = config($config_name)->get(); + $categories[$category['name']] = $category['category']; + } + $default_category = config('contact.default_category')->get('name'); // If there are no categories, do not display the form. if (!$categories) { @@ -82,7 +82,7 @@ function contact_site_form($form, &$form_state) { '#maxlength' => 255, '#required' => TRUE, ); - $form['cid'] = array( + $form['category_name'] = array( '#type' => 'select', '#title' => t('Category'), '#default_value' => $default_category, @@ -117,8 +117,8 @@ function contact_site_form($form, &$form_state) { * @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.')); + if (!$form_state['values']['category_name']) { + form_set_error('category_name', t('You must select a valid category.')); } } @@ -134,7 +134,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_load($values['category_name']); // Save the anonymous user information to a cookie for reuse. if (!$user->uid) { diff --git a/core/modules/contact/contact.test b/core/modules/contact/contact.test index c80f21d..5e9e413 100644 --- a/core/modules/contact/contact.test +++ b/core/modules/contact/contact.test @@ -57,18 +57,18 @@ class ContactSitewideTestCase 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)), t('Caught invalid recipient (' . $invalid_recipient . ').')); } // Test validation of empty category and recipients fields. - $this->addCategory($category = '', '', '', TRUE); + $this->addCategory($category = '', '', '', '', TRUE); $this->assertText(t('Category 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->addCategory($category = $this->randomName(16), drupal_strtolower($this->randomName(16)), implode(',', array($recipients[0])), '', TRUE); $this->assertRaw(t('Category %category has been saved.', array('%category' => $category)), t('Category successfully saved.')); // Make sure the newly created category is included in the list of categories. @@ -76,12 +76,12 @@ class ContactSitewideTestCase extends WebTestBase { // 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(); + $category_name = $this->updateCategory($categories, $category = $this->randomName(16), drupal_strtolower($this->randomName(16)), $recipients_str = implode(',', array($recipients[0], $recipients[1])), $reply = $this->randomName(30), FALSE); + $category_array = config('contact.category.' . $category_name)->get(); $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->assertNotEqual($category_name, config('contact.default_category')->get('name')); $this->assertRaw(t('Category %category has been saved.', array('%category' => $category)), t('Category successfully saved.')); // Ensure that the contact form is shown without a category selection input. @@ -93,14 +93,14 @@ class ContactSitewideTestCase extends WebTestBase { $this->drupalLogin($admin_user); // Add more categories. - $this->addCategory($category = $this->randomName(16), implode(',', array($recipients[0], $recipients[1])), '', FALSE); + $this->addCategory($category = $this->randomName(16), drupal_strtolower($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($category = $this->randomName(16), implode(',', array($recipients[0], $recipients[1], $recipients[2])), '', FALSE); + $this->addCategory($category = $this->randomName(16), $name = drupal_strtolower($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.')); // Try adding a category that already exists. - $this->addCategory($category, '', '', FALSE); + $this->addCategory($category, $name, '', '', 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.')); @@ -137,9 +137,7 @@ class ContactSitewideTestCase extends WebTestBase { $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.default_category')->delete(); $this->drupalGet('contact'); $this->assertRaw(t('- Please choose -'), t('Without selected categories the visitor is asked to chose a category.')); @@ -173,14 +171,14 @@ class ContactSitewideTestCase 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); // 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')); @@ -189,7 +187,7 @@ class ContactSitewideTestCase extends WebTestBase { // 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')); @@ -198,7 +196,7 @@ class ContactSitewideTestCase extends WebTestBase { // 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')); } @@ -207,7 +205,9 @@ class ContactSitewideTestCase extends WebTestBase { * Adds a category. * * @param string $category - * The category name. + * The category title. + * @param string $name + * The category machine name. * @param string $recipients * The list of recipient e-mail addresses. * @param string $reply @@ -216,9 +216,10 @@ class ContactSitewideTestCase extends WebTestBase { * @param boolean $selected * Boolean indicating whether the category should be selected by default. */ - function addCategory($category, $recipients, $reply, $selected) { + function addCategory($category, $name, $recipients, $reply, $selected) { $edit = array(); $edit['category'] = $category; + $edit['name'] = $name; $edit['recipients'] = $recipients; $edit['reply'] = $reply; $edit['selected'] = ($selected ? '1' : '0'); @@ -228,7 +229,10 @@ class ContactSitewideTestCase extends WebTestBase { /** * Updates a category. * + * @param array $categories * @param string $category + * The category title. + * @param string $name * The category name. * @param string $recipients * The list of recipient e-mail addresses. @@ -238,7 +242,7 @@ class ContactSitewideTestCase extends WebTestBase { * @param boolean $selected * Boolean indicating whether the category should be selected by default. */ - function updateCategory($categories, $category, $recipients, $reply, $selected) { + function updateCategory($categories, $category, $name, $recipients, $reply, $selected) { $category_id = $categories[array_rand($categories)]; $edit = array(); $edit['category'] = $category; @@ -258,17 +262,17 @@ class ContactSitewideTestCase extends WebTestBase { * The e-mail address of the sender. * @param string $subject * The subject of the message. - * @param integer $cid - * The category ID of the message. + * @param string $category_name + * The category name of the message. * @param string $message * The message body. */ - function submitContact($name, $mail, $subject, $cid, $message) { + function submitContact($name, $mail, $subject, $category_name, $message) { $edit = array(); $edit['name'] = $name; $edit['mail'] = $mail; $edit['subject'] = $subject; - $edit['cid'] = $cid; + $edit['category_name'] = $category_name; $edit['message'] = $message; $this->drupalPost('contact', $edit, t('Send message')); } @@ -278,21 +282,26 @@ class ContactSitewideTestCase extends WebTestBase { */ 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.')); + foreach ($categories as $category_name) { + $category = config('contact.category.' . $category_name)->get('category'); + $this->drupalPost('admin/structure/contact/delete/' . $category_name, array(), t('Delete')); + $this->assertRaw(t('Category %category has been deleted.', array('%category' => $category)), t('Category deleted successfully.')); } } /** - * Gets a list of all category IDs. + * Gets a list of all category names. * * @return array - * A list of the category IDs. + * A list of the category names. */ function getCategories() { - $categories = db_query('SELECT cid FROM {contact}')->fetchCol(); + $categories_names = config_get_storage_names_with_prefix('contact.category'); + $categories = array(); + foreach ($categories_names as $name) { + $categories[] = str_replace('contact.category.', '', $name); + } + return $categories; } }