Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/course/lib.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00027 defined('MOODLE_INTERNAL') || die;
00028 
00029 require_once($CFG->libdir.'/completionlib.php');
00030 require_once($CFG->libdir.'/filelib.php');
00031 
00032 define('COURSE_MAX_LOGS_PER_PAGE', 1000);       // records
00033 define('COURSE_MAX_RECENT_PERIOD', 172800);     // Two days, in seconds
00034 define('COURSE_MAX_SUMMARIES_PER_PAGE', 10);    // courses
00035 define('COURSE_MAX_COURSES_PER_DROPDOWN',1000); //  max courses in log dropdown before switching to optional
00036 define('COURSE_MAX_USERS_PER_DROPDOWN',1000);   //  max users in log dropdown before switching to optional
00037 define('FRONTPAGENEWS',           '0');
00038 define('FRONTPAGECOURSELIST',     '1');
00039 define('FRONTPAGECATEGORYNAMES',  '2');
00040 define('FRONTPAGETOPICONLY',      '3');
00041 define('FRONTPAGECATEGORYCOMBO',  '4');
00042 define('FRONTPAGECOURSELIMIT',    200);         // maximum number of courses displayed on the frontpage
00043 define('EXCELROWS', 65535);
00044 define('FIRSTUSEDEXCELROW', 3);
00045 
00046 define('MOD_CLASS_ACTIVITY', 0);
00047 define('MOD_CLASS_RESOURCE', 1);
00048 
00049 function make_log_url($module, $url) {
00050     switch ($module) {
00051         case 'course':
00052             if (strpos($url, 'report/') === 0) {
00053                 // there is only one report type, course reports are deprecated
00054                 $url = "/$url";
00055                 break;
00056             }
00057         case 'file':
00058         case 'login':
00059         case 'lib':
00060         case 'admin':
00061         case 'calendar':
00062         case 'mnet course':
00063             if (strpos($url, '../') === 0) {
00064                 $url = ltrim($url, '.');
00065             } else {
00066                 $url = "/course/$url";
00067             }
00068             break;
00069         case 'user':
00070         case 'blog':
00071             $url = "/$module/$url";
00072             break;
00073         case 'upload':
00074             $url = $url;
00075             break;
00076         case 'coursetags':
00077             $url = '/'.$url;
00078             break;
00079         case 'library':
00080         case '':
00081             $url = '/';
00082             break;
00083         case 'message':
00084             $url = "/message/$url";
00085             break;
00086         case 'notes':
00087             $url = "/notes/$url";
00088             break;
00089         case 'tag':
00090             $url = "/tag/$url";
00091             break;
00092         case 'role':
00093             $url = '/'.$url;
00094             break;
00095         default:
00096             $url = "/mod/$module/$url";
00097             break;
00098     }
00099 
00100     //now let's sanitise urls - there might be some ugly nasties:-(
00101     $parts = explode('?', $url);
00102     $script = array_shift($parts);
00103     if (strpos($script, 'http') === 0) {
00104         $script = clean_param($script, PARAM_URL);
00105     } else {
00106         $script = clean_param($script, PARAM_PATH);
00107     }
00108 
00109     $query = '';
00110     if ($parts) {
00111         $query = implode('', $parts);
00112         $query = str_replace('&amp;', '&', $query); // both & and &amp; are stored in db :-|
00113         $parts = explode('&', $query);
00114         $eq = urlencode('=');
00115         foreach ($parts as $key=>$part) {
00116             $part = urlencode(urldecode($part));
00117             $part = str_replace($eq, '=', $part);
00118             $parts[$key] = $part;
00119         }
00120         $query = '?'.implode('&amp;', $parts);
00121     }
00122 
00123     return $script.$query;
00124 }
00125 
00126 
00127 function build_mnet_logs_array($hostid, $course, $user=0, $date=0, $order="l.time ASC", $limitfrom='', $limitnum='',
00128                    $modname="", $modid=0, $modaction="", $groupid=0) {
00129     global $CFG, $DB;
00130 
00131     // It is assumed that $date is the GMT time of midnight for that day,
00132     // and so the next 86400 seconds worth of logs are printed.
00133 
00135 
00136     // TODO: I don't understand group/context/etc. enough to be able to do
00137     // something interesting with it here
00138     // What is the context of a remote course?
00139 
00142     //if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
00143     //    $groupid = get_current_group($course->id);
00144     //}
00146     //else if (!$course->groupmode) {
00147     //    $groupid = 0;
00148     //}
00149 
00150     $groupid = 0;
00151 
00152     $joins = array();
00153     $where = '';
00154 
00155     $qry = "SELECT l.*, u.firstname, u.lastname, u.picture
00156               FROM {mnet_log} l
00157                LEFT JOIN {user} u ON l.userid = u.id
00158               WHERE ";
00159     $params = array();
00160 
00161     $where .= "l.hostid = :hostid";
00162     $params['hostid'] = $hostid;
00163 
00164     // TODO: Is 1 really a magic number referring to the sitename?
00165     if ($course != SITEID || $modid != 0) {
00166         $where .= " AND l.course=:courseid";
00167         $params['courseid'] = $course;
00168     }
00169 
00170     if ($modname) {
00171         $where .= " AND l.module = :modname";
00172         $params['modname'] = $modname;
00173     }
00174 
00175     if ('site_errors' === $modid) {
00176         $where .= " AND ( l.action='error' OR l.action='infected' )";
00177     } else if ($modid) {
00178         //TODO: This assumes that modids are the same across sites... probably
00179         //not true
00180         $where .= " AND l.cmid = :modid";
00181         $params['modid'] = $modid;
00182     }
00183 
00184     if ($modaction) {
00185         $firstletter = substr($modaction, 0, 1);
00186         if ($firstletter == '-') {
00187             $where .= " AND ".$DB->sql_like('l.action', ':modaction', false, true, true);
00188             $params['modaction'] = '%'.substr($modaction, 1).'%';
00189         } else {
00190             $where .= " AND ".$DB->sql_like('l.action', ':modaction', false);
00191             $params['modaction'] = '%'.$modaction.'%';
00192         }
00193     }
00194 
00195     if ($user) {
00196         $where .= " AND l.userid = :user";
00197         $params['user'] = $user;
00198     }
00199 
00200     if ($date) {
00201         $enddate = $date + 86400;
00202         $where .= " AND l.time > :date AND l.time < :enddate";
00203         $params['date'] = $date;
00204         $params['enddate'] = $enddate;
00205     }
00206 
00207     $result = array();
00208     $result['totalcount'] = $DB->count_records_sql("SELECT COUNT('x') FROM {mnet_log} l WHERE $where", $params);
00209     if(!empty($result['totalcount'])) {
00210         $where .= " ORDER BY $order";
00211         $result['logs'] = $DB->get_records_sql("$qry $where", $params, $limitfrom, $limitnum);
00212     } else {
00213         $result['logs'] = array();
00214     }
00215     return $result;
00216 }
00217 
00218 function build_logs_array($course, $user=0, $date=0, $order="l.time ASC", $limitfrom='', $limitnum='',
00219                    $modname="", $modid=0, $modaction="", $groupid=0) {
00220     global $DB, $SESSION, $USER;
00221     // It is assumed that $date is the GMT time of midnight for that day,
00222     // and so the next 86400 seconds worth of logs are printed.
00223 
00225 
00228     if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
00229         if (isset($SESSION->currentgroup[$course->id])) {
00230             $groupid =  $SESSION->currentgroup[$course->id];
00231         } else {
00232             $groupid = groups_get_all_groups($course->id, $USER->id);
00233             if (is_array($groupid)) {
00234                 $groupid = array_shift(array_keys($groupid));
00235                 $SESSION->currentgroup[$course->id] = $groupid;
00236             } else {
00237                 $groupid = 0;
00238             }
00239         }
00240     }
00242     else if (!$course->groupmode) {
00243         $groupid = 0;
00244     }
00245 
00246     $joins = array();
00247     $params = array();
00248 
00249     if ($course->id != SITEID || $modid != 0) {
00250         $joins[] = "l.course = :courseid";
00251         $params['courseid'] = $course->id;
00252     }
00253 
00254     if ($modname) {
00255         $joins[] = "l.module = :modname";
00256         $params['modname'] = $modname;
00257     }
00258 
00259     if ('site_errors' === $modid) {
00260         $joins[] = "( l.action='error' OR l.action='infected' )";
00261     } else if ($modid) {
00262         $joins[] = "l.cmid = :modid";
00263         $params['modid'] = $modid;
00264     }
00265 
00266     if ($modaction) {
00267         $firstletter = substr($modaction, 0, 1);
00268         if ($firstletter == '-') {
00269             $joins[] = $DB->sql_like('l.action', ':modaction', false, true, true);
00270             $params['modaction'] = '%'.substr($modaction, 1).'%';
00271         } else {
00272             $joins[] = $DB->sql_like('l.action', ':modaction', false);
00273             $params['modaction'] = '%'.$modaction.'%';
00274         }
00275     }
00276 
00277 
00279     if ($groupid and !$user) {
00280         if ($gusers = groups_get_members($groupid)) {
00281             $gusers = array_keys($gusers);
00282             $joins[] = 'l.userid IN (' . implode(',', $gusers) . ')';
00283         } else {
00284             $joins[] = 'l.userid = 0'; // No users in groups, so we want something that will always be false.
00285         }
00286     }
00287     else if ($user) {
00288         $joins[] = "l.userid = :userid";
00289         $params['userid'] = $user;
00290     }
00291 
00292     if ($date) {
00293         $enddate = $date + 86400;
00294         $joins[] = "l.time > :date AND l.time < :enddate";
00295         $params['date'] = $date;
00296         $params['enddate'] = $enddate;
00297     }
00298 
00299     $selector = implode(' AND ', $joins);
00300 
00301     $totalcount = 0;  // Initialise
00302     $result = array();
00303     $result['logs'] = get_logs($selector, $params, $order, $limitfrom, $limitnum, $totalcount);
00304     $result['totalcount'] = $totalcount;
00305     return $result;
00306 }
00307 
00308 
00309 function print_log($course, $user=0, $date=0, $order="l.time ASC", $page=0, $perpage=100,
00310                    $url="", $modname="", $modid=0, $modaction="", $groupid=0) {
00311 
00312     global $CFG, $DB, $OUTPUT;
00313 
00314     if (!$logs = build_logs_array($course, $user, $date, $order, $page*$perpage, $perpage,
00315                        $modname, $modid, $modaction, $groupid)) {
00316         echo $OUTPUT->notification("No logs found!");
00317         echo $OUTPUT->footer();
00318         exit;
00319     }
00320 
00321     $courses = array();
00322 
00323     if ($course->id == SITEID) {
00324         $courses[0] = '';
00325         if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
00326             foreach ($ccc as $cc) {
00327                 $courses[$cc->id] = $cc->shortname;
00328             }
00329         }
00330     } else {
00331         $courses[$course->id] = $course->shortname;
00332     }
00333 
00334     $totalcount = $logs['totalcount'];
00335     $count=0;
00336     $ldcache = array();
00337     $tt = getdate(time());
00338     $today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
00339 
00340     $strftimedatetime = get_string("strftimedatetime");
00341 
00342     echo "<div class=\"info\">\n";
00343     print_string("displayingrecords", "", $totalcount);
00344     echo "</div>\n";
00345 
00346     echo $OUTPUT->paging_bar($totalcount, $page, $perpage, "$url&perpage=$perpage");
00347 
00348     $table = new html_table();
00349     $table->classes = array('logtable','generalbox');
00350     $table->align = array('right', 'left', 'left');
00351     $table->head = array(
00352         get_string('time'),
00353         get_string('ip_address'),
00354         get_string('fullnameuser'),
00355         get_string('action'),
00356         get_string('info')
00357     );
00358     $table->data = array();
00359 
00360     if ($course->id == SITEID) {
00361         array_unshift($table->align, 'left');
00362         array_unshift($table->head, get_string('course'));
00363     }
00364 
00365     // Make sure that the logs array is an array, even it is empty, to avoid warnings from the foreach.
00366     if (empty($logs['logs'])) {
00367         $logs['logs'] = array();
00368     }
00369 
00370     foreach ($logs['logs'] as $log) {
00371 
00372         if (isset($ldcache[$log->module][$log->action])) {
00373             $ld = $ldcache[$log->module][$log->action];
00374         } else {
00375             $ld = $DB->get_record('log_display', array('module'=>$log->module, 'action'=>$log->action));
00376             $ldcache[$log->module][$log->action] = $ld;
00377         }
00378         if ($ld && is_numeric($log->info)) {
00379             // ugly hack to make sure fullname is shown correctly
00380             if ($ld->mtable == 'user' && $ld->field == $DB->sql_concat('firstname', "' '" , 'lastname')) {
00381                 $log->info = fullname($DB->get_record($ld->mtable, array('id'=>$log->info)), true);
00382             } else {
00383                 $log->info = $DB->get_field($ld->mtable, $ld->field, array('id'=>$log->info));
00384             }
00385         }
00386 
00387         //Filter log->info
00388         $log->info = format_string($log->info);
00389 
00390         // If $log->url has been trimmed short by the db size restriction
00391         // code in add_to_log, keep a note so we don't add a link to a broken url
00392         $tl=textlib_get_instance();
00393         $brokenurl=($tl->strlen($log->url)==100 && $tl->substr($log->url,97)=='...');
00394 
00395         $row = array();
00396         if ($course->id == SITEID) {
00397             if (empty($log->course)) {
00398                 $row[] = get_string('site');
00399             } else {
00400                 $row[] = "<a href=\"{$CFG->wwwroot}/course/view.php?id={$log->course}\">". format_string($courses[$log->course])."</a>";
00401             }
00402         }
00403 
00404         $row[] = userdate($log->time, '%a').' '.userdate($log->time, $strftimedatetime);
00405 
00406         $link = new moodle_url("/iplookup/index.php?ip=$log->ip&user=$log->userid");
00407         $row[] = $OUTPUT->action_link($link, $log->ip, new popup_action('click', $link, 'iplookup', array('height' => 440, 'width' => 700)));
00408 
00409         $row[] = html_writer::link(new moodle_url("/user/view.php?id={$log->userid}&course={$log->course}"), fullname($log, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id))));
00410 
00411         $displayaction="$log->module $log->action";
00412         if ($brokenurl) {
00413             $row[] = $displayaction;
00414         } else {
00415             $link = make_log_url($log->module,$log->url);
00416             $row[] = $OUTPUT->action_link($link, $displayaction, new popup_action('click', $link, 'fromloglive'), array('height' => 440, 'width' => 700));
00417         }
00418         $row[] = $log->info;
00419         $table->data[] = $row;
00420     }
00421 
00422     echo html_writer::table($table);
00423     echo $OUTPUT->paging_bar($totalcount, $page, $perpage, "$url&perpage=$perpage");
00424 }
00425 
00426 
00427 function print_mnet_log($hostid, $course, $user=0, $date=0, $order="l.time ASC", $page=0, $perpage=100,
00428                    $url="", $modname="", $modid=0, $modaction="", $groupid=0) {
00429 
00430     global $CFG, $DB, $OUTPUT;
00431 
00432     if (!$logs = build_mnet_logs_array($hostid, $course, $user, $date, $order, $page*$perpage, $perpage,
00433                        $modname, $modid, $modaction, $groupid)) {
00434         echo $OUTPUT->notification("No logs found!");
00435         echo $OUTPUT->footer();
00436         exit;
00437     }
00438 
00439     if ($course->id == SITEID) {
00440         $courses[0] = '';
00441         if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname,c.visible')) {
00442             foreach ($ccc as $cc) {
00443                 $courses[$cc->id] = $cc->shortname;
00444             }
00445         }
00446     }
00447 
00448     $totalcount = $logs['totalcount'];
00449     $count=0;
00450     $ldcache = array();
00451     $tt = getdate(time());
00452     $today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
00453 
00454     $strftimedatetime = get_string("strftimedatetime");
00455 
00456     echo "<div class=\"info\">\n";
00457     print_string("displayingrecords", "", $totalcount);
00458     echo "</div>\n";
00459 
00460     echo $OUTPUT->paging_bar($totalcount, $page, $perpage, "$url&perpage=$perpage");
00461 
00462     echo "<table class=\"logtable\" cellpadding=\"3\" cellspacing=\"0\">\n";
00463     echo "<tr>";
00464     if ($course->id == SITEID) {
00465         echo "<th class=\"c0 header\">".get_string('course')."</th>\n";
00466     }
00467     echo "<th class=\"c1 header\">".get_string('time')."</th>\n";
00468     echo "<th class=\"c2 header\">".get_string('ip_address')."</th>\n";
00469     echo "<th class=\"c3 header\">".get_string('fullnameuser')."</th>\n";
00470     echo "<th class=\"c4 header\">".get_string('action')."</th>\n";
00471     echo "<th class=\"c5 header\">".get_string('info')."</th>\n";
00472     echo "</tr>\n";
00473 
00474     if (empty($logs['logs'])) {
00475         echo "</table>\n";
00476         return;
00477     }
00478 
00479     $row = 1;
00480     foreach ($logs['logs'] as $log) {
00481 
00482         $log->info = $log->coursename;
00483         $row = ($row + 1) % 2;
00484 
00485         if (isset($ldcache[$log->module][$log->action])) {
00486             $ld = $ldcache[$log->module][$log->action];
00487         } else {
00488             $ld = $DB->get_record('log_display', array('module'=>$log->module, 'action'=>$log->action));
00489             $ldcache[$log->module][$log->action] = $ld;
00490         }
00491         if (0 && $ld && !empty($log->info)) {
00492             // ugly hack to make sure fullname is shown correctly
00493             if (($ld->mtable == 'user') and ($ld->field == $DB->sql_concat('firstname', "' '" , 'lastname'))) {
00494                 $log->info = fullname($DB->get_record($ld->mtable, array('id'=>$log->info)), true);
00495             } else {
00496                 $log->info = $DB->get_field($ld->mtable, $ld->field, array('id'=>$log->info));
00497             }
00498         }
00499 
00500         //Filter log->info
00501         $log->info = format_string($log->info);
00502 
00503         echo '<tr class="r'.$row.'">';
00504         if ($course->id == SITEID) {
00505             $courseshortname = format_string($courses[$log->course], true, array('context' => get_context_instance(CONTEXT_COURSE, SITEID)));
00506             echo "<td class=\"r$row c0\" >\n";
00507             echo "    <a href=\"{$CFG->wwwroot}/course/view.php?id={$log->course}\">".$courseshortname."</a>\n";
00508             echo "</td>\n";
00509         }
00510         echo "<td class=\"r$row c1\" align=\"right\">".userdate($log->time, '%a').
00511              ' '.userdate($log->time, $strftimedatetime)."</td>\n";
00512         echo "<td class=\"r$row c2\" >\n";
00513         $link = new moodle_url("/iplookup/index.php?ip=$log->ip&user=$log->userid");
00514         echo $OUTPUT->action_link($link, $log->ip, new popup_action('click', $link, 'iplookup', array('height' => 400, 'width' => 700)));
00515         echo "</td>\n";
00516         $fullname = fullname($log, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
00517         echo "<td class=\"r$row c3\" >\n";
00518         echo "    <a href=\"$CFG->wwwroot/user/view.php?id={$log->userid}\">$fullname</a>\n";
00519         echo "</td>\n";
00520         echo "<td class=\"r$row c4\">\n";
00521         echo $log->action .': '.$log->module;
00522         echo "</td>\n";;
00523         echo "<td class=\"r$row c5\">{$log->info}</td>\n";
00524         echo "</tr>\n";
00525     }
00526     echo "</table>\n";
00527 
00528     echo $OUTPUT->paging_bar($totalcount, $page, $perpage, "$url&perpage=$perpage");
00529 }
00530 
00531 
00532 function print_log_csv($course, $user, $date, $order='l.time DESC', $modname,
00533                         $modid, $modaction, $groupid) {
00534     global $DB;
00535 
00536     $text = get_string('course')."\t".get_string('time')."\t".get_string('ip_address')."\t".
00537             get_string('fullnameuser')."\t".get_string('action')."\t".get_string('info');
00538 
00539     if (!$logs = build_logs_array($course, $user, $date, $order, '', '',
00540                        $modname, $modid, $modaction, $groupid)) {
00541         return false;
00542     }
00543 
00544     $courses = array();
00545 
00546     if ($course->id == SITEID) {
00547         $courses[0] = '';
00548         if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
00549             foreach ($ccc as $cc) {
00550                 $courses[$cc->id] = $cc->shortname;
00551             }
00552         }
00553     } else {
00554         $courses[$course->id] = $course->shortname;
00555     }
00556 
00557     $count=0;
00558     $ldcache = array();
00559     $tt = getdate(time());
00560     $today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
00561 
00562     $strftimedatetime = get_string("strftimedatetime");
00563 
00564     $filename = 'logs_'.userdate(time(),get_string('backupnameformat', 'langconfig'),99,false);
00565     $filename .= '.txt';
00566     header("Content-Type: application/download\n");
00567     header("Content-Disposition: attachment; filename=$filename");
00568     header("Expires: 0");
00569     header("Cache-Control: must-revalidate,post-check=0,pre-check=0");
00570     header("Pragma: public");
00571 
00572     echo get_string('savedat').userdate(time(), $strftimedatetime)."\n";
00573     echo $text."\n";
00574 
00575     if (empty($logs['logs'])) {
00576         return true;
00577     }
00578 
00579     foreach ($logs['logs'] as $log) {
00580         if (isset($ldcache[$log->module][$log->action])) {
00581             $ld = $ldcache[$log->module][$log->action];
00582         } else {
00583             $ld = $DB->get_record('log_display', array('module'=>$log->module, 'action'=>$log->action));
00584             $ldcache[$log->module][$log->action] = $ld;
00585         }
00586         if ($ld && !empty($log->info)) {
00587             // ugly hack to make sure fullname is shown correctly
00588             if (($ld->mtable == 'user') and ($ld->field ==  $DB->sql_concat('firstname', "' '" , 'lastname'))) {
00589                 $log->info = fullname($DB->get_record($ld->mtable, array('id'=>$log->info)), true);
00590             } else {
00591                 $log->info = $DB->get_field($ld->mtable, $ld->field, array('id'=>$log->info));
00592             }
00593         }
00594 
00595         //Filter log->info
00596         $log->info = format_string($log->info);
00597         $log->info = strip_tags(urldecode($log->info));    // Some XSS protection
00598 
00599         $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
00600         $firstField = format_string($courses[$log->course], true, array('context' => $coursecontext));
00601         $fullname = fullname($log, has_capability('moodle/site:viewfullnames', $coursecontext));
00602         $row = array($firstField, userdate($log->time, $strftimedatetime), $log->ip, $fullname, $log->module.' '.$log->action, $log->info);
00603         $text = implode("\t", $row);
00604         echo $text." \n";
00605     }
00606     return true;
00607 }
00608 
00609 
00610 function print_log_xls($course, $user, $date, $order='l.time DESC', $modname,
00611                         $modid, $modaction, $groupid) {
00612 
00613     global $CFG, $DB;
00614 
00615     require_once("$CFG->libdir/excellib.class.php");
00616 
00617     if (!$logs = build_logs_array($course, $user, $date, $order, '', '',
00618                        $modname, $modid, $modaction, $groupid)) {
00619         return false;
00620     }
00621 
00622     $courses = array();
00623 
00624     if ($course->id == SITEID) {
00625         $courses[0] = '';
00626         if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
00627             foreach ($ccc as $cc) {
00628                 $courses[$cc->id] = $cc->shortname;
00629             }
00630         }
00631     } else {
00632         $courses[$course->id] = $course->shortname;
00633     }
00634 
00635     $count=0;
00636     $ldcache = array();
00637     $tt = getdate(time());
00638     $today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
00639 
00640     $strftimedatetime = get_string("strftimedatetime");
00641 
00642     $nroPages = ceil(count($logs)/(EXCELROWS-FIRSTUSEDEXCELROW+1));
00643     $filename = 'logs_'.userdate(time(),get_string('backupnameformat', 'langconfig'),99,false);
00644     $filename .= '.xls';
00645 
00646     $workbook = new MoodleExcelWorkbook('-');
00647     $workbook->send($filename);
00648 
00649     $worksheet = array();
00650     $headers = array(get_string('course'), get_string('time'), get_string('ip_address'),
00651                         get_string('fullnameuser'),    get_string('action'), get_string('info'));
00652 
00653     // Creating worksheets
00654     for ($wsnumber = 1; $wsnumber <= $nroPages; $wsnumber++) {
00655         $sheettitle = get_string('logs').' '.$wsnumber.'-'.$nroPages;
00656         $worksheet[$wsnumber] =& $workbook->add_worksheet($sheettitle);
00657         $worksheet[$wsnumber]->set_column(1, 1, 30);
00658         $worksheet[$wsnumber]->write_string(0, 0, get_string('savedat').
00659                                     userdate(time(), $strftimedatetime));
00660         $col = 0;
00661         foreach ($headers as $item) {
00662             $worksheet[$wsnumber]->write(FIRSTUSEDEXCELROW-1,$col,$item,'');
00663             $col++;
00664         }
00665     }
00666 
00667     if (empty($logs['logs'])) {
00668         $workbook->close();
00669         return true;
00670     }
00671 
00672     $formatDate =& $workbook->add_format();
00673     $formatDate->set_num_format(get_string('log_excel_date_format'));
00674 
00675     $row = FIRSTUSEDEXCELROW;
00676     $wsnumber = 1;
00677     $myxls =& $worksheet[$wsnumber];
00678     foreach ($logs['logs'] as $log) {
00679         if (isset($ldcache[$log->module][$log->action])) {
00680             $ld = $ldcache[$log->module][$log->action];
00681         } else {
00682             $ld = $DB->get_record('log_display', array('module'=>$log->module, 'action'=>$log->action));
00683             $ldcache[$log->module][$log->action] = $ld;
00684         }
00685         if ($ld && !empty($log->info)) {
00686             // ugly hack to make sure fullname is shown correctly
00687             if (($ld->mtable == 'user') and ($ld->field == $DB->sql_concat('firstname', "' '" , 'lastname'))) {
00688                 $log->info = fullname($DB->get_record($ld->mtable, array('id'=>$log->info)), true);
00689             } else {
00690                 $log->info = $DB->get_field($ld->mtable, $ld->field, array('id'=>$log->info));
00691             }
00692         }
00693 
00694         // Filter log->info
00695         $log->info = format_string($log->info);
00696         $log->info = strip_tags(urldecode($log->info));  // Some XSS protection
00697 
00698         if ($nroPages>1) {
00699             if ($row > EXCELROWS) {
00700                 $wsnumber++;
00701                 $myxls =& $worksheet[$wsnumber];
00702                 $row = FIRSTUSEDEXCELROW;
00703             }
00704         }
00705 
00706         $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
00707 
00708         $myxls->write($row, 0, format_string($courses[$log->course], true, array('context' => $coursecontext)), '');
00709         $myxls->write_date($row, 1, $log->time, $formatDate); // write_date() does conversion/timezone support. MDL-14934
00710         $myxls->write($row, 2, $log->ip, '');
00711         $fullname = fullname($log, has_capability('moodle/site:viewfullnames', $coursecontext));
00712         $myxls->write($row, 3, $fullname, '');
00713         $myxls->write($row, 4, $log->module.' '.$log->action, '');
00714         $myxls->write($row, 5, $log->info, '');
00715 
00716         $row++;
00717     }
00718 
00719     $workbook->close();
00720     return true;
00721 }
00722 
00723 function print_log_ods($course, $user, $date, $order='l.time DESC', $modname,
00724                         $modid, $modaction, $groupid) {
00725 
00726     global $CFG, $DB;
00727 
00728     require_once("$CFG->libdir/odslib.class.php");
00729 
00730     if (!$logs = build_logs_array($course, $user, $date, $order, '', '',
00731                        $modname, $modid, $modaction, $groupid)) {
00732         return false;
00733     }
00734 
00735     $courses = array();
00736 
00737     if ($course->id == SITEID) {
00738         $courses[0] = '';
00739         if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
00740             foreach ($ccc as $cc) {
00741                 $courses[$cc->id] = $cc->shortname;
00742             }
00743         }
00744     } else {
00745         $courses[$course->id] = $course->shortname;
00746     }
00747 
00748     $count=0;
00749     $ldcache = array();
00750     $tt = getdate(time());
00751     $today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
00752 
00753     $strftimedatetime = get_string("strftimedatetime");
00754 
00755     $nroPages = ceil(count($logs)/(EXCELROWS-FIRSTUSEDEXCELROW+1));
00756     $filename = 'logs_'.userdate(time(),get_string('backupnameformat', 'langconfig'),99,false);
00757     $filename .= '.ods';
00758 
00759     $workbook = new MoodleODSWorkbook('-');
00760     $workbook->send($filename);
00761 
00762     $worksheet = array();
00763     $headers = array(get_string('course'), get_string('time'), get_string('ip_address'),
00764                         get_string('fullnameuser'),    get_string('action'), get_string('info'));
00765 
00766     // Creating worksheets
00767     for ($wsnumber = 1; $wsnumber <= $nroPages; $wsnumber++) {
00768         $sheettitle = get_string('logs').' '.$wsnumber.'-'.$nroPages;
00769         $worksheet[$wsnumber] =& $workbook->add_worksheet($sheettitle);
00770         $worksheet[$wsnumber]->set_column(1, 1, 30);
00771         $worksheet[$wsnumber]->write_string(0, 0, get_string('savedat').
00772                                     userdate(time(), $strftimedatetime));
00773         $col = 0;
00774         foreach ($headers as $item) {
00775             $worksheet[$wsnumber]->write(FIRSTUSEDEXCELROW-1,$col,$item,'');
00776             $col++;
00777         }
00778     }
00779 
00780     if (empty($logs['logs'])) {
00781         $workbook->close();
00782         return true;
00783     }
00784 
00785     $formatDate =& $workbook->add_format();
00786     $formatDate->set_num_format(get_string('log_excel_date_format'));
00787 
00788     $row = FIRSTUSEDEXCELROW;
00789     $wsnumber = 1;
00790     $myxls =& $worksheet[$wsnumber];
00791     foreach ($logs['logs'] as $log) {
00792         if (isset($ldcache[$log->module][$log->action])) {
00793             $ld = $ldcache[$log->module][$log->action];
00794         } else {
00795             $ld = $DB->get_record('log_display', array('module'=>$log->module, 'action'=>$log->action));
00796             $ldcache[$log->module][$log->action] = $ld;
00797         }
00798         if ($ld && !empty($log->info)) {
00799             // ugly hack to make sure fullname is shown correctly
00800             if (($ld->mtable == 'user') and ($ld->field == $DB->sql_concat('firstname', "' '" , 'lastname'))) {
00801                 $log->info = fullname($DB->get_record($ld->mtable, array('id'=>$log->info)), true);
00802             } else {
00803                 $log->info = $DB->get_field($ld->mtable, $ld->field, array('id'=>$log->info));
00804             }
00805         }
00806 
00807         // Filter log->info
00808         $log->info = format_string($log->info);
00809         $log->info = strip_tags(urldecode($log->info));  // Some XSS protection
00810 
00811         if ($nroPages>1) {
00812             if ($row > EXCELROWS) {
00813                 $wsnumber++;
00814                 $myxls =& $worksheet[$wsnumber];
00815                 $row = FIRSTUSEDEXCELROW;
00816             }
00817         }
00818 
00819         $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
00820 
00821         $myxls->write_string($row, 0, format_string($courses[$log->course], true, array('context' => $coursecontext)));
00822         $myxls->write_date($row, 1, $log->time);
00823         $myxls->write_string($row, 2, $log->ip);
00824         $fullname = fullname($log, has_capability('moodle/site:viewfullnames', $coursecontext));
00825         $myxls->write_string($row, 3, $fullname);
00826         $myxls->write_string($row, 4, $log->module.' '.$log->action);
00827         $myxls->write_string($row, 5, $log->info);
00828 
00829         $row++;
00830     }
00831 
00832     $workbook->close();
00833     return true;
00834 }
00835 
00836 
00837 function print_overview($courses, array $remote_courses=array()) {
00838     global $CFG, $USER, $DB, $OUTPUT;
00839 
00840     $htmlarray = array();
00841     if ($modules = $DB->get_records('modules')) {
00842         foreach ($modules as $mod) {
00843             if (file_exists(dirname(dirname(__FILE__)).'/mod/'.$mod->name.'/lib.php')) {
00844                 include_once(dirname(dirname(__FILE__)).'/mod/'.$mod->name.'/lib.php');
00845                 $fname = $mod->name.'_print_overview';
00846                 if (function_exists($fname)) {
00847                     $fname($courses,$htmlarray);
00848                 }
00849             }
00850         }
00851     }
00852     foreach ($courses as $course) {
00853         $fullname = format_string($course->fullname, true, array('context' => get_context_instance(CONTEXT_COURSE, $course->id)));
00854         echo $OUTPUT->box_start('coursebox');
00855         $attributes = array('title' => s($fullname));
00856         if (empty($course->visible)) {
00857             $attributes['class'] = 'dimmed';
00858         }
00859         echo $OUTPUT->heading(html_writer::link(
00860             new moodle_url('/course/view.php', array('id' => $course->id)), $fullname, $attributes), 3);
00861         if (array_key_exists($course->id,$htmlarray)) {
00862             foreach ($htmlarray[$course->id] as $modname => $html) {
00863                 echo $html;
00864             }
00865         }
00866         echo $OUTPUT->box_end();
00867     }
00868 
00869     if (!empty($remote_courses)) {
00870         echo $OUTPUT->heading(get_string('remotecourses', 'mnet'));
00871     }
00872     foreach ($remote_courses as $course) {
00873         echo $OUTPUT->box_start('coursebox');
00874         $attributes = array('title' => s($course->fullname));
00875         echo $OUTPUT->heading(html_writer::link(
00876             new moodle_url('/auth/mnet/jump.php', array('hostid' => $course->hostid, 'wantsurl' => '/course/view.php?id='.$course->remoteid)),
00877             format_string($course->shortname),
00878             $attributes) . ' (' . format_string($course->hostname) . ')', 3);
00879         echo $OUTPUT->box_end();
00880     }
00881 }
00882 
00883 
00888 function print_recent_activity($course) {
00889     // $course is an object
00890     global $CFG, $USER, $SESSION, $DB, $OUTPUT;
00891 
00892     $context = get_context_instance(CONTEXT_COURSE, $course->id);
00893 
00894     $viewfullnames = has_capability('moodle/site:viewfullnames', $context);
00895 
00896     $timestart = round(time() - COURSE_MAX_RECENT_PERIOD, -2); // better db caching for guests - 100 seconds
00897 
00898     if (!isguestuser()) {
00899         if (!empty($USER->lastcourseaccess[$course->id])) {
00900             if ($USER->lastcourseaccess[$course->id] > $timestart) {
00901                 $timestart = $USER->lastcourseaccess[$course->id];
00902             }
00903         }
00904     }
00905 
00906     echo '<div class="activitydate">';
00907     echo get_string('activitysince', '', userdate($timestart));
00908     echo '</div>';
00909     echo '<div class="activityhead">';
00910 
00911     echo '<a href="'.$CFG->wwwroot.'/course/recent.php?id='.$course->id.'">'.get_string('recentactivityreport').'</a>';
00912 
00913     echo "</div>\n";
00914 
00915     $content = false;
00916 
00918 
00919     $users = get_recent_enrolments($course->id, $timestart);
00920 
00921     //Accessibility: new users now appear in an <OL> list.
00922     if ($users) {
00923         echo '<div class="newusers">';
00924         echo $OUTPUT->heading(get_string("newusers").':', 3);
00925         $content = true;
00926         echo "<ol class=\"list\">\n";
00927         foreach ($users as $user) {
00928             $fullname = fullname($user, $viewfullnames);
00929             echo '<li class="name"><a href="'."$CFG->wwwroot/user/view.php?id=$user->id&amp;course=$course->id\">$fullname</a></li>\n";
00930         }
00931         echo "</ol>\n</div>\n";
00932     }
00933 
00935 
00936     $modinfo =& get_fast_modinfo($course);
00937 
00938     $changelist = array();
00939 
00940     $logs = $DB->get_records_select('log', "time > ? AND course = ? AND
00941                                             module = 'course' AND
00942                                             (action = 'add mod' OR action = 'update mod' OR action = 'delete mod')",
00943                                     array($timestart, $course->id), "id ASC");
00944 
00945     if ($logs) {
00946         $actions  = array('add mod', 'update mod', 'delete mod');
00947         $newgones = array(); // added and later deleted items
00948         foreach ($logs as $key => $log) {
00949             if (!in_array($log->action, $actions)) {
00950                 continue;
00951             }
00952             $info = explode(' ', $log->info);
00953 
00954             // note: in most cases I replaced hardcoding of label with use of
00955             // $cm->has_view() but it was not possible to do this here because
00956             // we don't necessarily have the $cm for it
00957             if ($info[0] == 'label') {     // Labels are ignored in recent activity
00958                 continue;
00959             }
00960 
00961             if (count($info) != 2) {
00962                 debugging("Incorrect log entry info: id = ".$log->id, DEBUG_DEVELOPER);
00963                 continue;
00964             }
00965 
00966             $modname    = $info[0];
00967             $instanceid = $info[1];
00968 
00969             if ($log->action == 'delete mod') {
00970                 // unfortunately we do not know if the mod was visible
00971                 if (!array_key_exists($log->info, $newgones)) {
00972                     $strdeleted = get_string('deletedactivity', 'moodle', get_string('modulename', $modname));
00973                     $changelist[$log->info] = array ('operation' => 'delete', 'text' => $strdeleted);
00974                 }
00975             } else {
00976                 if (!isset($modinfo->instances[$modname][$instanceid])) {
00977                     if ($log->action == 'add mod') {
00978                         // do not display added and later deleted activities
00979                         $newgones[$log->info] = true;
00980                     }
00981                     continue;
00982                 }
00983                 $cm = $modinfo->instances[$modname][$instanceid];
00984                 if (!$cm->uservisible) {
00985                     continue;
00986                 }
00987 
00988                 if ($log->action == 'add mod') {
00989                     $stradded = get_string('added', 'moodle', get_string('modulename', $modname));
00990                     $changelist[$log->info] = array('operation' => 'add', 'text' => "$stradded:<br /><a href=\"$CFG->wwwroot/mod/$cm->modname/view.php?id={$cm->id}\">".format_string($cm->name, true)."</a>");
00991 
00992                 } else if ($log->action == 'update mod' and empty($changelist[$log->info])) {
00993                     $strupdated = get_string('updated', 'moodle', get_string('modulename', $modname));
00994                     $changelist[$log->info] = array('operation' => 'update', 'text' => "$strupdated:<br /><a href=\"$CFG->wwwroot/mod/$cm->modname/view.php?id={$cm->id}\">".format_string($cm->name, true)."</a>");
00995                 }
00996             }
00997         }
00998     }
00999 
01000     if (!empty($changelist)) {
01001         echo $OUTPUT->heading(get_string("courseupdates").':', 3);
01002         $content = true;
01003         foreach ($changelist as $changeinfo => $change) {
01004             echo '<p class="activity">'.$change['text'].'</p>';
01005         }
01006     }
01007 
01009 
01010     $usedmodules = array();
01011     foreach($modinfo->cms as $cm) {
01012         if (isset($usedmodules[$cm->modname])) {
01013             continue;
01014         }
01015         if (!$cm->uservisible) {
01016             continue;
01017         }
01018         $usedmodules[$cm->modname] = $cm->modname;
01019     }
01020 
01021     foreach ($usedmodules as $modname) {      // Each module gets it's own logs and prints them
01022         if (file_exists($CFG->dirroot.'/mod/'.$modname.'/lib.php')) {
01023             include_once($CFG->dirroot.'/mod/'.$modname.'/lib.php');
01024             $print_recent_activity = $modname.'_print_recent_activity';
01025             if (function_exists($print_recent_activity)) {
01026                 // NOTE: original $isteacher (second parameter below) was replaced with $viewfullnames!
01027                 $content = $print_recent_activity($course, $viewfullnames, $timestart) || $content;
01028             }
01029         } else {
01030             debugging("Missing lib.php in lib/{$modname} - please reinstall files or uninstall the module");
01031         }
01032     }
01033 
01034     if (! $content) {
01035         echo '<p class="message">'.get_string('nothingnew').'</p>';
01036     }
01037 }
01038 
01043 function get_array_of_activities($courseid) {
01044 //  cm - course module id
01045 //  mod - name of the module (eg forum)
01046 //  section - the number of the section (eg week or topic)
01047 //  name - the name of the instance
01048 //  visible - is the instance visible or not
01049 //  groupingid - grouping id
01050 //  groupmembersonly - is this instance visible to group members only
01051 //  extra - contains extra string to include in any link
01052     global $CFG, $DB;
01053     if(!empty($CFG->enableavailability)) {
01054         require_once($CFG->libdir.'/conditionlib.php');
01055     }
01056 
01057     $course = $DB->get_record('course', array('id'=>$courseid));
01058 
01059     if (empty($course)) {
01060         throw new moodle_exception('courseidnotfound');
01061     }
01062 
01063     $mod = array();
01064 
01065     $rawmods = get_course_mods($courseid);
01066     if (empty($rawmods)) {
01067         return $mod; // always return array
01068     }
01069 
01070     if ($sections = $DB->get_records("course_sections", array("course"=>$courseid), "section ASC")) {
01071        foreach ($sections as $section) {
01072            if (!empty($section->sequence)) {
01073                $sequence = explode(",", $section->sequence);
01074                foreach ($sequence as $seq) {
01075                    if (empty($rawmods[$seq])) {
01076                        continue;
01077                    }
01078                    $mod[$seq] = new stdClass();
01079                    $mod[$seq]->id               = $rawmods[$seq]->instance;
01080                    $mod[$seq]->cm               = $rawmods[$seq]->id;
01081                    $mod[$seq]->mod              = $rawmods[$seq]->modname;
01082 
01083                     // Oh dear. Inconsistent names left here for backward compatibility.
01084                    $mod[$seq]->section          = $section->section;
01085                    $mod[$seq]->sectionid        = $rawmods[$seq]->section;
01086 
01087                    $mod[$seq]->module           = $rawmods[$seq]->module;
01088                    $mod[$seq]->added            = $rawmods[$seq]->added;
01089                    $mod[$seq]->score            = $rawmods[$seq]->score;
01090                    $mod[$seq]->idnumber         = $rawmods[$seq]->idnumber;
01091                    $mod[$seq]->visible          = $rawmods[$seq]->visible;
01092                    $mod[$seq]->visibleold       = $rawmods[$seq]->visibleold;
01093                    $mod[$seq]->groupmode        = $rawmods[$seq]->groupmode;
01094                    $mod[$seq]->groupingid       = $rawmods[$seq]->groupingid;
01095                    $mod[$seq]->groupmembersonly = $rawmods[$seq]->groupmembersonly;
01096                    $mod[$seq]->indent           = $rawmods[$seq]->indent;
01097                    $mod[$seq]->completion       = $rawmods[$seq]->completion;
01098                    $mod[$seq]->extra            = "";
01099                    $mod[$seq]->completiongradeitemnumber =
01100                            $rawmods[$seq]->completiongradeitemnumber;
01101                    $mod[$seq]->completionview   = $rawmods[$seq]->completionview;
01102                    $mod[$seq]->completionexpected = $rawmods[$seq]->completionexpected;
01103                    $mod[$seq]->availablefrom    = $rawmods[$seq]->availablefrom;
01104                    $mod[$seq]->availableuntil   = $rawmods[$seq]->availableuntil;
01105                    $mod[$seq]->showavailability = $rawmods[$seq]->showavailability;
01106                    $mod[$seq]->showdescription  = $rawmods[$seq]->showdescription;
01107                    if (!empty($CFG->enableavailability)) {
01108                        condition_info::fill_availability_conditions($rawmods[$seq]);
01109                        $mod[$seq]->conditionscompletion = $rawmods[$seq]->conditionscompletion;
01110                        $mod[$seq]->conditionsgrade  = $rawmods[$seq]->conditionsgrade;
01111                    }
01112 
01113                    $modname = $mod[$seq]->mod;
01114                    $functionname = $modname."_get_coursemodule_info";
01115 
01116                    if (!file_exists("$CFG->dirroot/mod/$modname/lib.php")) {
01117                        continue;
01118                    }
01119 
01120                    include_once("$CFG->dirroot/mod/$modname/lib.php");
01121 
01122                    if ($hasfunction = function_exists($functionname)) {
01123                        if ($info = $functionname($rawmods[$seq])) {
01124                            if (!empty($info->icon)) {
01125                                $mod[$seq]->icon = $info->icon;
01126                            }
01127                            if (!empty($info->iconcomponent)) {
01128                                $mod[$seq]->iconcomponent = $info->iconcomponent;
01129                            }
01130                            if (!empty($info->name)) {
01131                                $mod[$seq]->name = $info->name;
01132                            }
01133                            if ($info instanceof cached_cm_info) {
01134                                // When using cached_cm_info you can include three new fields
01135                                // that aren't available for legacy code
01136                                if (!empty($info->content)) {
01137                                    $mod[$seq]->content = $info->content;
01138                                }
01139                                if (!empty($info->extraclasses)) {
01140                                    $mod[$seq]->extraclasses = $info->extraclasses;
01141                                }
01142                                if (!empty($info->iconurl)) {
01143                                    $mod[$seq]->iconurl = $info->iconurl;
01144                                }
01145                                if (!empty($info->onclick)) {
01146                                    $mod[$seq]->onclick = $info->onclick;
01147                                }
01148                                if (!empty($info->customdata)) {
01149                                    $mod[$seq]->customdata = $info->customdata;
01150                                }
01151                            } else {
01152                                // When using a stdclass, the (horrible) deprecated ->extra field
01153                                // is available for BC
01154                                if (!empty($info->extra)) {
01155                                    $mod[$seq]->extra = $info->extra;
01156                                }
01157                            }
01158                        }
01159                    }
01160                    // When there is no modname_get_coursemodule_info function,
01161                    // but showdescriptions is enabled, then we use the 'intro'
01162                    // and 'introformat' fields in the module table
01163                    if (!$hasfunction && $rawmods[$seq]->showdescription) {
01164                        if ($modvalues = $DB->get_record($rawmods[$seq]->modname,
01165                                array('id' => $rawmods[$seq]->instance), 'name, intro, introformat')) {
01166                            // Set content from intro and introformat. Filters are disabled
01167                            // because we  filter it with format_text at display time
01168                            $mod[$seq]->content = format_module_intro($rawmods[$seq]->modname,
01169                                    $modvalues, $rawmods[$seq]->id, false);
01170 
01171                            // To save making another query just below, put name in here
01172                            $mod[$seq]->name = $modvalues->name;
01173                        }
01174                    }
01175                    if (!isset($mod[$seq]->name)) {
01176                        $mod[$seq]->name = $DB->get_field($rawmods[$seq]->modname, "name", array("id"=>$rawmods[$seq]->instance));
01177                    }
01178 
01179                    // Minimise the database size by unsetting default options when they are
01180                    // 'empty'. This list corresponds to code in the cm_info constructor.
01181                    foreach (array('idnumber', 'groupmode', 'groupingid', 'groupmembersonly',
01182                            'indent', 'completion', 'extra', 'extraclasses', 'iconurl', 'onclick', 'content',
01183                            'icon', 'iconcomponent', 'customdata', 'showavailability', 'availablefrom',
01184                            'availableuntil', 'conditionscompletion', 'conditionsgrade',
01185                            'completionview', 'completionexpected', 'score', 'showdescription')
01186                            as $property) {
01187                        if (property_exists($mod[$seq], $property) &&
01188                                empty($mod[$seq]->{$property})) {
01189                            unset($mod[$seq]->{$property});
01190                        }
01191                    }
01192                    // Special case: this value is usually set to null, but may be 0
01193                    if (property_exists($mod[$seq], 'completiongradeitemnumber') &&
01194                            is_null($mod[$seq]->completiongradeitemnumber)) {
01195                        unset($mod[$seq]->completiongradeitemnumber);
01196                    }
01197                }
01198             }
01199         }
01200     }
01201     return $mod;
01202 }
01203 
01204 
01208 function get_all_mods($courseid, &$mods, &$modnames, &$modnamesplural, &$modnamesused) {
01209     global $CFG, $DB, $COURSE;
01210 
01211     $mods          = array();    // course modules indexed by id
01212     $modnames      = array();    // all course module names (except resource!)
01213     $modnamesplural= array();    // all course module names (plural form)
01214     $modnamesused  = array();    // course module names used
01215 
01216     if ($allmods = $DB->get_records("modules")) {
01217         foreach ($allmods as $mod) {
01218             if (!file_exists("$CFG->dirroot/mod/$mod->name/lib.php")) {
01219                 continue;
01220             }
01221             if ($mod->visible) {
01222                 $modnames[$mod->name] = get_string("modulename", "$mod->name");
01223                 $modnamesplural[$mod->name] = get_string("modulenameplural", "$mod->name");
01224             }
01225         }
01226         collatorlib::asort($modnames);
01227     } else {
01228         print_error("nomodules", 'debug');
01229     }
01230 
01231     $course = ($courseid==$COURSE->id) ? $COURSE : $DB->get_record('course',array('id'=>$courseid));
01232     $modinfo = get_fast_modinfo($course);
01233 
01234     if ($rawmods=$modinfo->cms) {
01235         foreach($rawmods as $mod) {    // Index the mods
01236             if (empty($modnames[$mod->modname])) {
01237                 continue;
01238             }
01239             $mods[$mod->id] = $mod;
01240             $mods[$mod->id]->modfullname = $modnames[$mod->modname];
01241             if (!$mod->visible and !has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_COURSE, $courseid))) {
01242                 continue;
01243             }
01244             // Check groupings
01245             if (!groups_course_module_visible($mod)) {
01246                 continue;
01247             }
01248             $modnamesused[$mod->modname] = $modnames[$mod->modname];
01249         }
01250         if ($modnamesused) {
01251             collatorlib::asort($modnamesused);
01252         }
01253     }
01254 }
01255 
01267 function get_all_sections($courseid) {
01268     global $DB;
01269     static $coursesections = array();
01270     if (!array_key_exists($courseid, $coursesections)) {
01271         $coursesections[$courseid] = $DB->get_records("course_sections", array("course"=>"$courseid"), "section",
01272                            "section, id, course, name, summary, summaryformat, sequence, visible");
01273     }
01274     return $coursesections[$courseid];
01275 }
01276 
01284 function course_get_display($courseid) {
01285     global $USER, $DB;
01286 
01287     if (!isloggedin() or isguestuser()) {
01288         //do not get settings in db for guests
01289         return 0; //return the implicit setting
01290     }
01291 
01292     if (!isset($USER->display[$courseid])) {
01293         if (!$display = $DB->get_field('course_display', 'display', array('userid' => $USER->id, 'course'=>$courseid))) {
01294             $display = 0; // all sections option is not stored in DB, this makes the table much smaller
01295         }
01296         //use display cache for one course only - we need to keep session small
01297         $USER->display = array($courseid => $display);
01298     }
01299 
01300     return $USER->display[$courseid];
01301 }
01302 
01310 function course_set_display($courseid, $display) {
01311     global $USER, $DB;
01312 
01313     if ($display === 'all' or empty($display)) {
01314         $display = 0;
01315     }
01316 
01317     if (!isloggedin() or isguestuser()) {
01318         //do not store settings in db for guests
01319         return 0;
01320     }
01321 
01322     if ($display == 0) {
01323         //show all, do not store anything in database
01324         $DB->delete_records('course_display', array('userid' => $USER->id, 'course' => $courseid));
01325 
01326     } else {
01327         if ($DB->record_exists('course_display', array('userid' => $USER->id, 'course' => $courseid))) {
01328             $DB->set_field('course_display', 'display', $display, array('userid' => $USER->id, 'course' => $courseid));
01329         } else {
01330             $record = new stdClass();
01331             $record->userid = $USER->id;
01332             $record->course = $courseid;
01333             $record->display = $display;
01334             $DB->insert_record('course_display', $record);
01335         }
01336     }
01337 
01338     //use display cache for one course only - we need to keep session small
01339     $USER->display = array($courseid => $display);
01340 
01341     return $display;
01342 }
01343 
01348 function set_section_visible($courseid, $sectionnumber, $visibility) {
01349     global $DB;
01350 
01351     if ($section = $DB->get_record("course_sections", array("course"=>$courseid, "section"=>$sectionnumber))) {
01352         $DB->set_field("course_sections", "visible", "$visibility", array("id"=>$section->id));
01353         if (!empty($section->sequence)) {
01354             $modules = explode(",", $section->sequence);
01355             foreach ($modules as $moduleid) {
01356                 set_coursemodule_visible($moduleid, $visibility, true);
01357             }
01358         }
01359         rebuild_course_cache($courseid);
01360     }
01361 }
01362 
01376 function get_print_section_cm_text(cm_info $cm, $course) {
01377     global $OUTPUT;
01378 
01379     // Get content from modinfo if specified. Content displays either
01380     // in addition to the standard link (below), or replaces it if
01381     // the link is turned off by setting ->url to null.
01382     if (($content = $cm->get_content()) !== '') {
01383         // Improve filter performance by preloading filter setttings for all
01384         // activities on the course (this does nothing if called multiple
01385         // times)
01386         filter_preload_activities($cm->get_modinfo());
01387 
01388         // Get module context
01389         $modulecontext = get_context_instance(CONTEXT_MODULE, $cm->id);
01390         $labelformatoptions = new stdClass();
01391         $labelformatoptions->noclean = true;
01392         $labelformatoptions->overflowdiv = true;
01393         $labelformatoptions->context = $modulecontext;
01394         $content = format_text($content, FORMAT_HTML, $labelformatoptions);
01395     } else {
01396         $content = '';
01397     }
01398 
01399     // Get course context
01400     $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
01401     $stringoptions = new stdClass;
01402     $stringoptions->context = $coursecontext;
01403     $instancename = format_string($cm->name, true,  $stringoptions);
01404     return array($content, $instancename);
01405 }
01406 
01410 function print_section($course, $section, $mods, $modnamesused, $absolute=false, $width="100%", $hidecompletion=false) {
01411     global $CFG, $USER, $DB, $PAGE, $OUTPUT;
01412 
01413     static $initialised;
01414 
01415     static $groupbuttons;
01416     static $groupbuttonslink;
01417     static $isediting;
01418     static $ismoving;
01419     static $strmovehere;
01420     static $strmovefull;
01421     static $strunreadpostsone;
01422     static $groupings;
01423     static $modulenames;
01424 
01425     if (!isset($initialised)) {
01426         $groupbuttons     = ($course->groupmode or (!$course->groupmodeforce));
01427         $groupbuttonslink = (!$course->groupmodeforce);
01428         $isediting        = $PAGE->user_is_editing();
01429         $ismoving         = $isediting && ismoving($course->id);
01430         if ($ismoving) {
01431             $strmovehere  = get_string("movehere");
01432             $strmovefull  = strip_tags(get_string("movefull", "", "'$USER->activitycopyname'"));
01433         }
01434         $modulenames      = array();
01435         $initialised = true;
01436     }
01437 
01438     $tl = textlib_get_instance();
01439 
01440     $modinfo = get_fast_modinfo($course);
01441     $completioninfo = new completion_info($course);
01442 
01443     //Accessibility: replace table with list <ul>, but don't output empty list.
01444     if (!empty($section->sequence)) {
01445 
01446         // Fix bug #5027, don't want style=\"width:$width\".
01447         echo "<ul class=\"section img-text\">\n";
01448         $sectionmods = explode(",", $section->sequence);
01449 
01450         foreach ($sectionmods as $modnumber) {
01451             if (empty($mods[$modnumber])) {
01452                 continue;
01453             }
01454 
01458             $mod = $mods[$modnumber];
01459 
01460             if ($ismoving and $mod->id == $USER->activitycopy) {
01461                 // do not display moving mod
01462                 continue;
01463             }
01464 
01465             if (isset($modinfo->cms[$modnumber])) {
01466                 // We can continue (because it will not be displayed at all)
01467                 // if:
01468                 // 1) The activity is not visible to users
01469                 // and
01470                 // 2a) The 'showavailability' option is not set (if that is set,
01471                 //     we need to display the activity so we can show
01472                 //     availability info)
01473                 // or
01474                 // 2b) The 'availableinfo' is empty, i.e. the activity was
01475                 //     hidden in a way that leaves no info, such as using the
01476                 //     eye icon.
01477                 if (!$modinfo->cms[$modnumber]->uservisible &&
01478                     (empty($modinfo->cms[$modnumber]->showavailability) ||
01479                       empty($modinfo->cms[$modnumber]->availableinfo))) {
01480                     // visibility shortcut
01481                     continue;
01482                 }
01483             } else {
01484                 if (!file_exists("$CFG->dirroot/mod/$mod->modname/lib.php")) {
01485                     // module not installed
01486                     continue;
01487                 }
01488                 if (!coursemodule_visible_for_user($mod) &&
01489                     empty($mod->showavailability)) {
01490                     // full visibility check
01491                     continue;
01492                 }
01493             }
01494 
01495             if (!isset($modulenames[$mod->modname])) {
01496                 $modulenames[$mod->modname] = get_string('modulename', $mod->modname);
01497             }
01498             $modulename = $modulenames[$mod->modname];
01499 
01500             // In some cases the activity is visible to user, but it is
01501             // dimmed. This is done if viewhiddenactivities is true and if:
01502             // 1. the activity is not visible, or
01503             // 2. the activity has dates set which do not include current, or
01504             // 3. the activity has any other conditions set (regardless of whether
01505             //    current user meets them)
01506             $canviewhidden = has_capability(
01507                 'moodle/course:viewhiddenactivities',
01508                 get_context_instance(CONTEXT_MODULE, $mod->id));
01509             $accessiblebutdim = false;
01510             if ($canviewhidden) {
01511                 $accessiblebutdim = !$mod->visible;
01512                 if (!empty($CFG->enableavailability)) {
01513                     $accessiblebutdim = $accessiblebutdim ||
01514                         $mod->availablefrom > time() ||
01515                         ($mod->availableuntil && $mod->availableuntil < time()) ||
01516                         count($mod->conditionsgrade) > 0 ||
01517                         count($mod->conditionscompletion) > 0;
01518                 }
01519             }
01520 
01521             $liclasses = array();
01522             $liclasses[] = 'activity';
01523             $liclasses[] = $mod->modname;
01524             $liclasses[] = 'modtype_'.$mod->modname;
01525             $extraclasses = $mod->get_extra_classes();
01526             if ($extraclasses) {
01527                 $liclasses = array_merge($liclasses, explode(' ', $extraclasses));
01528             }
01529             echo html_writer::start_tag('li', array('class'=>join(' ', $liclasses), 'id'=>'module-'.$modnumber));
01530             if ($ismoving) {
01531                 echo '<a title="'.$strmovefull.'"'.
01532                      ' href="'.$CFG->wwwroot.'/course/mod.php?moveto='.$mod->id.'&amp;sesskey='.sesskey().'">'.
01533                      '<img class="movetarget" src="'.$OUTPUT->pix_url('movehere') . '" '.
01534                      ' alt="'.$strmovehere.'" /></a><br />
01535                      ';
01536             }
01537 
01538             $classes = array('mod-indent');
01539             if (!empty($mod->indent)) {
01540                 $classes[] = 'mod-indent-'.$mod->indent;
01541                 if ($mod->indent > 15) {
01542                     $classes[] = 'mod-indent-huge';
01543                 }
01544             }
01545             echo html_writer::start_tag('div', array('class'=>join(' ', $classes)));
01546 
01547             // Get data about this course-module
01548             list($content, $instancename) =
01549                     get_print_section_cm_text($modinfo->cms[$modnumber], $course);
01550 
01551             //Accessibility: for files get description via icon, this is very ugly hack!
01552             $altname = '';
01553             $altname = $mod->modfullname;
01554             if (!empty($customicon)) {
01555                 $archetype = plugin_supports('mod', $mod->modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
01556                 if ($archetype == MOD_ARCHETYPE_RESOURCE) {
01557                     $mimetype = mimeinfo_from_icon('type', $customicon);
01558                     $altname = get_mimetype_description($mimetype);
01559                 }
01560             }
01561             // Avoid unnecessary duplication: if e.g. a forum name already
01562             // includes the word forum (or Forum, etc) then it is unhelpful
01563             // to include that in the accessible description that is added.
01564             if (false !== strpos($tl->strtolower($instancename),
01565                     $tl->strtolower($altname))) {
01566                 $altname = '';
01567             }
01568             // File type after name, for alphabetic lists (screen reader).
01569             if ($altname) {
01570                 $altname = get_accesshide(' '.$altname);
01571             }
01572 
01573             // We may be displaying this just in order to show information
01574             // about visibility, without the actual link
01575             $contentpart = '';
01576             if ($mod->uservisible) {
01577                 // Nope - in this case the link is fully working for user
01578                 $linkclasses = '';
01579                 $textclasses = '';
01580                 if ($accessiblebutdim) {
01581                     $linkclasses .= ' dimmed';
01582                     $textclasses .= ' dimmed_text';
01583                     $accesstext = '<span class="accesshide">'.
01584                         get_string('hiddenfromstudents').': </span>';
01585                 } else {
01586                     $accesstext = '';
01587                 }
01588                 if ($linkclasses) {
01589                     $linkcss = 'class="' . trim($linkclasses) . '" ';
01590                 } else {
01591                     $linkcss = '';
01592                 }
01593                 if ($textclasses) {
01594                     $textcss = 'class="' . trim($textclasses) . '" ';
01595                 } else {
01596                     $textcss = '';
01597                 }
01598 
01599                 // Get on-click attribute value if specified
01600                 $onclick = $mod->get_on_click();
01601                 if ($onclick) {
01602                     $onclick = ' onclick="' . $onclick . '"';
01603                 }
01604 
01605                 if ($url = $mod->get_url()) {
01606                     // Display link itself
01607                     echo '<a ' . $linkcss . $mod->extra . $onclick .
01608                             ' href="' . $url . '"><img src="' . $mod->get_icon_url() .
01609                             '" class="activityicon" alt="' .
01610                             $modulename . '" /> ' .
01611                             $accesstext . '<span class="instancename">' .
01612                             $instancename . $altname . '</span></a>';
01613 
01614                     // If specified, display extra content after link
01615                     if ($content) {
01616                         $contentpart = '<div class="' . trim('contentafterlink' . $textclasses) .
01617                                 '">' . $content . '</div>';
01618                     }
01619                 } else {
01620                     // No link, so display only content
01621                     $contentpart = '<div ' . $textcss . $mod->extra . '>' .
01622                             $accesstext . $content . '</div>';
01623                 }
01624 
01625                 if (!empty($mod->groupingid) && has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
01626                     if (!isset($groupings)) {
01627                         $groupings = groups_get_all_groupings($course->id);
01628                     }
01629                     echo " <span class=\"groupinglabel\">(".format_string($groupings[$mod->groupingid]->name).')</span>';
01630                 }
01631             } else {
01632                 $textclasses = $extraclasses;
01633                 $textclasses .= ' dimmed_text';
01634                 if ($textclasses) {
01635                     $textcss = 'class="' . trim($textclasses) . '" ';
01636                 } else {
01637                     $textcss = '';
01638                 }
01639                 $accesstext = '<span class="accesshide">' .
01640                         get_string('notavailableyet', 'condition') .
01641                         ': </span>';
01642 
01643                 if ($url = $mod->get_url()) {
01644                     // Display greyed-out text of link
01645                     echo '<div ' . $textcss . $mod->extra .
01646                             ' >' . '<img src="' . $mod->get_icon_url() .
01647                             '" class="activityicon" alt="' .
01648                             $modulename .
01649                             '" /> <span>'. $instancename . $altname .
01650                             '</span></div>';
01651 
01652                     // Do not display content after link when it is greyed out like this.
01653                 } else {
01654                     // No link, so display only content (also greyed)
01655                     $contentpart = '<div ' . $textcss . $mod->extra . '>' .
01656                             $accesstext . $content . '</div>';
01657                 }
01658             }
01659 
01660             // Module can put text after the link (e.g. forum unread)
01661             echo $mod->get_after_link();
01662 
01663             // If there is content but NO link (eg label), then display the
01664             // content here (BEFORE any icons). In this case cons must be
01665             // displayed after the content so that it makes more sense visually
01666             // and for accessibility reasons, e.g. if you have a one-line label
01667             // it should work similarly (at least in terms of ordering) to an
01668             // activity.
01669             if (empty($url)) {
01670                 echo $contentpart;
01671             }
01672 
01673             if ($isediting) {
01674                 if ($groupbuttons and plugin_supports('mod', $mod->modname, FEATURE_GROUPS, 0)) {
01675                     if (! $mod->groupmodelink = $groupbuttonslink) {
01676                         $mod->groupmode = $course->groupmode;
01677                     }
01678 
01679                 } else {
01680                     $mod->groupmode = false;
01681                 }
01682                 echo '&nbsp;&nbsp;';
01683                 echo make_editing_buttons($mod, $absolute, true, $mod->indent, $section->section);
01684                 echo $mod->get_after_edit_icons();
01685             }
01686 
01687             // Completion
01688             $completion = $hidecompletion
01689                 ? COMPLETION_TRACKING_NONE
01690                 : $completioninfo->is_enabled($mod);
01691             if ($completion!=COMPLETION_TRACKING_NONE && isloggedin() &&
01692                 !isguestuser() && $mod->uservisible) {
01693                 $completiondata = $completioninfo->get_data($mod,true);
01694                 $completionicon = '';
01695                 if ($isediting) {
01696                     switch ($completion) {
01697                         case COMPLETION_TRACKING_MANUAL :
01698                             $completionicon = 'manual-enabled'; break;
01699                         case COMPLETION_TRACKING_AUTOMATIC :
01700                             $completionicon = 'auto-enabled'; break;
01701                         default: // wtf
01702                     }
01703                 } else if ($completion==COMPLETION_TRACKING_MANUAL) {
01704                     switch($completiondata->completionstate) {
01705                         case COMPLETION_INCOMPLETE:
01706                             $completionicon = 'manual-n'; break;
01707                         case COMPLETION_COMPLETE:
01708                             $completionicon = 'manual-y'; break;
01709                     }
01710                 } else { // Automatic
01711                     switch($completiondata->completionstate) {
01712                         case COMPLETION_INCOMPLETE:
01713                             $completionicon = 'auto-n'; break;
01714                         case COMPLETION_COMPLETE:
01715                             $completionicon = 'auto-y'; break;
01716                         case COMPLETION_COMPLETE_PASS:
01717                             $completionicon = 'auto-pass'; break;
01718                         case COMPLETION_COMPLETE_FAIL:
01719                             $completionicon = 'auto-fail'; break;
01720                     }
01721                 }
01722                 if ($completionicon) {
01723                     $imgsrc = $OUTPUT->pix_url('i/completion-'.$completionicon);
01724                     $imgalt = s(get_string('completion-alt-'.$completionicon, 'completion'));
01725                     if ($completion == COMPLETION_TRACKING_MANUAL && !$isediting) {
01726                         $imgtitle = s(get_string('completion-title-'.$completionicon, 'completion'));
01727                         $newstate =
01728                             $completiondata->completionstate==COMPLETION_COMPLETE
01729                             ? COMPLETION_INCOMPLETE
01730                             : COMPLETION_COMPLETE;
01731                         // In manual mode the icon is a toggle form...
01732 
01733                         // If this completion state is used by the
01734                         // conditional activities system, we need to turn
01735                         // off the JS.
01736                         if (!empty($CFG->enableavailability) &&
01737                             condition_info::completion_value_used_as_condition($course, $mod)) {
01738                             $extraclass = ' preventjs';
01739                         } else {
01740                             $extraclass = '';
01741                         }
01742                         echo "
01743 <form class='togglecompletion$extraclass' method='post' action='".$CFG->wwwroot."/course/togglecompletion.php'><div>
01744 <input type='hidden' name='id' value='{$mod->id}' />
01745 <input type='hidden' name='sesskey' value='".sesskey()."' />
01746 <input type='hidden' name='completionstate' value='$newstate' />
01747 <input type='image' src='$imgsrc' alt='$imgalt' title='$imgtitle' />
01748 </div></form>";
01749                     } else {
01750                         // In auto mode, or when editing, the icon is just an image
01751                         echo "<span class='autocompletion'>";
01752                         echo "<img src='$imgsrc' alt='$imgalt' title='$imgalt' /></span>";
01753                     }
01754                 }
01755             }
01756 
01757             // If there is content AND a link, then display the content here
01758             // (AFTER any icons). Otherwise it was displayed before
01759             if (!empty($url)) {
01760                 echo $contentpart;
01761             }
01762 
01763             // Show availability information (for someone who isn't allowed to
01764             // see the activity itself, or for staff)
01765             if (!$mod->uservisible) {
01766                 echo '<div class="availabilityinfo">'.$mod->availableinfo.'</div>';
01767             } else if ($canviewhidden && !empty($CFG->enableavailability)) {
01768                 $ci = new condition_info($mod);
01769                 $fullinfo = $ci->get_full_information();
01770                 if($fullinfo) {
01771                     echo '<div class="availabilityinfo">'.get_string($mod->showavailability
01772                         ? 'userrestriction_visible'
01773                         : 'userrestriction_hidden','condition',
01774                         $fullinfo).'</div>';
01775                 }
01776             }
01777 
01778             echo html_writer::end_tag('div');
01779             echo html_writer::end_tag('li')."\n";
01780         }
01781 
01782     } elseif ($ismoving) {
01783         echo "<ul class=\"section\">\n";
01784     }
01785 
01786     if ($ismoving) {
01787         echo '<li><a title="'.$strmovefull.'"'.
01788              ' href="'.$CFG->wwwroot.'/course/mod.php?movetosection='.$section->id.'&amp;sesskey='.sesskey().'">'.
01789              '<img class="movetarget" src="'.$OUTPUT->pix_url('movehere') . '" '.
01790              ' alt="'.$strmovehere.'" /></a></li>
01791              ';
01792     }
01793     if (!empty($section->sequence) || $ismoving) {
01794         echo "</ul><!--class='section'-->\n\n";
01795     }
01796 }
01797 
01801 function print_section_add_menus($course, $section, $modnames, $vertical=false, $return=false) {
01802     global $CFG, $OUTPUT;
01803 
01804     // check to see if user can add menus
01805     if (!has_capability('moodle/course:manageactivities', get_context_instance(CONTEXT_COURSE, $course->id))) {
01806         return false;
01807     }
01808 
01809     $urlbase = "/course/mod.php?id=$course->id&section=$section&sesskey=".sesskey().'&add=';
01810 
01811     $resources = array();
01812     $activities = array();
01813 
01814     foreach($modnames as $modname=>$modnamestr) {
01815         if (!course_allowed_module($course, $modname)) {
01816             continue;
01817         }
01818 
01819         $libfile = "$CFG->dirroot/mod/$modname/lib.php";
01820         if (!file_exists($libfile)) {
01821             continue;
01822         }
01823         include_once($libfile);
01824         $gettypesfunc =  $modname.'_get_types';
01825         if (function_exists($gettypesfunc)) {
01826             // NOTE: this is legacy stuff, module subtypes are very strongly discouraged!!
01827             if ($types = $gettypesfunc()) {
01828                 $menu = array();
01829                 $atype = null;
01830                 $groupname = null;
01831                 foreach($types as $type) {
01832                     if ($type->typestr === '--') {
01833                         continue;
01834                     }
01835                     if (strpos($type->typestr, '--') === 0) {
01836                         $groupname = str_replace('--', '', $type->typestr);
01837                         continue;
01838                     }
01839                     $type->type = str_replace('&amp;', '&', $type->type);
01840                     if ($type->modclass == MOD_CLASS_RESOURCE) {
01841                         $atype = MOD_CLASS_RESOURCE;
01842                     }
01843                     $menu[$urlbase.$type->type] = $type->typestr;
01844                 }
01845                 if (!is_null($groupname)) {
01846                     if ($atype == MOD_CLASS_RESOURCE) {
01847                         $resources[] = array($groupname=>$menu);
01848                     } else {
01849                         $activities[] = array($groupname=>$menu);
01850                     }
01851                 } else {
01852                     if ($atype == MOD_CLASS_RESOURCE) {
01853                         $resources = array_merge($resources, $menu);
01854                     } else {
01855                         $activities = array_merge($activities, $menu);
01856                     }
01857                 }
01858             }
01859         } else {
01860             $archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
01861             if ($archetype == MOD_ARCHETYPE_RESOURCE) {
01862                 $resources[$urlbase.$modname] = $modnamestr;
01863             } else {
01864                 // all other archetypes are considered activity
01865                 $activities[$urlbase.$modname] = $modnamestr;
01866             }
01867         }
01868     }
01869 
01870     $straddactivity = get_string('addactivity');
01871     $straddresource = get_string('addresource');
01872 
01873     $output  = '<div class="section_add_menus">';
01874 
01875     if (!$vertical) {
01876         $output .= '<div class="horizontal">';
01877     }
01878 
01879     if (!empty($resources)) {
01880         $select = new url_select($resources, '', array(''=>$straddresource), "ressection$section");
01881         $select->set_help_icon('resources');
01882         $output .= $OUTPUT->render($select);
01883     }
01884 
01885     if (!empty($activities)) {
01886         $select = new url_select($activities, '', array(''=>$straddactivity), "section$section");
01887         $select->set_help_icon('activities');
01888         $output .= $OUTPUT->render($select);
01889     }
01890 
01891     if (!$vertical) {
01892         $output .= '</div>';
01893     }
01894 
01895     $output .= '</div>';
01896 
01897     if ($return) {
01898         return $output;
01899     } else {
01900         echo $output;
01901     }
01902 }
01903 
01911 function get_category_or_system_context($categoryid) {
01912     if ($categoryid) {
01913         return get_context_instance(CONTEXT_COURSECAT, $categoryid);
01914     } else {
01915         return get_context_instance(CONTEXT_SYSTEM);
01916     }
01917 }
01918 
01926 function get_child_categories($parentid) {
01927     static $allcategories = null;
01928 
01929     // only fill in this variable the first time
01930     if (null == $allcategories) {
01931         $allcategories = array();
01932 
01933         $categories = get_categories();
01934         foreach ($categories as $category) {
01935             if (empty($allcategories[$category->parent])) {
01936                 $allcategories[$category->parent] = array();
01937             }
01938             $allcategories[$category->parent][] = $category;
01939         }
01940     }
01941 
01942     if (empty($allcategories[$parentid])) {
01943         return array();
01944     } else {
01945         return $allcategories[$parentid];
01946     }
01947 }
01948 
01985 function make_categories_list(&$list, &$parents, $requiredcapability = '',
01986         $excludeid = 0, $category = NULL, $path = "") {
01987 
01988     // initialize the arrays if needed
01989     if (!is_array($list)) {
01990         $list = array();
01991     }
01992     if (!is_array($parents)) {
01993         $parents = array();
01994     }
01995 
01996     if (empty($category)) {
01997         // Start at the top level.
01998         $category = new stdClass;
01999         $category->id = 0;
02000     } else {
02001         // This is the excluded category, don't include it.
02002         if ($excludeid > 0 && $excludeid == $category->id) {
02003             return;
02004         }
02005 
02006         $context = get_context_instance(CONTEXT_COURSECAT, $category->id);
02007         $categoryname = format_string($category->name, true, array('context' => $context));
02008 
02009         // Update $path.
02010         if ($path) {
02011             $path = $path.' / '.$categoryname;
02012         } else {
02013             $path = $categoryname;
02014         }
02015 
02016         // Add this category to $list, if the permissions check out.
02017         if (empty($requiredcapability)) {
02018             $list[$category->id] = $path;
02019 
02020         } else {
02021             $requiredcapability = (array)$requiredcapability;
02022             if (has_all_capabilities($requiredcapability, $context)) {
02023                 $list[$category->id] = $path;
02024             }
02025         }
02026     }
02027 
02028     // Add all the children recursively, while updating the parents array.
02029     if ($categories = get_child_categories($category->id)) {
02030         foreach ($categories as $cat) {
02031             if (!empty($category->id)) {
02032                 if (isset($parents[$category->id])) {
02033                     $parents[$cat->id]   = $parents[$category->id];
02034                 }
02035                 $parents[$cat->id][] = $category->id;
02036             }
02037             make_categories_list($list, $parents, $requiredcapability, $excludeid, $cat, $path);
02038         }
02039     }
02040 }
02041 
02056 function get_course_category_tree($id = 0, $depth = 0) {
02057     global $DB, $CFG;
02058     $viewhiddencats = has_capability('moodle/category:viewhiddencategories', get_context_instance(CONTEXT_SYSTEM));
02059     $categories = get_child_categories($id);
02060     $categoryids = array();
02061     foreach ($categories as $key => &$category) {
02062         if (!$category->visible && !$viewhiddencats) {
02063             unset($categories[$key]);
02064             continue;
02065         }
02066         $categoryids[$category->id] = $category;
02067         if (empty($CFG->maxcategorydepth) || $depth <= $CFG->maxcategorydepth) {
02068             list($category->categories, $subcategories) = get_course_category_tree($category->id, $depth+1);
02069             foreach ($subcategories as $subid=>$subcat) {
02070                 $categoryids[$subid] = $subcat;
02071             }
02072             $category->courses = array();
02073         }
02074     }
02075 
02076     if ($depth > 0) {
02077         // This is a recursive call so return the required array
02078         return array($categories, $categoryids);
02079     }
02080 
02081     // The depth is 0 this function has just been called so we can finish it off
02082 
02083     list($ccselect, $ccjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
02084     list($catsql, $catparams) = $DB->get_in_or_equal(array_keys($categoryids));
02085     $sql = "SELECT
02086             c.id,c.sortorder,c.visible,c.fullname,c.shortname,c.summary,c.category
02087             $ccselect
02088             FROM {course} c
02089             $ccjoin
02090             WHERE c.category $catsql ORDER BY c.sortorder ASC";
02091     if ($courses = $DB->get_records_sql($sql, $catparams)) {
02092         // loop throught them
02093         foreach ($courses as $course) {
02094             if ($course->id == SITEID) {
02095                 continue;
02096             }
02097             context_instance_preload($course);
02098             if (!empty($course->visible) || has_capability('moodle/course:viewhiddencourses', get_context_instance(CONTEXT_COURSE, $course->id))) {
02099                 $categoryids[$course->category]->courses[$course->id] = $course;
02100             }
02101         }
02102     }
02103     return $categories;
02104 }
02105 
02110 function print_whole_category_list($category=NULL, $displaylist=NULL, $parentslist=NULL, $depth=-1, $showcourses = true) {
02111     global $CFG;
02112 
02113     // maxcategorydepth == 0 meant no limit
02114     if (!empty($CFG->maxcategorydepth) && $depth >= $CFG->maxcategorydepth) {
02115         return;
02116     }
02117 
02118     if (!$displaylist) {
02119         make_categories_list($displaylist, $parentslist);
02120     }
02121 
02122     if ($category) {
02123         if ($category->visible or has_capability('moodle/category:viewhiddencategories', get_context_instance(CONTEXT_SYSTEM))) {
02124             print_category_info($category, $depth, $showcourses);
02125         } else {
02126             return;  // Don't bother printing children of invisible categories
02127         }
02128 
02129     } else {
02130         $category = new stdClass();
02131         $category->id = "0";
02132     }
02133 
02134     if ($categories = get_child_categories($category->id)) {   // Print all the children recursively
02135         $countcats = count($categories);
02136         $count = 0;
02137         $first = true;
02138         $last = false;
02139         foreach ($categories as $cat) {
02140             $count++;
02141             if ($count == $countcats) {
02142                 $last = true;
02143             }
02144             $up = $first ? false : true;
02145             $down = $last ? false : true;
02146             $first = false;
02147 
02148             print_whole_category_list($cat, $displaylist, $parentslist, $depth + 1, $showcourses);
02149         }
02150     }
02151 }
02152 
02156 function make_categories_options() {
02157     make_categories_list($cats,$parents);
02158     foreach ($cats as $key => $value) {
02159         if (array_key_exists($key,$parents)) {
02160             if ($indent = count($parents[$key])) {
02161                 for ($i = 0; $i < $indent; $i++) {
02162                     $cats[$key] = '&nbsp;'.$cats[$key];
02163                 }
02164             }
02165         }
02166     }
02167     return $cats;
02168 }
02169 
02177 function get_course_display_name_for_list($course) {
02178     global $CFG;
02179     if (!empty($CFG->courselistshortnames)) {
02180         return $course->shortname . ' ' .$course->fullname;
02181     } else {
02182         return $course->fullname;
02183     }
02184 }
02185 
02190 function print_category_info($category, $depth=0, $showcourses = false) {
02191     global $CFG, $DB, $OUTPUT;
02192 
02193     $strsummary = get_string('summary');
02194 
02195     $catlinkcss = null;
02196     if (!$category->visible) {
02197         $catlinkcss = array('class'=>'dimmed');
02198     }
02199     static $coursecount = null;
02200     if (null === $coursecount) {
02201         // only need to check this once
02202         $coursecount = $DB->count_records('course') <= FRONTPAGECOURSELIMIT;
02203     }
02204 
02205     if ($showcourses and $coursecount) {
02206         $catimage = '<img src="'.$OUTPUT->pix_url('i/course') . '" alt="" />';
02207     } else {
02208         $catimage = "&nbsp;";
02209     }
02210 
02211     $courses = get_courses($category->id, 'c.sortorder ASC', 'c.id,c.sortorder,c.visible,c.fullname,c.shortname,c.summary');
02212     $context = get_context_instance(CONTEXT_COURSECAT, $category->id);
02213     $fullname = format_string($category->name, true, array('context' => $context));
02214 
02215     if ($showcourses and $coursecount) {
02216         echo '<div class="categorylist clearfix">';
02217         $cat = '';
02218         $cat .= html_writer::tag('div', $catimage, array('class'=>'image'));
02219         $catlink = html_writer::link(new moodle_url('/course/category.php', array('id'=>$category->id)), $fullname, $catlinkcss);
02220         $cat .= html_writer::tag('div', $catlink, array('class'=>'name'));
02221 
02222         $html = '';
02223         if ($depth > 0) {
02224             for ($i=0; $i< $depth; $i++) {
02225                 $html = html_writer::tag('div', $html . $cat, array('class'=>'indentation'));
02226                 $cat = '';
02227             }
02228         } else {
02229             $html = $cat;
02230         }
02231         echo html_writer::tag('div', $html, array('class'=>'category'));
02232         echo html_writer::tag('div', '', array('class'=>'clearfloat'));
02233 
02234         // does the depth exceed maxcategorydepth
02235         // maxcategorydepth == 0 or unset meant no limit
02236         $limit = !(isset($CFG->maxcategorydepth) && ($depth >= $CFG->maxcategorydepth-1));
02237         if ($courses && ($limit || $CFG->maxcategorydepth == 0)) {
02238             foreach ($courses as $course) {
02239                 $linkcss = null;
02240                 if (!$course->visible) {
02241                     $linkcss = array('class'=>'dimmed');
02242                 }
02243 
02244                 $coursename = get_course_display_name_for_list($course);
02245                 $courselink = html_writer::link(new moodle_url('/course/view.php', array('id'=>$course->id)), format_string($coursename), $linkcss);
02246 
02247                 // print enrol info
02248                 $courseicon = '';
02249                 if ($icons = enrol_get_course_info_icons($course)) {
02250                     foreach ($icons as $pix_icon) {
02251                         $courseicon = $OUTPUT->render($pix_icon).' ';
02252                     }
02253                 }
02254 
02255                 $coursecontent = html_writer::tag('div', $courseicon.$courselink, array('class'=>'name'));
02256 
02257                 if ($course->summary) {
02258                     $link = new moodle_url('/course/info.php?id='.$course->id);
02259                     $actionlink = $OUTPUT->action_link($link, '<img alt="'.$strsummary.'" src="'.$OUTPUT->pix_url('i/info') . '" />',
02260                         new popup_action('click', $link, 'courseinfo', array('height' => 400, 'width' => 500)),
02261                         array('title'=>$strsummary));
02262 
02263                     $coursecontent .= html_writer::tag('div', $actionlink, array('class'=>'info'));
02264                 }
02265 
02266                 $html = '';
02267                 for ($i=0; $i <= $depth; $i++) {
02268                     $html = html_writer::tag('div', $html . $coursecontent , array('class'=>'indentation'));
02269                     $coursecontent = '';
02270                 }
02271                 echo html_writer::tag('div', $html, array('class'=>'course clearfloat'));
02272             }
02273         }
02274         echo '</div>';
02275     } else {
02276         echo '<div class="categorylist">';
02277         $html = '';
02278         $cat = html_writer::link(new moodle_url('/course/category.php', array('id'=>$category->id)), $fullname, $catlinkcss);
02279         if (count($courses) > 0) {
02280             $cat .= html_writer::tag('span', ' ('.count($courses).')', array('title'=>get_string('numberofcourses'), 'class'=>'numberofcourse'));
02281         }
02282 
02283         if ($depth > 0) {
02284             for ($i=0; $i< $depth; $i++) {
02285                 $html = html_writer::tag('div', $html .$cat, array('class'=>'indentation'));
02286                 $cat = '';
02287             }
02288         } else {
02289             $html = $cat;
02290         }
02291 
02292         echo html_writer::tag('div', $html, array('class'=>'category'));
02293         echo html_writer::tag('div', '', array('class'=>'clearfloat'));
02294         echo '</div>';
02295     }
02296 }
02297 
02303 function print_course_request_buttons($systemcontext) {
02304     global $CFG, $DB, $OUTPUT;
02305     if (empty($CFG->enablecourserequests)) {
02306         return;
02307     }
02308     if (!has_capability('moodle/course:create', $systemcontext) && has_capability('moodle/course:request', $systemcontext)) {
02310         echo $OUTPUT->single_button('request.php', get_string('requestcourse'), 'get');
02311     }
02313     if (has_capability('moodle/site:approvecourse', $systemcontext)) {
02314         $disabled = !$DB->record_exists('course_request', array());
02315         echo $OUTPUT->single_button('pending.php', get_string('coursespending'), 'get', array('disabled'=>$disabled));
02316     }
02317 }
02318 
02325 function can_edit_in_category($categoryid = 0) {
02326     $context = get_category_or_system_context($categoryid);
02327     return has_any_capability(array('moodle/category:manage', 'moodle/course:create'), $context);
02328 }
02329 
02337 function update_category_button($categoryid = 0) {
02338     global $CFG, $PAGE, $OUTPUT;
02339 
02340     // Check permissions.
02341     if (!can_edit_in_category($categoryid)) {
02342         return '';
02343     }
02344 
02345     // Work out the appropriate action.
02346     if ($PAGE->user_is_editing()) {
02347         $label = get_string('turneditingoff');
02348         $edit = 'off';
02349     } else {
02350         $label = get_string('turneditingon');
02351         $edit = 'on';
02352     }
02353 
02354     // Generate the button HTML.
02355     $options = array('categoryedit' => $edit, 'sesskey' => sesskey());
02356     if ($categoryid) {
02357         $options['id'] = $categoryid;
02358         $page = 'category.php';
02359     } else {
02360         $page = 'index.php';
02361     }
02362     return $OUTPUT->single_button(new moodle_url('/course/' . $page, $options), $label, 'get');
02363 }
02364 
02368 function print_courses($category) {
02369     global $CFG, $OUTPUT;
02370 
02371     if (!is_object($category) && $category==0) {
02372         $categories = get_child_categories(0);  // Parent = 0   ie top-level categories only
02373         if (is_array($categories) && count($categories) == 1) {
02374             $category   = array_shift($categories);
02375             $courses    = get_courses_wmanagers($category->id,
02376                                                 'c.sortorder ASC',
02377                                                 array('summary','summaryformat'));
02378         } else {
02379             $courses    = get_courses_wmanagers('all',
02380                                                 'c.sortorder ASC',
02381                                                 array('summary','summaryformat'));
02382         }
02383         unset($categories);
02384     } else {
02385         $courses    = get_courses_wmanagers($category->id,
02386                                             'c.sortorder ASC',
02387                                             array('summary','summaryformat'));
02388     }
02389 
02390     if ($courses) {
02391         echo html_writer::start_tag('ul', array('class'=>'unlist'));
02392         foreach ($courses as $course) {
02393             $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
02394             if ($course->visible == 1 || has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
02395                 echo html_writer::start_tag('li');
02396                 print_course($course);
02397                 echo html_writer::end_tag('li');
02398             }
02399         }
02400         echo html_writer::end_tag('ul');
02401     } else {
02402         echo $OUTPUT->heading(get_string("nocoursesyet"));
02403         $context = get_context_instance(CONTEXT_SYSTEM);
02404         if (has_capability('moodle/course:create', $context)) {
02405             $options = array();
02406             if (!empty($category->id)) {
02407                 $options['category'] = $category->id;
02408             } else {
02409                 $options['category'] = $CFG->defaultrequestcategory;
02410             }
02411             echo html_writer::start_tag('div', array('class'=>'addcoursebutton'));
02412             echo $OUTPUT->single_button(new moodle_url('/course/edit.php', $options), get_string("addnewcourse"));
02413             echo html_writer::end_tag('div');
02414         }
02415     }
02416 }
02417 
02424 function print_course($course, $highlightterms = '') {
02425     global $CFG, $USER, $DB, $OUTPUT;
02426 
02427     $context = get_context_instance(CONTEXT_COURSE, $course->id);
02428 
02429     // Rewrite file URLs so that they are correct
02430     $course->summary = file_rewrite_pluginfile_urls($course->summary, 'pluginfile.php', $context->id, 'course', 'summary', NULL);
02431 
02432     echo html_writer::start_tag('div', array('class'=>'coursebox clearfix'));
02433     echo html_writer::start_tag('div', array('class'=>'info'));
02434     echo html_writer::start_tag('h3', array('class'=>'name'));
02435 
02436     $linkhref = new moodle_url('/course/view.php', array('id'=>$course->id));
02437 
02438     $coursename = get_course_display_name_for_list($course);
02439     $linktext = highlight($highlightterms, format_string($coursename));
02440     $linkparams = array('title'=>get_string('entercourse'));
02441     if (empty($course->visible)) {
02442         $linkparams['class'] = 'dimmed';
02443     }
02444     echo html_writer::link($linkhref, $linktext, $linkparams);
02445     echo html_writer::end_tag('h3');
02446 
02448     if (!empty($CFG->coursecontact)) {
02449         $managerroles = explode(',', $CFG->coursecontact);
02450         $namesarray = array();
02451         $rusers = array();
02452 
02453         if (!isset($course->managers)) {
02454             $rusers = get_role_users($managerroles, $context, true,
02455                 'ra.id AS raid, u.id, u.username, u.firstname, u.lastname,
02456                  r.name AS rolename, r.sortorder, r.id AS roleid',
02457                 'r.sortorder ASC, u.lastname ASC');
02458         } else {
02459             //  use the managers array if we have it for perf reasosn
02460             //  populate the datastructure like output of get_role_users();
02461             foreach ($course->managers as $manager) {
02462                 $u = new stdClass();
02463                 $u = $manager->user;
02464                 $u->roleid = $manager->roleid;
02465                 $u->rolename = $manager->rolename;
02466 
02467                 $rusers[] = $u;
02468             }
02469         }
02470 
02472         if (isset($context)) {
02473             $aliasnames = $DB->get_records('role_names', array('contextid'=>$context->id), '', 'roleid,contextid,name');
02474         }
02475 
02476         $namesarray = array();
02477         $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
02478         foreach ($rusers as $ra) {
02479             if (isset($namesarray[$ra->id])) {
02480                 //  only display a user once with the higest sortorder role
02481                 continue;
02482             }
02483 
02484             if (isset($aliasnames[$ra->roleid])) {
02485                 $ra->rolename = $aliasnames[$ra->roleid]->name;
02486             }
02487 
02488             $fullname = fullname($ra, $canviewfullnames);
02489             $namesarray[$ra->id] = format_string($ra->rolename).': '.
02490                 html_writer::link(new moodle_url('/user/view.php', array('id'=>$ra->id, 'course'=>SITEID)), $fullname);
02491         }
02492 
02493         if (!empty($namesarray)) {
02494             echo html_writer::start_tag('ul', array('class'=>'teachers'));
02495             foreach ($namesarray as $name) {
02496                 echo html_writer::tag('li', $name);
02497             }
02498             echo html_writer::end_tag('ul');
02499         }
02500     }
02501     echo html_writer::end_tag('div'); // End of info div
02502 
02503     echo html_writer::start_tag('div', array('class'=>'summary'));
02504     $options = new stdClass();
02505     $options->noclean = true;
02506     $options->para = false;
02507     $options->overflowdiv = true;
02508     if (!isset($course->summaryformat)) {
02509         $course->summaryformat = FORMAT_MOODLE;
02510     }
02511     echo highlight($highlightterms, format_text($course->summary, $course->summaryformat, $options,  $course->id));
02512     if ($icons = enrol_get_course_info_icons($course)) {
02513         echo html_writer::start_tag('div', array('class'=>'enrolmenticons'));
02514         foreach ($icons as $icon) {
02515             echo $OUTPUT->render($icon);
02516         }
02517         echo html_writer::end_tag('div'); // End of enrolmenticons div
02518     }
02519     echo html_writer::end_tag('div'); // End of summary div
02520     echo html_writer::end_tag('div'); // End of coursebox div
02521 }
02522 
02527 function print_my_moodle() {
02528     global $USER, $CFG, $DB, $OUTPUT;
02529 
02530     if (!isloggedin() or isguestuser()) {
02531         print_error('nopermissions', '', '', 'See My Moodle');
02532     }
02533 
02534     $courses  = enrol_get_my_courses('summary', 'visible DESC,sortorder ASC');
02535     $rhosts   = array();
02536     $rcourses = array();
02537     if (!empty($CFG->mnet_dispatcher_mode) && $CFG->mnet_dispatcher_mode==='strict') {
02538         $rcourses = get_my_remotecourses($USER->id);
02539         $rhosts   = get_my_remotehosts();
02540     }
02541 
02542     if (!empty($courses) || !empty($rcourses) || !empty($rhosts)) {
02543 
02544         if (!empty($courses)) {
02545             echo '<ul class="unlist">';
02546             foreach ($courses as $course) {
02547                 if ($course->id == SITEID) {
02548                     continue;
02549                 }
02550                 echo '<li>';
02551                 print_course($course);
02552                 echo "</li>\n";
02553             }
02554             echo "</ul>\n";
02555         }
02556 
02557         // MNET
02558         if (!empty($rcourses)) {
02559             // at the IDP, we know of all the remote courses
02560             foreach ($rcourses as $course) {
02561                 print_remote_course($course, "100%");
02562             }
02563         } elseif (!empty($rhosts)) {
02564             // non-IDP, we know of all the remote servers, but not courses
02565             foreach ($rhosts as $host) {
02566                 print_remote_host($host, "100%");
02567             }
02568         }
02569         unset($course);
02570         unset($host);
02571 
02572         if ($DB->count_records("course") > (count($courses) + 1) ) {  // Some courses not being displayed
02573             echo "<table width=\"100%\"><tr><td align=\"center\">";
02574             print_course_search("", false, "short");
02575             echo "</td><td align=\"center\">";
02576             echo $OUTPUT->single_button("$CFG->wwwroot/course/index.php", get_string("fulllistofcourses"), "get");
02577             echo "</td></tr></table>\n";
02578         }
02579 
02580     } else {
02581         if ($DB->count_records("course_categories") > 1) {
02582             echo $OUTPUT->box_start("categorybox");
02583             print_whole_category_list();
02584             echo $OUTPUT->box_end();
02585         } else {
02586             print_courses(0);
02587         }
02588     }
02589 }
02590 
02591 
02592 function print_course_search($value="", $return=false, $format="plain") {
02593     global $CFG;
02594     static $count = 0;
02595 
02596     $count++;
02597 
02598     $id = 'coursesearch';
02599 
02600     if ($count > 1) {
02601         $id .= $count;
02602     }
02603 
02604     $strsearchcourses= get_string("searchcourses");
02605 
02606     if ($format == 'plain') {
02607         $output  = '<form id="'.$id.'" action="'.$CFG->wwwroot.'/course/search.php" method="get">';
02608         $output .= '<fieldset class="coursesearchbox invisiblefieldset">';
02609         $output .= '<label for="coursesearchbox">'.$strsearchcourses.': </label>';
02610         $output .= '<input type="text" id="coursesearchbox" size="30" name="search" value="'.s($value).'" />';
02611         $output .= '<input type="submit" value="'.get_string('go').'" />';
02612         $output .= '</fieldset></form>';
02613     } else if ($format == 'short') {
02614         $output  = '<form id="'.$id.'" action="'.$CFG->wwwroot.'/course/search.php" method="get">';
02615         $output .= '<fieldset class="coursesearchbox invisiblefieldset">';
02616         $output .= '<label for="shortsearchbox">'.$strsearchcourses.': </label>';
02617         $output .= '<input type="text" id="shortsearchbox" size="12" name="search" alt="'.s($strsearchcourses).'" value="'.s($value).'" />';
02618         $output .= '<input type="submit" value="'.get_string('go').'" />';
02619         $output .= '</fieldset></form>';
02620     } else if ($format == 'navbar') {
02621         $output  = '<form id="coursesearchnavbar" action="'.$CFG->wwwroot.'/course/search.php" method="get">';
02622         $output .= '<fieldset class="coursesearchbox invisiblefieldset">';
02623         $output .= '<label for="navsearchbox">'.$strsearchcourses.': </label>';
02624         $output .= '<input type="text" id="navsearchbox" size="20" name="search" alt="'.s($strsearchcourses).'" value="'.s($value).'" />';
02625         $output .= '<input type="submit" value="'.get_string('go').'" />';
02626         $output .= '</fieldset></form>';
02627     }
02628 
02629     if ($return) {
02630         return $output;
02631     }
02632     echo $output;
02633 }
02634 
02635 function print_remote_course($course, $width="100%") {
02636     global $CFG, $USER;
02637 
02638     $linkcss = '';
02639 
02640     $url = "{$CFG->wwwroot}/auth/mnet/jump.php?hostid={$course->hostid}&amp;wantsurl=/course/view.php?id={$course->remoteid}";
02641 
02642     echo '<div class="coursebox remotecoursebox clearfix">';
02643     echo '<div class="info">';
02644     echo '<div class="name"><a title="'.get_string('entercourse').'"'.
02645          $linkcss.' href="'.$url.'">'
02646         .  format_string($course->fullname) .'</a><br />'
02647         . format_string($course->hostname) . ' : '
02648         . format_string($course->cat_name) . ' : '
02649         . format_string($course->shortname). '</div>';
02650     echo '</div><div class="summary">';
02651     $options = new stdClass();
02652     $options->noclean = true;
02653     $options->para = false;
02654     $options->overflowdiv = true;
02655     echo format_text($course->summary, $course->summaryformat, $options);
02656     echo '</div>';
02657     echo '</div>';
02658 }
02659 
02660 function print_remote_host($host, $width="100%") {
02661     global $OUTPUT;
02662 
02663     $linkcss = '';
02664 
02665     echo '<div class="coursebox clearfix">';
02666     echo '<div class="info">';
02667     echo '<div class="name">';
02668     echo '<img src="'.$OUTPUT->pix_url('i/mnethost') . '" class="icon" alt="'.get_string('course').'" />';
02669     echo '<a title="'.s($host['name']).'" href="'.s($host['url']).'">'
02670         . s($host['name']).'</a> - ';
02671     echo $host['count'] . ' ' . get_string('courses');
02672     echo '</div>';
02673     echo '</div>';
02674     echo '</div>';
02675 }
02676 
02677 
02679 
02680 function add_course_module($mod) {
02681     global $DB;
02682 
02683     $mod->added = time();
02684     unset($mod->id);
02685 
02686     return $DB->insert_record("course_modules", $mod);
02687 }
02688 
02695 function get_course_section($section, $courseid) {
02696     global $DB;
02697 
02698     if ($cw = $DB->get_record("course_sections", array("section"=>$section, "course"=>$courseid))) {
02699         return $cw;
02700     }
02701     $cw = new stdClass();
02702     $cw->course   = $courseid;
02703     $cw->section  = $section;
02704     $cw->summary  = "";
02705     $cw->summaryformat = FORMAT_HTML;
02706     $cw->sequence = "";
02707     $id = $DB->insert_record("course_sections", $cw);
02708     return $DB->get_record("course_sections", array("id"=>$id));
02709 }
02717 function add_mod_to_section($mod, $beforemod=NULL) {
02718     global $DB;
02719 
02720     if ($section = $DB->get_record("course_sections", array("course"=>$mod->course, "section"=>$mod->section))) {
02721 
02722         $section->sequence = trim($section->sequence);
02723 
02724         if (empty($section->sequence)) {
02725             $newsequence = "$mod->coursemodule";
02726 
02727         } else if ($beforemod) {
02728             $modarray = explode(",", $section->sequence);
02729 
02730             if ($key = array_keys($modarray, $beforemod->id)) {
02731                 $insertarray = array($mod->id, $beforemod->id);
02732                 array_splice($modarray, $key[0], 1, $insertarray);
02733                 $newsequence = implode(",", $modarray);
02734 
02735             } else {  // Just tack it on the end anyway
02736                 $newsequence = "$section->sequence,$mod->coursemodule";
02737             }
02738 
02739         } else {
02740             $newsequence = "$section->sequence,$mod->coursemodule";
02741         }
02742 
02743         $DB->set_field("course_sections", "sequence", $newsequence, array("id"=>$section->id));
02744         return $section->id;     // Return course_sections ID that was used.
02745 
02746     } else {  // Insert a new record
02747         $section->course   = $mod->course;
02748         $section->section  = $mod->section;
02749         $section->summary  = "";
02750         $section->summaryformat = FORMAT_HTML;
02751         $section->sequence = $mod->coursemodule;
02752         return $DB->insert_record("course_sections", $section);
02753     }
02754 }
02755 
02756 function set_coursemodule_groupmode($id, $groupmode) {
02757     global $DB;
02758     return $DB->set_field("course_modules", "groupmode", $groupmode, array("id"=>$id));
02759 }
02760 
02761 function set_coursemodule_idnumber($id, $idnumber) {
02762     global $DB;
02763     return $DB->set_field("course_modules", "idnumber", $idnumber, array("id"=>$id));
02764 }
02765 
02773 function set_coursemodule_visible($id, $visible, $prevstateoverrides=false) {
02774     global $DB, $CFG;
02775     require_once($CFG->libdir.'/gradelib.php');
02776 
02777     if (!$cm = $DB->get_record('course_modules', array('id'=>$id))) {
02778         return false;
02779     }
02780     if (!$modulename = $DB->get_field('modules', 'name', array('id'=>$cm->module))) {
02781         return false;
02782     }
02783     if ($events = $DB->get_records('event', array('instance'=>$cm->instance, 'modulename'=>$modulename))) {
02784         foreach($events as $event) {
02785             if ($visible) {
02786                 show_event($event);
02787             } else {
02788                 hide_event($event);
02789             }
02790         }
02791     }
02792 
02793     // hide the associated grade items so the teacher doesn't also have to go to the gradebook and hide them there
02794     $grade_items = grade_item::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$modulename, 'iteminstance'=>$cm->instance, 'courseid'=>$cm->course));
02795     if ($grade_items) {
02796         foreach ($grade_items as $grade_item) {
02797             $grade_item->set_hidden(!$visible);
02798         }
02799     }
02800 
02801     if ($prevstateoverrides) {
02802         if ($visible == '0') {
02803             // Remember the current visible state so we can toggle this back.
02804             $DB->set_field('course_modules', 'visibleold', $cm->visible, array('id'=>$id));
02805         } else {
02806             // Get the previous saved visible states.
02807             return $DB->set_field('course_modules', 'visible', $cm->visibleold, array('id'=>$id));
02808         }
02809     }
02810     return $DB->set_field("course_modules", "visible", $visible, array("id"=>$id));
02811 }
02812 
02819 function delete_course_module($id) {
02820     global $CFG, $DB;
02821     require_once($CFG->libdir.'/gradelib.php');
02822     require_once($CFG->dirroot.'/blog/lib.php');
02823 
02824     if (!$cm = $DB->get_record('course_modules', array('id'=>$id))) {
02825         return true;
02826     }
02827     $modulename = $DB->get_field('modules', 'name', array('id'=>$cm->module));
02828     //delete events from calendar
02829     if ($events = $DB->get_records('event', array('instance'=>$cm->instance, 'modulename'=>$modulename))) {
02830         foreach($events as $event) {
02831             delete_event($event->id);
02832         }
02833     }
02834     //delete grade items, outcome items and grades attached to modules
02835     if ($grade_items = grade_item::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$modulename,
02836                                                    'iteminstance'=>$cm->instance, 'courseid'=>$cm->course))) {
02837         foreach ($grade_items as $grade_item) {
02838             $grade_item->delete('moddelete');
02839         }
02840     }
02841     // Delete completion and availability data; it is better to do this even if the
02842     // features are not turned on, in case they were turned on previously (these will be
02843     // very quick on an empty table)
02844     $DB->delete_records('course_modules_completion', array('coursemoduleid' => $cm->id));
02845     $DB->delete_records('course_modules_availability', array('coursemoduleid'=> $cm->id));
02846 
02847     delete_context(CONTEXT_MODULE, $cm->id);
02848     return $DB->delete_records('course_modules', array('id'=>$cm->id));
02849 }
02850 
02851 function delete_mod_from_section($mod, $section) {
02852     global $DB;
02853 
02854     if ($section = $DB->get_record("course_sections", array("id"=>$section)) ) {
02855 
02856         $modarray = explode(",", $section->sequence);
02857 
02858         if ($key = array_keys ($modarray, $mod)) {
02859             array_splice($modarray, $key[0], 1);
02860             $newsequence = implode(",", $modarray);
02861             return $DB->set_field("course_sections", "sequence", $newsequence, array("id"=>$section->id));
02862         } else {
02863             return false;
02864         }
02865 
02866     }
02867     return false;
02868 }
02869 
02877 function move_section($course, $section, $move) {
02879     global $USER, $DB;
02880 
02881     if (!$move) {
02882         return true;
02883     }
02884 
02885     $sectiondest = $section + $move;
02886 
02887     if ($sectiondest > $course->numsections or $sectiondest < 1) {
02888         return false;
02889     }
02890 
02891     if (!$sectionrecord = $DB->get_record("course_sections", array("course"=>$course->id, "section"=>$section))) {
02892         return false;
02893     }
02894 
02895     if (!$sectiondestrecord = $DB->get_record("course_sections", array("course"=>$course->id, "section"=>$sectiondest))) {
02896         return false;
02897     }
02898 
02899     $DB->set_field("course_sections", "section", $sectiondest, array("id"=>$sectionrecord->id));
02900     $DB->set_field("course_sections", "section", $section, array("id"=>$sectiondestrecord->id));
02901 
02902     // if the focus is on the section that is being moved, then move the focus along
02903     if (course_get_display($course->id) == $section) {
02904         course_set_display($course->id, $sectiondest);
02905     }
02906 
02907     // Check for duplicates and fix order if needed.
02908     // There is a very rare case that some sections in the same course have the same section id.
02909     $sections = $DB->get_records('course_sections', array('course'=>$course->id), 'section ASC');
02910     $n = 0;
02911     foreach ($sections as $section) {
02912         if ($section->section != $n) {
02913             $DB->set_field('course_sections', 'section', $n, array('id'=>$section->id));
02914         }
02915         $n++;
02916     }
02917     return true;
02918 }
02919 
02930 function move_section_to($course, $section, $destination) {
02932     global $USER, $DB;
02933 
02934     if (!$destination && $destination != 0) {
02935         return true;
02936     }
02937 
02938     if ($destination > $course->numsections) {
02939         return false;
02940     }
02941 
02942     // Get all sections for this course and re-order them (2 of them should now share the same section number)
02943     if (!$sections = $DB->get_records_menu('course_sections', array('course' => $course->id),
02944             'section ASC, id ASC', 'id, section')) {
02945         return false;
02946     }
02947 
02948     $sections = reorder_sections($sections, $section, $destination);
02949 
02950     // Update all sections
02951     foreach ($sections as $id => $position) {
02952         $DB->set_field('course_sections', 'section', $position, array('id' => $id));
02953     }
02954 
02955     // if the focus is on the section that is being moved, then move the focus along
02956     if (course_get_display($course->id) == $section) {
02957         course_set_display($course->id, $destination);
02958     }
02959     return true;
02960 }
02961 
02974 function reorder_sections($sections, $origin_position, $target_position) {
02975     if (!is_array($sections)) {
02976         return false;
02977     }
02978 
02979     // We can't move section position 0
02980     if ($origin_position < 1) {
02981         echo "We can't move section position 0";
02982         return false;
02983     }
02984 
02985     // Locate origin section in sections array
02986     if (!$origin_key = array_search($origin_position, $sections)) {
02987         echo "searched position not in sections array";
02988         return false; // searched position not in sections array
02989     }
02990 
02991     // Extract origin section
02992     $origin_section = $sections[$origin_key];
02993     unset($sections[$origin_key]);
02994 
02995     // Find offset of target position (stupid PHP's array_splice requires offset instead of key index!)
02996     $found = false;
02997     $append_array = array();
02998     foreach ($sections as $id => $position) {
02999         if ($found) {
03000             $append_array[$id] = $position;
03001             unset($sections[$id]);
03002         }
03003         if ($position == $target_position) {
03004             $found = true;
03005         }
03006     }
03007 
03008     // Append moved section
03009     $sections[$origin_key] = $origin_section;
03010 
03011     // Append rest of array (if applicable)
03012     if (!empty($append_array)) {
03013         foreach ($append_array as $id => $position) {
03014             $sections[$id] = $position;
03015         }
03016     }
03017 
03018     // Renumber positions
03019     $position = 0;
03020     foreach ($sections as $id => $p) {
03021         $sections[$id] = $position;
03022         $position++;
03023     }
03024 
03025     return $sections;
03026 
03027 }
03028 
03035 function moveto_module($mod, $section, $beforemod=NULL) {
03036     global $DB, $OUTPUT;
03037 
03039     if (! delete_mod_from_section($mod->id, $mod->section)) {
03040         echo $OUTPUT->notification("Could not delete module from existing section");
03041     }
03042 
03044 
03045     if ($mod->section != $section->id) {
03046         $mod->section = $section->id;
03047         $DB->update_record("course_modules", $mod);
03048         // if moving to a hidden section then hide module
03049         if (!$section->visible) {
03050             set_coursemodule_visible($mod->id, 0);
03051         }
03052     }
03053 
03055 
03056     $mod->course       = $section->course;
03057     $mod->section      = $section->section;  // need relative reference
03058     $mod->coursemodule = $mod->id;
03059 
03060     if (! add_mod_to_section($mod, $beforemod)) {
03061         return false;
03062     }
03063 
03064     return true;
03065 }
03066 
03079 function make_editing_buttons(stdClass $mod, $absolute_ignored = true, $moveselect = true, $indent=-1, $section=-1) {
03080     global $CFG, $OUTPUT;
03081 
03082     static $str;
03083 
03084     $coursecontext = get_context_instance(CONTEXT_COURSE, $mod->course);
03085     $modcontext = get_context_instance(CONTEXT_MODULE, $mod->id);
03086 
03087     $editcaps = array('moodle/course:manageactivities', 'moodle/course:activityvisibility', 'moodle/role:assign');
03088     $dupecaps = array('moodle/backup:backuptargetimport', 'moodle/restore:restoretargetimport');
03089 
03090     // no permission to edit anything
03091     if (!has_any_capability($editcaps, $modcontext) and !has_all_capabilities($dupecaps, $coursecontext)) {
03092         return false;
03093     }
03094 
03095     $hasmanageactivities = has_capability('moodle/course:manageactivities', $modcontext);
03096 
03097     if (!isset($str)) {
03098         $str = new stdClass;
03099         $str->assign         = get_string("assignroles", 'role');
03100         $str->delete         = get_string("delete");
03101         $str->move           = get_string("move");
03102         $str->moveup         = get_string("moveup");
03103         $str->movedown       = get_string("movedown");
03104         $str->moveright      = get_string("moveright");
03105         $str->moveleft       = get_string("moveleft");
03106         $str->update         = get_string("update");
03107         $str->duplicate      = get_string("duplicate");
03108         $str->hide           = get_string("hide");
03109         $str->show           = get_string("show");
03110         $str->groupsnone     = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsnone"));
03111         $str->groupsseparate = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsseparate"));
03112         $str->groupsvisible  = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsvisible"));
03113         $str->forcedgroupsnone     = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsnone"));
03114         $str->forcedgroupsseparate = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsseparate"));
03115         $str->forcedgroupsvisible  = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsvisible"));
03116     }
03117 
03118     $baseurl = new moodle_url('/course/mod.php', array('sesskey' => sesskey()));
03119 
03120     if ($section >= 0) {
03121         $baseurl->param('sr', $section);
03122     }
03123     $actions = array();
03124 
03125     // leftright
03126     if ($hasmanageactivities) {
03127         if (right_to_left()) {   // Exchange arrows on RTL
03128             $rightarrow = 't/left';
03129             $leftarrow  = 't/right';
03130         } else {
03131             $rightarrow = 't/right';
03132             $leftarrow  = 't/left';
03133         }
03134 
03135         if ($indent > 0) {
03136             $actions[] = new action_link(
03137                 new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '-1')),
03138                 new pix_icon($leftarrow, $str->moveleft, 'moodle', array('class' => 'iconsmall')),
03139                 null,
03140                 array('class' => 'editing_moveleft', 'title' => $str->moveleft)
03141             );
03142         }
03143         if ($indent >= 0) {
03144             $actions[] = new action_link(
03145                 new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '1')),
03146                 new pix_icon($rightarrow, $str->moveright, 'moodle', array('class' => 'iconsmall')),
03147                 null,
03148                 array('class' => 'editing_moveright', 'title' => $str->moveright)
03149             );
03150         }
03151     }
03152 
03153     // move
03154     if ($hasmanageactivities) {
03155         if ($moveselect) {
03156             $actions[] = new action_link(
03157                 new moodle_url($baseurl, array('copy' => $mod->id)),
03158                 new pix_icon('t/move', $str->move, 'moodle', array('class' => 'iconsmall')),
03159                 null,
03160                 array('class' => 'editing_move', 'title' => $str->move)
03161             );
03162         } else {
03163             $actions[] = new action_link(
03164                 new moodle_url($baseurl, array('id' => $mod->id, 'move' => '-1')),
03165                 new pix_icon('t/up', $str->moveup, 'moodle', array('class' => 'iconsmall')),
03166                 null,
03167                 array('class' => 'editing_moveup', 'title' => $str->moveup)
03168             );
03169             $actions[] = new action_link(
03170                 new moodle_url($baseurl, array('id' => $mod->id, 'move' => '1')),
03171                 new pix_icon('t/down', $str->movedown, 'moodle', array('class' => 'iconsmall')),
03172                 null,
03173                 array('class' => 'editing_movedown', 'title' => $str->movedown)
03174             );
03175         }
03176     }
03177 
03178     // Update
03179     if ($hasmanageactivities) {
03180         $actions[] = new action_link(
03181             new moodle_url($baseurl, array('update' => $mod->id)),
03182             new pix_icon('t/edit', $str->update, 'moodle', array('class' => 'iconsmall')),
03183             null,
03184             array('class' => 'editing_update', 'title' => $str->update)
03185         );
03186     }
03187 
03188     // Duplicate (require both target import caps to be able to duplicate, see modduplicate.php)
03189     if (has_all_capabilities($dupecaps, $coursecontext)) {
03190         $actions[] = new action_link(
03191             new moodle_url($baseurl, array('duplicate' => $mod->id)),
03192             new pix_icon('t/copy', $str->duplicate, 'moodle', array('class' => 'iconsmall')),
03193             null,
03194             array('class' => 'editing_duplicate', 'title' => $str->duplicate)
03195         );
03196     }
03197 
03198     // Delete
03199     if ($hasmanageactivities) {
03200         $actions[] = new action_link(
03201             new moodle_url($baseurl, array('delete' => $mod->id)),
03202             new pix_icon('t/delete', $str->delete, 'moodle', array('class' => 'iconsmall')),
03203             null,
03204             array('class' => 'editing_delete', 'title' => $str->delete)
03205         );
03206     }
03207 
03208     // hideshow
03209     if (has_capability('moodle/course:activityvisibility', $modcontext)) {
03210         if ($mod->visible) {
03211             $actions[] = new action_link(
03212                 new moodle_url($baseurl, array('hide' => $mod->id)),
03213                 new pix_icon('t/hide', $str->hide, 'moodle', array('class' => 'iconsmall')),
03214                 null,
03215                 array('class' => 'editing_hide', 'title' => $str->hide)
03216             );
03217         } else {
03218             $actions[] = new action_link(
03219                 new moodle_url($baseurl, array('show' => $mod->id)),
03220                 new pix_icon('t/show', $str->show, 'moodle', array('class' => 'iconsmall')),
03221                 null,
03222                 array('class' => 'editing_show', 'title' => $str->show)
03223             );
03224         }
03225     }
03226 
03227     // groupmode
03228     if ($hasmanageactivities and $mod->groupmode !== false) {
03229         if ($mod->groupmode == SEPARATEGROUPS) {
03230             $groupmode = 0;
03231             $grouptitle = $str->groupsseparate;
03232             $forcedgrouptitle = $str->forcedgroupsseparate;
03233             $groupclass = 'editing_groupsseparate';
03234             $groupimage = 't/groups';
03235         } else if ($mod->groupmode == VISIBLEGROUPS) {
03236             $groupmode = 1;
03237             $grouptitle = $str->groupsvisible;
03238             $forcedgrouptitle = $str->forcedgroupsvisible;
03239             $groupclass = 'editing_groupsvisible';
03240             $groupimage = 't/groupv';
03241         } else {
03242             $groupmode = 2;
03243             $grouptitle = $str->groupsnone;
03244             $forcedgrouptitle = $str->forcedgroupsnone;
03245             $groupclass = 'editing_groupsnone';
03246             $groupimage = 't/groupn';
03247         }
03248         if ($mod->groupmodelink) {
03249             $actions[] = new action_link(
03250                 new moodle_url($baseurl, array('id' => $mod->id, 'groupmode' => $groupmode)),
03251                 new pix_icon($groupimage, $grouptitle, 'moodle', array('class' => 'iconsmall')),
03252                 null,
03253                 array('class' => $groupclass, 'title' => $grouptitle)
03254             );
03255         } else {
03256             $actions[] = new pix_icon($groupimage, $forcedgrouptitle, 'moodle', array('title' => $forcedgrouptitle, 'class' => 'iconsmall'));
03257         }
03258     }
03259 
03260     // Assign
03261     if (has_capability('moodle/role:assign', $modcontext)){
03262         $actions[] = new action_link(
03263             new moodle_url('/'.$CFG->admin.'/roles/assign.php', array('contextid' => $modcontext->id)),
03264             new pix_icon('i/roles', $str->assign, 'moodle', array('class' => 'iconsmall')),
03265             null,
03266             array('class' => 'editing_assign', 'title' => $str->assign)
03267         );
03268     }
03269 
03270     $output = html_writer::start_tag('span', array('class' => 'commands'));
03271     foreach ($actions as $action) {
03272         if ($action instanceof renderable) {
03273             $output .= $OUTPUT->render($action);
03274         } else {
03275             $output .= $action;
03276         }
03277     }
03278     $output .= html_writer::end_tag('span');
03279     return $output;
03280 }
03281 
03286 function course_format_name ($course,$max=100) {
03287 
03288     $context = get_context_instance(CONTEXT_COURSE, $course->id);
03289     $shortname = format_string($course->shortname, true, array('context' => $context));
03290     $fullname = format_string($course->fullname, true, array('context' => get_context_instance(CONTEXT_COURSE, $course->id)));
03291     $str = $shortname.': '. $fullname;
03292     if (textlib::strlen($str) <= $max) {
03293         return $str;
03294     }
03295     else {
03296         return textlib::substr($str,0,$max-3).'...';
03297     }
03298 }
03299 
03300 function update_restricted_mods($course, $mods) {
03301     global $DB;
03302 
03304     $DB->delete_records('course_allowed_modules', array('course'=>$course->id));
03305 
03306     if (empty($course->restrictmodules)) {
03307         return;   // We're done
03308     }
03309 
03311     foreach ($mods as $mod) {
03312         if ($mod == 0) {
03313             continue; // this is the 'allow none' option
03314         }
03315         $am = new stdClass();
03316         $am->course = $course->id;
03317         $am->module = $mod;
03318         $DB->insert_record('course_allowed_modules',$am);
03319     }
03320 }
03321 
03329 function course_allowed_module($course,$mod) {
03330     global $DB;
03331 
03332     if (empty($course->restrictmodules)) {
03333         return true;
03334     }
03335 
03336     // Admins and admin-like people who can edit everything can also add anything.
03337     // Originally there was a course:update test only, but it did not match the test in course edit form
03338     if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) {
03339         return true;
03340     }
03341 
03342     if (is_numeric($mod)) {
03343         $modid = $mod;
03344     } else if (is_string($mod)) {
03345         $modid = $DB->get_field('modules', 'id', array('name'=>$mod));
03346     }
03347     if (empty($modid)) {
03348         return false;
03349     }
03350 
03351     return $DB->record_exists('course_allowed_modules', array('course'=>$course->id, 'module'=>$modid));
03352 }
03353 
03360 function category_delete_full($category, $showfeedback=true) {
03361     global $CFG, $DB;
03362     require_once($CFG->libdir.'/gradelib.php');
03363     require_once($CFG->libdir.'/questionlib.php');
03364     require_once($CFG->dirroot.'/cohort/lib.php');
03365 
03366     if ($children = $DB->get_records('course_categories', array('parent'=>$category->id), 'sortorder ASC')) {
03367         foreach ($children as $childcat) {
03368             category_delete_full($childcat, $showfeedback);
03369         }
03370     }
03371 
03372     $deletedcourses = array();
03373     if ($courses = $DB->get_records('course', array('category'=>$category->id), 'sortorder ASC')) {
03374         foreach ($courses as $course) {
03375             if (!delete_course($course, false)) {
03376                 throw new moodle_exception('cannotdeletecategorycourse','','',$course->shortname);
03377             }
03378             $deletedcourses[] = $course;
03379         }
03380     }
03381 
03382     // move or delete cohorts in this context
03383     cohort_delete_category($category);
03384 
03385     // now delete anything that may depend on course category context
03386     grade_course_category_delete($category->id, 0, $showfeedback);
03387     if (!question_delete_course_category($category, 0, $showfeedback)) {
03388         throw new moodle_exception('cannotdeletecategoryquestions','','',$category->name);
03389     }
03390 
03391     // finally delete the category and it's context
03392     $DB->delete_records('course_categories', array('id'=>$category->id));
03393     delete_context(CONTEXT_COURSECAT, $category->id);
03394 
03395     events_trigger('course_category_deleted', $category);
03396 
03397     return $deletedcourses;
03398 }
03399 
03406 function category_delete_move($category, $newparentid, $showfeedback=true) {
03407     global $CFG, $DB, $OUTPUT;
03408     require_once($CFG->libdir.'/gradelib.php');
03409     require_once($CFG->libdir.'/questionlib.php');
03410     require_once($CFG->dirroot.'/cohort/lib.php');
03411 
03412     if (!$newparentcat = $DB->get_record('course_categories', array('id'=>$newparentid))) {
03413         return false;
03414     }
03415 
03416     if ($children = $DB->get_records('course_categories', array('parent'=>$category->id), 'sortorder ASC')) {
03417         foreach ($children as $childcat) {
03418             move_category($childcat, $newparentcat);
03419         }
03420     }
03421 
03422     if ($courses = $DB->get_records('course', array('category'=>$category->id), 'sortorder ASC', 'id')) {
03423         if (!move_courses(array_keys($courses), $newparentid)) {
03424             echo $OUTPUT->notification("Error moving courses");
03425             return false;
03426         }
03427         echo $OUTPUT->notification(get_string('coursesmovedout', '', format_string($category->name)), 'notifysuccess');
03428     }
03429 
03430     // move or delete cohorts in this context
03431     cohort_delete_category($category);
03432 
03433     // now delete anything that may depend on course category context
03434     grade_course_category_delete($category->id, $newparentid, $showfeedback);
03435     if (!question_delete_course_category($category, $newparentcat, $showfeedback)) {
03436         echo $OUTPUT->notification(get_string('errordeletingquestionsfromcategory', 'question', $category), 'notifysuccess');
03437         return false;
03438     }
03439 
03440     // finally delete the category and it's context
03441     $DB->delete_records('course_categories', array('id'=>$category->id));
03442     delete_context(CONTEXT_COURSECAT, $category->id);
03443 
03444     events_trigger('course_category_deleted', $category);
03445 
03446     echo $OUTPUT->notification(get_string('coursecategorydeleted', '', format_string($category->name)), 'notifysuccess');
03447 
03448     return true;
03449 }
03450 
03459 function move_courses($courseids, $categoryid) {
03460     global $CFG, $DB, $OUTPUT;
03461 
03462     if (empty($courseids)) {
03463         // nothing to do
03464         return;
03465     }
03466 
03467     if (!$category = $DB->get_record('course_categories', array('id'=>$categoryid))) {
03468         return false;
03469     }
03470 
03471     $courseids = array_reverse($courseids);
03472     $newparent = get_context_instance(CONTEXT_COURSECAT, $category->id);
03473     $i = 1;
03474 
03475     foreach ($courseids as $courseid) {
03476         if ($course = $DB->get_record('course', array('id'=>$courseid), 'id, category')) {
03477             $course = new stdClass();
03478             $course->id = $courseid;
03479             $course->category  = $category->id;
03480             $course->sortorder = $category->sortorder + MAX_COURSES_IN_CATEGORY - $i++;
03481             if ($category->visible == 0) {
03482                 // hide the course when moving into hidden category,
03483                 // do not update the visibleold flag - we want to get to previous state if somebody unhides the category
03484                 $course->visible = 0;
03485             }
03486 
03487             $DB->update_record('course', $course);
03488 
03489             $context   = get_context_instance(CONTEXT_COURSE, $course->id);
03490             context_moved($context, $newparent);
03491         }
03492     }
03493     fix_course_sortorder();
03494 
03495     return true;
03496 }
03497 
03503 function course_category_hide($category) {
03504     global $DB;
03505 
03506     $category->visible = 0;
03507     $DB->set_field('course_categories', 'visible', 0, array('id'=>$category->id));
03508     $DB->set_field('course_categories', 'visibleold', 0, array('id'=>$category->id));
03509     $DB->execute("UPDATE {course} SET visibleold = visible WHERE category = ?", array($category->id)); // store visible flag so that we can return to it if we immediately unhide
03510     $DB->set_field('course', 'visible', 0, array('category' => $category->id));
03511     // get all child categories and hide too
03512     if ($subcats = $DB->get_records_select('course_categories', "path LIKE ?", array("$category->path/%"))) {
03513         foreach ($subcats as $cat) {
03514             $DB->set_field('course_categories', 'visibleold', $cat->visible, array('id'=>$cat->id));
03515             $DB->set_field('course_categories', 'visible', 0, array('id'=>$cat->id));
03516             $DB->execute("UPDATE {course} SET visibleold = visible WHERE category = ?", array($cat->id));
03517             $DB->set_field('course', 'visible', 0, array('category' => $cat->id));
03518         }
03519     }
03520 }
03521 
03527 function course_category_show($category) {
03528     global $DB;
03529 
03530     $category->visible = 1;
03531     $DB->set_field('course_categories', 'visible', 1, array('id'=>$category->id));
03532     $DB->set_field('course_categories', 'visibleold', 1, array('id'=>$category->id));
03533     $DB->execute("UPDATE {course} SET visible = visibleold WHERE category = ?", array($category->id));
03534     // get all child categories and unhide too
03535     if ($subcats = $DB->get_records_select('course_categories', "path LIKE ?", array("$category->path/%"))) {
03536         foreach ($subcats as $cat) {
03537             if ($cat->visibleold) {
03538                 $DB->set_field('course_categories', 'visible', 1, array('id'=>$cat->id));
03539             }
03540             $DB->execute("UPDATE {course} SET visible = visibleold WHERE category = ?", array($cat->id));
03541         }
03542     }
03543 }
03544 
03549 function move_category($category, $newparentcat) {
03550     global $CFG, $DB;
03551 
03552     $context = get_context_instance(CONTEXT_COURSECAT, $category->id);
03553 
03554     $hidecat = false;
03555     if (empty($newparentcat->id)) {
03556         $DB->set_field('course_categories', 'parent', 0, array('id'=>$category->id));
03557 
03558         $newparent = get_context_instance(CONTEXT_SYSTEM);
03559 
03560     } else {
03561         $DB->set_field('course_categories', 'parent', $newparentcat->id, array('id'=>$category->id));
03562         $newparent = get_context_instance(CONTEXT_COURSECAT, $newparentcat->id);
03563 
03564         if (!$newparentcat->visible and $category->visible) {
03565             // better hide category when moving into hidden category, teachers may unhide afterwards and the hidden children will be restored properly
03566             $hidecat = true;
03567         }
03568     }
03569 
03570     context_moved($context, $newparent);
03571 
03572     // now make it last in new category
03573     $DB->set_field('course_categories', 'sortorder', MAX_COURSES_IN_CATEGORY*MAX_COURSE_CATEGORIES, array('id'=>$category->id));
03574 
03575     // and fix the sortorders
03576     fix_course_sortorder();
03577 
03578     if ($hidecat) {
03579         course_category_hide($category);
03580     }
03581 }
03582 
03599 function get_section_name(stdClass $course, stdClass $section) {
03600     global $CFG;
03601 
03603     if ($course->format == 'site') {
03604         return get_string('site');
03605     }
03606 
03607     // Use course formatter callback if it exists
03608     $namingfile = $CFG->dirroot.'/course/format/'.$course->format.'/lib.php';
03609     $namingfunction = 'callback_'.$course->format.'_get_section_name';
03610     if (!function_exists($namingfunction) && file_exists($namingfile)) {
03611         require_once $namingfile;
03612     }
03613     if (function_exists($namingfunction)) {
03614         return $namingfunction($course, $section);
03615     }
03616 
03617     // else, default behavior:
03618     return get_generic_section_name($course->format, $section);
03619 }
03620 
03628 function get_generic_section_name($format, stdClass $section) {
03629     return get_string('sectionname', "format_$format") . ' ' . $section->section;
03630 }
03631 
03632 
03633 function course_format_uses_sections($format) {
03634     global $CFG;
03635 
03636     $featurefile = $CFG->dirroot.'/course/format/'.$format.'/lib.php';
03637     $featurefunction = 'callback_'.$format.'_uses_sections';
03638     if (!function_exists($featurefunction) && file_exists($featurefile)) {
03639         require_once $featurefile;
03640     }
03641     if (function_exists($featurefunction)) {
03642         return $featurefunction();
03643     }
03644 
03645     return false;
03646 }
03647 
03658 function course_format_ajax_support($format) {
03659     global $CFG;
03660 
03661     // set up default values
03662     $ajaxsupport = new stdClass();
03663     $ajaxsupport->capable = false;
03664     $ajaxsupport->testedbrowsers = array();
03665 
03666     // get the information from the course format library
03667     $featurefile = $CFG->dirroot.'/course/format/'.$format.'/lib.php';
03668     $featurefunction = 'callback_'.$format.'_ajax_support';
03669     if (!function_exists($featurefunction) && file_exists($featurefile)) {
03670         require_once $featurefile;
03671     }
03672     if (function_exists($featurefunction)) {
03673         $formatsupport = $featurefunction();
03674         if (isset($formatsupport->capable)) {
03675             $ajaxsupport->capable = $formatsupport->capable;
03676         }
03677         if (is_array($formatsupport->testedbrowsers)) {
03678             $ajaxsupport->testedbrowsers = $formatsupport->testedbrowsers;
03679         }
03680     }
03681 
03682     return $ajaxsupport;
03683 }
03684 
03692 function can_delete_course($courseid) {
03693     global $USER, $DB;
03694 
03695     $context = get_context_instance(CONTEXT_COURSE, $courseid);
03696 
03697     if (has_capability('moodle/course:delete', $context)) {
03698         return true;
03699     }
03700 
03701     // hack: now try to find out if creator created this course recently (1 day)
03702     if (!has_capability('moodle/course:create', $context)) {
03703         return false;
03704     }
03705 
03706     $since = time() - 60*60*24;
03707 
03708     $params = array('userid'=>$USER->id, 'url'=>"view.php?id=$courseid", 'since'=>$since);
03709     $select = "module = 'course' AND action = 'new' AND userid = :userid AND url = :url AND time > :since";
03710 
03711     return $DB->record_exists_select('log', $select, $params);
03712 }
03713 
03720 function save_local_role_names($courseid, $data) {
03721     global $DB;
03722     $context = get_context_instance(CONTEXT_COURSE, $courseid);
03723 
03724     foreach ($data as $fieldname => $value) {
03725         if (strpos($fieldname, 'role_') !== 0) {
03726             continue;
03727         }
03728         list($ignored, $roleid) = explode('_', $fieldname);
03729 
03730         // make up our mind whether we want to delete, update or insert
03731         if (!$value) {
03732             $DB->delete_records('role_names', array('contextid' => $context->id, 'roleid' => $roleid));
03733 
03734         } else if ($rolename = $DB->get_record('role_names', array('contextid' => $context->id, 'roleid' => $roleid))) {
03735             $rolename->name = $value;
03736             $DB->update_record('role_names', $rolename);
03737 
03738         } else {
03739             $rolename = new stdClass;
03740             $rolename->contextid = $context->id;
03741             $rolename->roleid = $roleid;
03742             $rolename->name = $value;
03743             $DB->insert_record('role_names', $rolename);
03744         }
03745     }
03746 }
03747 
03758 function create_course($data, $editoroptions = NULL) {
03759     global $CFG, $DB;
03760 
03761     //check the categoryid - must be given for all new courses
03762     $category = $DB->get_record('course_categories', array('id'=>$data->category), '*', MUST_EXIST);
03763 
03764     //check if the shortname already exist
03765     if (!empty($data->shortname)) {
03766         if ($DB->record_exists('course', array('shortname' => $data->shortname))) {
03767             throw new moodle_exception('shortnametaken');
03768         }
03769     }
03770 
03771     //check if the id number already exist
03772     if (!empty($data->idnumber)) {
03773         if ($DB->record_exists('course', array('idnumber' => $data->idnumber))) {
03774             throw new moodle_exception('idnumbertaken');
03775         }
03776     }
03777 
03778     $data->timecreated  = time();
03779     $data->timemodified = $data->timecreated;
03780 
03781     // place at beginning of any category
03782     $data->sortorder = 0;
03783 
03784     if ($editoroptions) {
03785         // summary text is updated later, we need context to store the files first
03786         $data->summary = '';
03787         $data->summary_format = FORMAT_HTML;
03788     }
03789 
03790     if (!isset($data->visible)) {
03791         // data not from form, add missing visibility info
03792         $data->visible = $category->visible;
03793     }
03794     $data->visibleold = $data->visible;
03795 
03796     $newcourseid = $DB->insert_record('course', $data);
03797     $context = get_context_instance(CONTEXT_COURSE, $newcourseid, MUST_EXIST);
03798 
03799     if ($editoroptions) {
03800         // Save the files used in the summary editor and store
03801         $data = file_postupdate_standard_editor($data, 'summary', $editoroptions, $context, 'course', 'summary', 0);
03802         $DB->set_field('course', 'summary', $data->summary, array('id'=>$newcourseid));
03803         $DB->set_field('course', 'summaryformat', $data->summary_format, array('id'=>$newcourseid));
03804     }
03805 
03806     $course = $DB->get_record('course', array('id'=>$newcourseid));
03807 
03808     // Setup the blocks
03809     blocks_add_default_course_blocks($course);
03810 
03811     $section = new stdClass();
03812     $section->course        = $course->id;   // Create a default section.
03813     $section->section       = 0;
03814     $section->summaryformat = FORMAT_HTML;
03815     $DB->insert_record('course_sections', $section);
03816 
03817     fix_course_sortorder();
03818 
03819     // update module restrictions
03820     if ($course->restrictmodules) {
03821         if (isset($data->allowedmods)) {
03822             update_restricted_mods($course, $data->allowedmods);
03823         } else {
03824             if (!empty($CFG->defaultallowedmodules)) {
03825                 update_restricted_mods($course, explode(',', $CFG->defaultallowedmodules));
03826             }
03827         }
03828     }
03829 
03830     // new context created - better mark it as dirty
03831     mark_context_dirty($context->path);
03832 
03833     // Save any custom role names.
03834     save_local_role_names($course->id, (array)$data);
03835 
03836     // set up enrolments
03837     enrol_course_updated(true, $course, $data);
03838 
03839     add_to_log(SITEID, 'course', 'new', 'view.php?id='.$course->id, $data->fullname.' (ID '.$course->id.')');
03840 
03841     // Trigger events
03842     events_trigger('course_created', $course);
03843 
03844     return $course;
03845 }
03846 
03857 function update_course($data, $editoroptions = NULL) {
03858     global $CFG, $DB;
03859 
03860     $data->timemodified = time();
03861 
03862     $oldcourse = $DB->get_record('course', array('id'=>$data->id), '*', MUST_EXIST);
03863     $context   = get_context_instance(CONTEXT_COURSE, $oldcourse->id);
03864 
03865     if ($editoroptions) {
03866         $data = file_postupdate_standard_editor($data, 'summary', $editoroptions, $context, 'course', 'summary', 0);
03867     }
03868 
03869     if (!isset($data->category) or empty($data->category)) {
03870         // prevent nulls and 0 in category field
03871         unset($data->category);
03872     }
03873     $movecat = (isset($data->category) and $oldcourse->category != $data->category);
03874 
03875     if (!isset($data->visible)) {
03876         // data not from form, add missing visibility info
03877         $data->visible = $oldcourse->visible;
03878     }
03879 
03880     if ($data->visible != $oldcourse->visible) {
03881         // reset the visibleold flag when manually hiding/unhiding course
03882         $data->visibleold = $data->visible;
03883     } else {
03884         if ($movecat) {
03885             $newcategory = $DB->get_record('course_categories', array('id'=>$data->category));
03886             if (empty($newcategory->visible)) {
03887                 // make sure when moving into hidden category the course is hidden automatically
03888                 $data->visible = 0;
03889             }
03890         }
03891     }
03892 
03893     // Update with the new data
03894     $DB->update_record('course', $data);
03895 
03896     $course = $DB->get_record('course', array('id'=>$data->id));
03897 
03898     if ($movecat) {
03899         $newparent = get_context_instance(CONTEXT_COURSECAT, $course->category);
03900         context_moved($context, $newparent);
03901     }
03902 
03903     fix_course_sortorder();
03904 
03905     // Test for and remove blocks which aren't appropriate anymore
03906     blocks_remove_inappropriate($course);
03907 
03908     // update module restrictions
03909     if (isset($data->allowedmods)) {
03910         update_restricted_mods($course, $data->allowedmods);
03911     }
03912 
03913     // Save any custom role names.
03914     save_local_role_names($course->id, $data);
03915 
03916     // update enrol settings
03917     enrol_course_updated(false, $course, $data);
03918 
03919     add_to_log($course->id, "course", "update", "edit.php?id=$course->id", $course->id);
03920 
03921     // Trigger events
03922     events_trigger('course_updated', $course);
03923 }
03924 
03929 function average_number_of_participants() {
03930     global $DB, $SITE;
03931 
03932     //count total of enrolments for visible course (except front page)
03933     $sql = 'SELECT COUNT(*) FROM (
03934         SELECT DISTINCT ue.userid, e.courseid
03935         FROM {user_enrolments} ue, {enrol} e, {course} c
03936         WHERE ue.enrolid = e.id
03937             AND e.courseid <> :siteid
03938             AND c.id = e.courseid
03939             AND c.visible = 1) as total';
03940     $params = array('siteid' => $SITE->id);
03941     $enrolmenttotal = $DB->count_records_sql($sql, $params);
03942 
03943 
03944     //count total of visible courses (minus front page)
03945     $coursetotal = $DB->count_records('course', array('visible' => 1));
03946     $coursetotal = $coursetotal - 1 ;
03947 
03948     //average of enrolment
03949     if (empty($coursetotal)) {
03950         $participantaverage = 0;
03951     } else {
03952         $participantaverage = $enrolmenttotal / $coursetotal;
03953     }
03954 
03955     return $participantaverage;
03956 }
03957 
03962 function average_number_of_courses_modules() {
03963     global $DB, $SITE;
03964 
03965     //count total of visible course module (except front page)
03966     $sql = 'SELECT COUNT(*) FROM (
03967         SELECT cm.course, cm.module
03968         FROM {course} c, {course_modules} cm
03969         WHERE c.id = cm.course
03970             AND c.id <> :siteid
03971             AND cm.visible = 1
03972             AND c.visible = 1) as total';
03973     $params = array('siteid' => $SITE->id);
03974     $moduletotal = $DB->count_records_sql($sql, $params);
03975 
03976 
03977     //count total of visible courses (minus front page)
03978     $coursetotal = $DB->count_records('course', array('visible' => 1));
03979     $coursetotal = $coursetotal - 1 ;
03980 
03981     //average of course module
03982     if (empty($coursetotal)) {
03983         $coursemoduleaverage = 0;
03984     } else {
03985         $coursemoduleaverage = $moduletotal / $coursetotal;
03986     }
03987 
03988     return $coursemoduleaverage;
03989 }
03990 
04011 class course_request {
04012 
04018     protected $properties;
04019 
04026     protected static $summaryeditoroptions;
04027 
04039     public static function prepare($data=null) {
04040         if ($data === null) {
04041             $data = new stdClass;
04042         }
04043         $data = file_prepare_standard_editor($data, 'summary', self::summary_editor_options());
04044         return $data;
04045     }
04046 
04057     public static function create($data) {
04058         global $USER, $DB, $CFG;
04059         $data->requester = $USER->id;
04060 
04061         // Summary is a required field so copy the text over
04062         $data->summary       = $data->summary_editor['text'];
04063         $data->summaryformat = $data->summary_editor['format'];
04064 
04065         $data->id = $DB->insert_record('course_request', $data);
04066 
04067         // Create a new course_request object and return it
04068         $request = new course_request($data);
04069 
04070         // Notify the admin if required.
04071         if ($users = get_users_from_config($CFG->courserequestnotify, 'moodle/site:approvecourse')) {
04072 
04073             $a = new stdClass;
04074             $a->link = "$CFG->wwwroot/course/pending.php";
04075             $a->user = fullname($USER);
04076             $subject = get_string('courserequest');
04077             $message = get_string('courserequestnotifyemail', 'admin', $a);
04078             foreach ($users as $user) {
04079                 $request->notify($user, $USER, 'courserequested', $subject, $message);
04080             }
04081         }
04082 
04083         return $request;
04084     }
04085 
04092     public static function summary_editor_options() {
04093         global $CFG;
04094         if (self::$summaryeditoroptions === null) {
04095             self::$summaryeditoroptions = array('maxfiles' => 0, 'maxbytes'=>0);
04096         }
04097         return self::$summaryeditoroptions;
04098     }
04099 
04107     public function __construct($properties) {
04108         global $DB;
04109         if (empty($properties->id)) {
04110             if (empty($properties)) {
04111                 throw new coding_exception('You must provide a course request id when creating a course_request object');
04112             }
04113             $id = $properties;
04114             $properties = new stdClass;
04115             $properties->id = (int)$id;
04116             unset($id);
04117         }
04118         if (empty($properties->requester)) {
04119             if (!($this->properties = $DB->get_record('course_request', array('id' => $properties->id)))) {
04120                 print_error('unknowncourserequest');
04121             }
04122         } else {
04123             $this->properties = $properties;
04124         }
04125         $this->properties->collision = null;
04126     }
04127 
04134     public function __get($key) {
04135         return $this->properties->$key;
04136     }
04137 
04146     public function __isset($key) {
04147         return (!empty($this->properties->$key));
04148     }
04149 
04158     public function get_requester() {
04159         global $DB;
04160         static $requesters= array();
04161         if (!array_key_exists($this->properties->requester, $requesters)) {
04162             $requesters[$this->properties->requester] = $DB->get_record('user', array('id'=>$this->properties->requester));
04163         }
04164         return $requesters[$this->properties->requester];
04165     }
04166 
04175     public function check_shortname_collision($shortnamemark = '[*]') {
04176         global $DB;
04177 
04178         if ($this->properties->collision !== null) {
04179             return $this->properties->collision;
04180         }
04181 
04182         if (empty($this->properties->shortname)) {
04183             debugging('Attempting to check a course request shortname before it has been set', DEBUG_DEVELOPER);
04184             $this->properties->collision = false;
04185         } else if ($DB->record_exists('course', array('shortname' => $this->properties->shortname))) {
04186             if (!empty($shortnamemark)) {
04187                 $this->properties->shortname .= ' '.$shortnamemark;
04188             }
04189             $this->properties->collision = true;
04190         } else {
04191             $this->properties->collision = false;
04192         }
04193         return $this->properties->collision;
04194     }
04195 
04205     public function approve() {
04206         global $CFG, $DB, $USER;
04207 
04208         $user = $DB->get_record('user', array('id' => $this->properties->requester, 'deleted'=>0), '*', MUST_EXIST);
04209 
04210         $category = get_course_category($CFG->defaultrequestcategory);
04211         $courseconfig = get_config('moodlecourse');
04212 
04213         // Transfer appropriate settings
04214         $data = clone($this->properties);
04215         unset($data->id);
04216         unset($data->reason);
04217         unset($data->requester);
04218 
04219         // Set category
04220         $data->category = $category->id;
04221         $data->sortorder = $category->sortorder; // place as the first in category
04222 
04223         // Set misc settings
04224         $data->requested = 1;
04225         if (!empty($CFG->restrictmodulesfor) && $CFG->restrictmodulesfor != 'none' && !empty($CFG->restrictbydefault)) {
04226             $data->restrictmodules = 1;
04227         }
04228 
04229         // Apply course default settings
04230         $data->format             = $courseconfig->format;
04231         $data->numsections        = $courseconfig->numsections;
04232         $data->hiddensections     = $courseconfig->hiddensections;
04233         $data->newsitems          = $courseconfig->newsitems;
04234         $data->showgrades         = $courseconfig->showgrades;
04235         $data->showreports        = $courseconfig->showreports;
04236         $data->maxbytes           = $courseconfig->maxbytes;
04237         $data->groupmode          = $courseconfig->groupmode;
04238         $data->groupmodeforce     = $courseconfig->groupmodeforce;
04239         $data->visible            = $courseconfig->visible;
04240         $data->visibleold         = $data->visible;
04241         $data->lang               = $courseconfig->lang;
04242 
04243         $course = create_course($data);
04244         $context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST);
04245 
04246         // add enrol instances
04247         if (!$DB->record_exists('enrol', array('courseid'=>$course->id, 'enrol'=>'manual'))) {
04248             if ($manual = enrol_get_plugin('manual')) {
04249                 $manual->add_default_instance($course);
04250             }
04251         }
04252 
04253         // enrol the requester as teacher if necessary
04254         if (!empty($CFG->creatornewroleid) and !is_viewing($context, $user, 'moodle/role:assign') and !is_enrolled($context, $user, 'moodle/role:assign')) {
04255             enrol_try_internal_enrol($course->id, $user->id, $CFG->creatornewroleid);
04256         }
04257 
04258         $this->delete();
04259 
04260         $a = new stdClass();
04261         $a->name = format_string($course->fullname, true, array('context' => get_context_instance(CONTEXT_COURSE, $course->id)));
04262         $a->url = $CFG->wwwroot.'/course/view.php?id=' . $course->id;
04263         $this->notify($user, $USER, 'courserequestapproved', get_string('courseapprovedsubject'), get_string('courseapprovedemail2', 'moodle', $a));
04264 
04265         return $course->id;
04266     }
04267 
04276     public function reject($notice) {
04277         global $USER, $DB;
04278         $user = $DB->get_record('user', array('id' => $this->properties->requester), '*', MUST_EXIST);
04279         $this->notify($user, $USER, 'courserequestrejected', get_string('courserejectsubject'), get_string('courserejectemail', 'moodle', $notice));
04280         $this->delete();
04281     }
04282 
04286     public function delete() {
04287         global $DB;
04288         $DB->delete_records('course_request', array('id' => $this->properties->id));
04289     }
04290 
04300     protected function notify($touser, $fromuser, $name='courserequested', $subject, $message) {
04301         $eventdata = new stdClass();
04302         $eventdata->component         = 'moodle';
04303         $eventdata->name              = $name;
04304         $eventdata->userfrom          = $fromuser;
04305         $eventdata->userto            = $touser;
04306         $eventdata->subject           = $subject;
04307         $eventdata->fullmessage       = $message;
04308         $eventdata->fullmessageformat = FORMAT_PLAIN;
04309         $eventdata->fullmessagehtml   = '';
04310         $eventdata->smallmessage      = '';
04311         $eventdata->notification      = 1;
04312         message_send($eventdata);
04313     }
04314 }
04315 
04322 function course_page_type_list($pagetype, $parentcontext, $currentcontext) {
04323     // if above course context ,display all course fomats
04324     list($currentcontext, $course, $cm) = get_context_info_array($currentcontext->id);
04325     if ($course->id == SITEID) {
04326         return array('*'=>get_string('page-x', 'pagetype'));
04327     } else {
04328         return array('*'=>get_string('page-x', 'pagetype'),
04329             'course-*'=>get_string('page-course-x', 'pagetype'),
04330             'course-view-*'=>get_string('page-course-view-x', 'pagetype')
04331         );
04332     }
04333 }
 All Data Structures Namespaces Files Functions Variables Enumerations