-----------------------moodle18/course/format/super/format.php (now based on topic format)-----------
libdir.'/ajax/ajaxlib.php');
$topic = optional_param('topic', -1, PARAM_INT);
// Bounds for block widths
// more flexible for theme designers taken from theme config.php
$lmin = (empty($THEME->block_l_min_width)) ? 100 : $THEME->block_l_min_width;
$lmax = (empty($THEME->block_l_max_width)) ? 210 : $THEME->block_l_max_width;
$rmin = (empty($THEME->block_r_min_width)) ? 100 : $THEME->block_r_min_width;
$rmax = (empty($THEME->block_r_max_width)) ? 210 : $THEME->block_r_max_width;
define('BLOCK_L_MIN_WIDTH', $lmin);
define('BLOCK_L_MAX_WIDTH', $lmax);
define('BLOCK_R_MIN_WIDTH', $rmin);
define('BLOCK_R_MAX_WIDTH', $rmax);
$preferred_width_left = bounded_number(BLOCK_L_MIN_WIDTH, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]),
BLOCK_L_MAX_WIDTH);
$preferred_width_right = bounded_number(BLOCK_R_MIN_WIDTH, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]),
BLOCK_R_MAX_WIDTH);
if ($topic != -1) {
$displaysection = course_set_display($course->id, $topic);
} else {
if (isset($USER->display[$course->id])) { // for admins, mostly
$displaysection = $USER->display[$course->id];
} else {
$displaysection = course_set_display($course->id, 0);
}
}
$context = get_context_instance(CONTEXT_COURSE, $course->id);
if (($marker >=0) && has_capability('moodle/course:setcurrentsection', $context) && confirm_sesskey()) {
$course->marker = $marker;
if (! set_field("course", "marker", $marker, "id", $course->id)) {
error("Could not mark that topic for this course");
}
}
$streditsummary = get_string('editsummary');
$stradd = get_string('add');
$stractivities = get_string('activities');
$strshowalltopics = get_string('showalltopics');
$strtopic = get_string('topic');
$strgroups = get_string('groups');
$strgroupmy = get_string('groupmy');
$editing = $PAGE->user_is_editing();
if ($editing) {
$strstudents = moodle_strtolower($course->students);
$strtopichide = get_string('topichide', '', $strstudents);
$strtopicshow = get_string('topicshow', '', $strstudents);
$strmarkthistopic = get_string('markthistopic');
$strmarkedthistopic = get_string('markedthistopic');
$strmoveup = get_string('moveup');
$strmovedown = get_string('movedown');
}
/// Layout the whole page as three big columns.
echo '
_print_block()
// function is called, since that function needs to set some
// stuff in the javascriptportal object.
$COURSE->javascriptportal = new jsportal();
$CFG->useajax = true;
}
}
}
$CFG->blocksdrag = $CFG->useajax; // this will add a new class to the header so we can style differently
if($parent) {
$PAGE->print_header(get_string('course').': %fullname%', '', '', $bodytags,$parentlink);
} else {
$PAGE->print_header(get_string('course').': %fullname%', '', '', $bodytags);
}
// Course wrapper start.
echo '';
get_all_mods($course->id, $mods, $modnames, $modnamesplural, $modnamesused);
if (! $sections = get_all_sections($course->id)) { // No sections found
// Double-check to be extra sure
if (! $section = get_record('course_sections', 'course', $course->id, 'section', 0)) {
$section->course = $course->id; // Create a default section.
$section->section = 0;
$section->visible = 1;
$section->id = insert_record('course_sections', $section);
}
if (! $sections = get_all_sections($course->id) ) { // Try again
error('Error finding or creating section structures for this course');
}
}
if (empty($course->modinfo)) {
// Course cache was never made.
rebuild_course_cache($course->id);
if (! $course = get_record('course', 'id', $course->id) ) {
error("That's an invalid course id");
}
}
// Include the actual course format.
require($CFG->dirroot .'/course/format/'. $course->format .'/format.php');
// Content wrapper end.
echo "
\n\n";
// Use AJAX?
if ($CFG->useajax) {
// At the bottom because we want to process sections and activities
// after the relevant html has been generated. We're forced to do this
// because of the way in which lib/ajax/ajaxcourse.js is written.
echo '\n";
$COURSE->javascriptportal->print_javascript($course->id);
}
print_footer(NULL, $course);
?>
-----------------------moodle18/course/lib.php-----------
id, '', '', 'u.id, u.firstname, u.lastname')) {
foreach ($courseusers as $courseuser) {
$users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
}
}
if ($guest = get_guest()) {
$users[$guest->id] = fullname($guest);
}
if (has_capability('moodle/course:update', get_context_instance(CONTEXT_SYSTEM, SITEID))) {
if ($ccc = get_records("course", "", "", "fullname")) {
foreach ($ccc as $cc) {
if ($cc->category) {
$courses["$cc->id"] = "$cc->fullname";
} else {
$courses["$cc->id"] = " $cc->fullname (Site)";
}
}
}
asort($courses);
}
$activities = array();
$selectedactivity = $modid;
/// Casting $course->modinfo to string prevents one notice when the field is null
if ($modinfo = unserialize((string)$course->modinfo)) {
$section = 0;
if ($course->format == 'weeks') { // Body
$strsection = get_string("week");
} else {
$strsection = get_string("topic");
}
$activities["activity/All"] = "All activities";
$activities["activity/Assignments"] = "All assignments";
$activities["activity/Chats"] = "All chats";
$activities["activity/Forums"] = "All forums";
$activities["activity/Quizzes"] = "All quizzes";
$activities["activity/Workshops"] = "All workshops";
$activities["section/individual"] = "------------- Individual Activities --------------";
foreach ($modinfo as $mod) {
if ($mod->mod == "label") {
continue;
}
if (!$mod->visible and !has_capability('moodle/course:viewhiddenactivities',get_context_instance(CONTEXT_MODULE, $mod->cm))) {
continue;
}
if ($mod->section > 0 and $section <> $mod->section) {
$activities["section/$mod->section"] = "-------------- $strsection $mod->section --------------";
}
$section = $mod->section;
$mod->name = strip_tags(format_string(urldecode($mod->name),true));
if (strlen($mod->name) > 55) {
$mod->name = substr($mod->name, 0, 50)."...";
}
if (!$mod->visible) {
$mod->name = "(".$mod->name.")";
}
$activities["$mod->cm"] = $mod->name;
if ($mod->cm == $modid) {
$selectedactivity = "$mod->cm";
}
}
}
$strftimedate = get_string("strftimedate");
$strftimedaydate = get_string("strftimedaydate");
asort($users);
// Get all the possible dates
// Note that we are keeping track of real (GMT) time and user time
// User time is only used in displays - all calcs and passing is GMT
$timenow = time(); // GMT
// What day is it now for the user, and when is midnight that day (in GMT).
$timemidnight = $today = usergetmidnight($timenow);
$dates = array();
$dates["$USER->lastlogin"] = get_string("lastlogin").", ".userdate($USER->lastlogin, $strftimedate);
$dates["$timemidnight"] = get_string("today").", ".userdate($timenow, $strftimedate);
if (!$course->startdate or ($course->startdate > $timenow)) {
$course->startdate = $course->timecreated;
}
$numdates = 1;
while ($timemidnight > $course->startdate and $numdates < 365) {
$timemidnight = $timemidnight - 86400;
$timenow = $timenow - 86400;
$dates["$timemidnight"] = userdate($timenow, $strftimedaydate);
$numdates++;
}
if ($selecteddate === "lastlogin") {
$selecteddate = $USER->lastlogin;
}
echo '";
} else {
$day_list = array("1","7","14","21","30");
$strsince = get_string("since");
$strlastlogin = get_string("lastlogin");
$strday = get_string("day");
$strdays = get_string("days");
$heading = "";
foreach ($day_list as $count) {
if ($count == "1") {
$day = $strday;
} else {
$day = $strdays;
}
$tmpdate = time() - ($count * 3600 * 24);
$heading = $heading .
"wwwroot/course/recent.php?id=$course->id&date=$tmpdate\"> $count $day | ";
}
$heading = $strsince . ": wwwroot/course/recent.php?id=$course->id\">$strlastlogin" . " | " . $heading;
print_heading($heading);
$advancedlink = "wwwroot/course/recent.php?id=$course->id&advancedfilter=1\">" . get_string("advancedfilter") . "";
print_heading($advancedlink);
}
}
function make_log_url($module, $url) {
switch ($module) {
case 'user':
case 'course':
case 'file':
case 'login':
case 'lib':
case 'admin':
case 'message':
case 'calendar':
case 'blog':
return "/$module/$url";
break;
case 'upload':
return $url;
break;
case 'library':
case '':
return '/';
break;
default:
return "/mod/$module/$url";
break;
}
}
function build_mnet_logs_array($hostid, $course, $user=0, $date=0, $order="l.time ASC", $limitfrom='', $limitnum='',
$modname="", $modid=0, $modaction="", $groupid=0) {
global $CFG;
// It is assumed that $date is the GMT time of midnight for that day,
// and so the next 86400 seconds worth of logs are printed.
/// Setup for group handling.
// TODO: I don't understand group/context/etc. enough to be able to do
// something interesting with it here
// What is the context of a remote course?
/// If the group mode is separate, and this user does not have editing privileges,
/// then only the user's group can be viewed.
//if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
// $groupid = get_current_group($course->id);
//}
/// If this course doesn't have groups, no groupid can be specified.
//else if (!$course->groupmode) {
// $groupid = 0;
//}
$groupid = 0;
$joins = array();
$qry = "
SELECT
l.*,
u.firstname,
u.lastname,
u.picture
FROM
{$CFG->prefix}mnet_log l
LEFT JOIN
{$CFG->prefix}user u
ON
l.userid = u.id
WHERE
";
$where .= "l.hostid = '$hostid'";
// TODO: Is 1 really a magic number referring to the sitename?
if ($course != 1 || $modid != 0) {
$where .= " AND\n l.course='$course'";
}
if ($modname) {
$where .= " AND\n l.module = '$modname'";
}
if ('site_errors' === $modid) {
$where .= " AND\n ( l.action='error' OR l.action='infected' )";
} else if ($modid) {
//TODO: This assumes that modids are the same across sites... probably
//not true
$where .= " AND\n l.cmid = '$modid'";
}
if ($modaction) {
$firstletter = substr($modaction, 0, 1);
if (ctype_alpha($firstletter)) {
$where .= " AND\n lower(l.action) LIKE '%" . strtolower($modaction) . "%'";
} else if ($firstletter == '-') {
$where .= " AND\n lower(l.action) NOT LIKE '%" . strtolower(substr($modaction, 1)) . "%'";
}
}
if ($user) {
$where .= " AND\n l.userid = '$user'";
}
if ($date) {
$enddate = $date + 86400;
$where .= " AND\n l.time > '$date' AND l.time < '$enddate'";
}
$result = array();
$result['totalcount'] = count_records_sql("SELECT COUNT(*) FROM {$CFG->prefix}mnet_log l WHERE $where");
if(!empty($result['totalcount'])) {
$where .= "\n ORDER BY\n $order";
$result['logs'] = get_records_sql($qry.$where, $limitfrom, $limitnum);
} else {
$result['logs'] = array();
}
return $result;
}
function build_logs_array($course, $user=0, $date=0, $order="l.time ASC", $limitfrom='', $limitnum='',
$modname="", $modid=0, $modaction="", $groupid=0) {
// It is assumed that $date is the GMT time of midnight for that day,
// and so the next 86400 seconds worth of logs are printed.
/// Setup for group handling.
/// If the group mode is separate, and this user does not have editing privileges,
/// then only the user's group can be viewed.
if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
$groupid = get_current_group($course->id);
}
/// If this course doesn't have groups, no groupid can be specified.
else if (!$course->groupmode) {
$groupid = 0;
}
$joins = array();
if ($course->id != SITEID || $modid != 0) {
$joins[] = "l.course='$course->id'";
}
if ($modname) {
$joins[] = "l.module = '$modname'";
}
if ('site_errors' === $modid) {
$joins[] = "( l.action='error' OR l.action='infected' )";
} else if ($modid) {
$joins[] = "l.cmid = '$modid'";
}
if ($modaction) {
$firstletter = substr($modaction, 0, 1);
if (ctype_alpha($firstletter)) {
$joins[] = "lower(l.action) LIKE '%" . strtolower($modaction) . "%'";
} else if ($firstletter == '-') {
$joins[] = "lower(l.action) NOT LIKE '%" . strtolower(substr($modaction, 1)) . "%'";
}
}
/// Getting all members of a group.
if ($groupid and !$user) {
if ($gusers = groups_get_members($groupid)) { //TODO:check.
$first = true;
foreach($gusers as $guser) {
if ($first) {
$gselect = '(l.userid='.$guser->userid;
$first = false;
}
else {
$gselect .= ' OR l.userid='.$guser->userid;
}
}
if (!$first) $gselect .= ')';
$joins[] = $gselect;
}
}
else if ($user) {
$joins[] = "l.userid = '$user'";
}
if ($date) {
$enddate = $date + 86400;
$joins[] = "l.time > '$date' AND l.time < '$enddate'";
}
$selector = '';
for ($i = 0; $i < count($joins); $i++) {
$selector .= $joins[$i] . (($i == count($joins)-1) ? " " : " AND ");
}
$totalcount = 0; // Initialise
$result = array();
$result['logs'] = get_logs($selector, $order, $limitfrom, $limitnum, $totalcount);
$result['totalcount'] = $totalcount;
return $result;
}
function print_log($course, $user=0, $date=0, $order="l.time ASC", $page=0, $perpage=100,
$url="", $modname="", $modid=0, $modaction="", $groupid=0) {
global $CFG;
if (!$logs = build_logs_array($course, $user, $date, $order, $page*$perpage, $perpage,
$modname, $modid, $modaction, $groupid)) {
notify("No logs found!");
print_footer($course);
exit;
}
$courses = array();
if ($course->id == SITEID) {
$courses[0] = '';
if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
foreach ($ccc as $cc) {
$courses[$cc->id] = $cc->shortname;
}
}
} else {
$courses[$course->id] = $course->shortname;
}
$totalcount = $logs['totalcount'];
$count=0;
$ldcache = array();
$tt = getdate(time());
$today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
$strftimedatetime = get_string("strftimedatetime");
echo "\n";
print_string("displayingrecords", "", $totalcount);
echo "
\n";
print_paging_bar($totalcount, $page, $perpage, "$url&perpage=$perpage&");
echo ''."\n";
// echo "\n";
echo "";
if ($course->id == SITEID) {
echo "".get_string('course')." | \n";
}
echo "".get_string('time')." | \n";
echo "".get_string('ip_address')." | \n";
echo "".get_string('fullname')." | \n";
echo "".get_string('action')." | \n";
echo "".get_string('info')." | \n";
echo "
\n";
if (empty($logs['logs'])) {
echo "
\n";
return;
}
$row = 1;
foreach ($logs['logs'] as $log) {
$row = ($row + 1) % 2;
if (isset($ldcache[$log->module][$log->action])) {
$ld = $ldcache[$log->module][$log->action];
} else {
$ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
$ldcache[$log->module][$log->action] = $ld;
}
if ($ld && !empty($log->info)) {
// ugly hack to make sure fullname is shown correctly
if (($ld->mtable == 'user') and ($ld->field == sql_concat('firstname', "' '" , 'lastname'))) {
$log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
} else {
$log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
}
}
//Filter log->info
$log->info = format_string($log->info);
$log->url = strip_tags(urldecode($log->url)); // Some XSS protection
$log->info = strip_tags(urldecode($log->info)); // Some XSS protection
$log->url = str_replace('&', '&', $log->url); /// XHTML compatibility
echo '';
if ($course->id == SITEID) {
echo "\n";
echo " wwwroot}/course/view.php?id={$log->course}\">". format_string($courses[$log->course])."\n";
echo " | \n";
}
echo "".userdate($log->time, '%a').
' '.userdate($log->time, $strftimedatetime)." | \n";
echo "\n";
link_to_popup_window("/iplookup/index.php?ip=$log->ip&user=$log->userid", 'iplookup',$log->ip, 400, 700);
echo " | \n";
$fullname = fullname($log, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
echo "\n";
echo " wwwroot/user/view.php?id={$log->userid}&course={$log->course}\">$fullname\n";
echo " | \n";
echo "\n";
link_to_popup_window( make_log_url($log->module,$log->url), 'fromloglive',"$log->module $log->action", 400, 600);
echo " | \n";;
echo "{$log->info} | \n";
echo "
\n";
}
echo "
\n";
print_paging_bar($totalcount, $page, $perpage, "$url&perpage=$perpage&");
}
function print_mnet_log($hostid, $course, $user=0, $date=0, $order="l.time ASC", $page=0, $perpage=100,
$url="", $modname="", $modid=0, $modaction="", $groupid=0) {
global $CFG;
if (!$logs = build_mnet_logs_array($hostid, $course, $user, $date, $order, $page*$perpage, $perpage,
$modname, $modid, $modaction, $groupid)) {
notify("No logs found!");
print_footer($course);
exit;
}
if ($course->id == SITEID) {
$courses[0] = '';
if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname,c.visible')) {
foreach ($ccc as $cc) {
$courses[$cc->id] = $cc->shortname;
}
}
}
$totalcount = $logs['totalcount'];
$count=0;
$ldcache = array();
$tt = getdate(time());
$today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
$strftimedatetime = get_string("strftimedatetime");
echo "\n";
print_string("displayingrecords", "", $totalcount);
echo "
\n";
print_paging_bar($totalcount, $page, $perpage, "$url&perpage=$perpage&");
echo "\n";
echo "";
if ($course->id == SITEID) {
echo "".get_string('course')." | \n";
}
echo "".get_string('time')." | \n";
echo "".get_string('ip_address')." | \n";
echo "".get_string('fullname')." | \n";
echo "".get_string('action')." | \n";
echo "".get_string('info')." | \n";
echo "
\n";
if (empty($logs['logs'])) {
echo "
\n";
return;
}
$row = 1;
foreach ($logs['logs'] as $log) {
$log->info = $log->coursename;
$row = ($row + 1) % 2;
if (isset($ldcache[$log->module][$log->action])) {
$ld = $ldcache[$log->module][$log->action];
} else {
$ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
$ldcache[$log->module][$log->action] = $ld;
}
if (0 && $ld && !empty($log->info)) {
// ugly hack to make sure fullname is shown correctly
if (($ld->mtable == 'user') and ($ld->field == sql_concat('firstname', "' '" , 'lastname'))) {
$log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
} else {
$log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
}
}
//Filter log->info
$log->info = format_string($log->info);
$log->url = strip_tags(urldecode($log->url)); // Some XSS protection
$log->info = strip_tags(urldecode($log->info)); // Some XSS protection
$log->url = str_replace('&', '&', $log->url); /// XHTML compatibility
echo '';
if ($course->id == SITEID) {
echo "\n";
echo " wwwroot}/course/view.php?id={$log->course}\">".$courses[$log->course]."\n";
echo " | \n";
}
echo "".userdate($log->time, '%a').
' '.userdate($log->time, $strftimedatetime)." | \n";
echo "\n";
link_to_popup_window("/iplookup/index.php?ip=$log->ip&user=$log->userid", 'iplookup',$log->ip, 400, 700);
echo " | \n";
$fullname = fullname($log, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
echo "\n";
echo " wwwroot/user/view.php?id={$log->userid}\">$fullname\n";
echo " | \n";
echo "\n";
echo $log->action .': '.$log->module;
echo " | \n";;
echo "{$log->info} | \n";
echo "
\n";
}
echo "\n";
print_paging_bar($totalcount, $page, $perpage, "$url&perpage=$perpage&");
}
function print_log_csv($course, $user, $date, $order='l.time DESC', $modname,
$modid, $modaction, $groupid) {
$text = get_string('course')."\t".get_string('time')."\t".get_string('ip_address')."\t".
get_string('fullname')."\t".get_string('action')."\t".get_string('info');
if (!$logs = build_logs_array($course, $user, $date, $order, '', '',
$modname, $modid, $modaction, $groupid)) {
return false;
}
$courses = array();
if ($course->id == SITEID) {
$courses[0] = '';
if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
foreach ($ccc as $cc) {
$courses[$cc->id] = $cc->shortname;
}
}
} else {
$courses[$course->id] = $course->shortname;
}
$count=0;
$ldcache = array();
$tt = getdate(time());
$today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
$strftimedatetime = get_string("strftimedatetime");
$filename = 'logs_'.userdate(time(),get_string('backupnameformat'),99,false);
$filename .= '.txt';
header("Content-Type: application/download\n");
header("Content-Disposition: attachment; filename=$filename");
header("Expires: 0");
header("Cache-Control: must-revalidate,post-check=0,pre-check=0");
header("Pragma: public");
echo get_string('savedat').userdate(time(), $strftimedatetime)."\n";
echo $text;
if (empty($logs['logs'])) {
return true;
}
foreach ($logs['logs'] as $log) {
if (isset($ldcache[$log->module][$log->action])) {
$ld = $ldcache[$log->module][$log->action];
} else {
$ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
$ldcache[$log->module][$log->action] = $ld;
}
if ($ld && !empty($log->info)) {
// ugly hack to make sure fullname is shown correctly
if (($ld->mtable == 'user') and ($ld->field == sql_concat('firstname', "' '" , 'lastname'))) {
$log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
} else {
$log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
}
}
//Filter log->info
$log->info = format_string($log->info);
$log->url = strip_tags(urldecode($log->url)); // Some XSS protection
$log->info = strip_tags(urldecode($log->info)); // Some XSS protection
$log->url = str_replace('&', '&', $log->url); // XHTML compatibility
$firstField = $courses[$log->course];
$fullname = fullname($log, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
$row = array($firstField, userdate($log->time, $strftimedatetime), $log->ip, $fullname, $log->module.' '.$log->action, $log->info);
$text = implode("\t", $row);
echo $text." \n";
}
return true;
}
function print_log_xls($course, $user, $date, $order='l.time DESC', $modname,
$modid, $modaction, $groupid) {
global $CFG;
require_once("$CFG->libdir/excellib.class.php");
if (!$logs = build_logs_array($course, $user, $date, $order, '', '',
$modname, $modid, $modaction, $groupid)) {
return false;
}
$courses = array();
if ($course->id == SITEID) {
$courses[0] = '';
if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
foreach ($ccc as $cc) {
$courses[$cc->id] = $cc->shortname;
}
}
} else {
$courses[$course->id] = $course->shortname;
}
$count=0;
$ldcache = array();
$tt = getdate(time());
$today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
$strftimedatetime = get_string("strftimedatetime");
$nroPages = ceil(count($logs)/(EXCELROWS-FIRSTUSEDEXCELROW+1));
$filename = 'logs_'.userdate(time(),get_string('backupnameformat'),99,false);
$filename .= '.xls';
$workbook = new MoodleExcelWorkbook('-');
$workbook->send($filename);
$worksheet = array();
$headers = array(get_string('course'), get_string('time'), get_string('ip_address'),
get_string('fullname'), get_string('action'), get_string('info'));
// Creating worksheets
for ($wsnumber = 1; $wsnumber <= $nroPages; $wsnumber++) {
$sheettitle = get_string('excel_sheettitle', 'logs', $wsnumber).$nroPages;
$worksheet[$wsnumber] =& $workbook->add_worksheet($sheettitle);
$worksheet[$wsnumber]->set_column(1, 1, 30);
$worksheet[$wsnumber]->write_string(0, 0, get_string('savedat').
userdate(time(), $strftimedatetime));
$col = 0;
foreach ($headers as $item) {
$worksheet[$wsnumber]->write(FIRSTUSEDEXCELROW-1,$col,$item,'');
$col++;
}
}
if (empty($logs['logs'])) {
$workbook->close();
return true;
}
$formatDate =& $workbook->add_format();
$formatDate->set_num_format(get_string('log_excel_date_format'));
$row = FIRSTUSEDEXCELROW;
$wsnumber = 1;
$myxls =& $worksheet[$wsnumber];
foreach ($logs['logs'] as $log) {
if (isset($ldcache[$log->module][$log->action])) {
$ld = $ldcache[$log->module][$log->action];
} else {
$ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
$ldcache[$log->module][$log->action] = $ld;
}
if ($ld && !empty($log->info)) {
// ugly hack to make sure fullname is shown correctly
if (($ld->mtable == 'user') and ($ld->field == sql_concat('firstname', "' '" , 'lastname'))) {
$log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
} else {
$log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
}
}
// Filter log->info
$log->info = format_string($log->info);
$log->info = strip_tags(urldecode($log->info)); // Some XSS protection
if ($nroPages>1) {
if ($row > EXCELROWS) {
$wsnumber++;
$myxls =& $worksheet[$wsnumber];
$row = FIRSTUSEDEXCELROW;
}
}
$myxls->write($row, 0, $courses[$log->course], '');
// Excel counts from 1/1/1900
$excelTime=25569+$log->time/(3600*24);
$myxls->write($row, 1, $excelTime, $formatDate);
$myxls->write($row, 2, $log->ip, '');
$fullname = fullname($log, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
$myxls->write($row, 3, $fullname, '');
$myxls->write($row, 4, $log->module.' '.$log->action, '');
$myxls->write($row, 5, $log->info, '');
$row++;
}
$workbook->close();
return true;
}
function print_log_ods($course, $user, $date, $order='l.time DESC', $modname,
$modid, $modaction, $groupid) {
global $CFG;
require_once("$CFG->libdir/odslib.class.php");
if (!$logs = build_logs_array($course, $user, $date, $order, '', '',
$modname, $modid, $modaction, $groupid)) {
return false;
}
$courses = array();
if ($course->id == SITEID) {
$courses[0] = '';
if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
foreach ($ccc as $cc) {
$courses[$cc->id] = $cc->shortname;
}
}
} else {
$courses[$course->id] = $course->shortname;
}
$count=0;
$ldcache = array();
$tt = getdate(time());
$today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
$strftimedatetime = get_string("strftimedatetime");
$nroPages = ceil(count($logs)/(EXCELROWS-FIRSTUSEDEXCELROW+1));
$filename = 'logs_'.userdate(time(),get_string('backupnameformat'),99,false);
$filename .= '.ods';
$workbook = new MoodleODSWorkbook('-');
$workbook->send($filename);
$worksheet = array();
$headers = array(get_string('course'), get_string('time'), get_string('ip_address'),
get_string('fullname'), get_string('action'), get_string('info'));
// Creating worksheets
for ($wsnumber = 1; $wsnumber <= $nroPages; $wsnumber++) {
$sheettitle = get_string('excel_sheettitle', 'logs', $wsnumber).$nroPages;
$worksheet[$wsnumber] =& $workbook->add_worksheet($sheettitle);
$worksheet[$wsnumber]->set_column(1, 1, 30);
$worksheet[$wsnumber]->write_string(0, 0, get_string('savedat').
userdate(time(), $strftimedatetime));
$col = 0;
foreach ($headers as $item) {
$worksheet[$wsnumber]->write(FIRSTUSEDEXCELROW-1,$col,$item,'');
$col++;
}
}
if (empty($logs['logs'])) {
$workbook->close();
return true;
}
$formatDate =& $workbook->add_format();
$formatDate->set_num_format(get_string('log_excel_date_format'));
$row = FIRSTUSEDEXCELROW;
$wsnumber = 1;
$myxls =& $worksheet[$wsnumber];
foreach ($logs['logs'] as $log) {
if (isset($ldcache[$log->module][$log->action])) {
$ld = $ldcache[$log->module][$log->action];
} else {
$ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
$ldcache[$log->module][$log->action] = $ld;
}
if ($ld && !empty($log->info)) {
// ugly hack to make sure fullname is shown correctly
if (($ld->mtable == 'user') and ($ld->field == sql_concat('firstname', "' '" , 'lastname'))) {
$log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
} else {
$log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
}
}
// Filter log->info
$log->info = format_string($log->info);
$log->info = strip_tags(urldecode($log->info)); // Some XSS protection
if ($nroPages>1) {
if ($row > EXCELROWS) {
$wsnumber++;
$myxls =& $worksheet[$wsnumber];
$row = FIRSTUSEDEXCELROW;
}
}
$myxls->write_string($row, 0, $courses[$log->course]);
$myxls->write_date($row, 1, $log->time);
$myxls->write_string($row, 2, $log->ip);
$fullname = fullname($log, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
$myxls->write_string($row, 3, $fullname);
$myxls->write_string($row, 4, $log->module.' '.$log->action);
$myxls->write_string($row, 5, $log->info);
$row++;
}
$workbook->close();
return true;
}
function print_log_graph($course, $userid=0, $type="course.png", $date=0) {
global $CFG;
if (empty($CFG->gdversion)) {
echo "(".get_string("gdneed").")";
} else {
echo '
';
}
}
function print_overview($courses) {
global $CFG, $USER;
$htmlarray = array();
if ($modules = get_records('modules')) {
foreach ($modules as $mod) {
if (file_exists(dirname(dirname(__FILE__)).'/mod/'.$mod->name.'/lib.php')) {
require_once(dirname(dirname(__FILE__)).'/mod/'.$mod->name.'/lib.php');
$fname = $mod->name.'_print_overview';
if (function_exists($fname)) {
$fname($courses,$htmlarray);
}
}
}
}
foreach ($courses as $course) {
print_simple_box_start('center', '100%', '', 5, "coursebox");
$linkcss = '';
if (empty($course->visible)) {
$linkcss = 'class="dimmed"';
}
print_heading(''. format_string($course->fullname).'');
if (array_key_exists($course->id,$htmlarray)) {
foreach ($htmlarray[$course->id] as $modname => $html) {
echo $html;
}
}
print_simple_box_end();
}
}
function print_recent_activity($course) {
// $course is an object
// This function trawls through the logs looking for
// anything new since the user's last login
global $CFG, $USER, $SESSION;
$context = get_context_instance(CONTEXT_COURSE, $course->id);
$timestart = time() - COURSE_MAX_RECENT_PERIOD;
if (!has_capability('moodle/legacy:guest', $context, NULL, false)) {
if (!empty($USER->lastcourseaccess[$course->id])) {
if ($USER->lastcourseaccess[$course->id] > $timestart) {
$timestart = $USER->lastcourseaccess[$course->id];
}
}
}
echo '';
echo get_string('activitysince', '', userdate($timestart));
echo '
';
echo '\n";
// Firstly, have there been any new enrolments?
$heading = false;
$content = false;
$users = get_recent_enrolments($course->id, $timestart);
//Accessibility: new users now appear in an list.
if ($users) {
echo '';
if (! $heading) {
print_headline(get_string("newusers").':', 3);
$heading = true;
$content = true;
}
echo "
\n";
foreach ($users as $user) {
$fullname = fullname($user, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
echo '- id&course=$course->id\">$fullname
\n";
}
echo "
\n
\n";
}
// Next, have there been any modifications to the course structure?
$logs = get_records_select('log', "time > '$timestart' AND course = '$course->id' AND
module = 'course' AND action LIKE '% mod'", "time ASC");
if ($logs) {
foreach ($logs as $key => $log) {
$info = split(' ', $log->info);
if ($info[0] == 'label') { // Labels are special activities
continue;
}
$modname = get_field($info[0], 'name', 'id', $info[1]);
//Create a temp valid module structure (course,id)
$tempmod->course = $log->course;
$tempmod->id = $info[1];
//Obtain the visible property from the instance
$modvisible = instance_is_visible($info[0],$tempmod);
//Only if the mod is visible
if ($modvisible) {
switch ($log->action) {
case 'add mod':
$stradded = get_string('added', 'moodle', get_string('modulename', $info[0]));
$changelist[$log->info] = array ('operation' => 'add', 'text' => "$stradded:
wwwroot/course/$log->url\">".format_string($modname,true)."");
break;
case 'update mod':
$strupdated = get_string('updated', 'moodle', get_string('modulename', $info[0]));
if (empty($changelist[$log->info])) {
$changelist[$log->info] = array ('operation' => 'update', 'text' => "$strupdated:
wwwroot/course/$log->url\">".format_string($modname,true)."");
}
break;
case 'delete mod':
if (!empty($changelist[$log->info]['operation']) and
$changelist[$log->info]['operation'] == 'add') {
$changelist[$log->info] = NULL;
} else {
$strdeleted = get_string('deletedactivity', 'moodle', get_string('modulename', $info[0]));
$changelist[$log->info] = array ('operation' => 'delete', 'text' => $strdeleted);
}
break;
}
}
}
}
if (!empty($changelist)) {
foreach ($changelist as $changeinfo => $change) {
if ($change) {
$changes[$changeinfo] = $change;
}
}
if (isset($changes)){
if (count($changes) > 0) {
print_headline(get_string('courseupdates').':', 3);
$content = true;
foreach ($changes as $changeinfo => $change) {
echo ''.$change['text'].'
';
}
}
}
}
// Now display new things from each module
$mods = get_records('modules', 'visible', '1', 'name', 'id, name');
$viewfullnames = has_capability('moodle/site:viewfullnames', $context);
foreach ($mods as $mod) { // Each module gets it's own logs and prints them
include_once($CFG->dirroot.'/mod/'.$mod->name.'/lib.php');
$print_recent_activity = $mod->name.'_print_recent_activity';
if (function_exists($print_recent_activity)) {
//
// NOTE:
// $isteacher (second parameter below) is to be deprecated!
//
// TODO:
// 1) Make sure that all _print_recent_activity functions are
// not using the $isteacher value.
// 2) Eventually, remove the $isteacher parameter from the
// function calls.
//
$modcontent = $print_recent_activity($course, $viewfullnames, $timestart);
if ($modcontent) {
$content = true;
}
}
}
if (! $content) {
echo ''.get_string('nothingnew').'
';
}
}
function get_array_of_activities($courseid) {
// For a given course, returns an array of course activity objects
// Each item in the array contains he following properties:
// cm - course module id
// mod - name of the module (eg forum)
// section - the number of the section (eg week or topic)
// name - the name of the instance
// visible - is the instance visible or not
// extra - contains extra string to include in any link
global $CFG;
$mod = array();
if (!$rawmods = get_course_mods($courseid)) {
return NULL;
}
if ($sections = get_records("course_sections", "course", $courseid, "section ASC")) {
foreach ($sections as $section) {
if (!empty($section->sequence)) {
$sequence = explode(",", $section->sequence);
foreach ($sequence as $seq) {
if (empty($rawmods[$seq])) {
continue;
}
$mod[$seq]->cm = $rawmods[$seq]->id;
$mod[$seq]->mod = $rawmods[$seq]->modname;
$mod[$seq]->section = $section->section;
$mod[$seq]->name = urlencode(get_field($rawmods[$seq]->modname, "name", "id", $rawmods[$seq]->instance));
$mod[$seq]->visible = $rawmods[$seq]->visible;
$mod[$seq]->extra = "";
$modname = $mod[$seq]->mod;
$functionname = $modname."_get_coursemodule_info";
include_once("$CFG->dirroot/mod/$modname/lib.php");
if (function_exists($functionname)) {
if ($info = $functionname($rawmods[$seq])) {
if (!empty($info->extra)) {
$mod[$seq]->extra = $info->extra;
}
if (!empty($info->icon)) {
$mod[$seq]->icon = $info->icon;
}
}
}
}
}
}
}
return $mod;
}
function get_all_mods($courseid, &$mods, &$modnames, &$modnamesplural, &$modnamesused) {
// Returns a number of useful structures for course displays
$mods = NULL; // course modules indexed by id
$modnames = NULL; // all course module names (except resource!)
$modnamesplural= NULL; // all course module names (plural form)
$modnamesused = NULL; // course module names used
if ($allmods = get_records("modules")) {
foreach ($allmods as $mod) {
if ($mod->visible) {
$modnames[$mod->name] = get_string("modulename", "$mod->name");
$modnamesplural[$mod->name] = get_string("modulenameplural", "$mod->name");
}
}
asort($modnames);
} else {
error("No modules are installed!");
}
if ($rawmods = get_course_mods($courseid)) {
foreach($rawmods as $mod) { // Index the mods
if (empty($modnames[$mod->modname])) {
continue;
}
$mods[$mod->id] = $mod;
$mods[$mod->id]->modfullname = $modnames[$mod->modname];
if ($mod->visible or has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_COURSE, $courseid))) {
$modnamesused[$mod->modname] = $modnames[$mod->modname];
}
}
if ($modnamesused) {
asort($modnamesused);
}
}
}
function get_all_sections($courseid) {
return get_records("course_sections", "course", "$courseid", "section",
"section, id, course, summary, sequence, visible");
}
function course_set_display($courseid, $display=0) {
global $USER;
if ($display == "all" or empty($display)) {
$display = 0;
}
if (empty($USER->id) or $USER->username == 'guest') {
//do not store settings in db for guests
} else if (record_exists("course_display", "userid", $USER->id, "course", $courseid)) {
set_field("course_display", "display", $display, "userid", $USER->id, "course", $courseid);
} else {
$record->userid = $USER->id;
$record->course = $courseid;
$record->display = $display;
if (!insert_record("course_display", $record)) {
notify("Could not save your course display!");
}
}
return $USER->display[$courseid] = $display; // Note: = not ==
}
function set_section_visible($courseid, $sectionnumber, $visibility) {
/// For a given course section, markes it visible or hidden,
/// and does the same for every activity in that section
if ($section = get_record("course_sections", "course", $courseid, "section", $sectionnumber)) {
set_field("course_sections", "visible", "$visibility", "id", $section->id);
if (!empty($section->sequence)) {
$modules = explode(",", $section->sequence);
foreach ($modules as $moduleid) {
set_coursemodule_visible($moduleid, $visibility, true);
}
}
rebuild_course_cache($courseid);
}
}
function print_section($course, $section, $mods, $modnamesused, $absolute=false, $width="100%") {
/// Prints a section full of activity modules
global $CFG, $USER;
static $groupbuttons;
static $groupbuttonslink;
static $isteacher;
static $isediting;
static $ismoving;
static $strmovehere;
static $strmovefull;
static $strunreadpostsone;
static $untracked;
static $usetracking;
$labelformatoptions = New stdClass;
if (!isset($isteacher)) {
$groupbuttons = ($course->groupmode or (!$course->groupmodeforce));
$groupbuttonslink = (!$course->groupmodeforce);
$isediting = isediting($course->id);
$ismoving = $isediting && ismoving($course->id);
if ($ismoving) {
$strmovehere = get_string("movehere");
$strmovefull = strip_tags(get_string("movefull", "", "'$USER->activitycopyname'"));
}
include_once($CFG->dirroot.'/mod/forum/lib.php');
if ($usetracking = forum_tp_can_track_forums()) {
$strunreadpostsone = get_string('unreadpostsone', 'forum');
$untracked = forum_tp_get_untracked_forums($USER->id, $course->id);
}
}
$labelformatoptions->noclean = true;
/// Casting $course->modinfo to string prevents one notice when the field is null
$modinfo = unserialize((string)$course->modinfo);
//Acccessibility: replace table with list
';
} else if ($format == 'short') {
$output = '';
} else if ($format == 'navbar') {
$output = '';
}
if ($return) {
return $output;
}
echo $output;
}
function print_remote_course($course, $width="100%") {
global $CFG, $USER;
$linkcss = '';
$url = "{$CFG->wwwroot}/auth/mnet/jump.php?hostid={$course->hostid}&wantsurl=/course/view.php?id={$course->remoteid}";
echo '';
echo '
';
$options = NULL;
$options->noclean = true;
$options->para = false;
echo format_text($course->summary, FORMAT_MOODLE, $options);
echo '
';
echo '
';
echo '';
}
function print_remote_host($host, $width="100%") {
global $CFG, $USER;
$linkcss = '';
echo '';
echo '';
}
/// MODULE FUNCTIONS /////////////////////////////////////////////////////////////////
function add_course_module($mod) {
$mod->added = time();
unset($mod->id);
return insert_record("course_modules", $mod);
}
function add_mod_to_section($mod, $beforemod=NULL) {
/// Given a full mod object with section and course already defined
/// If $before is specified, then this is an existing ID which we
/// will insert the new module before
///
/// Returns the course_sections ID where the mod is inserted
if ($section = get_record("course_sections", "course", "$mod->course", "section", "$mod->section")) {
$section->sequence = trim($section->sequence);
if (empty($section->sequence)) {
$newsequence = "$mod->coursemodule";
} else if ($beforemod) {
$modarray = explode(",", $section->sequence);
if ($key = array_keys ($modarray, $beforemod->id)) {
$insertarray = array($mod->id, $beforemod->id);
array_splice($modarray, $key[0], 1, $insertarray);
$newsequence = implode(",", $modarray);
} else { // Just tack it on the end anyway
$newsequence = "$section->sequence,$mod->coursemodule";
}
} else {
$newsequence = "$section->sequence,$mod->coursemodule";
}
if (set_field("course_sections", "sequence", $newsequence, "id", $section->id)) {
return $section->id; // Return course_sections ID that was used.
} else {
return 0;
}
} else { // Insert a new record
$section->course = $mod->course;
$section->section = $mod->section;
$section->summary = "";
$section->sequence = $mod->coursemodule;
return insert_record("course_sections", $section);
}
}
function set_coursemodule_groupmode($id, $groupmode) {
return set_field("course_modules", "groupmode", $groupmode, "id", $id);
}
/**
* $prevstateoverrides = true will set the visibility of the course module
* to what is defined in visibleold. This enables us to remember the current
* visibility when making a whole section hidden, so that when we toggle
* that section back to visible, we are able to return the visibility of
* the course module back to what it was originally.
*/
function set_coursemodule_visible($id, $visible, $prevstateoverrides=false) {
if (!$cm = get_record('course_modules', 'id', $id)) {
return false;
}
if (!$modulename = get_field('modules', 'name', 'id', $cm->module)) {
return false;
}
if ($events = get_records_select('event', "instance = '$cm->instance' AND modulename = '$modulename'")) {
foreach($events as $event) {
if ($visible) {
show_event($event);
} else {
hide_event($event);
}
}
}
if ($prevstateoverrides) {
if ($visible == '0') {
// Remember the current visible state so we can toggle this back.
set_field('course_modules', 'visibleold', $cm->visible, 'id', $id);
} else {
// Get the previous saved visible states.
return set_field('course_modules', 'visible', $cm->visibleold, 'id', $id);
}
}
return set_field("course_modules", "visible", $visible, "id", $id);
}
/*
* Delete a course module and any associated data at the course level (events)
* Until 1.5 this function simply marked a deleted flag ... now it
* deletes it completely.
*
*/
function delete_course_module($id) {
if (!$cm = get_record('course_modules', 'id', $id)) {
return true;
}
$modulename = get_field('modules', 'name', 'id', $cm->module);
if ($events = get_records_select('event', "instance = '$cm->instance' AND modulename = '$modulename'")) {
foreach($events as $event) {
delete_event($event);
}
}
return delete_records('course_modules', 'id', $cm->id);
}
function delete_mod_from_section($mod, $section) {
if ($section = get_record("course_sections", "id", "$section") ) {
$modarray = explode(",", $section->sequence);
if ($key = array_keys ($modarray, $mod)) {
array_splice($modarray, $key[0], 1);
$newsequence = implode(",", $modarray);
return set_field("course_sections", "sequence", $newsequence, "id", $section->id);
} else {
return false;
}
}
return false;
}
function move_section($course, $section, $move) {
/// Moves a whole course section up and down within the course
global $USER;
if (!$move) {
return true;
}
$sectiondest = $section + $move;
if ($sectiondest > $course->numsections or $sectiondest < 1) {
return false;
}
if (!$sectionrecord = get_record("course_sections", "course", $course->id, "section", $section)) {
return false;
}
if (!$sectiondestrecord = get_record("course_sections", "course", $course->id, "section", $sectiondest)) {
return false;
}
if (!set_field("course_sections", "section", $sectiondest, "id", $sectionrecord->id)) {
return false;
}
if (!set_field("course_sections", "section", $section, "id", $sectiondestrecord->id)) {
return false;
}
// if the focus is on the section that is being moved, then move the focus along
if (isset($USER->display[$course->id]) and ($USER->display[$course->id] == $section)) {
course_set_display($course->id, $sectiondest);
}
// Check for duplicates and fix order if needed.
// There is a very rare case that some sections in the same course have the same section id.
$sections = get_records_select('course_sections', "course = $course->id", 'section ASC');
$n = 0;
foreach ($sections as $section) {
if ($section->section != $n) {
if (!set_field('course_sections', 'section', $n, 'id', $section->id)) {
return false;
}
}
$n++;
}
return true;
}
function moveto_module($mod, $section, $beforemod=NULL) {
/// All parameters are objects
/// Move the module object $mod to the specified $section
/// If $beforemod exists then that is the module
/// before which $modid should be inserted
/// Remove original module from original section
if (! delete_mod_from_section($mod->id, $mod->section)) {
notify("Could not delete module from existing section");
}
/// Update module itself if necessary
if ($mod->section != $section->id) {
$mod->section = $section->id;
if (!update_record("course_modules", $mod)) {
return false;
}
// if moving to a hidden section then hide module
if (!$section->visible) {
set_coursemodule_visible($mod->id, 0);
}
}
/// Add the module into the new section
$mod->course = $section->course;
$mod->section = $section->section; // need relative reference
$mod->coursemodule = $mod->id;
if (! add_mod_to_section($mod, $beforemod)) {
return false;
}
return true;
}
function make_editing_buttons($mod, $absolute=false, $moveselect=true, $indent=-1, $section=-1) {
global $CFG, $USER;
static $str;
static $sesskey;
$modcontext = get_context_instance(CONTEXT_MODULE, $mod->id);
// no permission to edit
if (!has_capability('moodle/course:manageactivities', $modcontext)) {
return false;
}
if (!isset($str)) {
$str->delete = get_string("delete");
$str->move = get_string("move");
$str->moveup = get_string("moveup");
$str->movedown = get_string("movedown");
$str->moveright = get_string("moveright");
$str->moveleft = get_string("moveleft");
$str->update = get_string("update");
$str->duplicate = get_string("duplicate");
$str->hide = get_string("hide");
$str->show = get_string("show");
$str->clicktochange = get_string("clicktochange");
$str->forcedmode = get_string("forcedmode");
$str->groupsnone = get_string("groupsnone");
$str->groupsseparate = get_string("groupsseparate");
$str->groupsvisible = get_string("groupsvisible");
$sesskey = sesskey();
}
if ($section >= 0) {
$section = '&sr='.$section; // Section return
} else {
$section = '';
}
if ($absolute) {
$path = $CFG->wwwroot.'/course';
} else {
$path = '.';
}
if ($mod->visible) {
$hideshow = '
'."\n";
} else {
$hideshow = '
'."\n";
}
if ($mod->groupmode !== false) {
if ($mod->groupmode == SEPARATEGROUPS) {
$grouptitle = $str->groupsseparate;
$groupclass = 'editing_groupsseparate';
$groupimage = $CFG->pixpath.'/t/groups.gif';
$grouplink = $path.'/mod.php?id='.$mod->id.'&groupmode=0&sesskey='.$sesskey;
} else if ($mod->groupmode == VISIBLEGROUPS) {
$grouptitle = $str->groupsvisible;
$groupclass = 'editing_groupsvisible';
$groupimage = $CFG->pixpath.'/t/groupv.gif';
$grouplink = $path.'/mod.php?id='.$mod->id.'&groupmode=1&sesskey='.$sesskey;
} else {
$grouptitle = $str->groupsnone;
$groupclass = 'editing_groupsnone';
$groupimage = $CFG->pixpath.'/t/groupn.gif';
$grouplink = $path.'/mod.php?id='.$mod->id.'&groupmode=2&sesskey='.$sesskey;
}
if ($mod->groupmodelink) {
$groupmode = ''.
'
';
} else {
$groupmode = '
';
}
} else {
$groupmode = "";
}
if (has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $mod->course))) {
if ($moveselect) {
$move = '
'."\n";
} else {
$move = '
'."\n".
'
'."\n";
}
}
$leftright = "";
if ($indent > 0) {
$leftright .= '
'."\n";
}
if ($indent >= 0) {
$leftright .= '
'."\n";
}
return ''."\n".$leftright.$move.
'
'."\n".
'
'."\n".$hideshow.$groupmode."\n".'';
}
/**
* given a course object with shortname & fullname, this function will
* truncate the the number of chars allowed and add ... if it was too long
*/
function course_format_name ($course,$max=100) {
$str = $course->shortname.': '. $course->fullname;
if (strlen($str) <= $max) {
return $str;
}
else {
return substr($str,0,$max-3).'...';
}
}
/**
* This function will return true if the given course is a child course at all
*/
function course_in_meta ($course) {
return record_exists("course_meta","child_course",$course->id);
}
/**
* Print standard form elements on module setup forms in mod/.../mod.html
*/
function print_standard_coursemodule_settings($form) {
if (! $course = get_record('course', 'id', $form->course)) {
error("This course doesn't exist");
}
print_groupmode_setting($form, $course);
print_visible_setting($form, $course);
}
/**
* Print groupmode form element on module setup forms in mod/.../mod.html
*/
function print_groupmode_setting($form, $course=NULL) {
if (empty($course)) {
if (! $course = get_record('course', 'id', $form->course)) {
error("This course doesn't exist");
}
}
if ($form->coursemodule) {
if (! $cm = get_record('course_modules', 'id', $form->coursemodule)) {
error("This course module doesn't exist");
}
} else {
$cm = null;
}
$groupmode = groupmode($course, $cm);
if ($course->groupmode or (!$course->groupmodeforce)) {
echo '';
echo ''.get_string('groupmode').': | ';
echo '';
unset($choices);
$choices[NOGROUPS] = get_string('groupsnone');
$choices[SEPARATEGROUPS] = get_string('groupsseparate');
$choices[VISIBLEGROUPS] = get_string('groupsvisible');
choose_from_menu($choices, 'groupmode', $groupmode, '', '', 0, false, $course->groupmodeforce);
helpbutton('groupmode', get_string('groupmode'));
echo ' |
';
}
}
/**
* Print visibility setting form element on module setup forms in mod/.../mod.html
*/
function print_visible_setting($form, $course=NULL) {
if (empty($course)) {
if (! $course = get_record('course', 'id', $form->course)) {
error("This course doesn't exist");
}
}
if ($form->coursemodule) {
$visible = get_field('course_modules', 'visible', 'id', $form->coursemodule);
} else {
$visible = true;
}
if ($form->mode == 'add') { // in this case $form->section is the section number, not the id
$hiddensection = !get_field('course_sections', 'visible', 'section', $form->section, 'course', $form->course);
} else {
$hiddensection = !get_field('course_sections', 'visible', 'id', $form->section);
}
if ($hiddensection) {
$visible = false;
}
echo '';
echo ''.get_string('visible', '').': | ';
echo '';
unset($choices);
$choices[1] = get_string('show');
$choices[0] = get_string('hide');
choose_from_menu($choices, 'visible', $visible, '', '', 0, false, $hiddensection);
echo ' |
';
}
function update_restricted_mods($course,$mods) {
delete_records("course_allowed_modules","course",$course->id);
if (empty($course->restrictmodules)) {
return;
}
else {
foreach ($mods as $mod) {
if ($mod == 0)
continue; // this is the 'allow none' option
$am->course = $course->id;
$am->module = $mod;
insert_record("course_allowed_modules",$am);
}
}
}
/**
* This function will take an int (module id) or a string (module name)
* and return true or false, whether it's allowed in the given course (object)
* $mod is not allowed to be an object, as the field for the module id is inconsistent
* depending on where in the code it's called from (sometimes $mod->id, sometimes $mod->module)
*/
function course_allowed_module($course,$mod) {
if (empty($course->restrictmodules)) {
return true;
}
// i am not sure this capability is correct
if (has_capability('moodle/course:update', get_context_instance(CONTEXT_SYSTEM, SITEID))) {
return true;
}
if (is_numeric($mod)) {
$modid = $mod;
} else if (is_string($mod)) {
if ($mod = get_field("modules","id","name",$mod))
$modid = $mod;
}
if (empty($modid)) {
return false;
}
return (record_exists("course_allowed_modules","course",$course->id,"module",$modid));
}
/***
*** Efficiently moves many courses around while maintaining
*** sortorder in order.
***
*** $courseids is an array of course ids
***
**/
function move_courses ($courseids, $categoryid) {
global $CFG;
if (!empty($courseids)) {
$courseids = array_reverse($courseids);
foreach ($courseids as $courseid) {
if (! $course = get_record("course", "id", $courseid)) {
notify("Error finding course $courseid");
} else {
// figure out a sortorder that we can use in the destination category
$sortorder = get_field_sql('SELECT MIN(sortorder)-1 AS min
FROM ' . $CFG->prefix . 'course WHERE category=' . $categoryid);
if ($sortorder === false) {
// the category is empty
// rather than let the db default to 0
// set it to > 100 and avoid extra work in fix_coursesortorder()
$sortorder = 200;
} else if ($sortorder < 10) {
fix_course_sortorder($categoryid);
}
$course->category = $categoryid;
$course->sortorder = $sortorder;
$course->fullname = addslashes($course->fullname);
$course->shortname = addslashes($course->shortname);
$course->summary = addslashes($course->summary);
$course->password = addslashes($course->password);
$course->teacher = addslashes($course->teacher);
$course->teachers = addslashes($course->teachers);
$course->student = addslashes($course->student);
$course->students = addslashes($course->students);
if (!update_record('course', $course)) {
notify("An error occurred - course not moved!");
}
// parents changed (course category), do not delete child context relations
insert_context_rel(get_context_instance(CONTEXT_COURSE, $course->id), false);
}
}
fix_course_sortorder();
}
return true;
}
/**
* @param string $format Course format ID e.g. 'weeks'
* @return Name that the course format prefers for sections
*/
function get_section_name($format) {
$sectionname = get_string("name$format","format_$format");
if($sectionname == "[[name$format]]") {
$sectionname = get_string("name$format");
}
return $sectionname;
}
/**
* Can the current user delete this course?
* @param int $courseid
* @return boolean
*
* Exception here to fix MDL-7796.
*
* FIXME
* Course creators who can manage activities in the course
* shoule be allowed to delete the course. We do it this
* way because we need a quick fix to bring the functionality
* in line with what we had pre-roles. We can't give the
* default course creator role moodle/course:delete at
* CONTEXT_SYSTEM level because this will allow them to
* delete any course in the site. So we hard code this here
* for now.
*
* @author vyshane AT gmail.com
*/
function can_delete_course($courseid) {
$context = get_context_instance(CONTEXT_COURSE, $courseid);
return ( has_capability('moodle/course:delete', $context)
|| (has_capability('moodle/legacy:coursecreator', $context)
&& has_capability('moodle/course:manageactivities', $context)) );
}
/*
* Create a course and either return a $course object or false
*
* @param object $data - all the data needed for an entry in the 'course' table
*/
function create_course($data) {
global $CFG, $USER;
// preprocess allowed mods
$allowedmods = empty($data->allowedmods) ? array() : $data->allowedmods;
unset($data->allowedmods);
if (!has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) {
if ($CFG->restrictmodulesfor == 'all') {
$data->restrictmodules = 1;
} else {
$data->restrictmodules = 0;
}
}
$data->timecreated = time();
// place at beginning of category
fix_course_sortorder();
$data->sortorder = get_field_sql("SELECT min(sortorder)-1 FROM {$CFG->prefix}course WHERE category=$data->category");
if (empty($data->sortorder)) {
$data->sortorder = 100;
}
if ($newcourseid = insert_record('course', $data)) { // Set up new course
$course = get_record('course', 'id', $newcourseid);
// Setup the blocks
$page = page_create_object(PAGE_COURSE_VIEW, $course->id);
blocks_repopulate_page($page); // Return value not checked because you can always edit later
if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) {
update_restricted_mods($course, $allowedmods);
}
$section = new object();
$section->course = $course->id; // Create a default section.
$section->section = 0;
$section->id = insert_record('course_sections', $section);
fix_course_sortorder();
add_to_log(SITEID, 'course', 'new', 'view.php?id='.$course->id, $data->fullname.' (ID '.$course->id.')');
return $course;
}
return false; // error
}
/*
* Update a course and return true or false
*
* @param object $data - all the data needed for an entry in the 'course' table
*/
function update_course($data) {
global $USER, $CFG;
// preprocess allowed mods
$allowedmods = empty($data->allowedmods) ? array() : $data->allowedmods;
unset($data->allowedmods);
if (!has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) {
unset($data->restrictmodules);
}
$oldcourse = get_record('course', 'id', $data->id); // should not fail, already tested above
if (!has_capability('moodle/course:create', get_context_instance(CONTEXT_COURSECAT, $oldcourse->category))
or !has_capability('moodle/course:create', get_context_instance(CONTEXT_COURSECAT, $data->category))) {
// can not move to new category, keep the old one
unset($data->category);
}
// Update with the new data
if (update_record('course', $data)) {
$course = get_record('course', 'id', $data->id);
add_to_log($course->id, "course", "update", "edit.php?id=$course->id", "");
if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) {
update_restricted_mods($course, $allowedmods);
}
fix_course_sortorder();
// Test for and remove blocks which aren't appropriate anymore
$page = page_create_object(PAGE_COURSE_VIEW, $course->id);
blocks_remove_inappropriate($page);
return true;
}
return false;
}
?>
-----------------------moodle18/lib/pagelib.php-----------***********NEW CHANGES************
dirroot.'/'.$path.'pagelib.php';
if(is_file($file)) {
require($file);
if(!isset($DEFINEDPAGES)) {
error('Imported '.$file.' but found no page classes');
}
return $types[$path] = $DEFINEDPAGES;
}
return false;
}
/**
* Factory function page_create_object(). Called with a numeric ID for a page, it autodetects
* the page type, constructs the correct object and returns it.
*/
function page_create_instance($instance) {
page_id_and_class($id, $class);
return page_create_object($id, $instance);
}
/**
* Factory function page_create_object(). Called with a pagetype identifier and possibly with
* its numeric ID. Returns a fully constructed page_base subclass you can work with.
*/
function page_create_object($type, $id = NULL) {
global $CFG;
$data = new stdClass;
$data->pagetype = $type;
$data->pageid = $id;
$classname = page_map_class($type);
$object = &new $classname;
// TODO: subclassing check here
if ($object->get_type() !== $type) {
// Somehow somewhere someone made a mistake
debugging('Page object\'s type ('. $object->get_type() .') does not match requested type ('. $type .')');
}
$object->init_quick($data);
return $object;
}
/**
* Function page_map_class() is the way for your code to define its own page subclasses and let Moodle recognize them.
* Use it to associate the textual identifier of your Page with the actual class name that has to be instantiated.
*/
function page_map_class($type, $classname = NULL) {
global $CFG;
static $mappings = NULL;
if ($mappings === NULL) {
$mappings = array(
PAGE_COURSE_VIEW => 'page_course'
);
}
if (!empty($type) && !empty($classname)) {
$mappings[$type] = $classname;
}
if (!isset($mappings[$type])) {
debugging('Page class mapping requested for unknown type: '.$type);
}
if (empty($classname) && !class_exists($mappings[$type])) {
debugging('Page class mapping for id "'.$type.'" exists but class "'.$mappings[$type].'" is not defined');
}
return $mappings[$type];
}
/**
* Parent class from which all Moodle page classes derive
*
* @author Jon Papaioannou
* @package pages
* @todo This parent class is very messy still. Please for the moment ignore it and move on to the derived class page_course to see the comments there.
*/
class page_base {
/**
* The string identifier for the type of page being described.
* @var string $type
*/
var $type = NULL;
/**
* The numeric identifier of the page being described.
* @var int $id
*/
var $id = NULL;
/**
* Class bool to determine if the instance's full initialization has been completed.
* @var boolean $full_init_done
*/
var $full_init_done = false;
/**
* The class attribute that Moodle has to assign to the BODY tag for this page.
* @var string $body_class
*/
var $body_class = NULL;
/**
* The id attribute that Moodle has to assign to the BODY tag for this page.
* @var string $body_id
*/
var $body_id = NULL;
/// Class Functions
// CONSTRUCTION
// A whole battery of functions to allow standardized-name constructors in all versions of PHP.
// The constructor is actually called construct()
function page_base() {
$this->construct();
}
function __construct() {
$this->construct();
}
function construct() {
page_id_and_class($this->body_id, $this->body_class);
}
// USER-RELATED THINGS
// By default, no user is editing anything and none CAN edit anything. Developers
// will have to override these settings to let Moodle know when it should grant
// editing rights to the user viewing the page.
function user_allowed_editing() {
trigger_error('Page class does not implement method user_allowed_editing()', E_USER_WARNING);
return false;
}
function user_is_editing() {
trigger_error('Page class does not implement method user_is_editing()', E_USER_WARNING);
return false;
}
// HTML OUTPUT SECTION
// We have absolutely no idea what derived pages are all about
function print_header($title, $morebreadcrumbs) {
trigger_error('Page class does not implement method print_header()', E_USER_WARNING);
return;
}
// BLOCKS RELATED SECTION
// By default, pages don't have any blocks. Override this in your derived class if you need blocks.
function blocks_get_positions() {
return array();
}
// Thus there is no default block position. If you override the above you should override this one too.
// Because this makes sense only if blocks_get_positions() is overridden and because these two should
// be overridden as a group or not at all, this one issues a warning. The sneaky part is that this warning
// will only be seen if you override blocks_get_positions() but NOT blocks_default_position().
function blocks_default_position() {
trigger_error('Page class does not implement method blocks_default_position()', E_USER_WARNING);
return NULL;
}
// If you don't override this, newly constructed pages of this kind won't have any blocks.
function blocks_get_default() {
return '';
}
// If you don't override this, your blocks will not be able to change positions
function blocks_move_position(&$instance, $move) {
return $instance->position;
}
// SELF-REPORTING SECTION
// Derived classes HAVE to define their "home url"
function url_get_path() {
trigger_error('Page class does not implement method url_get_path()', E_USER_WARNING);
return NULL;
}
// It's not always required to pass any arguments to the home url, so this doesn't trigger any errors (sensible default)
function url_get_parameters() {
return array();
}
// This should actually NEVER be overridden unless you have GOOD reason. Works fine as it is.
function url_get_full($extraparams = array()) {
$path = $this->url_get_path();
if(empty($path)) {
return NULL;
}
$params = $this->url_get_parameters();
if (!empty($params)) {
$params = array_merge($params, $extraparams);
} else {
$params = $extraparams;
}
if(empty($params)) {
return $path;
}
$first = true;
foreach($params as $var => $value) {
$path .= $first? '?' : '&';
$path .= $var .'='. urlencode($value);
$first = false;
}
return $path;
}
// This forces implementers to actually hardwire their page identification constant in the class.
// Good thing, if you ask me. That way we can later auto-detect "installed" page types by querying
// the classes themselves in the future.
function get_type() {
trigger_error('Page class does not implement method get_type()', E_USER_ERROR);
return NULL;
}
// Simple stuff, do not override this.
function get_id() {
return $this->id;
}
// "Sensible default" case here. Take it from the body id.
function get_format_name() {
return $this->body_id;
}
// Returns $this->body_class
function get_body_class() {
return $this->body_class;
}
// Returns $this->body_id
function get_body_id() {
return $this->body_id;
}
// Initialize the data members of the parent class
function init_quick($data) {
$this->type = $data->pagetype;
$this->id = $data->pageid;
}
function init_full() {
$this->full_init_done = true;
}
// is this page always editable, regardless of anything else?
function edit_always() {
return (has_capability('moodle/site:manageblocks', get_context_instance(CONTEXT_SYSTEM)) && defined('ADMIN_STICKYBLOCKS'));
}
}
/**
* Class that models the behavior of a moodle course
*
* @author Jon Papaioannou
* @package pages
*/
class page_course extends page_base {
// Any data we might need to store specifically about ourself should be declared here.
// After init_full() is called for the first time, ALL of these variables should be
// initialized correctly and ready for use.
var $courserecord = NULL;
// Do any validation of the officially recognized bits of the data and forward to parent.
// Do NOT load up "expensive" resouces (e.g. SQL data) here!
function init_quick($data) {
if(empty($data->pageid) && !defined('ADMIN_STICKYBLOCKS')) {
error('Cannot quickly initialize page: empty course id');
}
parent::init_quick($data);
}
// Here you should load up all heavy-duty data for your page. Basically everything that
// does not NEED to be loaded for the class to make basic decisions should NOT be loaded
// in init_quick() and instead deferred here. Of course this function had better recognize
// $this->full_init_done to prevent wasteful multiple-time data retrieval.
function init_full() {
if($this->full_init_done) {
return;
}
if (empty($this->id)) {
$this->id = 0; // avoid db errors
}
$this->courserecord = get_record('course', 'id', $this->id);
if(empty($this->courserecord) && !defined('ADMIN_STICKYBLOCKS')) {
error('Cannot fully initialize page: invalid course id '. $this->id);
}
$this->full_init_done = true;
}
// USER-RELATED THINGS
// Can user edit the course page or "sticky page"?
// This is also about editting of blocks BUT mainly activities in course page layout, see
// update_course_icon() - it must use the same capability
function user_allowed_editing() {
if (has_capability('moodle/site:manageblocks', get_context_instance(CONTEXT_SYSTEM)) && defined('ADMIN_STICKYBLOCKS')) {
return true;
}
return has_capability('moodle/course:manageactivities', get_context_instance(CONTEXT_COURSE, $this->id));
}
// Is the user actually editing this course page or "sticky page" right now?
function user_is_editing() {
if (has_capability('moodle/site:manageblocks', get_context_instance(CONTEXT_SYSTEM)) && defined('ADMIN_STICKYBLOCKS')) {
//always in edit mode on sticky page
return true;
}
return isediting($this->id);
}
// HTML OUTPUT SECTION
// This function prints out the common part of the page's header.
// You should NEVER print the header "by hand" in other code.
function print_header($title, $morebreadcrumbs=NULL, $meta='', $bodytags='',$parentlink=NULL) {
global $USER, $CFG, $SESSION;
$this->init_full();
$replacements = array(
'%fullname%' => $this->courserecord->fullname
);
foreach($replacements as $search => $replace) {
$title = str_replace($search, $replace, $title);
}
if($this->courserecord->id == SITEID) {
$breadcrumbs = array();
}
else {
if(!$parentlink && $SESSION->parent) {
$parentlink = array($SESSION->parent => $SESSION->parentlink);
}
if($parentlink) {
$breadcrumbs = array_merge($parentlink, array($this->courserecord->shortname => $CFG->wwwroot.'/course/view.php?id='.$this->courserecord->id));
} else {
$breadcrumbs = array($this->courserecord->shortname => $CFG->wwwroot.'/course/view.php?id='.$this->courserecord->id);
}
}
if(!empty($morebreadcrumbs)) {
$breadcrumbs = array_merge($breadcrumbs, $morebreadcrumbs);
}
$total = count($breadcrumbs);
$current = 1;
$crumbtext = '';
foreach($breadcrumbs as $text => $href) {
if($current++ == $total) {
$crumbtext .= ' '.$text;
}
else {
$crumbtext .= ' '.$text.' ->';
}
}
// The "Editing On" button will be appearing only in the "main" course screen
// (i.e., no breadcrumbs other than the default one added inside this function)
$buttons = switchroles_form($this->courserecord->id) . update_course_icon($this->courserecord->id );
$buttons = empty($morebreadcrumbs) ? $buttons : ' ';
print_header($title, $this->courserecord->fullname, $crumbtext,
'', $meta, true, $buttons, user_login_string($this->courserecord, $USER), false, $bodytags);
echo '';
}
// SELF-REPORTING SECTION
// This is hardwired here so the factory function page_create_object() can be sure there was no mistake.
// Also, it doubles as a way to let others inquire about our type.
function get_type() {
return PAGE_COURSE_VIEW;
}
// This is like the "category" of a page of this "type". For example, if the type is PAGE_COURSE_VIEW
// the format_name is the actual name of the course format. If the type were PAGE_ACTIVITY_VIEW, then
// the format_name might be that activity's name etc.
function get_format_name() {
$this->init_full();
if (defined('ADMIN_STICKYBLOCKS')) {
return PAGE_COURSE_VIEW;
}
if($this->id == SITEID) {
return parent::get_format_name();
}
// This needs to reflect the path hierarchy under Moodle root.
return 'course-view-'.$this->courserecord->format;
}
// This should return a fully qualified path to the URL which is responsible for displaying us.
function url_get_path() {
global $CFG;
if (defined('ADMIN_STICKYBLOCKS')) {
return $CFG->wwwroot.'/'.$CFG->admin.'/stickyblocks.php';
}
if($this->id == SITEID) {
return $CFG->wwwroot .'/index.php';
}
else {
return $CFG->wwwroot .'/course/view.php';
}
}
// This should return an associative array of any GET/POST parameters that are needed by the URL
// which displays us to make it work. If none are needed, return an empty array.
function url_get_parameters() {
if (defined('ADMIN_STICKYBLOCKS')) {
return array('pt' => ADMIN_STICKYBLOCKS);
}
if($this->id == SITEID) {
return array();
}
else {
return array('id' => $this->id);
}
}
// BLOCKS RELATED SECTION
// Which are the positions in this page which support blocks? Return an array containing their identifiers.
// BE CAREFUL, ORDER DOES MATTER! In textual representations, lists of blocks in a page use the ':' character
// to delimit different positions in the page. The part before the first ':' in such a representation will map
// directly to the first item of the array you return here, the second to the next one and so on. This way,
// you can add more positions in the future without interfering with legacy textual representations.
function blocks_get_positions() {
return array(BLOCK_POS_LEFT, BLOCK_POS_RIGHT);
}
// When a new block is created in this page, which position should it go to?
function blocks_default_position() {
return BLOCK_POS_RIGHT;
}
// When we are creating a new page, use the data at your disposal to provide a textual representation of the
// blocks that are going to get added to this new page. Delimit block names with commas (,) and use double
// colons (:) to delimit between block positions in the page. See blocks_get_positions() for additional info.
function blocks_get_default() {
global $CFG;
$this->init_full();
if($this->id == SITEID) {
// Is it the site?
if (!empty($CFG->defaultblocks_site)) {
$blocknames = $CFG->defaultblocks_site;
}
/// Failsafe - in case nothing was defined.
else {
$blocknames = 'site_main_menu,admin_tree:course_summary,calendar_month';
}
}
// It's a normal course, so do it according to the course format
else {
$pageformat = $this->courserecord->format;
if (!empty($CFG->{'defaultblocks_'. $pageformat})) {
$blocknames = $CFG->{'defaultblocks_'. $pageformat};
}
else {
$format_config = $CFG->dirroot.'/course/format/'.$pageformat.'/config.php';
if (@is_file($format_config) && is_readable($format_config)) {
require($format_config);
}
if (!empty($format['defaultblocks'])) {
$blocknames = $format['defaultblocks'];
}
else if (!empty($CFG->defaultblocks)){
$blocknames = $CFG->defaultblocks;
}
/// Failsafe - in case nothing was defined.
else {
$blocknames = 'participants,activity_modules,search_forums,admin,course_list:news_items,calendar_upcoming,recent_activity';
}
}
}
return $blocknames;
}
// Given an instance of a block in this page and the direction in which we want to move it, where is
// it going to go? Return the identifier of the instance's new position. This allows us to tell blocklib
// how we want the blocks to move around in this page in an arbitrarily complex way. If the move as given
// does not make sense, make sure to return the instance's original position.
//
// Since this is going to get called a LOT, pass the instance by reference purely for speed. Do **NOT**
// modify its data in any way, this will actually confuse blocklib!!!
function blocks_move_position(&$instance, $move) {
if($instance->position == BLOCK_POS_LEFT && $move == BLOCK_MOVE_RIGHT) {
return BLOCK_POS_RIGHT;
} else if ($instance->position == BLOCK_POS_RIGHT && $move == BLOCK_MOVE_LEFT) {
return BLOCK_POS_LEFT;
}
return $instance->position;
}
}
/**
* Class that models the common parts of all activity modules
*
* @author Jon Papaioannou
* @package pages
*/
class page_generic_activity extends page_base {
var $activityname = NULL;
var $courserecord = NULL;
var $modulerecord = NULL;
var $activityrecord = NULL;
function init_full() {
if($this->full_init_done) {
return;
}
if(empty($this->activityname)) {
error('Page object derived from page_generic_activity but did not define $this->activityname');
}
$module = get_record('modules', 'name', $this->activityname);
$this->modulerecord = get_record('course_modules', 'module', $module->id, 'instance', $this->id);
if(empty($this->modulerecord)) {
error('Cannot fully initialize page: invalid '.$this->activityname.' instance id '. $this->id);
}
$this->courserecord = get_record('course', 'id', $this->modulerecord->course);
if(empty($this->courserecord)) {
error('Cannot fully initialize page: invalid course id '. $this->modulerecord->course);
}
$this->activityrecord = get_record($this->activityname, 'id', $this->id);
if(empty($this->courserecord)) {
error('Cannot fully initialize page: invalid '.$this->activityname.' id '. $this->id);
}
$this->full_init_done = true;
}
function user_allowed_editing() {
$this->init_full();
return has_capability('moodle/site:manageblocks', get_context_instance(CONTEXT_COURSE, $this->modulerecord->course));
}
function user_is_editing() {
$this->init_full();
return isediting($this->modulerecord->course);
}
function url_get_path() {
global $CFG;
return $CFG->wwwroot .'/mod/'.$this->activityname.'/view.php';
}
function url_get_parameters() {
$this->init_full();
return array('id' => $this->modulerecord->id);
}
function blocks_get_positions() {
return array(BLOCK_POS_LEFT);
}
function blocks_default_position() {
return BLOCK_POS_LEFT;
}
}
?>
-----------------------moodle18/lib/weblib.php -------------------------
libdir/filterlib.php");
require_once("$CFG->libdir/ajax/ajaxlib.php");
/// Constants
/// Define text formatting types ... eventually we can add Wiki, BBcode etc
/**
* Does all sorts of transformations and filtering
*/
define('FORMAT_MOODLE', '0'); // Does all sorts of transformations and filtering
/**
* Plain HTML (with some tags stripped)
*/
define('FORMAT_HTML', '1'); // Plain HTML (with some tags stripped)
/**
* Plain text (even tags are printed in full)
*/
define('FORMAT_PLAIN', '2'); // Plain text (even tags are printed in full)
/**
* Wiki-formatted text
* Deprecated: left here just to note that '3' is not used (at the moment)
* and to catch any latent wiki-like text (which generates an error)
*/
define('FORMAT_WIKI', '3'); // Wiki-formatted text
/**
* Markdown-formatted text http://daringfireball.net/projects/markdown/
*/
define('FORMAT_MARKDOWN', '4'); // Markdown-formatted text http://daringfireball.net/projects/markdown/
/**
* TRUSTTEXT marker - if present in text, text cleaning should be bypassed
*/
define('TRUSTTEXT', '#####TRUSTTEXT#####');
/**
* Allowed tags - string of html tags that can be tested against for safe html tags
* @global string $ALLOWED_TAGS
*/
$ALLOWED_TAGS =
'
| ';
return implode("\n", $menu);
}
/**
* Prints form items with the names $day, $month and $year
*
* @param string $day fieldname
* @param string $month fieldname
* @param string $year fieldname
* @param int $currenttime A default timestamp in GMT
* @param boolean $return
*/
function print_date_selector($day, $month, $year, $currenttime=0, $return=false) {
if (!$currenttime) {
$currenttime = time();
}
$currentdate = usergetdate($currenttime);
for ($i=1; $i<=31; $i++) {
$days[$i] = $i;
}
for ($i=1; $i<=12; $i++) {
$months[$i] = userdate(gmmktime(12,0,0,$i,15,2000), "%B");
}
for ($i=1970; $i<=2020; $i++) {
$years[$i] = $i;
}
return choose_from_menu($days, $day, $currentdate['mday'], '', '', '0', $return)
.choose_from_menu($months, $month, $currentdate['mon'], '', '', '0', $return)
.choose_from_menu($years, $year, $currentdate['year'], '', '', '0', $return);
}
/**
*Prints form items with the names $hour and $minute
*
* @param string $hour fieldname
* @param string ? $minute fieldname
* @param $currenttime A default timestamp in GMT
* @param int $step minute spacing
* @param boolean $return
*/
function print_time_selector($hour, $minute, $currenttime=0, $step=5, $return=false) {
if (!$currenttime) {
$currenttime = time();
}
$currentdate = usergetdate($currenttime);
if ($step != 1) {
$currentdate['minutes'] = ceil($currentdate['minutes']/$step)*$step;
}
for ($i=0; $i<=23; $i++) {
$hours[$i] = sprintf("%02d",$i);
}
for ($i=0; $i<=59; $i+=$step) {
$minutes[$i] = sprintf("%02d",$i);
}
return choose_from_menu($hours, $hour, $currentdate['hours'], '','','0',$return)
.choose_from_menu($minutes, $minute, $currentdate['minutes'], '','','0',$return);
}
/**
* Prints time limit value selector
*
* @uses $CFG
* @param int $timelimit default
* @param string $unit
* @param string $name
* @param boolean $return
*/
function print_timer_selector($timelimit = 0, $unit = '', $name = 'timelimit', $return=false) {
global $CFG;
if ($unit) {
$unit = ' '.$unit;
}
// Max timelimit is sessiontimeout - 10 minutes.
$maxvalue = ($CFG->sessiontimeout / 60) - 10;
for ($i=1; $i<=$maxvalue; $i++) {
$minutes[$i] = $i.$unit;
}
return choose_from_menu($minutes, $name, $timelimit, get_string('none'), '','','0',$return);
}
/**
* Prints a grade menu (as part of an existing form) with help
* Showing all possible numerical grades and scales
*
* @uses $CFG
* @param int $courseid ?
* @param string $name ?
* @param string $current ?
* @param boolean $includenograde ?
* @todo Finish documenting this function
*/
function print_grade_menu($courseid, $name, $current, $includenograde=true, $return=false) {
global $CFG;
$output = '';
$strscale = get_string('scale');
$strscales = get_string('scales');
$scales = get_scales_menu($courseid);
foreach ($scales as $i => $scalename) {
$grades[-$i] = $strscale .': '. $scalename;
}
if ($includenograde) {
$grades[0] = get_string('nograde');
}
for ($i=100; $i>=1; $i--) {
$grades[$i] = $i;
}
$output .= choose_from_menu($grades, $name, $current, '', '', 0, true);
$linkobject = ' ';
$output .= link_to_popup_window ('/course/scales.php?id='. $courseid .'&list=true', 'ratingscales',
$linkobject, 400, 500, $strscales, 'none', true);
if ($return) {
return $output;
} else {
echo $output;
}
}
/**
* Prints a scale menu (as part of an existing form) including help button
* Just like {@link print_grade_menu()} but without the numeric grades
*
* @param int $courseid ?
* @param string $name ?
* @param string $current ?
* @todo Finish documenting this function
*/
function print_scale_menu($courseid, $name, $current, $return=false) {
global $CFG;
$output = '';
$strscales = get_string('scales');
$output .= choose_from_menu(get_scales_menu($courseid), $name, $current, '', '', 0, true);
$linkobject = ' ';
$output .= link_to_popup_window ('/course/scales.php?id='. $courseid .'&list=true', 'ratingscales',
$linkobject, 400, 500, $strscales, 'none', true);
if ($return) {
return $output;
} else {
echo $output;
}
}
/**
* Prints a help button about a scale
*
* @uses $CFG
* @param id $courseid ?
* @param object $scale ?
* @todo Finish documenting this function
*/
function print_scale_menu_helpbutton($courseid, $scale, $return=false) {
global $CFG;
$output = '';
$strscales = get_string('scales');
$linkobject = ' ';
$output .= link_to_popup_window ('/course/scales.php?id='. $courseid .'&list=true&scaleid='. $scale->id, 'ratingscale',
$linkobject, 400, 500, $scale->name, 'none', true);
if ($return) {
return $output;
} else {
echo $output;
}
}
/**
* Print an error page displaying an error message.
* Old method, don't call directly in new code - use print_error instead.
*
*
* @uses $SESSION
* @uses $CFG
* @param string $message The message to display to the user about the error.
* @param string $link The url where the user will be prompted to continue. If no url is provided the user will be directed to the site index page.
*/
function error ($message, $link='', $adminroot=false) {
global $CFG, $SESSION;
$message = clean_text($message); // In case nasties are in here
if (defined('FULLME') && FULLME == 'cron') {
// Errors in cron should be mtrace'd.
mtrace($message);
die;
}
if (! defined('HEADER_PRINTED')) {
//header not yet printed
@header('HTTP/1.0 404 Not Found');
print_header(get_string('error'));
}
echo ' ';
print_simple_box($message, '', '', '', '', 'errorbox');
// in case we are logging upgrade in admin/index.php stop it
if (function_exists('upgrade_log_finish')) {
upgrade_log_finish();
}
if (!$link) {
if ( !empty($SESSION->fromurl) ) {
$link = $SESSION->fromurl;
unset($SESSION->fromurl);
} else {
$link = $CFG->wwwroot .'/';
}
}
if ($adminroot) {
admin_externalpage_print_footer($adminroot);
} else {
print_continue($link);
print_footer();
}
for ($i=0;$i<512;$i++) { // Padding to help IE work with 404
echo ' ';
}
die;
}
/**
* Print an error page displaying an error message. New method - use this for new code.
*
* @uses $SESSION
* @uses $CFG
* @param string $errorcode The name of the string from error.php to print
* @param string $link The url where the user will be prompted to continue. If no url is provided the user will be directed to the site index page.
* @param object $a Extra words and phrases that might be required in the error string
* @param boolean $adminroot Is the page an admin settings page?
*/
function print_error ($errorcode, $module='', $link='', $a=NULL, $adminroot=false) {
global $CFG;
if (empty($module) || $module == 'moodle' || $module == 'core') {
$module = 'error';
$modulelink = 'moodle';
} else {
$modulelink = $module;
}
if (!empty($CFG->errordocroot)) {
$errordocroot = $CFG->errordocroot;
} else if (!empty($CFG->docroot)) {
$errordocroot = $CFG->docroot;
} else {
$errordocroot = 'http://docs.moodle.org';
}
$message = ''.get_string($errorcode, $module, $a).' '.
''.
''.
get_string('moreinformation').' ';
error($message, $link, $adminroot);
}
/**
* Returns a string of html with an image of a help icon linked to a help page on a number of help topics.
* Should be used only with htmleditor or textarea.
* @param mixed $helptopics variable amount of params accepted. Each param may be a string or an array of arguments for
* helpbutton.
* @return string
*/
function editorhelpbutton(){
global $CFG, $SESSION;
$items = func_get_args();
$i = 1;
$urlparams = array();
$titles = array();
foreach ($items as $item){
if (is_array($item)){
$urlparams[] = "keyword$i=".urlencode($item[0]);
$urlparams[] = "title$i=".urlencode($item[1]);
if (isset($item[2])){
$urlparams[] = "module$i=".urlencode($item[2]);
}
$titles[] = trim($item[1], ". \t");
}elseif (is_string($item)){
$urlparams[] = "button$i=".urlencode($item);
switch ($item){
case 'reading' :
$titles[] = get_string("helpreading");
break;
case 'writing' :
$titles[] = get_string("helpwriting");
break;
case 'questions' :
$titles[] = get_string("helpquestions");
break;
case 'emoticons' :
$titles[] = get_string("helpemoticons");
break;
case 'richtext' :
$titles[] = get_string('helprichtext');
break;
case 'text' :
$titles[] = get_string('helptext');
break;
default :
error('Unknown help topic '.$item);
}
}
$i++;
}
if (count($titles)>1){
//join last two items with an 'and'
$a = new object();
$a->one = $titles[count($titles) - 2];
$a->two = $titles[count($titles) - 1];
$titles[count($titles) - 2] = get_string('and', '', $a);
unset($titles[count($titles) - 1]);
}
$alttag = join (', ', $titles);
$paramstring = join('&', $urlparams);
$linkobject = ' ';
return link_to_popup_window(s('/lib/form/editorhelp.php?'.$paramstring), $alttag, $linkobject, 400, 500, $alttag, 'none', true);
}
/**
* Print a help button.
*
* @uses $CFG
* @param string $page The keyword that defines a help page
* @param string $title The title of links, rollover tips, alt tags etc
* 'Help with' (or the language equivalent) will be prefixed and '...' will be stripped.
* @param string $module Which module is the page defined in
* @param mixed $image Use a help image for the link? (true/false/"both")
* @param boolean $linktext If true, display the title next to the help icon.
* @param string $text If defined then this text is used in the page, and
* the $page variable is ignored.
* @param boolean $return If true then the output is returned as a string, if false it is printed to the current page.
* @param string $imagetext The full text for the helpbutton icon. If empty use default help.gif
* @return string
* @todo Finish documenting this function
*/
function helpbutton ($page, $title='', $module='moodle', $image=true, $linktext=false, $text='', $return=false,
$imagetext='') {
global $CFG, $course;
// fix for MDL-7734
if (!empty($course->lang)) {
$forcelang = $course->lang;
} else {
$forcelang = '';
}
if ($module == '') {
$module = 'moodle';
}
$tooltip = get_string('helpprefix2', '', trim($title, ". \t"));
$linkobject = '';
if ($image) {
if ($linktext) {
// MDL-7469 If text link is displayed with help icon, change to alt to "help with this".
$linkobject .= $title.' ';
$tooltip = get_string('helpwiththis');
}
if ($imagetext) {
$linkobject .= $imagetext;
} else {
$linkobject .= ' ';
}
} else {
$linkobject .= $tooltip;
}
$tooltip .= ' ('.get_string('newwindow').')'; // Warn users about new window for Accessibility
// fix for MDL-7734
if ($text) {
$url = '/help.php?module='. $module .'&text='. s(urlencode($text).'&forcelang='.$forcelang);
} else {
$url = '/help.php?module='. $module .'&file='. $page .'.html&forcelang='.$forcelang;
}
$link = ''.
link_to_popup_window ($url, 'popup', $linkobject, 400, 500, $tooltip, 'none', true).
'';
if ($return) {
return $link;
} else {
echo $link;
}
}
/**
* Print a help button.
*
* Prints a special help button that is a link to the "live" emoticon popup
* @uses $CFG
* @uses $SESSION
* @param string $form ?
* @param string $field ?
* @todo Finish documenting this function
*/
function emoticonhelpbutton($form, $field, $return = false) {
global $CFG, $SESSION;
$SESSION->inserttextform = $form;
$SESSION->inserttextfield = $field;
$imagetext = ' ';
$help = helpbutton('emoticons', get_string('helpemoticons'), 'moodle', true, true, '', true, $imagetext);
if (!$return){
echo $help;
} else {
return $help;
}
}
/**
* Print a help button.
*
* Prints a special help button for html editors (htmlarea in this case)
* @uses $CFG
*/
function editorshortcutshelpbutton() {
global $CFG;
$imagetext = ' ';
return helpbutton('editorshortcuts', get_string('editorshortcutkeys'), 'moodle', true, false, '', true, $imagetext);
}
/**
* Print a message and exit.
*
* @uses $CFG
* @param string $message ?
* @param string $link ?
* @todo Finish documenting this function
*/
function notice ($message, $link='', $course=NULL, $adminroot='') {
global $CFG, $SITE;
$message = clean_text($message);
print_box($message, 'generalbox', 'notice');
print_continue($link);
// xhtml strict fix, need to make sure it's the right footer
if ($adminroot) {
admin_externalpage_print_footer($adminroot);
exit;
}
if (empty($course)) {
print_footer($SITE);
} else {
print_footer($course);
}
exit;
}
/**
* Print a message along with "Yes" and "No" links for the user to continue.
*
* @param string $message The text to display
* @param string $linkyes The link to take the user to if they choose "Yes"
* @param string $linkno The link to take the user to if they choose "No"
*/
function notice_yesno ($message, $linkyes, $linkno, $optionsyes=NULL, $optionsno=NULL, $methodyes='post', $methodno='post') {
global $CFG;
$message = clean_text($message);
$linkyes = clean_text($linkyes);
$linkno = clean_text($linkno);
print_box_start('generalbox', 'notice');
echo ''. $message .' ';
echo '';
print_single_button($linkyes, $optionsyes, get_string('yes'), $methodyes, $CFG->framename);
print_single_button($linkno, $optionsno, get_string('no'), $methodno, $CFG->framename);
echo ' ';
print_box_end();
}
/**
* Redirects the user to another page, after printing a notice
*
* @param string $url The url to take the user to
* @param string $message The text message to display to the user about the redirect, if any
* @param string $delay How long before refreshing to the new page at $url?
* @todo '&' needs to be encoded into '&' for XHTML compliance,
* however, this is not true for javascript. Therefore we
* first decode all entities in $url (since we cannot rely on)
* the correct input) and then encode for where it's needed
* echo "";
*/
function redirect($url, $message='', $delay=-1, $adminroot = '') {
global $CFG;
if (!empty($CFG->usesid) && !isset($_COOKIE[session_name()])) {
$url = sid_process_url($url);
}
$message = clean_text($message);
$url = html_entity_decode($url);
$url = str_replace(array("\n", "\r"), '', $url); // some more cleaning
$encodedurl = htmlentities($url);
$tmpstr = clean_text(''); //clean encoded URL
$encodedurl = substr($tmpstr, 9, strlen($tmpstr)-13);
$url = html_entity_decode($encodedurl);
$surl = addslashes($url);
/// when no message and header printed yet, try to redirect
if (empty($message) and !defined('HEADER_PRINTED')) {
// Technically, HTTP/1.1 requires Location: header to contain
// the absolute path. (In practice browsers accept relative
// paths - but still, might as well do it properly.)
// This code turns relative into absolute.
if (!preg_match('|^[a-z]+:|', $url)) {
// Get host name http://www.wherever.com
$hostpart = preg_replace('|^(.*?[^:/])/.*$|', '$1', $CFG->wwwroot);
if (preg_match('|^/|', $url)) {
// URLs beginning with / are relative to web server root so we just add them in
$url = $hostpart.$url;
} else {
// URLs not beginning with / are relative to path of current script, so add that on.
$url = $hostpart.preg_replace('|\?.*$|','',me()).'/../'.$url;
}
// Replace all ..s
while (true) {
$newurl = preg_replace('|/(?!\.\.)[^/]*/\.\./|', '/', $url);
if ($newurl == $url) {
break;
}
$url = $newurl;
}
}
$delay = 0;
//try header redirection first
@header($_SERVER['SERVER_PROTOCOL'] . ' 303 See Other'); //302 might not work for POST requests, 303 is ignored by obsolete clients
@header('Location: '.$url);
//another way for older browsers and already sent headers (eg trailing whitespace in config.php)
echo '';
echo ''; // To cope with Mozilla bug
die;
}
if ($delay == -1) {
$delay = 3; // if no delay specified wait 3 seconds
}
if (! defined('HEADER_PRINTED')) {
// this type of redirect might not be working in some browsers - such as lynx :-(
print_header('', '', '', '', '');
$delay += 3; // double redirect prevention, it was sometimes breaking upgrades before 1.7
}
echo '';
echo ' '. $message .' ';
echo ' ';
echo ' ';
// it might be better not to set timeout the same for both types of redirect, so that we can be sure which one wins
?>
'. $message .''." \n";
if ($return) {
return $output;
}
echo $output;
}
/**
* Given an email address, this function will return an obfuscated version of it
*
* @param string $email The email address to obfuscate
* @return string
*/
function obfuscate_email($email) {
$i = 0;
$length = strlen($email);
$obfuscated = '';
while ($i < $length) {
if (rand(0,2)) {
$obfuscated.='%'.dechex(ord($email{$i}));
} else {
$obfuscated.=$email{$i};
}
$i++;
}
return $obfuscated;
}
/**
* This function takes some text and replaces about half of the characters
* with HTML entity equivalents. Return string is obviously longer.
*
* @param string $plaintext The text to be obfuscated
* @return string
*/
function obfuscate_text($plaintext) {
$i=0;
$length = strlen($plaintext);
$obfuscated='';
$prev_obfuscated = false;
while ($i < $length) {
$c = ord($plaintext{$i});
$numerical = ($c >= ord('0')) && ($c <= ord('9'));
if ($prev_obfuscated and $numerical ) {
$obfuscated.=''.ord($plaintext{$i}).';';
} else if (rand(0,2)) {
$obfuscated.=''.ord($plaintext{$i}).';';
$prev_obfuscated = true;
} else {
$obfuscated.=$plaintext{$i};
$prev_obfuscated = false;
}
$i++;
}
return $obfuscated;
}
/**
* This function uses the {@link obfuscate_email()} and {@link obfuscate_text()}
* to generate a fully obfuscated email link, ready to use.
*
* @param string $email The email address to display
* @param string $label The text to dispalyed as hyperlink to $email
* @param boolean $dimmed If true then use css class 'dimmed' for hyperlink
* @return string
*/
function obfuscate_mailto($email, $label='', $dimmed=false) {
if (empty($label)) {
$label = $email;
}
if ($dimmed) {
$title = get_string('emaildisable');
$dimmed = ' class="dimmed"';
} else {
$title = '';
$dimmed = '';
}
return sprintf("%s",
obfuscate_text('mailto'), obfuscate_email($email),
obfuscate_text($label));
}
/**
* Prints a single paging bar to provide access to other pages (usually in a search)
*
* @param int $totalcount Thetotal number of entries available to be paged through
* @param int $page The page you are currently viewing
* @param int $perpage The number of entries that should be shown per page
* @param string $baseurl The url which will be used to create page numbered links. Each page will consist of the base url appended by the page
var an equal sign, then the page number.
* @param string $pagevar This is the variable name that you use for the page number in your code (ie. 'tablepage', 'blogpage', etc)
* @param bool $nocurr do not display the current page as a link
* @param bool $return whether to return an output string or echo now
* @return bool or string
*/
function print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar='page',$nocurr=false, $return=false) {
$maxdisplay = 18;
$output = '';
if ($totalcount > $perpage) {
$output .= '';
$output .= get_string('page') .':';
if ($page > 0) {
$pagenum = $page - 1;
$output .= ' ( '. get_string('previous') .') ';
}
$lastpage = ceil($totalcount / $perpage);
if ($page > 15) {
$startpage = $page - 10;
$output .= ' 1 ...';
} else {
$startpage = 0;
}
$currpage = $startpage;
$displaycount = 0;
while ($displaycount < $maxdisplay and $currpage < $lastpage) {
$displaypage = $currpage+1;
if ($page == $currpage && empty($nocurr)) {
$output .= ' '. $displaypage;
} else {
$output .= ' '. $displaypage .'';
}
$displaycount++;
$currpage++;
}
if ($currpage < $lastpage) {
$lastpageactual = $lastpage - 1;
$output .= ' ... '. $lastpage .' ';
}
$pagenum = $page + 1;
if ($pagenum != $displaypage) {
$output .= ' ( '. get_string('next') .')';
}
$output .= ' ';
}
if ($return) {
return $output;
}
echo $output;
return true;
}
/**
* This function is used to rebuild the tag because some formats (PLAIN and WIKI)
* will transform it to html entities
*
* @param string $text Text to search for nolink tag in
* @return string
*/
function rebuildnolinktag($text) {
$text = preg_replace('/<(\/*nolink)>/i','<$1>',$text);
return $text;
}
/**
* Prints a nice side block with an optional header. The content can either
* be a block of HTML or a list of text with optional icons.
*
* @param string $heading Block $title embedded in HTML tags, for example .
* @param string $content ?
* @param array $list ?
* @param array $icons ?
* @param string $footer ?
* @param array $attributes ?
* @param string $title Plain text title, as embedded in the $heading.
* @todo Finish documenting this function. Show example of various attributes, etc.
*/
function print_side_block($heading='', $content='', $list=NULL, $icons=NULL, $footer='', $attributes = array(), $title='') {
//Accessibility: skip block link, with title-text (or $block_id) to differentiate links.
static $block_id = 0;
$block_id++;
if (empty($heading)) {
$skip_text = get_string('skipblock', 'access').' '.$block_id;
}
else {
$skip_text = get_string('skipa', 'access', strip_tags($title));
}
$skip_link = ''."\n".''.$skip_text.''."\n".'';
$skip_dest = '';
if (! empty($heading)) {
$heading = $skip_link . $heading;
}
/*else { //ELSE: I think a single link on a page, "Skip block 4" is too confusing - don't print.
echo $skip_link;
}*/
print_side_block_start($heading, $attributes);
if ($content) {
echo $content;
if ($footer) {
echo '';
}
} else {
if ($list) {
$row = 0;
//Accessibility: replaced unnecessary table with list, see themes/standard/styles_layout.css
echo "\n\n";
foreach ($list as $key => $string) {
echo '- ';
if ($icons) {
echo '
'. $icons[$key] .' ';
}
echo ''. $string .' ';
echo " \n";
$row = $row ? 0:1;
}
echo " \n";
}
if ($footer) {
echo '';
}
}
print_side_block_end($attributes);
echo $skip_dest;
}
/**
* Starts a nice side block with an optional header.
*
* @param string $heading ?
* @param array $attributes ?
* @todo Finish documenting this function
*/
function print_side_block_start($heading='', $attributes = array()) {
global $CFG, $THEME;
// If there are no special attributes, give a default CSS class
if (empty($attributes) || !is_array($attributes)) {
$attributes = array('class' => 'sideblock');
} else if(!isset($attributes['class'])) {
$attributes['class'] = 'sideblock';
} else if(!strpos($attributes['class'], 'sideblock')) {
$attributes['class'] .= ' sideblock';
}
// OK, the class is surely there and in addition to anything
// else, it's tagged as a sideblock
/*
// IE misery: if I do it this way, blocks which start hidden cannot be "unhidden"
// If there is a cookie to hide this thing, start it hidden
if (!empty($attributes['id']) && isset($_COOKIE['hide:'.$attributes['id']])) {
$attributes['class'] = 'hidden '.$attributes['class'];
}
*/
$attrtext = '';
foreach ($attributes as $attr => $val) {
$attrtext .= ' '.$attr.'="'.$val.'"';
}
echo '';
if ($heading) {
//Accessibility: replaced with H2; no, H2 more appropriate in moodleblock.class.php: _title_html.
// echo '';
echo '';
} else {
if (!empty($THEME->roundcorners)) {
echo ' ';
}
}
if (!empty($THEME->roundcorners)) {
echo ' ';
}
echo ' ';
}
/**
* Print table ending tags for a side block box.
*/
function print_side_block_end($attributes = array()) {
global $CFG, $THEME;
echo ' ';
if (!empty($THEME->roundcorners)) {
echo ' ';
echo ' ';
}
echo ' ';
// IE workaround: if I do it THIS way, it works! WTF?
if (!empty($CFG->allowuserblockhiding) && isset($attributes['id'])) {
echo '';
}
}
/**
* Prints out code needed for spellchecking.
* Original idea by Ludo (Marc Alier).
*
* Opening CDATA and |
---|