Permalink
Browse files

Merge branch 'MOODLE_24_STABLE' into install_24_STABLE

  • Loading branch information...
2 parents d2dc75f + e81fce9 commit 38753adc60c91cd13229d761cbdf13002370d770 AMOS bot committed Sep 14, 2013
View
@@ -125,7 +125,7 @@ function loginpage_hook() {
// test pgtIou parameter for proxy mode (https connection
// in background from CAS server to the php server)
if ($authCAS != 'CAS' && !isset($_GET['pgtIou'])) {
- $PAGE->set_url('/auth/cas/auth.php');
+ $PAGE->set_url('/login/index.php');
$PAGE->navbar->add($CASform);
$PAGE->set_title("$site->fullname: $CASform");
$PAGE->set_heading($site->fullname);
@@ -36,13 +36,13 @@
$string['auth_dbfieldpass_key'] = 'Password field';
$string['auth_dbfielduser'] = 'Name of the field containing usernames';
$string['auth_dbfielduser_key'] = 'Username field';
-$string['auth_dbhost'] = 'The computer hosting the database server.';
+$string['auth_dbhost'] = 'The computer hosting the database server. Use a system DSN entry if using ODBC.';
$string['auth_dbhost_key'] = 'Host';
$string['auth_dbchangepasswordurl_key'] = 'Password-change URL';
$string['auth_dbinsertuser'] = 'Inserted user {$a->name} id {$a->id}';
$string['auth_dbinsertuserduplicate'] = 'Error inserting user {$a->username} - user with this username was already created through \'{$a->auth}\' plugin.';
$string['auth_dbinsertusererror'] = 'Error inserting user {$a}';
-$string['auth_dbname'] = 'Name of the database itself';
+$string['auth_dbname'] = 'Name of the database itself. Leave empty if using an ODBC DSN.';
$string['auth_dbname_key'] = 'DB name';
$string['auth_dbpass'] = 'Password matching the above username';
$string['auth_dbpass_key'] = 'Password';
@@ -335,6 +335,9 @@ public function execute_precheck($droptemptablesafter = false) {
if ($this->status != backup::STATUS_NEED_PRECHECK) {
throw new restore_controller_exception('cannot_precheck_wrong_status', $this->status);
}
+ // Basic/initial prevention against time/memory limits
+ set_time_limit(1 * 60 * 60); // 1 hour for 1 course initially granted
+ raise_memory_limit(MEMORY_EXTRA);
$this->precheck = restore_prechecks_helper::execute_prechecks($this, $droptemptablesafter);
if (!array_key_exists('errors', $this->precheck)) { // No errors, can be executed
$this->set_status(backup::STATUS_AWAITING);
@@ -475,22 +475,21 @@ protected function initialise_stage_form() {
if ($this->stageform === null) {
$form = new restore_schema_form($this, $PAGE->url);
$tasks = $this->ui->get_tasks();
- $content = '';
$courseheading = false;
+
+ $allsettings = array();
foreach ($tasks as $task) {
if (!($task instanceof restore_root_task)) {
if (!$courseheading) {
// If we havn't already display a course heading to group nicely
$form->add_heading('coursesettings', get_string('coursesettings', 'backup'));
$courseheading = true;
}
- // First add each setting
- foreach ($task->get_settings() as $setting) {
- $form->add_setting($setting, $task);
- }
- // The add all the dependencies
+ // Put each setting into an array of settings to add. Adding
+ // a setting individually is a very slow operation, so we add
+ // them all in a batch later on.
foreach ($task->get_settings() as $setting) {
- $form->add_dependencies($setting);
+ $allsettings[] = array($setting, $task);
}
} else if ($this->ui->enforce_changed_dependencies()) {
// Only show these settings if dependencies changed them.
@@ -505,6 +504,15 @@ protected function initialise_stage_form() {
}
}
}
+
+ // Actually add all the settings that we put in the array.
+ $form->add_settings($allsettings);
+
+ // Add the dependencies for all the settings.
+ foreach ($allsettings as $settingtask) {
+ $form->add_dependencies($settingtask[0]);
+ }
+
$this->stageform = $form;
}
return $this->stageform;
@@ -0,0 +1,9 @@
+/* RSS Feeds
+-------------------------*/
+.block_rss_client .list li:first-child {
+ border-top-width: 0;
+}
+.block_rss_client .list li {
+ border-top: 1px solid;
+ padding: 5px;
+}
View
@@ -328,19 +328,23 @@ function definition_after_data() {
/// perform some extra moodle validation
function validation($data, $files) {
- global $DB, $CFG;
+ global $DB;
$errors = parent::validation($data, $files);
- if ($foundcourses = $DB->get_records('course', array('shortname'=>$data['shortname']))) {
- if (!empty($data['id'])) {
- unset($foundcourses[$data['id']]);
+
+ // Add field validation check for duplicate shortname.
+ if ($course = $DB->get_record('course', array('shortname' => $data['shortname']), '*', IGNORE_MULTIPLE)) {
+ if (empty($data['id']) || $course->id != $data['id']) {
+ $errors['shortname'] = get_string('shortnametaken', '', $course->fullname);
}
- if (!empty($foundcourses)) {
- foreach ($foundcourses as $foundcourse) {
- $foundcoursenames[] = $foundcourse->fullname;
+ }
+
+ // Add field validation check for duplicate idnumber.
+ if (!empty($data['idnumber']) && (empty($data['id']) || $this->course->idnumber != $data['idnumber'])) {
+ if ($course = $DB->get_record('course', array('idnumber' => $data['idnumber']), '*', IGNORE_MULTIPLE)) {
+ if (empty($data['id']) || $course->id != $data['id']) {
+ $errors['idnumber'] = get_string('idnumbertaken', 'error');
}
- $foundcoursenamestring = implode(',', $foundcoursenames);
- $errors['shortname']= get_string('shortnametaken', '', $foundcoursenamestring);
}
}
View
@@ -3962,6 +3962,20 @@ function update_course($data, $editoroptions = NULL) {
$data = file_postupdate_standard_editor($data, 'summary', $editoroptions, $context, 'course', 'summary', 0);
}
+ // Check we don't have a duplicate shortname.
+ if (!empty($data->shortname) && $oldcourse->shortname != $data->shortname) {
+ if ($DB->record_exists('course', array('shortname' => $data->shortname))) {
+ throw new moodle_exception('shortnametaken', '', '', $data->shortname);
+ }
+ }
+
+ // Check we don't have a duplicate idnumber.
+ if (!empty($data->idnumber) && $oldcourse->idnumber != $data->idnumber) {
+ if ($DB->record_exists('course', array('idnumber' => $data->idnumber))) {
+ throw new moodle_exception('idnumbertaken', 'error');
+ }
+ }
+
if (!isset($data->category) or empty($data->category)) {
// prevent nulls and 0 in category field
unset($data->category);
@@ -4001,7 +4015,9 @@ function update_course($data, $editoroptions = NULL) {
context_moved($context, $newparent);
}
- fix_course_sortorder();
+ if ($movecat || (isset($data->sortorder) && $oldcourse->sortorder != $data->sortorder)) {
+ fix_course_sortorder();
+ }
// Test for and remove blocks which aren't appropriate anymore
blocks_remove_inappropriate($course);
@@ -97,6 +97,53 @@ public function test_create_course_sections() {
$this->assertEquals(range(0, $course->numsections + 1), $sectionscreated);
}
+ public function test_update_course() {
+ global $DB;
+
+ $this->resetAfterTest();
+
+ $defaultcategory = $DB->get_field_select('course_categories', 'MIN(id)', 'parent = 0');
+
+ $course = new stdClass();
+ $course->fullname = 'Apu loves Unit Təsts';
+ $course->shortname = 'test1';
+ $course->idnumber = '1';
+ $course->summary = 'Awesome!';
+ $course->summaryformat = FORMAT_PLAIN;
+ $course->format = 'topics';
+ $course->newsitems = 0;
+ $course->numsections = 5;
+ $course->category = $defaultcategory;
+
+ $created = create_course($course);
+ // Ensure the checks only work on idnumber/shortname that are not already ours.
+ update_course($created);
+
+ $course->shortname = 'test2';
+ $course->idnumber = '2';
+
+ $created2 = create_course($course);
+
+ // Test duplicate idnumber.
+ $created2->idnumber = '1';
+ try {
+ update_course($created2);
+ $this->fail('Expected exception when trying to update a course with duplicate idnumber');
+ } catch (moodle_exception $e) {
+ $this->assertEquals(get_string('idnumbertaken', 'error'), $e->getMessage());
+ }
+
+ // Test duplicate shortname.
+ $created2->idnumber = '2';
+ $created2->shortname = 'test1';
+ try {
+ update_course($created2);
+ $this->fail('Expected exception when trying to update a course with a duplicate shortname');
+ } catch (moodle_exception $e) {
+ $this->assertEquals(get_string('shortnametaken', 'error', $created2->shortname), $e->getMessage());
+ }
+ }
+
public function test_course_add_cm_to_section() {
global $DB;
$this->resetAfterTest(true);
@@ -25,8 +25,9 @@
$string['database:unenrol'] = 'Unenrol suspended users';
$string['dbencoding'] = 'Database encoding';
$string['dbhost'] = 'Database host';
-$string['dbhost_desc'] = 'Type database server IP address or host name';
+$string['dbhost_desc'] = 'Type database server IP address or host name. Use a system DSN name if using ODBC.';
$string['dbname'] = 'Database name';
+$string['dbname_desc'] = 'Leave empty if using a DSN name in database host.';
$string['dbpass'] = 'Database password';
$string['dbsetupsql'] = 'Database setup command';
$string['dbsetupsql_desc'] = 'SQL command for special database setup, often used to setup communication encoding - example for MySQL and PostgreSQL: <em>SET NAMES \'utf8\'</em>';
@@ -41,7 +41,7 @@
$settings->add(new admin_setting_configpasswordunmask('enrol_database/dbpass', get_string('dbpass', 'enrol_database'), '', ''));
- $settings->add(new admin_setting_configtext('enrol_database/dbname', get_string('dbname', 'enrol_database'), '', ''));
+ $settings->add(new admin_setting_configtext('enrol_database/dbname', get_string('dbname', 'enrol_database'), get_string('dbname_desc', 'enrol_database'), ''));
$settings->add(new admin_setting_configtext('enrol_database/dbencoding', get_string('dbencoding', 'enrol_database'), '', 'utf-8'));
View
@@ -950,7 +950,7 @@ function create_course($course_ext, $skip_fix_course_sortorder=false) {
$template->groupmodeforce = $courseconfig->groupmodeforce;
$template->visible = $courseconfig->visible;
$template->lang = $courseconfig->lang;
- $template->groupmodeforce = $courseconfig->groupmodeforce;
+ $template->enablecompletion = $courseconfig->enablecompletion;
}
$course = $template;
View
@@ -47,7 +47,12 @@ public function get_instance_name($instance) {
} else if (empty($instance->name)) {
$enrol = $this->get_name();
$course = $DB->get_record('course', array('id'=>$instance->customint1));
- $coursename = format_string(get_course_display_name_for_list($course));
+ if ($course) {
+ $coursename = format_string(get_course_display_name_for_list($course));
+ } else {
+ // Use course id, if course is deleted.
+ $coursename = $instance->customint1;
+ }
return get_string('pluginname', 'enrol_' . $enrol) . ' (' . $coursename . ')';
} else {
return format_string($instance->name);
View
@@ -399,7 +399,7 @@ private function fm_js_template_fileselectlayout() {
<button class="{!}fp-file-cancel">'.get_string('cancel').'</button>
</div>
</form>
- <div class="fp-info">
+ <div class="fp-info clearfix">
<div class="fp-hr"></div>
<p class="{!}fp-thumbnail"></p>
<div class="fp-fileinfo">
@@ -698,7 +698,7 @@ private function fp_js_template_selectlayout() {
<button class="{!}fp-select-cancel">'.get_string('cancel').'</button>
</div>
</form>
- <div class="fp-info">
+ <div class="fp-info clearfix">
<div class="fp-hr"></div>
<p class="{!}fp-thumbnail"></p>
<div class="fp-fileinfo">
View
@@ -261,10 +261,10 @@ function _process_submission($method) {
$submission = array();
if ($method == 'post') {
if (!empty($_POST)) {
- $submission = $_POST;
+ $submission = $this->_get_post_params();
}
} else {
- $submission = array_merge_recursive($_GET, $_POST); // emulate handling of parameters in xxxx_param()
+ $submission = array_merge_recursive($_GET, $this->_get_post_params()); // Emulate handling of parameters in xxxx_param().
}
// following trick is needed to enable proper sesskey checks when using GET forms
@@ -283,6 +283,37 @@ function _process_submission($method) {
}
/**
+ * Internal method. Gets all POST variables, bypassing max_input_vars limit if needed.
+ *
+ * @return array All POST variables as an array, in the same format as $_POST.
+ */
+ protected function _get_post_params() {
+ $enctype = $this->_form->getAttribute('enctype');
+ $max = (int)ini_get('max_input_vars');
+
+ if (empty($max) || count($_POST, COUNT_RECURSIVE) < $max || (!empty($enctype) && $enctype == 'multipart/form-data')) {
+ return $_POST;
+ }
+
+ // Large POST request with enctype supported by php://input.
+ // Parse php://input in chunks to bypass max_input_vars limit, which also applies to parse_str().
+ $allvalues = array();
+ $values = array();
+ $str = file_get_contents("php://input");
+ $delim = '&';
+
+ $fun = create_function('$p', 'return implode("'.$delim.'", $p);');
+ $chunks = array_map($fun, array_chunk(explode($delim, $str), $max));
+
+ foreach ($chunks as $chunk) {
+ parse_str($chunk, $values);
+ $allvalues = array_merge_recursive($allvalues, $values);
+ }
+
+ return $allvalues;
+ }
+
+ /**
* Internal method. Validates all old-style deprecated uploaded files.
* The new way is to upload files via repository api.
*
View
@@ -228,9 +228,7 @@ public function request_token() {
// oauth_token_secret
$result = $this->parse_result($content);
if (empty($result['oauth_token'])) {
- // failed
- var_dump($result);
- exit;
+ throw new moodle_exception('Error while requesting an oauth token');
}
// build oauth authrize url
if (!empty($this->oauth_callback)) {
Oops, something went wrong.

0 comments on commit 38753ad

Please sign in to comment.