diff --git a/admin/roles/lib.php b/admin/roles/lib.php
index 3e9624eece2..7fc5782eb2d 100644
--- a/admin/roles/lib.php
+++ b/admin/roles/lib.php
@@ -1316,6 +1316,7 @@ abstract class role_allow_role_page {
foreach ($rs as $allow) {
$this->allowed[$allow->roleid][$allow->{$this->targetcolname}] = true;
}
+ $rs->close();
}
/**
diff --git a/backup/util/xml/parser/processors/grouped_parser_processor.class.php b/backup/util/xml/parser/processors/grouped_parser_processor.class.php
index ca5d3f494ff..46391e62975 100644
--- a/backup/util/xml/parser/processors/grouped_parser_processor.class.php
+++ b/backup/util/xml/parser/processors/grouped_parser_processor.class.php
@@ -70,16 +70,6 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
parent::add_path($path);
}
- /**
- * Notify start of path if selected and not under grouped
- */
- public function before_path($path) {
- if ($this->path_is_selected($path) && !$this->grouped_parent_exists($path)) {
- parent::before_path($path);
- }
- }
-
-
/**
* Dispatch grouped chunks safely once their end tag happens.
* Also notify end of path if selected and not under grouped
@@ -110,6 +100,7 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
$path = $data['path'];
// If the chunk is a grouped one, simply put it into currentdata
if ($this->path_is_grouped($path)) {
+ $this->notify_path_start($path);
$this->currentdata[$path] = $data;
// If the chunk is child of grouped one, add it to currentdata
@@ -119,6 +110,7 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
// No grouped nor child of grouped, dispatch it
} else {
+ $this->notify_path_start($path);
$this->dispatch_chunk($data);
}
}
diff --git a/backup/util/xml/parser/processors/simplified_parser_processor.class.php b/backup/util/xml/parser/processors/simplified_parser_processor.class.php
index e4432af9b48..0544b436445 100644
--- a/backup/util/xml/parser/processors/simplified_parser_processor.class.php
+++ b/backup/util/xml/parser/processors/simplified_parser_processor.class.php
@@ -149,15 +149,6 @@ abstract class simplified_parser_processor extends progressive_parser_processor
return true;
}
- /**
- * The parser fires this each time one path is going to be parsed
- */
- public function before_path($path) {
- if ($this->path_is_selected($path)) {
- $this->notify_path_start($path);
- }
- }
-
/**
* The parser fires this each time one path has been parsed
*/
@@ -170,6 +161,7 @@ abstract class simplified_parser_processor extends progressive_parser_processor
// Protected API starts here
protected function postprocess_chunk($data) {
+ $this->notify_path_start($data['path']);
$this->dispatch_chunk($data);
}
diff --git a/backup/util/xml/parser/simpletest/testparser.php b/backup/util/xml/parser/simpletest/testparser.php
index eccc2c44741..02983041833 100644
--- a/backup/util/xml/parser/simpletest/testparser.php
+++ b/backup/util/xml/parser/simpletest/testparser.php
@@ -330,6 +330,13 @@ class progressive_parser_test extends UnitTestCase {
sort($snotifs);
sort($enotifs);
$this->assertEqual($snotifs, $enotifs);
+
+ // Now verify that the start/process/end order is correct
+ $allnotifs = $pr->get_all_notifications();
+ $this->assertEqual(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks)); // The count
+ // Check integrity of the notifications
+ $errcount = $this->helper_check_notifications_order_integrity($allnotifs);
+ $this->assertEqual($errcount, 0); // No errors found, plz
}
/*
@@ -498,6 +505,67 @@ class progressive_parser_test extends UnitTestCase {
sort($snotifs);
sort($enotifs);
$this->assertEqual($snotifs, $enotifs);
+
+ // Now verify that the start/process/end order is correct
+ $allnotifs = $pr->get_all_notifications();
+ $this->assertEqual(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks)); // The count
+ // Check integrity of the notifications
+ $errcount = $this->helper_check_notifications_order_integrity($allnotifs);
+ $this->assertEqual($errcount, 0); // No errors found, plz
+ }
+
+ /**
+ * Helper function that given one array of ordered start/process/end notifications will
+ * check it of integrity like:
+ * - process only happens if start is the previous notification
+ * - end only happens if dispatch is the previous notification
+ * - start only happen with level > than last one and if there is no already started like that
+ *
+ * @param array $notifications ordered array of notifications with format [start|process|end]:path
+ * @return int number of integrity problems found (errors)
+ */
+ function helper_check_notifications_order_integrity($notifications) {
+ $numerrors = 0;
+ $notifpile = array('pilebase' => 'start');
+ $lastpile = 'start:pilebase';
+ foreach ($notifications as $notif) {
+ $lastpilelevel = strlen(preg_replace('/[^\/]/', '', $lastpile));
+ $lastpiletype = preg_replace('/:.*/', '', $lastpile);
+ $lastpilepath = preg_replace('/.*:/', '', $lastpile);
+
+ $notiflevel = strlen(preg_replace('/[^\/]/', '', $notif));
+ $notiftype = preg_replace('/:.*/', '', $notif);
+ $notifpath = preg_replace('/.*:/', '', $notif);
+
+ switch ($notiftype) {
+ case 'process':
+ if ($lastpilepath != $notifpath or $lastpiletype != 'start') {
+ $numerrors++; // Only start for same path is allowed before process
+ }
+ $notifpile[$notifpath] = 'process'; // Update the status in the pile
+ break;
+ case 'end':
+ if ($lastpilepath != $notifpath or $lastpiletype != 'process') {
+ $numerrors++; // Only process for same path is allowed before end
+ }
+ unset($notifpile[$notifpath]); // Delete from the pile
+ break;
+ case 'start':
+ if (array_key_exists($notifpath, $notifpile) or $notiflevel <= $lastpilelevel) {
+ $numerrors++; // If same path exists or the level is < than the last one
+ }
+ $notifpile[$notifpath] = 'start'; // Add to the pile
+ break;
+ default:
+ $numerrors++; // Incorrect type of notification => error
+ }
+ // Update lastpile
+ end($notifpile);
+ $path = key($notifpile);
+ $type = $notifpile[$path];
+ $lastpile = $type. ':' . $path;
+ }
+ return $numerrors;
}
}
@@ -572,17 +640,21 @@ class mock_simplified_parser_processor extends simplified_parser_processor {
private $chunksarr = array(); // To accumulate the found chunks
private $startarr = array(); // To accumulate all the notified path starts
private $endarr = array(); // To accumulate all the notified path ends
+ private $allnotif = array(); // To accumulate all the notified and dispatched events in an ordered way
public function dispatch_chunk($data) {
$this->chunksarr[] = $data;
+ $this->allnotif[] = 'process:' . $data['path'];
}
public function notify_path_start($path) {
$this->startarr[] = $path;
+ $this->allnotif[] = 'start:' . $path;
}
public function notify_path_end($path) {
$this->endarr[] = $path;
+ $this->allnotif[] = 'end:' . $path;
}
public function get_chunks() {
@@ -596,6 +668,10 @@ class mock_simplified_parser_processor extends simplified_parser_processor {
public function get_end_notifications() {
return $this->endarr;
}
+
+ public function get_all_notifications() {
+ return $this->allnotif;
+ }
}
/*
@@ -606,17 +682,21 @@ class mock_grouped_parser_processor extends grouped_parser_processor {
private $chunksarr = array(); // To accumulate the found chunks
private $startarr = array(); // To accumulate all the notified path starts
private $endarr = array(); // To accumulate all the notified path ends
+ private $allnotif = array(); // To accumulate all the notified and dispatched events in an ordered way
public function dispatch_chunk($data) {
$this->chunksarr[] = $data;
+ $this->allnotif[] = 'process:' . $data['path'];
}
public function notify_path_start($path) {
$this->startarr[] = $path;
+ $this->allnotif[] = 'start:' . $path;
}
public function notify_path_end($path) {
$this->endarr[] = $path;
+ $this->allnotif[] = 'end:' . $path;
}
public function get_chunks() {
@@ -630,4 +710,8 @@ class mock_grouped_parser_processor extends grouped_parser_processor {
public function get_end_notifications() {
return $this->endarr;
}
+
+ public function get_all_notifications() {
+ return $this->allnotif;
+ }
}
diff --git a/calendar/export_execute.php b/calendar/export_execute.php
index 3fe48f14f44..bfda4578521 100644
--- a/calendar/export_execute.php
+++ b/calendar/export_execute.php
@@ -13,7 +13,7 @@ if (empty($CFG->enablecalendarexport)) {
}
//Fetch user information
-if (!$user = get_complete_user_data('username', $username)) {
+if (!$user = $DB->get_record('user', array('username' => $username), 'id,password')) {
//No such user
die('Invalid authentication');
}
diff --git a/comment/lib.php b/comment/lib.php
index 2bf59795394..184e320f569 100644
--- a/comment/lib.php
+++ b/comment/lib.php
@@ -127,16 +127,14 @@ class comment {
*/
protected $totalcommentcount = null;
/**
- * By default a user must have the generic comment capabilities plus any capabilities the
- * component being commented on requires.
- * When set to true only the component capabilities are checked, the system capabilities are
- * ignored.
- * This can be toggled by the component defining a callback in its lib.php e.g.
- * function forum_comment_allow_anonymous_access(comment $comment) {}
- * Note: On the front page this defaults to true.
+ * When set to true any user to the system is able to view comments.
+ *
+ * This can be set to true by a plugin by implementing a allow_anonymous_access callback.
+ * By default it is false except on the front page.
+ *
* @var bool
*/
- protected $ignoresystempermissions = false;
+ protected $allowanonymousaccess = false;
/**#@+
* static variable will be used by non-js comments UI
diff --git a/lib/xhprof/xhprof_moodle.php b/lib/xhprof/xhprof_moodle.php
index 853e5f50d3b..28c41f30065 100644
--- a/lib/xhprof/xhprof_moodle.php
+++ b/lib/xhprof/xhprof_moodle.php
@@ -152,7 +152,7 @@ function profiling_start() {
* Stop profiling, gathering results and storing them
*/
function profiling_stop() {
- global $CFG, $SCRIPT;
+ global $CFG, $DB, $SCRIPT;
// If profiling isn't available, nothing to stop
if (!extension_loaded('xhprof') || !function_exists('xhprof_enable')) {
@@ -176,6 +176,14 @@ function profiling_stop() {
profiling_is_running(false);
$data = xhprof_disable();
+ // We only save the run after ensuring the DB table exists
+ // (this prevents problems with profiling runs enabled in
+ // config.php before Moodle is installed. Rare but...
+ $tables = $DB->get_tables();
+ if (!in_array('profiling', $tables)) {
+ return false;
+ }
+
$run = new moodle_xhprofrun();
$run->prepare_run($script);
$runid = $run->save_run($data, null);
diff --git a/message/lib.php b/message/lib.php
index 280542aba8f..611abc88c36 100644
--- a/message/lib.php
+++ b/message/lib.php
@@ -200,6 +200,8 @@ function message_get_blocked_users($user1=null, $user2=null) {
$user2->isblocked = false;
}
+ $blockedusers = array();
+
$userfields = user_picture::fields('u', array('lastaccess'));
$blockeduserssql = "SELECT $userfields, COUNT(m.id) AS messagecount
FROM {message_contacts} mc
@@ -210,18 +212,14 @@ function message_get_blocked_users($user1=null, $user2=null) {
ORDER BY u.firstname ASC";
$rs = $DB->get_recordset_sql($blockeduserssql, array('user1id1' => $user1->id, 'user1id2' => $user1->id));
- $blockedusers = array();
- if (!empty($rs)) {
- foreach($rs as $rd) {
- $blockedusers[] = $rd;
+ foreach($rs as $rd) {
+ $blockedusers[] = $rd;
- if (!empty($user2) && $user2->id == $rd->id) {
- $user2->isblocked = true;
- }
+ if (!empty($user2) && $user2->id == $rd->id) {
+ $user2->isblocked = true;
}
- unset($rd);
- $rs->close();
}
+ $rs->close();
return $blockedusers;
}
@@ -2129,6 +2127,8 @@ function message_mark_messages_read($touserid, $fromuserid){
foreach ($messages as $message) {
message_mark_message_read($message, time());
}
+
+ $messages->close();
}
/**
diff --git a/mod/assignment/lang/en/assignment.php b/mod/assignment/lang/en/assignment.php
index b56aa8e525f..9540c4d6a0a 100644
--- a/mod/assignment/lang/en/assignment.php
+++ b/mod/assignment/lang/en/assignment.php
@@ -144,12 +144,13 @@ $string['noblogs'] = 'You have no blog entries to submit!';
$string['nofiles'] = 'No files were submitted';
$string['nofilesyet'] = 'No files submitted yet';
$string['nomoresubmissions'] = 'No further submissions are allowed.';
-$string['nosubmitusers'] = 'No users were found with permissions to submit this assignment';
$string['notavailableyet'] = 'Sorry, this assignment is not yet available. Assignment instructions will be displayed here on the date given below.';
$string['notes'] = 'Notes';
$string['notesempty'] = 'No entry';
$string['notesupdateerror'] = 'Error when updating notes';
$string['notgradedyet'] = 'Not graded yet';
+$string['norequiregrading'] = 'There are no assignments that require grading';
+$string['nosubmisson'] = 'No assignments have been submit';
$string['notsubmittedyet'] = 'Not submitted yet';
$string['onceassignmentsent'] = 'Once the assignment is sent for marking, you will no longer be able to delete or attach file(s). Do you want to continue?';
$string['operation'] = 'Operation';
diff --git a/mod/assignment/lib.php b/mod/assignment/lib.php
index c27ca95d50b..c681a3c57b5 100644
--- a/mod/assignment/lib.php
+++ b/mod/assignment/lib.php
@@ -1128,6 +1128,7 @@ class assignment_base {
$course = $this->course;
$assignment = $this->assignment;
$cm = $this->cm;
+ $hassubmission = false;
$tabindex = 1; //tabindex for quick grading tabbing; Not working for dropdowns yet
add_to_log($course->id, 'assignment', 'view submission', 'submissions.php?id='.$this->cm->id, $this->assignment->id, $this->cm->id);
@@ -1264,16 +1265,7 @@ class assignment_base {
// Start working -- this is necessary as soon as the niceties are over
$table->setup();
- if (empty($users)) {
- echo $OUTPUT->heading(get_string('nosubmitusers','assignment'));
- echo '';
- return true;
- }
- if ($this->assignment->assignmenttype=='upload' || $this->assignment->assignmenttype=='online' || $this->assignment->assignmenttype=='uploadsingle') { //TODO: this is an ugly hack, where is the plugin spirit? (skodak)
- echo '
';
+ }
+ ///Print grade, dropdown or text
+ if ($auser->timemarked > 0) {
+ $teachermodified = '
'.userdate($auser->timemarked).'
';
- if (!empty($auser->submissionid)) {
- ///Prints student answer and student modified date
- ///attach file or print link to student answer, depending on the type of the assignment.
- ///Refer to print_student_answer in inherited classes.
- if ($auser->timemodified > 0) {
- $studentmodified = '