summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlastair Aitchison2010-06-03 14:40:15 (GMT)
committer Alastair Aitchison2010-06-03 14:40:15 (GMT)
commite371e92b9d899643868325db53c0aa52b93ec06e (patch)
tree4d53ae1f57f03ee938034de744fa13d6a922efa7
parent81cbba4cec3ad30707dee7febdeda85f567a07ec (diff)
by tanoshimi: initial commit of suggest and notify submodules. Various changes to keep up with D7 core
-rw-r--r--question.install8
-rw-r--r--question.module30
-rw-r--r--question_notify/question_notify.info9
-rw-r--r--question_notify/question_notify.install36
-rw-r--r--question_notify/question_notify.module296
-rw-r--r--question_suggest/question_suggest.info9
-rw-r--r--question_suggest/question_suggest.module91
7 files changed, 458 insertions, 21 deletions
diff --git a/question.install b/question.install
index 6f237d4..29a0fdb 100644
--- a/question.install
+++ b/question.install
@@ -10,7 +10,6 @@
/**
* Implements hook_schema().
*/
-
function question_schema() {
$schema['question_queue'] = array(
'description' => 'Stores items in a question queue.',
@@ -41,7 +40,7 @@ function question_install() {
$t = get_t();
// Do not allow Drupal to define the default permissions set for this node type.
- // We will control the access to question/answers manually using hook_node_access().
+ // We will control access to question/answers manually using hook_node_access().
variable_set('node_permissions_question', 0);
// Define the Question node type.
@@ -57,7 +56,7 @@ function question_install() {
// Save the node type
node_type_save($content_type);
- // Load the instance of the body field for our content type
+ // Get the instance of the body field for our content type
$body_instance = field_info_instance('node', 'body', 'question');
// Delete the body field instance
@@ -153,8 +152,7 @@ function question_field_instances() {
}
/**
- * Implementation of hook_uninstall().
- *
+ * Implements hook_uninstall().
*/
function question_uninstall() {
diff --git a/question.module b/question.module
index 37bfe9c..5a90e3c 100644
--- a/question.module
+++ b/question.module
@@ -4,10 +4,8 @@
* @file
* Allows users to submit questions to a queue that may be answered by site administrators
*
- * TODO
- * Create upgrade path in hook_install_N
- * Theme functions for question form
- * Update tests
+ * @todo
+ * - Create upgrade path in hook_install_N
*/
/************************************************
@@ -139,7 +137,7 @@ function question_menu() {
/**
* Implements hook_menu_alter().
*
- * Removes the default link to create a question/answer page from the
+ * Removes the default link to create a question/answer page from the
* "Add new content" menu at node/add.
* Instead, we only want users to create answers by promoting questions from the queue.
*/
@@ -222,7 +220,7 @@ function question_ask_form($node, &$form_state) {
'#markup' => check_plain($instructions),
);
}
-
+
$form['question'] = array(
'#type' => 'textarea',
'#title' => t('Question'),
@@ -239,14 +237,14 @@ function question_ask_form($node, &$form_state) {
);
$form['#method'] = 'post';
$form['#theme'] = 'question_ask_form';
-
+
return $form;
}
/**
* Implements _form_validate.
*/
-function question_ask_form_validate(&$form, &$form_state) {
+function question_ask_form_validate(&$form, &$form_state) {
if ($form_state['values']['question'] == '') {
form_set_error('question', t('Please enter a question.'));
}
@@ -264,7 +262,7 @@ function question_ask_form_submit($form, &$form_state) {
drupal_write_record('question_queue', $row);
// Retrieve the question id assigned by the database to be used in future form processing
$form_state['storage']['qid'] = $row['qid'];
-
+
// Determine where the browser should now go to
$path = variable_get('question_ask_form_redirect', '');
if (!empty($path)) {
@@ -275,13 +273,13 @@ function question_ask_form_submit($form, &$form_state) {
// Return to the site frontpage
$form_state['redirect'] = '<front>';
}
-
+
// Display message to user
$message = variable_get('question_submission_message', '');
if (!empty($message)) {
drupal_set_message(check_plain($message));
}
-
+
// Add an entry to the watchdog log
watchdog('Question', 'Question submitted: %question.', array('%question' => $form_state['values']['question']), WATCHDOG_NOTICE);
}
@@ -325,7 +323,7 @@ function question_theme() {
* Provide an array of the bulk operations that can be
* perfomed on items in the question queue.
*
- * @see hook_node_operations().
+ * @see hook_node_operations()
*/
function question_question_queue_operations() {
$operations = array();
@@ -344,7 +342,7 @@ function question_question_queue_operations() {
/**
* Admin form for questions in the queue.
*
- * @see node_admin_content().
+ * @see node_admin_content()
*/
function question_queue_admin($form, &$form_state) {
if (isset($form_state['values']['operation']) && $form_state['values']['operation'] == 'delete') {
@@ -378,7 +376,7 @@ function question_question_queue_fields() {
* Lists all questions currently in the queue, and allows
* bulk operations to be performed against those questions.
*
- * @see node_admin_nodes().
+ * @see node_admin_nodes()
*/
function question_queue_admin_form() {
@@ -679,10 +677,10 @@ function question_form_validate(&$elements, &$form_state, $form_id = NULL) {
}
if ($elements['title']['#value'] == '') {
form_set_error('title', t('Please enter a short title for the question.'));
- }
+ }
if ($elements['question_answer']['und'][0]['value']['#value'] == '') {
form_set_error('question_answer', t('Please enter the answer.'));
- }
+ }
}
/**
diff --git a/question_notify/question_notify.info b/question_notify/question_notify.info
new file mode 100644
index 0000000..fea230e
--- /dev/null
+++ b/question_notify/question_notify.info
@@ -0,0 +1,9 @@
+; $Id$
+name = Question Notify
+description = Notify users by email when their questions are answered.
+dependencies[] = question
+package = Question
+core = 7.x
+files[] = question_notify.module
+files[] = question_notify.install
+files[] = question_notify.test
diff --git a/question_notify/question_notify.install b/question_notify/question_notify.install
new file mode 100644
index 0000000..5b2fdbf
--- /dev/null
+++ b/question_notify/question_notify.install
@@ -0,0 +1,36 @@
+<?php
+// $Id$
+/**
+ * @file
+ * install file for Question Notify module.
+ *
+ * Most of the definition of the node type is in this module.
+ */
+
+/**
+ * Implements hook_schema().
+ */
+
+function question_notify_schema() {
+ $schema['question_notify'] = array(
+ 'description' => 'Stores details required to email users when questions are are answered.',
+ 'fields' => array(
+ 'qid' => array(
+ 'description' => 'The unique id assigned to this question.',
+ 'type' => 'serial', // auto-increment field
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ //'default' => 0,
+ ),
+ 'mail' => array(
+ 'description' => "User's email address.",
+ 'type' => 'varchar',
+ 'length' => '255',
+ 'not null' => TRUE,
+ ),
+ ),
+ 'primary key' => array('qid'),
+ );
+
+ return $schema;
+} \ No newline at end of file
diff --git a/question_notify/question_notify.module b/question_notify/question_notify.module
new file mode 100644
index 0000000..7d4aa58
--- /dev/null
+++ b/question_notify/question_notify.module
@@ -0,0 +1,296 @@
+<?php
+// $Id$
+/**
+ * @file
+ * Allows users to be notified when their question is answered.
+ *
+ * TODO
+ * Tests!
+ * Check submit handler to delete record from notify table when question is deleted (or mass-deleted) from queue
+ */
+
+/**
+ * Implements hook_trigger_info().
+ *
+ * List the triggers defined by this module when actions
+ * can be fired.
+ */
+function question_notify_trigger_info() {
+ return array(
+ 'question' => array(
+ 'question_submission' => array(
+ 'label' => t('After a question is submitted to the queue'),
+ ),
+ 'question_response' => array(
+ 'label' => t('After a reply is made to a question'),
+ ),
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_action_info().
+ *
+ * Define actions that can be triggered on certain events.
+ */
+function question_action_info() {
+ return array(
+ 'question_email_questioner_action' => array(
+ 'label' => t('Send email to questioner'),
+ 'type' => 'question',
+ 'configurable' => TRUE,
+ 'triggers' => array('question_submission', 'question_response'),
+ ),
+ );
+}
+
+/**
+ * Configuration form for the "Send email to questioner" action
+ */
+function question_email_questioner_action_form($context) {
+ $form['email'] = array(
+ '#title' => t('Email body'),
+ '#type' => 'textfield',
+ '#description' => t('Enter the body message of the email here.'),
+ '#default_value' => 'A question you asked has been answered',
+ );
+ return $form;
+}
+
+function question_email_questioner_action_submit($form, $form_state) {
+ return array('message' => $form_state['values']['email']);
+}
+
+function question_email_questioner_action($object, $context) {
+ // Check that the email is valid
+ if(valid_email_address($object->mail)) {
+
+ // Try to retrieve account information for this email address
+ $account = user_load(array('mail' => $email));
+ // If the account is not anonymous
+ if ($account) {
+ $language = user_preferred_language($account);
+ }
+ else {
+ $language = language_default();
+ }
+
+ // Build the array of parameters to complete the email template
+ $params['question'] = $node->title;
+ $params['nid'] = $node->nid;
+
+ // Attempt to send the e-mail to the asker.
+ $mail_sent = drupal_mail('question', 'question_submission', $object->mail, $email, $language, $params);
+
+ // Check whether successful
+ if ($mail_sent) {
+ watchdog('Question', 'Asker notification email sent to @to for question @quest',
+ array('@to' => $object->mail, '@quest' => check_plain($node->title)), WATCHDOG_NOTICE);
+ }
+ else {
+ watchdog('Question', 'Asker notification email to @to failed for the "@quest" question.',
+ array('@to' => $email, '@quest' => check_plain($node->title)), WATCHDOG_ERROR);
+ }
+ }
+}
+
+/**
+ * Implementation of hook_mail().
+ *
+ * This function defines the templates for al emails sent from question module.
+ */
+function question_mail($key, &$message, $params) {
+ $message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed';
+ $language = $message['language'];
+ $variables = user_mail_tokens($params['account'], $language);
+ switch ($key) {
+ case 'question_submission':
+ $subject = t('You have been assigned a question on !site', $variables, $language->language);
+ $body = t('Dear !username,', array('!username' => 'user'), $language->language) . '\n<br/><br/>';
+ $body .= t('The following question has been posted on the Teenage Health Freak site.', $language->language) . '\n<br/><br/>';
+ $body .= $params['question'];
+ break;
+
+ case 'question_response':
+ $subject = t('You have been assigned a question on !site', $variables, $language->language);
+ $body = t('Dear !username,', array('!username' => 'user'), $language->language) . '\n<br/><br/>';
+ $body .= t('The following question has been posted on the Teenage Health Freak site.', $language->language) . '\n<br/><br/>';
+ $body .= $params['question'];
+ break;
+ }
+ $message['body'] = $body;
+ $message['subject'] = $subject;
+}
+
+
+
+/************************************************
+ * *
+ * USER QUESTION SUBMISSION *
+ * *
+ ************************************************/
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * Add new form fields to the question submission form
+ * to record user's notification email address.
+ */
+function question_notify_form_question_ask_form_alter(&$form, &$form_state) {
+ // Registered users sign up for notifications with a checkbox
+ if (user_is_logged_in()) {
+ $form['notify'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Notify by e-mail'),
+ '#default_value' => FALSE,
+ '#weight' => 0,
+ '#description' => t('Check this box to receive an email when your question is answered.'),
+ );
+ }
+ // Anonymous users must provide a notification email address
+ else {
+ $form['email'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Your email address'),
+ '#size' => 40,
+ '#maxlength' => 60,
+ '#description' => t('If you would like to be notified when your question is answered, please enter your email address'),
+ );
+ }
+ // Add validation and submit handlers for the new fields
+ $form['#validate'][] = 'question_notify_question_ask_form_validate';
+ $form['#submit'][] = 'question_notify_question_ask_form_submit';
+}
+
+/**
+ * Implements _form_validate().
+ */
+function question_notify_question_ask_form_validate(&$form, &$form_state) {
+ // Check validity of notification email address
+ if (!empty($form_state['values']['email'])) {
+ if (!valid_email_address($form_state['values']['email'])) {
+ form_set_error('email', t('Please enter a valid email address'));
+ }
+ }
+}
+
+/**
+ * Implements _form_submit().
+ */
+function question_notify_question_ask_form_submit($form, &$form_state) {
+ // If an authenticated user asked to be notified, get their user email address
+ if (isset($form_state['values']['notify']) && $form_state['values']['notify']) {
+ global $user;
+ $mail = $user->mail;
+ }
+ // If an anonymous user asked to be notified, get the (validated) email address
+ elseif (!empty($form_state['values']['email'])) {
+ $mail = $form_state['values']['email'];
+ }
+
+ $row = array();
+
+ if (isset($mail)) {
+ // Make an array containing all the values to insert
+ $row = array(
+ 'qid' => $form_state['storage']['qid'],
+ 'mail' => $mail,
+ );
+ // Insert the row
+ db_insert('question_notify')->fields($row)->execute();
+ }
+
+ // Trigger all actions associated with a question submission
+ $aids = trigger_get_assigned_actions('question_submission');
+ $context = array(
+ 'group' => 'question',
+ 'hook' => 'question_submission'
+ );
+ actions_do(array_keys($aids), (object) $row, $context);
+}
+
+/************************************************
+ * *
+ * QUESTION QUEUE MANAGEMENT *
+ * *
+ ************************************************ /
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * Alter the question queue form.
+ */
+function question_notify_form_question_queue_admin_alter(&$form, &$form_state) {
+ // Add an additional submit handler
+ $form['#submit'][] = 'question_notify_question_queue_multiple_delete_confirm_submit';
+}
+/**
+ * Delete row from question_fields table when corresponding
+ * question is deleted from the queue.
+ */
+function question_notify_question_queue_multiple_delete_confirm_submit($form, &$form_state) {
+ if ($form['operation']['#value'] = 'delete' && $form_state['values']['confirm']) {
+ foreach ($form_state['values']['questions'] as $qid => $value) {
+ $num_deleted = db_delete('question_notify')
+ ->condition('qid', $qid)
+ ->execute();
+ }
+ }
+}
+
+function question_notify_form_question_delete_confirm_alter(&$form, &$form_state) {
+ // Add an additional submit handler
+ $form['#submit'][] = 'question_notify_question_queue_delete_confirm_submit';
+}
+
+function question_notify_question_queue_delete_confirm_submit($form, &$form_state) {
+ if ($form_state['values']['confirm']) {
+ $qid = $form_state['values']['qid'];
+ $num_deleted = db_delete('question_notify')
+ ->condition('qid', $qid)
+ ->execute();
+ }
+}
+
+/************************************************
+ * *
+ * RESPOND TO QUESTIONS *
+ * *
+ ************************************************/
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function question_notify_form_question_node_form_alter(&$form, &$form_state) {
+ // Add additional submit handler
+ $form['#submit'][] = 'question_notify_question_node_form_submit';
+}
+
+/**
+ * Implements _form_submit().
+ */
+function question_notify_question_node_form_submit(&$elements, &$form_state, $form_id = NULL) {
+
+ // If this node came from the queue
+ if (isset($elements['qid'])) {
+
+ // If the user asked to be notifed, get the right email address
+ $mail = db_query("SELECT mail FROM {question_notify} WHERE qid = :qid", array(':qid' => $elements['qid']['#value']))->fetchField();
+
+ // Then delete the notification record from the queue
+ $num_deleted = db_delete('question_notify')
+ ->condition('qid', $elements['qid']['#value'])
+ ->execute();
+ }
+
+ $options = new stdClass();
+ $options->mail = $mail;
+
+ // Trigger all actions associated with a question response
+ $aids = trigger_get_assigned_actions('question_response');
+ $context = array(
+ 'group' => 'question',
+ 'hook' => 'question_response'
+ );
+ actions_do(array_keys($aids), (object) $options, $context);
+}
diff --git a/question_suggest/question_suggest.info b/question_suggest/question_suggest.info
new file mode 100644
index 0000000..0e5d363
--- /dev/null
+++ b/question_suggest/question_suggest.info
@@ -0,0 +1,9 @@
+; $Id$
+name = Question Suggest
+description = Search the site and suggest relevant content for user questions.
+dependencies[] = question
+package = Question
+core = 7.x
+files[] = question_suggest.module
+files[] = question_suggest.test
+depedendencies[] = search
diff --git a/question_suggest/question_suggest.module b/question_suggest/question_suggest.module
new file mode 100644
index 0000000..dbee821
--- /dev/null
+++ b/question_suggest/question_suggest.module
@@ -0,0 +1,91 @@
+<?php
+// $Id$
+/**
+ * @file
+ * Suggest relevant content when users ask a question.
+ *
+ * @todo
+ * Tests!
+ */
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function question_suggest_form_question_ask_form_alter(&$form, &$form_state) {
+
+ // Make the question form a multistep form
+ $step = isset($form_state['storage']['step']) ? $form_state['storage']['step'] : 0;
+
+ switch ($step) {
+ case 0:
+ // Change the submit button text
+ $form['submit']['#value'] = 'Suggest';
+ break;
+
+ case 1:
+ // Create a search query for any of the words in the supplied question
+ $keys = str_replace(' ', ' OR ', $form_state['values']['question']);
+ // Should we exclude stop words from the search?
+ //$keys = str_replace(array('the', 'and', 'a', 'to', 'of', 'in', 'i', 'is', 'that', 'it', 'on', 'you', 'this', 'for', 'but', 'with', 'are', 'have', 'be', 'at', 'or', 'as', 'was', 'so', 'if', 'out', 'not'), '', $form_state['values']['question']);
+
+ // Execute the search
+ $results = module_invoke('node', 'search_execute', $keys);
+
+ // Limit the array to three top results
+ $results = array_slice($results, 0, 3);
+
+ // Display the results on the form
+ $form['suggestions'] = array(
+ '#type' => 'markup',
+ '#markup' => theme('question_suggest_results', array('suggestions' => $results))
+ );
+ break;
+ }
+ // Add an additional validate handler to rebuild the form with suggested links
+ $form['#validate'][] = 'question_suggest_question_ask_form_validate';
+
+}
+
+/**
+ * Implements hook_form_validate().
+ */
+function question_suggest_question_ask_form_validate(&$form, &$form_state) {
+ if (!isset($form_state['storage']['step'])) {
+ $form_state['storage']['step'] = 0;
+ }
+ switch ($form_state['storage']['step']) {
+ case 0:
+ $form_state['storage']['step'] = $form_state['storage']['step'] + 1;
+ $form_state['rebuild'] = TRUE;
+ break;
+ }
+}
+
+/**
+ * Implements hook_theme().
+ */
+function question_suggest_theme() {
+ return array(
+ 'question_suggest_results' => array('arguments' => array('suggestions' => NULL),
+ ),
+ );
+}
+
+/**
+ * Themes the suggested links returned on the question form
+ */
+function theme_question_suggest_results($variables) {
+
+ $suggestions = $variables['suggestions'];
+
+ $output = '';
+ if($suggestions) {
+ $output .= '<h2>Suggested Links</h2>';
+ $output .= '<table id="question_suggestions">';
+ foreach ($suggestions as $suggestion) {
+ $output .= '<tr><td>' . $suggestion['type'] . '</td><td>' . $suggestion['title'] . '</td></tr>';
+ }
+ $output .= '</table>';
+ }
+ return $output;
+}