Merge branch 'MDL-25939'
authorSam Hemelryk <sam@moodle.com>
Mon, 7 Feb 2011 05:40:51 +0000 (13:40 +0800)
committerSam Hemelryk <sam@moodle.com>
Mon, 7 Feb 2011 05:40:51 +0000 (13:40 +0800)
152 files changed:
admin/modules.php
admin/multilangupgrade.php
admin/settings/development.php
admin/user/lib.php
admin/user/user_bulk_confirm.php
admin/user/user_bulk_delete.php
admin/user/user_bulk_forcepasswordchange.php
admin/user/user_bulk_message.php
blocks/activity_modules/block_activity_modules.php
blocks/myprofile/block_myprofile.php
blocks/myprofile/edit_form.php
blocks/myprofile/lang/en/block_myprofile.php
blocks/myprofile/version.php
blocks/site_main_menu/block_site_main_menu.php
blocks/social_activities/block_social_activities.php
blog/lib.php
brokenfile.php [new file with mode: 0644]
config-dist.php
course/lib.php
course/report/completion/index.php
course/report/outline/index.php
course/report/participation/index.php
course/resources.php
course/togglecompletion.php
course/user.php
enrol/authorize/localfuncs.php
enrol/imsenterprise/db/install.php [new file with mode: 0644]
enrol/imsenterprise/db/upgrade.php [new file with mode: 0644]
enrol/imsenterprise/version.php
enrol/self/lib.php
filter/activitynames/lang/en/filter_activitynames.php
filter/algebra/lang/en/filter_algebra.php
filter/censor/lang/en/filter_censor.php
filter/emailprotect/lang/en/filter_emailprotect.php
filter/mediaplugin/filter.php
filter/mediaplugin/lang/en/filter_mediaplugin.php
filter/tex/lang/en/filter_tex.php
grade/report/user/lib.php
group/overview.php
install/lang/ca/admin.php
install/lang/da/error.php
install/lang/da/install.php
install/lang/he/install.php
install/lang/nn/langconfig.php
install/lang/pl/admin.php
install/lang/pl/install.php
install/lang/pt/error.php
install/lang/sl/admin.php
lib/accesslib.php
lib/completion/completion_criteria_activity.php
lib/completion/completion_criteria_course.php
lib/completion/completion_criteria_date.php
lib/completion/completion_criteria_duration.php
lib/completion/completion_criteria_grade.php
lib/completion/cron.php
lib/datalib.php
lib/db/install.xml
lib/db/upgrade.php
lib/db/upgradelib.php
lib/dml/moodle_database.php
lib/dml/oci_native_moodle_database.php
lib/dml/pdo_moodle_database.php
lib/eventslib.php
lib/filelib.php
lib/filestorage/file_storage.php
lib/grade/grade_category.php
lib/grade/grade_grade.php
lib/grade/grade_item.php
lib/gradelib.php
lib/grouplib.php
lib/javascript-static.js
lib/modinfolib.php [new file with mode: 0644]
lib/moodlelib.php
lib/navigationlib.php
lib/questionlib.php
lib/setup.php
lib/setuplib.php
lib/spikephpcoverage/readme_moodle.txt
lib/spikephpcoverage/src/phpcoverage.remote.bottom.inc.php
lib/spikephpcoverage/src/phpcoverage.remote.top.inc.php
lib/upgradelib.php
lib/weblib.php
message/lib.php
message/output/email/message_output_email.php
message/output/jabber/message_output_jabber.php
message/search.html
message/search_advanced.html
mod/assignment/db/upgrade.php
mod/assignment/lib.php
mod/data/db/upgrade.php
mod/data/lib.php
mod/folder/db/upgradelib.php
mod/forum/db/upgrade.php
mod/forum/lib.php
mod/glossary/db/upgrade.php
mod/glossary/lib.php
mod/imscp/db/upgradelib.php
mod/label/lib.php
mod/lesson/lib.php
mod/page/db/upgradelib.php
mod/quiz/attemptlib.php
mod/quiz/comment.php
mod/quiz/db/upgrade.php
mod/quiz/lib.php
mod/quiz/locallib.php
mod/quiz/report/overview/lang/en/quiz_overview.php
mod/quiz/report/responses/lang/en/quiz_responses.php
mod/quiz/report/statistics/lang/en/quiz_statistics.php
mod/quiz/reviewquestion.php
mod/quiz/version.php
mod/quiz/view.php
mod/resource/db/upgrade.php
mod/resource/db/upgradelib.php
mod/scorm/datamodels/aicclib.php
mod/scorm/datamodels/scorm_12lib.php
mod/scorm/datamodels/scorm_13lib.php
mod/scorm/db/upgrade.php
mod/scorm/lang/en/scorm.php
mod/scorm/lib.php
mod/scorm/locallib.php
mod/scorm/player.php
mod/scorm/prereqs.php
mod/scorm/settings.php
mod/scorm/styles.css
mod/scorm/version.php
mod/scorm/view.php
mod/survey/lib.php
mod/url/db/upgradelib.php
mod/wiki/db/migration/lib.php
mod/wiki/db/upgrade.php
mod/wiki/db/upgradelib.php
mod/wiki/locallib.php
question/format/multianswer/lang/en/qformat_multianswer.php
question/type/calculated/lang/en/qtype_calculated.php
question/type/calculatedmulti/lang/en/qtype_calculatedmulti.php
question/type/calculatedsimple/lang/en/qtype_calculatedsimple.php
question/type/multianswer/edit_multianswer_form.php
question/type/multianswer/lang/en/qtype_multianswer.php
question/type/multichoice/lang/en/qtype_multichoice.php
question/type/questiontype.php
repository/repository_ajax.php
tag/coursetags_more.php
tag/lib.php
theme/arialist/style/core.css
theme/base/style/course.css
theme/binarius/style/core.css
theme/magazine/style/core.css
theme/nonzero/style/pagelayout.css
theme/overlay/style/core.css
user/profile/lib.php
user/selector/lib.php
version.php

index 3ecb952..71e22bd 100644 (file)
             $settings = "";
         }
 
-        $count = $DB->count_records_select($module->name, "course<>0");
+        try {
+            $count = $DB->count_records_select($module->name, "course<>0");
+        } catch (dml_exception $e) {
+            $count = -1;
+        }
         if ($count>0) {
             $countlink = "<a href=\"{$CFG->wwwroot}/course/search.php?modulelist=$module->name" .
                 "&amp;sesskey=".sesskey()."\" title=\"$strshowmodulecourse\">$count</a>";
-        }
-        else {
+        } else if ($count < 0) {
+            $countlink = get_string('error');
+        } else {
             $countlink = "$count";
         }
 
