adding capabilities
[moodle.git] / course / lib.php
1 <?php  // $Id$
2    // Library of useful functions
5 if (defined('COURSE_MAX_LOG_DISPLAY')) {  // Being included again - should never happen!!
6     return;
7 }
9 define('COURSE_MAX_LOG_DISPLAY', 150);          // days
10 define('COURSE_MAX_LOGS_PER_PAGE', 1000);       // records
11 define('COURSE_LIVELOG_REFRESH', 60);           // Seconds
12 define('COURSE_MAX_RECENT_PERIOD', 172800);     // Two days, in seconds
13 define('COURSE_MAX_SUMMARIES_PER_PAGE', 10);    // courses
14 define('COURSE_MAX_COURSES_PER_DROPDOWN',1000); //  max courses in log dropdown before switching to optional
15 define('COURSE_MAX_USERS_PER_DROPDOWN',1000);   //  max users in log dropdown before switching to optional
16 define('FRONTPAGENEWS', 0);
17 define('FRONTPAGECOURSELIST',     1);
18 define('FRONTPAGECATEGORYNAMES',  2);
19 define('FRONTPAGETOPICONLY',      3);
20 define('FRONTPAGECATEGORYCOMBO',  4);
21 define('FRONTPAGECOURSELIMIT',    200);         // maximum number of courses displayed on the frontpage
22 define('EXCELROWS', 65535);
23 define('FIRSTUSEDEXCELROW', 3);
26 function print_recent_selector_form($course, $advancedfilter=0, $selecteduser=0, $selecteddate="lastlogin",
27                                     $mod="", $modid="activity/All", $modaction="", $selectedgroup="", $selectedsort="default") {
29     global $USER, $CFG;
31     $isteacher = isteacher($course->id);
32     if ($advancedfilter) {
34         // Get all the possible users
35         $users = array();
37         if ($courseusers = get_course_users($course->id, '', '', 'u.id, u.firstname, u.lastname')) {
38             foreach ($courseusers as $courseuser) {
39                 $users[$courseuser->id] = fullname($courseuser, $isteacher);
40             }
41         }
42         if ($guest = get_guest()) {
43             $users[$guest->id] = fullname($guest);
44         }
46         if (isadmin()) {
47             if ($ccc = get_records("course", "", "", "fullname")) {
48                 foreach ($ccc as $cc) {
49                     if ($cc->category) {
50                         $courses["$cc->id"] = "$cc->fullname";
51                     } else {
52                         $courses["$cc->id"] = " $cc->fullname (Site)";
53                     }
54                 }
55             }
56             asort($courses);
57         }
59         $activities = array();
61         $selectedactivity = $modid;
63     /// Casting $course->modinfo to string prevents one notice when the field is null
64         if ($modinfo = unserialize((string)$course->modinfo)) {
65             $section = 0;
66             if ($course->format == 'weeks') {  // Body
67                 $strsection = get_string("week");
68             } else {
69                 $strsection = get_string("topic");
70             }
72             $activities["activity/All"] = "All activities";
73             $activities["activity/Assignments"] =  "All assignments";
74             $activities["activity/Chats"] = "All chats";
75             $activities["activity/Forums"] = "All forums";
76             $activities["activity/Quizzes"] = "All quizzes";
77             $activities["activity/Workshops"] = "All workshops";
79             $activities["section/individual"] = "------------- Individual Activities --------------";
81             foreach ($modinfo as $mod) {
82                 if ($mod->mod == "label") {
83                     continue;
84                 }
85                 if (!$mod->visible and !has_capability('moodle/course:viewhiddenactivities',get_context_instance(CONTEXT_MODULE, $mod->cm))) {
86                     continue;
87                 }
89                 if ($mod->section > 0 and $section <> $mod->section) {
90                     $activities["section/$mod->section"] = "-------------- $strsection $mod->section --------------";
91                 }
92                 $section = $mod->section;
93                 $mod->name = strip_tags(format_string(urldecode($mod->name),true));
94                 if (strlen($mod->name) > 55) {
95                     $mod->name = substr($mod->name, 0, 50)."...";
96                 }
97                 if (!$mod->visible) {
98                     $mod->name = "(".$mod->name.")";
99                 }
100                 $activities["$mod->cm"] = $mod->name;
102                 if ($mod->cm == $modid) {
103                     $selectedactivity = "$mod->cm";
104                 }
105             }
106         }
108         $strftimedate = get_string("strftimedate");
109         $strftimedaydate = get_string("strftimedaydate");
111         asort($users);
113         // Get all the possible dates
114         // Note that we are keeping track of real (GMT) time and user time
115         // User time is only used in displays - all calcs and passing is GMT
117         $timenow = time(); // GMT
119         // What day is it now for the user, and when is midnight that day (in GMT).
120         $timemidnight = $today = usergetmidnight($timenow);
122         $dates = array();
123         $dates["$USER->lastlogin"] = get_string("lastlogin").", ".userdate($USER->lastlogin, $strftimedate);
124         $dates["$timemidnight"] = get_string("today").", ".userdate($timenow, $strftimedate);
126         if (!$course->startdate or ($course->startdate > $timenow)) {
127             $course->startdate = $course->timecreated;
128         }
130         $numdates = 1;
131         while ($timemidnight > $course->startdate and $numdates < 365) {
132             $timemidnight = $timemidnight - 86400;
133             $timenow = $timenow - 86400;
134             $dates["$timemidnight"] = userdate($timenow, $strftimedaydate);
135             $numdates++;
136         }
138         if ($selecteddate === "lastlogin") {
139             $selecteddate = $USER->lastlogin;
140         }
142         echo '<form action="recent.php" method="get">';
143         echo '<input type="hidden" name="chooserecent" value="1" />';
144         echo "<center>";
145         echo "<table>";
147         if (isadmin()) {
148             echo "<tr><td><b>" . get_string("courses") . "</b></td><td>";
149             choose_from_menu ($courses, "id", $course->id, "");
150             echo "</td></tr>";
151         } else {
152             echo '<input type="hidden" name="id" value="'.$course->id.'" />';
153         }
155         $sortfields = array("default" => get_string("bycourseorder"),"dateasc" => get_string("datemostrecentlast"), "datedesc" => get_string("datemostrecentfirst"));
157         echo "<tr><td><b>" . get_string("participants") . "</b></td><td>";
158         choose_from_menu ($users, "user", $selecteduser, get_string("allparticipants") );
159         echo "</td>";
161         echo '<td align="right"><b>' . get_string("since") . '</b></td><td>';
162         choose_from_menu ($dates, "date", $selecteddate, get_string("alldays"));
163         echo "</td></tr>";
165         echo "<tr><td><b>" . get_string("activities") . "</b></td><td>";
166         choose_from_menu ($activities, "modid", $selectedactivity, "");
167         echo "</td>";
169         echo '<td align="right"><b>' . get_string("sortby") . "</b></td><td>";
170         choose_from_menu ($sortfields, "sortby", $selectedsort, "");
171         echo "</td></tr>";
173         echo '<tr>';
175         $groupmode =  groupmode($course);
177         if ($groupmode == VISIBLEGROUPS or ($groupmode and has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id)))) {
178             if ($groups = get_records_menu("groups", "courseid", $course->id, "name ASC", "id,name")) {
179             echo '<td><b>';
180                 if ($groupmode == VISIBLEGROUPS) {
181                     print_string('groupsvisible');
182                 } else {
183                     print_string('groupsseparate');
184                 }
185                 echo ':</b></td><td>';
186                 choose_from_menu($groups, "selectedgroup", $selectedgroup, get_string("allgroups"), "", "");
187                 echo '</td>';
188             }
189         }
192         echo '<td colspan="2" align="right">';
193         echo '<input type="submit" value="'.get_string('showrecent').'" />';
194         echo "</td></tr>";
196         echo "</table>";
198         $advancedlink = "<a href=\"$CFG->wwwroot/course/recent.php?id=$course->id&amp;advancedfilter=0\">" . get_string("normalfilter") . "</a>";
199         print_heading($advancedlink);
200         echo "</center>";
201         echo "</form>";
203     } else {
205         $day_list = array("1","7","14","21","30");
206         $strsince = get_string("since");
207         $strlastlogin = get_string("lastlogin");
208         $strday = get_string("day");
209         $strdays = get_string("days");
211         $heading = "";
212         foreach ($day_list as $count)  {
213             if ($count == "1") {
214               $day = $strday;
215             } else {
216               $day = $strdays;
217             }
218             $tmpdate = time() - ($count * 3600 * 24);
219             $heading = $heading .
220                 "<a href=\"$CFG->wwwroot/course/recent.php?id=$course->id&amp;date=$tmpdate\"> $count $day</a> | ";
221         }
223         $heading = $strsince . ": <a href=\"$CFG->wwwroot/course/recent.php?id=$course->id\">$strlastlogin</a>" . " | " . $heading;
224         print_heading($heading);
226         $advancedlink = "<a href=\"$CFG->wwwroot/course/recent.php?id=$course->id&amp;advancedfilter=1\">" . get_string("advancedfilter") . "</a>";
227         print_heading($advancedlink);
229     }
234 function make_log_url($module, $url) {
235     switch ($module) {
236         case 'user':
237         case 'course':
238         case 'file':
239         case 'login':
240         case 'lib':
241         case 'admin':
242         case 'message':
243         case 'calendar':
244         case 'blog':
245             return "/$module/$url";
246             break;
247         case 'upload':
248             return $url;
249             break;
250         case 'library':
251         case '':
252             return '/';
253             break;
254         default:
255             return "/mod/$module/$url";
256             break;
257     }
261 function build_logs_array($course, $user=0, $date=0, $order="l.time ASC", $limitfrom='', $limitnum='',
262                    $modname="", $modid=0, $modaction="", $groupid=0) {
264     // It is assumed that $date is the GMT time of midnight for that day,
265     // and so the next 86400 seconds worth of logs are printed.
267     global $db;
269     /// Setup for group handling.
270     $isteacher = isteacher($course->id);
271     $isteacheredit = isteacheredit($course->id);
273     /// If the group mode is separate, and this user does not have editing privileges,
274     /// then only the user's group can be viewed.
275     if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
276         $groupid = get_current_group($course->id);
277     }
278     /// If this course doesn't have groups, no groupid can be specified.
279     else if (!$course->groupmode) {
280         $groupid = 0;
281     }
283     $joins = array();
285     if ($course->id != SITEID || $modid != 0) {
286         $joins[] = "l.course='$course->id'";
287     }
289     if ($modname) {
290         $joins[] = "l.module = '$modname'";
291     }
293     if ('site_errors' === $modid) {
294         $joins[] = "( l.action='error' OR l.action='infected' )";
295     } else if ($modid) {
296         $joins[] = "l.cmid = '$modid'";
297     }
299     if ($modaction) {
300         $firstletter = substr($modaction, 0, 1);
301         if (ctype_alpha($firstletter)) {
302             $joins[] = "lower(l.action) LIKE '%" . strtolower($modaction) . "%'";
303         } else if ($firstletter == '-') {
304             $joins[] = "lower(l.action) NOT LIKE '%" . strtolower(substr($modaction, 1)) . "%'";
305         }
306     }
308     /// Getting all members of a group.
309     if ($groupid and !$user) {
310         if ($gusers = get_records('groups_members', 'groupid', $groupid)) {
311             $first = true;
312             foreach($gusers as $guser) {
313                 if ($first) {
314                     $gselect = '(l.userid='.$guser->userid;
315                     $first = false;
316                 }
317                 else {
318                     $gselect .= ' OR l.userid='.$guser->userid;
319                 }
320             }
321             if (!$first) $gselect .= ')';
322             $joins[] = $gselect;
323         }
324     }
325     else if ($user) {
326         $joins[] = "l.userid = '$user'";
327     }
329     if ($date) {
330         $enddate = $date + 86400;
331         $joins[] = "l.time > '$date' AND l.time < '$enddate'";
332     }
334     $selector = '';
335     for ($i = 0; $i < count($joins); $i++) {
336         $selector .= $joins[$i] . (($i == count($joins)-1) ? " " : " AND ");
337     }
339     $totalcount = 0;  // Initialise
340     
341     $result = array();
342     $result['logs'] = get_logs($selector, $order, $limitfrom, $limitnum, $totalcount);
343     $result['totalcount'] = $totalcount;
344     return $result;
346     
347     
348 function print_log($course, $user=0, $date=0, $order="l.time ASC", $page=0, $perpage=100,
349                    $url="", $modname="", $modid=0, $modaction="", $groupid=0) {
350     
351     global $CFG;
352     
353     if (!$logs = build_logs_array($course, $user, $date, $order, $page*$perpage, $perpage,
354                        $modname, $modid, $modaction, $groupid)) {
355         notify("No logs found!");
356         print_footer($course);
357         exit;
358     }
359     
360     if ($course->id == SITEID) {
361         $courses[0] = '';
362         if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
363             foreach ($ccc as $cc) {
364                 $courses[$cc->id] = $cc->shortname;
365             }
366         }
367     }
368     
369     $totalcount = $logs['totalcount'];
370     $count=0;
371     $ldcache = array();
372     $tt = getdate(time());
373     $today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
375     $strftimedatetime = get_string("strftimedatetime");
376     $isteacher = isteacher($course->id);
378     echo "<p align=\"center\">\n";
379     print_string("displayingrecords", "", $totalcount);
380     echo "</p>\n";
382     print_paging_bar($totalcount, $page, $perpage, "$url&amp;perpage=$perpage&amp;");
384     echo "<table class=\"logtable\" border=\"0\" align=\"center\" cellpadding=\"3\" cellspacing=\"0\">\n";
385     echo "<tr>";
386     if ($course->id == SITEID) {
387         echo "<th class=\"c0 header\">".get_string('course')."</th>\n";
388     }
389     echo "<th class=\"c1 header\">".get_string('time')."</th>\n";
390     echo "<th class=\"c2 header\">".get_string('ip_address')."</th>\n";
391     echo "<th class=\"c3 header\">".get_string('fullname')."</th>\n";
392     echo "<th class=\"c4 header\">".get_string('action')."</th>\n";
393     echo "<th class=\"c5 header\">".get_string('info')."</th>\n";
394     echo "</tr>\n";
396     $row = 1;
397     foreach ($logs['logs'] as $log) {
399         $row = ($row + 1) % 2;
401         if (isset($ldcache[$log->module][$log->action])) {
402             $ld = $ldcache[$log->module][$log->action];
403         } else {
404             $ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
405             $ldcache[$log->module][$log->action] = $ld;
406         }
407         if ($ld && !empty($log->info)) {
408             // ugly hack to make sure fullname is shown correctly
409             if (($ld->mtable == 'user') and ($ld->field == 'CONCAT(firstname," ",lastname)')) {
410                 $log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
411             } else {
412                 $log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
413             }
414         }
416         //Filter log->info 
417         $log->info = format_string($log->info);
419         $log->url  = strip_tags(urldecode($log->url));   // Some XSS protection
420         $log->info = strip_tags(urldecode($log->info));  // Some XSS protection
421         $log->url  = str_replace('&', '&amp;', $log->url); /// XHTML compatibility
423         echo '<tr class="r'.$row.'">';
424         if ($course->id == SITEID) {
425             echo "<td class=\"r$row c0\" nowrap=\"nowrap\">\n";
426             echo "    <a href=\"{$CFG->wwwroot}/course/view.php?id={$log->course}\">".$courses[$log->course]."</a>\n";
427             echo "</td>\n";
428         }
429         echo "<td class=\"r$row c1\" nowrap=\"nowrap\" align=\"right\">".userdate($log->time, '%a').
430              ' '.userdate($log->time, $strftimedatetime)."</td>\n";
431         echo "<td class=\"r$row c2\" nowrap=\"nowrap\">\n";
432         link_to_popup_window("/iplookup/index.php?ip=$log->ip&amp;user=$log->userid", 'iplookup',$log->ip, 400, 700);
433         echo "</td>\n";
434         $fullname = fullname($log, $isteacher);
435         echo "<td class=\"r$row c3\" nowrap=\"nowrap\">\n";
436         echo "    <a href=\"$CFG->wwwroot/user/view.php?id={$log->userid}&amp;course={$log->course}\">$fullname</a>\n";
437         echo "</td>\n";
438         echo "<td class=\"r$row c4\" nowrap=\"nowrap\">\n";
439         link_to_popup_window( make_log_url($log->module,$log->url), 'fromloglive',"$log->module $log->action", 400, 600);
440         echo "</td>\n";;
441         echo "<td class=\"r$row c5\" nowrap=\"nowrap\">{$log->info}</td>\n";
442         echo "</tr>\n";
443     }
444     echo "</table>\n";
446     print_paging_bar($totalcount, $page, $perpage, "$url&amp;perpage=$perpage&amp;");
450 function print_log_csv($course, $user, $date, $order='l.time DESC', $modname,
451                         $modid, $modaction, $groupid) {
452     
453     $text = get_string('course')."\t".get_string('time')."\t".get_string('ip_address')."\t".
454             get_string('fullname')."\t".get_string('action')."\t".get_string('info');
455     
456     if (!$logs = build_logs_array($course, $user, $date, $order, '', '',
457                        $modname, $modid, $modaction, $groupid)) {
458         return false;
459     }
460     
461     if ($course->id == SITEID) {
462         $courses[0] = '';
463         if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
464             foreach ($ccc as $cc) {
465                 $courses[$cc->id] = $cc->shortname;
466             }
467         }
468     }
469     
470     $count=0;
471     $ldcache = array();
472     $tt = getdate(time());
473     $today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
475     $strftimedatetime = get_string("strftimedatetime");
476     $isteacher = isteacher($course->id);
478     $filename = 'logs_'.userdate(time(),get_string('backupnameformat'),99,false);
479     $filename .= '.txt';
480     header("Content-Type: application/download\n");   
481     header("Content-Disposition: attachment; filename=$filename");
482     header("Expires: 0");
483     header("Cache-Control: must-revalidate,post-check=0,pre-check=0");
484     header("Pragma: public");
486     echo get_string('savedat').userdate(time(), $strftimedatetime)."\n";
487     echo $text;
489     foreach ($logs['logs'] as $log) {
490         if (isset($ldcache[$log->module][$log->action])) {
491             $ld = $ldcache[$log->module][$log->action];
492         } else {
493             $ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
494             $ldcache[$log->module][$log->action] = $ld;
495         }
496         if ($ld && !empty($log->info)) {
497             // ugly hack to make sure fullname is shown correctly
498             if (($ld->mtable == 'user') and ($ld->field == 'CONCAT(firstname," ",lastname)')) {
499                 $log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
500             } else {
501                 $log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
502             }
503         }
505         //Filter log->info 
506         $log->info = format_string($log->info);
508         $log->url  = strip_tags(urldecode($log->url));     // Some XSS protection
509         $log->info = strip_tags(urldecode($log->info));    // Some XSS protection
510         $log->url  = str_replace('&', '&amp;', $log->url); // XHTML compatibility
512         $firstField = $courses[$log->course];
513         $fullname = fullname($log, $isteacher);
514         $row = array($firstField, userdate($log->time, $strftimedatetime), $log->ip, $fullname, $log->module.' '.$log->action, $log->info);
515         $text = implode("\t", $row);
516         echo $text." \n";
517     }
518     return true;
522 function print_log_xls($course, $user, $date, $order='l.time DESC', $modname,
523                         $modid, $modaction, $groupid) {
524     
525     global $CFG;
527     require_once("$CFG->libdir/excellib.class.php");
528     
529     if (!$logs = build_logs_array($course, $user, $date, $order, '', '',
530                        $modname, $modid, $modaction, $groupid)) {
531         return false;
532     }
533     
534     if ($course->id == SITEID) {
535         $courses[0] = '';
536         if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
537             foreach ($ccc as $cc) {
538                 $courses[$cc->id] = $cc->shortname;
539             }
540         }
541     }
542     
543     $count=0;
544     $ldcache = array();
545     $tt = getdate(time());
546     $today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
548     $strftimedatetime = get_string("strftimedatetime");
549     $isteacher = isteacher($course->id);
551     $nroPages = ceil(count($logs)/(EXCELROWS-FIRSTUSEDEXCELROW+1));
552     $filename = 'logs_'.userdate(time(),get_string('backupnameformat'),99,false);
553     $filename .= '.xls';
554     
555     $workbook = new MoodleExcelWorkbook('-');
556     $workbook->send($filename);
557     
558     $worksheet = array();
559     $headers = array(get_string('course'), get_string('time'), get_string('ip_address'),
560                         get_string('fullname'),    get_string('action'), get_string('info'));
561     
562     // Creating worksheets
563     for ($wsnumber = 1; $wsnumber <= $nroPages; $wsnumber++) {
564         $sheettitle = get_string('excel_sheettitle', 'logs', $wsnumber).$nroPages;
565         $worksheet[$wsnumber] =& $workbook->add_worksheet($sheettitle);
566         $worksheet[$wsnumber]->set_column(1, 1, 30);
567         $worksheet[$wsnumber]->write_string(0, 0, get_string('savedat').
568                                     userdate(time(), $strftimedatetime));
569         $col = 0;
570         foreach ($headers as $item) {
571             $worksheet[$wsnumber]->write(FIRSTUSEDEXCELROW-1,$col,$item,'');
572             $col++;
573         }
574     }
576     $formatDate =& $workbook->add_format();
577     $formatDate->set_num_format(get_string('log_excel_date_format'));
579     $row = FIRSTUSEDEXCELROW;
580     $wsnumber = 1;
581     $myxls =& $worksheet[$wsnumber];
582     foreach ($logs['logs'] as $log) {
583         if (isset($ldcache[$log->module][$log->action])) {
584             $ld = $ldcache[$log->module][$log->action];
585         } else {
586             $ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
587             $ldcache[$log->module][$log->action] = $ld;
588         }
589         if ($ld && !empty($log->info)) {
590             // ugly hack to make sure fullname is shown correctly
591             if (($ld->mtable == 'user') and ($ld->field == 'CONCAT(firstname," ",lastname)')) {
592                 $log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
593             } else {
594                 $log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
595             }
596         }
598         // Filter log->info
599         $log->info = format_string($log->info);
600         $log->info = strip_tags(urldecode($log->info));  // Some XSS protection
602         if ($nroPages>1) {
603             if ($row > EXCELROWS) {
604                 $wsnumber++;
605                 $myxls =& $worksheet[$wsnumber];
606                 $row = FIRSTUSEDEXCELROW;
607             }
608         }
609         
610         $myxls->write($row, 0, $courses[$log->course], '');
611         // Excel counts from 1/1/1900
612         $excelTime=25569+$log->time/(3600*24);
613         $myxls->write($row, 1, $excelTime, $formatDate);
614         $myxls->write($row, 2, $log->ip, '');
615         $fullname = fullname($log, $isteacher);
616         $myxls->write($row, 3, $fullname, '');
617         $myxls->write($row, 4, $log->module.' '.$log->action, '');
618         $myxls->write($row, 5, $log->info, '');
619     
620         $row++;
621     }
623     $workbook->close();
624     return true;
627 /*
628 // Relies on $CFG->libdir.'/phpdocwriter/lib/include.php', which is not
629 // included in the default Moodle distribution.
631 function print_log_ooo($course, $user, $date, $order='l.time DESC', $modname,
632                         $modid, $modaction, $groupid) {
633     
634     global $CFG;
635     require_once($CFG->libdir.'/phpdocwriter/lib/include.php');
636     
637     if (!$logs = build_logs_array($course, $user, $date, $order, '', '',
638                        $modname, $modid, $modaction, $groupid)) {
639         return false;
640     }
641     
642     if ($course->id == SITEID) {
643         $courses[0] = '';
644         if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
645             foreach ($ccc as $cc) {
646                 $courses[$cc->id] = $cc->shortname;
647             }
648         }
649     }
650     
651     $count=0;
652     $ldcache = array();
653     $tt = getdate(time());
654     $today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
656     $strftimedatetime = get_string("strftimedatetime");
657     $isteacher = isteacher($course->id);
659     $filename = 'logs_'.userdate(time(),get_string('backupnameformat'),99,false);
660     $filename .= '.sxw';
661     import('phpdocwriter.pdw_document');
662     header("Content-Type: application/download\n");
663     header("Content-Disposition: attachment; filename=$filename");
664     header("Expires: 0");
665     header("Cache-Control: must-revalidate,post-check=0,pre-check=0");
666     header("Pragma: public");
667     header("Content-Transfer-Encoding: binary");
669     $sxw = new pdw_document;
670     $sxw->SetFileName($filename);
671     $sxw->SetAuthor('Moodle');
672     $sxw->SetTitle('logs');
673     $sxw->SetDescription('logs'.' - '.$filename);
674     $sxw->SetLanguage('es','ES');
675     $sxw->SetStdFont("Times New Roman",12);
676     $sxw->AddPageDef(array('name'=>'Standard', 'margins'=>'1,1,1,1', 'w'=>'29.7', 'h'=>'21'));
677     $sxw->Write(get_string('savedat').userdate(time(), $strftimedatetime));
678     $sxw->Ln(3);
679     
680     $headers = array(get_string('course'), get_string('time'), get_string('ip_address'),
681                         get_string('fullname'),    get_string('action'), get_string('info'));
682     
683     foreach($headers as $key=>$header){
684         $headers[$key] = eregi_replace ("<br?>", " ",$header);
685     }
687     foreach ($logs['logs'] as $log) {
688         if (isset($ldcache[$log->module][$log->action])) {
689             $ld = $ldcache[$log->module][$log->action];
690         } else {
691             $ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
692             $ldcache[$log->module][$log->action] = $ld;
693         }
694         if ($ld && !empty($log->info)) {
695             // ugly hack to make sure fullname is shown correctly
696             if (($ld->mtable == 'user') and ($ld->field == 'CONCAT(firstname," ",lastname)')) {
697                 $log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
698             } else {
699                 $log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
700             }
701         }
703         // Filter log->info 
704         $log->info = format_string($log->info);
706         $log->url  = strip_tags(urldecode($log->url));     // Some XSS protection
707         $log->info = strip_tags(urldecode($log->info));    // Some XSS protection
708         $log->url  = str_replace('&', '&amp;', $log->url); // XHTML compatibility
710         $firstField = $courses[$log->course];
711         $fullname = fullname($log, $isteacher);
712         $row = array($firstField, userdate($log->time, $strftimedatetime), $log->ip, $fullname, $log->module.' '.$log->action, $log->info);
714         $data[] = $row;
715     }
716     $sxw->Table($headers,$data);
717     $sxw->Output();
718     
719     return true;
721 */
723 function print_log_graph($course, $userid=0, $type="course.png", $date=0) {
724     global $CFG;
725     if (empty($CFG->gdversion)) {
726         echo "(".get_string("gdneed").")";
727     } else {
728         echo '<img src="'.$CFG->wwwroot.'/course/report/log/graph.php?id='.$course->id.
729              '&amp;user='.$userid.'&amp;type='.$type.'&amp;date='.$date.'" alt="" />';
730     }
734 function print_overview($courses) {
736     global $CFG, $USER;
738     $htmlarray = array();
739     if ($modules = get_records('modules')) {
740         foreach ($modules as $mod) {
741             if (file_exists(dirname(dirname(__FILE__)).'/mod/'.$mod->name.'/lib.php')) {
742                 require_once(dirname(dirname(__FILE__)).'/mod/'.$mod->name.'/lib.php');
743                 $fname = $mod->name.'_print_overview';
744                 if (function_exists($fname)) {
745                     $fname($courses,$htmlarray);
746                 }
747             }
748         }
749     }
750     foreach ($courses as $course) {
751         print_simple_box_start('center', '100%', '', 5, "coursebox");
752         $linkcss = '';
753         if (empty($course->visible)) {
754             $linkcss = 'class="dimmed"';
755         }
756         print_heading('<a title="'.$course->fullname.'" '.$linkcss.' href="'.$CFG->wwwroot.'/course/view.php?id='.$course->id.'">'.$course->fullname.'</a>');
757         if (array_key_exists($course->id,$htmlarray)) {
758             foreach ($htmlarray[$course->id] as $modname => $html) {
759                 echo $html;
760             }
761         }
762         print_simple_box_end();
763     }
767 function print_recent_activity($course) {
768     // $course is an object
769     // This function trawls through the logs looking for
770     // anything new since the user's last login
772     global $CFG, $USER, $SESSION;
774     $isteacher = isteacher($course->id);
776     $timestart = time() - COURSE_MAX_RECENT_PERIOD;
778     if (!empty($USER->timeaccess[$course->id])) {
779         if ($USER->timeaccess[$course->id] > $timestart) {
780             $timestart = $USER->timeaccess[$course->id];
781         }
782     }
784     echo '<div class="activitydate">';
785     echo get_string('activitysince', '', userdate($timestart));
786     echo '</div>';
787     echo '<div class="activityhead">';
789     echo '<a href="'.$CFG->wwwroot.'/course/recent.php?id='.$course->id.'">'.get_string('recentactivityreport').'</a>';
791     echo "</div>\n";
794     // Firstly, have there been any new enrolments?
796     $heading = false;
797     $content = false;
799     $users = get_recent_enrolments($course->id, $timestart);
801     //Accessibility: new users now appear in an <OL> list.
802     if ($users) {
803         echo '<div class="newusers">';
804         if (! $heading) {
805             print_headline(get_string("newusers").':', 3);      
806             $heading = true;
807             $content = true;
808         }
809         echo "<ol class=\"list\">\n";
810         foreach ($users as $user) {
811             
812             $fullname = fullname($user, $isteacher);
813             echo '<li class="name"><a href="'.$CFG->wwwroot."/user/view.php?id=$user->id&amp;course=$course->id\">$fullname</a></li>\n";
814         }
815         echo "</ol>\n</div>\n";
816     }
818     // Next, have there been any modifications to the course structure?
820     $logs = get_records_select('log', "time > '$timestart' AND course = '$course->id' AND
821                                        module = 'course' AND action LIKE '% mod'", "time ASC");
823     if ($logs) {
824         foreach ($logs as $key => $log) {
825             $info = split(' ', $log->info);
827             if ($info[0] == 'label') {     // Labels are special activities
828                 continue;
829             }
831             $modname = get_field($info[0], 'name', 'id', $info[1]);
832             //Create a temp valid module structure (course,id)
833             $tempmod->course = $log->course;
834             $tempmod->id = $info[1];
835             //Obtain the visible property from the instance
836             $modvisible = instance_is_visible($info[0],$tempmod);
838             //Only if the mod is visible
839             if ($modvisible) {
840                 switch ($log->action) {
841                     case 'add mod':
842                         $stradded = get_string('added', 'moodle', get_string('modulename', $info[0]));
843                         $changelist[$log->info] = array ('operation' => 'add', 'text' => "$stradded:<br /><a href=\"$CFG->wwwroot/course/$log->url\">".format_string($modname,true)."</a>");
844                     break;
845                     case 'update mod':
846                        $strupdated = get_string('updated', 'moodle', get_string('modulename', $info[0]));
847                        if (empty($changelist[$log->info])) {
848                            $changelist[$log->info] = array ('operation' => 'update', 'text' => "$strupdated:<br /><a href=\"$CFG->wwwroot/course/$log->url\">".format_string($modname,true)."</a>");
849                        }
850                     break;
851                     case 'delete mod':
852                        if (!empty($changelist[$log->info]['operation']) and
853                                   $changelist[$log->info]['operation'] == 'add') {
854                            $changelist[$log->info] = NULL;
855                        } else {
856                            $strdeleted = get_string('deletedactivity', 'moodle', get_string('modulename', $info[0]));
857                            $changelist[$log->info] = array ('operation' => 'delete', 'text' => $strdeleted);
858                        }
859                     break;
860                 }
861             }
862         }
863     }
865     if (!empty($changelist)) {
866         foreach ($changelist as $changeinfo => $change) {
867             if ($change) {
868                 $changes[$changeinfo] = $change;
869             }
870         }
871         if (isset($changes)){
872             if (count($changes) > 0) {
873                 print_headline(get_string('courseupdates').':', 3);
874                 $content = true;
875                 foreach ($changes as $changeinfo => $change) {
876                     echo '<p class="activity">'.$change['text'].'</p>';
877                 }
878             }
879         }
880     }
882     // Now display new things from each module
884     $mods = get_records('modules', 'visible', '1', 'name', 'id, name');
886     foreach ($mods as $mod) {      // Each module gets it's own logs and prints them
887         include_once($CFG->dirroot.'/mod/'.$mod->name.'/lib.php');
888         $print_recent_activity = $mod->name.'_print_recent_activity';
889         if (function_exists($print_recent_activity)) {
890             $modcontent = $print_recent_activity($course, $isteacher, $timestart);
891             if ($modcontent) {
892                 $content = true;
893             }
894         }
895     }
897     if (! $content) {
898         echo '<p class="message">'.get_string('nothingnew').'</p>';
899     }
903 function get_array_of_activities($courseid) {
904 // For a given course, returns an array of course activity objects
905 // Each item in the array contains he following properties:
906 //  cm - course module id
907 //  mod - name of the module (eg forum)
908 //  section - the number of the section (eg week or topic)
909 //  name - the name of the instance
910 //  visible - is the instance visible or not
911 //  extra - contains extra string to include in any link
913     global $CFG;
915     $mod = array();
917     if (!$rawmods = get_course_mods($courseid)) {
918         return NULL;
919     }
921     if ($sections = get_records("course_sections", "course", $courseid, "section ASC")) {
922        foreach ($sections as $section) {
923            if (!empty($section->sequence)) {
924                $sequence = explode(",", $section->sequence);
925                foreach ($sequence as $seq) {
926                    if (empty($rawmods[$seq])) {
927                        continue;
928                    }
929                    $mod[$seq]->cm = $rawmods[$seq]->id;
930                    $mod[$seq]->mod = $rawmods[$seq]->modname;
931                    $mod[$seq]->section = $section->section;
932                    $mod[$seq]->name = urlencode(get_field($rawmods[$seq]->modname, "name", "id", $rawmods[$seq]->instance));
933                    $mod[$seq]->visible = $rawmods[$seq]->visible;
934                    $mod[$seq]->extra = "";
936                    $modname = $mod[$seq]->mod;
937                    $functionname = $modname."_get_coursemodule_info";
939                    include_once("$CFG->dirroot/mod/$modname/lib.php");
941                    if (function_exists($functionname)) {
942                        if ($info = $functionname($rawmods[$seq])) {
943                            if (!empty($info->extra)) {
944                                $mod[$seq]->extra = $info->extra;
945                            }
946                            if (!empty($info->icon)) {
947                                $mod[$seq]->icon = $info->icon;
948                            }
949                        }
950                    }
951                }
952             }
953         }
954     }
955     return $mod;
961 function get_all_mods($courseid, &$mods, &$modnames, &$modnamesplural, &$modnamesused) {
962 // Returns a number of useful structures for course displays
964     $mods          = NULL;    // course modules indexed by id
965     $modnames      = NULL;    // all course module names (except resource!)
966     $modnamesplural= NULL;    // all course module names (plural form)
967     $modnamesused  = NULL;    // course module names used
969     if ($allmods = get_records("modules")) {
970         foreach ($allmods as $mod) {
971             if ($mod->visible) {
972                 $modnames[$mod->name] = get_string("modulename", "$mod->name");
973                 $modnamesplural[$mod->name] = get_string("modulenameplural", "$mod->name");
974             }
975         }
976         asort($modnames);
977     } else {
978         error("No modules are installed!");
979     }
981     if ($rawmods = get_course_mods($courseid)) {
982         foreach($rawmods as $mod) {    // Index the mods
983             if (empty($modnames[$mod->modname])) {
984                 continue;
985             }
986             $mods[$mod->id] = $mod;
987             $mods[$mod->id]->modfullname = $modnames[$mod->modname];
988             if ($mod->visible or has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_COURSE, $courseid))) {
989                 $modnamesused[$mod->modname] = $modnames[$mod->modname];
990             }
991         }
992         if ($modnamesused) {
993             asort($modnamesused);
994         }
995     }
997     unset($modnames['resource']);
998     unset($modnames['label']);
1002 function get_all_sections($courseid) {
1004     return get_records("course_sections", "course", "$courseid", "section",
1005                        "section, id, course, summary, sequence, visible");
1008 function course_set_display($courseid, $display=0) {
1009     global $USER;
1011     if (empty($USER->id)) {
1012         return false;
1013     }
1015     if ($display == "all" or empty($display)) {
1016         $display = 0;
1017     }
1019     if (record_exists("course_display", "userid", $USER->id, "course", $courseid)) {
1020         set_field("course_display", "display", $display, "userid", $USER->id, "course", $courseid);
1021     } else {
1022         $record->userid = $USER->id;
1023         $record->course = $courseid;
1024         $record->display = $display;
1025         if (!insert_record("course_display", $record)) {
1026             notify("Could not save your course display!");
1027         }
1028     }
1030     return $USER->display[$courseid] = $display;  // Note: = not ==
1033 function set_section_visible($courseid, $sectionnumber, $visibility) {
1034 /// For a given course section, markes it visible or hidden,
1035 /// and does the same for every activity in that section
1037     if ($section = get_record("course_sections", "course", $courseid, "section", $sectionnumber)) {
1038         set_field("course_sections", "visible", "$visibility", "id", $section->id);
1039         if (!empty($section->sequence)) {
1040             $modules = explode(",", $section->sequence);
1041             foreach ($modules as $moduleid) {
1042                 set_coursemodule_visible($moduleid, $visibility, true);
1043             }
1044         }
1045         rebuild_course_cache($courseid);
1046     }
1050 function print_section($course, $section, $mods, $modnamesused, $absolute=false, $width="100%") {
1051 /// Prints a section full of activity modules
1052     global $CFG, $USER;
1054     static $groupbuttons;
1055     static $groupbuttonslink;
1056     static $isteacher;
1057     static $isediting;
1058     static $ismoving;
1059     static $strmovehere;
1060     static $strmovefull;
1061     static $strunreadpostsone;
1063     static $untracked;
1064     static $usetracking;
1066     $labelformatoptions = New stdClass;
1068     if (!isset($isteacher)) {
1069         $groupbuttons     = ($course->groupmode or (!$course->groupmodeforce));
1070         $groupbuttonslink = (!$course->groupmodeforce);
1071         $isteacher = isteacher($course->id);
1072         $isediting = isediting($course->id);
1073         $ismoving = $isediting && ismoving($course->id);
1074         if ($ismoving) {
1075             $strmovehere = get_string("movehere");
1076             $strmovefull = strip_tags(get_string("movefull", "", "'$USER->activitycopyname'"));
1077         }
1078         include_once($CFG->dirroot.'/mod/forum/lib.php');
1079         if ($usetracking = forum_tp_can_track_forums()) {
1080             $strunreadpostsone    = get_string('unreadpostsone', 'forum');
1081             $untracked = forum_tp_get_untracked_forums($USER->id, $course->id);
1082         }
1083     }
1084     $labelformatoptions->noclean = true;
1086 /// Casting $course->modinfo to string prevents one notice when the field is null
1087     $modinfo = unserialize((string)$course->modinfo);
1089     //Acccessibility: replace table with list <ul>, but don't output empty list.
1090     if (!empty($section->sequence)) {
1092         // Fix bug #5027, don't want style=\"width:$width\".
1093         echo "<ul class=\"section\">\n";
1094         $sectionmods = explode(",", $section->sequence);
1096         foreach ($sectionmods as $modnumber) {
1097             if (empty($mods[$modnumber])) {
1098                 continue;
1099             }
1100             $mod = $mods[$modnumber];
1102             if ($mod->visible or has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_COURSE, $course->id))) {
1103                 echo '<li class="activity '.$mod->modname.'" id="module-'.$modnumber.'">';  // Unique ID
1104                 if ($ismoving) {
1105                     if ($mod->id == $USER->activitycopy) {
1106                         continue;
1107                     }
1108                     echo '<a title="'.$strmovefull.'"'.
1109                          ' href="'.$CFG->wwwroot.'/course/mod.php?moveto='.$mod->id.'&amp;sesskey='.$USER->sesskey.'">'.
1110                          '<img class="movetarget" src="'.$CFG->pixpath.'/movehere.gif" '.
1111                          ' alt="'.$strmovehere.'" /></a><br />
1112                          ';
1113                 }
1114                 $instancename = urldecode($modinfo[$modnumber]->name);
1115                 $instancename = format_string($instancename, true,  $course->id);
1117                 if (!empty($modinfo[$modnumber]->extra)) {
1118                     $extra = urldecode($modinfo[$modnumber]->extra);
1119                 } else {
1120                     $extra = "";
1121                 }
1123                 if (!empty($modinfo[$modnumber]->icon)) {
1124                     $icon = "$CFG->pixpath/".urldecode($modinfo[$modnumber]->icon);
1125                 } else {
1126                     $icon = "$CFG->modpixpath/$mod->modname/icon.gif";
1127                 }
1129                 if ($mod->indent) {
1130                     print_spacer(12, 20 * $mod->indent, false);
1131                 }
1133                 if ($mod->modname == "label") {
1134                     if (!$mod->visible) {
1135                         echo "<span class=\"dimmed_text\">";
1136                     }
1137                     echo format_text($extra, FORMAT_HTML, $labelformatoptions);
1138                     if (!$mod->visible) {
1139                         echo "</span>";
1140                     }
1142                 } else { // Normal activity
1143                     $linkcss = $mod->visible ? "" : " class=\"dimmed\" ";
1144                     echo '<img src="'.$icon.'"'.
1145                          ' class="activityicon" alt="'.$mod->modfullname.'" />'.
1146                          ' <a title="'.$mod->modfullname.'" '.$linkcss.' '.$extra.
1147                          ' href="'.$CFG->wwwroot.'/mod/'.$mod->modname.'/view.php?id='.$mod->id.'">'.
1148                          $instancename.'</a>';
1149                 }
1150                 if ($usetracking && $mod->modname == 'forum') {
1151                     $groupmode = groupmode($course, $mod);
1152                     $groupid = ($groupmode == SEPARATEGROUPS && !has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) ?
1153                                get_current_group($course->id) : false;
1155                     if (forum_tp_can_track_forums() && !isset($untracked[$mod->instance])) {
1156                         $unread = forum_tp_count_forum_unread_posts($USER->id, $mod->instance, $groupid);
1157                         if ($unread) {
1158                             echo '<span class="unread"> <a href="'.$CFG->wwwroot.'/mod/forum/view.php?id='.$mod->id.'">';
1159                             if ($unread == 1) {
1160                                 echo $strunreadpostsone;
1161                             } else {
1162                                 print_string('unreadpostsnumber', 'forum', $unread);
1163                             }
1164                             echo '</a> </span>';
1165                         }
1166                     }
1167                 }
1169                 if ($isediting) {
1170                     if ($groupbuttons and $mod->modname != 'label' and $mod->modname != 'resource') {
1171                         if (! $mod->groupmodelink = $groupbuttonslink) {
1172                             $mod->groupmode = $course->groupmode;
1173                         }
1175                     } else {
1176                         $mod->groupmode = false;
1177                     }
1178                     echo '&nbsp;&nbsp;';
1179                     echo make_editing_buttons($mod, $absolute, true, $mod->indent, $section->section);
1180                 }
1181                 echo "</li>\n";
1182             }
1183         }
1184     } elseif ($ismoving) {
1185         echo "<ul class=\"section\">\n";
1186     }    
1187     if ($ismoving) {
1188         echo '<li><a title="'.$strmovefull.'"'.
1189              ' href="'.$CFG->wwwroot.'/course/mod.php?movetosection='.$section->id.'&amp;sesskey='.$USER->sesskey.'">'.
1190              '<img class="movetarget" src="'.$CFG->pixpath.'/movehere.gif" '.
1191              ' alt="'.$strmovehere.'" /></a></li>
1192              ';
1193     }
1194     if (!empty($section->sequence) || $ismoving) {
1195         echo "</ul><!--class='section'-->\n\n";
1196     }
1200 function print_section_add_menus($course, $section, $modnames, $vertical=false, $return=false) {
1201 // Prints the menus to add activities and resources
1203     global $CFG, $USER;
1204     static $straddactivity, $stractivities, $straddresource, $resources;
1206     if (!isset($straddactivity)) {
1207         $straddactivity = get_string('addactivity');
1208         $straddresource = get_string('addresource');
1210         /// Standard resource types
1211         require_once("$CFG->dirroot/mod/resource/lib.php");
1212         $resourceraw = resource_get_resource_types();
1214         foreach ($resourceraw as $type => $name) {
1215             $resources["resource&amp;type=$type"] = $name;
1216         }
1217         if (course_allowed_module($course,'label')) {
1218             $resources['label'] = get_string('resourcetypelabel', 'resource');
1219         }
1220     }
1222     $output  = '<div style="text-align: right">';
1223     if (course_allowed_module($course,'resource')) {
1224         $resourceallowed = true;
1225         $output .= popup_form("$CFG->wwwroot/course/mod.php?id=$course->id&amp;section=$section&amp;sesskey=$USER->sesskey&amp;add=",
1226                               $resources, "ressection$section", "", $straddresource, 'resource/types', $straddresource, true);
1227     }
1229     if ($vertical) {
1230         $output .= '<div>';
1231     }
1233     // we need to loop through the forms and check to see if we can add them.
1234     foreach ($modnames as $key=>$value) {
1235         if (!course_allowed_module($course,$key))
1236             unset($modnames[$key]);
1237     }
1238     
1239     // this is stupid but labels get put into resource, so if resource is hidden and label is not, we're in trouble.
1240     if (course_allowed_module($course,'label') && empty($resourceallowed)) {
1241         $modnames['label'] = get_string('modulename', 'label');
1242     }
1244     $output .= ' ';
1245     $output .= popup_form("$CFG->wwwroot/course/mod.php?id=$course->id&amp;section=$section&amp;sesskey=$USER->sesskey&amp;add=",
1246                 $modnames, "section$section", "", $straddactivity, 'mods', $straddactivity, true);
1248     if ($vertical) {
1249         $output .= '</div>';
1250     }
1252     $output .= '</div>';
1254     if ($return) {
1255         return $output;
1256     } else {
1257         echo $output;
1258     }
1261 function rebuild_course_cache($courseid=0) {
1262 // Rebuilds the cached list of course activities stored in the database
1263 // If a courseid is not specified, then all are rebuilt
1265     if ($courseid) {
1266         $select = "id = '$courseid'";
1267     } else {
1268         $select = "";
1269     }
1271     if ($courses = get_records_select("course", $select,'','id,fullname')) {
1272         foreach ($courses as $course) {
1273             $modinfo = serialize(get_array_of_activities($course->id));
1274             if (!set_field("course", "modinfo", $modinfo, "id", $course->id)) {
1275                 notify("Could not cache module information for course '$course->fullname'!");
1276             }
1277         }
1278     }
1283 function make_categories_list(&$list, &$parents, $category=NULL, $path="") {
1284 /// Given an empty array, this function recursively travels the
1285 /// categories, building up a nice list for display.  It also makes
1286 /// an array that list all the parents for each category.
1288     // initialize the arrays if needed
1289     if (!is_array($list)) {
1290         $list = array(); 
1291     }
1292     if (!is_array($parents)) {
1293         $parents = array(); 
1294     }
1296     if ($category) {
1297         if ($path) {
1298             $path = $path.' / '.$category->name;
1299         } else {
1300             $path = $category->name;
1301         }
1302         $list[$category->id] = $path;
1303     } else {
1304         $category->id = 0;
1305     }
1307     if ($categories = get_categories($category->id)) {   // Print all the children recursively
1308         foreach ($categories as $cat) {
1309             if (!empty($category->id)) {
1310                 if (isset($parents[$category->id])) {
1311                     $parents[$cat->id]   = $parents[$category->id];
1312                 }
1313                 $parents[$cat->id][] = $category->id;
1314             }
1315             make_categories_list($list, $parents, $cat, $path);
1316         }
1317     }
1321 function print_whole_category_list($category=NULL, $displaylist=NULL, $parentslist=NULL, $depth=-1, $files = true) {
1322 /// Recursive function to print out all the categories in a nice format
1323 /// with or without courses included
1324     global $CFG;
1326     if (isset($CFG->max_category_depth) && ($depth >= $CFG->max_category_depth)) {
1327         return;
1328     }
1330     if (!$displaylist) {
1331         make_categories_list($displaylist, $parentslist);
1332     }
1334     if ($category) {
1335         if ($category->visible or has_capability('moodle/course:update', get_context_instance(CONTEXT_SYSTEM, SITEID))) {
1336             print_category_info($category, $depth, $files);
1337         } else {
1338             return;  // Don't bother printing children of invisible categories
1339         }
1341     } else {
1342         $category->id = "0";
1343     }
1345     if ($categories = get_categories($category->id)) {   // Print all the children recursively
1346         $countcats = count($categories);
1347         $count = 0;
1348         $first = true;
1349         $last = false;
1350         foreach ($categories as $cat) {
1351             $count++;
1352             if ($count == $countcats) {
1353                 $last = true;
1354             }
1355             $up = $first ? false : true;
1356             $down = $last ? false : true;
1357             $first = false;
1359             print_whole_category_list($cat, $displaylist, $parentslist, $depth + 1, $files);
1360         }
1361     }
1364 // this function will return $options array for choose_from_menu, with whitespace to denote nesting.
1366 function make_categories_options() {
1367     make_categories_list($cats,$parents);
1368     foreach ($cats as $key => $value) {
1369         if (array_key_exists($key,$parents)) {
1370             if ($indent = count($parents[$key])) {
1371                 for ($i = 0; $i < $indent; $i++) {
1372                     $cats[$key] = '&nbsp;'.$cats[$key];
1373                 }
1374             }
1375         }
1376     }
1377     return $cats;
1380 function print_category_info($category, $depth, $files = false) {
1381 /// Prints the category info in indented fashion
1382 /// This function is only used by print_whole_category_list() above
1384     global $CFG;
1385     static $strallowguests, $strrequireskey, $strsummary;
1387     if (empty($strsummary)) {
1388         $strallowguests = get_string('allowguests');
1389         $strrequireskey = get_string('requireskey');
1390         $strsummary = get_string('summary');
1391     }
1393     $catlinkcss = $category->visible ? '' : ' class="dimmed" ';
1395     $coursecount = count_records('course') <= FRONTPAGECOURSELIMIT;
1396     if ($files and $coursecount) {
1397         $catimage = '<img src="'.$CFG->pixpath.'/i/course.gif" width="16" height="16" border="0" alt="" />';
1398     } else {
1399         $catimage = "&nbsp;";
1400     }
1402     echo "\n\n".'<table border="0" cellpadding="3" cellspacing="0" width="100%">';
1404     if ($files and $coursecount) {
1405         $courses = get_courses($category->id, 'c.sortorder ASC', 'c.id,c.sortorder,c.visible,c.fullname,c.shortname,c.password,c.summary,c.guest,c.cost,c.currency');
1407         echo "<tr>";
1409         if ($depth) {
1410             $indent = $depth*30;
1411             $rows = count($courses) + 1;
1412             echo '<td rowspan="'.$rows.'" valign="top" width="'.$indent.'">';
1413             print_spacer(10, $indent);
1414             echo '</td>';
1415         }
1417         echo '<td valign="top">'.$catimage.'</td>';
1418         echo '<td valign="top" width="100%" class="category name">';
1419         echo '<a '.$catlinkcss.' href="'.$CFG->wwwroot.'/course/category.php?id='.$category->id.'">'.$category->name.'</a>';
1420         echo '</td>';
1421         echo '<td class="category info">&nbsp;</td>';
1422         echo '</tr>';
1424         if ($courses && !(isset($CFG->max_category_depth)&&($depth>=$CFG->max_category_depth-1))) {
1425             foreach ($courses as $course) {
1426                 $linkcss = $course->visible ? '' : ' class="dimmed" ';
1427                 echo '<tr><td valign="top" width="30">&nbsp;';
1428                 echo '</td><td valign="top" width="100%" class="course name">';
1429                 echo '<a '.$linkcss.' href="'.$CFG->wwwroot.'/course/view.php?id='.$course->id.'">'.$course->fullname.'</a>';
1430                 echo '</td><td align="right" valign="top" nowrap="nowrap" class="course info">';
1431                 if ($course->guest ) {
1432                     echo '<a title="'.$strallowguests.'" href="'.$CFG->wwwroot.'/course/view.php?id='.$course->id.'">';
1433                     echo '<img hspace="1" alt="'.$strallowguests.'" height="16" width="16" border="0" src="'.$CFG->pixpath.'/i/guest.gif" /></a>';
1434                 } else {
1435                     echo '<img alt="" height="16" width="18" border="0" src="'.$CFG->pixpath.'/spacer.gif" />';
1436                 }
1437                 if ($course->password) {
1438                     echo '<a title="'.$strrequireskey.'" href="'.$CFG->wwwroot.'/course/view.php?id='.$course->id.'">';
1439                     echo '<img hspace="1" alt="'.$strrequireskey.'" height="16" width="16" border="0" src="'.$CFG->pixpath.'/i/key.gif" /></a>';
1440                 } else {
1441                     echo '<img alt="" height="16" width="18" border="0" src="'.$CFG->pixpath.'/spacer.gif" />';
1442                 }
1443                 if ($course->summary) {
1444                     link_to_popup_window ('/course/info.php?id='.$course->id, 'courseinfo',
1445                                           '<img hspace="1" alt="'.$strsummary.'" height="16" width="16" border="0" src="'.$CFG->pixpath.'/i/info.gif" />',
1446                                            400, 500, $strsummary);
1447                 } else {
1448                     echo '<img alt="" height="16" width="18" border="0" src="'.$CFG->pixpath.'/spacer.gif" />';
1449                 }
1450                 echo '</td></tr>';
1451             }
1452         }
1453     } else {
1455         echo '<tr>';
1457         if ($depth) {
1458             $indent = $depth*20;
1459             echo '<td valign="top" width="'.$indent.'">';
1460             print_spacer(10, $indent);
1461             echo '</td>';
1462         }
1464         echo '<td valign="top" width="100%" class="category name">';
1465         echo '<a '.$catlinkcss.' href="'.$CFG->wwwroot.'/course/category.php?id='.$category->id.'">'.$category->name.'</a>';
1466         echo '</td>';
1467         echo '<td valign="top" class="category number">';
1468         if ($category->coursecount) {
1469             echo $category->coursecount;
1470         }
1471         echo '</td></tr>';
1472     }
1473     echo '</table>';
1477 function print_courses($category, $width="100%", $hidesitecourse = false) {
1478 /// Category is 0 (for all courses) or an object
1480     global $CFG;
1482     if (empty($category)) {
1483         $categories = get_categories(0);  // Parent = 0   ie top-level categories only
1484         if (count($categories) == 1) {
1485             $category   = array_shift($categories);
1486             $courses    = get_courses($category->id, 'c.sortorder ASC', 'c.id,c.category,c.sortorder,c.visible,c.fullname,c.shortname,c.password,c.summary,c.teacher,c.cost,c.currency,c.enrol');
1487         } else {
1488             $courses    = get_courses('all', 'c.sortorder ASC', 'c.id,c.category,c.sortorder,c.visible,c.fullname,c.shortname,c.password,c.summary,c.teacher,c.cost,c.currency,c.enrol');
1489         }
1490         unset($categories);
1491     } else {
1492         $categories = get_categories($category->id);  // sub categories
1493         $courses    = get_courses($category->id, 'c.sortorder ASC', 'c.id,c.category,c.sortorder,c.visible,c.fullname,c.shortname,c.password,c.summary,c.teacher,c.cost,c.currency,c.enrol');
1494     }
1496     if ($courses) {
1497         foreach ($courses as $course) {
1498             if ($hidesitecourse && !$course->category) {
1499                 continue;
1500             }
1501             print_course($course, $width);
1502         }
1503     } else {
1504         print_heading(get_string("nocoursesyet"));
1505         $context = get_context_instance(CONTEXT_SYSTEM, SITEID);
1506         if (has_capability('moodle/course:create', $context)) {
1507             $options = array();
1508             $options['category'] = $category->id;
1509             echo '<div class="addcoursebutton" align="center">';
1510             print_single_button($CFG->wwwroot.'/course/edit.php', $options, get_string("addnewcourse"));
1511             echo '</div>';
1512         }
1513     }
1518 function print_course($course, $width="100%") {
1520     global $CFG, $USER;
1522     require_once("$CFG->dirroot/enrol/enrol.class.php");
1524     $enrol = enrolment_factory::factory($course->enrol);
1526     print_simple_box_start("center", "$width", '', 5, "coursebox");
1528     $linkcss = $course->visible ? "" : " class=\"dimmed\" ";
1530     echo "<table width=\"100%\">";
1531     echo '<tr valign="top">';
1532     echo '<td valign="top" width="50%" class="info">';
1533     echo '<b><a title="'.get_string('entercourse').'"'.
1534          $linkcss.' href="'.$CFG->wwwroot.'/course/view.php?id='.$course->id.'">'.
1535          $course->fullname.'</a></b><br />';
1536     if ($teachers = get_course_teachers($course->id)) {
1537         echo "<span class=\"teachers\">\n";
1538         foreach ($teachers as $teacher) {
1539             if ($teacher->authority > 0) {
1540                 if (!$teacher->role) {
1541                     $teacher->role = $course->teacher;
1542                 }
1543                 $fullname = fullname($teacher, isteacher($course->id)); // is the USER a teacher of that course
1544                 echo $teacher->role.': <a href="'.$CFG->wwwroot.'/user/view.php?id='.$teacher->id.
1545                      '&amp;course='.SITEID.'">'.$fullname.'</a><br />';
1546             }
1547         }
1548         echo "</span>\n";
1549     }
1551     echo $enrol->get_access_icons($course);
1553     echo '</td><td valign="top" width="50%" class="summary">';
1554     $options = NULL;
1555     $options->noclean = true;
1556     $options->para = false;
1557     echo format_text($course->summary, FORMAT_MOODLE, $options,  $course->id);
1558     echo "</td></tr>";
1559     echo "</table>";
1561     print_simple_box_end();
1565 function print_my_moodle() {
1566 /// Prints custom user information on the home page.
1567 /// Over time this can include all sorts of information
1569     global $USER, $CFG;
1571     if (empty($USER->id)) {
1572         error("It shouldn't be possible to see My Moodle without being logged in.");
1573     }
1575     if ($courses = get_my_courses($USER->id)) {
1576         foreach ($courses as $course) {
1577             if (!$course->category) {
1578                 continue;
1579             }
1580             print_course($course, "100%");
1581         }
1583         if (count_records("course") > (count($courses) + 1) ) {  // Some courses not being displayed
1584             echo "<table width=\"100%\"><tr><td align=\"center\">";
1585             print_course_search("", false, "short");
1586             echo "</td><td align=\"center\">";
1587             print_single_button("$CFG->wwwroot/course/index.php", NULL, get_string("fulllistofcourses"), "get");
1588             echo "</td></tr></table>\n";
1589         }
1590     } else {
1591         if (count_records("course_categories") > 1) {
1592             print_simple_box_start("center", "100%", "#FFFFFF", 5, "categorybox");
1593             print_whole_category_list();
1594             print_simple_box_end();
1595         } else {
1596             print_courses(0, "100%");
1597         }
1598     }
1602 function print_course_search($value="", $return=false, $format="plain") {
1604     global $CFG;
1606     $strsearchcourses= get_string("searchcourses");
1608     if ($format == 'plain') {
1609         $output  = '<form name="coursesearch" action="'.$CFG->wwwroot.'/course/search.php" method="get">';
1610         $output .= '<center><p align="center" class="coursesearchbox">';
1611         $output .= '<input type="text" size="30" name="search" alt="'.s($strsearchcourses).'" value="'.s($value, true).'" />';
1612         $output .= '<input type="submit" value="'.s($strsearchcourses).'" />';
1613         $output .= '</p></center></form>';
1614     } else if ($format == 'short') {
1615         $output  = '<form name="coursesearch" action="'.$CFG->wwwroot.'/course/search.php" method="get">';
1616         $output .= '<center><p align="center" class="coursesearchbox">';
1617         $output .= '<input type="text" size="12" name="search" alt="'.s($strsearchcourses).'" value="'.s($value, true).'" />';
1618         $output .= '<input type="submit" value="'.s($strsearchcourses).'" />';
1619         $output .= '</p></center></form>';
1620     } else if ($format == 'navbar') {
1621         $output  = '<form name="coursesearch" action="'.$CFG->wwwroot.'/course/search.php" method="get">';
1622         $output .= '<table border="0" cellpadding="0" cellspacing="0"><tr><td nowrap="nowrap">';
1623         $output .= '<input type="text" size="20" name="search" alt="'.s($strsearchcourses).'" value="'.s($value, true).'" />';
1624         $output .= '<input type="submit" value="'.s($strsearchcourses).'" />';
1625         $output .= '</td></tr></table>';
1626         $output .= '</form>';
1627     }
1629     if ($return) {
1630         return $output;
1631     }
1632     echo $output;
1635 /// MODULE FUNCTIONS /////////////////////////////////////////////////////////////////
1637 function add_course_module($mod) {
1639     $mod->added = time();
1640     unset($mod->id);
1642     return insert_record("course_modules", $mod);
1645 function add_mod_to_section($mod, $beforemod=NULL) {
1646 /// Given a full mod object with section and course already defined
1647 /// If $before is specified, then this is an existing ID which we
1648 /// will insert the new module before
1649 ///
1650 /// Returns the course_sections ID where the mod is inserted
1652     if ($section = get_record("course_sections", "course", "$mod->course", "section", "$mod->section")) {
1654         $section->sequence = trim($section->sequence);
1656         if (empty($section->sequence)) {
1657             $newsequence = "$mod->coursemodule";
1659         } else if ($beforemod) {
1660             $modarray = explode(",", $section->sequence);
1662             if ($key = array_keys ($modarray, $beforemod->id)) {
1663                 $insertarray = array($mod->id, $beforemod->id);
1664                 array_splice($modarray, $key[0], 1, $insertarray);
1665                 $newsequence = implode(",", $modarray);
1667             } else {  // Just tack it on the end anyway
1668                 $newsequence = "$section->sequence,$mod->coursemodule";
1669             }
1671         } else {
1672             $newsequence = "$section->sequence,$mod->coursemodule";
1673         }
1675         if (set_field("course_sections", "sequence", $newsequence, "id", $section->id)) {
1676             return $section->id;     // Return course_sections ID that was used.
1677         } else {
1678             return 0;
1679         }
1681     } else {  // Insert a new record
1682         $section->course = $mod->course;
1683         $section->section = $mod->section;
1684         $section->summary = "";
1685         $section->sequence = $mod->coursemodule;
1686         return insert_record("course_sections", $section);
1687     }
1690 function set_coursemodule_groupmode($id, $groupmode) {
1691     return set_field("course_modules", "groupmode", $groupmode, "id", $id);
1694 /**
1695 * $prevstateoverrides = true will set the visibility of the course module
1696 * to what is defined in visibleold. This enables us to remember the current
1697 * visibility when making a whole section hidden, so that when we toggle
1698 * that section back to visible, we are able to return the visibility of
1699 * the course module back to what it was originally.
1700 */
1701 function set_coursemodule_visible($id, $visible, $prevstateoverrides=false) {
1702     $cm = get_record('course_modules', 'id', $id);
1703     $modulename = get_field('modules', 'name', 'id', $cm->module);
1704     if ($events = get_records_select('event', "instance = '$cm->instance' AND modulename = '$modulename'")) {
1705         foreach($events as $event) {
1706             if ($visible) {
1707                 show_event($event);
1708             } else {
1709                 hide_event($event);
1710             }
1711         }
1712     }
1713     if ($prevstateoverrides) {
1714         if ($visible == '0') {
1715             // Remember the current visible state so we can toggle this back.
1716             set_field('course_modules', 'visibleold', $cm->visible, 'id', $id);
1717         } else {
1718             // Get the previous saved visible states.
1719             return set_field('course_modules', 'visible', $cm->visibleold, 'id', $id);
1720         }
1721     }
1722     return set_field("course_modules", "visible", $visible, "id", $id);
1725 /*
1726  * Delete a course module and any associated data at the course level (events)
1727  * Until 1.5 this function simply marked a deleted flag ... now it 
1728  * deletes it completely.
1729  *
1730  */
1731 function delete_course_module($id) {
1732     if (!$cm = get_record('course_modules', 'id', $id)) {
1733         return true;
1734     }
1735     $modulename = get_field('modules', 'name', 'id', $cm->module);
1736     if ($events = get_records_select('event', "instance = '$cm->instance' AND modulename = '$modulename'")) {
1737         foreach($events as $event) {
1738             delete_event($event);
1739         }
1740     }
1741     return delete_records('course_modules', 'id', $cm->id);
1744 function delete_mod_from_section($mod, $section) {
1746     if ($section = get_record("course_sections", "id", "$section") ) {
1748         $modarray = explode(",", $section->sequence);
1750         if ($key = array_keys ($modarray, $mod)) {
1751             array_splice($modarray, $key[0], 1);
1752             $newsequence = implode(",", $modarray);
1753             return set_field("course_sections", "sequence", $newsequence, "id", $section->id);
1754         } else {
1755             return false;
1756         }
1758     }
1759     return false;
1762 function move_section($course, $section, $move) {
1763 /// Moves a whole course section up and down within the course
1764     global $USER;
1766     if (!$move) {
1767         return true;
1768     }
1770     $sectiondest = $section + $move;
1772     if ($sectiondest > $course->numsections or $sectiondest < 1) {
1773         return false;
1774     }
1776     if (!$sectionrecord = get_record("course_sections", "course", $course->id, "section", $section)) {
1777         return false;
1778     }
1780     if (!$sectiondestrecord = get_record("course_sections", "course", $course->id, "section", $sectiondest)) {
1781         return false;
1782     }
1784     if (!set_field("course_sections", "section", $sectiondest, "id", $sectionrecord->id)) {
1785         return false;
1786     }
1787     if (!set_field("course_sections", "section", $section, "id", $sectiondestrecord->id)) {
1788         return false;
1789     }
1790     // if the focus is on the section that is being moved, then move the focus along
1791     if (isset($USER->display[$course->id]) and ($USER->display[$course->id] == $section)) {
1792         course_set_display($course->id, $sectiondest);
1793     }
1795     // Check for duplicates and fix order if needed.
1796     // There is a very rare case that some sections in the same course have the same section id.
1797     $sections = get_records_select('course_sections', "course = $course->id", 'section ASC');
1798     $n = 0;
1799     foreach ($sections as $section) {
1800         if ($section->section != $n) {
1801             if (!set_field('course_sections', 'section', $n, 'id', $section->id)) {
1802                 return false;
1803             }
1804         }
1805         $n++;
1806     }
1807     return true;
1811 function moveto_module($mod, $section, $beforemod=NULL) {
1812 /// All parameters are objects
1813 /// Move the module object $mod to the specified $section
1814 /// If $beforemod exists then that is the module
1815 /// before which $modid should be inserted
1817 /// Remove original module from original section
1819     if (! delete_mod_from_section($mod->id, $mod->section)) {
1820         notify("Could not delete module from existing section");
1821     }
1823 /// Update module itself if necessary
1825     if ($mod->section != $section->id) {
1826         $mod->section = $section->id;
1827         if (!update_record("course_modules", $mod)) {
1828             return false;
1829         }
1830         // if moving to a hidden section then hide module
1831         if (!$section->visible) {
1832             set_coursemodule_visible($mod->id, 0);
1833         }
1834     }
1836 /// Add the module into the new section
1838     $mod->course       = $section->course;
1839     $mod->section      = $section->section;  // need relative reference
1840     $mod->coursemodule = $mod->id;
1842     if (! add_mod_to_section($mod, $beforemod)) {
1843         return false;
1844     }
1846     return true;
1850 function make_editing_buttons($mod, $absolute=false, $moveselect=true, $indent=-1, $section=-1) {
1851     global $CFG, $USER;
1853     static $str;
1854     static $sesskey;
1856     if (!isset($str)) {
1857         $str->delete    = get_string("delete");
1858         $str->move      = get_string("move");
1859         $str->moveup    = get_string("moveup");
1860         $str->movedown  = get_string("movedown");
1861         $str->moveright = get_string("moveright");
1862         $str->moveleft  = get_string("moveleft");
1863         $str->update    = get_string("update");
1864         $str->duplicate    = get_string("duplicate");
1865         $str->hide      = get_string("hide");
1866         $str->show      = get_string("show");
1867         $str->clicktochange  = get_string("clicktochange");
1868         $str->forcedmode     = get_string("forcedmode");
1869         $str->groupsnone     = get_string("groupsnone");
1870         $str->groupsseparate = get_string("groupsseparate");
1871         $str->groupsvisible  = get_string("groupsvisible");
1872         $sesskey = sesskey();
1873     }
1875     if ($section >= 0) {
1876         $section = '&amp;sr='.$section;   // Section return
1877     } else {
1878         $section = '';
1879     }
1881     if ($absolute) {
1882         $path = $CFG->wwwroot.'/course';
1883     } else {
1884         $path = '.';
1885     }
1887     if ($mod->visible) {
1888         $hideshow = '<a title="'.$str->hide.'" href="'.$path.'/mod.php?hide='.$mod->id.
1889                     '&amp;sesskey='.$sesskey.$section.'"><img'.
1890                     ' src="'.$CFG->pixpath.'/t/hide.gif" hspace="2" height="11" width="11" '.
1891                     ' border="0" alt="'.$str->hide.'" /></a> ';
1892     } else {
1893         $hideshow = '<a title="'.$str->show.'" href="'.$path.'/mod.php?show='.$mod->id.
1894                     '&amp;sesskey='.$sesskey.$section.'"><img'.
1895                     ' src="'.$CFG->pixpath.'/t/show.gif" hspace="2" height="11" width="11" '.
1896                     ' border="0" alt="'.$str->show.'" /></a> ';
1897     }
1898     if ($mod->groupmode !== false) {
1899         if ($mod->groupmode == SEPARATEGROUPS) {
1900             $grouptitle = $str->groupsseparate;
1901             $groupimage = $CFG->pixpath.'/t/groups.gif';
1902             $grouplink  = $path.'/mod.php?id='.$mod->id.'&amp;groupmode=0&amp;sesskey='.$sesskey;
1903         } else if ($mod->groupmode == VISIBLEGROUPS) {
1904             $grouptitle = $str->groupsvisible;
1905             $groupimage = $CFG->pixpath.'/t/groupv.gif';
1906             $grouplink  = $path.'/mod.php?id='.$mod->id.'&amp;groupmode=1&amp;sesskey='.$sesskey;
1907         } else {
1908             $grouptitle = $str->groupsnone;
1909             $groupimage = $CFG->pixpath.'/t/groupn.gif';
1910             $grouplink  = $path.'/mod.php?id='.$mod->id.'&amp;groupmode=2&amp;sesskey='.$sesskey;
1911         }
1912         if ($mod->groupmodelink) {
1913             $groupmode = '<a title="'.$grouptitle.' ('.$str->clicktochange.')" href="'.$grouplink.'">'.
1914                          '<img src="'.$groupimage.'" hspace="2" height="11" width="11" '.
1915                          'border="0" alt="'.$grouptitle.'" /></a>';
1916         } else {
1917             $groupmode = '<img title="'.$grouptitle.' ('.$str->forcedmode.')" '.
1918                          ' src="'.$groupimage.'" hspace="2" height="11" width="11" '.
1919                          'border="0" alt="'.$grouptitle.'" />';
1920         }
1921     } else {
1922         $groupmode = "";
1923     }
1925     if ($moveselect) {
1926         $move =     '<a title="'.$str->move.'" href="'.$path.'/mod.php?copy='.$mod->id.
1927                     '&amp;sesskey='.$sesskey.$section.'"><img'.
1928                     ' src="'.$CFG->pixpath.'/t/move.gif" hspace="2" height="11" width="11" '.
1929                     ' border="0" alt="'.$str->move.'" /></a>';
1930     } else {
1931         $move =     '<a title="'.$str->moveup.'" href="'.$path.'/mod.php?id='.$mod->id.
1932                     '&amp;move=-1&amp;sesskey='.$sesskey.$section.'"><img'.
1933                     ' src="'.$CFG->pixpath.'/t/up.gif" hspace="2" height="11" width="11" '.
1934                     ' border="0" alt="'.$str->moveup.'" /></a>'.
1935                     '<a title="'.$str->movedown.'" href="'.$path.'/mod.php?id='.$mod->id.
1936                     '&amp;move=1&amp;sesskey='.$sesskey.$section.'"><img'.
1937                     ' src="'.$CFG->pixpath.'/t/down.gif" hspace="2" height="11" width="11" '.
1938                     ' border="0" alt="'.$str->movedown.'" /></a>';
1939     }
1941     $leftright = "";
1942     if ($indent > 0) {
1943         $leftright .= '<a title="'.$str->moveleft.'" href="'.$path.'/mod.php?id='.$mod->id.
1944                       '&amp;indent=-1&amp;sesskey='.$sesskey.$section.'"><img'.
1945                       ' src="'.$CFG->pixpath.'/t/left.gif" hspace="2" height="11" width="11" '.
1946                       ' border="0" alt="'.$str->moveleft.'" /></a>';
1947     }
1948     if ($indent >= 0) {
1949         $leftright .= '<a title="'.$str->moveright.'" href="'.$path.'/mod.php?id='.$mod->id.
1950                       '&amp;indent=1&amp;sesskey='.$sesskey.$section.'"><img'.
1951                       ' src="'.$CFG->pixpath.'/t/right.gif" hspace="2" height="11" width="11" '.
1952                       ' border="0" alt="'.$str->moveright.'" /></a>';
1953     }
1955     return '<span class="commands">'.$leftright.$move.
1956            '<a title="'.$str->update.'" href="'.$path.'/mod.php?update='.$mod->id.
1957            '&amp;sesskey='.$sesskey.$section.'"><img'.
1958            ' src="'.$CFG->pixpath.'/t/edit.gif" hspace="2" height="11" width="11" border="0" '.
1959            ' alt="'.$str->update.'" /></a>'.
1960            '<a title="'.$str->delete.'" href="'.$path.'/mod.php?delete='.$mod->id.
1961            '&amp;sesskey='.$sesskey.$section.'"><img'.
1962            ' src="'.$CFG->pixpath.'/t/delete.gif" hspace="2" height="11" width="11" border="0" '.
1963            ' alt="'.$str->delete.'" /></a>'.$hideshow.$groupmode.'</span>';
1966 /**
1967  * given a course object with shortname & fullname, this function will 
1968  * truncate the the number of chars allowed and add ... if it was too long
1969  */
1970 function course_format_name ($course,$max=100) {
1971     
1972     $str = $course->shortname.': '.$course->fullname;
1973     if (strlen($str) <= $max) {
1974         return $str;
1975     }
1976     else {
1977         return substr($str,0,$max-3).'...';
1978     }
1981 /**
1982  * This function will return true if the given course is a child course at all
1983  */
1984 function course_in_meta ($course) {
1985     return record_exists("course_meta","child_course",$course->id);
1989 /**
1990  * Print standard form elements on module setup forms in mod/.../mod.html
1991  */
1992 function print_standard_coursemodule_settings($form) {
1993     if (! $course = get_record('course', 'id', $form->course)) {
1994         error("This course doesn't exist");
1995     }
1996     print_groupmode_setting($form, $course);
1997     print_visible_setting($form, $course);
2000 /**
2001  * Print groupmode form element on module setup forms in mod/.../mod.html
2002  */
2003 function print_groupmode_setting($form, $course=NULL) {
2005     if (empty($course)) {
2006         if (! $course = get_record('course', 'id', $form->course)) {
2007             error("This course doesn't exist");
2008         }
2009     }
2010     if ($form->coursemodule) {
2011         if (! $cm = get_record('course_modules', 'id', $form->coursemodule)) {
2012             error("This course module doesn't exist");
2013         }
2014     } else {
2015         $cm = null;
2016     }
2017     $groupmode = groupmode($course, $cm);
2018     if ($course->groupmode or (!$course->groupmodeforce)) {
2019         echo '<tr valign="top">';
2020         echo '<td align="right"><b>'.get_string('groupmode').':</b></td>';
2021         echo '<td align="left">';
2022         unset($choices);
2023         $choices[NOGROUPS] = get_string('groupsnone');
2024         $choices[SEPARATEGROUPS] = get_string('groupsseparate');
2025         $choices[VISIBLEGROUPS] = get_string('groupsvisible');
2026         choose_from_menu($choices, 'groupmode', $groupmode, '', '', 0, false, $course->groupmodeforce);
2027         helpbutton('groupmode', get_string('groupmode'));
2028         echo '</td></tr>';
2029     }
2032 /**
2033  * Print visibility setting form element on module setup forms in mod/.../mod.html
2034  */
2035 function print_visible_setting($form, $course=NULL) {
2036     if (empty($course)) {
2037         if (! $course = get_record('course', 'id', $form->course)) {
2038             error("This course doesn't exist");
2039         }
2040     }
2041     if ($form->coursemodule) {
2042         $visible = get_field('course_modules', 'visible', 'id', $form->coursemodule);
2043     } else {
2044         $visible = true;
2045     }
2047     if ($form->mode == 'add') { // in this case $form->section is the section number, not the id
2048         $hiddensection = !get_field('course_sections', 'visible', 'section', $form->section, 'course', $form->course);
2049     } else {
2050         $hiddensection = !get_field('course_sections', 'visible', 'id', $form->section);
2051     }
2052     if ($hiddensection) {
2053         $visible = false;
2054     }
2055     
2056     echo '<tr valign="top">';
2057     echo '<td align="right"><b>'.get_string('visibletostudents','',moodle_strtolower($course->students)).':</b></td>';
2058     echo '<td align="left">';
2059     unset($choices);
2060     $choices[1] = get_string('show');
2061     $choices[0] = get_string('hide');
2062     choose_from_menu($choices, 'visible', $visible, '', '', 0, false, $hiddensection);
2063     echo '</td></tr>';
2064
2066 function update_restricted_mods($course,$mods) {
2067     delete_records("course_allowed_modules","course",$course->id);
2068     if (empty($course->restrictmodules)) {
2069         return;
2070     }
2071     else {
2072         foreach ($mods as $mod) {
2073             if ($mod == 0)
2074                 continue; // this is the 'allow none' option
2075             $am->course = $course->id;
2076             $am->module = $mod;
2077             insert_record("course_allowed_modules",$am);
2078         }
2079     }
2082 /**
2083  * This function will take an int (module id) or a string (module name)
2084  * and return true or false, whether it's allowed in the given course (object)
2085  * $mod is not allowed to be an object, as the field for the module id is inconsistent 
2086  * depending on where in the code it's called from (sometimes $mod->id, sometimes $mod->module)
2087  */
2089 function course_allowed_module($course,$mod) {
2090     if (empty($course->restrictmodules)) {
2091         return true;
2092     }
2093     if (isadmin()) {
2094         return true;
2095     }
2096     if (is_numeric($mod)) {
2097         $modid = $mod;
2098     } else if (is_string($mod)) {
2099         if ($mod = get_field("modules","id","name",$mod))
2100             $modid = $mod;
2101     }
2102     if (empty($modid)) {
2103         return false;
2104     }
2105     return (record_exists("course_allowed_modules","course",$course->id,"module",$modid));
2108 /***
2109  *** Efficiently moves many courses around while maintaining
2110  *** sortorder in order.
2111  *** 
2112  *** $courseids is an array of course ids
2113  ***
2114  **/
2116 function move_courses ($courseids, $categoryid) {
2118     global $CFG;
2120     if (!empty($courseids)) {
2121        
2122             $courseids = array_reverse($courseids); 
2124             foreach ($courseids as $courseid) {
2125                                       
2126                 if (! $course  = get_record("course", "id", $courseid)) {
2127                     notify("Error finding course $courseid");
2128                 } else {
2129                     // figure out a sortorder that we can use in the destination category
2130                     $sortorder = get_field_sql('SELECT MIN(sortorder)-1 AS min
2131                                                     FROM ' . $CFG->prefix . 'course WHERE category=' . $categoryid);
2132                     if ($sortorder === false) {
2133                         // the category is empty
2134                         // rather than let the db default to 0
2135                         // set it to > 100 and avoid extra work in fix_coursesortorder()                        
2136                         $sortorder = 200;
2137                     } else if ($sortorder < 10) {
2138                         fix_course_sortorder($categoryid);
2139                     }
2141                     $course->category  = $categoryid;
2142                     $course->sortorder = $sortorder;
2143                     $course->fullname = addslashes($course->fullname);
2144                     $course->shortname = addslashes($course->shortname);
2145                     $course->summary = addslashes($course->summary);
2146                     $course->password = addslashes($course->password);
2147                     $course->teacher = addslashes($course->teacher);
2148                     $course->teachers = addslashes($course->teachers);
2149                     $course->student = addslashes($course->student);
2150                     $course->students = addslashes($course->students);
2151                     
2152                     if (!update_record('course', $course)) {
2153                         notify("An error occurred - course not moved!");
2154                     }
2155                 }
2156             }
2157             fix_course_sortorder();
2158         }    
2159     return true;
2162 ?>