Index: faq_ask.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/faq_ask/faq_ask.info,v retrieving revision 1.2 diff -u -r1.2 faq_ask.info --- faq_ask.info 5 Jan 2008 03:18:53 -0000 1.2 +++ faq_ask.info 22 Jan 2008 15:26:49 -0000 @@ -1,4 +1,5 @@ ; $Id: faq_ask.info,v 1.2 2008/01/05 03:18:53 nancyw Exp $ name = Faq_Ask description = "Allows an unanswered question 'queue' for the FAQ module." -dependencies = faq +dependencies[] = faq +core = 6.x Index: faq_ask.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/faq_ask/faq_ask.install,v retrieving revision 1.4 diff -u -r1.4 faq_ask.install --- faq_ask.install 17 Jan 2008 14:36:52 -0000 1.4 +++ faq_ask.install 21 Jan 2008 22:33:12 -0000 @@ -3,7 +3,7 @@ /** * Implementation of hook_schema(). - **/ + */ function faq_ask_schema() { $schema['faq_expert'] = array( 'description' => t('Contact form log table.'), @@ -31,39 +31,23 @@ /** * Implementation of hook_install(). - **/ + */ function faq_ask_install() { - // Note: I did not specify defaults here because an insert should fail if a value is not supplied. - switch ($GLOBALS['db_type']) { - case 'mysql': - case 'mysqli': - $result = db_query("CREATE TABLE IF NOT EXISTS {faq_expert} ( - uid INT(10) UNSIGNED NOT NULL, - tid INT(10) UNSIGNED NOT NULL, - PRIMARY KEY (uid, tid), - INDEX tid (tid, uid) - ) /*!40100 DEFAULT CHARACTER SET UTF8 */ "); - break; + $result = drupal_install_schema('faq_ask'); - case 'pgsql': - $result = db_query("CREATE TABLE {faq_expert} ( - uid integer NOT NULL, - tid integer NOT NULL, - PRIMARY KEY (uid, tid) - )"); - db_query("CREATE INDEX {faq_expert}_tid ON {faq_expert} (tid, uid)"); - break; + if (count($result) > 0) { + drupal_set_message(t('faq_ask module installed.')); + } + else { + drupal_set_message(t('faq_ask table creation failed. Please "uninstall" the module and retry.')); } - - if ($result) { drupal_set_message(t('faq_ask module installed.')); } - else { drupal_set_message(t('faq_ask table creation failed. Please "uninstall" the module and retry.')); } } /** * Implementation of hook_uninstall(). - **/ + */ function faq_ask_uninstall() { - db_query('DROP TABLE {faq_expert}'); + drupal_uninstall_schema('faq_ask'); variable_del('faq_expert_role'); variable_del('faq_ask_vocabularies'); Index: faq_ask.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/faq_ask/faq_ask.module,v retrieving revision 1.17 diff -u -r1.17 faq_ask.module --- faq_ask.module 10 Jan 2008 18:15:38 -0000 1.17 +++ faq_ask.module 22 Jan 2008 18:36:36 -0000 @@ -39,9 +39,12 @@ * Implementation of hook_access() */ function faq_ask_access($op, $node) { - global $user; - if ($op == 'create') { return user_access(t('ask_question')) || user_access('answer question'); } - else { return user_access('answer question') || user_access('edit_own_faq'); } + if ($op == 'create') { + return user_access(t('ask_question')) || user_access('answer question'); + } + else { + return user_access('answer question') || user_access('edit_own_faq'); + } } /** @@ -53,55 +56,64 @@ } /** + * Determines whether the current user has one of the given permissions. + */ +function faq_ask_user_access_or($string1, $string2) { + return user_access($string1) || user_access($string2); +} + +/** * Implementation of hook_menu() */ -function faq_ask_menu($may_cache) { +function faq_ask_menu() { $items = array(); - if ($may_cache) { - $items[] = array( - 'path' => 'admin/settings/faq/ask', - 'title' => t('Experts'), - 'callback' => 'drupal_get_form', - 'callback arguments' => array('faq_ask_settings_form'), - 'access' => user_access('administer faq'), - 'description' => t('Allows the user to configure the Ask_FAQ module.'), - 'type' => MENU_LOCAL_TASK, - 'weight' => -2, - ); + $items['admin/settings/faq/ask'] = array( + 'title' => t('Experts'), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('faq_ask_settings_form'), + 'access arguments' => array('administer faq'), + 'description' => t('Allows the user to configure the Ask_FAQ module.'), + 'type' => MENU_LOCAL_TASK, + 'weight' => -2, + ); - $items[] = array( - 'path' => 'faq_ask', - 'title' => t('Ask a question'), - 'callback' => 'faq_ask_page', - 'access' => user_access('ask question'), - ); - } - else { - $items[] = array( - 'path' => 'faq_ask/answer', - 'title' => t('Answer a question'), - 'callback' => 'faq_ask_answer', - 'access' => user_access('answer question'), - 'type' => MENU_CALLBACK, - ); - - $items[] = array( - 'path' => 'faq_ask/edit', - 'title' => t('Edit a question'), - 'callback' => 'faq_ask_edit', - 'access' => user_access('answer question'), - 'type' => MENU_CALLBACK, - ); - - $items[] = array( - 'path' => 'faq_ask/more', - 'title' => t('List more unanswered questions'), - 'callback' => 'faq_ask_list_more', - 'access' => user_access('answer question') || user_access('ask question'), - 'type' => MENU_CALLBACK, - ); - } + $items['faq_ask'] = array( + 'title' => t('Ask a question'), + 'page callback' => 'faq_ask_page', + 'access callback' => 'user_access', + 'access arguments' => array('ask question'), + 'weight' => 1, + ); + + $items['faq_ask/%'] = array( + 'page arguments' => array(1), + 'access arguments' => array('ask question'), + ); + + $items['faq_ask/answer/%node'] = array( + 'title' => t('Answer a question'), + 'page callback' => 'faq_ask_answer', + 'page arguments' => array(2), + 'access arguments' => array('answer question'), + 'type' => MENU_CALLBACK, + ); + + $items['faq_ask/edit/%node'] = array( + 'title' => t('Edit a question'), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('faq_ask_form', null, 2), + 'access arguments' => array('answer question'), + 'type' => MENU_CALLBACK, + ); + + $items['faq_ask/more'] = array( + 'title' => t('List more unanswered questions'), + 'page callback' => 'faq_ask_list_more', + 'access callback' => 'faq_ask_user_access_or', + 'access arguments' => array('answer question', 'ask question'), + 'type' => MENU_CALLBACK, + ); return $items; } @@ -125,25 +137,18 @@ } /** - * Get the edit question form. - */ -function faq_ask_edit($nid = null) { - $form = drupal_get_form('faq_ask_form', null, $nid); - return $form; -} - -/** * Implementation of hook_form() * This is the "ask question" form. */ -function faq_ask_form($tid, $nid, $form_values = null) { +function faq_ask_form($form_state, $tid, $node) { $form = array(); - + // We will allow term suggestions only if the setting is chosen // AND there is a vocabulary named "FAQ." $vid = db_result(db_query("SELECT vid FROM {vocabulary} WHERE name='FAQ' LIMIT 1")); $suggest = variable_get('faq_ask_suggest', false) && $vid; - + + $cat_list = array(); if ($suggest) { $cat_list[0] = t(''); $form['#multistep'] = true; @@ -156,7 +161,6 @@ // Find all the categories for which we have experts. $result = db_query('SELECT DISTINCT(name), e.tid FROM {faq_expert} e JOIN {term_data} t USING (tid)'); - $cat_list = array(); while ($term = db_fetch_array($result)) { $cat_list[$term['tid']] = $term['name']; } @@ -172,13 +176,14 @@ } // If a nid exists, then get the existing values. - if ($nid) { - $node = node_load($nid); + if ($node) { + $nid = $node->nid; $title = $node->title; $taxo = array_keys($node->taxonomy); $default_tid = $taxo[0]; } else { + $nid = null; $default_tid = $tid; $title = null; } @@ -199,8 +204,8 @@ '#description' => t('Please select the correct category for your question.'), ); - if (isset($form_values)) { - if ($form_values['category'] == 0) { + if (count($form_state['post']) > 0) { + if ($form_state['post']['category'] == 0) { $form['new_cat'] = array( '#title' => t('Suggested Category'), '#type' => 'textfield', @@ -240,9 +245,10 @@ * Implementation of hook_form_submit. * This function gets the entered question and category and creates an unpublished FAQ node. */ -function faq_ask_form_submit($form_id, $form_values) { +function faq_ask_form_submit($form, &$form_state) { global $user; - + $form_values = $form_state['values']; + $category = $form_values['category']; if ($category == 0 && empty($form_values['new_cat'])) { // Can only be 0 if allowing category suggestion. @@ -262,7 +268,9 @@ $cert_tid = $term['tid']; // Setting up the expert will be done in hook_taxonomy. } - $term = taxonomy_get_term($category); + else { + $term = taxonomy_get_term($category); + } $node = array( 'type' => 'faq', @@ -271,11 +279,12 @@ 'taxonomy' => array($category => $term), 'created' => time(), 'uid' => $user->uid, + 'name' => $user->name, 'status' => 0, /* Unpublished. */ 'format' => 1, /* Default filter (filtered HTML) */ 'comment' => variable_get('comment_faq', 0), ); - + $node_options = variable_get('node_options_'. $node['type'], array('status', 'promote')); foreach (array('promote', 'sticky', 'revision') as $key) { $node[$key] = in_array($key, $node_options) ? 1 : 0; @@ -286,11 +295,11 @@ // Okay, let's get it done. Node_submit will prepare it and make it an object. $node = node_submit($node); node_save($node); - + // Are we notifying the expert(s)? if (variable_get('faq_ask_notify', false)) { // Find out who the experts are. - $result = db_query("SELECT u.mail FROM {faq_expert} e JOIN {users} u USING (uid) WHERE e.tid=%d", $category); + $result = db_query('SELECT u.mail FROM {faq_expert} e JOIN {users} u USING (uid) WHERE e.tid=%d', $category); $to_addresses = array(); while ($expert = db_fetch_array($result)) { $to_addresses[] = $expert['mail']; @@ -309,9 +318,9 @@ $body = t('The following question has been posted in the "!cat" category.', array('!cat' => $term->name)); $body .= '

'. $form_values['title']; // The URLs in the following are contructed as absolute addresses. - $body .= '

'. t('In order to answer it you will first need to login to the site.', array('!url' => url('user', null, null, true))); - $body .= '
'. t('Once logged in, you may proceed directly to the question to answer it.', array('!url' => url('faq_ask/answer/'. $node->nid, null, null, true))); - + $body .= '

'. t('In order to answer it you will first need to login to the site.', array('!url' => url('user', array('absolute' => TRUE)))); + $body .= '
'. t('Once logged in, you may proceed directly to the question to answer it.', array('!url' => url('faq_ask/answer/'. $node->nid, array('absolute' => TRUE)))); + $mail_sent = drupal_mail('expert-notify', $to, 'You have a question waiting', $body, $from, $header); if ($mail_sent) { watchdog('FAQ_Ask', t('Expert notification email sent.') .' '. $to, WATCHDOG_NOTICE); @@ -350,11 +359,13 @@ } else { $msg = t('It should appear in the list momentarily.'); - } + } + } + else { + $msg = null; } - else { $msg = null; } drupal_set_message(t('Your question has been submitted.') .' '. $msg, 'notice'); - + drupal_goto('faq/'. $category); } } @@ -363,7 +374,7 @@ * Implementation of hook_form. * This form allows the users to select the expert roles and to which categories the users in those roles are assigned. * Note, the expert/category table attempts to use the least horizontal space, - * so it can "flip" based on whether there are more categories or experts. + * so it can "flip" based on whether there are more categories or experts. */ function faq_ask_settings_form($op = null, $aid = null) { $form = array(); @@ -402,6 +413,7 @@ if (count($vocabs) == 1) { // Single vocabulary, don't bother with a selection box, just set it. $vid = key($vocabs); + $def_vid = $vid; variable_set('faq_ask_vocabularies', array($vid => $vid)); $vobj = $vocabs[$vid]; $free = $vobj->tags; @@ -484,7 +496,7 @@ // Put them in alphabetical order. asort($faq_expert_names); } - + if (!empty($role_list)) { $form['faq_expert_role'] = array( '#type' => 'select', @@ -501,7 +513,7 @@ // If there is only one eligible expert, we might as well preset all categories. $expert_msg = null; $only_one_expert = (count($faq_expert_names) == 1); - + $count = 0; if ($more_experts_than_terms) { // Experts go down the left; terms go across the top. @@ -526,11 +538,15 @@ '#suffix' => '', ); $top = null; - $left = null; + $left = null; } - $form[$box_name]['#suffix'] .= ''; + if (isset($box_name)) { + $form[$box_name]['#suffix'] .= ''; + } + } + if (isset($box_name)) { + $form[$box_name]['#suffix'] .= ''; } - $form[$box_name]['#suffix'] .= ''; } else { // Experts go across the top; terms go down the left. @@ -552,11 +568,11 @@ '#suffix' => '', ); $top = null; - $left = null; + $left = null; } - $form[$box_name]['#suffix'] .= ''; + $form[$box_name]['#suffix'] .= ''; } - $form[$box_name]['#suffix'] .= ''; + $form[$box_name]['#suffix'] .= ''; } $result = db_query("SELECT * FROM {faq_expert}"); while ($expert = db_fetch_array($result)) { @@ -583,7 +599,7 @@ '#description' => t('The selected user will be assigned as the expert for all terms that are added to the selected vocabularies until you return to this page and update it.'), '#default_value' => variable_get('faq_ask_default_expert', 1), ); - } + } $form['save']['update'] = array( '#type' => 'submit', @@ -598,10 +614,15 @@ * Implementation of hook_form_submit. * It saves the expert roles that were selected, then rebuilds the expert/category table. */ -function faq_ask_settings_form_submit($form_id, $form_values) { +function faq_ask_settings_form_submit($form, &$form_state) { + $form_values = $form_state['values']; // Save the simple stuff. - variable_set('faq_expert_role', $form_values['faq_expert_role']); - variable_set('faq_ask_vocabularies', $form_values['faq_ask_vocabularies']); + if (isset($form_values['faq_expert_role'])) { + variable_set('faq_expert_role', $form_values['faq_expert_role']); + } + if (isset($form_values['faq_ask_vocabularies'])) { + variable_set('faq_ask_vocabularies', $form_values['faq_ask_vocabularies']); + } variable_set('faq_ask_title_len', $form_values['faq_ask_title_len']); variable_set('faq_ask_suggest', $form_values['faq_ask_suggest']); variable_set('faq_ask_notify', $form_values['faq_ask_notify']); @@ -632,12 +653,12 @@ * This function is called when an expert selects a question to answer. * It changes the status option to "published" then goes to the regular FAQ edit function. */ -function faq_ask_answer($nid) { +function faq_ask_answer($node) { // Change the status to published. - db_query("UPDATE {node} SET status=1 WHERE nid=%d", $nid); - + db_query("UPDATE {node} SET status=1 WHERE nid=%d", $node->nid); + // Need to invoke node/##/edit. - drupal_goto('node/'. $nid .'/edit'); + drupal_goto('node/'. $node->nid .'/edit'); } /** @@ -670,14 +691,14 @@ } } break; - + case 'vocabulary': // New vocabulary created. It will not show on the ask page until the user // goes to the settings page, so we don't need to do anything. break; } // End insert switch type. break; - + case 'delete': switch ($type) { case 'term': @@ -686,7 +707,7 @@ _faq_ask_delete_expert($array['tid'], $array['name']); } break; - + case 'vocabulary': // Each term gets deleted first, so all we have to do is remove it from our vocab list. if ($our_vocab) { @@ -695,7 +716,7 @@ break; } // End delete switch type. break; - + case 'update': // Two cases for vocabulary: // 1) FAQ is added to the vocab. -- see insert comment. @@ -705,7 +726,7 @@ case 'term': // Term update: nothing to do. break; - + case 'vocabulary': if (in_array('faq', $array['nodes'])) { // If it's there now, we're done. @@ -728,7 +749,7 @@ default: drupal_set_message(t('Faq_ask_taxonomy: Unknown op (@op) encountered', array('@op' => $op)), 'warning'); - + } // End switch $op } @@ -775,7 +796,7 @@ * * @param: none. * - * @return: + * @return: * vocabulary object from taxonomy module, or a boolean false if no faq nodes were found. */ function faq_ask_get_vocabulary() { @@ -843,13 +864,15 @@ function faq_ask_list_unanswered($limit) { global $user; // Bounce anonymous users. - if ($user->uid == 0) { return null; } - + if ($user->uid == 0) { + return null; + } + // What permissions does this user have? $can_edit = user_access('administer faq') || user_access('administer nodes'); $is_expert = user_access('answer question'); $only_own = user_access('edit own faq'); - + $mode = 'edit'; $extra_msg = null; @@ -871,22 +894,24 @@ $where = implode(',', array_fill(0, count($terms), '%d')); $result = db_query("SELECT n.title, n.nid FROM {node} n JOIN {term_node} tn USING (nid) WHERE n.type='faq' AND n.status=0 AND tn.tid IN ($where) ORDER BY n.created ASC", $terms); } - else { if ($can_edit) { - $result = db_query("SELECT title, nid FROM {node} WHERE type='faq' AND status=0 ORDER BY n.created ASC"); - } - else { // Edit own. + else { + if ($can_edit) { + $result = db_query("SELECT title, nid FROM {node} WHERE type='faq' AND status=0 ORDER BY n.created ASC"); + } + // Edit own. + else { $result = db_query("SELECT title, nid FROM {node} n $join WHERE n.type='faq' AND n.status=0 AND n.uid=%d ORDER BY n.created ASC", $user->uid); } } - + // Get unpublished nodes that are type='faq'. Stop at the limit given. $items = array(); $i = 0; - + while ($node = db_fetch_array($result)) { ++$i; if ($i > $limit) { - $items[] = l(''. t('more...') .'', 'faq_ask/more', array(), null, null, false, true); + $items[] = l(''. t('more...') .'', 'faq_ask/more', array('html' => TRUE)); break; } $items[] = l($node['title'], 'faq_ask/'. $mode .'/'. $node['nid']); @@ -894,7 +919,9 @@ if (count($items)) { return theme('item_list', $items) . $extra_msg; } - else { return null; } + else { + return null; + } } /* @@ -904,51 +931,56 @@ function faq_ask_list_more() { global $user; // Bounce anonymous users. - if ($user->uid == 0) { return null; } + if ($user->uid == 0) { + return null; + } drupal_set_title(t('All Unanswered Questions')); if (user_access('administer blocks')) { $output = '

'. t('You may go here to change the block limit.', array('!setting' => url('admin/build/block/configure/faq_ask/0'))) .'

'; } - else { $output = null; } + else { + $output = null; + } $output .= '
'; - + // What permissions does this user have? $can_edit = user_access('administer faq') || user_access('administer nodes'); $is_expert = user_access('answer question'); $only_own = user_access('edit own faq'); - + $mode = 'edit'; - + if ($can_edit) { $result = db_query("SELECT n.title, n.nid, tn.tid FROM {node} n JOIN {term_node} tn USING (nid) WHERE n.type='faq' AND n.status=0 ORDER BY tn.tid ASC, created ASC", $terms); } - else { if ($is_expert) { - $mode = 'answer'; - // Get the expert's terms. - $result = db_query('SELECT * FROM {faq_expert} WHERE uid=%d ORDER BY n.created ASC', $user->uid); - $terms = array(); - while ($expert = db_fetch_array($result)) { - $terms[] = $expert['tid']; - } - - // Check if this expert has any categories. - if (count($terms) == 0) { - return '

'. t("For some strange reason, I couldn't find any categories for you.") .'

'; + else { + if ($is_expert) { + $mode = 'answer'; + // Get the expert's terms. + $result = db_query('SELECT * FROM {faq_expert} WHERE uid=%d ORDER BY n.created ASC', $user->uid); + $terms = array(); + while ($expert = db_fetch_array($result)) { + $terms[] = $expert['tid']; + } + + // Check if this expert has any categories. + if (count($terms) == 0) { + return '

'. t("For some strange reason, I couldn't find any categories for you.") .'

'; + } + // Join the term_data table to select based on tid. + $where = implode(',', array_fill(0, count($terms), '%d')); + $result = db_query("SELECT n.title, n.nid, tn.tid FROM {node} n JOIN {term_node} tn USING (nid) WHERE n.type='faq' AND n.status=0 AND tn.tid IN ($where) ORDER BY tn.tid ASC, created ASC", $terms); } - // Join the term_data table to select based on tid. - $where = implode(',', array_fill(0, count($terms), '%d')); - $result = db_query("SELECT n.title, n.nid, tn.tid FROM {node} n JOIN {term_node} tn USING (nid) WHERE n.type='faq' AND n.status=0 AND tn.tid IN ($where) ORDER BY tn.tid ASC, created ASC", $terms); - } else { // Edit own. $result = db_query("SELECT n.title, n.nid, tn.tid FROM {node} n JOIN {term_node} tn USING (nid) WHERE n.type='faq' AND n.status=0 AND n.uid=%d ORDER BY tn.tid ASC, created ASC", $user->uid); } } - + // Get unpublished nodes that are type='faq'. $items = array(); $prev_cat = -1; - + while ($node = db_fetch_array($result)) { $tid = $node['tid']; if ($prev_cat == $tid) {