? config.php ? patch.txt Index: course/lib.php =================================================================== RCS file: /cvsroot/moodle/moodle/course/lib.php,v retrieving revision 1.538.2.79 diff -u -r1.538.2.79 lib.php --- course/lib.php 9 Sep 2009 12:45:14 -0000 1.538.2.79 +++ course/lib.php 22 Jan 2010 12:22:00 -0000 @@ -2146,16 +2146,47 @@ error("It shouldn't be possible to see My Moodle without being logged in."); } - $courses = get_my_courses($USER->id, 'visible DESC,sortorder ASC', array('summary')); + $coursepage = optional_param('coursepage', 0, PARAM_INT); + $courses = get_my_courses($USER->id, 'visible DESC,sortorder ASC', array('summary'), false, 0, $coursepage); $rhosts = array(); $rcourses = array(); + + // calculate the pagination variables without remote courses + $totalcourses = count_my_courses(); + $totalpages = (int) ceil($totalcourses / $CFG->coursesperpage); + if (!empty($CFG->mnet_dispatcher_mode) && $CFG->mnet_dispatcher_mode==='strict') { - $rcourses = get_my_remotecourses($USER->id); - $rhosts = get_my_remotehosts(); + + // calculate pagination variables with remote courses + $remotecoursepage = ($coursepage-$totalpages)+1; + $remotepageoffset = $totalcourses % $CFG->coursesperpage; + if ($remotepageoffset==0) { + $remotepageoffset = $CFG->coursesperpage; + } + $totalcourses = $totalcourses + count_my_remote_courses($USER->id); + $totalpages = ceil($totalcourses / $CFG->coursesperpage); + + // only ask for the remote host course if this is a page that contains them + if ($remotecoursepage>=0) { + $rcourses = get_my_remotecourses($USER->id, + $remotecoursepage, + $remotepageoffset); + } + $rhosts = get_my_remotehosts(); } if (!empty($courses) || !empty($rcourses) || !empty($rhosts)) { + // build the HTML navigation tool to browse between the pages + $paginationhtml = print_paging_bar($totalcourses, $coursepage, + $CFG->coursesperpage, $CFG->wwwroot.'/index.php?', + 'coursepage', false, true); + + if ($totalpages>1) { + // put the page navigation above the list of courses + echo $paginationhtml; + } + if (!empty($courses)) { echo '\n"; - } + echo "\n"; + } // MNET if (!empty($rcourses)) { @@ -2175,7 +2206,15 @@ foreach ($rcourses as $course) { print_remote_course($course, "100%"); } - } elseif (!empty($rhosts)) { + } + + if ($totalpages>1) { + // Also put a page navigation bar below the list of courses + echo $paginationhtml; + } + + // MNET remote hosts + if (empty($rcourses) && (!empty($rhosts))) { // non-IDP, we know of all the remote servers, but not courses foreach ($rhosts as $host) { print_remote_host($host, "100%"); Index: lib/datalib.php =================================================================== RCS file: /cvsroot/moodle/moodle/lib/datalib.php,v retrieving revision 1.439.2.36 diff -u -r1.439.2.36 datalib.php --- lib/datalib.php 8 Jan 2010 07:08:59 -0000 1.439.2.36 +++ lib/datalib.php 22 Jan 2010 12:22:01 -0000 @@ -773,6 +773,23 @@ } /** + * Calculates and returns the number of courses accessible to the logged in user + * This is the same as the number of records returned by get_my_courses($USER->id) + * @return int number of courses the user has access to + */ +function count_my_courses() { + global $USER; + + if (!isset($USER->mycoursescount) || !is_int($USER->mycoursescount)) { + // $USER->mycoursescount is set by get_my_courses + unset($USER->mycoursescount); + get_my_courses($USER->id); + } + + return $USER->mycoursescount; +} + +/** * Convenience function - lists courses that a user has access to view. * * For admins and others with access to "every" course in the system, we should @@ -803,9 +820,13 @@ * @param array $fields - names of _additional_ fields to return (also accepts a string) * @param bool $doanything True if using the doanything flag * @param int $limit Maximum number of records to return, or 0 for unlimited + * @param int $page (optional) Get only the courses which appear on this page of courses. + * The number of courses per page is determined by $CFG->coursesperpage + * Note that the first page is page 0! (not 1) + * Default is all courses are returned * @return array {@link $COURSE} of course objects */ -function get_my_courses($userid, $sort='visible DESC,sortorder ASC', $fields=NULL, $doanything=false,$limit=0) { +function get_my_courses($userid, $sort='visible DESC,sortorder ASC', $fields=NULL, $doanything=false,$limit=0,$page=null) { global $CFG,$USER; @@ -815,6 +836,8 @@ return(array()); } + if (!is_null($page) && $page<0) $page = 0; + $basefields = array('id', 'category', 'sortorder', 'shortname', 'fullname', 'idnumber', 'teacher', 'teachers', 'student', 'students', @@ -886,6 +909,23 @@ } } if (isset($courseids)) { + + // if using pagination, cut the page out of the list of all courses + if (!is_null($page)) { + // convert back to array to operate on (could use PCRE?) + $visiblecoursearray = explode(',', $courseids); + $firstcoursetoreturn = $page * (int) $CFG->coursesperpage; + + // if there are no courses on this page, return nothing + if ($firstcoursetoreturn>=count($visiblecoursearray)) return array(); + + // copy the necessary courses and convert to a string + $pagedcoursearray = array_slice($visiblecoursearray, + $firstcoursetoreturn, + (int) $CFG->coursesperpage); + $courseids = implode(',', $pagedcoursearray); + } + // The data massaging here MUST be kept in sync with // get_user_courses_bycap() so we return // the same... @@ -970,6 +1010,15 @@ $courses_count = count($courses); $cacheids = NULL; $vcatpaths = array(); + $visiblecoursescount = 0; + $firstcoursetoreturn = 0; + $lastcoursetoreturn = 0; + + if (!is_null($page)) { + $firstcoursetoreturn = $page * (int) $CFG->coursesperpage; + $lastcoursetoreturn = $firstcoursetoreturn + (int) $CFG->coursesperpage; + } + if ($userid === $USER->id && $courses_count < 500) { $cacheids = array(); } @@ -1043,10 +1092,29 @@ } } if ($cansee === true) { - $kcourses[$courses[$n]->id] = $courses[$n]; + // increment the counter which is counting courses that could appear + // on a page (courses visible to the user) + $visiblecoursescount++; + + // if this is a course within the page, (or pages not used) include it + if (is_null($page) || $visiblecoursescount>=$firstcoursetoreturn + && $visiblecoursescount<=$lastcoursetoreturn) { + $kcourses[$courses[$n]->id] = $courses[$n]; + } + + // cache this as a visible course for this user if (is_array($cacheids)) { $cacheids[] = $courses[$n]->id; - } + } else if (!is_null($page) + && isset($USER->mycoursescount) + && count($kcourses) == $CFG->coursesperpage) { + // if we're not caching and are using pagination, stop looking + // at further courses if the total number of courses which can + // appear on the page has been reached + // unless we have not worked out how many courses the user can + // see in total yet ($USER->mycoursescount) + break; + } } } if (is_array($cacheids)) { @@ -1060,6 +1128,11 @@ unset($USER->mycourses); } + // cache the total number of courses the user can see + if ($userid === $USER->id && !isset($USER->mycoursescount)) { + $USER->mycoursescount = $visiblecoursescount; + } + return $kcourses; } @@ -1460,26 +1533,101 @@ } /** + * Number of courses the user is assigned to on remote hosts + * This is the total number of courses returned by the get_my_remotecourses() + * function. + * The result (for logged in user) is cached in $USER->myremotecoursescount. + * @param int $userid - the user id to count remove courses of + * @return int - number of remote courses + */ +function count_my_remote_courses($userid) { + global $CFG, $USER; + + // return cached value for the logged in user + if ($USER->id==$userid && isset($USER->myremotecoursescount)) + return $USER->myremotecoursescount; + + $sql = "SELECT COUNT(*) + FROM {$CFG->prefix}mnet_enrol_course c + JOIN {$CFG->prefix}mnet_enrol_assignments a ON c.id=a.courseid + JOIN {$CFG->prefix}mnet_host h ON c.hostid=h.id + WHERE a.userid={$userid}"; + + $countremotecourses = count_records_sql($sql); + + // cache this result for the logged in user + if ($USER->id==$userid) + $USER->myremotecoursescount = $countremotecourses; + + return $countremotecourses; +} + +/** * List of remote courses that a user has access to via MNET. * Works only on the IDP * * @uses $CFG, $USER + * $userid int (optional) userid to get the remote courses of default is logged in user + * @param $page int (optional) page, page of results clustered by $CFG->coursesperpage + * default is to get all users remote courses + * $page_offset int (optional) the first page to display $CFG->coursesperpage + * courses minus this value. Subsequent pages offset by this value. * @return array {@link $COURSE} of course objects */ -function get_my_remotecourses($userid=0) { +function get_my_remotecourses($userid=0, $page=null, $pageoffset=null) { global $CFG, $USER; if (empty($userid)) { $userid = $USER->id; } + $limitclause = ""; + + // set default behviour in the event of a bad $page to return everything + if (!is_null($page) && $page<0) $page = null; + + // limit the return from the query to only get the courses for the current page + if (!is_null($page)) { + + if ($USER->id==$userid) { + + // see if any remote courses exist for the logged in user + $countremotecourses = count_my_remote_courses($userid); + + // if this user has no remote courses, quickly return an empty array + if ($countremotecourses<1) return array(); + } + + if (is_null($pageoffset) || $pageoffset<0) $pageoffset = 0; + if ($pageoffset>$CFG->coursesperpage) { + debugging("page_offset ({$pageoffset}) is set larger than coursesperpage ({$CFG->coursesperpage})"); + $pageoffset = 0; + } + + $limitstart = $page*$CFG->coursesperpage; + $limitlength = $CFG->coursesperpage; + + if ($pageoffset>0) { + if ($page==0) { + // the first page of results is shrunk by $pageoffset + $limitlength = $limitlength-$pageoffset; + } else { + // subsequent pages are offset by $pageoffset + $limitstart = $limitstart-$pageoffset; + } + } + + $limitclause = "LIMIT {$limitstart},{$limitlength}"; + } + $sql = "SELECT c.id, c.remoteid, c.shortname, c.fullname, c.hostid, c.summary, c.cat_name, h.name AS hostname FROM {$CFG->prefix}mnet_enrol_course c JOIN {$CFG->prefix}mnet_enrol_assignments a ON c.id=a.courseid JOIN {$CFG->prefix}mnet_host h ON c.hostid=h.id - WHERE a.userid={$userid}"; + WHERE a.userid={$userid} + {$limitclause}"; return get_records_sql($sql); }