/[drupal]/contributions/modules/question/question.module
ViewVC logotype

Contents of /contributions/modules/question/question.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.9 - (show annotations) (download) (as text)
Fri Oct 24 04:34:00 2008 UTC (13 months ago) by codepoet
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--1
Changes since 1.8: +0 -0 lines
File MIME type: text/x-php
*** empty log message ***
1 <?php
2 // $Id: question.module,v 1.7.4.10 2008/10/24 02:39:28 codepoet Exp $
3
4 /**
5 * Implementation of hook_help().
6 *
7 */
8
9 function question_help($section) {
10 switch ($section) {
11 case 'node/add#question':
12 // This description shows up when users click "create content."
13 return t('A question/answer node.');
14 case 'admin/question':
15 return t('Here is a list of the questions that have been submitted to your site. Each question can be answered by selecting "promote". Once submitted, this question becomes a node. Choose "delete" to delete this question without answering.');
16 }
17 }
18
19 /**
20 * Implementation of hook_node_info().
21 *
22 */
23 function question_node_info() {
24 return array('question' => array(
25 'name' => t('Question'),
26 'module' => 'question',
27 'description' => 'Users can ask questions and administrators can respond.'));
28 }
29
30 /**
31 * Implementation of hook_access().
32 *
33 */
34 function question_access($op, $node) {
35 global $user;
36
37 if ($op == 'create') {
38 return user_access('ask questions');
39 } elseif ($op == 'update' && $node->uid == $user->uid) {
40 if (user_access('ask questions')) { return TRUE; }
41 else { return NULL; }
42 } elseif ($op == 'update') {
43 if (user_access('manage questions')) { return TRUE; }
44 else { return NULL; }
45 }
46 }
47
48 /**
49 * Implementation of hook_perm().
50 *
51 */
52 function question_perm() {
53 return array('ask questions', 'manage questions');
54 }
55
56
57 /**
58 * Implementation of hook_menu().
59 *
60 */
61 function question_menu($may_cache) {
62 $items = array();
63
64 if ($may_cache) {
65 $items[] = array(
66 'path' => 'node/add/question',
67 'title' => t('Question'),
68 'access' => user_access('manage questions'));
69 $items[] = array(
70 'path' => 'admin/content/question',
71 'title' => t('Questions'),
72 'description' => t('Manage the question queue.'),
73 'access' => user_access('manage questions'),
74 'callback' => 'question_list_page');
75 $items[] = array(
76 'path' => 'question',
77 'title' => t('Ask a question'),
78 'access' => user_access('ask questions'),
79 'callback' => 'question_add');
80 $items[] = array(
81 'path' => 'admin/settings/question',
82 'title' => t('Question'),
83 'description' => t('Edit Question settings.'),
84 'callback' => 'drupal_get_form',
85 'callback arguments' => 'question_settings',
86 'access' => user_access('administer site configuration'),
87 'type' => MENU_NORMAL_ITEM );
88 }
89
90 return $items;
91 }
92
93 /**
94 * Implementation of hook_form().
95 *
96 */
97 function question_form(&$node) {
98
99 if (arg(2)=='question' && is_numeric(arg(3))) {
100 $que = db_fetch_object(db_query('SELECT * FROM {question_queue} WHERE qid = %d', arg(3)));
101 $node->questioner = $que->questioner;
102 $node->question = $que->question;
103 $form['qid'] = array(
104 '#type' => 'hidden',
105 '#value' => arg(3),
106 );
107 }
108
109 $form['title'] = array('#type' => 'textfield',
110 '#title' => t('Subject'),
111 '#default_value' => $node->title,
112 '#size' => 60,
113 '#maxlength' => 128,
114 '#weight' => -8,
115 '#required' => TRUE);
116
117 $form['questioner'] = array(
118 '#type' => 'textfield',
119 '#title' => t('Questioner'),
120 '#default_value' => $node->questioner,
121 '#size' => 60,
122 '#maxlength' => 128,
123 '#weight' => -7,
124 '#description' => t("The person asking the question. Can be the user's id (uid), username, or an email address."),
125 );
126
127 // Now we define the form elements specific to our node type.
128 $form['question'] = array('#weight' => -6);
129 $form['question']['question'] = array(
130 '#type' => 'textarea',
131 '#title' => t('Question'),
132 '#default_value' => $node->question,
133 '#cols' => 60,
134 '#rows' => 20
135 );
136 $form['question']['q_format'] = filter_form($node->q_format, 10, array('q_format'));
137
138 $form['answer'] = array('#weight' => -5);
139 $form['answer']['answer'] = array(
140 '#type' => 'textarea',
141 '#title' => t('Answer'),
142 '#default_value' => $node->answer,
143 '#cols' => 60,
144 '#rows' => 20
145 );
146 $form['answer']['a_format'] = filter_form($node->a_format, 10, array('a_format'));
147
148 return $form;
149 }
150
151 /**
152 * Implementation of hook_validate().
153 *
154 */
155 function question_validate(&$node) {
156
157 $node->body = '';
158
159 // make body for node previews and whatnot
160 //$node->body = '<em>'.$node->question."</em><br />\n
161 //".$node->answer;
162 //$node->format = $node->a_format;
163
164 //check validity of questioner
165 $req = (variable_get('question_require_registered', FALSE));
166 if (is_numeric($node->questioner)) {
167 // is it a uid?
168 if (!$account = user_load(array('uid'=>$node->questioner))) {
169 // it is not a uid
170 if ($req) {
171 form_set_error('questioner', t('This is not a valid user id.'));
172 }
173 }
174 else {
175 // it is a uid
176 $node->quid = $account->uid;
177 $node->questioner = $account->name;
178 }
179 }
180 else {
181 if (valid_email_address($node->questioner)) {
182 // it's an email address
183 if ($account = user_load(array('mail'=>$node->questioner))) {
184 // they're "one of us"
185 $node->quid = $account->uid;
186 $node->questioner = $account->name;
187 }
188 }
189 elseif ($account = user_load(array('name'=>$node->questioner))) {
190 // it's a user
191 $node->quid = $account->uid;
192 }
193 else {
194 // it's neither an email nor a user
195 if ($req) {
196 form_set_error('questioner', t('This is neither an email address nor a valid user name.'));
197 }
198 }
199 }
200 }
201
202
203 function question_settings() {
204 // require users to be registered in order to ask questions?
205 $form['question_require_registered'] = array(
206 '#type' => 'checkbox',
207 '#weight' => -5,
208 '#title' => t('Require registered users?'),
209 '#return_value' => 1,
210 '#default_value' => variable_get('question_require_registered', FALSE),
211 '#description' => t('Require users to be authenticated in order to submit questions?'),
212 );
213
214 // Thank You node
215 $form['question_thanks'] = array(
216 '#type' => 'textfield',
217 '#weight' => -3,
218 '#title' => t('Path to "Thank You" node'),
219 '#default_value' => variable_get('question_thanks', FALSE),
220 '#size' => 40,
221 '#maxlength' => 100,
222 '#description' => t('This is where users will end up after they submit the question form. Example: "node/454".<br/>Leave blank and user will be returned to the form page with a thank you message.'),
223 );
224
225 // Instructions
226 $form['question_instructions'] = array(
227 '#type' => 'textarea',
228 '#weight' => -1,
229 '#title' => t('Instructions for the user'),
230 '#default_value' => variable_get('question_instructions', FALSE),
231 '#size' => 40,
232 '#description' => t('This message will appear above the question form to provide the user instructions.'),
233 );
234
235 $form['question_instructions_format'] = filter_form(variable_get('question_instructions_format', false), 0, array('question_instructions_format'));
236
237 return system_settings_form($form);
238 }
239
240
241 function question_list_page($op = NULL, $qid = NULL) {
242 if ($_POST['edit']['confirm']) {
243 question_queue_item_delete($_POST['edit']['qid']);
244 unset($_POST);
245 drupal_goto('admin/content/question');
246 }
247 switch ($op) {
248 case 'delete':
249 return drupal_get_form('question_queue_item_delete');
250 break;
251 default:
252 $headers = array(t('Question'), t('Operations'));
253 $sql = 'SELECT * FROM {question_queue} ORDER BY qid DESC';
254 $result = pager_query($sql);
255 while ($r = db_fetch_object($result)) {
256 $rows[$r->qid]['question']['data'] = '<i>'.$r->questioner.'</i><br/>'.check_markup($r->question);
257 $rows[$r->qid]['question']['style'] = 'vertical-align:top;border-bottom:solid 1px #666;';
258 $rows[$r->qid]['operations']['data'] = l(t('delete'), 'admin/content/question/delete/'.$r->qid).'&nbsp;'.l(t('promote'), 'node/add/question/'.$r->qid, array('title'=>t('create a question node based on this submission')));
259 $rows[$r->qid]['operations']['style'] = 'vertical-align:top;border-bottom:solid 1px #666;';
260 }
261 $output = theme('table', $headers, $rows, array('style'=>'width:100%', 'cellpadding'=>'5'));
262 $output .= theme('pager');
263 }
264 return $output;
265 }
266
267 function question_queue_item_delete() {
268 $qid = arg(4);
269 $queue_item = db_fetch_object(db_query("SELECT * from {question_queue} WHERE qid = %d", $qid));
270
271 $form['qid'] = array(
272 '#type' => 'hidden',
273 '#value' => $qid
274 );
275 return confirm_form($form, t('Are you sure you want to delete this question?'), 'admin/content/question', $queue_item->question, t('Delete'), t('Cancel'), 'question_queue_item_delete');
276 }
277
278 function question_queue_item_delete_submit($form_id, $form_values) {
279 db_query('DELETE FROM {question_queue} WHERE qid="%d"', $form_values['qid']);
280 drupal_set_message(t('Item deleted'));
281 drupal_goto('admin/content/question');
282 }
283
284 /**
285 * Implementation of hook_insert().
286 *
287 */
288 function question_insert($node) {
289 db_query("INSERT INTO {question_node} (nid, questioner, quid, question, q_format, answer, a_format) VALUES (%d, '%s', %d, '%s', %d, '%s', %d)", $node->nid, $node->questioner, $node->quid, $node->question, $node->q_format, $node->answer, $node->a_format);
290 // if this node came from the queue, delete the queue item...
291 if (isset($node->qid)) {
292 db_query("DELETE FROM {question_queue} WHERE qid = %d", $node->qid);
293 }
294 }
295
296 /**
297 * Implementation of hook_update().
298 *
299 */
300 function question_update($node) {
301 db_query("UPDATE {question_node} SET questioner='%s', quid=%d, question='%s', q_format=%d, answer='%s', a_format=%d WHERE nid = %d", $node->questioner, $node->quid, $node->question, $node->q_format, $node->answer, $node->a_format, $node->nid);
302 }
303
304 /**
305 * Implementation of hook_delete().
306 *
307 */
308 function question_delete($node) {
309 db_query('DELETE FROM {question_node} WHERE nid = %d', $node->nid);
310 }
311
312 /**
313 * Implementation of hook_load().
314 *
315 */
316 function question_load($node) {
317 $additions = db_fetch_object(db_query('SELECT questioner, quid, question, q_format, answer, a_format FROM {question_node} WHERE nid = %d', $node->nid));
318 return $additions;
319 }
320
321 /**
322 * Implementation of hook_view().
323 *
324 */
325 function question_view($node, $teaser = FALSE, $page = FALSE) {
326 $node = node_prepare($node, $teaser);
327 if ($teaser) {
328 $node->content['teaser']['#value'] = theme('question_teaser', $node);
329 } else {
330 $node->content['body']['#value'] = theme('question_body', $node);
331 }
332 return $node;
333 }
334
335 function theme_question_body($node) {
336 if ($node->quid) {
337 $node->questioner = l($node->questioner, 'user/'.$node->quid);
338 }
339 $output = '<div class="question">';
340 if ($node->questioner) {
341 $output .= '<div class="question-asks">'.$node->questioner.t(" asks:")."</div>";
342 }
343 $output .= '<div class="question-question">'.t('<h3>Question</h3>').check_markup($node->question, $node->q_format, FALSE).'</div>';
344 $output .= '<div class="question-answer">'.t('<h3>Answer</h3>').check_markup($node->answer, $node->a_format, FALSE).'</div>';
345 $output .= '</div>';
346 return $output;
347 }
348
349 function theme_question_teaser($node) {
350 // just the question for the teasers...
351 $output = '<div class="question">';
352 $output .= '<div class="question-question">'.check_markup($node->question, $node->q_format, FALSE).'</div>';
353 $output .= '</div>';
354 $output .= l(t('Read the answer...'),'node/'.$node->nid);
355 return $output;
356 }
357
358 function question_add() {
359 // initial form...
360 drupal_set_title(t("Submit a Question"));
361
362 $instructions = check_markup(variable_get('question_instructions', false), variable_get('question_instructions_format', false), false);
363 if (strlen($instructions)) {
364 $output = '<div class="question instructions">' . t($instructions) . '</div>';
365 }
366
367 $output .= drupal_get_form('question_qform');
368 print theme('page', $output);
369 return;
370 }
371
372 function theme_question_qform($form) {
373 global $user;
374 return drupal_render($form);
375 }
376
377 function question_qform() {
378 global $user;
379
380 // if we are requiring registered users, but user is not logged in
381 if (!$user->uid && variable_get('question_require_registered', FALSE)) {
382 $form['error'] = array(
383 '#type' => 'markup',
384 '#value' => t('<p />Please <a href="!login">login or register</a> to submit questions.', array("!login" => url('user/login', drupal_get_destination())))
385 );
386 return $form;
387 }
388 // if user is logged in or we're not requiring registered users
389 else if (!variable_get('question_require_registered', FALSE)) {
390 $form['questioner'] = array(
391 '#type' => 'textfield',
392 '#title' => t('Your name'),
393 '#default_value' => $user->name,
394 '#size' => 40,
395 '#maxlength' => 60,
396 '#description' => t('Your name, username, or email address'),
397 );
398 }
399 else {
400 $form['questioner'] = array(
401 '#type' => 'hidden',
402 '#value' => $user->name,
403 );
404 }
405 $form['question'] = array(
406 '#type' => 'textarea',
407 '#title' => t('Question'),
408 '#default_value' => $_POST['question'],
409 '#cols' => 60,
410 '#rows' => 10,
411 '#description' => NULL,
412 '#attributes' => NULL,
413 '#required' => TRUE,
414 );
415 $form[] = array(
416 '#type' => 'submit',
417 '#value' => t('Submit Question'),
418 );
419 $form['#method'] = 'post';
420 $form['#action'] = url('question', drupal_get_destination());
421 return $form;
422 }
423
424 function question_qform_validate ($form_id, $form_values) {
425 if ($form_values['question'] == '') {
426 form_set_error('question', t('Please enter a question.'));
427 }
428 }
429
430 function question_qform_submit ($form_id, $form_values) {
431 $qid = db_next_id('question_queue');
432 global $user;
433 $quid = $user->uid;
434 db_query('INSERT INTO {question_queue} (qid, questioner, quid, question) VALUES (%d, "%s", %d, "%s")', $qid, $form_values['questioner'], $quid, $form_values['question']);
435 $path = variable_get('question_thanks', '');
436 $dest = $_REQUEST['destination'];
437 unset($_REQUEST['destination']);
438
439 if (strlen(trim($path))) {
440 // if the 'question thank you node' variable was set...
441 drupal_goto($path);
442 }
443 else {
444 drupal_set_message(t('Your question was submitted.'));
445
446 // if not...
447 if ($dest) {
448 //go back to the original question node...
449 drupal_goto($dest);
450 }
451 else {
452 // last resort
453 drupal_goto('node');
454 }
455 }
456 }
457
458 /**
459 * This function is for those that want to insert a question form into
460 * a node to make it easier for people to ask questions. All it does
461 * is pull the rendered form and print it out.
462 */
463
464 function question_print_form() {
465 print drupal_get_form('question_qform');
466 }
467
468 /**
469 * Returns node object for latest question (based on node's creation date)
470 *
471 */
472
473 function question_get_latest() {
474 $obj = db_fetch_object(db_query('SELECT n.nid FROM {question_node} q INNER JOIN {node} n ON n.nid = q.nid WHERE n.status = 1 ORDER BY n.created DESC'));
475 if ($obj) {
476 $node = node_load($obj->nid);
477 return $node;
478 } else {
479 return;
480 }
481 }
482
483 function question_get_random() {
484 $obj = db_fetch_object(db_query('SELECT n.nid FROM {question_node} q INNER JOIN {node} n ON n.nid = q.nid WHERE n.status = 1 ORDER BY RAND()'));
485 if ($obj) {
486 $node = node_load($obj->nid);
487 return $node;
488 } else {
489 return;
490 }
491 }
492
493 /**
494 * Returns rendered listing of questions
495 * $teaser is a true/false indicating whether the teaser version
496 * of the node should be displayed
497 * $links is a true/false indicating whether links should be displayed
498 * $joins is a string containing JOIN arguments for SQL call
499 * example: 'INNER JOIN {term_node} t ON t.nid = q.nid'
500 * $wheres is a string containing additional WHERE arguments
501 * example: 'AND t.tid = 12'
502 * $order is a string containing ORDER BY
503 *
504 * The above example arguments would return the node ids of all question nodes
505 * that are tagged with taxonomy term 12
506 */
507
508 function question_list_questions($teaser = TRUE, $links = FALSE, $joins = '', $wheres = '', $order = 'ORDER BY n.created DESC') {
509 $result = db_query("SELECT n.nid FROM {node} n ".$joins." WHERE n.type = 'question' AND n.status = 1 ".$wheres." ".$order);
510 while ($row = db_fetch_object($result)) {
511 $node = node_load($row->nid);
512 $output .= node_view($node, $teaser, FALSE, $links);
513 }
514 return $output;
515 }
516
517 /**
518 * Implementation of hook_block.
519 *
520 * Offers 2 blocks: latest question and random question
521 */
522 function question_block($op, $delta = 0) {
523 switch ($op) {
524 case 'list':
525 $block[0]['info'] = t('Latest question');
526 $block[1]['info'] = t('Random question');
527
528 return $block;
529 case 'view':
530 if (user_access('access content')) {
531 switch($delta) {
532 case 0:
533 $question = question_get_latest();
534 $block['subject'] = t('Latest question');
535 $block['content'] = theme('question_block', $question);
536 break;
537 case 1:
538 $question = question_get_random();
539 $block['subject'] = t('Random question');
540 $block['content'] = theme('question_block', $question);
541 break;
542 }
543 }
544 return $block;
545 }
546 }
547
548 function theme_question_block($node) {
549 return theme_question_teaser($node);
550 }

  ViewVC Help
Powered by ViewVC 1.1.2