### Eclipse Workspace Patch 1.0
#P faq_ask
Index: faq_ask.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/faq_ask/faq_ask.module,v
retrieving revision 1.17.2.23.2.14
diff -u -r1.17.2.23.2.14 faq_ask.module
--- faq_ask.module 22 Oct 2009 04:11:46 -0000 1.17.2.23.2.14
+++ faq_ask.module 25 Feb 2010 11:51:42 -0000
@@ -61,7 +61,7 @@
else {
// return user_access('answer question') || user_access('edit_own_faq');
// We don't include "edit own" because the intent is they can edit their own until it's published.
- return user_access('answer question') || $account->uid == $node->uid;
+ return user_access('answer question') || $account->uid == $node->uid;
}
}
@@ -158,11 +158,11 @@
}
/**
- * Implementation of hook_form_alter().
+ * Implementation of hook_form_FORM_ID_alter().
* This is how we build the "ask question" form.
*/
-function faq_ask_form_alter(&$form, $form_state, $form_id) {
- if ($form_id != 'faq_node_form' || !isset($_GET['ask'])) {
+function faq_ask_form_faq_node_form_alter(&$form, $form_state) {
+ if (!isset($_GET['ask'])) {
return;
}
if ($_GET['ask'] != 1 && $_GET['ask'] != 'true') {
@@ -183,9 +183,140 @@
}
$form['body'] = array('#type' => 'value', '#value' => variable_get('faq_ask_unanswered', t('Not answered yet.')));
+ // if we're supposed to notify asker on answer, add form item for this
+ if (variable_get('faq_ask_notify_asker', FALSE)) {
+
+ global $user;
+
+ // If asker is anonymous, add an optional e-mail field that may be used for notification when question is answered
+ if ($user->uid == 0) {
+ // Form field for e-mail.
+ $form['faq-email'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Notification E-mail (optional)'),
+ '#default_value' => '',
+ '#weight' => 0,
+ '#description' => t('Write your e-mail here if you would like to be notified when the question is answered.')
+ );
+ }
+ else {
+ // Checkbox for notification
+ $form['faq-notify'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Notify by E-mail (optional)'),
+ '#default_value' => false,
+ '#weight' => 0,
+ '#description' => t('Check this box if you would like to be notified when the question is answered.'),
+ );
+ }
+ }
+
+ // Add validation of the e-mail field
+ if (isset($form['#validate'])) {
+ $temp_val = $form['#validate'];
+ $form['#validate'] = array($temp_val);
+ }
+ else {
+ $form['#validate'] = array();
+ }
+ $form['#validate'][] = 'faq_ask_form_validate';
+
// Make sure we know we came from here.
$form['faq_ask'] = array('#type' => 'value', '#value' => TRUE);
- $form['#submit'][] = 'faq_ask_submit';
+ $form['buttons']['submit']['#submit'][] = 'faq_ask_submit';
+
+ // Sean Corales: Redirect to faq page if user is anonymous or cannot edit own faq nodes
+ global $user;
+ if ((!user_access('edit own faq') && !user_access('edit faq')) || ($user->uid == 0)) {
+ $form['#redirect'] = 'faq';
+ }
+
+ // Handle special cases if this is a block form
+ if (isset($_GET['block'])) {
+ if($_GET['block']) {
+
+ // Shorten the description text on taxonomy field
+ if (!variable_get('faq_ask_categorize', FALSE) && isset($form['taxonomy']['tags'])) {
+ $tags = array_keys($form['taxonomy']['tags']);
+ $form['taxonomy']['tags'][$tags[0]]['#description'] = t('A comma-separated list of terms.');
+ }
+
+ // Shorter description on Qestion field + move it higher
+ $form['title']['#description'] = t('Question to be answered.');
+ $form['title']['#weight'] = '-5';
+
+ // Shorter description on detailed question field
+ $form['detailed_question']['#description'] = t('Longer question text.');
+
+ }
+ }
+}
+
+/**
+ * Validation form for the FAQ Ask form
+ * Thanks to http://hokuten.net/2010/drupal-creating-an-e-mail-subscription-block/
+ */
+function faq_ask_form_validate($form, &$form_state) {
+
+ if (isset($form_state['values']['faq-email'])) {
+ $email = $form_state['values']['faq-email'];
+ if (strlen($email) > 1 && !eregi('^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.([a-zA-Z]{2,4})$', $email)) {
+ form_set_error('email', t('That is not a valid e-mail address.'));
+ }
+ }
+}
+
+/**
+ * Implementation of hook_nodeapi()
+ * Checks if the node being updated is a question that has been answered
+ */
+function faq_ask_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
+ if($node->type == 'faq') {
+ switch ($op) {
+ case 'update':
+
+ // return if the asker notification should be done by cron
+ if (variable_get('faq_ask_notify_by_cron', true)) {
+ return;
+ }
+ // Check if the node is published
+ $email = _faq_ask_get_faq_notification($node->nid);
+ if ($node->status == '1') {
+
+ // Get the asker account
+ $account = user_load(array('mail' => $email));
+ // If the account is not anonymous
+ if ($account) {
+ $params['account'] = $account;
+ }
+ else {
+ $params['account'] = null;
+ }
+
+ // Send the e-mail to the asker. Drupal calls hook_mail() via this
+ $mail_sent = drupal_mail('faq_ask', 'notify_asker', $email, user_preferred_language($params['account']), $params);
+
+ // Handle sending result
+ if ($mail_sent) {
+ watchdog('FAQ_Ask', 'Asker notification email sent to @to for question @quest',
+ array('@to' => $email, '@quest' => check_plain($node->title)), WATCHDOG_NOTICE);
+ // If email sent, remove the notification from the queue
+ _faq_ask_delete_faq_notification($node->nid);
+ }
+ else {
+ watchdog('FAQ_Ask', 'Asker notification email to @to failed for the "@quest" question.',
+ array('@to' => $email, '@quest' => check_plain($node->title)), WATCHDOG_ERROR);
+ drupal_set_message( t( 'Asker notification email to @to failed for the "@quest" question.',
+ array('@to' => $email, '@quest' => check_plain($node->title))
+ )
+ );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
}
function faq_ask_submit($form, &$form_state) {
@@ -202,12 +333,13 @@
else {
$category = 0; // 0 is default expert.
}
+
// Are we notifying the expert(s)?
if (variable_get('faq_ask_notify', FALSE)) {
$params = array(
'category' => $category ? $category : -1,
- 'question' => $node->title,
- 'nid' => $node->nid,
+ 'question' => $form_state['title'],
+ 'nid' => $form_state['nid'],
'creator' => theme('username', $node, array('plain' => TRUE)),
);
// Find out who the experts are.
@@ -228,10 +360,157 @@
}
}
- drupal_set_message(t('Your question has been submitted. It will appear in the FAQ listing as soon as it has been answered.'), 'status');
+ // Handle the notification of asker
+ if (isset($form_state['values']['faq-email'])) {
+ _faq_ask_set_faq_notification($form_state['nid'], $form_state['values']['faq-email']);
+ drupal_set_message(t('Your question has been submitted. An e-mail will be sent to @mail when answered.', array('@mail' => $form_state['values']['faq-email'])), 'status');
+ }
+ else if (isset($form_state['values']['faq-notify'])) {
+ if ($form_state['values']['faq-notify']) {
+ global $user;
+ $email = $user->mail;
+ _faq_ask_set_faq_notification($form_state['nid'], $email);
+ drupal_set_message(t('Your question has been submitted. An e-mail will be sent to @mail when answered.', array('@mail' => $email)), 'status');
+ }
+ }
+ else {
+ drupal_set_message(t('Your question has been submitted. It will appear in the FAQ listing as soon as it has been answered.'), 'status');
+ }
}
/**
+ * Implementation of hook_cron()
+ * Checks the que for asker notifications and sends a notification to the asker when the question is published
+ *
+ */
+function faq_ask_cron() {
+
+ // If the asker notification should be done by cron
+ if (!variable_get('faq_ask_notify_by_cron', true)) {
+ return;
+ }
+ // Get all the waiting notifications
+ $notifications = _faq_ask_get_faq_notifications();
+ foreach ($notifications as $nid => $email) {
+ // With the notification record, check if status of the question is published
+ if ($result = db_query('SELECT title,status FROM {node} WHERE nid=%d', $nid)) {
+ $notification = db_fetch_array($result);
+ if ($notification['status'] == '1') {
+
+ $params = array(
+ 'question' => $notification['title'],
+ 'nid' => $nid,
+ 'account' => user_load(array('mail' => $email)),
+ );
+
+ // Send the e-mail to the asker. Drupal calls hook_mail() via this
+ $mail_sent = drupal_mail('faq_ask', 'notify_asker', $email, user_preferred_language($params['account']), $params);
+
+ // Handle sending result
+ if ($mail_sent) {
+ watchdog('FAQ_Ask', 'Asker notification email sent to @to for question: "@quest"',
+ array('@to' => $email, '@quest' => check_plain($notification['title'])), WATCHDOG_NOTICE);
+ // If email sent, remove the notification from the queue
+ _faq_ask_delete_faq_notification($nid);
+ }
+ else {
+ watchdog('FAQ_Ask', 'Asker notification email to @to failed for the "@quest" question.',
+ array('@to' => $email, '@quest' => check_plain($notification['title'])), WATCHDOG_ERROR);
+ drupal_set_message(t('Asker notification email to @to failed for the "@quest" question.', array('@to' => $email, '@quest' => check_plain($notification['title']))));
+ }
+ }
+ }
+
+ }
+}
+/**
+ * Helper function to fetch an email for notification assigned to an faq node
+ *
+ */
+function _faq_ask_get_faq_notification_email($nid) {
+ $result = db_query('SELECT email FROM {faq_ask_notify} WHERE nid=%d', $nid);
+ return db_fetch_array($result);
+}
+
+/**
+ * Helper function fetching all notifications
+ * returns: Array containing all outstanding notifications
+ */
+function _faq_ask_get_faq_notifications() {
+ $notifications = array();
+
+ $result = db_query('SELECT nid, email FROM {faq_ask_notify}');
+ while ($row = db_fetch_array($result)) {
+ $notifications[$row['nid']] = $row['email'];
+ }
+ return $notifications;
+
+}
+function _faq_ask_set_faq_notification($nid, $email) {
+
+ $data = array(
+ 'nid' => $nid,
+ 'email' => $email
+ );
+ drupal_write_record('faq_ask_notify', $data);
+}
+
+function _faq_ask_delete_faq_notification($nid) {
+ $delete = db_query("DELETE FROM {faq_ask_notify} WHERE nid=%d", $nid);
+ if ($delete === FALSE) {
+ drupal_set_message(t('Attempt to delete email notification failed.'), 'error');
+ }
+}
+
+
+
+/**
+ * Block "Ask a Question" form implementation
+ * This implements the form displayed in a block where the user may ask a question
+ *
+ */
+function faq_ask_a_question_blockform() {
+
+ // Include page handler for node_add()
+ module_load_include('inc', 'node', 'node.pages');
+
+ // If user is allowed to create a faq content type
+ if (node_access('create', 'faq')) {
+
+ // Fool the hook_form_alter function to think we're in an faq-ask page
+ $saved_get = '';
+ if (isset($_GET['ask'])) {
+ $saved_get = $_GET['ask'];
+ }
+ $_GET['ask'] = '1';
+ $_GET['block'] = 'true';
+
+ // Note title before rendering of form.
+ $title = drupal_get_title();
+ // Create the form
+ $form = node_add('faq');
+ // Restore title, which will have been overridden.
+ drupal_set_title($title);
+
+ // Restore the $_GET['ask'] variable status
+ if ($saved_get != '') {
+ $_GET['ask'] = $saved_get;
+ }
+ else {
+ unset($_GET['ask']);
+ }
+ unset($_GET['block']);
+
+ return $form;
+ }
+ else {
+ return '';
+ }
+
+}
+
+
+/**
* Implementation of hook_mail().
* This function completes the email, allowing for placeholder substitution.
* @TODO: notify_asker.
@@ -264,6 +543,24 @@
$body[] = t('In order to answer it you will first need to login to the site.', $variables, $language->language);
$body[] = t('Once logged in, you may proceed directly to the question to answer it.', $variables, $language->language);
break;
+
+ case 'notify_asker':
+ $variables = array_merge($variables, array(
+ '!cat' => $params['category'],
+ '@question' => $params['question'],
+ '!question_uri' => url('node/'. $params['nid'], array('absolute' => TRUE)),
+ ));
+
+ if ($variables['!username'] == '') {
+ $variables['!username'] = t('user');
+ }
+
+ $subject = t('A question you asked has been answered on !site', $variables, $language->language);
+ $body[] = t('Dear !username,', $variables, $language->language);
+ $body[] = t('The question: "@question" you asked on !site has been answered. ', $variables, $language->language);
+ $body[] = t('To view the answer, please visit the question you created on !question_uri.', $variables, $language->language);
+ $body[] = t('Thank you for visiting.', $variables, $language->language);
+ break;
}
$message['body'] = drupal_wrap_mail(implode($newline, $body));
$message['subject'] = $subject;
@@ -276,6 +573,7 @@
* so it can "flip" based on whether there are more categories or experts.
*/
function faq_ask_settings_form(&$form_state, $op = NULL, $aid = NULL) {
+
$form = array();
// Set a basic message that will be unset once we pass the error checking.
$form['error'] = array('#value' => t('Errors were found, please correct them before proceeding.'), '#weight' => -10);
@@ -296,9 +594,9 @@
// Get the admin's name.
$admin = ucwords(db_result(db_query('SELECT name FROM {users} WHERE uid=1')));
- $form['notification'] = array(
+ $form['notification'] = Array(
'#type' => 'fieldset',
- '#title' => t('Notifications'),
+ '#title' => T('Notifications'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
@@ -310,6 +608,28 @@
'#default_value' => variable_get('faq_ask_notify', 0),
);
+ $form['notification']['notify_asker'] = Array(
+ '#type' => 'fieldset',
+ '#title' => T('Asker notification'),
+ '#collapsible' => FALSE,
+ '#collapsed' => FALSE,
+ );
+
+ $form['notification']['notify_asker']['faq_ask_asker_notify'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Notify askers'),
+ '#description' => t('If this box is checked, the asker creating the question will be notified via email that their question is answered.'),
+ '#default_value' => variable_get('faq_ask_notify_asker', 0),
+ );
+
+ $form['notification']['notify_asker']['faq_ask_asker_notify_cron'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Use cron for asker notification'),
+ '#description' => t('If this box is checked, the asker notifications will be sendt via cron.'),
+ '#default_value' => variable_get('faq_ask_notify_by_cron', true),
+ '#disabled' => !variable_get('faq_ask_notify_asker', 0),
+ );
+
$form['options'] = array(
'#type' => 'fieldset',
'#title' => t('Options'),
@@ -345,7 +665,7 @@
'#description' => t('This text will be inserted into the body of questions when they are asked. This helps make editing easier'),
'#default_value' => variable_get('faq_ask_unanswered', t('Not answered yet.')),
);
-
+
$form['options']['faq_ask_expert_advice'] = array(
'#type' => 'textarea',
'#title' => t('Answer advice for the expert'),
@@ -434,7 +754,7 @@
//$vocabs = variable_get('faq_ask_vocabularies', $def_vid);
$vocabs_array = array();
foreach ($vocabs as $vocab) {
- $vocabs_array[$vocab->vid] = $vocab->vid;
+ $vocabs_array[$vocab->vid] = $vocab->vid;
}
$result = db_query('SELECT td.tid, td.name, td.description FROM {term_data} td WHERE td.vid IN ('. db_placeholders($vocabs_array) .') ORDER BY td.weight ASC, td.name ASC', $vocabs_array);
@@ -566,7 +886,7 @@
else {
// Expert 0 means default expert; overlook it.
if ($expert['tid'] != 0) {
- drupal_set_message(t("!name doesn't exist. If you have just changed your role selections this may be okay.", array('!name' => $box_name)), 'warning');
+ drupal_set_message(t("!name doesn't exist. If you have just changed your role selections this may be okay.", array('!name' => $box_name)), 'warning');
}
}
}
@@ -590,7 +910,7 @@
}
// Get rid of error element.
- unset($form['error']);
+ unset($form['error']);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save configuration'),
@@ -615,6 +935,8 @@
variable_set('faq_ask_categorize', $form_state['values']['faq_ask_categorize']);
variable_set('faq_ask_expert_own', $form_state['values']['faq_ask_expert_own']);
variable_set('faq_ask_notify', $form_state['values']['faq_ask_notify']);
+ variable_set('faq_ask_notify_asker', $form_state['values']['faq_ask_asker_notify']);
+ variable_set('faq_ask_notify_by_cron', $form_state['values']['faq_ask_asker_notify_cron']);
variable_set('faq_ask_unanswered', $form_state['values']['faq_ask_unanswered']);
variable_set('faq_ask_default_expert', $form_state['values']['faq_ask_default_expert']);
variable_set('faq_ask_expert_advice', $form_state['values']['faq_ask_expert_advice']);
@@ -652,7 +974,7 @@
global $user;
// Validate the request.
if (!isset($_REQUEST['token']) || !drupal_valid_token($_REQUEST['token'], "faq_ask/answer/$node->nid")) {
- watchdog('Faq_Ask',
+ watchdog('Faq_Ask',
'Received an invalid answer request (@query_string) from @user_ip.',
array('@query_string' => $_SERVER['QUERY_STRING'], '@user_ip' => $_SERVER['REMOTE_ADDR']),
WATCHDOG_ALERT);
@@ -849,6 +1171,7 @@
*/
function faq_ask_block($op = 'list', $delta = 0, $edit = array()) {
global $user;
+ $block = array();
switch ($op) {
case 'list':
$blocks[0]['info'] = t('Unanswered Questions');
@@ -865,7 +1188,8 @@
case 1:
// Ask a question block.
if (user_access('ask question')) {
- $block['content'] = faq_ask_page(NULL);
+ $block['title']= t('Ask a Question');
+ $block['content'] = faq_ask_a_question_blockform();
}
} // end switch($delta).
@@ -912,7 +1236,7 @@
// What permissions does this user have?
$can_edit = user_access('administer faq') || user_access('administer nodes');
$is_expert = user_access('answer question');
-
+
$mode = 'edit';
$output = $extra_msg = NULL;
// A high limit means we are doing the "unanswered" page.
Index: faq_ask.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/faq_ask/faq_ask.install,v
retrieving revision 1.4.2.7
diff -u -r1.4.2.7 faq_ask.install
--- faq_ask.install 24 Nov 2008 20:13:07 -0000 1.4.2.7
+++ faq_ask.install 25 Feb 2010 11:51:41 -0000
@@ -32,6 +32,28 @@
'tid' => array('tid', 'uid'),
),
);
+
+ $schema['faq_ask_notify'] = array(
+ 'description' => t('FAQ node to asker mapping.'),
+ 'fields' => array(
+ 'nid' => array(
+ 'description' => t('Node identifier for notification'),
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ ),
+ 'email' => array(
+ 'description' => t('Node identifier for notification'),
+ 'type' => 'varchar',
+ 'length' => '128',
+ 'not null' => TRUE,
+ ),
+ ),
+ 'primary key' => array('nid', 'email'),
+ 'indexes' => array(
+ 'nid' => array('nid', 'email'),
+ ),
+ );
return $schema;
}
@@ -55,11 +77,22 @@
function faq_ask_update_6100() {
$ret = array();
- $ret[] = update_sql('INSERT INTO {faq_expert} (uid, tid) VALUES ('. variable_get('faq_ask_default_expert', 1) .', 0)');
+ $ret[] = update_sql('INSERT INTO {faq_expert} (uid, tid) VALUES ('. variable_get('faq_ask_default_expert', 1) .', 0)');
+
+ return $ret;
+}
+
+function faq_ask_update_6101() {
+
+ $ret = array();
+ $schema = faq_ask_schema();
+ db_create_table($ret, 'faq_ask_notify', $schema['faq_ask_notify']);
return $ret;
+
}
+
/**
* Implementation of hook_uninstall().
*/
@@ -77,6 +110,6 @@
variable_del('faq_ask_help_text');
variable_del('faq_ask_categorize');
variable_del('faq_ask_expert_own');
-
+
drupal_set_message(t('faq_ask module uninstalled.'));
}