index d25c709..77c2219 100644 (file)
@@ -56,35 +56,34 @@ foreach ($tables as $table) {
             if (in_array($data->type, array('text','mediumtext','longtext','varchar'))) {  // Text stuff only
                 // first find candidate records
                 $sql = "SELECT id, $column FROM $fulltable WHERE $column LIKE '%</lang>%' OR $column LIKE '%<span lang=%'";
-                if ($rs = $DB->get_recordset_sql($sql)) {
-                    foreach ($rs as $data) {
-                        $text = $data->$column;
-                        $id   = $data->id;
-                        if ($i % 600 == 0) {
-                            echo '<br />';
-                        }
-                        if ($i % 10 == 0) {
-                            echo '.';
-                        }
-                        $i++;
-
-                        if (empty($text) or is_numeric($text)) {
-                            continue; // nothing to do
-                        }
-
-                        $search = '/(<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.+?<\/(?:lang|span)>)(\s*<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.+?<\/(?:lang|span)>)+/is';
-                        $newtext = preg_replace_callback($search, 'multilangupgrade_impl', $text);
-
-                        if (is_null($newtext)) {
-                            continue; // regex error
-                        }
-
-                        if ($newtext != $text) {
-                            $DB->execute("UPDATE $fulltable SET $column=? WHERE id=?", array($newtext, $id));
-                        }
+                $rs = $DB->get_recordset_sql($sql);
+                foreach ($rs as $data) {
+                    $text = $data->$column;
+                    $id   = $data->id;
+                    if ($i % 600 == 0) {
+                        echo '<br />';
+                    }
+                    if ($i % 10 == 0) {
+                        echo '.';
+                    }
+                    $i++;
+
+                    if (empty($text) or is_numeric($text)) {
+                        continue; // nothing to do
+                    }
+
+                    $search = '/(<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.+?<\/(?:lang|span)>)(\s*<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.+?<\/(?:lang|span)>)+/is';
+                    $newtext = preg_replace_callback($search, 'multilangupgrade_impl', $text);
+
+                    if (is_null($newtext)) {
+                        continue; // regex error
+                    }
+
+                    if ($newtext != $text) {
+                        $DB->execute("UPDATE $fulltable SET $column=? WHERE id=?", array($newtext, $id));
                     }
-                    $rs->close();
                 }
+                $rs->close();
             }
         }
     }
index 29d72ff..7de0346 100644 (file)
@@ -20,8 +20,8 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
     $ADMIN->add('experimental', $temp);
 
     // DB transfer related pages
-    $ADMIN->add('experimental', new admin_externalpage('dbtransfer', get_string('dbtransfer', 'dbtransfer'), $CFG->wwwroot.'/'.$CFG->admin.'/dbtransfer/index.php', 'moodle/site:config'));
-    $ADMIN->add('experimental', new admin_externalpage('dbexport', get_string('dbexport', 'dbtransfer'), $CFG->wwwroot.'/'.$CFG->admin.'/dbtransfer/dbexport.php', 'moodle/site:config'));
+    $ADMIN->add('experimental', new admin_externalpage('dbtransfer', get_string('dbtransfer', 'dbtransfer'), $CFG->wwwroot.'/'.$CFG->admin.'/dbtransfer/index.php', 'moodle/site:config', true));
+    $ADMIN->add('experimental', new admin_externalpage('dbexport', get_string('dbexport', 'dbtransfer'), $CFG->wwwroot.'/'.$CFG->admin.'/dbtransfer/dbexport.php', 'moodle/site:config', true));
 
     // "debugging" settingpage
     $temp = new admin_settingpage('debugging', get_string('debugging', 'admin'));
index 3f21653..25775cb 100644 (file)
@@ -11,14 +11,13 @@ function add_selection_all($ufiltering) {
 
     list($sqlwhere, $params) = $ufiltering->get_sql_filter("id<>:exguest AND deleted <> 1", array('exguest'=>$CFG->siteguest));
 
-    if ($rs = $DB->get_recordset_select('user', $sqlwhere, $params, 'fullname', 'id,'.$DB->sql_fullname().' AS fullname')) {
-        foreach ($rs as $user) {
-            if (!isset($SESSION->bulk_users[$user->id])) {
-                $SESSION->bulk_users[$user->id] = $user->id;
-            }
+    $rs = $DB->get_recordset_select('user', $sqlwhere, $params, 'fullname', 'id,'.$DB->sql_fullname().' AS fullname');
+    foreach ($rs as $user) {
+        if (!isset($SESSION->bulk_users[$user->id])) {
+            $SESSION->bulk_users[$user->id] = $user->id;
         }
-        $rs->close();
     }
+    $rs->close();
 }
 
 function get_selection_data($ufiltering) {
index 7f10341..c7ba604 100755 (executable)
@@ -24,19 +24,18 @@ echo $OUTPUT->header();
 
 if ($confirm and confirm_sesskey()) {
     list($in, $params) = $DB->get_in_or_equal($SESSION->bulk_users);
-    if ($rs = $DB->get_recordset_select('user', "id $in", $params, '', 'id, username, secret, confirmed, auth, firstname, lastname')) {
-        foreach ($rs as $user) {
-            if ($user->confirmed) {
-                continue;
-            }
-            $auth = get_auth_plugin($user->auth);
-            $result = $auth->user_confirm($user->username, $user->secret);
-            if ($result != AUTH_CONFIRM_OK && $result != AUTH_CONFIRM_ALREADY) {
-                echo $OUTPUT->notification(get_string('usernotconfirmed', '', fullname($user, true)));
-            }
+    $rs = $DB->get_recordset_select('user', "id $in", $params, '', 'id, username, secret, confirmed, auth, firstname, lastname');
+    foreach ($rs as $user) {
+        if ($user->confirmed) {
+            continue;
+        }
+        $auth = get_auth_plugin($user->auth);
+        $result = $auth->user_confirm($user->username, $user->secret);
+        if ($result != AUTH_CONFIRM_OK && $result != AUTH_CONFIRM_ALREADY) {
+            echo $OUTPUT->notification(get_string('usernotconfirmed', '', fullname($user, true)));
         }
-        $rs->close();
     }
+    $rs->close();
     redirect($return, get_string('changessaved'));
 
 } else {
index 26e11f0..a8b6705 100755 (executable)
@@ -25,16 +25,15 @@ echo $OUTPUT->header();
 if ($confirm and confirm_sesskey()) {
 
     list($in, $params) = $DB->get_in_or_equal($SESSION->bulk_users);
-    if ($rs = $DB->get_recordset_select('user', "id $in", $params)) {
-        foreach ($rs as $user) {
-            if (!is_siteadmin($user) and $USER->id != $user->id and delete_user($user)) {
-                unset($SESSION->bulk_users[$user->id]);
-            } else {
-                echo $OUTPUT->notification(get_string('deletednot', '', fullname($user, true)));
-            }
+    $rs = $DB->get_recordset_select('user', "id $in", $params);
+    foreach ($rs as $user) {
+        if (!is_siteadmin($user) and $USER->id != $user->id and delete_user($user)) {
+            unset($SESSION->bulk_users[$user->id]);
+        } else {
+            echo $OUTPUT->notification(get_string('deletednot', '', fullname($user, true)));
         }
-        $rs->close();
     }
+    $rs->close();
     session_gc(); // remove stale sessions
     redirect($return, get_string('changessaved'));
 
index 6988c74..d67c942 100644 (file)
@@ -38,17 +38,16 @@ if ($confirm and confirm_sesskey()) {
     $parts = array_chunk($SESSION->bulk_users, 300);
     foreach ($parts as $users) {
         list($in, $params) = $DB->get_in_or_equal($users);
-        if ($rs = $DB->get_recordset_select('user', "id $in", $params)) {
-            foreach ($rs as $user) {
-                if (!empty($changeable[$user->auth])) {
-                    set_user_preference('auth_forcepasswordchange', 1, $user->id);
-                    unset($SESSION->bulk_users[$user->id]);
-                } else {
-                    echo $OUTPUT->notification(get_string('forcepasswordchangenot', '', fullname($user, true)));
-                }
+        $rs = $DB->get_recordset_select('user', "id $in", $params);
+        foreach ($rs as $user) {
+            if (!empty($changeable[$user->auth])) {
+                set_user_preference('auth_forcepasswordchange', 1, $user->id);
+                unset($SESSION->bulk_users[$user->id]);
+            } else {
+                echo $OUTPUT->notification(get_string('forcepasswordchangenot', '', fullname($user, true)));
             }
-            $rs->close();
         }
+        $rs->close();
     }
     echo $OUTPUT->notification(get_string('changessaved'), 'notifysuccess');
     echo $OUTPUT->continue_button($return);
index 52127fd..ceb5bcd 100755 (executable)
@@ -25,15 +25,14 @@ if (empty($CFG->messaging)) {
 
 if ($confirm and !empty($msg) and confirm_sesskey()) {
     list($in, $params) = $DB->get_in_or_equal($SESSION->bulk_users);
-    if ($rs = $DB->get_recordset_select('user', "id $in", $params)) {
-        foreach ($rs as $user) {
-            //TODO we should probably support all text formats here or only FORMAT_MOODLE
-            //For now bulk messaging is still using the html editor and its supplying html
-            //so we have to use html format for it to be displayed correctly
-            message_post_message($USER, $user, $msg, FORMAT_HTML, 'direct');
-        }
-        $rs->close();
+    $rs = $DB->get_recordset_select('user', "id $in", $params);
+    foreach ($rs as $user) {
+        //TODO we should probably support all text formats here or only FORMAT_MOODLE
+        //For now bulk messaging is still using the html editor and its supplying html
+        //so we have to use html format for it to be displayed correctly
+        message_post_message($USER, $user, $msg, FORMAT_HTML, 'direct');
     }
+    $rs->close();
     redirect($return);
 }
 
index adff582..c44ceb4 100644 (file)
@@ -27,7 +27,8 @@ class block_activity_modules extends block_list {
         $archetypes = array();
 
         foreach($modinfo->cms as $cm) {
-            if (!$cm->uservisible or $cm->modname === 'label') {
+            // Exclude activities which are not visible or have no link (=label)
+            if (!$cm->uservisible or !$cm->has_view()) {
                 continue;
             }
             if (array_key_exists($cm->modname, $modfullnames)) {
index fe03b67..73daf36 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * Displays the user's profile information.
+ * Block displaying information about current logged-in user.
+ *
+ * This block can be used as anti cheating measure, you
+ * can easily check the logged-in user matches the person
+ * operating the computer.
  *
- * @package    blocks
+ * @package    block
+ * @subpackage myprofile
  * @copyright  2010 Remote-Learner.net
  * @author     Olav Jordan <olav.jordan@remote-learner.ca>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
- * Displays the user's profile information.
+ * Displays the current user's profile information.
  *
  * @copyright  2010 Remote-Learner.net
  * @author     Olav Jordan <olav.jordan@remote-learner.ca>
@@ -51,8 +57,8 @@ class block_myprofile extends block_base {
             return $this->content;
         }
 
-        if (!isloggedin()){
-            return '';      // Never useful unless you are logged in
+        if (!isloggedin() or isguestuser()) {
+            return '';      // Never useful unless you are logged in as real users
         }
 
         $this->content = new stdClass;
@@ -60,169 +66,114 @@ class block_myprofile extends block_base {
         $this->content->footer = '';
 
         $course = $this->page->course;
-        if ($PAGE->context->contextlevel == CONTEXT_USER) {
-            $user = $DB->get_record('user', array('id' => $PAGE->context->instanceid));
-        } else {
-            $user = $USER;
-        }
-
-        if ($course->id == SITEID) {
-            $coursecontext = get_context_instance(CONTEXT_SYSTEM);
-        } else {
-            $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);   // Course context
-            // Make sure they can view the course
-            if (!is_viewing($coursecontext)) {
-                return '';
-            }
-        }
-
-
-        // TODO: clean up the following even more
 
         if (!isset($this->config->display_picture) || $this->config->display_picture == 1) {
             $this->content->text .= '<div class="myprofileitem picture">';
-            $this->content->text .= $OUTPUT->user_picture($user, array('courseid'=>$course->id, 'size'=>'100', 'class'=>'profilepicture'));  // The new class makes CSS easier
+            $this->content->text .= $OUTPUT->user_picture($USER, array('courseid'=>$course->id, 'size'=>'100', 'class'=>'profilepicture'));  // The new class makes CSS easier
             $this->content->text .= '</div>';
         }
 
-        $this->content->text .= '<div class="myprofileitem fullname">'.fullname($user).'</div>';
+        $this->content->text .= '<div class="myprofileitem fullname">'.fullname($USER).'</div>';
 
         if(!isset($this->config->display_country) || $this->config->display_country == 1) {
             $countries = get_string_manager()->get_list_of_countries();
-            if (isset($countries[$user->country])) {
+            if (isset($countries[$USER->country])) {
                 $this->content->text .= '<div class="myprofileitem country">';
-                $this->content->text .= get_string('country') . ': ' . $countries[$user->country];
+                $this->content->text .= get_string('country') . ': ' . $countries[$USER->country];
                 $this->content->text .= '</div>';
             }
         }
 
         if(!isset($this->config->display_city) || $this->config->display_city == 1) {
             $this->content->text .= '<div class="myprofileitem city">';
-            $this->content->text .= get_string('city') . ': ' . $user->city;
+            $this->content->text .= get_string('city') . ': ' . format_string($USER->city);
             $this->content->text .= '</div>';
         }
 
         if(!isset($this->config->display_email) || $this->config->display_email == 1) {
             $this->content->text .= '<div class="myprofileitem email">';
-            $this->content->text .= obfuscate_mailto($user->email, '');
+            $this->content->text .= obfuscate_mailto($USER->email, '');
             $this->content->text .= '</div>';
         }
 
-        if(!empty($this->config->display_icq) && !empty($user->icq)) {
+        if(!empty($this->config->display_icq) && !empty($USER->icq)) {
             $this->content->text .= '<div class="myprofileitem icq">';
-            $this->content->text .= 'ICQ: ' . $user->icq;
+            $this->content->text .= 'ICQ: ' . s($USER->icq);
             $this->content->text .= '</div>';
         }
 
-        if(!empty($this->config->display_skype) && !empty($user->skype)) {
+        if(!empty($this->config->display_skype) && !empty($USER->skype)) {
             $this->content->text .= '<div class="myprofileitem skype">';
-            $this->content->text .= 'Skype: ' . $user->skype;
+            $this->content->text .= 'Skype: ' . s($USER->skype);
             $this->content->text .= '</div>';
         }
 
-        if(!empty($this->config->display_yahoo) && !empty($user->yahoo)) {
+        if(!empty($this->config->display_yahoo) && !empty($USER->yahoo)) {
             $this->content->text .= '<div class="myprofileitem yahoo">';
-            $this->content->text .= 'Yahoo: ' . $user->yahoo;
+            $this->content->text .= 'Yahoo: ' . s($USER->yahoo);
             $this->content->text .= '</div>';
         }
 
-        if(!empty($this->config->display_aim) && !empty($user->aim)) {
+        if(!empty($this->config->display_aim) && !empty($USER->aim)) {
             $this->content->text .= '<div class="myprofileitem aim">';
-            $this->content->text .= 'AIM: ' . $user->aim;
+            $this->content->text .= 'AIM: ' . s($USER->aim);
             $this->content->text .= '</div>';
         }
 
-        if(!empty($this->config->display_msn) && !empty($user->msn)) {
+        if(!empty($this->config->display_msn) && !empty($USER->msn)) {
             $this->content->text .= '<div class="myprofileitem msn">';
-            $this->content->text .= 'MSN: ' . $user->msn;
+            $this->content->text .= 'MSN: ' . s($USER->msn);
             $this->content->text .= '</div>';
         }
 
-        if(!empty($this->config->display_phone1) && !empty($user->phone1)) {
+        if(!empty($this->config->display_phone1) && !empty($USER->phone1)) {
             $this->content->text .= '<div class="myprofileitem phone1">';
-            $this->content->text .= get_string('phone').': ' . $user->phone1;
+            $this->content->text .= get_string('phone').': ' . s($USER->phone1);
             $this->content->text .= '</div>';
         }
 
-        if(!empty($this->config->display_phone2) && !empty($user->phone2)) {
+        if(!empty($this->config->display_phone2) && !empty($USER->phone2)) {
             $this->content->text .= '<div class="myprofileitem phone2">';
-            $this->content->text .= get_string('phone').': ' . $user->phone2;
+            $this->content->text .= get_string('phone').': ' . s($USER->phone2);
             $this->content->text .= '</div>';
         }
 
-        if(!empty($this->config->display_institution) && !empty($user->institution)) {
+        if(!empty($this->config->display_institution) && !empty($USER->institution)) {
             $this->content->text .= '<div class="myprofileitem institution">';
-            $this->content->text .= $user->institution;
+            $this->content->text .= format_string($USER->institution);
             $this->content->text .= '</div>';
         }
 
-        if(!empty($this->config->display_address) && !empty($user->address)) {
+        if(!empty($this->config->display_address) && !empty($USER->address)) {
             $this->content->text .= '<div class="myprofileitem address">';
-            $this->content->text .= $user->address;
+            $this->content->text .= format_string($USER->address);
             $this->content->text .= '</div>';
         }
 
-        if(!empty($this->config->display_firstaccess) && !empty($user->firstaccess)) {
+        if(!empty($this->config->display_firstaccess) && !empty($USER->firstaccess)) {
             $this->content->text .= '<div class="myprofileitem firstaccess">';
-            $this->content->text .= get_string('firstaccess').': ' . userdate($user->firstaccess);
+            $this->content->text .= get_string('firstaccess').': ' . userdate($USER->firstaccess);
             $this->content->text .= '</div>';
         }
 
-        if(!empty($this->config->display_lastaccess) && !empty($user->lastaccess)) {
+        if(!empty($this->config->display_lastaccess) && !empty($USER->lastaccess)) {
             $this->content->text .= '<div class="myprofileitem lastaccess">';
-            $this->content->text .= get_string('lastaccess').': ' . userdate($user->lastaccess);
+            $this->content->text .= get_string('lastaccess').': ' . userdate($USER->lastaccess);
             $this->content->text .= '</div>';
         }
 
-        if(!empty($this->config->display_currentlogin) && !empty($user->currentlogin)) {
+        if(!empty($this->config->display_currentlogin) && !empty($USER->currentlogin)) {
             $this->content->text .= '<div class="myprofileitem currentlogin">';
-            $this->content->text .= get_string('login').': ' . userdate($user->currentlogin);
+            $this->content->text .= get_string('login').': ' . userdate($USER->currentlogin);
             $this->content->text .= '</div>';
         }
 
-        if(!empty($this->config->display_lastip) && !empty($user->lastip)) {
+        if(!empty($this->config->display_lastip) && !empty($USER->lastip)) {
             $this->content->text .= '<div class="myprofileitem lastip">';
-            $this->content->text .= 'IP: ' . $user->lastip;
-            $this->content->text .= '</div>';
-        }
-
-        $editscript = NULL;
-        if (isguestuser($user)) {
-            // guest account can not be edited
-
-        } else if (is_mnet_remote_user($user)) {
-            // cannot edit remote users
-
-        } else if (isguestuser() or !isloggedin()) {
-            // guests and not logged in can not edit own profile
-
-        } else if ($USER->id == $user->id) {
-            $systemcontext = get_context_instance(CONTEXT_SYSTEM);
-            if (has_capability('moodle/user:update', $systemcontext)) {
-                $editscript = '/user/editadvanced.php';
-            } else if (has_capability('moodle/user:editownprofile', $systemcontext)) {
-                $editscript = '/user/edit.php';
-            }
-
-        } else {
-            $systemcontext = get_context_instance(CONTEXT_SYSTEM);
-            $personalcontext = get_context_instance(CONTEXT_USER, $user->id);
-            if (has_capability('moodle/user:update', $systemcontext) and !is_primary_admin($user->id)){
-                $editscript = '/user/editadvanced.php';
-            } else if (has_capability('moodle/user:editprofile', $personalcontext) and !is_primary_admin($user->id)){
-                //teachers, parents, etc.
-                $editscript = '/user/edit.php';
-            }
-        }
-
-
-        if ($editscript) {
-            $this->content->text .= '<div class="myprofileitem edit">';
-            $this->content->text .= '<a href="'.$CFG->wwwroot.$editscript.'?id='.$user->id.'&amp;course='.$course->id.'">'.get_string('editmyprofile').'</a>';
+            $this->content->text .= 'IP: ' . $USER->lastip;
             $this->content->text .= '</div>';
         }
 
-
         return $this->content;
     }
 
@@ -304,4 +255,3 @@ class block_myprofile extends block_base {
     }
 
 }
-?>
index 4605853..4500c0e 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * Form for editing profile block settings
  *
- * @package    blocks
+ * @package    block
+ * @subpackage myprofile
  * @copyright  2010 Remote-Learner.net
  * @author     Olav Jordan <olav.jordan@remote-learner.ca>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
index 09c256d..74dea91 100644 (file)
@@ -1,6 +1,31 @@
 <?php
-$string['pluginname'] = 'Personal profile';
-$string['myprofile_settings'] = 'Personal profile settings';
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Strings for component 'block_myprofile', language 'en', branch 'MOODLE_20_STABLE'
+ *
+ * @package    block
+ * @subpackage myprofile
+ * @copyright  2010 Remote-Learner.net
+ * @author     Olav Jordan <olav.jordan@remote-learner.ca>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+$string['pluginname'] = 'Logged in user';
+$string['myprofile_settings'] = 'Visible user information';
 $string['contentsettings'] = 'Display settings for content region';
 $string['display_picture'] = 'Display picture';
 $string['display_country'] = 'Display country';
@@ -20,4 +45,3 @@ $string['display_firstaccess'] = 'Display first access';
 $string['display_lastaccess'] = 'Display last access';
 $string['display_currentlogin'] = 'Display current login';
 $string['display_lastip'] = 'Display last IP';
-?>
index fa4218c..b845d6e 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
+/**
+ * Current user info block.
+ *
+ * @package    block
+ * @subpackage myprofile
+ * @copyright  2010 Remote-Learner.net
+ * @author     Olav Jordan <olav.jordan@remote-learner.ca>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
 $plugin->version = 2009123100;
index 3e139ac..d3434f8 100644 (file)
@@ -40,21 +40,19 @@ class block_site_main_menu extends block_list {
                     if (!$cm->uservisible) {
                         continue;
                     }
-                    if ($cm->modname == 'label') {
-                        $this->content->items[] = format_text($cm->extra, FORMAT_HTML, $options);
+
+                    list($content, $instancename) =
+                            get_print_section_cm_text($cm, $course);
+
+                    if (!($url = $cm->get_url())) {
+                        $this->content->items[] = $content;
                         $this->content->icons[] = '';
                     } else {
                         $linkcss = $cm->visible ? '' : ' class="dimmed" ';
-                        $instancename = format_string($cm->name, true, $course->id);
                         //Accessibility: incidental image - should be empty Alt text
-                        if (!empty($cm->icon)) {
-                            $icon = $OUTPUT->pix_url($cm->icon);
-                        } else {
-                            $icon = $OUTPUT->pix_url('icon', $cm->modname);
-                        }
-                        $icon = '<img src="'.$icon.'" class="icon" alt="" />&nbsp;';
+                        $icon = '<img src="' . $cm->get_icon_url() . '" class="icon" alt="" />&nbsp;';
                         $this->content->items[] = '<a title="'.$cm->modplural.'" '.$linkcss.' '.$cm->extra.
-                            ' href="'.$CFG->wwwroot.'/mod/'.$cm->modname.'/view.php?id='.$cm->id.'">'.$icon.$instancename.'</a>';
+                                ' href="' . $url . '">' . $icon . $instancename . '</a>';
                     }
                 }
             }
@@ -114,28 +112,18 @@ class block_site_main_menu extends block_list {
                             '<img style="height:16px; width:80px; border:0px" src="'.$OUTPUT->pix_url('movehere') . '" alt="'.$strmovehere.'" /></a>';
                         $this->content->icons[] = '';
                     }
-                    $instancename = $modinfo->cms[$modnumber]->name;
-                    $instancename = format_string($instancename, true, $course->id);
+                    list($content, $instancename) =
+                            get_print_section_cm_text($modinfo->cms[$modnumber], $course);
                     $linkcss = $mod->visible ? '' : ' class="dimmed" ';
-                    if (!empty($modinfo->cms[$modnumber]->extra)) {
-                        $extra = $modinfo->cms[$modnumber]->extra;
-                    } else {
-                        $extra = '';
-                    }
-                    if (!empty($modinfo->cms[$modnumber]->icon)) {
-                        $icon = $OUTPUT->pix_url($modinfo->cms[$modnumber]->icon);
-                    } else {
-                        $icon = $OUTPUT->pix_url('icon', $mod->modname);
-                    }
 
-                    if ($mod->modname == 'label') {
-                        $this->content->items[] = format_text($extra, FORMAT_HTML,$options).$editbuttons;
+                    if (!($url = $mod->get_url())) {
+                        $this->content->items[] = $content . $editbuttons;
                         $this->content->icons[] = '';
                     } else {
                         //Accessibility: incidental image - should be empty Alt text
-                        $icon = '<img src="'.$icon.'" class="icon" alt="" />&nbsp;';
-                        $this->content->items[] = '<a title="'.$mod->modfullname.'" '.$linkcss.' '.$extra.
-                            ' href="'.$CFG->wwwroot.'/mod/'.$mod->modname.'/view.php?id='.$mod->id.'">'.$icon.$instancename.'</a>'.$editbuttons;
+                        $icon = '<img src="' . $mod->get_icon_url() . '" class="icon" alt="" />&nbsp;';
+                        $this->content->items[] = '<a title="' . $mod->modfullname . '" ' . $linkcss . ' ' . $mod->extra .
+                            ' href="' . $url . '">' . $icon . $instancename . '</a>' . $editbuttons;
                     }
                 }
             }
index bcf7d7b..886e888 100644 (file)
@@ -42,21 +42,19 @@ class block_social_activities extends block_list {
                     if (!$cm->uservisible) {
                         continue;
                     }
-                    if ($cm->modname == 'label') {
-                        $this->content->items[] = format_text($cm->extra, FORMAT_HTML, $options);
+
+                    list($content, $instancename) =
+                            get_print_section_cm_text($cm, $course);
+
+                    if (!($url = $cm->get_url())) {
+                        $this->content->items[] = $content;
                         $this->content->icons[] = '';
                     } else {
                         $linkcss = $cm->visible ? '' : ' class="dimmed" ';
-                        $instancename = format_string($cm->name, true, $course->id);
                         //Accessibility: incidental image - should be empty Alt text
-                        if (!empty($cm->icon)) {
-                            $icon = $OUTPUT->pix_url($cm->icon);
-                        } else {
-                            $icon = $OUTPUT->pix_url('icon', $cm->modname);
-                        }
-                        $icon = '<img src="'.$icon.'" class="icon" alt="" />&nbsp;';
+                        $icon = '<img src="' . $cm->get_icon_url() . '" class="icon" alt="" />&nbsp;';
                         $this->content->items[] = '<a title="'.$cm->modplural.'" '.$linkcss.' '.$cm->extra.
-                            ' href="'.$CFG->wwwroot.'/mod/'.$cm->modname.'/view.php?id='.$cm->id.'">'.$icon.$instancename.'</a>';
+                                ' href="' . $url . '">' . $icon . $instancename . '</a>';
                     }
                 }
             }
@@ -123,28 +121,19 @@ class block_social_activities extends block_list {
                             '<img style="height:16px; width:80px; border:0px" src="'.$OUTPUT->pix_url('movehere') . '" alt="'.$strmovehere.'" /></a>';
                         $this->content->icons[] = '';
                     }
-                    $instancename = $modinfo->cms[$modnumber]->name;
-                    $instancename = format_string($instancename, true, $course->id);
+                    list($content, $instancename) =
+                                get_print_section_cm_text($modinfo->cms[$modnumber], $course);
+
                     $linkcss = $mod->visible ? '' : ' class="dimmed" ';
-                    if (!empty($modinfo->cms[$modnumber]->extra)) {
-                        $extra = $modinfo->cms[$modnumber]->extra;
-                    } else {
-                        $extra = '';
-                    }
-                    if (!empty($modinfo->cms[$modnumber]->icon)) {
-                        $icon = $OUTPUT->pix_url($modinfo->cms[$modnumber]->icon);
-                    } else {
-                        $icon = $OUTPUT->pix_url('icon', $mod->modname);
-                    }
 
-                    if ($mod->modname == 'label') {
-                        $this->content->items[] = format_text($extra, FORMAT_HTML, $options).$editbuttons;
+                    if (!($url = $mod->get_url())) {
+                        $this->content->items[] = $content . $editbuttons;
                         $this->content->icons[] = '';
                     } else {
                         //Accessibility: incidental image - should be empty Alt text
-                        $icon = '<img src="'.$icon.'" class="icon" alt="" />&nbsp;';
-                        $this->content->items[] = '<a title="'.$mod->modfullname.'" '.$linkcss.' '.$extra.
-                            ' href="'.$CFG->wwwroot.'/mod/'.$mod->modname.'/view.php?id='.$mod->id.'">'.$icon.$instancename.'</a>'.$editbuttons;
+                        $icon = '<img src="' . $mod->get_icon_url() . '" class="icon" alt="" />&nbsp;';
+                        $this->content->items[] = '<a title="' . $mod->modfullname . '" ' . $linkcss . ' ' . $mod->extra .
+                            ' href="' . $url . '">' . $icon . $instancename . '</a>' . $editbuttons;
                     }
                 }
             }
index 7f7a780..781f4a0 100644 (file)
@@ -548,11 +548,11 @@ function blog_get_options_for_course(stdClass $course, stdClass $user=null) {
  * Get the blog options relating to the given module for the given user
  *
  * @staticvar array $moduleoptions Cache
- * @param stdClass $module The module to get options for
+ * @param stdClass|cm_info $module The module to get options for
  * @param stdClass $user The user to get options for null == currentuser
  * @return array
  */
-function blog_get_options_for_module(stdClass $module, stdClass $user=null) {
+function blog_get_options_for_module($module, $user=null) {
     global $CFG, $USER;
     // Cache
     static $moduleoptions = array();
diff --git a/brokenfile.php b/brokenfile.php
new file mode 100644 (file)
index 0000000..3153ade
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This is an empty file which is used in order to prevent
+ * error logs in the serverlog.
+ *
+ * Sometimes developer forgets to postprocess files when saving
+ * submitted form data or forget to replace the file placeholders
+ * with the current area information.
+ *
+ * @package    core
+ * @subpackage file
+ * @copyright  2011 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+@header('HTTP/1.0 404 not found');
index f9909be..79e0d9d 100644 (file)
@@ -379,7 +379,8 @@ $CFG->admin = 'admin';
 // Prevent core_string_manager on-disk cache
 // $CFG->langstringcache = false; // NOT FOR PRODUCTION SERVERS!
 //
-// When working with production data on test servers, no emails should ever be send to real users
+// When working with production data on test servers, no emails or other messages
+// should ever be send to real users
 // $CFG->noemailever = true;    // NOT FOR PRODUCTION SERVERS!
 //
 // Divert all outgoing emails to this address to test and debug emailing features
index 28983a9..492275d 100644 (file)
@@ -48,10 +48,6 @@ define('FIRSTUSEDEXCELROW', 3);
 define('MOD_CLASS_ACTIVITY', 0);
 define('MOD_CLASS_RESOURCE', 1);
 
-if (!defined('MAX_MODINFO_CACHE_SIZE')) {
-    define('MAX_MODINFO_CACHE_SIZE', 10);
-}
-
 function make_log_url($module, $url) {
     switch ($module) {
         case 'course':
@@ -959,6 +955,9 @@ function print_recent_activity($course) {
             }
             $info = explode(' ', $log->info);
 
+            // note: in most cases I replaced hardcoding of label with use of
+            // $cm->has_view() but it was not possible to do this here because
+            // we don't necessarily have the $cm for it
             if ($info[0] == 'label') {     // Labels are ignored in recent activity
                 continue;
             }
@@ -1112,9 +1111,6 @@ function get_array_of_activities($courseid) {
 
                    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;
                            }
@@ -1124,11 +1120,45 @@ function get_array_of_activities($courseid) {
                            if (!empty($info->name)) {
                                $mod[$seq]->name = $info->name;
                            }
+                           if ($info instanceof cached_cm_info) {
+                               // When using cached_cm_info you can include three new fields
+                               // that aren't available for legacy code
+                               if (!empty($info->content)) {
+                                   $mod[$seq]->content = $info->content;
+                               }
+                               if (!empty($info->extraclasses)) {
+                                   $mod[$seq]->extraclasses = $info->extraclasses;
+                               }
+                               if (!empty($info->onclick)) {
+                                   $mod[$seq]->onclick = $info->onclick;
+                               }
+                               if (!empty($info->customdata)) {
+                                   $mod[$seq]->customdata = $info->customdata;
+                               }
+                           } else {
+                               // When using a stdclass, the (horrible) deprecated ->extra field
+                               // is available for BC
+                               if (!empty($info->extra)) {
+                                   $mod[$seq]->extra = $info->extra;
+                               }
+                           }
                        }
                    }
                    if (!isset($mod[$seq]->name)) {
                        $mod[$seq]->name = $DB->get_field($rawmods[$seq]->modname, "name", array("id"=>$rawmods[$seq]->instance));
                    }
+
+                   // Minimise the database size by unsetting default options when they are
+                   // 'empty'. This list corresponds to code in the cm_info constructor.
+                   foreach(array('idnumber', 'groupmode', 'groupingid', 'groupmembersonly',
+                           'indent', 'completion', 'extra', 'extraclasses', 'onclick', 'content',
+                           'icon', 'iconcomponent', 'customdata', 'availablefrom', 'availableuntil',
+                           'conditionscompletion', 'conditionsgrade') as $property) {
+                       if (property_exists($mod[$seq], $property) &&
+                               empty($mod[$seq]->{$property})) {
+                           unset($mod[$seq]->{$property});
+                       }
+                   }
                }
             }
         }
@@ -1250,6 +1280,44 @@ function set_section_visible($courseid, $sectionnumber, $visibility) {
     }
 }
 
+/**
+ * Obtains shared data that is used in print_section when displaying a
+ * course-module entry.
+ *
+ * Calls format_text or format_string as appropriate, and obtains the correct icon.
+ *
+ * This data is also used in other areas of the code.
+ * @param cm_info $cm Course-module data (must come from get_fast_modinfo)
+ * @param object $course Moodle course object
+ * @return array An array with the following values in this order:
+ *   $content (optional extra content for after link),
+ *   $instancename (text of link)
+ */
+function get_print_section_cm_text(cm_info $cm, $course) {
+    global $OUTPUT;
+
+    // Get course context
+    $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
+
+    // Get content from modinfo if specified. Content displays either
+    // in addition to the standard link (below), or replaces it if
+    // the link is turned off by setting ->url to null.
+    if (($content = $cm->get_content()) !== '') {
+        $labelformatoptions = new stdClass();
+        $labelformatoptions->noclean = true;
+        $labelformatoptions->overflowdiv = true;
+        $labelformatoptions->context = $coursecontext;
+        $content = format_text($content, FORMAT_HTML, $labelformatoptions);
+    } else {
+        $content = '';
+    }
+
+    $stringoptions = new stdClass;
+    $stringoptions->context = $coursecontext;
+    $instancename = format_string($cm->name, true,  $stringoptions);
+    return array($content, $instancename);
+}
+
 /**
  * Prints a section full of activity modules
  */
@@ -1265,8 +1333,8 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
     static $strmovehere;
     static $strmovefull;
     static $strunreadpostsone;
-    static $usetracking;
     static $groupings;
+    static $modulenames;
 
     if (!isset($initialised)) {
         $groupbuttons     = ($course->groupmode or (!$course->groupmodeforce));
@@ -1277,18 +1345,12 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
             $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');
-        }
+        $modulenames      = array();
         $initialised = true;
     }
 
-    $labelformatoptions = new stdClass();
-    $labelformatoptions->noclean = true;
-    $labelformatoptions->overflowdiv = true;
+    $tl = textlib_get_instance();
 
-/// Casting $course->modinfo to string prevents one notice when the field is null
     $modinfo = get_fast_modinfo($course);
     $completioninfo = new completion_info($course);
 
@@ -1304,6 +1366,9 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
                 continue;
             }
 
+            /**
+             * @var cm_info
+             */
             $mod = $mods[$modnumber];
 
             if ($ismoving and $mod->id == $USER->activitycopy) {
@@ -1341,6 +1406,11 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
                 }
             }
 
+            if (!isset($modulenames[$mod->modname])) {
+                $modulenames[$mod->modname] = get_string('modulename', $mod->modname);
+            }
+            $modulename = $modulenames[$mod->modname];
+
             // In some cases the activity is visible to user, but it is
             // dimmed. This is done if viewhiddenactivities is true and if:
             // 1. the activity is not visible, or
@@ -1366,6 +1436,10 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
             $liclasses[] = 'activity';
             $liclasses[] = $mod->modname;
             $liclasses[] = 'modtype_'.$mod->modname;
+            $extraclasses = $mod->get_extra_classes();
+            if ($extraclasses) {
+                $liclasses = array_merge($liclasses, explode(' ', $extraclasses));
+            }
             echo html_writer::start_tag('li', array('class'=>join(' ', $liclasses), 'id'=>'module-'.$modnumber));
             if ($ismoving) {
                 echo '<a title="'.$strmovefull.'"'.
@@ -1384,105 +1458,122 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
             }
             echo html_writer::start_tag('div', array('class'=>join(' ', $classes)));
 
-            $extra = '';
-            if (!empty($modinfo->cms[$modnumber]->extra)) {
-                $extra = $modinfo->cms[$modnumber]->extra;
+            // Get data about this course-module
+            list($content, $instancename) =
+                    get_print_section_cm_text($modinfo->cms[$modnumber], $course);
+
+            //Accessibility: for files get description via icon, this is very ugly hack!
+            $altname = '';
+            $altname = $mod->modfullname;
+            if (!empty($customicon)) {
+                $archetype = plugin_supports('mod', $mod->modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
+                if ($archetype == MOD_ARCHETYPE_RESOURCE) {
+                    $mimetype = mimeinfo_from_icon('type', $customicon);
+                    $altname = get_mimetype_description($mimetype);
+                }
+            }
+            // Avoid unnecessary duplication: if e.g. a forum name already
+            // includes the word forum (or Forum, etc) then it is unhelpful
+            // to include that in the accessible description that is added.
+            if (false !== strpos($tl->strtolower($instancename),
+                    $tl->strtolower($altname))) {
+                $altname = '';
+            }
+            // File type after name, for alphabetic lists (screen reader).
+            if ($altname) {
+                $altname = get_accesshide(' '.$altname);
             }
 
-            if ($mod->modname == "label") {
-                if ($accessiblebutdim || !$mod->uservisible) {
-                    echo '<div class="dimmed_text"><span class="accesshide">'.
-                        get_string('hiddenfromstudents').'</span>';
+            // We may be displaying this just in order to show information
+            // about visibility, without the actual link
+            $contentpart = '';
+            if ($mod->uservisible) {
+                // Nope - in this case the link is fully working for user
+                $linkclasses = '';
+                $textclasses = '';
+                if ($accessiblebutdim) {
+                    $linkclasses .= ' dimmed';
+                    $textclasses .= ' dimmed_text';
+                    $accesstext = '<span class="accesshide">'.
+                        get_string('hiddenfromstudents').': </span>';
                 } else {
-                    echo '<div>';
+                    $accesstext = '';
                 }
-                echo format_text($extra, FORMAT_HTML, $labelformatoptions);
-                echo "</div>";
-                if (!empty($mod->groupingid) && has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
-                    if (!isset($groupings)) {
-                        $groupings = groups_get_all_groupings($course->id);
-                    }
-                    echo " <span class=\"groupinglabel\">(".format_string($groupings[$mod->groupingid]->name).')</span>';
+                if ($linkclasses) {
+                    $linkcss = 'class="' . trim($linkclasses) . '" ';
+                } else {
+                    $linkcss = '';
+                }
+                if ($textclasses) {
+                    $textcss = 'class="' . trim($textclasses) . '" ';
+                } else {
+                    $textcss = '';
                 }
 
-            } else { // Normal activity
-                $instancename = format_string($modinfo->cms[$modnumber]->name, true,  $course->id);
+                // Get on-click attribute value if specified
+                $onclick = $mod->get_on_click();
+                if ($onclick) {
+                    $onclick = ' onclick="' . $onclick . '"';
+                }
 
-                $customicon = $modinfo->cms[$modnumber]->icon;
-                if (!empty($customicon)) {
-                    if (substr($customicon, 0, 4) === 'mod/') {
-                        list($modname, $iconname) = explode('/', substr($customicon, 4), 2);
-                        $icon = $OUTPUT->pix_url($iconname, $modname);
-                    } else {
-                        $icon = $OUTPUT->pix_url($customicon);
+                if ($url = $mod->get_url()) {
+                    // Display link itself
+                    echo '<a ' . $linkcss . $mod->extra . $onclick .
+                            ' href="' . $url . '"><img src="' . $mod->get_icon_url() .
+                            '" class="activityicon" alt="' .
+                            $modulename . '" /> ' .
+                            $accesstext . '<span class="instancename">' .
+                            $instancename . $altname . '</span></a>';
+
+                    // If specified, display extra content after link
+                    if ($content) {
+                        $contentpart = '<div class="contentafterlink' .
+                                trim($textclasses) . '">' . $content . '</div>';
                     }
                 } else {
-                    $icon = $OUTPUT->pix_url('icon', $mod->modname);
+                    // No link, so display only content
+                    $contentpart = '<div ' . $textcss . $mod->extra . '>' .
+                            $accesstext . $content . '</div>';
                 }
 
-                //Accessibility: for files get description via icon, this is very ugly hack!
-                $altname = '';
-                $altname = $mod->modfullname;
-                if (!empty($customicon)) {
-                    $archetype = plugin_supports('mod', $mod->modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
-                    if ($archetype == MOD_ARCHETYPE_RESOURCE) {
-                        $mimetype = mimeinfo_from_icon('type', $customicon);
-                        $altname = get_mimetype_description($mimetype);
+                if (!empty($mod->groupingid) && has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
+                    if (!isset($groupings)) {
+                        $groupings = groups_get_all_groupings($course->id);
                     }
+                    echo " <span class=\"groupinglabel\">(".format_string($groupings[$mod->groupingid]->name).')</span>';
                 }
-                // Avoid unnecessary duplication.
-                if (false !== stripos($instancename, $altname)) {
-                    $altname = '';
-                }
-                // File type after name, for alphabetic lists (screen reader).
-                if ($altname) {
-                    $altname = get_accesshide(' '.$altname);
+            } else {
+                $textclasses = $extraclasses;
+                $textclasses .= ' dimmed_text';
+                if ($textclasses) {
+                    $textcss = 'class="' . trim($textclasses) . '" ';
+                } else {
+                    $textcss = '';
                 }
+                $accesstext = '<span class="accesshide">' .
+                        get_string('notavailableyet', 'condition') .
+                        ': </span>';
 
-                // We may be displaying this just in order to show information
-                // about visibility, without the actual link
-                if ($mod->uservisible) {
-                    // Display normal module link
-                    if (!$accessiblebutdim) {
-                        $linkcss = '';
-                        $accesstext  ='';
-                    } else {
-                        $linkcss = ' class="dimmed" ';
-                        $accesstext = '<span class="accesshide">'.
-                            get_string('hiddenfromstudents').': </span>';
-                    }
-
-                    echo '<a '.$linkcss.' '.$extra.
-                         ' href="'.$CFG->wwwroot.'/mod/'.$mod->modname.'/view.php?id='.$mod->id.'">'.
-                         '<img src="'.$icon.'" class="activityicon" alt="'.get_string('modulename',$mod->modname).'" /> '.
-                         $accesstext.'<span class="instancename">'.$instancename.$altname.'</span></a>';
-
-                    if (!empty($mod->groupingid) && has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
-                        if (!isset($groupings)) {
-                            $groupings = groups_get_all_groupings($course->id);
-                        }
-                        echo " <span class=\"groupinglabel\">(".format_string($groupings[$mod->groupingid]->name).')</span>';
-                    }
-                } else {
+                if ($url = $mod->get_url()) {
                     // Display greyed-out text of link
-                    echo '<span class="dimmed_text" '.$extra.' ><span class="accesshide">'.
-                        get_string('notavailableyet','condition').': </span>'.
-                        '<img src="'.$icon.'" class="activityicon" alt="'.get_string('modulename', $mod->modname).'" /> <span>'.
-                        $instancename.$altname.'</span></span>';
-                }
-            }
-            if ($usetracking && $mod->modname == 'forum') {
-                if ($unread = forum_tp_count_forum_unread_posts($mod, $course)) {
-                    echo '<span class="unread"> <a href="'.$CFG->wwwroot.'/mod/forum/view.php?id='.$mod->id.'">';
-                    if ($unread == 1) {
-                        echo $strunreadpostsone;
-                    } else {
-                        print_string('unreadpostsnumber', 'forum', $unread);
-                    }
-                    echo '</a></span>';
+                    echo '<div ' . $textcss . $mod->extra .
+                            ' >' . '<img src="' . $mod->get_icon_url() .
+                            '" class="activityicon" alt="' .
+                            $modulename .
+                            '" /> <span>'. $instancename . $altname .
+                            '</span></div>';
+
+                    // Do not display content after link when it is greyed out like this.
+                } else {
+                    // No link, so display only content (also greyed)
+                    $contentpart = '<div ' . $textcss . $mod->extra . '>' .
+                            $accesstext . $content . '</div>';
                 }
             }
 
+            // Module can put text after the link (e.g. forum unread)
+            echo $mod->get_after_link();
+
             if ($isediting) {
                 if ($groupbuttons and plugin_supports('mod', $mod->modname, FEATURE_GROUPS, 0)) {
                     if (! $mod->groupmodelink = $groupbuttonslink) {
@@ -1494,6 +1585,7 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
                 }
                 echo '&nbsp;&nbsp;';
                 echo make_editing_buttons($mod, $absolute, true, $mod->indent, $section->section);
+                echo $mod->get_after_edit_icons();
             }
 
             // Completion
@@ -1566,6 +1658,9 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
                 }
             }
 
+            // Display the content (if any) at this part of the html
+            echo $contentpart;
+
             // Show availability information (for someone who isn't allowed to
             // see the activity itself, or for staff)
             if (!$mod->uservisible) {
@@ -1757,17 +1852,16 @@ function rebuild_course_cache($courseid=0, $clearonly=false) {
         @set_time_limit(0);  // this could take a while!   MDL-10954
     }
 
-    if ($rs = $DB->get_recordset("course", $select,'','id,fullname')) {
-        foreach ($rs as $course) {
-            $modinfo = serialize(get_array_of_activities($course->id));
-            $DB->set_field("course", "modinfo", $modinfo, array("id"=>$course->id));
-            // update cached global COURSE too ;-)
-            if ($course->id == $COURSE->id) {
-                $COURSE->modinfo = $modinfo;
-            }
+    $rs = $DB->get_recordset("course", $select,'','id,fullname');
+    foreach ($rs as $course) {
+        $modinfo = serialize(get_array_of_activities($course->id));
+        $DB->set_field("course", "modinfo", $modinfo, array("id"=>$course->id));
+        // update cached global COURSE too ;-)
+        if ($course->id == $COURSE->id) {
+            $COURSE->modinfo = $modinfo;
         }
-        $rs->close();
     }
+    $rs->close();
     // reset the fast modinfo cache
     $reset = 'reset';
     get_fast_modinfo($reset);
index 4a630b2..9f3df05 100644 (file)
@@ -632,7 +632,7 @@ foreach ($progress as $user) {
                 $describe = get_string('completion-alt-auto-'.$completiontype,'completion');
 
                 print '<td class="completion-progresscell">'.
-                    '<a href="'.$CFG->wwwroot.'/course/togglecompletion.php?user='.$user->id.'&course='.$course->id.'&rolec='.$allow_marking_criteria.'">'.
+                    '<a href="'.$CFG->wwwroot.'/course/togglecompletion.php?user='.$user->id.'&amp;course='.$course->id.'&amp;rolec='.$allow_marking_criteria.'&amp;sesskey='.sesskey().'">'.
                     '<img src="'.$OUTPUT->pix_url('i/completion-manual-'.($is_complete ? 'y' : 'n')).
                     '" alt="'.$describe.'" class="icon" title="Mark as complete" /></a></td>'; //TODO: localize
             } else {
index 5c151df..ad4ef64 100644 (file)
@@ -74,7 +74,7 @@
     foreach ($modinfo->sections as $sectionnum=>$section) {
         foreach ($section as $cmid) {
             $cm = $modinfo->cms[$cmid];
-            if ($cm->modname == 'label') {
+            if (!$cm->has_view()) {
                 continue;
             }
             if (!$cm->uservisible) {
index bb460b8..2ad66bb 100644 (file)
@@ -63,7 +63,7 @@
 
     $modinfo = get_fast_modinfo($course);
 
-    $modules = $DB->get_records_select('modules', "visible = 1 AND name <> 'label'", null, 'name ASC');
+    $modules = $DB->get_records_select('modules', "visible = 1", null, 'name ASC');
 
     $instanceoptions = array();
     foreach ($modules as $module) {
         }
         $instances = array();
         foreach ($modinfo->instances[$module->name] as $cm) {
+            // Skip modules such as label which do not actually have links;
+            // this means there's nothing to participate in
+            if (!$cm->has_view()) {
+                continue;
+            }
             $instances[$cm->id] = format_string($cm->name);
         }
+        if (count($instances) == 0) {
+            continue;
+        }
         $instanceoptions[] = array(get_string('modulenameplural', $module->name)=>$instances);
     }
 
index b98ced9..abf50b2 100644 (file)
@@ -37,9 +37,6 @@ $allmodules = $DB->get_records('modules', array('visible'=>1));
 $modules = array();
 foreach ($allmodules as $key=>$module) {
     $modname = $module->name;
-    if ($modname === 'label') {
-        continue;
-    }
     $libfile = "$CFG->dirroot/mod/$modname/lib.php";
     if (!file_exists($libfile)) {
         continue;
@@ -80,6 +77,10 @@ foreach ($modinfo->cms as $cm) {
     if (!array_key_exists($cm->modname, $modules)) {
         continue;
     }
+    if (!$cm->has_view()) {
+        // Exclude label and similar
+        continue;
+    }
     $cms[$cm->id] = $cm;
     $resources[$cm->modname][] = $cm->instance;
 }
index 9f5e82c..d720144 100644 (file)
@@ -38,9 +38,10 @@ if (!$cmid && !$courseid) {
 // Process self completion
 if ($courseid) {
     $PAGE->set_url(new moodle_url('/course/togglecompletion.php', array('course'=>$courseid)));
-    
+
     // Check user is logged in
     $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
+    $context = get_context_instance(CONTEXT_COURSE, $course->id);
     require_login($course);
 
     $completion = new completion_info($course);
@@ -50,14 +51,19 @@ if ($courseid) {
     $rolec = optional_param('rolec', 0, PARAM_INT);
 
     if ($user && $rolec) {
+        require_sesskey();
+
+        completion_criteria::factory((object) array('id'=>$rolec, 'criteriatype'=>COMPLETION_CRITERIA_TYPE_ROLE)); //TODO: this is dumb, because it does not fetch the data?!?!
+        $criteria = completion_criteria_role::fetch(array('id'=>$rolec));
 
-        $criteria = completion_criteria::factory((object) array('id'=>$rolec, 'criteriatype'=>COMPLETION_CRITERIA_TYPE_ROLE));
-        $criteria_completions = $completion->get_completions($user, COMPLETION_CRITERIA_TYPE_ROLE);
+        if ($criteria and user_has_role_assignment($USER->id, $criteria->role, $context->id)) {
+            $criteria_completions = $completion->get_completions($user, COMPLETION_CRITERIA_TYPE_ROLE);
 
-        foreach ($criteria_completions as $criteria_completion) {
-            if ($criteria_completion->criteriaid == $rolec) {
-                $criteria->complete($criteria_completion);
-                break;
+            foreach ($criteria_completions as $criteria_completion) {
+                if ($criteria_completion->criteriaid == $rolec) {
+                    $criteria->complete($criteria_completion);
+                    break;
+                }
             }
         }
 
@@ -71,7 +77,7 @@ if ($courseid) {
     } else {
 
         // Confirm with user
-        if ($confirm) {
+        if ($confirm and confirm_sesskey()) {
             $completion = $completion->get_completion($USER->id, COMPLETION_CRITERIA_TYPE_SELF);
 
             if (!$completion) {
@@ -94,7 +100,7 @@ if ($courseid) {
         $PAGE->set_heading($course->fullname);
         $PAGE->navbar->add($strconfirm);
         echo $OUTPUT->header();
-        $buttoncontinue = new single_button(new moodle_url('/course/togglecompletion.php', array('course'=>$courseid, 'confirm'=>1)), get_string('yes'), 'post');
+        $buttoncontinue = new single_button(new moodle_url('/course/togglecompletion.php', array('course'=>$courseid, 'confirm'=>1, 'sesskey'=>sesskey())), get_string('yes'), 'post');
         $buttoncancel   = new single_button(new moodle_url('/course/view.php', array('id'=>$courseid)), get_string('no'), 'get');
         echo $OUTPUT->confirm($strconfirm, $buttoncontinue, $buttoncancel);
         echo $OUTPUT->footer();
index c50dc40..b5ab6cd 100644 (file)
@@ -400,7 +400,8 @@ switch ($mode) {
         }
 
         // Check if result is empty
-        if (!$rs = $DB->get_recordset_sql($sql)) {
+        $rs = $DB->get_recordset_sql($sql);
+        if (!$rs->valid()) {
 
             if ($course->id != 1) {
                 $error = get_string('nocompletions', 'coursereport_completion');
@@ -409,6 +410,7 @@ switch ($mode) {
             }
 
             echo $OUTPUT->notification($error);
+            $rs->close(); // not going to loop (but break), close rs
             break;
         }
 
@@ -437,8 +439,7 @@ switch ($mode) {
                 $courses['unstarted'][] = $c_info;
             }
         }
-
-        $rs->close();
+        $rs->close(); // after loop, close rs
 
         // Loop through course status groups
         foreach ($courses as $type => $infos) {
index a1f946f..a05c20e 100644 (file)
@@ -194,7 +194,9 @@ function send_welcome_messages($orderdata) {
              WHERE e.id IN(" . implode(',', $orderdata) . ")
           ORDER BY e.userid";
 
-    if (!$rs = $DB->get_recordset_sql($sql)) {
+    $rs = $DB->get_recordset_sql($sql);
+    if (!$rs->valid()) {
+        $rs->close(); // Not going to iterate (but exit), close rs
         return;
     }
 
@@ -247,7 +249,7 @@ function send_welcome_messages($orderdata) {
         }
         while ($ei);
 
-        $rs->close();
+        $rs->close(); // end of iteration, close rs
     }
 }
 
diff --git a/enrol/imsenterprise/db/install.php b/enrol/imsenterprise/db/install.php
new file mode 100644 (file)
index 0000000..0180d16
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * imsenterprise enrolment plugin installation.
+ *
+ * @package    enrol
+ * @subpackage imsenterprise
+ * @copyright  2011 Petr Skoda {@link http://skodak.org}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+function xmldb_enrol_imsenterprise_install() {
+    global $CFG, $DB;
+
+    // NOTE: this file is executed during upgrade from 1.9.x!
+
+
+    // this plugin does not use the new file api - lets undo the migration
+    $fs = get_file_storage();
+
+    if ($DB->record_exists('course', array('id'=>1))) { //course 1 is hardcoded here intentionally!
+        if ($context = get_context_instance(CONTEXT_COURSE, 1)) {
+            if ($file = $fs->get_file($context->id, 'course', 'legacy', 0, '/', 'imsenterprise-enrol.xml')) {
+                if (!file_exists("$CFG->dataroot/1/imsenterprise-enrol.xml")) {
+                    check_dir_exists($CFG->dataroot.'/');
+                    $file->copy_content_to("$CFG->dataroot/1/imsenterprise-enrol.xml");
+                }
+                $file->delete();
+            }
+        }
+    }
+
+    if (!empty($CFG->enrol_imsfilelocation)) {
+        if (strpos($CFG->enrol_imsfilelocation, "$CFG->dataroot/") === 0) {
+            $location = str_replace("$CFG->dataroot/", '', $CFG->enrol_imsfilelocation);
+            $location = str_replace('\\', '/', $location);
+            $parts = explode('/', $location);
+            $courseid = array_shift($parts);
+            if (is_number($courseid) and $DB->record_exists('course', array('id'=>$courseid))) {
+                if ($context = get_context_instance(CONTEXT_COURSE, $courseid)) {
+                    $file = array_pop($parts);
+                    if ($parts) {
+                        $dir = '/'.implode('/', $parts).'/';
+                    } else {
+                        $dir = '/';
+                    }
+                    if ($file = $fs->get_file($context->id, 'course', 'legacy', 0, $dir, $file)) {
+                        if (!file_exists($CFG->enrol_imsfilelocation)) {
+                            check_dir_exists($CFG->dataroot.'/'.$courseid.$dir);
+                            $file->copy_content_to($CFG->enrol_imsfilelocation);
+                        }
+                        $file->delete();
+                    }
+                }
+            }
+        }
+    }
+
+
+    // TODO: migrate old config settings
+
+}
diff --git a/enrol/imsenterprise/db/upgrade.php b/enrol/imsenterprise/db/upgrade.php
new file mode 100644 (file)
index 0000000..a7d9841
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This file keeps track of upgrades to the imsenterprise enrolment plugin
+ *
+ * @package    enrol
+ * @subpackage imsenterprise
+ * @copyright  2011 Petr Skoda {@link http://skodak.org
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+function xmldb_enrol_imsenterprise_upgrade($oldversion) {
+    global $CFG, $DB, $OUTPUT;
+
+    $dbman = $DB->get_manager();
+
+
+    //NOTE: this file is not executed during upgrade from 1.9.x!
+
+
+    if ($oldversion < 2011013000) {
+        // this plugin does not use the new file api - lets undo the migration
+
+        $fs = get_file_storage();
+
+        if ($DB->record_exists('course', array('id'=>1))) { //course 1 is hardcoded here intentionally!
+            if ($context = get_context_instance(CONTEXT_COURSE, 1)) {
+                if ($file = $fs->get_file($context->id, 'course', 'legacy', 0, '/', 'imsenterprise-enrol.xml')) {
+                    if (!file_exists("$CFG->dataroot/1/imsenterprise-enrol.xml")) {
+                        check_dir_exists($CFG->dataroot.'/');
+                        $file->copy_content_to("$CFG->dataroot/1/imsenterprise-enrol.xml");
+                    }
+                    $file->delete();
+                }
+            }
+        }
+
+        if (!empty($CFG->enrol_imsfilelocation)) {
+            if (strpos($CFG->enrol_imsfilelocation, "$CFG->dataroot/") === 0) {
+                $location = str_replace("$CFG->dataroot/", '', $CFG->enrol_imsfilelocation);
+                $location = str_replace('\\', '/', $location);
+                $parts = explode('/', $location);
+                $courseid = array_shift($parts);
+                if (is_number($courseid) and $DB->record_exists('course', array('id'=>$courseid))) {
+                    if ($context = get_context_instance(CONTEXT_COURSE, $courseid)) {
+                        $file = array_pop($parts);
+                        if ($parts) {
+                            $dir = '/'.implode('/', $parts).'/';
+                        } else {
+                            $dir = '/';
+                        }
+                        if ($file = $fs->get_file($context->id, 'course', 'legacy', 0, $dir, $file)) {
+                            if (!file_exists($CFG->enrol_imsfilelocation)) {
+                                check_dir_exists($CFG->dataroot.'/'.$courseid.$dir);
+                                $file->copy_content_to($CFG->enrol_imsfilelocation);
+                            }
+                            $file->delete();
+                        }
+                    }
+                }
+            }
+        }
+
+        upgrade_plugin_savepoint(true, 2011013000, 'enrol', 'imsenterprise');
+    }
+
+
+    return true;
+}
+
+
index e0be8af..a955872 100644 (file)
@@ -26,5 +26,5 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2010071200;
+$plugin->version = 2011013000;
 $plugin->cron = 60;
index c977fcf..99f4779 100644 (file)
@@ -179,12 +179,12 @@ class enrol_self_plugin extends enrol_plugin {
             return null;
         }
 
-        if ($instance->enrolstartdate != 0 and $instance->enrolstartdate < time()) {
+        if ($instance->enrolstartdate != 0 and $instance->enrolstartdate > time()) {
             //TODO: inform that we can not enrol yet
             return null;
         }
 
-        if ($instance->enrolenddate != 0 and $instance->enrolenddate > time()) {
+        if ($instance->enrolenddate != 0 and $instance->enrolenddate < time()) {
             //TODO: inform that enrolment is not possible any more
             return null;
         }
index 345d6e5..6ffcaf9 100644 (file)
@@ -23,4 +23,4 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$string['filtername'] = 'Activity Names Auto-linking';
+$string['filtername'] = 'Activity names auto-linking';
index 711539e..5435f7f 100644 (file)
@@ -23,4 +23,4 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$string['filtername'] = 'Algebra Notation';
+$string['filtername'] = 'Algebra notation';
index 36c86db..5669366 100644 (file)
@@ -23,5 +23,5 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$string['badwords'] = 'shit,fucked,fucker,fuck,dickhead, dick,cockhead,cock,cunt,asshole,arsehole,prick,bitch, jism,whore,slut,wanker, wank,bastard,dildo,masturbate, orgasm,penis,nigger, pussy,vagina';
-$string['filtername'] = 'Word Censorship';
+$string['badwords'] = 'shit,fucked,fucker,fuck,dickhead,dick,cockhead,cock,cunt,asshole,arsehole,prick,bitch,jism,whore,slut,wanker,wank,bastard,dildo,masturbate,orgasm,penis,nigger,pussy,vagina';
+$string['filtername'] = 'Word censorship';
index 26a3fec..7c86187 100644 (file)
@@ -23,4 +23,4 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$string['filtername'] = 'Email Protection';
+$string['filtername'] = 'Email protection';
index 59d8151..6a9ec85 100644 (file)
@@ -125,6 +125,9 @@ class filter_mediaplugin extends moodle_text_filter {
 
             $search = '/<a[^>]*href="([^<]*)youtube.com\/v\/([^"]*)"[^>]*>(.*?)<\/a>/is';
             $newtext = preg_replace_callback($search, 'filter_mediaplugin_youtube_callback', $newtext);
+
+            $search = '/<a(\s+[^>]+?)?\s+href="((([^"]+)youtube\.com)\/view_play_list\?p=([^"]*))"[^>]*>(.*?)<\/a>/is';
+            $newtext = preg_replace_callback($search, 'filter_mediaplugin_youtube_playlist_callback', $newtext);
         }
 
         if (!empty($CFG->filter_mediaplugin_enable_img)) {
@@ -349,6 +352,25 @@ function filter_mediaplugin_youtube_callback($link, $autostart=false) {
            '</object>';
 }
 
+/**
+ * Change Youtube playlist into embedded Youtube playlist videos
+ */
+function filter_mediaplugin_youtube_playlist_callback($link, $autostart=false) {
+
+    $site = s($link[4]);
+    $param = s($link[5]);
+    $info = s($link[6]);
+
+    return '<object title="'.$info.'"
+                    class="mediaplugin mediaplugin_youtube" type="application/x-shockwave-flash"
+                    data="'.$site.'youtube.com/p/'.$param.'&amp;fs=1&amp;rel=0" width="400" height="320">'.
+           '<param name="movie" value="'.$site.'youtube.com/p/'.$param.'&amp;fs=1&amp;rel=0" />'.
+           '<param name="FlashVars" value="playerMode=embedded" />'.
+           '<param name="wmode" value="transparent" />'.
+           '<param name="allowFullScreen" value="true" />'.
+           '</object>';
+}
+
 /**
  * Change links to images into embedded images
  */
index fadff70..7ec6bae 100644 (file)
@@ -23,7 +23,7 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$string['filtername'] = 'Multimedia Plugins';
+$string['filtername'] = 'Multimedia plugins';
 $string['flashanimation'] = 'Flash animation';
 $string['flashvideo'] = 'Flash video';
 $string['mp3audio'] = 'MP3 audio';
index 434bab3..f7166ed 100644 (file)
@@ -23,4 +23,4 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$string['filtername'] = 'TeX Notation';
+$string['filtername'] = 'TeX notation';
index 6d66a6e..7a84094 100644 (file)
@@ -634,12 +634,11 @@ class grade_report_user extends grade_report {
                   GROUP BY gg.itemid";
 
             $sum_array = array();
-            if ($sums = $DB->get_recordset_sql($sql, $params)) {
-                foreach ($sums as $itemid => $csum) {
-                    $sum_array[$itemid] = $csum->sum;
-                }
-                $sums->close();
+            $sums = $DB->get_recordset_sql($sql, $params);
+            foreach ($sums as $itemid => $csum) {
+                $sum_array[$itemid] = $csum->sum;
             }
+            $sums->close();
 
             $columncount=0;
 
index 53a5a8b..88d348c 100644 (file)
@@ -80,26 +80,25 @@ $sql = "SELECT g.id AS groupid, gg.groupingid, u.id AS userid, u.firstname, u.la
          WHERE g.courseid = :courseid $groupwhere $groupingwhere
       ORDER BY g.name, u.lastname, u.firstname";
 
-if ($rs = $DB->get_recordset_sql($sql, $params)) {
-    foreach ($rs as $row) {
-        $user = new stdClass();
-        $user->id        = $row->userid;
-        $user->firstname = $row->firstname;
-        $user->lastname  = $row->lastname;
-        $user->username  = $row->username;
-        $user->idnumber  = $row->idnumber;
-        if (!$row->groupingid) {
-            $row->groupingid = -1;
-        }
-        if (!array_key_exists($row->groupid, $members[$row->groupingid])) {
-            $members[$row->groupingid][$row->groupid] = array();
-        }
-        if(isset($user->id)){
-           $members[$row->groupingid][$row->groupid][] = $user;
-        }
+$rs = $DB->get_recordset_sql($sql, $params);
+foreach ($rs as $row) {
+    $user = new stdClass();
+    $user->id        = $row->userid;
+    $user->firstname = $row->firstname;
+    $user->lastname  = $row->lastname;
+    $user->username  = $row->username;
+    $user->idnumber  = $row->idnumber;
+    if (!$row->groupingid) {
+        $row->groupingid = -1;
+    }
+    if (!array_key_exists($row->groupid, $members[$row->groupingid])) {
+        $members[$row->groupingid][$row->groupid] = array();
+    }
+    if(isset($user->id)){
+        $members[$row->groupingid][$row->groupid][] = $user;
     }
-    $rs->close();
 }
+$rs->close();
 
 navigation_node::override_active_url(new moodle_url('/group/index.php', array('id'=>$courseid)));
 $PAGE->navbar->add(get_string('overview', 'group'));
index 239eb85..ad2e8e4 100644 (file)
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+$string['cliincorrectvalueerror'] = 'Error, valor incorrecte "{$a->value}" per a "{$a->option}"';
+$string['cliincorrectvalueretry'] = 'Valor incorrecte, si us plau, torneu-ho a provar.';
+$string['clitypevalue'] = 'Valor de tipus';
+$string['clitypevaluedefault'] = 'valor de tipus, premeu Intro per fer servir un valor per defecte ({$a})';
+$string['cliunknowoption'] = 'Opcions invàlides: 
+ {$a}
+L\'opció --help us orientarà.';
 $string['environmentrequireinstall'] = 'es requereix instal·lar/habilitar';
 $string['environmentrequireversion'] = 'esteu executant la versió {$a->current} i es requereix la {$a->needed}';
index 3523a68..9635987 100644 (file)
@@ -35,11 +35,11 @@ $string['cannotdownloadzipfile'] = 'Kan ikke downloade zip-fil';
 $string['cannotfindcomponent'] = 'Kan ikke finde komponent';
 $string['cannotsavemd5file'] = 'Kan ikke gemme md5-fil';
 $string['cannotsavezipfile'] = 'Kan ikke gemme zip-fil';
-$string['cannotunzipfile'] = 'Kan ikke unzippe filen';
+$string['cannotunzipfile'] = 'Kan ikke pakke filen ud';
 $string['componentisuptodate'] = 'Komponenten er ajour';
 $string['downloadedfilecheckfailed'] = 'Downloadet fil-tjek fejlede';
-$string['invalidmd5'] = 'Ugyldig md5';
+$string['invalidmd5'] = 'Tjekvariablen var forkert - prøv igen';
 $string['missingrequiredfield'] = 'Der mangler nogle obligatoriske felter';
 $string['wrongdestpath'] = 'Forkert destinationssti';
 $string['wrongsourcebase'] = 'Forkert kilde-URL';
-$string['wrongzipfilename'] = 'Forkert zip-filnavn.';
+$string['wrongzipfilename'] = 'Forkert zip-filnavn';
index 3475113..214d968 100644 (file)
@@ -72,7 +72,7 @@ $string['pathssubdataroot'] = 'Du har brug for et sted, hvor Moodle kan gemme up
 $string['pathssubdirroot'] = 'Den fulde sti til Moodleinstallationen.';
 $string['pathssubwwwroot'] = 'Moodles fulde web-adresse. 
 Det er ikke muligt at komme ind på Moodle fra mere end en adresse.
-Hvis dit websted har flere offentlige adresser skal du opsætte permanent viderestilling på dem alle undtagen fra denne.
+Hvis dit websted har flere offentlige adresser skal du opsætte permanent viderestilling til dem alle undtagen denne.
 Hvis dit websted er tilgængeligt fra både internet og intranet skal du bruge internetadressen her og opsætte din DNS sådan at intranet-brugerne kan bruge den offentlige adresse også.
 Hvis ikke adressen er korrekt må du ændre URL\'en i din browser og genstarte installationen med den rigtige adresse.
 ';
index 11739b9..8f5a3c5 100644 (file)
@@ -32,12 +32,19 @@ $string['admindirname'] = 'ספריית מנהל המערכת';
 $string['availablelangs'] = 'חבילות שפה זמינות';
 $string['chooselanguagehead'] = 'בחר שפה';
 $string['chooselanguagesub'] = 'אנא בחר שפה עבור ההתקנה בלבד. תוכל לבחור בשפה שונה לאתר ולמשתמש באחד מהמסכים הבאים.';
+$string['clialreadyinstalled'] = 'קובץ ה-config.php קיים כבר, אנא השתמש ב- admin/cli/upgrade.php
+אם ברצונך לשדרג את האתר שלך.';
+$string['cliinstallheader'] = 'תוכנית התקנת Moodle {$a} בשורת הפקודה';
 $string['databasehost'] = 'מסד הנתונים המארח (host)';
 $string['databasename'] = 'שם מסד הנתונים';
+$string['databasetypehead'] = 'בחר התקן מסד הנתונים';
 $string['dataroot'] = 'ספריית הנתונים';
 $string['dbprefix'] = 'Tables prefix';
 $string['dirroot'] = 'ספריית ה-Moodle';
 $string['environmenthead'] = 'בודק את הסביבה שלך...';
+$string['environmentsub2'] = 'לכל התקנת Moodle יש דרישות מינימליות לגרסת ה-PHP ומספר הרחבות הכרחי של ה-PHP.
+בדיקת הסביבה הושלמה לפני התקנת כל אחד ושדרוגו.אם הינך מתקשה, אנא פנה למנהל המערכת בכדי להתקין גרסת PHP חדשה או לאפשר הרחבות PHP.';
+$string['errorsinenvironment'] = 'בדיקת הסביבה נכשלה!';
 $string['installation'] = 'התקנה';
 $string['langdownloaderror'] = 'לצערינו השפה "{$a}" לא הותקנה. תהליך ההתקנה ימשיך באנגלית.';
 $string['memorylimithelp'] = '<p>
@@ -62,6 +69,16 @@ $string['memorylimithelp'] = '<p>
 </ol>
 
 </p>';
+$string['paths'] = 'נתיבים';
+$string['pathserrcreatedataroot'] = 'ספריית המידע (Data Directory) - ({$a->dataroot}) לא יכולה להיווצר על-ידי המתקין.';
+$string['pathshead'] = 'נתיבים מאושרים';
+$string['pathsrodataroot'] = 'ספריית המידע (Data Directory) לא ניתנת לכתיבה.';
+$string['pathsroparentdataroot'] = 'ספריית האב - ({$a->parent}) לא ניתנת לכתיבה. 
+ספריית המידע (Data Directory) - ({$a->dataroot}) לא יכולה להיווצר על-ידי המתקין. ';
+$string['pathssubdirroot'] = 'הנתיב המלא לספריית ההתקנה של Moodle';
+$string['pathsunsecuredataroot'] = 'ספריית המידע (Data Directory) לא מאובטחת';
+$string['pathswrongadmindir'] = 'ספריית ה-admin לא קיימת';
+$string['phpextension'] = 'הרחבת PHP {$a}';
 $string['phpversion'] = 'גירסת PHP';
 $string['phpversionhelp'] = '<p>גירסת PHP חייבת להיות לפחות 4.3.0 או 5.1.0 (בגירסאות 5.0.x קיימות מספר בעיות ידועות) </p>
 <p> במערכת שלך פועלת כרגע גירסת {$a} </p>
index 353f2f2..83f4f9f 100644 (file)
@@ -28,5 +28,6 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+$string['parentlanguage'] = 'no';
 $string['thisdirection'] = 'ltr';
 $string['thislanguage'] = 'Norsk - nynorsk';
index 26bd66d..499fe84 100644 (file)
@@ -28,5 +28,9 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+$string['cliincorrectvalueerror'] = 'Błąd, niepoprawna wartość "{$a->value}" dla "{$a->option}"';
+$string['clitypevalue'] = 'typ wartości';
+$string['clitypevaluedefault'] = 'typ wartości, naciśnij Enter, aby użyć wartości domyślnej ({$a})';
+$string['cliyesnoprompt'] = 'wpisz y (czyli tak) lub n (czyli nie)';
 $string['environmentrequireinstall'] = 'jest niezbędnę, żeby było zainstalowane/włączone';
 $string['environmentrequireversion'] = 'wersja {$a->needed} jest niezbędna a ty używasz wersji {$a->current}';
index 8e7cc6c..6c1aa02 100644 (file)
@@ -32,6 +32,8 @@ $string['admindirname'] = 'Katalog admin';
 $string['availablelangs'] = 'Dostępne paczki językowe';
 $string['chooselanguagehead'] = 'Wybierz język';
 $string['chooselanguagesub'] = 'Proszę wybrać język TYLKO do instalacji. Stronę i języki dla użytkowników będzie można wybrać na następnym ekranie.';
+$string['databasehost'] = 'Host bazy danych';
+$string['databasename'] = 'Nazwa bazy danych';
 $string['dataroot'] = 'Katalog z danymi';
 $string['dbprefix'] = 'prefiksy tabel';
 $string['dirroot'] = 'Katalog Moodle';
index 854f87e..73691ec 100644 (file)
@@ -29,7 +29,7 @@
  */
 
 $string['cannotcreatelangdir'] = 'Não é possível criar o directório para pacotes linguísticos';
-$string['cannotcreatetempdir'] = 'Não é possível criar o directório temporal';
+$string['cannotcreatetempdir'] = 'Não é possível criar o directório temporário';
 $string['cannotdownloadcomponents'] = 'Não é possível descarregar a cópia dos componentes';
 $string['cannotdownloadzipfile'] = 'Não é possível descarregar a cópia do ficheiro ZIP';
 $string['cannotfindcomponent'] = 'Não foi encontrado um componente';
index ce40a1a..0d44e8f 100644 (file)
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+$string['clianswerno'] = 'n';
+$string['cliansweryes'] = 'd';
+$string['cliincorrectvalueerror'] = 'Napaka, nepravilna vrednost "{$a->value}" za "{$a->option}"';
+$string['cliincorrectvalueretry'] = 'Nepravilna vrednost, prosimo poskusite znova.';
+$string['clitypevalue'] = 'tip vrednosti';
+$string['clitypevaluedefault'] = 'tip vrednosti, kliknite Enter za uporabo privzete vrednosti ({$a})';
+$string['cliunknowoption'] = 'Neprepoznane možnosti:
+{$a}
+Uporabite --help opcijo.';
+$string['cliyesnoprompt'] = 'pritisnite d (pomeni da) ali n (pomeni ne)';
 $string['environmentrequireinstall'] = 'namestitev oz. omogočanje je zahtevano.';
 $string['environmentrequireversion'] = 'različica {$a->needed} je zahtevana, vi uporabljate {$a->current}';
index 87a8287..e36c126 100755 (executable)
@@ -425,12 +425,11 @@ function get_role_access($roleid, $accessdata = null) {
 
         if (!isset($ACCESSLIB_PRIVATE->croncache[$roleid])) {
             $ACCESSLIB_PRIVATE->croncache[$roleid] = array();
-            if ($rs = $DB->get_recordset_sql($sql, $params)) {
-                foreach ($rs as $rd) {
-                    $ACCESSLIB_PRIVATE->croncache[$roleid][] = $rd;
-                }
-                $rs->close();
+            $rs = $DB->get_recordset_sql($sql, $params);
+            foreach ($rs as $rd) {
+                $ACCESSLIB_PRIVATE->croncache[$roleid][] = $rd;
             }
+            $rs->close();
         }
 
         foreach ($ACCESSLIB_PRIVATE->croncache[$roleid] as $rd) {
@@ -439,14 +438,15 @@ function get_role_access($roleid, $accessdata = null) {
         }
 
     } else {
-        if ($rs = $DB->get_recordset_sql($sql, $params)) {
+        $rs = $DB->get_recordset_sql($sql, $params);
+        if ($rs->valid()) {
             foreach ($rs as $rd) {
                 $k = "{$rd->path}:{$roleid}";
                 $accessdata['rdef'][$k][$rd->capability] = $rd->permission;
             }
             unset($rd);
-            $rs->close();
         }
+        $rs->close();
     }
 
     return $accessdata;
@@ -480,14 +480,15 @@ function get_default_frontpage_role_access($roleid, $accessdata = null) {
           ORDER BY ctx.depth, ctx.path";
     $params = array($roleid, "$base/%");
 
-    if ($rs = $DB->get_recordset_sql($sql, $params)) {
+    $rs = $DB->get_recordset_sql($sql, $params);
+    if ($rs->valid()) {
         foreach ($rs as $rd) {
             $k = "{$rd->path}:{$roleid}";
             $accessdata['rdef'][$k][$rd->capability] = $rd->permission;
         }
         unset($rd);
-        $rs->close();
     }
+    $rs->close();
 
     return $accessdata;
 }
@@ -1315,18 +1316,15 @@ function load_subcontext($userid, $context, &$accessdata) {
     $params = array($context->id, $context->path."/%");
 
     $newrdefs = array();
-    if ($rs = $DB->get_recordset_sql($sql, $params)) {
-        foreach ($rs as $rd) {
-            $k = "{$rd->path}:{$rd->roleid}";
-            if (!array_key_exists($k, $newrdefs)) {
-                $newrdefs[$k] = array();
-            }
-            $newrdefs[$k][$rd->capability] = $rd->permission;
+    $rs = $DB->get_recordset_sql($sql, $params);
+    foreach ($rs as $rd) {
+        $k = "{$rd->path}:{$rd->roleid}";
+        if (!array_key_exists($k, $newrdefs)) {
+            $newrdefs[$k] = array();
         }
-        $rs->close();
-    } else {
-        debugging('Bad SQL encountered!');
+        $newrdefs[$k][$rd->capability] = $rd->permission;
     }
+    $rs->close();
 
     compact_rdefs($newrdefs);
     foreach ($newrdefs as $key=>$value) {
@@ -1389,13 +1387,12 @@ function get_role_access_bycontext($roleid, $context, $accessdata = null) {
           ORDER BY ctx.depth ASC, ctx.path DESC, rc.roleid ASC ";
     $params = array($roleid, $context->path."/%");
 
-    if ($rs = $DB->get_recordset_sql($sql, $params)) {
-        foreach ($rs as $rd) {
-            $k = "{$rd->path}:{$roleid}";
-            $accessdata['rdef'][$k][$rd->capability] = $rd->permission;
-        }
-        $rs->close();
+    $rs = $DB->get_recordset_sql($sql, $params);
+    foreach ($rs as $rd) {
+        $k = "{$rd->path}:{$roleid}";
+        $accessdata['rdef'][$k][$rd->capability] = $rd->permission;
     }
+    $rs->close();
 
     return $accessdata;
 }
@@ -1615,13 +1612,12 @@ function load_temp_role($context, $roleid, array $accessdata) {
                    AND rc.roleid = ?
           ORDER BY ctx.depth, ctx.path";
     $params = array($context->path."/%", $roleid);
-    if ($rs = $DB->get_recordset_sql($sql, $params)) {
-        foreach ($rs as $rd) {
-            $k = "{$rd->path}:{$roleid}";
-            $accessdata['rdef'][$k][$rd->capability] = $rd->permission;
-        }
-        $rs->close();
+    $rs = $DB->get_recordset_sql($sql, $params);
+    foreach ($rs as $rd) {
+        $k = "{$rd->path}:{$roleid}";
+        $accessdata['rdef'][$k][$rd->capability] = $rd->permission;
     }
+    $rs->close();
 
     //
     // Say we loaded everything for the course context
@@ -2132,12 +2128,11 @@ function cleanup_contexts() {
     // transactions used only for performance reasons here
     $transaction = $DB->start_delegated_transaction();
 
-    if ($rs = $DB->get_recordset_sql($sql)) {
-        foreach ($rs as $ctx) {
-            delete_context($ctx->contextlevel, $ctx->instanceid);
-        }
-        $rs->close();
+    $rs = $DB->get_recordset_sql($sql);
+    foreach ($rs as $ctx) {
+        delete_context($ctx->contextlevel, $ctx->instanceid);
     }
+    $rs->close();
 
     $transaction->allow_commit();
     return true;
@@ -5335,16 +5330,13 @@ function get_user_capability_course($capability, $userid = null, $doanything = t
     // Note the result can be used directly as a context (we are going to), the course
     // fields are just appended.
 
-    if (!$rs = $DB->get_recordset_sql("SELECT x.*, c.id AS courseid $fieldlist
-                                         FROM {course} c
-                                        INNER JOIN {context} x
-                                              ON (c.id=x.instanceid AND x.contextlevel=".CONTEXT_COURSE.")
-                                     $orderby")) {
-         return false;
-    }
-
-    // Check capability for each course in turn
     $courses = array();
+    $rs = $DB->get_recordset_sql("SELECT x.*, c.id AS courseid $fieldlist
+                                    FROM {course} c
+                                   INNER JOIN {context} x
+                                         ON (c.id=x.instanceid AND x.contextlevel=".CONTEXT_COURSE.")
+                                $orderby");
+    // Check capability for each course in turn
     foreach ($rs as $coursecontext) {
         if (has_capability($capability, $coursecontext, $userid, $doanything)) {
             // We've got the capability. Make the record look like a course record
@@ -5357,7 +5349,7 @@ function get_user_capability_course($capability, $userid = null, $doanything = t
         }
     }
     $rs->close();
-    return $courses;
+    return empty($courses) ? false : $courses;
 }
 
 /**
@@ -5526,18 +5518,33 @@ function get_users_from_role_on_context($role, $context) {
 }
 
 /**
- * Simple function returning a boolean true if roles exist, otherwise false
+ * Simple function returning a boolean true if user has roles
+ * in context or parent contexts, otherwise false.
  *
  * @param int $userid
  * @param int $roleid
- * @param int $contextid
+ * @param int $contextid empty means any context
  * @return bool
  */
 function user_has_role_assignment($userid, $roleid, $contextid = 0) {
     global $DB;
 
     if ($contextid) {
-        return $DB->record_exists('role_assignments', array('userid'=>$userid, 'roleid'=>$roleid, 'contextid'=>$contextid));
+        if (!$context = get_context_instance_by_id($contextid)) {
+            return false;
+        }
+        $parents = get_parent_contexts($context, true);
+        list($contexts, $params) = $DB->get_in_or_equal($parents, SQL_PARAMS_NAMED, 'r0000');
+        $params['userid'] = $userid;
+        $params['roleid'] = $roleid;
+
+        $sql = "SELECT COUNT(ra.id)
+                  FROM {role_assignments} ra
+                 WHERE ra.userid = :userid AND ra.roleid = :roleid AND ra.contextid $contexts";
+
+        $count = $DB->get_field_sql($sql, $params);
+        return ($count > 0);
+
     } else {
         return $DB->record_exists('role_assignments', array('userid'=>$userid, 'roleid'=>$roleid));
     }
index feb5aa6..803dd94 100644 (file)
@@ -228,15 +228,13 @@ class completion_criteria_activity extends completion_criteria {
         ';
 
         // Loop through completions, and mark as complete
-        if ($rs = $DB->get_recordset_sql($sql)) {
-            foreach ($rs as $record) {
+        $rs = $DB->get_recordset_sql($sql);
+        foreach ($rs as $record) {
 
-                $completion = new completion_criteria_completion((array)$record);
-                $completion->mark_complete($record->timecompleted);
-            }
-
-            $rs->close();
+            $completion = new completion_criteria_completion((array)$record);
+            $completion->mark_complete($record->timecompleted);
         }
+        $rs->close();
     }
 
     /**
index afafeb5..2107c21 100644 (file)
@@ -185,14 +185,12 @@ class completion_criteria_course extends completion_criteria {
         ";
 
         // Loop through completions, and mark as complete
-        if ($rs = $DB->get_recordset_sql($sql)) {
-            foreach ($rs as $record) {
-                $completion = new completion_criteria_completion((array)$record);
-                $completion->mark_complete($record->timecompleted);
-            }
-
-            $rs->close();
+        $rs = $DB->get_recordset_sql($sql);
+        foreach ($rs as $record) {
+            $completion = new completion_criteria_completion((array)$record);
+            $completion->mark_complete($record->timecompleted);
         }
+        $rs->close();
     }
 
     /**
index 9551a88..9bd66a2 100644 (file)
@@ -178,15 +178,12 @@ class completion_criteria_date extends completion_criteria {
         ';
 
         // Loop through completions, and mark as complete
-        if ($rs = $DB->get_recordset_sql($sql, array(time()))) {
-            foreach ($rs as $record) {
-
-                $completion = new completion_criteria_completion((array)$record);
-                $completion->mark_complete($record->timeend);
-            }
-
-            $rs->close();
+        $rs = $DB->get_recordset_sql($sql, array(time()));
+        foreach ($rs as $record) {
+            $completion = new completion_criteria_completion((array)$record);
+            $completion->mark_complete($record->timeend);
         }
+        $rs->close();
     }
 
     /**
index 96847ec..bb4ab66 100644 (file)
@@ -219,22 +219,19 @@ class completion_criteria_duration extends completion_criteria {
 
         // Loop through completions, and mark as complete
         $now = time();
-        if ($rs = $DB->get_recordset_sql($sql, array($now, $now))) {
-            foreach ($rs as $record) {
+        $rs = $DB->get_recordset_sql($sql, array($now, $now));
+        foreach ($rs as $record) {
 
-                $completion = new completion_criteria_completion((array)$record);
+            $completion = new completion_criteria_completion((array)$record);
 
-                // Use time start if not 0, otherwise use timeenrolled
-                if ($record->otimestart) {
-                    $completion->mark_complete($record->ctimestart);
-                }
-                else {
-                    $completion->mark_complete($record->ctimeenrolled);
-                }
+            // Use time start if not 0, otherwise use timeenrolled
+            if ($record->otimestart) {
+                $completion->mark_complete($record->ctimestart);
+            } else {
+                $completion->mark_complete($record->ctimeenrolled);
             }
-
-            $rs->close();
         }
+        $rs->close();
     }
 
     /**
index 985942a..00e75ab 100644 (file)
@@ -214,15 +214,12 @@ class completion_criteria_grade extends completion_criteria {
         ';
 
         // Loop through completions, and mark as complete
-        if ($rs = $DB->get_recordset_sql($sql)) {
-            foreach ($rs as $record) {
-
-                $completion = new completion_criteria_completion((array)$record);
-                $completion->mark_complete($record->timecompleted);
-            }
-
-            $rs->close();
+        $rs = $DB->get_recordset_sql($sql);
+        foreach ($rs as $record) {
+            $completion = new completion_criteria_completion((array)$record);
+            $completion->mark_complete($record->timecompleted);
         }
+        $rs->close();
     }
 
     /**
index 1c30809..281a9d7 100644 (file)
@@ -118,9 +118,12 @@ function completion_cron_mark_started() {
             userid
     ";
 
-    // Check if result is empty
     $now = time();
-    if (!$rs = $DB->get_recordset_sql($sql, array($now, $now, $now, $now))) {
+    $rs = $DB->get_recordset_sql($sql, array($now, $now, $now, $now));
+
+    // Check if result is empty
+    if (!$rs->valid()) {
+        $rs->close(); // Not going to iterate (but exit), close rs
         return;
     }
 
@@ -267,8 +270,11 @@ function completion_cron_completions() {
             userid
     ';
 
+    $rs = $DB->get_recordset_sql($sql, array('timestarted' => $timestarted));
+
     // Check if result is empty
-    if (!$rs = $DB->get_recordset_sql($sql, array('timestarted' => $timestarted))) {
+    if (!$rs->valid()) {
+        $rs->close(); // Not going to iterate (but exit), close rs
         return;
     }
 
index cb3d926..79a69e4 100644 (file)
@@ -438,6 +438,12 @@ function get_courses_page($categoryid="all", $sort="c.sortorder ASC", $fields="c
 
     list($ccselect, $ccjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
 
+    $totalcount = 0;
+    if (!$limitfrom) {
+        $limitfrom = 0;
+    }
+    $visiblecourses = array();
+
     $sql = "SELECT $fields $ccselect
               FROM {course} c
               $ccjoin
@@ -445,17 +451,8 @@ function get_courses_page($categoryid="all", $sort="c.sortorder ASC", $fields="c
           ORDER BY $sort";
 
     // pull out all course matching the cat
-    if (!$rs = $DB->get_recordset_sql($sql, $params)) {
-        return array();
-    }
-    $totalcount = 0;
-
-    if (!$limitfrom) {
-        $limitfrom = 0;
-    }
-
+    $rs = $DB->get_recordset_sql($sql, $params);
     // iteration will have to be done inside loop to keep track of the limitfrom and limitnum
-    $visiblecourses = array();
     foreach($rs as $course) {
         context_instance_preload($course);
         if ($course->visible <= 0) {
@@ -764,35 +761,35 @@ function get_courses_search($searchterms, $sort='fullname ASC', $page=0, $record
 
     $searchcond = implode(" AND ", $searchcond);
 
+    $courses = array();
+    $c = 0; // counts how many visible courses we've seen
+
+    // Tiki pagination
+    $limitfrom = $page * $recordsperpage;
+    $limitto   = $limitfrom + $recordsperpage;
+
     list($ccselect, $ccjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
     $sql = "SELECT c.* $ccselect
               FROM {course} c
            $ccjoin
              WHERE $searchcond AND c.id <> ".SITEID."
           ORDER BY $sort";
-    $courses = array();
-    $c = 0; // counts how many visible courses we've seen
-
-    if ($rs = $DB->get_recordset_sql($sql, $params)) {
-        // Tiki pagination
-        $limitfrom = $page * $recordsperpage;
-        $limitto   = $limitfrom + $recordsperpage;
 
-        foreach($rs as $course) {
-            context_instance_preload($course);
-            $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
-            if ($course->visible || has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
-                // Don't exit this loop till the end
-                // we need to count all the visible courses
-                // to update $totalcount
-                if ($c >= $limitfrom && $c < $limitto) {
-                    $courses[$course->id] = $course;
-                }
-                $c++;
+    $rs = $DB->get_recordset_sql($sql, $params);
+    foreach($rs as $course) {
+        context_instance_preload($course);
+        $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
+        if ($course->visible || has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
+            // Don't exit this loop till the end
+            // we need to count all the visible courses
+            // to update $totalcount
+            if ($c >= $limitfrom && $c < $limitto) {
+                $courses[$course->id] = $course;
             }
+            $c++;
         }
-        $rs->close();
     }
+    $rs->close();
 
     // our caller expects 2 bits of data - our return
     // array, and an updated $totalcount
@@ -857,16 +854,15 @@ function get_categories($parent='none', $sort=NULL, $shallow=true) {
     }
     $categories = array();
 
-    if( $rs = $DB->get_recordset_sql($sql, $params) ){
-        foreach($rs as $cat) {
-            context_instance_preload($cat);
-            $catcontext = get_context_instance(CONTEXT_COURSECAT, $cat->id);
-            if ($cat->visible || has_capability('moodle/category:viewhiddencategories', $catcontext)) {
-                $categories[$cat->id] = $cat;
-            }
+    $rs = $DB->get_recordset_sql($sql, $params);
+    foreach($rs as $cat) {
+        context_instance_preload($cat);
+        $catcontext = get_context_instance(CONTEXT_COURSECAT, $cat->id);
+        if ($cat->visible || has_capability('moodle/category:viewhiddencategories', $catcontext)) {
+            $categories[$cat->id] = $cat;
         }
-        $rs->close();
     }
+    $rs->close();
     return $categories;
 }
 
index 8d63338..2088df6 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="lib/db" VERSION="20110114" COMMENT="XMLDB file for core Moodle tables"
+<XMLDB PATH="lib/db" VERSION="20110125" COMMENT="XMLDB file for core Moodle tables"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
 >
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
       </KEYS>
+      <INDEXES>
+        <INDEX NAME="userfieldidx" UNIQUE="false" FIELDS="userid, fieldid"/>
+      </INDEXES>
     </TABLE>
     <TABLE NAME="question_categories" COMMENT="Categories are for grouping questions" PREVIOUS="user_info_data" NEXT="question">
       <FIELDS>
index 4a5377e..1be183d 100644 (file)
@@ -2825,10 +2825,10 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
 
     if ($oldversion < 2010033102.00) {
         // rename course view capability to participate
-        $params = array('view'=>'moodle/course:view', 'participate'=>'moodle/course:participate');
-        $sql = "UPDATE {role_capabilities} SET capability = :participate WHERE capability = :view";
+        $params = array('viewcap'=>'moodle/course:view', 'participatecap'=>'moodle/course:participate');
+        $sql = "UPDATE {role_capabilities} SET capability = :participatecap WHERE capability = :viewcap";
         $DB->execute($sql, $params);
-        $sql = "UPDATE {capabilities} SET name = :participate WHERE name = :view";
+        $sql = "UPDATE {capabilities} SET name = :participatecap WHERE name = :viewcap";
         $DB->execute($sql, $params);
         // note: the view capability is readded again at the end of upgrade, but with different meaning
         upgrade_main_savepoint(true, 2010033102.00);
@@ -3933,8 +3933,8 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
     if ($oldversion < 2010061900.04) {
         // there is no default course role any more, each enrol plugin has to handle it separately
         if (!empty($CFG->defaultcourseroleid)) {
-            $sql = "UPDATE {course} SET defaultrole = :default WHERE defaultrole = 0";
-            $params = array('default' => $CFG->defaultcourseroleid);
+            $sql = "UPDATE {course} SET defaultrole = :defaultrole WHERE defaultrole = 0";
+            $params = array('defaultrole' => $CFG->defaultcourseroleid);
             $DB->execute($sql, $params);
         }
         unset_config('defaultcourseroleid');
@@ -5993,6 +5993,18 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
         upgrade_main_savepoint(true, 2011012500);
     }
 
+    if ($oldversion < 2011012501) {
+        //add the index userfieldidx (not unique) to user_info_data
+        $table = new xmldb_table('user_info_data');
+        $index = new xmldb_index('userfieldidx', XMLDB_INDEX_NOTUNIQUE, array('userid', 'fieldid'));
+
+        if (!$dbman->index_exists($table, $index)) {
+            $dbman->add_index($table, $index);
+        }
+
+        upgrade_main_savepoint(true, 2011012501);
+    }
+
     return true;
 }
 
index 0653ef7..27e797f 100644 (file)
@@ -38,15 +38,14 @@ function upgrade_fix_category_depths() {
     $sql = "SELECT c.id
               FROM {course_categories} c
              WHERE c.parent > 0 AND c.parent NOT IN (SELECT pc.id FROM {course_categories} pc)";
-    if ($rs = $DB->get_recordset_sql($sql)) {
-        foreach ($rs as $cat) {
-            $cat->depth  = 1;
-            $cat->path   = '/'.$cat->id;
-            $cat->parent = 0;
-            $DB->update_record('course_categories', $cat);
-        }
-        $rs->close();
+    $rs = $DB->get_recordset_sql($sql);
+    foreach ($rs as $cat) {
+        $cat->depth  = 1;
+        $cat->path   = '/'.$cat->id;
+        $cat->parent = 0;
+        $DB->update_record('course_categories', $cat);
     }
+    $rs->close();
 
     // now add path and depth to top level categories
     $sql = "UPDATE {course_categories}
@@ -60,14 +59,13 @@ function upgrade_fix_category_depths() {
         $sql = "SELECT c.id, pc.path
                   FROM {course_categories} c, {course_categories} pc
                  WHERE c.parent=pc.id AND c.depth=0 AND pc.depth=?";
-        if ($rs = $DB->get_recordset_sql($sql, array($parentdepth))) {
-            foreach ($rs as $cat) {
-                $cat->depth = $parentdepth+1;
-                $cat->path  = $cat->path.'/'.$cat->id;
-                $DB->update_record('course_categories', $cat);
-            }
-            $rs->close();
+        $rs = $DB->get_recordset_sql($sql, array($parentdepth));
+        foreach ($rs as $cat) {
+            $cat->depth = $parentdepth+1;
+            $cat->path  = $cat->path.'/'.$cat->id;
+            $DB->update_record('course_categories', $cat);
         }
+        $rs->close();
         $parentdepth++;
         if ($parentdepth > 100) {
             //something must have gone wrong - nobody can have more than 100 levels of categories, right?
@@ -246,7 +244,10 @@ function upgrade_migrate_group_icons() {
         upgrade_set_timeout(60); /// Give upgrade at least 60 more seconds
         $pbar->update($i, $count, "Migrated group icons  $i/$count.");
 
-        $context = get_context_instance(CONTEXT_COURSE, $group->courseid);
+        if (!$context = get_context_instance(CONTEXT_COURSE, $group->courseid)) {
+            debugging('Invalid group record (id=' . $group->id . ') found.');
+            continue;
+        }
 
         if ($fs->file_exists($context->id, 'group', 'icon', $group->id, '/', 'f1.jpg')) {
             // already converted!
@@ -378,7 +379,9 @@ function upgrade_migrate_files_blog() {
 
     $count = $DB->count_records_select('post', "module='blog' AND attachment IS NOT NULL AND attachment <> '1'");
 
-    if ($rs = $DB->get_recordset_select('post', "module='blog' AND attachment IS NOT NULL AND attachment <> '1'")) {
+    $rs = $DB->get_recordset_select('post', "module='blog' AND attachment IS NOT NULL AND attachment <> '1'");
+
+    if ($rs->valid()) {
 
         upgrade_set_timeout(60*20); // set up timeout, may also abort execution
 
@@ -419,8 +422,8 @@ function upgrade_migrate_files_blog() {
             $DB->update_record('post', $entry);
             $pbar->update($i, $count, "Migrated blog attachments - $i/$count.");
         }
-        $rs->close();
     }
+    $rs->close();
 
     @rmdir("$CFG->dataroot/blog/attachments/");
     @rmdir("$CFG->dataroot/blog/");
@@ -539,13 +542,12 @@ function upgrade_fix_incorrect_mnethostids() {
 
     $params = array_merge($in_params, array($current_mnet_localhost_host->id));
 
-    if ($rs = $DB->get_recordset_sql($sql, $params)) {
-        foreach ($rs as $rec) {
-            $DB->set_field('user', 'mnethostid', $current_mnet_localhost_host->id, array('id' => $rec->id));
-            upgrade_set_timeout(60); /// Give upgrade at least 60 more seconds
-        }
-        $rs->close();
+    $rs = $DB->get_recordset_sql($sql, $params);
+    foreach ($rs as $rec) {
+        $DB->set_field('user', 'mnethostid', $current_mnet_localhost_host->id, array('id' => $rec->id));
+        upgrade_set_timeout(60); /// Give upgrade at least 60 more seconds
     }
+    $rs->close();
 
     // fix up any host records that have incorrect ids
     $DB->set_field_select('mnet_host', 'applicationid', $moodleapplicationid, 'id = ? or id = ?', array($current_mnet_localhost_host->id, $current_mnet_all_hosts_host->id));
@@ -642,4 +644,4 @@ function update_fix_automated_backup_config() {
 
     unset_config('backup_sche_gradebook_history');
     unset_config('disablescheduleddbackups');
-}
\ No newline at end of file
+}
index 3fa9b29..b21edf1 100644 (file)
@@ -1550,12 +1550,10 @@ abstract class moodle_database {
      * @throws dml_exception if error
      */
     public function record_exists_sql($sql, array $params=null) {
-        if ($mrs = $this->get_recordset_sql($sql, $params, 0, 1)) {
-            $return = $mrs->valid();
-            $mrs->close();
-            return $return;
-        }
-        return false;
+        $mrs = $this->get_recordset_sql($sql, $params, 0, 1);
+        $return = $mrs->valid();
+        $mrs->close();
+        return $return;
     }
 
     /**
index 7da5810..1ab255f 100644 (file)
@@ -968,15 +968,14 @@ class oci_native_moodle_database extends moodle_database {
         $strictness = (int)$strictness;
         if ($strictness == IGNORE_MULTIPLE) {
             // do not limit here - ORA does not like that
-            if (!$rs = $this->get_recordset_sql($sql, $params)) {
-                return false;
-            }
-            foreach ($rs as $result) {
-                $rs->close();
-                return $result;
+            $rs = $this->get_recordset_sql($sql, $params);
+            $result = false;
+            foreach ($rs as $rec) {
+                $result = $rec;
+                break;
             }
             $rs->close();
-            return false;
+            return $result;
         }
         return parent::get_record_sql($sql, $params, $strictness);
     }
index 9af6193..2cc8770 100644 (file)
@@ -287,7 +287,9 @@ abstract class pdo_moodle_database extends moodle_database {
      * @return array of values
      */
     public function get_fieldset_sql($sql, array $params=null) {
-        if(!$rs = $this->get_recordset_sql($sql, $params)) {
+        $rs = $this->get_recordset_sql($sql, $params);
+        if (!$rs->valid()) {
+            $rs->close(); // Not going to iterate (but exit), close rs
             return false;
         }
         $result = array();
@@ -312,7 +314,9 @@ abstract class pdo_moodle_database extends moodle_database {
      * @return array of objects, or empty array if no records were found, or false if an error occurred.
      */
     public function get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) {
-        if(!$rs = $this->get_recordset_sql($sql, $params, $limitfrom, $limitnum)) {
+        $rs = $this->get_recordset_sql($sql, $params, $limitfrom, $limitnum);
+        if (!$rs->valid()) {
+            $rs->close(); // Not going to iterate (but exit), close rs
             return false;
         }
         $objects = array();
index d5f3045..9cc2938 100755 (executable)
@@ -435,25 +435,24 @@ function events_cron($eventname='') {
         $params = array();
     }
 
-    if ($rs = $DB->get_recordset_sql($sql, $params)) {
-        foreach ($rs as $qhandler) {
-            if (isset($failed[$qhandler->handlerid])) {
-                // do not try to dispatch any later events when one already asked for retry or ended with exception
-                continue;
-            }
-            $status = events_process_queued_handler($qhandler);
-            if ($status === false) {
-                // handler is asking for retry, do not send other events to this handler now
-                $failed[$qhandler->handlerid] = $qhandler->handlerid;
-            } else if ($status === NULL) {
-                // means completely broken handler, event data was purged
-                $failed[$qhandler->handlerid] = $qhandler->handlerid;
-            } else {
-                $processed++;
-            }
+    $rs = $DB->get_recordset_sql($sql, $params);
+    foreach ($rs as $qhandler) {
+        if (isset($failed[$qhandler->handlerid])) {
+            // do not try to dispatch any later events when one already asked for retry or ended with exception
+            continue;
+        }
+        $status = events_process_queued_handler($qhandler);
+        if ($status === false) {
+            // handler is asking for retry, do not send other events to this handler now
+            $failed[$qhandler->handlerid] = $qhandler->handlerid;
+        } else if ($status === NULL) {
+            // means completely broken handler, event data was purged
+            $failed[$qhandler->handlerid] = $qhandler->handlerid;
+        } else {
+            $processed++;
         }
-        $rs->close();
     }
+    $rs->close();
 
     // remove events that do not have any handlers waiting
     $sql = "SELECT eq.id
index 05bc057..adaaedc 100644 (file)
@@ -321,7 +321,7 @@ function file_get_unused_draft_itemid() {
  * @return string if $text was passed in, the rewritten $text is returned. Otherwise NULL.
  */
 function file_prepare_draft_area(&$draftitemid, $contextid, $component, $filearea, $itemid, array $options=null, $text=null) {
-    global $CFG, $USER;
+    global $CFG, $USER, $CFG;
 
     $options = (array)$options;
     if (!isset($options['subdirs'])) {
@@ -351,6 +351,12 @@ function file_prepare_draft_area(&$draftitemid, $contextid, $component, $fileare
                 $fs->create_file_from_storedfile($file_record, $file);
             }
         }
+        if (!is_null($text)) {
+            // at this point there should not be any draftfile links yet,
+            // because this is a new text from database that should still contain the @@pluginfile@@ links
+            // this happens when developers forget to post process the text
+            $text = str_replace("\"$CFG->httpswwwroot/draftfile.php", "\"$CFG->httpswwwroot/brokenfile.php#", $text);
+        }
     } else {
         // nothing to do
     }
index 679cac1..383da52 100644 (file)
@@ -1214,6 +1214,7 @@ class file_storage {
         foreach ($rs as $dir) {
             $this->delete_area_files($dir->contextid, $dir->component, $dir->filearea, $dir->itemid);
         }
+        $rs->close();
         mtrace('done.');
 
         // remove trash pool files once a day
@@ -1226,12 +1227,14 @@ class file_storage {
                     FROM {files} f
                     LEFT OUTER JOIN {context} c ON f.contextid = c.id
                     WHERE c.id IS NULL";
-            if ($rs = $DB->get_recordset_sql($sql)) {
+            $rs = $DB->get_recordset_sql($sql);
+            if ($rs->valid()) {
                 $fs = get_file_storage();
                 foreach ($rs as $ctx) {
                     $fs->delete_area_files($ctx->contextid);
                 }
             }
+            $rs->close();
             mtrace('done.');
 
             mtrace('Deleting trash files... ', '');
index 98cbb6c..abe6120 100644 (file)
@@ -481,7 +481,8 @@ class grade_category extends grade_object {
               ORDER BY g.userid";
 
         // group the results by userid and aggregate the grades for this user
-        if ($rs = $DB->get_recordset_sql($sql, $params)) {
+        $rs = $DB->get_recordset_sql($sql, $params);
+        if ($rs->valid()) {
             $prevuser = 0;
             $grade_values = array();
             $excluded     = array();
@@ -506,9 +507,9 @@ class grade_category extends grade_object {
                     $oldgrade = $used;
                 }
             }
-            $rs->close();
             $this->aggregate_grades($prevuser, $items, $grade_values, $oldgrade, $excluded);//the last one
         }
+        $rs->close();
 
         return true;
     }
index 1b710ae..97c4233 100644 (file)
@@ -390,14 +390,13 @@ class grade_grade extends grade_object {
         $now = time(); // no rounding needed, this is not supposed to be called every 10 seconds
         list($usql, $params) = $DB->get_in_or_equal($items);
         $params[] = $now;
-        if ($rs = $DB->get_recordset_select('grade_grades', "itemid $usql AND locked = 0 AND locktime > 0 AND locktime < ?", $params)) {
-            foreach ($rs as $grade) {
-                $grade_grade = new grade_grade($grade, false);
-                $grade_grade->locked = time();
-                $grade_grade->update('locktime');
-            }
-            $rs->close();
+        $rs = $DB->get_recordset_select('grade_grades', "itemid $usql AND locked = 0 AND locktime > 0 AND locktime < ?", $params);
+        foreach ($rs as $grade) {
+            $grade_grade = new grade_grade($grade, false);
+            $grade_grade->locked = time();
+            $grade_grade->update('locktime');
         }
+        $rs->close();
     }
 
     /**
index f4301ec..630e915 100644 (file)
@@ -1722,7 +1722,8 @@ class grade_item extends grade_object {
         $return = true;
 
         // group the grades by userid and use formula on the group
-        if ($rs = $DB->get_recordset_sql($sql, $params)) {
+        $rs = $DB->get_recordset_sql($sql, $params);
+        if ($rs->valid()) {
             $prevuser = 0;
             $grade_records   = array();
             $oldgrade    = null;
@@ -1740,11 +1741,11 @@ class grade_item extends grade_object {
                 }
                 $grade_records['gi'.$used->itemid] = $used->finalgrade;
             }
-            $rs->close();
             if (!$this->use_formula($prevuser, $grade_records, $useditems, $oldgrade)) {
                 $return = false;
             }
         }
+        $rs->close();
 
         return $return;
     }
index c0dad20..1fd916f 100644 (file)
@@ -1206,13 +1206,12 @@ function grade_uninstalled_module($modname) {
              WHERE itemtype='mod' AND itemmodule=?";
 
     // go all items for this module and delete them including the grades
-    if ($rs = $DB->get_recordset_sql($sql, array($modname))) {
-        foreach ($rs as $item) {
-            $grade_item = new grade_item($item, false);
-            $grade_item->delete('moduninstall');
-        }
-        $rs->close();
+    $rs = $DB->get_recordset_sql($sql, array($modname));
+    foreach ($rs as $item) {
+        $grade_item = new grade_item($item, false);
+        $grade_item->delete('moduninstall');
     }
+    $rs->close();
 }
 
 /**
@@ -1260,14 +1259,13 @@ function grade_cron() {
                 SELECT 'x' FROM {grade_items} c WHERE c.itemtype='course' AND c.needsupdate=0 AND c.courseid=i.courseid)";
 
     // go through all courses that have proper final grades and lock them if needed
-    if ($rs = $DB->get_recordset_sql($sql, array($now))) {
-        foreach ($rs as $item) {
-            $grade_item = new grade_item($item, false);
-            $grade_item->locked = $now;
-            $grade_item->update('locktime');
-        }
-        $rs->close();
+    $rs = $DB->get_recordset_sql($sql, array($now));
+    foreach ($rs as $item) {
+        $grade_item = new grade_item($item, false);
+        $grade_item->locked = $now;
+        $grade_item->update('locktime');
     }
+    $rs->close();
 
     $grade_inst = new grade_grade();
     $fields = 'g.'.implode(',g.', $grade_inst->required_fields);
@@ -1278,14 +1276,13 @@ function grade_cron() {
                 SELECT 'x' FROM {grade_items} c WHERE c.itemtype='course' AND c.needsupdate=0 AND c.courseid=i.courseid)";
 
     // go through all courses that have proper final grades and lock them if needed
-    if ($rs = $DB->get_recordset_sql($sql, array($now))) {
-        foreach ($rs as $grade) {
-            $grade_grade = new grade_grade($grade, false);
-            $grade_grade->locked = $now;
-            $grade_grade->update('locktime');
-        }
-        $rs->close();
+    $rs = $DB->get_recordset_sql($sql, array($now));
+    foreach ($rs as $grade) {
+        $grade_grade = new grade_grade($grade, false);
+        $grade_grade->locked = $now;
+        $grade_grade->update('locktime');
     }
+    $rs->close();
 
     //TODO: do not run this cleanup every cron invocation
     // cleanup history tables
index 5eaf108..17cba03 100644 (file)
@@ -199,7 +199,10 @@ function groups_get_user_groups($courseid, $userid=0) {
              WHERE gm.userid = ? AND g.courseid = ?";
     $params = array($userid, $courseid);
 
-    if (!$rs = $DB->get_recordset_sql($sql, $params)) {
+    $rs = $DB->get_recordset_sql($sql, $params);
+
+    if (!$rs->valid()) {
+        $rs->close(); // Not going to iterate (but exit), close rs
         return array('0' => array());
     }
 
index a60ddaf..184ef84 100644 (file)
@@ -1058,7 +1058,7 @@ function close_window(e) {
     } else {
         e.returnValue = false;
     }
-    self.close();
+    window.close();
 }
 
 /**
@@ -1067,7 +1067,7 @@ function close_window(e) {
 function close_window_reloading_opener() {
     if (window.opener) {
         window.opener.location.reload(1);
-        close_window();
+        close_window({});
         // Intentionally, only try to close the window if there is some evidence we are in a popup.
     }
 }
diff --git a/lib/modinfolib.php b/lib/modinfolib.php
new file mode 100644 (file)
index 0000000..0d5bf93
--- /dev/null
@@ -0,0 +1,1092 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * modinfolib.php - Functions/classes relating to cached information about module instances on
+ * a course.
+ * @package    core
+ * @subpackage lib
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @author     sam marshall
+ */
+
+
+// Maximum number of modinfo items to keep in memory cache. Do not increase this to a large
+// number because:
+// a) modinfo can be big (megabyte range) for some courses
+// b) performance of cache will deteriorate if there are very many items in it
+if (!defined('MAX_MODINFO_CACHE_SIZE')) {
+    define('MAX_MODINFO_CACHE_SIZE', 10);
+}
+
+
+/**
+ * Information about a course that is cached in the course table 'modinfo' field (and then in
+ * memory) in order to reduce the need for other database queries.
+ *
+ * This includes information about the course-modules and the sections on the course. It can also
+ * include dynamic data that has been updated for the current user.
+ */
+class course_modinfo extends stdClass {
+    // For convenience we store the course object here as it is needed in other parts of code
+    private $course;
+
+    // Existing data fields
+    ///////////////////////
+
+    // These are public for backward compatibility. Note: it is not possible to retain BC
+    // using PHP magic get methods because behaviour is different with regard to empty().
+
+    /**
+     * Course ID
+     * @var int
+     * @deprecated For new code, use get_course_id instead.
+     */
+    public $courseid;
+
+    /**
+     * User ID
+     * @var int
+     * @deprecated For new code, use get_user_id instead.
+     */
+    public $userid;
+
+    /**
+     * Array from int (section num, e.g. 0) => array of int (course-module id); this list only
+     * includes sections that actually contain at least one course-module
+     * @var array
+     * @deprecated For new code, use get_sections instead
+     */
+    public $sections;
+
+    /**
+     * Array from int (cm id) => cm_info object
+     * @var array
+     * @deprecated For new code, use get_cms or get_cm instead.
+     */
+    public $cms;
+
+    /**
+     * Array from string (modname) => int (instance id) => cm_info object
+     * @var array
+     * @deprecated For new code, use get_instances or get_instances_of instead.
+     */
+    public $instances;
+
+    /**
+     * Groups that the current user belongs to. This value is usually not available (set to null)
+     * unless the course has activities set to groupmembersonly. When set, it is an array of
+     * grouping id => array of group id => group id. Includes grouping id 0 for 'all groups'.
+     * @var array
+     * @deprecated Don't use this! For new code, use get_groups.
+     */
+    public $groups;
+
+    // Get methods for data
+    ///////////////////////
+
+    /**
+     * @return object Moodle course object that was used to construct this data
+     */
+    public function get_course() {
+        return $this->course;
+    }
+
+    /**
+     * @return int Course ID
+     */
+    public function get_course_id() {
+        return $this->courseid;
+    }
+
+    /**
+     * @return int User ID
+     */
+    public function get_user_id() {
+        return $this->userid;
+    }
+
+    /**
+     * @return array Array from section number (e.g. 0) to array of course-module IDs in that
+     *   section; this only includes sections that contain at least one course-module
+     */
+    public function get_sections() {
+        return $this->sections;
+    }
+
+    /**
+     * @return array Array from course-module instance to cm_info object within this course, in
+     *   order of appearance
+     */
+    public function get_cms() {
+        return $this->cms;
+    }
+
+    /**
+     * Obtains a single course-module object (for a course-module that is on this course).
+     * @param int $cmid Course-module ID
+     * @return cm_info Information about that course-module
+     * @throws moodle_exception If the course-module does not exist
+     */
+    public function get_cm($cmid) {
+        if (empty($this->cms[$cmid])) {
+            throw new moodle_exception('invalidcoursemodule', 'error');
+        }
+        return $this->cms[$cmid];
+    }
+
+    /**
+     * Obtains all module instances on this course.
+     * @return array Array from module name => array from instance id => cm_info
+     */
+    public function get_instances() {
+        return $this->instances;
+    }
+
+    /**
+     * Obtains all instances of a particular module on this course.
+     * @param $modname Name of module (not full frankenstyle) e.g. 'label'
+     * @return array Array from instance id => cm_info for modules on this course; empty if none
+     */
+    public function get_instances_of($modname) {
+        if (empty($this->instances[$modname])) {
+            return array();
+        }
+        return $this->instances[$modname];
+    }
+
+    /**
+     * Returns groups that the current user belongs to on the course. Note: If not already
+     * available, this may make a database query.
+     * @param int $groupingid Grouping ID or 0 (default) for all groups
+     * @return array Array of int (group id) => int (same group id again); empty array if none
+     */
+    public function get_groups($groupingid=0) {
+        if (is_null($this->groups)) {
+            // NOTE: Performance could be improved here. The system caches user groups
+            // in $USER->groupmember[$courseid] => array of groupid=>groupid. Unfortunately this
+            // structure does not include grouping information. It probably could be changed to
+            // do so, without a significant performance hit on login, thus saving this one query
+            // each request.
+            $this->groups = groups_get_user_groups($this->courseid, $this->userid);
+        }
+        if (!isset($this->groups[$groupingid])) {
+            return array();
+        }
+        return $this->groups[$groupingid];
+    }
+
+    /**
+     * Constructs based on course.
+     * Note: This constructor should not usually be called directly.
+     * Use get_fast_modinfo($course) instead as this maintains a cache.
+     * @param object $course Moodle course object, which may include modinfo
+     * @param int $userid User ID
+     */
+    public function __construct($course, $userid) {
+        global $CFG, $DB;
+
+        // Set initial values
+        $this->courseid = $course->id;
+        $this->userid = $userid;
+        $this->sections = array();
+        $this->cms = array();
+        $this->instances = array();
+        $this->groups = null;
+        $this->course = $course;
+
+        // Check modinfo field is set. If not, build and load it.
+        if (empty($course->modinfo)) {
+            rebuild_course_cache($course->id);
+            $course->modinfo = $DB->get_field('course', 'modinfo', array('id'=>$course->id));
+        }
+
+        // Load modinfo field into memory as PHP object and check it's valid
+        $info = unserialize($course->modinfo);
+        if (!is_array($info)) {
+            // hmm, something is wrong - lets try to fix it
+            rebuild_course_cache($course->id);
+            $course->modinfo = $DB->get_field('course', 'modinfo', array('id'=>$course->id));
+            $info = unserialize($course->modinfo);
+            if (!is_array($info)) {
+                // If it still fails, abort
+                debugging('Problem with "modinfo" data for this course');
+                return;
+            }
+        }
+
+        // If we haven't already preloaded contexts for the course, do it now
+        preload_course_contexts($course->id);
+
+        // Loop through each piece of module data, constructing it
+        $modexists = array();
+        foreach ($info as $mod) {
+            if (empty($mod->name)) {
+                // something is wrong here
+                continue;
+            }
+
+            // Skip modules which don't exist
+            if (empty($modexists[$mod->mod])) {
+                if (!file_exists("$CFG->dirroot/mod/$mod->mod/lib.php")) {
+                    continue;
+                }
+                $modexists[$mod->mod] = true;
+            }
+
+            // Construct info for this module
+            $cm = new cm_info($this, $course, $mod, $info);
+
+            // Store module in instances and cms array
+            if (!isset($this->instances[$cm->modname])) {
+                $this->instances[$cm->modname] = array();
+            }
+            $this->instances[$cm->modname][$cm->instance] = $cm;
+            $this->cms[$cm->id] = $cm;
+
+            // Reconstruct sections. This works because modules are stored in order
+            if (!isset($this->sections[$cm->sectionnum])) {
+                $this->sections[$cm->sectionnum] = array();
+            }
+            $this->sections[$cm->sectionnum][] = $cm->id;
+        }
+
+        // We need at least 'dynamic' data from each course-module (this is basically the remaining
+        // data which was always present in previous version of get_fast_modinfo, so it's required
+        // for BC). Creating it in a second pass is necessary because obtain_dynamic_data sometimes
+        // needs to be able to refer to a 'complete' (with basic data) modinfo.
+        foreach ($this->cms as $cm) {
+            $cm->obtain_dynamic_data();
+        }
+    }
+}
+
+
+/**
+ * Data about a single module on a course. This contains most of the fields in the course_modules
+ * table, plus additional data when required.
+ *
+ * This object has many public fields; code should treat all these fields as read-only and set
+ * data only using the supplied set functions. Setting the fields directly is not supported
+ * and may cause problems later.
+ */
+class cm_info extends stdClass  {
+    /**
+     * State: Only basic data from modinfo cache is available.
+     */
+    const STATE_BASIC = 0;
+
+    /**
+     * State: Dynamic data is available too.
+     */
+    const STATE_DYNAMIC = 1;
+
+    /**
+     * State: View data (for course page) is available.
+     */
+    const STATE_VIEW = 2;
+
+    /**
+     * Parent object
+     * @var course_modinfo
+     */
+    private $modinfo;
+
+    /**
+     * Level of information stored inside this object (STATE_xx constant)
+     * @var int
+     */
+    private $state;
+
+    // Existing data fields
+    ///////////////////////
+
+    /**
+     * Course-module ID - from course_modules table
+     * @var int
+     */
+    public $id;
+
+    /**
+     * Module instance (ID within module table) - from course_modules table
+     * @var int
+     */
+    public $instance;
+
+    /**
+     * Course ID - from course_modules table
+     * @var int
+     */
+    public $course;
+
+    /**
+     * 'ID number' from course-modules table (arbitrary text set by user) - from
+     * course_modules table
+     * @var string
+     */
+    public $idnumber;
+
+    /**
+     * Visible setting (0 or 1; if this is 0, students cannot see/access the activity)  - from
+     * course_modules table
+     * @var int
+     */
+    public $visible;
+
+    /**
+     * Group mode (one of the constants NONE, SEPARATEGROUPS, or VISIBLEGROUPS) - from
+     * course_modules table
+     * @var int
+     */
+    public $groupmode;
+
+    /**
+     * Grouping ID (0 = all groupings)
+     * @var int
+     */
+    public $groupingid;
+
+    /**
+     * Group members only (if set to 1, only members of a suitable group see this link on the
+     * course page; 0 = everyone sees it even if they don't belong to a suitable group)  - from
+     * course_modules table
+     * @var int
+     */
+    public $groupmembersonly;
+
+    /**
+     * Indent level on course page (0 = no indent) - from course_modules table
+     * @var int
+     */
+    public $indent;
+
+    /**
+     * Activity completion setting for this activity, COMPLETION_TRACKING_xx constant - from
+     * course_modules table
+     * @var int
+     */
+    public $completion;
+
+    /**
+     * Available date for this activity (0 if not set, or set to seconds since epoch; before this
+     * date, activity does not display to students) - from course_modules table
+     * @var int
+     */
+    public $availablefrom;
+
+    /**
+     * Available until date for this activity (0 if not set, or set to seconds since epoch; from
+     * this date, activity does not display to students) - from course_modules table
+     * @var int
+     */
+    public $availableuntil;
+
+    /**
+     * When activity is unavailable, this field controls whether it is shown to students (0 =
+     * hide completely, 1 = show greyed out with information about when it will be available) -
+     * from course_modules table
+     * @var int
+     */
+    public $showavailability;
+
+    /**
+     * Extra HTML that is put in an unhelpful part of the HTML when displaying this module in
+     * course page - from cached data in modinfo field
+     * @deprecated This is crazy, don't use it. Replaced by ->extraclasses and ->onclick
+     * @var string
+     */
+    public $extra;
+
+    /**
+     * Name of icon to use - from cached data in modinfo field
+     * @var string
+     */
+    public $icon;
+
+    /**
+     * Component that contains icon - from cached data in modinfo field
+     * @var string
+     */
+    public $iconcomponent;
+
+    /**
+     * Name of module e.g. 'forum' (this is the same name as the module's main database
+     * table) - from cached data in modinfo field
+     * @var string
+     */
+    public $modname;
+
+    /**
+     * Name of module instance for display on page e.g. 'General discussion forum' - from cached
+     * data in modinfo field
+     * @var string
+     */
+    public $name;
+
+    /**
+     * Section number that this course-module is in (section 0 = above the calendar, section 1
+     * = week/topic 1, etc) - from cached data in modinfo field
+     * @var string
+     */
+    public $sectionnum;
+
+    /**
+     * Availability conditions for this course-module based on the completion of other
+     * course-modules (array from other course-module id to required completion state for that
+     * module) - from cached data in modinfo field
+     * @var array
+     */
+    public $conditionscompletion;
+
+    /**
+     * Availability conditions for this course-module based on course grades (array from
+     * grade item id to object with ->min, ->max fields) - from cached data in modinfo field
+     * @var array
+     */
+    public $conditionsgrade;
+
+    /**
+     * Plural name of module type, e.g. 'Forums' - from lang file
+     * @deprecated Do not use this value (you can obtain it by calling get_string instead); it
+     *   will be removed in a future version (see later TODO in this file)
+     * @var string
+     */
+    public $modplural;
+
+    /**
+     * True if this course-module is available to students i.e. if all availability conditions
+     * are met - obtained dynamically
+     * @var bool
+     */
+    public $available;
+
+    /**
+     * If course-module is not available to students, this string gives information about
+     * availability which can be displayed to students and/or staff (e.g. 'Available from 3
+     * January 2010') for display on main page - obtained dynamically
+     * @var string
+     */
+    public $availableinfo;
+
+    /**
+     * True if this course-module is available to the CURRENT user (for example, if current user
+     * has viewhiddenactivities capability, they can access the course-module even if it is not
+     * visible or not available, so this would be true in that case)
+     * @var bool
+     */
+    public $uservisible;
+
+    // New data available only via functions
+    ////////////////////////////////////////
+
+    /**
+     * @var moodle_url
+     */
+    private $url;
+
+    /**
+     * @var string
+     */
+    private $content;
+
+    /**
+     * @var string
+     */
+    private $extraclasses;
+
+    /**
+     * @var string
+     */
+    private $onclick;
+
+    /**
+     * @var mixed
+     */
+    private $customdata;
+
+    /**
+     * @var string
+     */
+    private $afterlink;
+
+    /**
+     * @var string
+     */
+    private $afterediticons;
+
+    /**
+     * @return bool True if this module has a 'view' page that should be linked to in navigation
+     *   etc (note: modules may still have a view.php file, but return false if this is not
+     *   intended to be linked to from 'normal' parts of the interface; this is what label does).
+     */
+    public function has_view() {
+        return !is_null($this->url);
+    }
+
+    /**
+     * @return moodle_url URL to link to for this module, or null if it doesn't have a view page
+     */
+    public function get_url() {
+        return $this->url;
+    }
+
+    /**
+     * Obtains content to display on main (view) page.
+     * Note: Will collect view data, if not already obtained.
+     * @return string Content to display on main page below link, or empty string if none
+     */
+    public function get_content() {
+        $this->obtain_view_data();
+        return $this->content;
+    }
+
+    /**
+     * Note: Will collect view data, if not already obtained.
+     * @return string Extra CSS classes to add to html output for this activity on main page
+     */
+    public function get_extra_classes() {
+        $this->obtain_view_data();
+        return $this->extraclasses;
+    }
+
+    /**
+     * @return string Content of HTML on-click attribute. This string will be used literally
+     * as a string so should be pre-escaped.
+     */
+    public function get_on_click() {
+        // Does not need view data; may be used by navigation
+        return $this->onclick;
+    }
+    /**
+     * @return mixed Optional custom data stored in modinfo cache for this activity, or null if none
+     */
+    public function get_custom_data() {
+        return $this->customdata;
+    }
+
+    /**
+     * Note: Will collect view data, if not already obtained.
+                * @return string Extra HTML code to display after link
+     */
+    public function get_after_link() {
+        $this->obtain_view_data();
+        return $this->afterlink;
+    }
+
+    /**
+     * Note: Will collect view data, if not already obtained.
+     * @return string Extra HTML code to display after editing icons (e.g. more icons)
+     */
+    public function get_after_edit_icons() {
+        $this->obtain_view_data();
+        return $this->afterediticons;
+    }
+
+    /**
+     * @param moodle_core_renderer $output Output render to use, or null for default (global)
+     * @return moodle_url Icon URL for a suitable icon to put beside this cm
+     */
+    public function get_icon_url($output = null) {
+        global $OUTPUT;
+        if (!$output) {
+            $output = $OUTPUT;
+        }
+        if (!empty($this->icon)) {
+            if (substr($this->icon, 0, 4) === 'mod/') {
+                list($modname, $iconname) = explode('/', substr($this->icon, 4), 2);
+                $icon = $output->pix_url($iconname, $modname);
+            } else {
+                if (!empty($this->iconcomponent)) {
+                    // Icon  has specified component
+                    $icon = $output->pix_url($this->icon, $this->iconcomponent);
+                } else {
+                    // Icon does not have specified component, use default
+                    $icon = $output->pix_url($this->icon);
+                }
+            }
+        } else {
+            $icon = $output->pix_url('icon', $this->modname);
+        }
+        return $icon;
+    }
+
+    /**
+     * @return course_modinfo Modinfo object that this came from
+     */
+    public function get_modinfo() {
+        return $this->modinfo;
+    }
+
+    /**
+     * @return object Moodle course object that was used to construct this data
+     */
+    public function get_course() {
+        return $this->modinfo->get_course();
+    }
+
+    // Set functions
+    ////////////////
+
+    /**
+     * Sets content to display on course view page below link (if present).
+     * @param string $content New content as HTML string (empty string if none)
+     * @return void
+     */
+    public function set_content($content) {
+        $this->content = $content;
+    }
+
+    /**
+     * Sets extra classes to include in CSS.
+     * @param string $extraclasses Extra classes (empty string if none)
+     * @return void
+     */
+    public function set_extra_classes($extraclasses) {
+        $this->extraclasses = $extraclasses;
+    }
+
+    /**
+     * Sets value of on-click attribute for JavaScript.
+     * Note: May not be called from _cm_info_view (only _cm_info_dynamic).
+     * @param string $onclick New onclick attribute which should be HTML-escaped
+     *   (empty string if none)
+     * @return void
+     */
+    public function set_on_click($onclick) {
+        $this->check_not_view_only();
+        $this->onclick = $onclick;
+    }
+
+    /**
+     * Sets HTML that displays after link on course view page.
+     * @param string $afterlink HTML string (empty string if none)
+     * @return void
+     */
+    public function set_after_link($afterlink) {
+        $this->afterlink = $afterlink;
+    }
+
+    /**
+     * Sets HTML that displays after edit icons on course view page.
+     * @param string $afterediticons HTML string (empty string if none)
+     * @return void
+     */
+    public function set_after_edit_icons($afterediticons) {
+        $this->afterediticons = $afterediticons;
+    }
+
+    /**
+     * Changes the name (text of link) for this module instance.
+     * Note: May not be called from _cm_info_view (only _cm_info_dynamic).
+     * @param string $name Name of activity / link text
+     * @return void
+     */
+    public function set_name($name) {
+        $this->update_user_visible();
+        $this->name = $name;
+    }
+
+    /**
+     * Turns off the view link for this module instance.
+     * Note: May not be called from _cm_info_view (only _cm_info_dynamic).
+     * @return void
+     */
+    public function set_no_view_link() {
+        $this->check_not_view_only();
+        $url = null;
+    }
+
+    /**
+     * Sets the 'uservisible' flag. This can be used (by setting false) to prevent access and
+     * display of this module link for the current user.
+     * Note: May not be called from _cm_info_view (only _cm_info_dynamic).
+     * @param bool $uservisible
+     * @return void
+     */
+    public function set_user_visible($uservisible) {
+        $this->check_not_view_only();
+        $this->uservisible = $uservisible;
+    }
+
+    /**
+     * Sets the 'available' flag and related details. This flag is normally used to make
+     * course modules unavailable until a certain date or condition is met. (When a course
+     * module is unavailable, it is still visible to users who have viewhiddenactivities
+     * permission.)
+     *
+     * When this is function is called, user-visible status is recalculated automatically.
+     *
+     * Note: May not be called from _cm_info_view (only _cm_info_dynamic).
+     * @param bool $available False if this item is not 'available'
+     * @param int $showavailability 0 = do not show this item at all if it's not available,
+     *   1 = show this item greyed out with the following message
+     * @param string $availableinfo Information about why this is not available which displays
+     *   to those who have viewhiddenactivities, and to everyone if showavailability is set;
+     *   note that this function replaces the existing data (if any)
+     * @return void
+     */
+    public function set_available($available, $showavailability=0, $availableinfo='') {
+        $this->check_not_view_only();
+        $this->available = $available;
+        $this->showavailability = $showavailability;
+        $this->availableinfo = $availableinfo;
+        $this->update_user_visible();
+    }
+
+    /**
+     * Some set functions can only be called from _cm_info_dynamic and not _cm_info_view.
+     * This is because they may affect parts of this object which are used on pages other
+     * than the view page (e.g. in the navigation block, or when checking access on
+     * module pages).
+     * @return void
+     */
+    private function check_not_view_only() {
+        if ($this->state >= self::STATE_DYNAMIC) {
+            throw new coding_exception('Cannot set this data from _cm_info_view because it may ' .
+                    'affect other pages as well as view');
+        }
+    }
+
+    /**
+     * Constructor should not be called directly; use get_fast_modinfo.
+     * @param course_modinfo $modinfo Parent object
+     * @param object $course Course row
+     * @param object $mod Module object from the modinfo field of course table
+     * @param object $info Entire object from modinfo field of course table
+     */
+    public function __construct(course_modinfo $modinfo, $course, $mod, $info) {
+        global $CFG;
+        $this->modinfo = $modinfo;
+
+        $this->id               = $mod->cm;
+        $this->instance         = $mod->id;
+        $this->course           = $course->id;
+        $this->modname          = $mod->mod;
+        $this->idnumber         = isset($mod->idnumber) ? $mod->idnumber : '';
+        $this->name             = $mod->name;
+        $this->visible          = $mod->visible;
+        $this->sectionnum       = $mod->section;
+        $this->groupmode        = isset($mod->groupmode) ? $mod->groupmode : 0;
+        $this->groupingid       = isset($mod->groupingid) ? $mod->groupingid : 0;
+        $this->groupmembersonly = isset($mod->groupmembersonly) ? $mod->groupmembersonly : 0;
+        $this->indent           = isset($mod->indent) ? $mod->indent : 0;
+        $this->completion       = isset($mod->completion) ? $mod->completion : 0;
+        $this->extra            = isset($mod->extra) ? $mod->extra : '';
+        $this->extraclasses     = isset($mod->extraclasses) ? $mod->extraclasses : '';
+        $this->onclick          = isset($mod->onclick) ? $mod->onclick : '';
+        $this->content          = isset($mod->content) ? $mod->content : '';
+        $this->icon             = isset($mod->icon) ? $mod->icon : '';
+        $this->iconcomponent    = isset($mod->iconcomponent) ? $mod->iconcomponent : '';
+        $this->customdata       = isset($mod->customdata) ? $mod->customdata : '';
+        $this->state = self::STATE_BASIC;
+
+        // This special case handles old label data. Labels used to use the 'name' field for
+        // content
+        if ($this->modname === 'label' && $this->content === '') {
+            $this->content = $this->extra;
+            $this->extra = '';
+        }
+
+        if (!empty($CFG->enableavailability)) {
+            // We must have completion information from modinfo. If it's not
+            // there, cache needs rebuilding
+            if (!isset($mod->showavailability)) {
+                throw new modinfo_rebuild_cache_exception(
+                        'enableavailability option was changed; rebuilding '.
+                        'cache for course ' . $course->id);
+            }
+            $this->showavailability = $mod->showavailability;
+            $this->availablefrom = isset($mod->availablefrom) ? $mod->availablefrom : 0;
+            $this->availableuntil = isset($mod->availableuntil) ? $mod->availableuntil : 0;
+            $this->conditionscompletion = isset($mod->conditionscompletion)
+                    ? $mod->conditionscompletion : array();
+            $this->conditionsgrade = isset($mod->conditionsgrade)
+                    ? $mod->conditionsgrade : array();
+        }
+
+        // Get module plural name.
+        // TODO This was a very old performance hack and should now be removed as the information
+        // certainly doesn't belong in modinfo. On a 'normal' page this is only used in the
+        // activity_modules block, so if it needs caching, it should be cached there.
+        static $modplurals;
+        if (!isset($modplurals[$this->modname])) {
+            $modplurals[$this->modname] = get_string('modulenameplural', $this->modname);
+        }
+        $this->modplural = $modplurals[$this->modname];
+
+        static $modviews;
+        if (!isset($modviews[$this->modname])) {
+            $modviews[$this->modname] = !plugin_supports('mod', $this->modname,
+                    FEATURE_NO_VIEW_LINK);
+        }
+        $this->url = $modviews[$this->modname]
+                ? new moodle_url('/mod/' . $this->modname . '/view.php', array('id'=>$this->id))
+                : null;
+    }
+
+    /**
+     * If dynamic data for this course-module is not yet available, gets it.
+     *
+     * This function is automatically called when constructing course_modinfo, so users don't
+     * need to call it.
+     *
+     * Dynamic data is data which does not come directly from the cache but is calculated at
+     * runtime based on the current user. Primarily this concerns whether the user can access
+     * the module or not.
+     *
+     * As part of this function, the module's _cm_info_dynamic function from its lib.php will
+     * be called (if it exists).
+     * @return void
+     */
+    public function obtain_dynamic_data() {
+        global $CFG;
+        if ($this->state >= self::STATE_DYNAMIC) {
+            return;
+        }
+        $userid = $this->modinfo->get_user_id();
+
+        if (!empty($CFG->enableavailability)) {
+            // Get availability information
+            $ci = new condition_info($this);
+            // Note that the modinfo currently available only includes minimal details (basic data)
+            // so passing it to this function is a bit dangerous as it would cause infinite
+            // recursion if it tried to get dynamic data, however we know that this function only
+            // uses basic data.
+            $this->available = $ci->is_available($this->availableinfo, true,
+                    $userid, $this->modinfo);
+        } else {
+            $this->available = true;
+        }
+
+        // Update visible state for current user
+        $this->update_user_visible();
+
+        // Let module make dynamic changes at this point
+        $this->call_mod_function('cm_info_dynamic');
+        $this->state = self::STATE_DYNAMIC;
+    }
+
+    /**
+     * Works out whether activity is visible *for current user* - if this is false, they
+     * aren't allowed to access it.
+     * @return void
+     */
+    private function update_user_visible() {
+        global $CFG;
+        $modcontext = get_context_instance(CONTEXT_MODULE, $this->id);
+        $userid = $this->modinfo->get_user_id();
+        $this->uservisible = true;
+        if ((!$this->visible or !$this->available) and
+                !has_capability('moodle/course:viewhiddenactivities', $modcontext, $userid)) {
+            // If the activity is hidden or unavailable, and you don't have viewhiddenactivities,
+            // set it so that user can't see or access it
+            $this->uservisible = false;
+        } else if (!empty($CFG->enablegroupmembersonly) and !empty($this->groupmembersonly)
+                and !has_capability('moodle/site:accessallgroups', $modcontext, $userid)) {
+            // If the activity has 'group members only' and you don't have accessallgroups...
+            $groups = $this->modinfo->get_groups();
+            if (empty($this->groups[$this->groupingid])) {
+                // ...and you don't belong to a group, then set it so you can't see/access it
+                $this->uservisible = false;
+            }
+        }
+    }
+
+    /**
+     * Calls a module function (if exists), passing in one parameter: this object.
+     * @param string $type Name of function e.g. if this is 'grooblezorb' and the modname is
+     *   'forum' then it will try to call 'mod_forum_grooblezorb' or 'forum_grooblezorb'
+     * @return void
+     */
+    private function call_mod_function($type) {
+        global $CFG;
+        $libfile = $CFG->dirroot . '/mod/' . $this->modname . '/lib.php';
+        if (file_exists($libfile)) {
+            include_once($libfile);
+            $function = 'mod_' . $this->modname . '_' . $type;
+            if (function_exists($function)) {
+                $function($this);
+            } else {
+                $function = $this->modname . '_' . $type;
+                if (function_exists($function)) {
+                    $function($this);
+                }
+            }
+        }
+    }
+
+    /**
+     * If view data for this course-module is not yet available, obtains it.
+     *
+     * This function is automatically called if any of the functions (marked) which require
+     * view data are called.
+     *
+     * View data is data which is needed only for displaying the course main page (& any similar
+     * functionality on other pages) but is not needed in general. Obtaining view data may have
+     * a performance cost.
+     *
+     * As part of this function, the module's _cm_info_view function from its lib.php will
+     * be called (if it exists).
+     * @return void
+     */
+    private function obtain_view_data() {
+        if ($this->state >= self::STATE_VIEW) {
+            return;
+        }
+
+        // Let module make changes at this point
+        $this->call_mod_function('cm_info_view');
+        $this->state = self::STATE_VIEW;
+    }
+}
+
+
+/**
+ * Special exception that may only be thrown within the constructor for course_modinfo to
+ * indicate that the cache needs to be rebuilt. Not for use anywhere else.
+ */
+class modinfo_rebuild_cache_exception extends coding_exception {
+    function __construct($why) {
+        // If it ever escapes, that's a code bug
+        parent::__construct('This exception should be caught by code', $why);
+    }
+}
+
+
+/**
+ * Returns reference to full info about modules in course (including visibility).
+ * Cached and as fast as possible (0 or 1 db query).
+ *
+ * @global object
+ * @global object
+ * @global moodle_database
+ * @uses MAX_MODINFO_CACHE_SIZE
+ * @param mixed $course object or 'reset' string to reset caches, modinfo may be updated in db
+ * @param int $userid Defaults to current user id
+ * @return course_modinfo Module information for course, or null if resetting
+ */
+function get_fast_modinfo(&$course, $userid=0) {
+    global $CFG, $USER, $DB;
+    require_once($CFG->dirroot.'/course/lib.php');
+
+    if (!empty($CFG->enableavailability)) {
+        require_once($CFG->libdir.'/conditionlib.php');
+    }
+
+    static $cache = array();
+
+    if ($course === 'reset') {
+        $cache = array();
+        return null;
+    }
+
+    if (empty($userid)) {
+        $userid = $USER->id;
+    }
+
+    if (array_key_exists($course->id, $cache) and $cache[$course->id]->userid == $userid) {
+        return $cache[$course->id];
+    }
+
+    if (!property_exists($course, 'modinfo')) {
+        debugging('Coding problem - missing course modinfo property in get_fast_modinfo() call');
+    }
+
+    unset($cache[$course->id]); // prevent potential reference problems when switching users
+
+    try {
+        $cache[$course->id] = new course_modinfo($course, $userid);
+    } catch (modinfo_rebuild_cache_exception $e) {
+        debugging($e->debuginfo);
+        rebuild_course_cache($course->id, true);
+        $course = $DB->get_record('course', array('id' => $course->id), '*', MUST_EXIST);
+        // This second time we don't catch the exception - if you request cache rebuild twice
+        // in a row, that's a bug => coding_exception
+        $cache[$course->id] = new course_modinfo($course, $userid);
+    }
+
+    // Ensure cache does not use too much RAM
+    if (count($cache) > MAX_MODINFO_CACHE_SIZE) {
+        reset($cache);
+        $key = key($cache);
+        unset($cache[$key]);
+    }
+
+    return $cache[$course->id];
+}
+
+
+/**
+ * Class that is the return value for the _get_coursemodule_info module API function.
+ *
+ * Note: For backward compatibility, you can also return a stdclass object from that function.
+ * The difference is that the stdclass object may contain an 'extra' field (deprecated because
+ * it was crazy, except for label which uses it differently). The stdclass object may not contain
+ * the new fields defined here (content, extraclasses, customdata).
+ */
+class cached_cm_info {
+    /**
+     * Name (text of link) for this activity; Leave unset to accept default name
+     * @var string
+     */
+    public $name;
+
+    /**
+     * Name of icon for this activity. Normally, this should be used together with $iconcomponent
+     * to define the icon, as per pix_url function.
+     * For backward compatibility, if this value is of the form 'mod/forum/icon' then an icon
+     * within that module will be used.
+     * @see cm_info::get_icon_url()
+     * @see renderer_base::pix_url()
+     * @var string
+     */
+    public $icon;
+
+    /**
+     * Component for icon for this activity, as per pix_url; leave blank to use default 'moodle'
+     * component
+     * @see renderer_base::pix_url()
+     * @var string
+     */
+    public $iconcomponent;
+
+    /**
+     * HTML content to be displayed on the main page below the link (if any) for this course-module
+     * @var string
+     */
+    public $content;
+
+    /**
+     * Custom data to be stored in modinfo for this activity; useful if there are cases when
+     * internal information for this activity type needs to be accessible from elsewhere on the
+     * course without making database queries. May be of any type but should be short.
+     * @var mixed
+     */
+    public $customdata;
+
+    /**
+     * Extra CSS class or classes to be added when this activity is displayed on the main page;
+     * space-separated string
+     * @var string
+     */
+    public $extraclasses;
+
+    /**
+     * Content of onclick JavaScript; escaped HTML to be inserted as attribute value
+     * @var string
+     */
+    public $onclick;
+}
\ No newline at end of file
index dd9bbef..c59449a 100644 (file)
@@ -352,6 +352,8 @@ define('FEATURE_COMPLETION_TRACKS_VIEWS', 'completion_tracks_views');
 /** True if module has custom completion rules */
 define('FEATURE_COMPLETION_HAS_RULES', 'completion_has_rules');
 
+/** True if module has no 'view' page (like label) */
+define('FEATURE_NO_VIEW_LINK', 'viewlink');
 /** True if module supports outcomes */
 define('FEATURE_IDNUMBER', 'idnumber');
 /** True if module supports groups */
@@ -2312,6 +2314,14 @@ function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $
             if ($cm->course != $course->id) {
                 throw new coding_exception('course and cm parameters in require_login() call do not match!!');
             }
+            // make sure we have a $cm from get_fast_modinfo as this contains activity access details
+            if (!($cm instanceof cm_info)) {
+                // note: nearly all pages call get_fast_modinfo anyway and it does not make any
+                // db queries so this is not really a performance concern, however it is obviously
+                // better if you use get_fast_modinfo to get the cm before calling this.
+                $modinfo = get_fast_modinfo($course);
+                $cm = $modinfo->get_cm($cm->id);
+            }
             $PAGE->set_cm($cm, $course); // set's up global $COURSE
             $PAGE->set_pagelayout('incourse');
         } else {
@@ -2583,47 +2593,15 @@ function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $
         }
     }
 
-    // test visibility
-    if ($cm && !$cm->visible && !has_capability('moodle/course:viewhiddenactivities', $cmcontext)) {
+    // Check visibility of activity to current user; includes visible flag, groupmembersonly,
+    // conditional availability, etc
+    if ($cm && !$cm->uservisible) {
         if ($preventredirect) {
             throw new require_login_exception('Activity is hidden');
         }
         redirect($CFG->wwwroot, get_string('activityiscurrentlyhidden'));
     }
 
-    // groupmembersonly access control
-    if (!empty($CFG->enablegroupmembersonly) and $cm and $cm->groupmembersonly and !has_capability('moodle/site:accessallgroups', get_context_instance(CONTEXT_MODULE, $cm->id))) {
-        if (isguestuser() or !groups_has_membership($cm)) {
-            if ($preventredirect) {
-                throw new require_login_exception('Not member of a group');
-            }
-            print_error('groupmembersonlyerror', 'group', $CFG->wwwroot.'/course/view.php?id='.$cm->course);
-        }
-    }
-
-    // Conditional activity access control
-    if (!empty($CFG->enableavailability) and $cm) {
-        // TODO: this is going to work with login-as-user, sorry!
-        // We cache conditional access in session
-        if (!isset($SESSION->conditionaccessok)) {
-            $SESSION->conditionaccessok = array();
-        }
-        // If you have been allowed into the module once then you are allowed
-        // in for rest of session, no need to do conditional checks
-        if (!array_key_exists($cm->id, $SESSION->conditionaccessok)) {
-            // Get condition info (does a query for the availability table)
-            require_once($CFG->libdir.'/conditionlib.php');
-            $ci = new condition_info($cm, CONDITION_MISSING_EXTRATABLE);
-            // Check condition for user (this will do a query if the availability
-            // information depends on grade or completion information)
-            if ($ci->is_available($junk) || has_capability('moodle/course:viewhiddenactivities', $cmcontext)) {
-                $SESSION->conditionaccessok[$cm->id] = true;
-            } else {
-                print_error('activityiscurrentlyhidden');
-            }
-        }
-    }
-
     // Finally access granted, update lastaccess times
     user_accesstime_log($course->id);
 }
@@ -2674,16 +2652,29 @@ function require_logout() {
  */
 function require_course_login($courseorid, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false) {
     global $CFG, $PAGE, $SITE;
+    $issite = (is_object($courseorid) and $courseorid->id == SITEID)
+          or (!is_object($courseorid) and $courseorid == SITEID);
+    if ($issite && !empty($cm) && !($cm instanceof cm_info)) {
+        // note: nearly all pages call get_fast_modinfo anyway and it does not make any
+        // db queries so this is not really a performance concern, however it is obviously
+        // better if you use get_fast_modinfo to get the cm before calling this.
+        if (is_object($courseorid)) {
+            $course = $courseorid;
+        } else {
+            $course = clone($SITE);
+        }
+        $modinfo = get_fast_modinfo($course);
+        $cm = $modinfo->get_cm($cm->id);
+    }
     if (!empty($CFG->forcelogin)) {
         // login required for both SITE and courses
         require_login($courseorid, $autologinguest, $cm, $setwantsurltome, $preventredirect);
 
-    } else if (!empty($cm) and !$cm->visible) {
+    } else if ($issite && !empty($cm) and !$cm->uservisible) {
         // always login for hidden activities
         require_login($courseorid, $autologinguest, $cm, $setwantsurltome, $preventredirect);
 
-    } else if ((is_object($courseorid) and $courseorid->id == SITEID)
-          or (!is_object($courseorid) and $courseorid == SITEID)) {
+    } else if ($issite) {
               //login for SITE not required
         if ($cm and empty($cm->visible)) {
             // hidden activities are not accessible without login
@@ -3006,207 +2997,6 @@ function reset_login_count() {
     $SESSION->logincount = 0;
 }
 
-/**
- * Returns reference to full info about modules in course (including visibility).
- * Cached and as fast as possible (0 or 1 db query).
- *
- * @global object
- * @global object
- * @global object
- * @uses CONTEXT_MODULE
- * @uses MAX_MODINFO_CACHE_SIZE
- * @param mixed $course object or 'reset' string to reset caches, modinfo may be updated in db
- * @param int $userid Defaults to current user id
- * @return mixed courseinfo object or nothing if resetting
- */
-function &get_fast_modinfo(&$course, $userid=0) {
-    global $CFG, $USER, $DB;
-    require_once($CFG->dirroot.'/course/lib.php');
-
-    if (!empty($CFG->enableavailability)) {
-        require_once($CFG->libdir.'/conditionlib.php');
-    }
-
-    static $cache = array();
-
-    if ($course === 'reset') {
-        $cache = array();
-        $nothing = null;
-        return $nothing; // we must return some reference
-    }
-
-    if (empty($userid)) {
-        $userid = $USER->id;
-    }
-
-    if (array_key_exists($course->id, $cache) and $cache[$course->id]->userid == $userid) {
-        return $cache[$course->id];
-    }
-
-    if (!property_exists($course, 'modinfo')) {
-        debugging('Coding problem - missing course modinfo property in get_fast_modinfo() call');
-    }
-
-    if (empty($course->modinfo)) {
-        // no modinfo yet - load it
-        rebuild_course_cache($course->id);
-        $course->modinfo = $DB->get_field('course', 'modinfo', array('id'=>$course->id));
-    }
-
-    $modinfo = new stdClass();
-    $modinfo->courseid  = $course->id;
-    $modinfo->userid    = $userid;
-    $modinfo->sections  = array();
-    $modinfo->cms       = array();
-    $modinfo->instances = array();
-    $modinfo->groups    = null; // loaded only when really needed - the only one db query
-
-    $info = unserialize($course->modinfo);
-    if (!is_array($info)) {
-        // hmm, something is wrong - lets try to fix it
-        rebuild_course_cache($course->id);
-        $course->modinfo = $DB->get_field('course', 'modinfo', array('id'=>$course->id));
-        $info = unserialize($course->modinfo);
-        if (!is_array($info)) {
-            return $modinfo;
-        }
-    }
-
-    if ($info) {
-        // detect if upgrade required
-        $first = reset($info);
-        if (!isset($first->id)) {
-            rebuild_course_cache($course->id);
-            $course->modinfo = $DB->get_field('course', 'modinfo', array('id'=>$course->id));
-            $info = unserialize($course->modinfo);
-            if (!is_array($info)) {
-                return $modinfo;
-            }
-        }
-    }
-
-    $modlurals = array();
-
-    // If we haven't already preloaded contexts for the course, do it now
-    preload_course_contexts($course->id);
-
-    foreach ($info as $mod) {
-        if (empty($mod->name)) {
-            // something is wrong here
-            continue;
-        }
-        // reconstruct minimalistic $cm
-        $cm = new stdClass();
-        $cm->id               = $mod->cm;
-        $cm->instance         = $mod->id;
-        $cm->course           = $course->id;
-        $cm->modname          = $mod->mod;
-        $cm->idnumber         = $mod->idnumber;
-        $cm->name             = $mod->name;
-        $cm->visible          = $mod->visible;
-        $cm->sectionnum       = $mod->section;
-        $cm->groupmode        = $mod->groupmode;
-        $cm->groupingid       = $mod->groupingid;
-        $cm->groupmembersonly = $mod->groupmembersonly;
-        $cm->indent           = $mod->indent;
-        $cm->completion       = $mod->completion;
-        $cm->extra            = isset($mod->extra) ? $mod->extra : '';
-        $cm->icon             = isset($mod->icon) ? $mod->icon : '';
-        $cm->iconcomponent    = isset($mod->iconcomponent) ? $mod->iconcomponent : '';
-        $cm->uservisible      = true;
-        if (!empty($CFG->enableavailability)) {
-            // We must have completion information from modinfo. If it's not
-            // there, cache needs rebuilding
-            if(!isset($mod->availablefrom)) {
-                debugging('enableavailability option was changed; rebuilding '.
-                    'cache for course '.$course->id);
-                rebuild_course_cache($course->id,true);
-                // Re-enter this routine to do it all properly
-                return get_fast_modinfo($course, $userid);
-            }
-            $cm->availablefrom    = $mod->availablefrom;
-            $cm->availableuntil   = $mod->availableuntil;
-            $cm->showavailability = $mod->showavailability;
-            $cm->conditionscompletion = $mod->conditionscompletion;
-            $cm->conditionsgrade  = $mod->conditionsgrade;
-        }
-
-        // preload long names plurals and also check module is installed properly
-        if (!isset($modlurals[$cm->modname])) {
-            if (!file_exists("$CFG->dirroot/mod/$cm->modname/lib.php")) {
-                continue;
-            }
-            $modlurals[$cm->modname] = get_string('modulenameplural', $cm->modname);
-        }
-        $cm->modplural = $modlurals[$cm->modname];
-        $modcontext = get_context_instance(CONTEXT_MODULE,$cm->id);
-
-        if (!empty($CFG->enableavailability)) {
-            // Unfortunately the next call really wants to call
-            // get_fast_modinfo, but that would be recursive, so we fake up a
-            // modinfo for it already
-            if (empty($minimalmodinfo)) { //TODO: this is suspicious (skodak)
-                $minimalmodinfo = new stdClass();
-                $minimalmodinfo->cms = array();
-                foreach($info as $mod) {
-                    if (empty($mod->name)) {
-                        // something is wrong here
-                        continue;
-                    }
-                    $minimalcm = new stdClass();
-                    $minimalcm->id = $mod->cm;
-                    $minimalcm->name = $mod->name;
-                    $minimalmodinfo->cms[$minimalcm->id]=$minimalcm;
-                }
-            }
-
-            // Get availability information
-            $ci = new condition_info($cm);
-            $cm->available = $ci->is_available($cm->availableinfo, true, $userid, $minimalmodinfo);
-        } else {
-            $cm->available = true;
-        }
-        if ((!$cm->visible or !$cm->available) and !has_capability('moodle/course:viewhiddenactivities', $modcontext, $userid)) {
-            $cm->uservisible = false;
-
-        } else if (!empty($CFG->enablegroupmembersonly) and !empty($cm->groupmembersonly)
-                and !has_capability('moodle/site:accessallgroups', $modcontext, $userid)) {
-            if (is_null($modinfo->groups)) {
-                $modinfo->groups = groups_get_user_groups($course->id, $userid);
-            }
-            if (empty($modinfo->groups[$cm->groupingid])) {
-                $cm->uservisible = false;
-            }
-        }
-
-        if (!isset($modinfo->instances[$cm->modname])) {
-            $modinfo->instances[$cm->modname] = array();
-        }
-        $modinfo->instances[$cm->modname][$cm->instance] =& $cm;
-        $modinfo->cms[$cm->id] =& $cm;
-
-        // reconstruct sections
-        if (!isset($modinfo->sections[$cm->sectionnum])) {
-            $modinfo->sections[$cm->sectionnum] = array();
-        }
-        $modinfo->sections[$cm->sectionnum][] = $cm->id;
-
-        unset($cm);
-    }
-
-    unset($cache[$course->id]); // prevent potential reference problems when switching users
-    $cache[$course->id] = $modinfo;
-
-    // Ensure cache does not use too much RAM
-    if (count($cache) > MAX_MODINFO_CACHE_SIZE) {
-        reset($cache);
-        $key = key($cache);
-        unset($cache[$key]);
-    }
-
-    return $cache[$course->id];
-}
-
 /**
  * Determines if the currently logged in user is in editing mode.
  * Note: originally this function had $userid parameter - it was not usable anyway
@@ -8012,14 +7802,13 @@ function notify_login_failures() {
           GROUP BY ip
             HAVING COUNT(*) >= ?";
     $params = array($CFG->lastnotifyfailure, $CFG->notifyloginthreshold);
-    if ($rs = $DB->get_recordset_sql($sql, $params)) {
-        foreach ($rs as $iprec) {
-            if (!empty($iprec->ip)) {
-                set_cache_flag('login_failure_by_ip', $iprec->ip, '1', 0);
-            }
+    $rs = $DB->get_recordset_sql($sql, $params);
+    foreach ($rs as $iprec) {
+        if (!empty($iprec->ip)) {
+            set_cache_flag('login_failure_by_ip', $iprec->ip, '1', 0);
         }
-        $rs->close();
     }
+    $rs->close();
 
 /// Get all the INFOs with more than notifyloginthreshold failures since lastnotifyfailure
 /// and insert them into the cache_flags temp table
@@ -8030,14 +7819,13 @@ function notify_login_failures() {
           GROUP BY info
             HAVING count(*) >= ?";
     $params = array($CFG->lastnotifyfailure, $CFG->notifyloginthreshold);
-    if ($rs = $DB->get_recordset_sql($sql, $params)) {
-        foreach ($rs as $inforec) {
-            if (!empty($inforec->info)) {
-                set_cache_flag('login_failure_by_info', $inforec->info, '1', 0);
-            }
+    $rs = $DB->get_recordset_sql($sql, $params);
+    foreach ($rs as $inforec) {
+        if (!empty($inforec->info)) {
+            set_cache_flag('login_failure_by_info', $inforec->info, '1', 0);
         }
-        $rs->close();
     }
+    $rs->close();
 
 /// Now, select all the login error logged records belonging to the ips and infos
 /// since lastnotifyfailure, that we have stored in the cache_flags table
@@ -8063,14 +7851,13 @@ function notify_login_failures() {
     $count = 0;
     $messages = '';
 /// Iterate over the logs recordset
-    if ($rs = $DB->get_recordset_sql($sql, $params)) {
-        foreach ($rs as $log) {
-            $log->time = userdate($log->time);
-            $messages .= get_string('notifyloginfailuresmessage','',$log)."\n";
-            $count++;
-        }
-        $rs->close();
+    $rs = $DB->get_recordset_sql($sql, $params);
+    foreach ($rs as $log) {
+        $log->time = userdate($log->time);
+        $messages .= get_string('notifyloginfailuresmessage','',$log)."\n";
+        $count++;
     }
+    $rs->close();
 
 /// If we haven't run in the last hour and
 /// we have something useful to report and we
index 3a62e6a..1a9f007 100644 (file)
@@ -1026,10 +1026,14 @@ class global_navigation extends navigation_node {
                 if ($course->id !== SITEID) {
                     // Find the section for the $CM associated with the page and collect
                     // its section number.
-                    foreach ($sections as $section) {
-                        if ($section->id == $cm->section) {
-                            $cm->sectionnumber = $section->section;
-                            break;
+                    if (isset($cm->sectionnum)) {
+                        $cm->sectionnumber = $cm->sectionnum;
+                    } else {
+                        foreach ($sections as $section) {
+                            if ($section->id == $cm->section) {
+                                $cm->sectionnumber = $section->section;
+                                break;
+                            }
                         }
                     }
 
@@ -1429,10 +1433,10 @@ class global_navigation extends navigation_node {
      *
      * @param navigation_node $sectionnode
      * @param int $sectionnumber
-     * @param stdClass $modinfo Object returned from {@see get_fast_modinfo()}
+     * @param course_modinfo $modinfo Object returned from {@see get_fast_modinfo()}
      * @return array Array of activity nodes
      */
-    protected function load_section_activities(navigation_node $sectionnode, $sectionnumber, $modinfo) {
+    protected function load_section_activities(navigation_node $sectionnode, $sectionnumber, course_modinfo $modinfo) {
         if (!array_key_exists($sectionnumber, $modinfo->sections)) {
             return true;
         }
@@ -1449,11 +1453,12 @@ class global_navigation extends navigation_node {
             } else {
                 $icon = new pix_icon('icon', get_string('modulename', $cm->modname), $cm->modname);
             }
-            $url = new moodle_url('/mod/'.$cm->modname.'/view.php', array('id'=>$cm->id));
+            $url = $cm->get_url();
             $activitynode = $sectionnode->add(format_string($cm->name), $url, navigation_node::TYPE_ACTIVITY, null, $cm->id, $icon);
             $activitynode->title(get_string('modulename', $cm->modname));
             $activitynode->hidden = (!$cm->visible);
-            if ($cm->modname == 'label') {
+            if (!$url) {
+                // Do not show activities that don't have links!
                 $activitynode->display = false;
             } else if ($this->module_extends_navigation($cm->modname)) {
                 $activitynode->nodetype = navigation_node::NODETYPE_BRANCH;
@@ -1482,11 +1487,12 @@ class global_navigation extends navigation_node {
         } else {
             $icon = new pix_icon('icon', get_string('modulename', $cm->modname), $cm->modname);
         }
-        $url = new moodle_url('/mod/'.$cm->modname.'/view.php', array('id'=>$cm->id));
+        $url = $cm->get_url();
         $activitynode = $coursenode->add(format_string($cm->name), $url, navigation_node::TYPE_ACTIVITY, null, $cm->id, $icon);
         $activitynode->title(get_string('modulename', $cm->modname));
         $activitynode->hidden = (!$cm->visible);
-        if ($cm->modname == 'label') {
+        if (!$url) {
+            // Don't show activities that don't have links!
             $activitynode->display = false;
         } else if ($this->module_extends_navigation($cm->modname)) {
             $activitynode->nodetype = navigation_node::NODETYPE_BRANCH;
@@ -1509,7 +1515,7 @@ class global_navigation extends navigation_node {
      * @param navigation_node $activity
      * @return bool
      */
-    protected function load_activity(stdClass $cm, stdClass $course, navigation_node $activity) {
+    protected function load_activity($cm, stdClass $course, navigation_node $activity) {
         global $CFG, $DB;
 
         $activity->make_active();
@@ -2537,7 +2543,7 @@ class settings_navigation extends navigation_node {
      *
      */
     public function initialise() {
-        global $DB;
+        global $DB, $SESSION;
 
         if (during_initial_install()) {
             return false;
@@ -2581,7 +2587,13 @@ class settings_navigation extends navigation_node {
         }
 
         $settings = $this->load_user_settings($this->page->course->id);
-        $admin = $this->load_administration_settings();
+
+        if (isloggedin() && !isguestuser() && (!property_exists($SESSION, 'load_navigation_admin') || $SESSION->load_navigation_admin)) {
+            $admin = $this->load_administration_settings();
+            $SESSION->load_navigation_admin = ($admin->has_children());
+        } else {
+            $admin = false;
+        }
 
         if ($context->contextlevel == CONTEXT_SYSTEM && $admin) {
             $admin->force_open();
@@ -2598,8 +2610,6 @@ class settings_navigation extends navigation_node {
             $this->add(get_string('returntooriginaluser', 'moodle', fullname($realuser, true)), $url, self::TYPE_SETTING, null, null, new pix_icon('t/left', ''));
         }
 
-        // Make sure the first child doesnt have proceed with hr set to true
-
         foreach ($this->children as $key=>$node) {
             if ($node->nodetype != self::NODETYPE_BRANCH || $node->children->count()===0) {
                 $node->remove();
index 6ae69e4..dc3805f 100644 (file)
@@ -1225,12 +1225,13 @@ function get_question_states(&$questions, $cmoptions, $attempt, $lastattemptid =
  * @global object
  * @param array $question The question to load the state for.
  * @param object $cmoptions Options from the specifica activity module, e.g. $quiz.
- * @param object $attempt The attempt for which the question sessions are to be loaded.
+ * @param integer $attemptid The question_attempts this is part of.
  * @param integer $stateid The id of a specific state of this question.
  * @return object the requested state. False on error.
  */
-function question_load_specific_state($question, $cmoptions, $attempt, $stateid) {
+function question_load_specific_state($question, $cmoptions, $attemptid, $stateid) {
     global $DB;
+
     // Load specified states for the question.
     // sess.sumpenalty is probably wrong here shoul really be a sum of penalties from before the one we are asking for.
     $sql = 'SELECT st.*, sess.sumpenalty, sess.manualcomment, sess.manualcommentformat,
@@ -1241,7 +1242,7 @@ function question_load_specific_state($question, $cmoptions, $attempt, $stateid)
                AND sess.attemptid = st.attempt
                AND st.question = ?
                AND sess.questionid = st.question';
-    $state = $DB->get_record_sql($sql, array($stateid, $attempt->id, $question->id));
+    $state = $DB->get_record_sql($sql, array($stateid, $attemptid, $question->id));
     if (!$state) {
         return false;
     }
@@ -1258,7 +1259,7 @@ function question_load_specific_state($question, $cmoptions, $attempt, $stateid)
                AND sess.questionid = st.question
                AND st.event IN ('.QUESTION_EVENTS_GRADED.') '.
            'ORDER BY st.seq_number DESC';
-    $gradedstates = $DB->get_records_sql($sql, array($state->seq_number, $attempt->id, $question->id), 0, 1);
+    $gradedstates = $DB->get_records_sql($sql, array($state->seq_number, $attemptid, $question->id), 0, 1);
     if (empty($gradedstates)) {
         $state->last_graded = clone($state);
     } else {
@@ -1534,7 +1535,7 @@ function regrade_question_in_attempt($question, $attempt, $cmoptions, $verbose=f
         $attempt->sumgrades -= $states[count($states)-1]->grade;
 
         // Initialise the replaystate
-        $replaystate = question_load_specific_state($question, $cmoptions, $attempt, $states[0]->id);
+        $replaystate = question_load_specific_state($question, $cmoptions, $attempt->uniqueid, $states[0]->id);
         $replaystate->sumpenalty = 0;
         $replaystate->last_graded->sumpenalty = 0;
 
index e677754..de6f9ff 100644 (file)
@@ -414,6 +414,7 @@ require_once($CFG->libdir .'/grouplib.php');        // Groups functions
 require_once($CFG->libdir .'/sessionlib.php');      // All session and cookie related stuff
 require_once($CFG->libdir .'/editorlib.php');       // All text editor related functions and classes
 require_once($CFG->libdir .'/messagelib.php');      // Messagelib functions
+require_once($CFG->libdir .'/modinfolib.php');      // Cached information on course-module instances
 
 // make sure PHP is not severly misconfigured
 setup_validate_php_configuration();
index cbf6ffd..46028a7 100644 (file)
@@ -750,6 +750,9 @@ function setup_get_remote_url() {
 
     } else if (stripos($_SERVER['SERVER_SOFTWARE'], 'nginx') !== false) {
         //nginx - not officially supported
+        if (!isset($_SERVER['SCRIPT_NAME'])) {
+            die('Invalid server configuration detected, please try to add "fastcgi_param SCRIPT_NAME $fastcgi_script_name;" to the nginx server configuration.');
+        }
         $rurl['scheme']   = empty($_SERVER['HTTPS']) ? 'http' : 'https';
         $rurl['fullpath'] = $_SERVER['REQUEST_URI']; // TODO: verify this is always properly encoded
 
index 820516d..6cd68c7 100644 (file)
@@ -18,5 +18,7 @@ Our changes: /// Look for "moodle" in code
  * src/reporter/HtmlCoverageReporter.php, src/reporter/html/indexheader.html,
    src/reporter/html/header.html, src/reporter/html/footer.html - various xhtml fixes
  * removed deprecated "=& new"
+ * src/phpcoverage.remote.bottom.inc.php | => Prevent execution (not used and unsecure)
+   src/phpcoverage.remote.top.inc.php    |
 
 20090621 - Eloy Lafuente (stronk7): Original import of 0.8.2 release
index 6b45037..c27b2aa 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+    die(); // This (unsecure MDL-26237) stuff isn't used by moodle at all
 /*
  *  $Id$
  *  
index 4a26176..73f241e 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+    die(); // This (unsecure MDL-26237) stuff isn't used by moodle at all
 /*
  *  $Id$
  *  
index 1ec90fa..81de9b7 100644 (file)
@@ -668,7 +668,7 @@ function upgrade_plugins_blocks($startcallback, $endcallback, $verbose) {
             if ($conflictblock !== false) {
                 // Duplicate block titles are not allowed, they confuse people
                 // AND PHP's associative arrays ;)
-                throw new plugin_defective_exception($component, get_string('blocknameconflict', '', (object)array('name'=>$block->name, 'conflict'=>$conflictblock)));
+                throw new plugin_defective_exception($component, get_string('blocknameconflict', 'error', (object)array('name'=>$block->name, 'conflict'=>$conflictblock)));
             }
             $startcallback($component, true, $verbose);
 
index 2537afc..69b13a4 100644 (file)
@@ -1106,6 +1106,13 @@ function format_text($text, $format = FORMAT_MOODLE, $options = NULL, $courseid_
             $text = $filtermanager->filter_text($text, $context, array('originalformat' => $format));
             break;
     }
+    if ($options['filter']) {
+        // at this point there should not be any draftfile links any more,
+        // this happens when developers forget to post process the text.
+        // The only potential problem is that somebody might try to format
+        // the text before storing into database which would be itself big bug.
+        $text = str_replace("\"$CFG->httpswwwroot/draftfile.php", "\"$CFG->httpswwwroot/brokenfile.php#", $text);
+    }
 
     // Warn people that we have removed this old mechanism, just in case they
     // were stupid enough to rely on it.
@@ -2174,7 +2181,8 @@ function navmenulist($course, $sections, $modinfo, $strsection, $strjumpto, $wid
 
     $menu[] = '<ul class="navmenulist"><li class="jumpto section"><span>'.$strjumpto.'</span><ul>';
     foreach ($modinfo->cms as $mod) {
-        if ($mod->modname == 'label') {
+        if (!$mod->has_view()) {
+            // Don't show modules which you can't link to!
             continue;
         }
 
index 4409bf9..bbb4a93 100644 (file)
@@ -140,7 +140,7 @@ function message_print_participants($context, $courseid, $contactselecturl=null,
 
     $countparticipants = count_enrolled_users($context);
     $participants = get_enrolled_users($context, '', 0, 'u.*', '', $page*MESSAGE_CONTACTS_PER_PAGE, MESSAGE_CONTACTS_PER_PAGE);
-    
+
     $pagingbar = new paging_bar($countparticipants, $page, MESSAGE_CONTACTS_PER_PAGE, $PAGE->url, 'page');
     echo $OUTPUT->render($pagingbar);
 
@@ -269,24 +269,21 @@ function message_get_contacts($user1=null, &$user2=null) {
                  GROUP BY $userfields
                  ORDER BY u.firstname ASC";
 
-    if ($rs = $DB->get_recordset_sql($contactsql, array($user1->id, $user1->id))){
-        foreach($rs as $rd){
-
-            if($rd->lastaccess >= $timefrom){
-                // they have been active recently, so are counted online
-                $onlinecontacts[] = $rd;
+    $rs = $DB->get_recordset_sql($contactsql, array($user1->id, $user1->id));
+    foreach ($rs as $rd) {
+        if ($rd->lastaccess >= $timefrom) {
+            // they have been active recently, so are counted online
+            $onlinecontacts[] = $rd;
 
-            }else{
-                $offlinecontacts[] = $rd;
-            }
+        } else {
+            $offlinecontacts[] = $rd;
+        }
 
-            if (!empty($user2) && $user2->id==$rd->id) {
-                $user2->iscontact = true;
-            }
+        if (!empty($user2) && $user2->id==$rd->id) {
+            $user2->iscontact = true;
         }
-        unset($rd);
-        $rs->close();
     }
+    $rs->close();
 
     // get messages from anyone who isn't in our contact list and count the number
     // of messages we have from each of them
@@ -298,13 +295,11 @@ function message_get_contacts($user1=null, &$user2=null) {
                   GROUP BY $userfields
                   ORDER BY u.firstname ASC";
 
-    if($rs = $DB->get_recordset_sql($strangersql, array($USER->id))){
-        foreach($rs as $rd){
-            $strangers[] = $rd;
-        }
-        unset($rd);
-        $rs->close();
+    $rs = $DB->get_recordset_sql($strangersql, array($USER->id));
+    foreach ($rs as $rd) {
+        $strangers[] = $rd;
     }
+    $rs->close();
 
     return array($onlinecontacts, $offlinecontacts, $strangers);
 }
@@ -527,7 +522,11 @@ function message_print_search($advancedsearch = false, $user1=null) {
 
     $doingsearch = false;
     if ($frm) {
-        $doingsearch = !empty($frm->combinedsubmit) || !empty($frm->keywords) || (!empty($frm->personsubmit) and !empty($frm->name));
+        if (confirm_sesskey()) {
+            $doingsearch = !empty($frm->combinedsubmit) || !empty($frm->keywords) || (!empty($frm->personsubmit) and !empty($frm->name));
+        } else {
+            $frm = false;
+        }
     }
 
     if (!empty($frm->combinedsearch)) {
@@ -1568,7 +1567,7 @@ function message_post_message($userfrom, $userto, $message, $format, $messagetyp
         $eventdata->fullmessage      = $message;
         $eventdata->fullmessagehtml  = '';
     }
-    
+
     $eventdata->fullmessageformat = $format;
     $eventdata->smallmessage     = strip_tags($message);//strip just in case there are is any html that would break the popup notification
 
@@ -1583,7 +1582,7 @@ function message_post_message($userfrom, $userto, $message, $format, $messagetyp
     if (!empty($eventdata->fullmessagehtml)) {
         $eventdata->fullmessagehtml .= "<br /><br />---------------------------------------------------------------------<br />".$emailtagline;
     }
-    
+
     $eventdata->timecreated     = time();
     return message_send($eventdata);
 }
@@ -1769,7 +1768,7 @@ function message_mark_messages_read($touserid, $fromuserid){
 */
 function message_mark_message_read($message, $timeread, $messageworkingempty=false) {
     global $DB;
-    
+
     $message->timeread = $timeread;
 
     $messageid = $message->id;
index 3edfb1f..90bf792 100644 (file)
@@ -38,7 +38,13 @@ class message_output_email extends message_output {
      * @param object $eventdata the event data submitted by the message sender plus $eventdata->savedmessageid
      */
     function send_message($eventdata) {
-        global $SITE;
+        global $CFG;
+
+        if (!empty($CFG->noemailever)) {
+            // hidden setting for development sites, set in config.php if needed
+            debugging('$CFG->noemailever active, no email message sent.', DEBUG_MINIMAL);
+            return true;
+        }
 
         //hold onto email preference because /admin/cron.php sends a lot of messages at once
         static $useremailaddresses = array();
index 6f3c4a5..a6f9f65 100644 (file)
@@ -45,6 +45,12 @@ class message_output_jabber extends message_output {
         global $CFG;
 
         if (message_output_jabber::_jabber_configured()) {
+            if (!empty($CFG->noemailever)) {
+                // hidden setting for development sites, set in config.php if needed
+                debugging('$CFG->noemailever active, no jabber message sent.', DEBUG_MINIMAL);
+                return true;
+            }
+
             //hold onto jabber id preference because /admin/cron.php sends a lot of messages at once
             static $jabberaddresses = array();
 
@@ -86,7 +92,7 @@ class message_output_jabber extends message_output {
      */
     function config_form($preferences){
         global $CFG;
-        
+
         if (!message_output_jabber::_jabber_configured()) {
             return get_string('notconfigured','message_jabber');
         } else {
index e1e6120..edbe055 100644 (file)
@@ -3,7 +3,8 @@
 <table cellpadding="5" class="message_form">
     <tr>
         <td colspan="3" class="message_heading mdl-left">
-            <input type="text" name="combinedsearch" size="40" id="combinedsearch" value="<?php echo $combinedsearchstring; ?>" />
+            <input type="hidden" name="sesskey" value="<?php p(sesskey()); ?>" />
+            <input type="text" name="combinedsearch" size="40" id="combinedsearch" value="<?php p($combinedsearchstring); ?>" />
             <input type="submit" name="combinedsubmit" value="<?php print_string('searchcombined','message') ?>" />
             <a href="index.php?usergroup=<?php echo VIEW_SEARCH ?>&advanced=1" id="advancedcontactsearchlink"><?php print_string('advanced') ?></a>
         </td>
index 48fce17..e6fffc8 100644 (file)
@@ -9,13 +9,15 @@
     </tr>
     <tr>
         <td><label for="name"><?php print_string('name') ?></label></td>
-        <td><input type="text" name="name" size="40" id="name" value="<? echo $personsearch ?>" /></td>
+        <td><input type="text" name="name" size="40" id="name" value="<?php p($personsearch) ?>" /></td>
         <td><input type="submit" name="personsubmit" value="<?php print_string('searchforperson','message') ?>" /></td>
     </tr>
     <tr>
         <td>&nbsp;</td>
         <td colspan="2">
-            <input type="checkbox" name="mycourses" id="mycourses" /><label for="mycourses"><?php print_string('onlymycourses', 'message') ?></label></td>
+            <input type="checkbox" name="mycourses" id="mycourses" /><label for="mycourses"><?php print_string('onlymycourses', 'message') ?></label>
+            <input type="hidden" name="sesskey" value="<?php p(sesskey()); ?>" />
+        </td>
     </tr>
 
     <tr><td colspan="3"></td></tr>
@@ -26,7 +28,7 @@
     </tr>
     <tr>
         <td><label for="keywords"><?php print_string('keywords', 'message') ?></label></td>
-        <td><input type="text" name="keywords" id="keywords" size="40" value="<? echo $messagesearch ?>" /></td>
+        <td><input type="text" name="keywords" id="keywords" size="40" value="<?php p($messagesearch) ?>" /></td>
         <td><input type="submit" name="keywordssubmit" value="<?php print_string('searchmessages','message') ?>" /></td>
     </tr>
 
     <tr><td>&nbsp;</td><td colspan="2"><input type="radio" name="keywordsoption" id="keywordsoption4" value="allusers" /><label for="keywordsoption4"><?php print_string('allusers', 'message') ?></label></td></tr>
     <?php } ?>
 
-<?php
-/* Potential abuse problems - temporarily disabled
-    echo '<tr><td colspan="3"><input type="radio" name="keywordsoption" alt="'.get_string('allstudents', 'message').'" value="courseusers" />'.get_string('allstudents', 'message').'<br />&nbsp;&nbsp;&nbsp;'.$cs.'; </td></tr>';
-
-*/
-
-?>
-
 </table>
 </div>
 
index d5e891c..2841111 100644 (file)
@@ -49,10 +49,10 @@ function xmldb_assignment_upgrade($oldversion) {
 
         $count = $DB->count_records_sql("SELECT COUNT('x') $sqlfrom");
 
-        if ($rs = $DB->get_recordset_sql("SELECT s.id, s.userid, s.teacher, s.assignment, a.course, cm.id AS cmid $sqlfrom ORDER BY a.course, s.assignment")) {
+        $rs = $DB->get_recordset_sql("SELECT s.id, s.userid, s.teacher, s.assignment, a.course, cm.id AS cmid $sqlfrom ORDER BY a.course, s.assignment");
 
+        if ($rs->valid()) {
             $pbar = new progress_bar('migrateassignmentfiles', 500, true);
-
             $i = 0;
             foreach ($rs as $submission) {
                 $i++;
@@ -122,9 +122,8 @@ function xmldb_assignment_upgrade($oldversion) {
                 @rmdir("$CFG->dataroot/$submission->course/$CFG->moddata/assignment/$submission->assignment");
                 @rmdir("$CFG->dataroot/$submission->course/$CFG->moddata/assignment");
             }
-            $rs->close();
-
         }
+        $rs->close();
 
         upgrade_mod_savepoint(true, 2008081900, 'assignment');
     }
index 634f663..9c51c09 100644 (file)
@@ -2688,7 +2688,8 @@ function assignment_upgrade_grades() {
     $sql = "SELECT a.*, cm.idnumber AS cmidnumber, a.course AS courseid
               FROM {assignment} a, {course_modules} cm, {modules} m
              WHERE m.name='assignment' AND m.id=cm.module AND cm.instance=a.id";
-    if ($rs = $DB->get_recordset_sql($sql)) {
+    $rs = $DB->get_recordset_sql($sql);
+    if ($rs->valid()) {
         // too much debug output
         $pbar = new progress_bar('assignmentupgradegrades', 500, true);
         $i=0;
@@ -2698,9 +2699,9 @@ function assignment_upgrade_grades() {
             assignment_update_grades($assignment);
             $pbar->update($i, $count, "Updating Assignment grades ($i/$count).");
         }
-        $rs->close();
         upgrade_set_timeout(); // reset to default timeout
     }
+    $rs->close();
 }
 
 /**
index 1d85846..371da31 100644 (file)
@@ -55,16 +55,16 @@ function xmldb_data_upgrade($oldversion) {
     }
 
     if ($oldversion < 2008081400) {
-        if ($rs = $DB->get_recordset('data')) {
-            $pattern = '/\#\#delete\#\#(\s+)\#\#approve\#\#/';
-            $replacement = '##delete##$1##approve##$1##export##';
-            foreach ($rs as $data) {
-                $data->listtemplate = preg_replace($pattern, $replacement, $data->listtemplate);
-                $data->singletemplate = preg_replace($pattern, $replacement, $data->singletemplate);
-                $DB->update_record('data', $data);
-            }
-            $rs->close();
+        $pattern = '/\#\#delete\#\#(\s+)\#\#approve\#\#/';
+        $replacement = '##delete##$1##approve##$1##export##';
+        $rs = $DB->get_recordset('data');
+        foreach ($rs as $data) {
+            $data->listtemplate = preg_replace($pattern, $replacement, $data->listtemplate);
+            $data->singletemplate = preg_replace($pattern, $replacement, $data->singletemplate);
+            $DB->update_record('data', $data);
         }
+        $rs->close();
+
         upgrade_mod_savepoint(true, 2008081400, 'data');
     }
 
@@ -89,8 +89,9 @@ function xmldb_data_upgrade($oldversion) {
 
         $count = $DB->count_records_sql("SELECT COUNT('x') $sqlfrom");
 
-        if ($rs = $DB->get_recordset_sql("SELECT c.id, f.type, r.dataid, c.recordid, f.id AS fieldid, r.userid, c.content, c.content1, d.course, r.userid, cm.id AS cmid $sqlfrom ORDER BY d.course, d.id")) {
+        $rs = $DB->get_recordset_sql("SELECT c.id, f.type, r.dataid, c.recordid, f.id AS fieldid, r.userid, c.content, c.content1, d.course, r.userid, cm.id AS cmid $sqlfrom ORDER BY d.course, d.id");
 
+        if ($rs->valid()) {
             $pbar = new progress_bar('migratedatafiles', 500, true);
 
             $i = 0;
@@ -142,8 +143,9 @@ function xmldb_data_upgrade($oldversion) {
                 @rmdir("$CFG->dataroot/$content->course/$CFG->moddata/data");
                 @rmdir("$CFG->dataroot/$content->course/$CFG->moddata");
             }
-            $rs->close();
         }
+        $rs->close();
+
         upgrade_mod_savepoint(true, 2008091400, 'data');
     }
 
@@ -218,31 +220,31 @@ function xmldb_data_upgrade($oldversion) {
             $lastdataid = null;
             $lastcourseid = null;
             $modcontext = null;
-            if ($rs = $DB->get_recordset_sql($sql)) {
-                foreach($rs as $res) {
-                    if ($res->dataid != $lastdataid || $res->courseid != $lastcourseid) {
-                        $cm = get_coursemodule_from_instance('data', $res->dataid, $res->courseid);
-                        if ($cm) {
-                            $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
-                        }
-                        $lastdataid = $res->dataid;
-                        $lastcourseid = $res->courseid;
-                    }
-                    $cmt = new stdClass();
-                    $cmt->contextid   = $modcontext->id;
-                    $cmt->commentarea = 'database_entry';
-                    $cmt->itemid      = $res->itemid;
-                    $cmt->content     = $res->commentcontent;
-                    $cmt->format      = $res->format;
-                    $cmt->userid      = $res->userid;
-                    $cmt->timecreated = $res->timecreated;
-                    // comments class will throw an exception if error occurs
-                    $cmt_id = $DB->insert_record('comments', $cmt);
-                    if (!empty($cmt_id)) {
-                        $DB->delete_records('data_comments', array('id'=>$res->commentid));
+            $rs = $DB->get_recordset_sql($sql);
+            foreach($rs as $res) {
+                if ($res->dataid != $lastdataid || $res->courseid != $lastcourseid) {
+                    $cm = get_coursemodule_from_instance('data', $res->dataid, $res->courseid);
+                    if ($cm) {
+                        $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
                     }
+                    $lastdataid = $res->dataid;
+                    $lastcourseid = $res->courseid;
+                }
+                $cmt = new stdClass();
+                $cmt->contextid   = $modcontext->id;
+                $cmt->commentarea = 'database_entry';
+                $cmt->itemid      = $res->itemid;
+                $cmt->content     = $res->commentcontent;
+                $cmt->format      = $res->format;
+                $cmt->userid      = $res->userid;
+                $cmt->timecreated = $res->timecreated;
+                // comments class will throw an exception if error occurs
+                $cmt_id = $DB->insert_record('comments', $cmt);
+                if (!empty($cmt_id)) {
+                    $DB->delete_records('data_comments', array('id'=>$res->commentid));
                 }
             }
+            $rs->close();
             // the default exception handler will stop the script if error occurs before
             $dbman->drop_table($table);
         }
index a22aa6b..534e424 100755 (executable)
@@ -361,13 +361,14 @@ class data_field_base {     // Base class for Database Field Types (see field/*/
             $conditions = array('fieldid'=>$this->field->id);
         }
 
-        if ($rs = $DB->get_recordset('data_content', $conditions)) {
+        $rs = $DB->get_recordset('data_content', $conditions);
+        if ($rs->valid()) {
             $fs = get_file_storage();
             foreach ($rs as $content) {
                 $fs->delete_area_files($this->context->id, 'mod_data', 'content', $content->id);
             }
-            $rs->close();
         }
+        $rs->close();
 
         return $DB->delete_records('data_content', $conditions);
     }
@@ -1071,7 +1072,8 @@ function data_upgrade_grades() {
     $sql = "SELECT d.*, cm.idnumber AS cmidnumber, d.course AS courseid
               FROM {data} d, {course_modules} cm, {modules} m
              WHERE m.name='data' AND m.id=cm.module AND cm.instance=d.id";
-    if ($rs = $DB->get_recordset_sql($sql)) {
+    $rs = $DB->get_recordset_sql($sql);
+    if ($rs->valid()) {
         // too much debug output
         $pbar = new progress_bar('dataupgradegrades', 500, true);
         $i=0;
@@ -1081,8 +1083,8 @@ function data_upgrade_grades() {
             data_update_grades($data, 0, false);
             $pbar->update($i, $count, "Updating Database grades ($i/$count).");
         }
-        $rs->close();
     }
+    $rs->close();
 }
 
 /**
@@ -2448,39 +2450,38 @@ function data_reset_userdata($data) {
         $course_context = get_context_instance(CONTEXT_COURSE, $data->courseid);
         $notenrolled = array();
         $fields = array();
-        if ($rs = $DB->get_recordset_sql($recordssql, array($data->courseid))) {
-            foreach ($rs as $record) {
-                if (array_key_exists($record->userid, $notenrolled) or !$record->userexists or $record->userdeleted
-                  or !is_enrolled($course_context, $record->userid)) {
-                    //delete ratings
-                    if (!$cm = get_coursemodule_from_instance('data', $record->dataid)) {
-                        continue;
-                    }
-                    $datacontext = get_context_instance(CONTEXT_MODULE, $cm->id);
-                    $ratingdeloptions->contextid = $datacontext->id;
-                    $ratingdeloptions->itemid = $record->id;
-                    $rm->delete_ratings($ratingdeloptions);
-
-                    $DB->delete_records('comments', array('itemid'=>$record->id, 'commentarea'=>'database_entry'));
-                    $DB->delete_records('data_content', array('recordid'=>$record->id));
-                    $DB->delete_records('data_records', array('id'=>$record->id));
-                    // HACK: this is ugly - the recordid should be before the fieldid!
-                    if (!array_key_exists($record->dataid, $fields)) {
-                        if ($fs = $DB->get_records('data_fields', array('dataid'=>$record->dataid))) {
-                            $fields[$record->dataid] = array_keys($fs);
-                        } else {
-                            $fields[$record->dataid] = array();
-                        }
-                    }
-                    foreach($fields[$record->dataid] as $fieldid) {
-                        fulldelete("$CFG->dataroot/$data->courseid/moddata/data/$record->dataid/$fieldid/$record->id");
+        $rs = $DB->get_recordset_sql($recordssql, array($data->courseid));
+        foreach ($rs as $record) {
+            if (array_key_exists($record->userid, $notenrolled) or !$record->userexists or $record->userdeleted
+              or !is_enrolled($course_context, $record->userid)) {
+                //delete ratings
+                if (!$cm = get_coursemodule_from_instance('data', $record->dataid)) {
+                    continue;
+                }
+                $datacontext = get_context_instance(CONTEXT_MODULE, $cm->id);
+                $ratingdeloptions->contextid = $datacontext->id;
+                $ratingdeloptions->itemid = $record->id;
+                $rm->delete_ratings($ratingdeloptions);
+
+                $DB->delete_records('comments', array('itemid'=>$record->id, 'commentarea'=>'database_entry'));
+                $DB->delete_records('data_content', array('recordid'=>$record->id));
+                $DB->delete_records('data_records', array('id'=>$record->id));
+                // HACK: this is ugly - the recordid should be before the fieldid!
+                if (!array_key_exists($record->dataid, $fields)) {
+                    if ($fs = $DB->get_records('data_fields', array('dataid'=>$record->dataid))) {
+                        $fields[$record->dataid] = array_keys($fs);
+                    } else {
+                        $fields[$record->dataid] = array();
                     }
-                    $notenrolled[$record->userid] = true;
                 }
+                foreach($fields[$record->dataid] as $fieldid) {
+                    fulldelete("$CFG->dataroot/$data->courseid/moddata/data/$record->dataid/$fieldid/$record->id");
+                }
+                $notenrolled[$record->userid] = true;
             }
-            $rs->close();
-            $status[] = array('component'=>$componentstr, 'item'=>get_string('deletenotenrolled', 'data'), 'error'=>false);
         }
+        $rs->close();
+        $status[] = array('component'=>$componentstr, 'item'=>get_string('deletenotenrolled', 'data'), 'error'=>false);
     }
 
     // remove all ratings
index 016f079..0be56e1 100644 (file)
@@ -48,7 +48,10 @@ function folder_20_migrate() {
         return;
     }
 
-    if (!$candidates = $DB->get_recordset('resource_old', array('type'=>'directory', 'migrated'=>0))) {
+    $candidates = $DB->get_recordset('resource_old', array('type'=>'directory', 'migrated'=>0));
+
+    if (!$candidates->valid()) {
+        $candidates->close(); // Not going to iterate (but exit), close rs
         return;
     }
 
@@ -101,4 +104,4 @@ function folder_20_migrate() {
 
     // clear all course modinfo caches
     rebuild_course_cache(0, true);
-}
\ No newline at end of file
+}
index a4f3106..3a56755 100644 (file)
@@ -104,7 +104,8 @@ function xmldb_forum_upgrade($oldversion) {
 
         $count = $DB->count_records_sql("SELECT COUNT('x') $sqlfrom");
 
-        if ($rs = $DB->get_recordset_sql("SELECT p.id, p.attachment, p.userid, d.forum, f.course, cm.id AS cmid $sqlfrom ORDER BY f.course, f.id, d.id")) {
+        $rs = $DB->get_recordset_sql("SELECT p.id, p.attachment, p.userid, d.forum, f.course, cm.id AS cmid $sqlfrom ORDER BY f.course, f.id, d.id");
+        if ($rs->valid()) {
 
             $pbar = new progress_bar('migrateforumfiles', 500, true);
 
@@ -146,8 +147,8 @@ function xmldb_forum_upgrade($oldversion) {
                 @rmdir("$CFG->dataroot/$post->course/$CFG->moddata/forum/$post->forum");
                 @rmdir("$CFG->dataroot/$post->course/$CFG->moddata/forum");
             }
-            $rs->close();
         }
+        $rs->close();
 
         upgrade_mod_savepoint(true, 2008081900, 'forum');
     }
index 8ffaaa9..df7c7cd 100644 (file)
@@ -1504,7 +1504,8 @@ function forum_upgrade_grades() {
     $sql = "SELECT f.*, cm.idnumber AS cmidnumber, f.course AS courseid
               FROM {forum} f, {course_modules} cm, {modules} m
              WHERE m.name='forum' AND m.id=cm.module AND cm.instance=f.id";
-    if ($rs = $DB->get_recordset_sql($sql)) {
+    $rs = $DB->get_recordset_sql($sql);
+    if ($rs->valid()) {
         $pbar = new progress_bar('forumupgradegrades', 500, true);
         $i=0;
         foreach ($rs as $forum) {
@@ -1513,8 +1514,8 @@ function forum_upgrade_grades() {
             forum_update_grades($forum, 0, false);
             $pbar->update($i, $count, "Updating Forum grades ($i/$count).");
         }
-        $rs->close();
     }
+    $rs->close();
 }
 
 /**
@@ -7791,3 +7792,35 @@ class forum_existing_subscriber_selector extends forum_subscriber_selector_base
     }
 
 }
+
+/**
+ * Adds information about unread messages, that is only required for the course view page (and
+ * similar), to the course-module object.
+ * @param cm_info $cm Course-module object
+ */
+function forum_cm_info_view(cm_info $cm) {
+    global $CFG;
+
+    // Get tracking status (once per request)
+    static $initialised;
+    static $usetracking, $strunreadpostsone;
+    if (!isset($initialised)) {
+        if ($usetracking = forum_tp_can_track_forums()) {
+            $strunreadpostsone = get_string('unreadpostsone', 'forum');
+        }
+        $initialised = true;
+    }
+
+    if ($usetracking) {
+        if ($unread = forum_tp_count_forum_unread_posts($cm, $cm->get_course())) {
+            $out = '<span class="unread"> <a href="' . $cm->get_url() . '">';
+            if ($unread == 1) {
+                $out .= $strunreadpostsone;
+            } else {
+                $out .= get_string('unreadpostsnumber', 'forum', $unread);
+            }
+            $out .= '</a></span>';
+            $cm->set_after_link($out);
+        }
+    }
+}
index f6507cf..722bdf1 100644 (file)
@@ -45,7 +45,8 @@ function xmldb_glossary_upgrade($oldversion) {
 
         $count = $DB->count_records_sql("SELECT COUNT('x') $sqlfrom");
 
-        if ($rs = $DB->get_recordset_sql("SELECT ge.id, ge.userid, ge.attachment, ge.glossaryid, ge.sourceglossaryid, g.course, cm.id AS cmid $sqlfrom ORDER BY g.course, g.id")) {
+        $rs = $DB->get_recordset_sql("SELECT ge.id, ge.userid, ge.attachment, ge.glossaryid, ge.sourceglossaryid, g.course, cm.id AS cmid $sqlfrom ORDER BY g.course, g.id");
+        if ($rs->valid()) {
 
             $pbar = new progress_bar('migrateglossaryfiles', 500, true);
 
@@ -92,8 +93,8 @@ function xmldb_glossary_upgrade($oldversion) {
                 @rmdir("$CFG->dataroot/$entry->course/$CFG->moddata/glossary/$entry->glossaryid");
                 @rmdir("$CFG->dataroot/$entry->course/$CFG->moddata/glossary");
             }
-            $rs->close();
         }
+        $rs->close();
 
         upgrade_mod_savepoint(true, 2008081900, 'glossary');
     }
@@ -240,30 +241,30 @@ function xmldb_glossary_upgrade($oldversion) {
             $modcontext     = null;
 
         /// move glossary comments to comments table
-            if ($rs = $DB->get_recordset_sql($sql)) {
-                foreach($rs as $res) {
-                    if ($res->glossaryid != $lastglossaryid || $res->courseid != $lastcourseid) {
-                        $cm = get_coursemodule_from_instance('glossary', $res->glossaryid, $res->courseid);
-                        if ($cm) {
-                            $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
-                        }
-                        $lastglossaryid = $res->glossaryid;
-                        $lastcourseid   = $res->courseid;
-                    }
-                    $cmt = new stdClass();
-                    $cmt->contextid     = $modcontext->id;
-                    $cmt->commentarea   = 'glossary_entry';
-                    $cmt->itemid        = $res->itemid;
-                    $cmt->content       = $res->commentcontent;
-                    $cmt->format        = $res->format;
-                    $cmt->userid        = $res->userid;
-                    $cmt->timecreated    = $res->timemodified;
-                    $cmt_id = $DB->insert_record('comments', $cmt);
-                    if (!empty($cmt_id)) {
-                        $DB->delete_records('glossary_comments', array('id'=>$res->old_id));
+            $rs = $DB->get_recordset_sql($sql);
+            foreach($rs as $res) {
+                if ($res->glossaryid != $lastglossaryid || $res->courseid != $lastcourseid) {
+                    $cm = get_coursemodule_from_instance('glossary', $res->glossaryid, $res->courseid);
+                    if ($cm) {
+                        $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
                     }
+                    $lastglossaryid = $res->glossaryid;
+                    $lastcourseid   = $res->courseid;
+                }
+                $cmt = new stdClass();
+                $cmt->contextid     = $modcontext->id;
+                $cmt->commentarea   = 'glossary_entry';
+                $cmt->itemid        = $res->itemid;
+                $cmt->content       = $res->commentcontent;
+                $cmt->format        = $res->format;
+                $cmt->userid        = $res->userid;
+                $cmt->timecreated    = $res->timemodified;
+                $cmt_id = $DB->insert_record('comments', $cmt);
+                if (!empty($cmt_id)) {
+                    $DB->delete_records('glossary_comments', array('id'=>$res->old_id));
                 }
             }
+            $rs->close();
             $dbman->drop_table($table);
         }
 
index 858093a..498036b 100644 (file)
@@ -506,7 +506,8 @@ function glossary_upgrade_grades() {
     $sql = "SELECT g.*, cm.idnumber AS cmidnumber, g.course AS courseid
               FROM {glossary} g, {course_modules} cm, {modules} m
              WHERE m.name='glossary' AND m.id=cm.module AND cm.instance=g.id";
-    if ($rs = $DB->get_recordset_sql($sql)) {
+    $rs = $DB->get_recordset_sql($sql);
+    if ($rs->valid()) {
         $pbar = new progress_bar('glossaryupgradegrades', 500, true);
         $i=0;
         foreach ($rs as $glossary) {
@@ -515,8 +516,8 @@ function glossary_upgrade_grades() {
             glossary_update_grades($glossary, 0, false);
             $pbar->update($i, $count, "Updating Glossary grades ($i/$count).");
         }
-        $rs->close();
     }
+    $rs->close();
 }
 
 /**
@@ -2462,7 +2463,8 @@ function glossary_reset_userdata($data) {
 
         $course_context = get_context_instance(CONTEXT_COURSE, $data->courseid);
         $notenrolled = array();
-        if ($rs = $DB->get_recordset_sql($entriessql, $params)) {
+        $rs = $DB->get_recordset_sql($entriessql, $params);
+        if ($rs->valid()) {
             foreach ($rs as $entry) {
                 if (array_key_exists($entry->userid, $notenrolled) or !$entry->userexists or $entry->userdeleted
                   or !is_enrolled($course_context , $entry->userid)) {
@@ -2479,9 +2481,9 @@ function glossary_reset_userdata($data) {
                     }
                 }
             }
-            $rs->close();
             $status[] = array('component'=>$componentstr, 'item'=>get_string('deletenotenrolled', 'glossary'), 'error'=>false);
         }
+        $rs->close();
     }
 
     // remove all ratings
index e905f39..5138318 100644 (file)
@@ -49,7 +49,9 @@ function imscp_20_migrate() {
         return;
     }
 
-    if (!$candidates = $DB->get_recordset('resource_old', array('type'=>'ims', 'migrated'=>0))) {
+    $candidates = $DB->get_recordset('resource_old', array('type'=>'ims', 'migrated'=>0));
+    if (!$candidates->valid()) {
+        $candidates->close(); // Not going to iterate (but exit), close rs
         return;
     }
 
@@ -133,7 +135,6 @@ function imscp_20_migrate() {
             fulldelete($root);
         }
     }
-
     $candidates->close();
 
     // clear all course modinfo caches
index 1f77822..2e21e13 100644 (file)
@@ -209,6 +209,7 @@ function label_supports($feature) {
         case FEATURE_GRADE_OUTCOMES:          return false;
         case FEATURE_MOD_ARCHETYPE:           return MOD_ARCHETYPE_RESOURCE;
         case FEATURE_BACKUP_MOODLE2:          return true;
+        case FEATURE_NO_VIEW_LINK:            return true;
 
         default: return null;
     }
index 3bfaa41..ed5a0a0 100644 (file)
@@ -429,7 +429,8 @@ function lesson_upgrade_grades() {
     $sql = "SELECT l.*, cm.idnumber AS cmidnumber, l.course AS courseid
               FROM {lesson} l, {course_modules} cm, {modules} m
              WHERE m.name='lesson' AND m.id=cm.module AND cm.instance=l.id";
-    if ($rs = $DB->get_recordset_sql($sql)) {
+    $rs = $DB->get_recordset_sql($sql);
+    if ($rs->valid()) {
         $pbar = new progress_bar('lessonupgradegrades', 500, true);
         $i=0;
         foreach ($rs as $lesson) {
@@ -438,8 +439,8 @@ function lesson_upgrade_grades() {
             lesson_update_grades($lesson, 0, false);
             $pbar->update($i, $count, "Updating Lesson grades ($i/$count).");
         }
-        $rs->close();
     }
+    $rs->close();
 }
 
 /**
index 3a159b6..3ffeb7a 100644 (file)
@@ -51,24 +51,22 @@ function page_20_migrate() {
 
     $fs = get_file_storage();
 
-    if ($candidates = $DB->get_recordset('resource_old', array('type'=>'html', 'migrated'=>0))) {
-        foreach ($candidates as $candidate) {
-            page_20_migrate_candidate($candidate, $fs, FORMAT_HTML);
-        }
-        $candidates->close();
+    $candidates = $DB->get_recordset('resource_old', array('type'=>'html', 'migrated'=>0));
+    foreach ($candidates as $candidate) {
+        page_20_migrate_candidate($candidate, $fs, FORMAT_HTML);
     }
-
-    if ($candidates = $DB->get_recordset('resource_old', array('type'=>'text', 'migrated'=>0))) {
-        foreach ($candidates as $candidate) {
-            //there might be some rubbish instead of format int value
-            $format = (int)$candidate->reference;
-            if ($format < 0 or $format > 4) {
-                $format = FORMAT_MOODLE;
-            }
-            page_20_migrate_candidate($candidate, $fs, $format);
+    $candidates->close();
+
+    $candidates = $DB->get_recordset('resource_old', array('type'=>'text', 'migrated'=>0));
+    foreach ($candidates as $candidate) {
+        //there might be some rubbish instead of format int value
+        $format = (int)$candidate->reference;
+        if ($format < 0 or $format > 4) {
+            $format = FORMAT_MOODLE;
         }
-        $candidates->close();
+        page_20_migrate_candidate($candidate, $fs, $format);
     }
+    $candidates->close();
 
     // clear all course modinfo caches
     rebuild_course_cache(0, true);
index 7580482..9039f25 100644 (file)
@@ -375,14 +375,14 @@ class quiz {
         $this->pagequestionids = array();
 
         // Get the appropriate layout string (from quiz or attempt).
-        $layout = $this->get_layout_string();
+        $layout = quiz_clean_layout($this->get_layout_string(), true);
         if (empty($layout)) {
             // Nothing to do.
             return;
         }
 
         // Break up the layout string into pages.
-        $pagelayouts = explode(',0', quiz_clean_layout($layout, true));
+        $pagelayouts = explode(',0', $layout);
 
         // Strip off any empty last page (normally there is one).
         if (end($pagelayouts) == '') {
@@ -536,7 +536,7 @@ class quiz_attempt extends quiz {
     public function load_specific_question_state($questionid, $stateid) {
         global $DB;
         $state = question_load_specific_state($this->questions[$questionid],
-                $this->quiz, $this->attempt, $stateid);
+                $this->quiz, $this->attempt->uniqueid, $stateid);
         if ($state === false) {
             throw new moodle_quiz_exception($this, 'invalidstateid');
         }
index 66b1d94..ea8da3a 100644 (file)
@@ -2,9 +2,11 @@
 /**
  * This page allows the teacher to enter a manual grade for a particular question.
  * This page is expected to only be used in a popup window.
- *  *
+ *
+ * @package mod
+ * @subpackage quiz
+ * @copyright gustav delius 2006
  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package quiz
  */
 
     require_once('../../config.php');
@@ -61,7 +63,7 @@
     $attemptobj->question_print_comment_fields($questionid, 'response');
 ?>
 <div>
-    <input type="hidden" name="attempt" value="<?php echo $attemptobj->get_uniqueid(); ?>" />
+    <input type="hidden" name="attempt" value="<?php echo $attemptobj->get_attemptid(); ?>" />
     <input type="hidden" name="question" value="<?php echo $questionid; ?>" />
     <input type="hidden" name="sesskey" value="<?php echo sesskey(); ?>" />
 </div>
index a38e4c9..28c59c6 100644 (file)
@@ -116,50 +116,56 @@ function xmldb_quiz_upgrade($oldversion) {
 
     /// Changing the type of all the columns that store grades to be NUMBER(10, 5) or similar.
     if ($oldversion < 2008081501) {
+        // First set all quiz.sumgrades to 0 if they are null. This should never
+        // happen however some users have encountered a null value there.
+        $DB->execute('UPDATE {quiz} SET sumgrades=0 WHERE sumgrades IS NULL');
         $table = new xmldb_table('quiz');
-        $field = new xmldb_field('sumgrades', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, 'questions');
+        $field = new xmldb_field('sumgrades', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'questions');
         $dbman->change_field_type($table, $field);
         upgrade_mod_savepoint(true, 2008081501, 'quiz');
     }
 
     if ($oldversion < 2008081502) {
         $table = new xmldb_table('quiz');
-        $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, 'sumgrades');
+        $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0', 'sumgrades');
         $dbman->change_field_type($table, $field);
         upgrade_mod_savepoint(true, 2008081502, 'quiz');