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

Contents of /contributions/modules/gradebook/gradebook.module

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


Revision 1.15 - (show annotations) (download) (as text)
Sat Apr 7 05:25:53 2007 UTC (2 years, 7 months ago) by rwohleb
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-5, DRUPAL-6--1
Changes since 1.14: +382 -275 lines
File MIME type: text/x-php
* Initial support for Drupal 5
* Fixed 'default' SQL bug in text/blob field for MySQL
1 <?php
2 // $Id: gradebook.module,v 1.14 2006/11/15 02:07:01 rwohleb Exp $
3
4 /**
5 * hook_perm
6 *
7 * @return array
8 */
9 function gradebook_perm() {
10 return array('admin gradebook');
11 }
12
13 /**
14 * hook_menu
15 *
16 * @return array
17 */
18 function gradebook_menu($may_cache) {
19 global $user;
20 $items = array();
21
22 $access = $user->uid; // login is required
23
24 // The $may_cache parameter is used to divide menu items into two parts. Those
25 // returned when $may_cache is true must be consistently applicable for the
26 // current user at all times; the others may change or be defined at only
27 // certain paths. Most modules will have excusively cacheable menu items.
28 if ($may_cache) {
29 $items[] = array(
30 'path' => 'gradebook',
31 'title' => t('Gradebooks'),
32 'callback' => 'gradebook_list_page',
33 'access' => user_access('access content'),
34 'type' => MENU_SUGGESTED_ITEM,
35 );
36
37 // admin menu
38 $items[] = array(
39 'path' => 'admin/gradebook/gradebook',
40 'title' => t('Gradebooks'),
41 'description' => t('Control gradebooks and change gradebook settings.'),
42 'callback' => 'gradebook_admin_list_page',
43 'access' => user_access('administer gradebook'),
44 'type' => MENU_NORMAL_ITEM,
45 );
46 $items[] = array(
47 'path' => 'admin/gradebook/gradebook/list',
48 'title' => t('List'),
49 'access' => user_access('administer gradebook'),
50 'type' => MENU_DEFAULT_LOCAL_TASK,
51 'weight' => -10,
52 );
53 $items[] = array(
54 'path' => 'admin/gradebook/gradebook/add',
55 'title' => t('Add gradebook'),
56 'callback' => 'gradebook_add_page',
57 'access' => user_access('administer gradebook'),
58 'type' => MENU_LOCAL_TASK,
59 );
60 $items[] = array(
61 'path' => 'admin/gradebook/gradebook/edit',
62 'title' => t('Edit gradebook'),
63 'callback' => 'gradebook_edit_page',
64 'access' => user_access('administer gradebook'),
65 'type' => MENU_CALLBACK,
66 );
67 $items[] = array(
68 'path' => 'admin/gradebook/gradebook/settings',
69 'title' => t('Settings'),
70 'callback' => 'drupal_get_form',
71 'callback arguments' => array('gradebook_admin_settings'),
72 'weight' => 5,
73 'access' => user_access('administer gradebook'),
74 'type' => MENU_LOCAL_TASK,
75 );
76 }
77 else {
78 if (arg(0) == 'gradebook' && is_numeric(arg(1))) {
79 $tid = arg(1);
80 $uid = (is_int(arg(2))) ? arg(2) : NULL;
81
82 $gradebook = gradebookapi_gradebook_load($tid);
83 if ($gradebook) {
84 $items[] = array(
85 'path' => 'gradebook/'.$tid,
86 'title' => $gradebook->name,
87 'callback' => 'gradebook_gradebook_page',
88 'callback arguments' => array($gradebook, $uid),
89 'access' => user_access('access content'),
90 );
91 $items[] = array(
92 'path' => 'gradebook/'.$tid.'/view',
93 'title' => t('view'),
94 'type' => MENU_DEFAULT_LOCAL_TASK,
95 'weight' => -10,
96 );
97 $items[] = array(
98 'path' => 'gradebook/'.$tid.'/catlist',
99 'title' => t('list categories'),
100 'callback' => 'gradebook_category_page',
101 'callback arguments' => array($gradebook),
102 'access' => gradebookapi_is_teacher($gradebook),
103 'type' => MENU_LOCAL_TASK,
104 'weight' => 0,
105 );
106 $items[] = array(
107 'path' => 'gradebook/'.$tid.'/catadd',
108 'title' => t('add category'),
109 'callback' => 'gradebook_category_add_page',
110 'callback arguments' => array($gradebook),
111 'access' => gradebookapi_is_teacher($gradebook),
112 'type' => MENU_LOCAL_TASK,
113 'weight' => 1,
114 );
115
116 if (arg(2) == 'catedit' && is_numeric(arg(3))) {
117 $cat_tid = arg(3);
118 $items[] = array(
119 'path' => 'gradebook/'.$tid.'/catedit/'.$cat_tid,
120 'title' => t('edit category'),
121 'callback' => 'gradebook_category_edit_page',
122 'callback arguments' => array($gradebook, $cat_tid),
123 'access' => gradebookapi_is_teacher($gradebook),
124 'type' => MENU_LOCAL_TASK,
125 'weight' => 2,
126 );
127 }
128
129 if (arg(2) == 'grade' && is_numeric(arg(3)) && is_numeric(arg(4))) {
130 $uid = arg(3);
131 $nid = arg(4);
132 $items[] = array(
133 'path' => 'gradebook/'.$tid.'/grade/'.$uid.'/'.$nid,
134 'title' => t('edit grade'),
135 'callback' => 'gradebook_grade_page',
136 'callback arguments' => array($gradebook, $uid, $nid),
137 'access' => gradebookapi_is_teacher($gradebook),
138 'type' => MENU_CALLBACK,
139 'weight' => 2,
140 );
141 }
142 }
143 }
144
145 // Add the CSS for this module
146 // We put this in !$may_cache so it's only added once per request
147 drupal_add_css(drupal_get_path('module', 'gradebook') .'/gradebook.css');
148 }
149
150 return $items;
151 }
152
153 function gradebook_admin_settings() {
154 $form = array();
155
156 drupal_set_title(t('Gradebook configuration'));
157
158 $form['sitewide'] = array(
159 '#type' => 'fieldset',
160 '#title' => t('Sitewide gradebook settings'),
161 '#weight' => -1,
162 '#collapsible' => TRUE,
163 '#collapsed' => FALSE,
164 '#description' => 'Any student and teacher roles selected here will apply to ALL gradebooks. If you are using the OG_Gradebook module, this is probably not what you want.',
165 );
166
167 $roles = user_roles();
168 unset($roles[DRUPAL_ANONYMOUS_RID]);
169
170 $sel_roles = (array) variable_get('gradebook_student_rids', array());
171 $default = array();
172 foreach ($sel_roles as $rid => $value) {
173 if ($value) {
174 $default[] = $rid;
175 }
176 }
177 $form['sitewide']['gradebook_student_rids'] = array(
178 '#type' => 'checkboxes',
179 '#title' => t('Student roles'),
180 '#default_value' => $default,
181 '#options' => $roles,
182 '#required' => TRUE,
183 );
184
185 $sel_roles = (array) variable_get('gradebook_teacher_rids', array());
186 $default = array();
187 foreach ($sel_roles as $rid => $value) {
188 if ($value) {
189 $default[] = $rid;
190 }
191 }
192 $form['sitewide']['gradebook_teacher_rids'] = array(
193 '#type' => 'checkboxes',
194 '#title' => t('Teacher roles'),
195 '#default_value' => $default,
196 '#options' => $roles,
197 '#required' => TRUE,
198 );
199
200 $form['general'] = array(
201 '#type' => 'fieldset',
202 '#title' => t('General gradebook settings'),
203 '#weight' => 0,
204 '#collapsible' => TRUE,
205 '#collapsed' => FALSE,
206 );
207
208 $form['general']['gradebook_empty_grade'] = array(
209 '#type' => 'textfield',
210 '#title' => t('Empty grade'),
211 '#default_value' => variable_get('gradebook_empty_grade', '--'),
212 '#description' => t('This the text displayed when no grade has been entered.'),
213 '#required' => TRUE,
214 );
215
216 $number = drupal_map_assoc(array(10, 25, 50, 75, 100));
217 $form['general']['gradebooks_per_page'] = array(
218 '#type' => 'select',
219 '#title' => t('Gradebooks per page'),
220 '#default_value' => variable_get('gradebooks_per_page', 25),
221 '#options' => $number,
222 '#description' => t('The default number of gradebooks displayed per page.'),
223 );
224
225 return system_settings_form($form);
226 }
227
228 /**
229 * Returns an overview list of existing gradebooks
230 */
231 function gradebook_admin_list_page() {
232 $vid = gradebookapi_get_vid();
233
234 $header = array(
235 array('data' => t('Name'), 'field' => 't.name', 'sort' => 'asc'),
236 array('data' => t('Operations')),
237 );
238
239 $sql = 'SELECT DISTINCT t.tid, t.name FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE h.parent = 0 AND t.vid = '.$vid;
240 $sql .= tablesort_sql($header, 'weight, ');
241 $result = pager_query($sql, variable_get('gradebooks_per_page', 25));
242
243 while ($term = db_fetch_object($result)) {
244 $rows[] = array('name' => l($term->name, 'gradebook/'.$term->tid), 'operations' => l(t('edit'), 'admin/gradebook/gradebook/edit/'. $term->tid));
245 }
246
247 $output .= theme('table', $header, $rows);
248 $output .= theme('pager');
249
250 return $output;
251 }
252
253 function gradebook_add_page() {
254 return drupal_get_form('gradebook_gradebook_form');
255 }
256
257 function gradebook_edit_page($tid=-1) {
258 // TODO: check to make sure gradebook tid is valid
259
260 if ($_POST['op'] == t('Delete') || $_POST['confirm']) {
261 return drupal_get_form('gradebook_confirm_gradebook_delete', $tid);
262 }
263
264 $term = taxonomy_get_term($tid);
265 return drupal_get_form('gradebook_gradebook_form', (array)$term);
266 }
267
268 function gradebook_gradebook_form($edit = array()) {
269 $form['name'] = array(
270 '#type' => 'textfield',
271 '#title' => t('Gradebook name'),
272 '#default_value' => $edit['name'],
273 '#maxlength' => 64,
274 '#description' => t('The gradebook name is used to identify related assignments/grades.'),
275 '#required' => TRUE,
276 );
277 $form['description'] = array(
278 '#type' => 'textarea',
279 '#title' => t('Description'),
280 '#default_value' => $edit['description'],
281 '#description' => t('The gradebook description can give users more information about the assignments/grades it contains.'),
282 );
283 $form['weight'] = array(
284 '#type' => 'weight',
285 '#title' => t('Weight'),
286 '#default_value' => $edit['weight'],
287 '#description' => t('When listing gradebooks, those with lighter (smaller) weights get listed before gradebooks with heavier (larger) weights. Gradebooks with equal weights are sorted alphabetically.'),
288 );
289
290 $form['vid'] = array('#type' => 'hidden', '#value' => gradebookapi_get_vid());
291 $form['submit' ] = array('#type' => 'submit', '#value' => t('Submit'));
292 if ($edit['tid']) {
293 $form['delete'] = array('#type' => 'submit', '#value' => t('Delete'));
294 $form['tid'] = array('#type' => 'hidden', '#value' => $edit['tid']);
295 }
296
297 return $form;
298 }
299
300 function gradebook_gradebook_form_submit($form_id, $form_values) {
301 $status = taxonomy_save_term($form_values);
302 switch ($status) {
303 case SAVED_NEW:
304 drupal_set_message(t('Created new gradebook %term.', array('%term' => $form_values['name'])));
305 break;
306 case SAVED_UPDATED:
307 drupal_set_message(t('The gradebook %term has been updated.', array('%term' => $form_values['name'])));
308 break;
309 }
310 return 'admin/gradebook/gradebook';
311 }
312
313 /**
314 * Returns a confirmation page for deleting a gradebook taxonomy term.
315 *
316 * @param $tid ID of the term to be deleted
317 */
318 function gradebook_confirm_gradebook_delete($tid) {
319 // TODO: make sure this is a valid gradebook term
320
321 $term = taxonomy_get_term($tid);
322
323 $form['tid'] = array('#type' => 'value', '#value' => $tid);
324 $form['name'] = array('#type' => 'value', '#value' => $term->name);
325
326 return confirm_form($form, t('Are you sure you want to delete the gradebook %name?', array('%name' => $term->name)), 'admin/gradebook/gradebook', t('Deleting a gradebook will delete all associated grades as well. This action cannot be undone.'), t('Delete'), t('Cancel'));
327 }
328
329 /**
330 * Implementation of forms api _submit call. Deletes a gradebook after confirmation.
331 */
332 function gradebook_confirm_gradebook_delete_submit($form_id, $form_values) {
333 // TODO: delete grades
334 var_dump($form_values);
335 taxonomy_del_term($form_values['tid']);
336 drupal_set_message(t('The gradebook %term and all associated grades have been deleted.', array('%term' => $form_values['name'])));
337 watchdog('content', t('gradebook: deleted %term and associated grades.', array('%term' => $form_values['name'])));
338
339 return 'admin/gradebook/gradebook';
340 }
341
342 /**
343 * Menu callback; prints a forum listing.
344 */
345 function gradebook_list_page() {
346 $vid = gradebookapi_get_vid();
347
348 $header = array(
349 array('data' => t('Name'), 'field' => 't.name', 'sort' => 'asc'),
350 );
351
352 $sql = 'SELECT DISTINCT t.tid, t.name FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE h.parent = 0 AND t.vid = '.$vid;
353 $sql .= tablesort_sql($header, 'weight, ');
354 $result = pager_query($sql, variable_get('gradebooks_per_page', 25));
355
356 while ($term = db_fetch_object($result)) {
357 $rows[] = array('name' => l($term->name, 'gradebook/'.$term->tid));
358 }
359
360 $output .= theme('table', $header, $rows);
361 $output .= theme('pager');
362
363 return $output;
364 }
365
366 function gradebook_gradebook_page($gradebook, $uid=NULL) {
367 global $user;
368 $assignments = array();
369 $student_grades = array();
370 $assignment_order = array();
371 $order = isset($_GET['order']) ? $_GET['order'] : '';
372 $sort = isset($_GET['sort']) ? (($_GET['sort'] == 'desc') ? 'desc' : 'asc') : 'asc';
373
374 // make sure we have permission to be here
375 if (!gradebookapi_is_teacher($gradebook) && $uid) {
376 if ($uid != $user->uid) {
377 drupal_access_denied();
378 return;
379 }
380 }
381
382 // if not a teacher set uid to own
383 if (!gradebookapi_is_teacher($gradebook)) {
384 $uid = $user->uid;
385 }
386
387 // get sorted assignments
388 switch ($order) {
389 case 'title':
390 $result = gradebookapi_select_nodes($gradebook, $tids, 'or', 0, FALSE, 'n.title ASC');
391 while ($assignment = db_fetch_object($result)) {
392 $assignments[] = node_load($assignment->nid);
393 }
394 break;
395 case 'date':
396 $result = gradebookapi_select_nodes($gradebook, $tids, 'or', 0, FALSE, 'n.created ASC');
397 while ($assignment = db_fetch_object($result)) {
398 $assignments[] = node_load($assignment->nid);
399 }
400 break;
401 break;
402 case 'possible':
403 $values = array();
404 $result = gradebookapi_select_nodes($gradebook, $tids, 'or', 0, FALSE, 'a.possible ASC');
405 while ($assignment = db_fetch_object($result)) {
406 $assignments[] = node_load($assignment->nid);
407 }
408 break;
409 case 'category':
410 default:
411 $result = gradebookapi_select_nodes($gradebook, $tids, 'or', 0, FALSE, 'td.name ASC');
412 while ($assignment = db_fetch_object($result)) {
413 $assignments[] = node_load($assignment->nid);
414 }
415 break;
416 }
417
418 if ($uid) {
419 $result = db_query("SELECT uid, name FROM {users} WHERE uid=%d", $uid);
420 }
421 else {
422 $students = gradebookapi_get_students($gradebook);
423 if ( $str_uids = implode(',', $students) )
424 $result = db_query("SELECT u.uid, u.name FROM {users} u WHERE u.status != 0 AND u.uid IN (". $str_uids .") ORDER BY u.name ASC");
425 else {
426 $result = FALSE;
427 }
428 }
429
430 if ($result) {
431 while ($account = db_fetch_object($result)) {
432 $student_grades[$account->uid] = array();
433 foreach ($assignments as $assignment) {
434 $student_grades[$account->uid][$assignment->nid] = gradebookapi_get_grade($account->uid, $assignment->nid);
435 }
436 $student_grades[$account->uid]['total'] = gradebookapi_get_term_grade($account->uid, $gradebook->tid);
437 }
438 }
439
440 return theme('gradebook_page', $gradebook, $assignments, $student_grades);
441 }
442
443 function theme_gradebook_page($gradebook, $assignments, $student_grades) {
444 $headers = array(
445 'category' => array(l('category', 'gradebook/'.$gradebook->tid, '', 'order=category&sort=asc')),
446 'possible' => array(l('possible', 'gradebook/'.$gradebook->tid, '', 'order=possible&sort=asc')),
447 'date' => array(l('date', 'gradebook/'.$gradebook->tid, '', 'order=date&sort=asc')),
448 'title' => array(l('title', 'gradebook/'.$gradebook->tid, '', 'order=title&sort=asc')),
449 );
450 $rows = array();
451
452 $sort = NULL;
453 if ($order = isset($_GET['order']) ? $_GET['order'] : '') {
454 $sort .= 'order=' . $order;
455 $sort .= '&sort=' . (isset($_GET['sort']) ? (($_GET['sort'] == 'desc') ? 'desc' : 'asc') : 'asc');
456 }
457
458 foreach ($assignments as $assignment) {
459 $terms = gradebookapi_assignment_terms($assignment);
460 $category = '';
461 foreach ($terms as $term) {
462 if ($term->tid != $gradebook->tid) {
463 if ($category) {
464 $category .= ', ' . $term->name;
465 }
466 else {
467 $category .= $term->name;
468 }
469 }
470 }
471 $headers['category'][] = array('data' => $category, 'class' => 'assignment_category');
472 $headers['possible'][] = array('data' => $assignment->possible, 'class' => 'assignment_possible');
473 $headers['date'][] = array('data' => format_date($assignment->created, 'custom', 'Y/m/d'), 'class' => 'assignment_date');
474 $headers['title'][] = array('data' => l($assignment->title, 'node/'.$assignment->nid), 'class' => 'assignment_title');
475 }
476
477 foreach ($student_grades as $uid => $grades) {
478 $row = array();
479
480 $account = user_load(array('uid' => $uid));
481 //$row[] = theme('username', $account);
482 $row[] = l($account->name, 'gradebook/' . $gradebook->tid . '/' . $account->uid, '', $sort);
483
484 foreach ($assignments as $assignment) {
485 $grade = $grades[$assignment->nid];
486 $row[] = theme_gradebook_assignment_grade($gradebook, $grade);
487 }
488
489 $grade = gradebookapi_get_term_grade($account->uid, $gradebook->tid);
490 $row[] = theme_gradebook_term_grade($gradebook, $grade);
491 $rows[] = $row;
492 }
493
494 return theme('gradebook_table', $headers, $rows, array('class' => 'gradebook'));
495 }
496
497 function theme_gradebook_assignment_grade($gradebook, $grade) {
498 if (isset($grade->earned)) {
499 //$results = gradebookapi_invoke_gradebookapi('view', 'grade', $grade);
500 if (count($results)) {
501 $text = array_pop($results);
502 }
503 else {
504 $text = $grade->earned;
505 }
506 }
507 else {
508 $text = variable_get('gradebook_empty_grade', '--');
509 }
510
511 $ret = array();
512 if (gradebookapi_is_teacher($gradebook) || $grade->note) {
513 $ret['data'] = l($text, 'gradebook/' . $gradebook->tid . '/grade/' . $grade->uid . '/' . $grade->nid);
514 }
515 else {
516 $ret['data'] = $text;
517 }
518 $ret['class'] = ($grade->exempt?'exempt':'');
519
520 return $ret;
521 }
522
523 function theme_gradebook_term_grade($gradebook, $grade) {
524 if (isset($grade->earned)) {
525 //$results = gradebookapi_invoke_gradebookapi('view', 'grade', $grade);
526 if (count($results)) {
527 return array_pop($results);
528 }
529 else {
530 return $grade->earned . '/' . $grade->possible . (($grade->earned && $grade->possible)?(' (' . sprintf('%.1f', ($grade->earned/$grade->possible)*100) . '%)'):'');
531 }
532 }
533 else {
534 return variable_get('gradebook_empty_grade', '--');
535 }
536 }
537
538 function _gradebook_tablesort_sql($headers, $before = '') {
539 foreach ($headers as $header) {
540 $ts = tablesort_init($header);
541 if ($ts['sql']) {
542 $sql = db_escape_string($ts['sql']);
543 $sort = drupal_strtoupper(db_escape_string($ts['sort']));
544 return " ORDER BY $before $sql $sort";
545 }
546 }
547 }
548
549 function theme_gradebook_table($headers, $rows, $attributes = array(), $caption = NULL) {
550 $output = '<table'. drupal_attributes($attributes) .">\n";
551
552 if (isset($caption)) {
553 $output .= '<caption>'. $caption ."</caption>\n";
554 }
555
556 // Format the table header:
557 if (count($headers)) {
558 $output .= ' <thead>';
559 foreach ($headers as $header) {
560 $ts = tablesort_init($header);
561 $output .= ' <tr>';
562 foreach ($header as $cell) {
563 $cell = tablesort_header($cell, $header, $ts);
564 $output .= _theme_table_cell($cell, 1);
565 }
566 $output .= ' </tr>';
567 }
568 $output .= " </thead>\n";
569 }
570
571 // Format the table rows:
572 $output .= "<tbody>\n";
573 if (count($rows)) {
574 foreach ($rows as $number => $row) {
575 $attributes = array();
576
577 // Check if we're dealing with a simple or complex row
578 if (isset($row['data'])) {
579 foreach ($row as $key => $value) {
580 if ($key == 'data') {
581 $cells = $value;
582 }
583 else {
584 $attributes[$key] = $value;
585 }
586 }
587 }
588 else {
589 $cells = $row;
590 }
591
592 // Add odd/even class
593 $class = ($number % 2 == 1) ? 'even': 'odd';
594 if (isset($attributes['class'])) {
595 $attributes['class'] .= ' '. $class;
596 }
597 else {
598 $attributes['class'] = $class;
599 }
600
601 // Build row
602 $output .= ' <tr'. drupal_attributes($attributes) .'>';
603 $i = 0;
604 foreach ($cells as $cell) {
605 $cell = tablesort_cell($cell, $header, $ts, $i++);
606 $output .= _theme_table_cell($cell, 0);
607 }
608 $output .= " </tr>\n";
609 }
610 }
611
612 $output .= "</tbody></table>\n";
613 return $output;
614 }
615
616 function gradebook_category_page($gradebook) {
617 // TODO: code borrowed from forum.module
618 // needs serious cleanup
619 $vid = gradebookapi_get_vid();
620 $destination = drupal_get_destination();
621
622 $header = array(t('Name'), t('Operations'));
623 $vocabulary = taxonomy_get_vocabulary($vid);
624
625 //drupal_set_title(check_plain($vocabulary->name));
626 $start_from = $_GET['page'] ? $_GET['page'] : 0;
627 $total_entries = 0; // total count for pager
628 $page_increment = 25; // number of tids per page
629 $displayed_count = 0; // number of tids shown
630
631 $tree = taxonomy_get_tree($vocabulary->vid, $gradebook->tid);
632 foreach ($tree as $term) {
633 $total_entries++; // we're counting all-totals, not displayed
634 if (($start_from && ($start_from * $page_increment) >= $total_entries) || ($displayed_count == $page_increment)) { continue; }
635 //$rows[] = array(str_repeat('--', $term->depth) . ' ' . l($term->name, 'gradebook/' . $gradebook->tid . "/category/edit/$term->tid"), l(t('edit'), 'gradebook/' . $gradebook->tid . "/category/edit/$term->tid", array(), $destination));
636 $rows[] = array(str_repeat('--', $term->depth) . ' ' . $term->name, l(t('edit'), 'gradebook/'.$gradebook->tid.'/catedit/'.$term->tid, array(), $destination));
637 $displayed_count++; // we're counting tids displayed
638 }
639
640 if (!$rows) {
641 $rows[] = array(array('data' => t('No categories available.'), 'colspan' => '2'));
642 }
643
644 $GLOBALS['pager_page_array'][] = $start_from; // FIXME
645 $GLOBALS['pager_total'][] = intval($total_entries / $page_increment) + 1; // FIXME
646
647 if ($total_entries >= $page_increment) {
648 $rows[] = array(array('data' => theme('pager', NULL, $page_increment), 'colspan' => '2'));
649 }
650
651 return theme('table', $header, $rows, array('id' => 'taxonomy'));
652 }
653
654 function gradebook_category_add_page($gradebook) {
655 return drupal_get_form('gradebook_category_form', $gradebook);
656 }
657
658 function gradebook_category_edit_page($gradebook, $tid=-1) {
659 // TODO: check to make sure category tid is valid
660
661 if ($_POST['op'] == t('Delete') || $_POST['confirm']) {
662 return drupal_get_form('gradebook_confirm_category_delete', $tid);
663 }
664
665 $term = taxonomy_get_term($tid);
666 return drupal_get_form('gradebook_category_form', $gradebook, (array)$term);
667 }
668
669 function gradebook_category_form($gradebook, $edit = array()) {
670 $form['name'] = array(
671 '#title' => t('Category name'),
672 '#type' => 'textfield',
673 '#default_value' => $edit['name'],
674 '#maxlength' => 64,
675 '#description' => t('The category name is used to identify related assignments.'),
676 '#required' => TRUE
677 );
678
679 $form['description'] = array(
680 '#type' => 'textarea',
681 '#title' => t('Description'),
682 '#default_value' => $edit['description'],
683 '#description' => t('The category description can give users more information about the assignments it contains.')
684 );
685 $form['parent']['#tree'] = TRUE;
686 $form['parent'][0] = _gradebook_parent_select($gradebook->tid, $edit['tid'], t('Parent'));
687 $form['weight'] = array(
688 '#type' => 'weight',
689 '#title' => t('Weight'),
690 '#default_value' => $edit['weight'],
691 '#description' => t('When listing categories, those with with light (small) weights get listed before containers with heavier (larger) weights. Categories with equal weights are sorted alphabetically.')
692 );
693
694 $form['vid'] = array('#type' => 'hidden', '#value' => gradebookapi_get_vid());
695 $form['submit' ] = array('#type' => 'submit', '#value' => t('Submit'));
696 if ($edit['tid']) {
697 $form['delete'] = array('#type' => 'submit', '#value' => t('Delete'));
698 $form['tid'] = array('#type' => 'hidden', '#value' => $edit['tid']);
699 }
700
701 return $form;
702 }
703
704 function gradebook_category_form_submit($form_id, $form_values) {
705 $status = taxonomy_save_term($form_values);
706 switch ($status) {
707 case SAVED_NEW:
708 drupal_set_message(t('Created new %type %term.', array('%term' => $form_values['name'], '%type' => t('category'))));
709 break;
710 case SAVED_UPDATED:
711 if ($form_values['parent_old'] != $form_values['parent'][0]) {
712 gradebookapi_calc_grades_all_users($form_values['parent_old']);
713 gradebookapi_calc_grades_all_users($form_values['parent'][0]);
714 }
715 drupal_set_message(t('The %type %term has been updated.', array('%term' => theme('placeholder', $form_values['name']), '%type' => t('category'))));
716 break;
717 }
718 }
719
720 function gradebook_grade_view($gradebook, $grade) {
721 $grade = (object)$grade;
722 $account = user_load(array('uid' => $grade->uid));
723 $node = node_load($grade->nid);
724
725 // TODO: cleanup grade view rendering
726 // ideally edit is in-place in gradebook using AJAX
727 $form['user'] = array(
728 '#value' => 'Student: ' . $account->name . "<br />\n",
729 );
730
731 $form['node'] = array(
732 '#value' => 'Assignment: ' . $node->title . "<br />\n",
733 );
734
735 $form['possible'] = array(
736 '#value' => 'Possible: ' . $node->possible . "<br />\n",
737 );
738
739 $form['earned'] = array(
740 '#value' => 'Earned: ' . $grade->earned . "<br />\n",
741 );
742
743 $form['exempt'] = array(
744 '#value' => 'Exempt: ' . $grade->exempt . "<br />\n",
745 );
746
747 $form['note'] = array(
748 '#value' => 'Note: ' . $grade->note . "<br />\n",
749 );
750
751 return drupal_get_form('gradebook_grade_view', $form);
752 }
753
754 function gradebook_grade_page($gradebook, $uid, $nid) {
755 $account = user_load(array('uid' => $uid));
756 $node = node_load($nid);
757 $grade = gradebookapi_get_grade($uid, $nid);
758
759 return drupal_get_form('gradebook_grade_form', $gradebook, $account, $node, (array)$grade);
760 }
761
762 function gradebook_grade_form($gradebook, $account, $node, $edit=array()) {
763 // TODO: cleanup grade form rendering
764 // ideally edit is in-place in gradebook using AJAX
765 $form['user'] = array(
766 '#value' => 'Student: ' . $account->name . "<br />\n",
767 );
768
769 $form['node'] = array(
770 '#value' => 'Assignment: ' . $node->title . "<br />\n",
771 );
772
773 $form['possible'] = array(
774 '#value' => 'Possible: ' . $node->possible . "<br />\n",
775 );
776
777 $form['earned'] = array(
778 '#title' => t('Earned'),
779 '#type' => 'textfield',
780 '#default_value' => $edit['earned'],
781 '#maxlength' => 64,
782 '#description' => t('The grade earned.'),
783 '#required' => TRUE
784 );
785
786 $form['exempt'] = array(
787 '#type' => 'checkbox',
788 '#title' => t('Exempt student from this assignment'),
789 '#default_value' => $edit['exempt'],
790 );
791
792 $form['note'] = array(
793 '#type' => 'textarea',
794 '#title' => t('Note to student'),
795 '#default_value' => $edit['note'],
796 );
797
798 $form['uid'] = array(
799 '#type' => 'hidden',
800 '#value' => $account->uid,
801 );
802 $form['nid'] = array(
803 '#type' => 'hidden',
804 '#value' => $node->nid,
805 );
806
807 $form['submit'] = array(
808 '#type' => 'submit',
809 '#value' => t('Submit'),
810 );
811
812 return $form;
813 }
814
815 function gradebook_grade_form_validate($form_id, $form_values) {
816 $account = user_load(array('uid' => $form_values['uid']));
817 $node = node_load($form_values['nid']);
818
819 if (!$account || !$node) {
820 form_set_error('earned', t('The UID/NID has an error.'));
821 }
822
823 if (is_numeric($form_values['earned']) ? intval($form_values['earned']) != $form_values['earned'] : TRUE) {
824 form_set_error('earned', t('The earned value for the assignment must be an integer.'));
825 }
826
827 $grade = (object)$form_values;
828 $grade->possible = $node->possible;
829 //gradebookapi_invoke_gradebookapi('validate', 'grade', $grade);
830 }
831
832 function gradebook_grade_form_submit($form_id, $form_values) {
833 $account = user_load(array('uid' => $form_values['uid']));
834 $node = node_load($form_values['nid']);
835
836 $grade = (object)$form_values;
837 $grade->possible = $node->possible;
838 //gradebookapi_invoke_gradebookapi('submit', 'grade', $grade);
839
840 gradebookapi_set_grade($grade);
841 drupal_set_message(t('Saved %type.', array('%type' => t('grade'))));
842
843 //return _gradebook_base_url();
844 }
845
846 function _gradebook_parent_select($root, $tid, $title) {
847 $parents = taxonomy_get_parents($tid);
848 if ($parents) {
849 $parent = array_shift($parents);
850 $parent = $parent->tid;
851 }
852 else {
853 $parent = $root;
854 }
855
856 $children = taxonomy_get_tree(gradebookapi_get_vid(), $tid);
857
858 // A term can't be the child of itself, nor of its children.
859 foreach ($children as $child) {
860 $exclude[] = $child->tid;
861 }
862 $exclude[] = $tid;
863
864 $tree = taxonomy_get_tree(gradebookapi_get_vid(), $root);
865 $options[$root] = '<'. t('root') .'>';
866 if ($tree) {
867 foreach ($tree as $term) {
868 if (!in_array($term->tid, $exclude)) {
869 $options[$term->tid] = str_repeat('--', $term->depth) . $term->name;
870 }
871 }
872 }
873
874 return array('#type' => 'select', '#title' => $title, '#default_value' => $parent, '#options' => $options, '#description' => $description, '#required' => TRUE);
875 }
876
877 function gradebook_confirm_category_delete($tid) {
878 // TODO: make sure this is a valid category term
879
880 $term = taxonomy_get_term($tid);
881
882 $form['tid'] = array('#type' => 'value', '#value' => $tid);
883 $form['name'] = array('#type' => 'value', '#value' => $term->name);
884
885 return confirm_form($form, t('Are you sure you want to delete the category %name?', array('%name' => $term->name)), 'admin/forums', t('Deleting a category will delete all categories. This action cannot be undone.'), t('Delete'), t('Cancel'));
886 }
887
888 function gradebook_confirm_category_delete_submit($form_id, $form_values) {
889 taxonomy_del_term($form_values['tid']);
890 drupal_set_message(t('The category %term and all sub-categories and associated assignments have been deleted.', array('%term' => theme('placeholder', $form_values['name']))));
891 watchdog('content', t('gradebook: deleted %term and all its sub-categories and associated posts.', array('%term' => theme('placeholder', $form_values['name']))));
892 }
893
894 function gradebook_rebuild_page($gradebook) {
895 gradebookapi_rebuild_grades($gradebook->tid);
896 drupal_goto('gradebook/' . $gradebook->tid);
897 }
898
899 /**
900 * hook_gradebookapi_students
901 *
902 * @return array
903 */
904 function gradebook_gradebookapi_students($gradebook) {
905 $students = array();
906
907 $roles = user_roles();
908 unset($roles[DRUPAL_ANONYMOUS_RID]);
909 unset($roles[DRUPAL_AUTHENTICATED_RID]);
910
911 $sel_roles = (array) variable_get('gradebook_student_rids', array());
912 foreach ($sel_roles as $rid => $value) {
913 if (!$value) {
914 unset($roles[$rid]);
915 }
916 }
917
918 if (count($roles)) {
919 if ( $str_rids = implode(',', array_keys($roles)) ) {
920 $result = db_query("SELECT u.uid FROM {users} u INNER JOIN {users_roles} r ON u.uid = r.uid WHERE u.status != 0 AND r.rid IN (". $str_rids .")");
921 while ($user = db_fetch_object($result)) {
922 $students[$user->uid] = $user->uid;
923 }
924 }
925 }
926
927 return $students;
928 }
929
930 /**
931 * hook_gradebookapi_teachers
932 *
933 * @return array
934 */
935 function gradebook_gradebookapi_teachers($gradebook) {
936 $teachers = array();
937
938 $roles = user_roles();
939 unset($roles[DRUPAL_ANONYMOUS_RID]);
940 unset($roles[DRUPAL_AUTHENTICATED_RID]);
941
942 $sel_roles = (array) variable_get('gradebook_teacher_rids', array());
943 foreach ($sel_roles as $rid => $value) {
944 if (!$value) {
945 unset($roles[$rid]);
946 }
947 }
948
949 if (count($roles)) {
950 if ( $str_rids = implode(',', array_keys($roles)) ) {
951 $result = db_query("SELECT u.uid FROM {users} u INNER JOIN {users_roles} r ON u.uid = r.uid WHERE u.status != 0 AND r.rid IN (". $str_rids .")");
952 while ($user = db_fetch_object($result)) {
953 $teachers[$user->uid] = $user->uid;
954 }
955 }
956 }
957
958 return $teachers;
959 }
960
961 /**
962 * hook_term_path from taxonomy module
963 *
964 * @param $term
965 * A term object.
966 * @return
967 * An internal Drupal path.
968 */
969 function gradebook_term_path($term) {
970 $gradebook = gradebookapi_get_tid_gradebook($term->tid);
971 return 'gradebook/' . $gradebook->tid;
972 }

  ViewVC Help
Powered by ViewVC 1.1.2