Skip to content
Permalink
Browse files

Merge branch 'MOODLE_24_STABLE' into install_24_STABLE

  • Loading branch information...
AMOS bot
AMOS bot committed Aug 24, 2013
2 parents 26af11e + abb7671 commit a8416f35c5d01bf66118289140bb88422833cc6e
@@ -113,31 +113,46 @@
// Mark the UI finished.
$rc->finish_ui();
// Execute prechecks
$warnings = false;
if (!$rc->execute_precheck()) {
$precheckresults = $rc->get_precheck_results();
if (is_array($precheckresults) && !empty($precheckresults['errors'])) {
fulldelete($tempdestination);
echo $OUTPUT->header();
echo $renderer->precheck_notices($precheckresults);
echo $OUTPUT->continue_button(new moodle_url('/course/view.php', array('id'=>$course->id)));
echo $OUTPUT->footer();
die();
if (is_array($precheckresults)) {
if (!empty($precheckresults['errors'])) { // If errors are found, terminate the import.
fulldelete($tempdestination);
echo $OUTPUT->header();
echo $renderer->precheck_notices($precheckresults);
echo $OUTPUT->continue_button(new moodle_url('/course/view.php', array('id'=>$course->id)));
echo $OUTPUT->footer();
die();
}
if (!empty($precheckresults['warnings'])) { // If warnings are found, go ahead but display warnings later.
$warnings = $precheckresults['warnings'];
}
}
} else {
if ($restoretarget == backup::TARGET_CURRENT_DELETING || $restoretarget == backup::TARGET_EXISTING_DELETING) {
restore_dbops::delete_course_content($course->id);
}
// Execute the restore
$rc->execute_plan();
}
if ($restoretarget == backup::TARGET_CURRENT_DELETING || $restoretarget == backup::TARGET_EXISTING_DELETING) {
restore_dbops::delete_course_content($course->id);
}
// Execute the restore.
$rc->execute_plan();
// Delete the temp directory now
fulldelete($tempdestination);
// Display a notification and a continue button
echo $OUTPUT->header();
echo $OUTPUT->notification(get_string('importsuccess', 'backup'),'notifysuccess');
if ($warnings) {
echo $OUTPUT->box_start();
echo $OUTPUT->notification(get_string('warning'), 'notifywarning');
echo html_writer::start_tag('ul', array('class'=>'list'));
foreach ($warnings as $warning) {
echo html_writer::tag('li', $warning);
}
echo html_writer::end_tag('ul');
echo $OUTPUT->box_end();
}
echo $OUTPUT->notification(get_string('importsuccess', 'backup'), 'notifysuccess');
echo $OUTPUT->continue_button(new moodle_url('/course/view.php', array('id'=>$course->id)));
echo $OUTPUT->footer();
@@ -35,6 +35,18 @@
*/
abstract class restore_qtype_plugin extends restore_plugin {
/*
* A simple answer to id cache for a single questions answers.
* @var array
*/
private $questionanswercache = array();
/*
* The id of the current question in the questionanswercache.
* @var int
*/
private $questionanswercacheid = null;
/**
* Add to $paths the restore_path_elements needed
* to handle question_answers for a given question
@@ -147,38 +159,32 @@ public function process_question_answer($data) {
// The question existed, we need to map the existing question_answers
} else {
// Look in question_answers by answertext matching
$sql = 'SELECT id
FROM {question_answers}
WHERE question = ?
AND ' . $DB->sql_compare_text('answer', 255) . ' = ' . $DB->sql_compare_text('?', 255);
$params = array($newquestionid, $data->answertext);
$newitemid = $DB->get_field_sql($sql, $params);
// Not able to find the answer, let's try cleaning the answertext
// of all the question answers in DB as slower fallback. MDL-30018.
if (!$newitemid) {
// Have we cached the current question?
if ($this->questionanswercacheid !== $newquestionid) {
// The question changed, purge and start again!
$this->questionanswercache = array();
$params = array('question' => $newquestionid);
$answers = $DB->get_records('question_answers', $params, '', 'id, answer');
$this->questionanswercacheid = $newquestionid;
// Cache all cleaned answers for a simple text match.
foreach ($answers as $answer) {
// Clean in the same way than {@link xml_writer::xml_safe_utf8()}.
// MDL-30018: Clean in the same way as {@link xml_writer::xml_safe_utf8()}.
$clean = preg_replace('/[\x-\x8\xb-\xc\xe-\x1f\x7f]/is','', $answer->answer); // Clean CTRL chars.
$clean = preg_replace("/\r\n|\r/", "\n", $clean); // Normalize line ending.
if ($clean === $data->answertext) {
$newitemid = $data->id;
}
$this->questionanswercache[$clean] = $answer->id;
}
}
// If we haven't found the newitemid, something has gone really wrong, question in DB
// is missing answers, exception
if (!$newitemid) {
if (!isset($this->questionanswercache[$data->answertext])) {
// If we haven't found the matching answer, something has gone really wrong, the question in the DB
// is missing answers, throw an exception.
$info = new stdClass();
$info->filequestionid = $oldquestionid;
$info->dbquestionid = $newquestionid;
$info->answer = $data->answertext;
throw new restore_step_exception('error_question_answers_missing_in_db', $info);
}
$newitemid = $this->questionanswercache[$data->answertext];
}
// Create mapping (we'll use this intensively when restoring question_states. And also answerfeedback files)
$this->set_mapping('question_answer', $oldid, $newitemid);
@@ -0,0 +1,71 @@
<?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/>.
/**
* Calendar lib unit tests
*
* @package core_calendar
* @copyright 2013 Dan Poltawski <dan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/calendar/lib.php');
/**
* Unit tests for calendar lib
*
* @package core_calendar
* @copyright 2013 Dan Poltawski <dan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class core_calendar_lib_testcase extends advanced_testcase {
public function test_calendar_get_course_cached() {
$this->resetAfterTest(true);
// Setup some test courses.
$course1 = $this->getDataGenerator()->create_course();
$course2 = $this->getDataGenerator()->create_course();
$course3 = $this->getDataGenerator()->create_course();
// Load courses into cache.
$coursecache = null;
calendar_get_course_cached($coursecache, $course1->id);
calendar_get_course_cached($coursecache, $course2->id);
calendar_get_course_cached($coursecache, $course3->id);
// Verify the cache.
$this->assertArrayHasKey($course1->id, $coursecache);
$cachedcourse1 = $coursecache[$course1->id];
$this->assertEquals($course1->id, $cachedcourse1->id);
$this->assertEquals($course1->shortname, $cachedcourse1->shortname);
$this->assertEquals($course1->fullname, $cachedcourse1->fullname);
$this->assertArrayHasKey($course2->id, $coursecache);
$cachedcourse2 = $coursecache[$course2->id];
$this->assertEquals($course2->id, $cachedcourse2->id);
$this->assertEquals($course2->shortname, $cachedcourse2->shortname);
$this->assertEquals($course2->fullname, $cachedcourse2->fullname);
$this->assertArrayHasKey($course3->id, $coursecache);
$cachedcourse3 = $coursecache[$course3->id];
$this->assertEquals($course3->id, $cachedcourse3->id);
$this->assertEquals($course3->shortname, $cachedcourse3->shortname);
$this->assertEquals($course3->fullname, $cachedcourse3->fullname);
}
}
@@ -487,7 +487,10 @@
// $CFG->debugusers = '2';
//
// Prevent theme caching
// $CFG->themerev = -1; // NOT FOR PRODUCTION SERVERS!
// $CFG->themedesignermode = true; // NOT FOR PRODUCTION SERVERS!
//
// Prevent JS caching
// $CFG->cachejs = false; // NOT FOR PRODUCTION SERVERS!
//
// Prevent core_string_manager on-disk cache
// $CFG->langstringcache = false; // NOT FOR PRODUCTION SERVERS!
@@ -1159,7 +1159,9 @@ function get_array_of_activities($courseid) {
$mod[$seq]->extraclasses = $info->extraclasses;
}
if (!empty($info->iconurl)) {
$mod[$seq]->iconurl = $info->iconurl;
// Convert URL to string as it's easier to store. Also serialized object contains \0 byte and can not be written to Postgres DB.
$url = new moodle_url($info->iconurl);
$mod[$seq]->iconurl = $url->out(false);
}
if (!empty($info->onclick)) {
$mod[$seq]->onclick = $info->onclick;
@@ -121,8 +121,8 @@ protected function process_file() {
continue;
}
if (! $user = $DB->get_record("user", array("idnumber"=>$fields[2]))) {
$this->log .= "Unknown user idnumber in field 3 - ignoring line\n";
if (! $user = $DB->get_record("user", array("idnumber"=>$fields[2], 'deleted'=>0))) {
$this->log .= "Unknown user idnumber or deleted user in field 3 - ignoring line\n";
continue;
}
@@ -250,4 +250,33 @@ public function test_enrol_user_sees_own_courses() {
$this->assertTrue(enrol_user_sees_own_courses());
$this->assertEquals($reads, $DB->perf_get_reads());
}
public function test_enrol_get_shared_courses() {
$this->resetAfterTest();
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
$user3 = $this->getDataGenerator()->create_user();
$course1 = $this->getDataGenerator()->create_course();
$this->getDataGenerator()->enrol_user($user1->id, $course1->id);
$this->getDataGenerator()->enrol_user($user2->id, $course1->id);
$course2 = $this->getDataGenerator()->create_course();
$this->getDataGenerator()->enrol_user($user1->id, $course2->id);
// Test that user1 and user2 have courses in common.
$this->assertTrue(enrol_get_shared_courses($user1, $user2, false, true));
// Test that user1 and user3 have no courses in common.
$this->assertFalse(enrol_get_shared_courses($user1, $user3, false, true));
// Test retrieving the courses in common.
$sharedcourses = enrol_get_shared_courses($user1, $user2, true);
// Only should be one shared course.
$this->assertCount(1, $sharedcourses);
$sharedcourse = array_shift($sharedcourses);
// It should be course 1.
$this->assertEquals($sharedcourse->id, $course1->id);
}
}
@@ -1218,7 +1218,7 @@ public function sql_length($fieldname) {
}
public function sql_order_by_text($fieldname, $numchars=32) {
return ' CONVERT(varchar, ' . $fieldname . ', ' . $numchars . ')';
return " CONVERT(varchar({$numchars}), {$fieldname})";
}
/**
@@ -1281,7 +1281,7 @@ public function sql_length($fieldname) {
}
public function sql_order_by_text($fieldname, $numchars = 32) {
return ' CONVERT(varchar, '.$fieldname.', '.$numchars.')';
return " CONVERT(varchar({$numchars}), {$fieldname})";
}
/**
@@ -3573,7 +3573,7 @@ function test_cast_char2real() {
$this->assertEquals(next($records)->nametext, '91.10');
}
function sql_compare_text() {
public function test_sql_compare_text() {
$DB = $this->tdb;
$dbman = $DB->get_manager();
@@ -3588,15 +3588,43 @@ function sql_compare_text() {
$DB->insert_record($tablename, array('name'=>'abcd', 'description'=>'abcd'));
$DB->insert_record($tablename, array('name'=>'abcdef', 'description'=>'bbcdef'));
$DB->insert_record($tablename, array('name'=>'aaaabb', 'description'=>'aaaacccccccccccccccccc'));
$DB->insert_record($tablename, array('name'=>'aaaa', 'description'=>'aaaacccccccccccccccccc'));
$DB->insert_record($tablename, array('name'=>'xxxx', 'description'=>'123456789a123456789b123456789c123456789d'));
// Only some supported databases truncate TEXT fields for comparisons, currently MSSQL and Oracle.
$dbtruncatestextfields = ($DB->get_dbfamily() == 'mssql' || $DB->get_dbfamily() == 'oracle');
if ($dbtruncatestextfields) {
// Ensure truncation behaves as expected.
$sql = "SELECT " . $DB->sql_compare_text('description') . " AS field FROM {{$tablename}} WHERE name = ?";
$description = $DB->get_field_sql($sql, array('xxxx'));
// Should truncate to 32 chars (the default).
$this->assertEquals('123456789a123456789b123456789c12', $description);
$sql = "SELECT " . $DB->sql_compare_text('description', 35) . " AS field FROM {{$tablename}} WHERE name = ?";
$description = $DB->get_field_sql($sql, array('xxxx'));
// Should truncate to the specified number of chars.
$this->assertEquals('123456789a123456789b123456789c12345', $description);
}
// Ensure text field comparison is successful.
$sql = "SELECT * FROM {{$tablename}} WHERE name = ".$DB->sql_compare_text('description');
$records = $DB->get_records_sql($sql);
$this->assertEquals(count($records), 1);
$this->assertCount(1, $records);
$sql = "SELECT * FROM {{$tablename}} WHERE name = ".$DB->sql_compare_text('description', 4);
$records = $DB->get_records_sql($sql);
$this->assertEquals(count($records), 2);
if ($dbtruncatestextfields) {
// Should truncate description to 4 characters before comparing.
$this->assertCount(2, $records);
} else {
// Should leave untruncated, so one less match.
$this->assertCount(1, $records);
}
}
function test_unique_index_collation_trouble() {
@@ -1952,18 +1952,23 @@ function qf_errorHandler(element, _qfMsg) {
errorSpan.id = \'id_error_\'+element.name;
errorSpan.className = "error";
element.parentNode.insertBefore(errorSpan, element.parentNode.firstChild);
document.getElementById(errorSpan.id).setAttribute(\'TabIndex\', \'0\');
document.getElementById(errorSpan.id).focus();
}
while (errorSpan.firstChild) {
errorSpan.removeChild(errorSpan.firstChild);
}
errorSpan.appendChild(document.createTextNode(_qfMsg.substring(3)));
errorSpan.appendChild(document.createElement("br"));
if (div.className.substr(div.className.length - 6, 6) != " error"
&& div.className != "error") {
div.className += " error";
&& div.className != "error") {
div.className += " error";
linebreak = document.createElement("br");
linebreak.className = "error";
linebreak.id = \'id_error_break_\'+element.name;
errorSpan.parentNode.insertBefore(linebreak, errorSpan.nextSibling);
}
return false;
@@ -1972,6 +1977,10 @@ function qf_errorHandler(element, _qfMsg) {
if (errorSpan) {
errorSpan.parentNode.removeChild(errorSpan);
}
var linebreak = document.getElementById(\'id_error_break_\'+element.name);
if (linebreak) {
linebreak.parentNode.removeChild(linebreak);
}
if (div.className.substr(div.className.length - 6, 6) == " error") {
div.className = div.className.substr(0, div.className.length - 6);
@@ -2019,7 +2028,7 @@ function validate_' . $this->_formName . '_' . $escapedElementName . '(element)
ret = validate_' . $this->_formName . '_' . $escapedElementName.'(frm.elements[\''.$elementName.'\']) && ret;
if (!ret && !first_focus) {
first_focus = true;
frm.elements[\''.$elementName.'\'].focus();
document.getElementById(\'id_error_'.$elementName.'\').focus();
}
';
Oops, something went wrong.

0 comments on commit a8416f3

Please sign in to comment.
You can’t perform that action at this time.