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

Contents of /contributions/modules/vocab/vocab.module

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


Revision 1.6 - (show annotations) (download) (as text)
Sat Jan 6 17:39:10 2007 UTC (2 years, 10 months ago) by suuch
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +1 -1 lines
File MIME type: text/x-php
Removed redundant argument for hook_link
1 <?php //$Id
2 /**
3 * @file
4 * Creates vocabulary sets as nodes.
5 */
6 /**
7 * Implementation of hook_help().
8 *
9 * Throughout Drupal, hook_help() is used to display help text at the top of
10 * pages. Some other parts of Drupal pages get explanatory text from these hooks
11 * as well. We use it here to provide a description of the module on the
12 * module administration page.
13 */
14 function vocab_help($section) {
15 switch ($section) {
16 case 'admin/modules#description':
17 // This description is shown in the listing at admin/modules.
18 return t('Create a glossary of vocabulary pairs in two languages for review with other modules like the flashcard module');
19 case 'node/add#vocab':
20 // This description shows up when users click "create content."
21 return t('A vocabulary set is a group of vocabulary pairs that are typically reviewed in some form of memory exercise. ');
22 }
23 }
24
25 /**
26 * Implementation of hook_user().
27 */
28
29 function vocab_user($op, &$edit, &$user, $category = array('weight'=>-15)) {
30 global $pager_page_array, $pager_total, $pager_total_items;
31 switch ($op) {
32 case 'view':
33 {//display all user vocabs
34 $my = pager_query("SELECT * FROM {node} WHERE uid='$user->uid' AND type = 'vocab'
35 ORDER BY changed ASC", 10);
36 while($vocab = db_fetch_object($my)){
37 $nurl = 'node/'.$vocab->nid;
38 $myvocab[l('Vocabulary Sets', 'vocab/user')][] = l($vocab->title, $nurl );
39 $true = 1;
40 }
41
42 if($true){
43 $myvocab[l('Vocabulary Sets', 'vocab/user')] = array(array('title'=>join($myvocab[l('Vocabulary Sets', 'vocab/user')], ', ')));
44 }
45 return ($myvocab);
46 }
47 break;
48 }
49 }
50
51 function _vocab_user() {
52 global $user, $pager_page_array, $pager_total, $pager_total_items;
53
54 $js = '<script language="JavaScript">function vocab_jumpMenu(targ,selObj,restore){ //v3.0
55 eval(targ+".location=\'"+selObj.options[selObj.selectedIndex].value+"\'");
56 if (restore) selObj.selectedIndex=0;}
57 </script>';
58
59 drupal_set_html_head($js);
60 $myvocab = array();
61 //display all user vocabs
62 $my = pager_query("SELECT * FROM {node} WHERE uid='$user->uid' AND type = 'vocab'
63 ORDER BY changed ASC", 10);
64
65
66
67 while($vocab = db_fetch_object($my)){
68 $nurl = url('node/'.$vocab->nid.'/');
69 $options = array();
70 $options['none'] = t('Select Review Method');
71 module_exist('flashcard')?( $options[$nurl.'flashcard'] = t('view as flashcards')):'';
72 module_exist('typecheck')?( $options[$nurl.'typecheck'] = t('view as typechecks')):'';
73 $form['myvocab'] = array(
74 '#type' => 'select',
75 '#title' => $vocab->title,
76 '#options' => $options,
77 '#default_value' => 'none',
78 '#description'=>t('If there are no review methods, ask the administrator to enable a method.'),
79 '#attributes' => array(
80 'onChange' => "vocab_jumpMenu('self',this,0)"));
81 $myvocab['Vocabulary Sets'][]= form_render(form_builder(NULL, $form));
82 }
83
84
85 drupal_set_title(t('My Vocabulary Sets'));
86 $output.= join($myvocab['Vocabulary Sets'], ''). theme_pager(array());
87 return $output;
88 }
89 /**
90 * Implementation of hook_node_name().
91 *
92 * This is a required node hook. Since our module only defines one node
93 * type, we won't implement hook_node_types(), and our hook_node_name()
94 * implementation simply returns the translated name of the node type.
95 */
96 function vocab_node_info() {
97 return array('vocab' => array('name' => t('Vocabulary Set'), 'base' => 'vocab'));
98 }
99
100 /**
101 * Implementation of hook_access().
102 *
103 * Node modules may implement node_access() to determine the operations
104 * users may perform on nodes. This vocab uses a very common access pattern.
105 */
106 function vocab_access($op, $node) {
107 global $user;
108
109 if ($op == 'create') {
110 // Only users with permission to do so may create this node type.
111 return user_access('create vocab set');
112 }
113
114 // Users who create a node may edit or delete it later, assuming they have the
115 // necessary permissions.
116 if ($op == 'update' || $op == 'delete') {
117 if (user_access('edit own vocab sets') && ($user->uid == $node->uid)) {
118 return TRUE;
119 }
120 }
121
122 if($op == 'view')
123 {
124 return user_access('view vocab set');
125 }
126 }
127
128 /**
129 * Implementation of hook_perm().
130 *
131 * Since we are limiting the ability to create new nodes to certain users,
132 * we need to define what those permissions are here. We also define a permission
133 * to allow users to edit the nodes they created.
134 */
135 function vocab_perm() {
136 return array('view vocab set', 'create vocab set', 'edit own vocab sets', 'delete vocab set');
137 }
138
139 /**
140 * Implementation of hook_link().
141 *
142 * This is implemented so that an edit link is displayed for users who have
143 * the rights to edit a node.
144 */
145 function vocab_link($type, $node = 0) {
146 $links = array();
147
148 if ($type == 'node' && $node->type == 'vocab') {
149 // Don't display a redundant edit link if they are node administrators.
150 if (vocab_access('update', $node) && !user_access('administer nodes')) {
151 $links[] = l(t('edit this vocab set'), "node/$node->nid/edit");
152 }
153 }
154
155 return $links;
156 }
157
158 /**
159 * Implementation of hook_menu().
160 *
161 * In order for users to be able to add nodes of their own, we need to
162 * give them a link to the node composition form here.
163 */
164 function vocab_menu($may_cache) {
165 $items = array();
166
167 if ($may_cache)
168 {
169 $items[] = array('path' => 'node/add/vocab', 'title' => t('vocab set'),
170 'access' => user_access('create vocab set'));
171 }
172
173 $items[] = array('path' => 'vocab',
174 'access' => user_access('create vocab set'),
175 'callback' => add_vocab_pair,
176 'type'=>MENU_CALLBACK);
177
178 $items[] = array('path' => 'vocab/user',
179 'title'=>t('My vocabulary sets'),
180 'access' => user_access('edit own vocab set'),
181 'callback' => _vocab_user,
182 'type'=> MENU_SUGGESTED_ITEM);
183
184
185 return $items;
186 }
187
188
189 /**
190 * Implementation of hook_form().
191 *
192 * Now it's time to describe the form for collecting the information
193 * specific to this node type. This hook requires us to return some HTML
194 * that will be later placed inside the form.
195 */
196 function vocab_form(&$node)
197 {
198 $form['#token'] = FALSE;
199 $form['title'] = array('#type' => 'textfield',
200 '#title' => t('Subject'),
201 '#default_value' => $node->title,
202 '#size' => 60,
203 '#maxlength' => 128,
204 '#required' => TRUE,
205 '#description'=>t('The subject matter of this vocabulary set'));
206 $form['body_filter'] = array('#type'=>'fieldset');
207 $form['body_filter']['filter'] = filter_form($node->format);
208 $form['body_filter']['body'] = array('#type' => 'textarea',
209 '#title' => t('Preamble'),
210 '#cols' => 60,
211 '#rows' => 5,
212 '#default_value' => $node->body,
213 '#description' => t('Preamble text.'));
214 $form['body_filter']['flabel'] = array('#type' => 'textfield',
215 '#title' => t('Front label'),
216 '#cols' => 60,
217 '#rows' => 5,
218 '#default_value' => $node->flabel,
219 '#description' => t('Front label.'));
220 $form['body_filter']['blabel'] = array('#type' => 'textfield',
221 '#title' => t('Back label'),
222 '#cols' => 60,
223 '#rows' => 5,
224 '#default_value' => $node->blabel,
225 '#description' => t('Back label.'));
226
227 return $form;
228 }
229
230
231
232
233
234 /**
235 * Implementation of hook_update().
236 *
237 * As an existing node is being updated in the database, we need to do our own
238 * database updates.
239 */
240 function vocab_update($node) {
241 $args = preg_split("/\//",$_GET['q']);
242
243 $pos = (sizeof($args)-2);
244 switch( $args[$pos])
245 {
246 case "edit":
247 {
248 if(is_numeric($args[$pos + 1]))
249 {
250 db_query("UPDATE {vocab_data} SET front='%s', back='%s', imageurl='%s' WHERE id = %d ", $_POST['edit']['front'], $_POST['edit']['back'], $_POST['edit']['imageurl'], $args[$pos + 1]);
251 if(db_error()) exit();
252 }
253 else //add
254 {
255 db_query("INSERT INTO {vocab_data} (nid, front, back, imageurl) VALUES (%d, '%s', '%s', '%s')", $node->nid, $_POST['edit']['front'], $_POST['edit']['back'], $_POST['edit']['imageurl']);
256 }
257
258 }
259 break;
260 default:
261 {
262 db_query("REPLACE INTO {vocab_labels} (nid, flabel, blabel) VALUES (%d, '%s', '%s')", $node->nid, $node->flabel, $node->blabel);
263 }
264 break;
265 }
266 }
267
268 /**
269 * Implementation of hook_delete().
270 *
271 * When a node is deleted, we need to clean up related tables.
272 */
273 function vocab_delete($node) {
274 db_query("DELETE FROM {vocab_data} WHERE nid = '%d'", $node->nid);
275 db_query("DELETE FROM {vocab_labels} WHERE nid=%d", $node->nid);
276 }
277
278 /**
279 * Implementation of hook_load().
280 *
281 * Now that we've defined how to manage the node data in the database, we
282 * need to tell Drupal how to get the node back out. This hook is called
283 * every time a node is loaded, and allows us to do some loading of our own.
284 */
285 /*function vocab_load($node) {
286
287
288 // $additions = db_fetch_object(db_query('SELECT * FROM {vocab_data} WHERE id = %d', $node->nid));
289 return $additions;
290 }*/
291
292 /**
293 * Implementation of hook_view().
294 *
295 * This is a typical implementation that simply runs the node text through
296 * the output filters.
297 */
298 function vocab_view(&$node, $teaser = FALSE, $page = FALSE) {
299 $data_info = theme('vocab_data_info', $node);
300 $add_data = theme('vocab_add_data', $node);
301 $node->body .= $data_info;
302 $node->body .= $add_data;
303 $node->teaser .= $data_info;
304 // $node = node_prepare($node, $teaser); //applies selected filters to $node
305 }
306
307 /**
308 * A custom theme function.
309 *
310 * By using this function to format our node-specific information, themes
311 * can override this presentation if they wish. We also wrap the default
312 * presentation in a CSS class that is prefixed by the module name. This
313 * way, style sheets can modify the output without requiring theme code.
314 */
315 function theme_vocab_data_info($node) {
316 global $user;
317 $toDisplay = variable_get('vocabset_display_number', 10);
318
319 $nrows = db_num_rows(db_query('SELECT front, back FROM {vocab_data} WHERE nid = %d', $node->nid));
320 $output = '<div class="vocab_data_info">';
321 $output .= t('%npairs vocabulary pair(s) in this vocabulary set.', array('%npairs' => $nrows));
322
323 $result = pager_query("SELECT * FROM {vocab_data} WHERE nid='$node->nid'
324 ORDER BY nid ASC", $toDisplay);
325 $header = array('', t('Card ID'), t($node->flabel), t($node->blabel), t('Explanation'), '');
326
327 if(isset($_GET['page']))
328 $from = $_GET['page'];
329 else
330 $from = 0;
331
332 while($row = db_fetch_object($result)){
333 if(user_access('edit own vocab sets') && ($user->uid == $node->uid)){
334 $edit = '['.l(t("Edit"), "vocab/$node->nid/edit/$row->id").']';
335 if($_GET['op'] == "delete/".$row->id)
336 $delete = '['.l(t("Confirm"), "node/$node->nid", NULL, 'op=confirmdelete/'.$row->id.'&page='.$from).' | '.l(t("Cancel"), "node/$node->nid", NULL, 'page='.$from).']' ;
337 else if($_GET['op'] == "confirmdelete/".$row->id){
338 $todel = split("/", $_GET['op']);
339 db_query("DELETE FROM {vocab_data} WHERE id=%d", $todel[1]);
340 $delete = '<b>Deleted</b>';
341 }
342 else
343 $delete = '['.l(t("Delete"), "node/$node->nid", NULL, 'op=delete/'.$row->id.'&page='.$from).']';
344 }
345
346 //the "image" is really the explanation keeping the field names to preserve compatibility.
347 //since a link to an image may be the greatest explanation of all :)
348 $image = $row->imageurl;
349
350 $rows[] = array(
351 array('data'=>$edit),
352 array('data'=>$node->nid.'-'.$row->id),
353 array('data'=>check_plain($row->front)),
354 array('data'=>check_plain($row->back)),
355 array('data'=>check_markup($row->imageurl)),
356 array('data'=>$delete),
357 );
358 }
359
360 //make sure we are on the node's own page (rather than the listing of all nodes say) for the theme_pager to work
361 if (arg(0) == 'node' && is_numeric(arg(1))){
362 $pager .= theme_pager(array(),$toDisplay);
363 }
364
365 if(user_access('edit own vocab sets') && ($user->uid == $node->uid)){
366 $addvp .= l(t("Add a vocabulary pair to this set."),'vocab/'.$node->nid.'/add' );
367 }
368 $output .= '</div>';
369 $output.= $addvp.theme('table', $header, $rows, array('width'=>'90%', 'align'=>'center')).$addvp.$pager;
370 return $output;
371 }
372
373 /* Add another / Edit existing vocabulary pair to/in the vocabulary set */
374 function vocab_add_data_form($node) {
375 $form = array();
376 $form['#token'] = FALSE;
377 switch( arg(2))
378 {
379 case "add":
380 {
381 $form['add'] = array(
382 '#type' => 'fieldset',
383 '#title' => t('Add a "Vocabulary" pair to this set.'),
384 '#prefix' => '<div class="vocab_add_data"><h4 style="color:black";>',
385 '#suffix' => '</h4>');
386
387
388 $form['add']['front'] = array(
389 '#type' => 'textarea',
390 '#title' => t($node->flabel),
391 '#default_value' => $node->front,
392 '#cols' => 60,
393 '#rows' => 3,
394 '#maxlength' => 250);
395
396 $form['add']['back'] = array(
397 '#type' => 'textarea',
398 '#title' => t($node->blabel),
399 '#default_value' => $node->back,
400 '#cols' => 60,
401 '#rows' => 5,
402 '#maxlength' => 250);
403
404 $form['add']['imageurl'] = array(
405 '#type' => 'textarea',
406 '#title' => t('Explanation'),
407 '#cols' => 60,
408 '#rows' => 5,
409 '#description'=>t('Feedback for this pair'),
410 '#default_value' => $node->imageurl);
411
412 $form['div_tag'] = array(
413 '#type' => 'markup',
414 '#value' => '</div> <script> </script>');
415
416 $form['add']['submit'] = array(
417 '#type' => 'submit',
418 '#value' => t('Submit'));
419 }
420 break;
421 case "edit":
422 {
423 if(is_numeric(arg(3)))
424 {
425 $form['edit'] = array(
426 '#type' => 'fieldset',
427 '#title' => t('Edit this "Vocabulary" pair.'),
428 '#prefix' => '<div class="vocab_add_data"><h4 style="color:red";>',
429 '#suffix' => '</h4>');
430 $row = db_fetch_object(db_query("SELECT * FROM {vocab_data} WHERE id =%d", arg(3)));
431 $node->front = $row->front;
432 $node->back = $row->back;
433 $node->imageurl = $row->imageurl;
434 }
435 else{
436 $form['edit'] = array(
437 '#type' => 'fieldset',
438 '#title' => t('Add a "Vocabulary" pair to this set.'),
439 '#prefix' => '<div class="vocab_add_data"><h4 style="color:black";>',
440 '#suffix' => '</h4>');
441 }
442
443 $form['edit']['front'] = array(
444 '#type' => 'textarea',
445 '#title' => t($node->flabel),
446 '#default_value' => $node->front,
447 '#size' => 60,
448 '#maxlength' => 250,
449 '#required' => TRUE);
450
451 $form['edit']['back'] = array(
452 '#type' => 'textarea',
453 '#title' => t($node->blabel),
454 '#default_value' => $node->back,
455 '#size' => 60,
456 '#maxlength' => 250);
457
458 $form['edit']['imageurl'] = array(
459 '#type' => 'textarea',
460 '#title' => t('Explanation'),
461 '#cols' => 60,
462 '#rows' => 5,
463 '#description'=>t('Feedback for this pair.'),
464 '#default_value' => $node->imageurl);
465
466 $form['edit']['pid'] = array(
467 '#type' => 'hidden',
468 '#value' => arg(3));
469
470 $form['div_tag'] = array(
471 '#type' => 'markup',
472 '#value' => '</div>');
473
474 $form['edit']['submit'] = array(
475 '#type' => 'submit',
476 '#value' => t('Submit'));
477
478 }
479 break;
480 }
481 return $form;
482 }
483
484
485 function add_vocab_pair_validate($form_id, $form_values)
486 {
487 if ('add_vocab_pair' == $form_id)
488 {
489 if(isset($form_value['edit']))
490 {
491 if($form_values['front'] == "" || $form_values['back'] == "")
492 {
493 form_set_error('',t('Only the Image field may be left blank'));
494 }
495 }
496 }
497 }
498
499 function add_vocab_pair_submit($form_id, $form_values)
500 {
501 $nid = arg(1);
502 $pid = arg(3);
503 if(isset($nid) && $nid != 0)
504 {
505 if ( 'add_vocab_pair' == $form_id)
506 {
507 $pair = (object) array('nid'=> $nid, 'front'=>$form_values['front'], 'back'=>$form_values['back'],'imageurl'=> $form_values['imageurl']);
508
509 if(is_numeric($form_values['pid']))
510 vocab_update($pair);
511 else
512 _vocab_insert($pair);
513
514 drupal_set_message("[".$pair->front." | ". $pair->back."] added");
515 drupal_goto('vocab/'.$nid.'/add');
516 }
517 }
518 else
519 {
520 drupal_goto("node");
521 }
522 }
523
524 /******************** HELPER FUNCTIONS *****************************/
525
526 function add_vocab_pair()
527 {
528 $nid = arg(1);
529 $pid = arg(3);
530 if(isset($nid))
531 {
532 $node = node_load(array('nid' => $nid));
533 $breadcrumb[] = array('path' => 'node/'.$nid, 'title' => ($node->title));
534
535 switch(arg(2)){
536 case 'add':
537 $breadcrumb[] = array('path' => 'vocab/'. $nid.'/add', 'title' => t("add vocab pair", array()));
538 break;
539 case 'edit':
540 $breadcrumb[] = array('path' => 'vocab/'. $nid.'/edit/'.$pid, 'title' => t("edit vocab pair", array()));
541 break;
542 }
543 menu_set_location($breadcrumb);
544
545 //TODO: focus cursor in first box
546 $add_data = vocab_add_data_form($node);
547 $output = drupal_get_form('add_vocab_pair', $add_data);
548 $output .= l(t("Return to the key page"), "node/".$nid);
549
550 }
551 else
552 {
553 drupal_goto("node");
554 }
555 return $output;
556 }
557
558 function _vocab_insert($node)
559 {
560 db_query("INSERT INTO {vocab_data} (nid, front, back, imageurl) VALUES (%d, '%s', '%s', '%s')", $node->nid, $node->front, $node->back, $node->imageurl);
561 }
562
563 /**
564 * hook_insert()
565 */
566 function vocab_insert($node) {//REPLACE INTO less efficient, but solves the problem of orphaned older nodes which didn't have labels
567 db_query("REPLACE INTO {vocab_labels} (nid, flabel, blabel) VALUES (%d, '%s', '%s')", $node->nid, $node->flabel, $node->blabel);
568 }
569
570 /**
571 * hook_load
572 */
573 function vocab_load($node) {
574 return db_fetch_array(db_query("SELECT * FROM {vocab_labels} WHERE nid=%d", $node->nid));
575 }
576 function vocab_settings()
577 {
578 $form['labels']= array('#type'=>'fieldset', '#description'=>t('Vocabulary pairs display'));
579 $form['labels']['vocabset_display_number'] = array (
580 '#type'=>'textfield',
581 '#title'=>t('Default number of pairs to display'),
582 '#default_value'=>variable_get('vocabset_display_number', 10),
583 );
584 $form['#token'] = FALSE;
585 return $form;
586 }
587
588 ?>

  ViewVC Help
Powered by ViewVC 1.1.2