Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'MOODLE_24_STABLE' into install_24_STABLE

  • Loading branch information...
commit 38753adc60c91cd13229d761cbdf13002370d770 2 parents d2dc75f + e81fce9
AMOS bot authored
Showing with 328 additions and 126 deletions.
  1. +1 −1  auth/cas/auth.php
  2. +2 −2 auth/db/lang/en/auth_db.php
  3. +3 −0  backup/controller/restore_controller.class.php
  4. +15 −7 backup/util/ui/restore_ui_stage.class.php
  5. +9 −0 blocks/rss_client/styles.css
  6. +13 −9 course/edit_form.php
  7. +17 −1 course/lib.php
  8. +47 −0 course/tests/courselib_test.php
  9. +2 −1  enrol/database/lang/en/enrol_database.php
  10. +1 −1  enrol/database/settings.php
  11. +1 −1  enrol/ldap/lib.php
  12. +6 −1 enrol/meta/lib.php
  13. +2 −2 files/renderer.php
  14. +33 −2 lib/formslib.php
  15. +1 −3 lib/oauthlib.php
  16. +43 −9 mod/assign/locallib.php
  17. +1 −1  mod/book/view.php
  18. +5 −45 mod/forum/lib.php
  19. +62 −5 mod/resource/backup/moodle2/backup_resource_activity_task.class.php
  20. +1 −0  mod/scorm/styles.css
  21. +1 −1  mod/survey/lang/en/survey.php
  22. +23 −17 mod/survey/lib.php
  23. +15 −2 question/format/blackboard_six/tests/blackboardformatpool_test.php
  24. +15 −2 question/format/blackboard_six/tests/blackboardsixformatqti_test.php
  25. +1 −0  repository/url/lang/en/repository_url.php
  26. +2 −0  repository/url/lib.php
  27. +1 −2  theme/canvas/style/core.css
  28. +2 −7 theme/formal_white/style/formal_white.css
  29. +1 −2  theme/standard/style/blocks.css
  30. +2 −2 version.php
View
2  auth/cas/auth.php
@@ -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);
View
4 auth/db/lang/en/auth_db.php
@@ -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';
View
3  backup/controller/restore_controller.class.php
@@ -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);
View
22 backup/util/ui/restore_ui_stage.class.php
@@ -475,8 +475,9 @@ 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) {
@@ -484,13 +485,11 @@ protected function initialise_stage_form() {
$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;
View
9 blocks/rss_client/styles.css
@@ -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
22 course/edit_form.php
@@ -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
18 course/lib.php
@@ -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);
View
47 course/tests/courselib_test.php
@@ -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);
View
3  enrol/database/lang/en/enrol_database.php
@@ -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>';
View
2  enrol/database/settings.php
@@ -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
2  enrol/ldap/lib.php
@@ -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
7 enrol/meta/lib.php
@@ -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
4 files/renderer.php
@@ -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
35 lib/formslib.php
@@ -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
4 lib/oauthlib.php
@@ -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)) {
View
52 mod/assign/locallib.php
@@ -2327,9 +2327,15 @@ private function view_single_grade_page($mform, $offset=0) {
$showedit = $this->submissions_open($userid) && ($this->is_any_submission_plugin_enabled());
if ($teamsubmission) {
- $showsubmit = $showedit && $teamsubmission && ($teamsubmission->status == ASSIGN_SUBMISSION_STATUS_DRAFT);
+ $showsubmit = $showedit &&
+ $teamsubmission &&
+ ($teamsubmission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) &&
+ !$this->submission_empty($teamsubmission);
} else {
- $showsubmit = $showedit && $submission && ($submission->status == ASSIGN_SUBMISSION_STATUS_DRAFT);
+ $showsubmit = $showedit &&
+ $submission &&
+ ($submission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) &&
+ !$this->submission_empty($submission);
}
if (!$this->get_instance()->submissiondrafts) {
$showsubmit = false;
@@ -2896,13 +2902,19 @@ public function view_student_summary($user, $showlinks) {
}
}
- $showsubmit = ($submission || $teamsubmission) && $showlinks;
+ $showsubmit = ($submission || $teamsubmission) && $showlinks && $this->submissions_open($user->id);
if ($teamsubmission && ($teamsubmission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED)) {
$showsubmit = false;
}
+ if ($teamsubmission && $this->submission_empty($teamsubmission)) {
+ $showsubmit = false;
+ }
if ($submission && ($submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED)) {
$showsubmit = false;
}
+ if ($submission && $this->submission_empty($submission)) {
+ $showsubmit = false;
+ }
if (!$this->get_instance()->submissiondrafts) {
$showsubmit = false;
}
@@ -3566,6 +3578,9 @@ private function process_submit_for_grading($mform) {
require_once($CFG->dirroot . '/mod/assign/submissionconfirmform.php');
require_sesskey();
+ if (!$this->submissions_open()) {
+ return $this->view_student_error_message();
+ }
$data = new stdClass();
$adminconfig = $this->get_admin_config();
$requiresubmissionstatement = (!empty($adminconfig->requiresubmissionstatement) ||
@@ -3983,7 +3998,26 @@ private function format_submission_for_log(stdClass $submission) {
}
/**
- * save assignment submission
+ * Determine if the current submission is empty or not.
+ *
+ * @param submission $submission the students submission record to check.
+ * @return bool
+ */
+ public function submission_empty($submission) {
+ $allempty = true;
+
+ foreach ($this->submissionplugins as $plugin) {
+ if ($plugin->is_enabled() && $plugin->is_visible()) {
+ if (!$allempty || !$plugin->is_empty($submission)) {
+ $allempty = false;
+ }
+ }
+ }
+ return $allempty;
+ }
+
+ /**
+ * Save assignment submission.
*
* @param moodleform $mform
* @param array $notices Any error messages that should be shown to the user at the top of the edit submission form.
@@ -3998,6 +4032,10 @@ private function process_save_submission(&$mform, &$notices) {
// Need submit permission to submit an assignment.
require_capability('mod/assign:submit', $this->context);
require_sesskey();
+ if (!$this->submissions_open()) {
+ $notices[] = get_string('duedatereached', 'assign');
+ return false;
+ }
$data = new stdClass();
$mform = new mod_assign_submission_form(null, array($this, $data));
@@ -4022,8 +4060,6 @@ private function process_save_submission(&$mform, &$notices) {
return true;
}
-
- $allempty = true;
$pluginerror = false;
foreach ($this->submissionplugins as $plugin) {
if ($plugin->is_enabled() && $plugin->is_visible()) {
@@ -4031,11 +4067,9 @@ private function process_save_submission(&$mform, &$notices) {
$notices[] = $plugin->get_error();
$pluginerror = true;
}
- if (!$allempty || !$plugin->is_empty($submission)) {
- $allempty = false;
- }
}
}
+ $allempty = $this->submission_empty($submission);
if ($pluginerror || $allempty) {
if ($allempty) {
$notices[] = get_string('submissionempty', 'mod_assign');
View
2  mod/book/view.php
@@ -191,7 +191,7 @@
}
}
$chaptertext = file_rewrite_pluginfile_urls($chapter->content, 'pluginfile.php', $context->id, 'mod_book', 'chapter', $chapter->id);
-echo format_text($chaptertext, $chapter->contentformat, array('noclean'=>true, 'context'=>$context));
+echo format_text($chaptertext, $chapter->contentformat, array('noclean'=>true, 'overflowdiv'=>true, 'context'=>$context));
echo $OUTPUT->box_end();
View
50 mod/forum/lib.php
@@ -3455,9 +3455,10 @@ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=fa
$options->trusted = $post->messagetrust;
$options->context = $modcontext;
if ($shortenpost) {
- // Prepare shortened version
+ // Prepare shortened version by filtering the text then shortening it.
$postclass = 'shortenedpost';
- $postcontent = format_text(forum_shorten_post($post->message), $post->messageformat, $options, $course->id);
+ $postcontent = format_text($post->message, $post->messageformat, $options);
+ $postcontent = forum_shorten_post($postcontent);
$postcontent .= html_writer::link($discussionlink, get_string('readtherest', 'forum'));
$postcontent .= html_writer::tag('span', '('.get_string('numwords', 'moodle', count_words(strip_tags($post->message))).')...', array('class'=>'post-word-count'));
} else {
@@ -3795,50 +3796,9 @@ function forum_print_discussion_header(&$post, $forum, $group=-1, $datestring=""
* @return string
*/
function forum_shorten_post($message) {
+ global $CFG;
- global $CFG;
-
- $i = 0;
- $tag = false;
- $length = strlen($message);
- $count = 0;
- $stopzone = false;
- $truncate = 0;
-
- for ($i=0; $i<$length; $i++) {
- $char = $message[$i];
-
- switch ($char) {
- case "<":
- $tag = true;
- break;
- case ">":
- $tag = false;
- break;
- default:
- if (!$tag) {
- if ($stopzone) {
- if ($char == ".") {
- $truncate = $i+1;
- break 2;
- }
- }
- $count++;
- }
- break;
- }
- if (!$stopzone) {
- if ($count > $CFG->forum_shortpost) {
- $stopzone = true;
- }
- }
- }
-
- if (!$truncate) {
- $truncate = $i;
- }
-
- return substr($message, 0, $truncate);
+ return shorten_text($message, $CFG->forum_shortpost);
}
/**
View
67 mod/resource/backup/moodle2/backup_resource_activity_task.class.php
@@ -34,6 +34,11 @@
class backup_resource_activity_task extends backup_activity_task {
/**
+ * @param bool $resourceoldexists True if there are records in the resource_old table.
+ */
+ protected static $resourceoldexists = null;
+
+ /**
* No specific settings for this activity
*/
protected function define_my_settings() {
@@ -53,18 +58,70 @@ protected function define_my_steps() {
* @return string the content with the URLs encoded
*/
static public function encode_content_links($content) {
- global $CFG;
+ global $CFG, $DB;
$base = preg_quote($CFG->wwwroot,"/");
- // Link to the list of resources
+ // Link to the list of resources.
$search="/(".$base."\/mod\/resource\/index.php\?id\=)([0-9]+)/";
$content= preg_replace($search, '$@RESOURCEINDEX*$2@$', $content);
- // Link to resource view by moduleid
- $search="/(".$base."\/mod\/resource\/view.php\?id\=)([0-9]+)/";
- $content= preg_replace($search, '$@RESOURCEVIEWBYID*$2@$', $content);
+ // Link to resource view by moduleid.
+ $search = "/(".$base."\/mod\/resource\/view.php\?id\=)([0-9]+)/";
+ // Link to resource view by recordid
+ $search2 = "/(".$base."\/mod\/resource\/view.php\?r\=)([0-9]+)/";
+
+ // Check whether there are contents in the resource old table.
+ if (static::$resourceoldexists === null) {
+ static::$resourceoldexists = $DB->record_exists('resource_old', array());
+ }
+
+ // If there are links to items in the resource_old table, rewrite them to be links to the correct URL
+ // for their new module.
+ if (static::$resourceoldexists) {
+ // Match all of the resources.
+ $result = preg_match_all($search, $content, $matches, PREG_PATTERN_ORDER);
+
+ // Course module ID resource links.
+ if ($result) {
+ list($insql, $params) = $DB->get_in_or_equal($matches[2]);
+ $oldrecs = $DB->get_records_select('resource_old', "cmid $insql", $params, '', 'cmid, newmodule');
+
+ for ($i = 0; $i < count($matches[0]); $i++) {
+ $cmid = $matches[2][$i];
+ if (isset($oldrecs[$cmid])) {
+ // Resource_old item, rewrite it
+ $replace = '$@' . strtoupper($oldrecs[$cmid]->newmodule) . 'VIEWBYID*' . $cmid . '@$';
+ } else {
+ // Not in the resource old table, don't rewrite
+ $replace = '$@RESOURCEVIEWBYID*'.$cmid.'@$';
+ }
+ $content = str_replace($matches[0][$i], $replace, $content);
+ }
+ }
+
+ $matches = null;
+ $result = preg_match_all($search2, $content, $matches, PREG_PATTERN_ORDER);
+
+ // No resource links.
+ if (!$result) {
+ return $content;
+ }
+ // Resource ID links.
+ list($insql, $params) = $DB->get_in_or_equal($matches[2]);
+ $oldrecs = $DB->get_records_select('resource_old', "oldid $insql", $params, '', 'oldid, cmid, newmodule');
+ for ($i = 0; $i < count($matches[0]); $i++) {
+ $recordid = $matches[2][$i];
+ if (isset($oldrecs[$recordid])) {
+ // Resource_old item, rewrite it
+ $replace = '$@' . strtoupper($oldrecs[$recordid]->newmodule) . 'VIEWBYID*' . $oldrecs[$recordid]->cmid . '@$';
+ $content = str_replace($matches[0][$i], $replace, $content);
+ }
+ }
+ } else {
+ $content = preg_replace($search, '$@RESOURCEVIEWBYID*$2@$', $content);
+ }
return $content;
}
}
View
1  mod/scorm/styles.css
@@ -39,3 +39,4 @@
.path-mod-scorm.jsenabled .scorm-center { display:block;}
.path-mod-scorm.jsenabled .toc { display:block;}
.path-mod-scorm.jsenabled #scormpage #tocbox { display:block;}
+#page-mod-scorm-userreport table .c2 { word-wrap:break-word; word-break: break-all;}
View
2  mod/survey/lang/en/survey.php
@@ -108,7 +108,7 @@
$string['collesaname'] = 'COLLES (Actual)';
$string['collesapintro'] = 'The purpose of this questionnaire is to help us understand how well the online delivery of this unit enabled you to learn.
-Each one of the 24 statements below asks you to compare your <b>preferred</b> (ideal) and <b>actual</b> experience in this unit.
+Each couple of the 24 statements below asks you to compare your <b>preferred</b> (ideal) and <b>actual</b> experience in this unit.
There are no \'right\' or \'wrong\' answers; we are interested only in your opinion. Please be assured that your responses will be treated with a high degree of confidentiality, and will not affect your assessment.
View
40 mod/survey/lib.php
@@ -509,8 +509,22 @@ function survey_print_multi($question) {
$options = explode( ",", $question->options);
$numoptions = count($options);
+ // COLLES Actual (which is having questions of type 1) and COLLES Preferred (type 2)
+ // expect just one answer per question. COLLES Actual and Preferred (type 3) expects
+ // two answers per question. ATTLS (having a single question of type 1) expects one
+ // answer per question. CIQ is not using multiquestions (i.e. a question with subquestions).
+ // Note that the type of subquestions does not really matter, it's the type of the
+ // question itself that determines everything.
$oneanswer = ($question->type == 1 || $question->type == 2) ? true : false;
+ // COLLES Preferred (having questions of type 2) will use the radio elements with the name
+ // like qP1, qP2 etc. COLLES Actual and ATTLS have radios like q1, q2 etc.
+ if ($question->type == 2) {
+ $P = "P";
+ } else {
+ $P = "";
+ }
+
echo "<tr class=\"smalltext\"><th scope=\"row\">$strresponses</th>";
echo "<th scope=\"col\" class=\"hresponse\">". get_string('notyetanswered', 'survey'). "</th>";
while (list ($key, $val) = each ($options)) {
@@ -518,28 +532,21 @@ function survey_print_multi($question) {
}
echo "</tr>\n";
- if ($oneanswer) {
- echo "<tr><th scope=\"col\" colspan=\"7\">$question->intro</th></tr>\n";
- } else {
- echo "<tr><th scope=\"col\" colspan=\"7\">$question->intro</th></tr>\n";
- }
+ echo "<tr><th scope=\"col\" colspan=\"7\">$question->intro</th></tr>\n";
$subquestions = $DB->get_records_list("survey_questions", "id", explode(',', $question->multi));
foreach ($subquestions as $q) {
$qnum++;
- $rowclass = survey_question_rowclass($qnum);
+ if ($oneanswer) {
+ $rowclass = survey_question_rowclass($qnum);
+ } else {
+ $rowclass = survey_question_rowclass(round($qnum / 2));
+ }
if ($q->text) {
$q->text = get_string($q->text, "survey");
}
- $oneanswer = ($q->type == 1 || $q->type == 2) ? true : false;
- if ($q->type == 2) {
- $P = "P";
- } else {
- $P = "";
- }
-
echo "<tr class=\"$rowclass rblock\">";
if ($oneanswer) {
echo "<th scope=\"row\" class=\"optioncell\">";
@@ -557,15 +564,14 @@ function survey_print_multi($question) {
$checklist["q$P$q->id"] = 0;
} else {
- // yu : fix for MDL-7501, possibly need to use user flag as this is quite ugly.
echo "<th scope=\"row\" class=\"optioncell\">";
echo "<b class=\"qnumtopcell\">$qnum</b> &nbsp; ";
$qnum++;
- echo "<span class=\"preferthat smalltext\">$stripreferthat</span> &nbsp; ";
+ echo "<span class=\"preferthat\">$stripreferthat</span> &nbsp; ";
echo "<span class=\"option\">$q->text</span></th>\n";
$default = get_accesshide($strdefault);
- echo '<td class="whitecell"><label for="qP'. $P.$q->id .'"><input type="radio" name="qP'.$P.$q->id. '" id="qP'. $q->id .'" value="0" checked="checked" />'.$default.'</label></td>';
+ echo '<td class="whitecell"><label for="qP'.$q->id.'"><input type="radio" name="qP'.$q->id.'" id="qP'.$q->id.'" value="0" checked="checked" />'.$default.'</label></td>';
for ($i=1;$i<=$numoptions;$i++) {
@@ -578,7 +584,7 @@ function survey_print_multi($question) {
echo "<tr class=\"$rowclass rblock\">";
echo "<th scope=\"row\" class=\"optioncell\">";
echo "<b class=\"qnumtopcell\">$qnum</b> &nbsp; ";
- echo "<span class=\"foundthat smalltext\">$strifoundthat</span> &nbsp; ";
+ echo "<span class=\"foundthat\">$strifoundthat</span> &nbsp; ";
echo "<span class=\"option\">$q->text</span></th>\n";
$default = get_accesshide($strdefault);
View
17 question/format/blackboard_six/tests/blackboardformatpool_test.php
@@ -56,8 +56,12 @@ public function test_import_match() {
$q = $questions[4];
+ // If qtype_ddmatch is installed, the formatter produces ddmatch
+ // qtypes, not match ones.
+ $ddmatchisinstalled = question_bank::is_qtype_installed('ddmatch');
+
$expectedq = new stdClass();
- $expectedq->qtype = 'match';
+ $expectedq->qtype = $ddmatchisinstalled ? 'ddmatch' : 'match';
$expectedq->name = 'Classify the animals.';
$expectedq->questiontext = '<i>Classify the animals.</i>';
$expectedq->questiontextformat = FORMAT_HTML;
@@ -78,8 +82,17 @@ public function test_import_match() {
array('text' => '', 'format' => FORMAT_HTML),
array('text' => 'frog', 'format' => FORMAT_HTML),
array('text' => 'newt', 'format' => FORMAT_HTML));
- $expectedq->subanswers = array('mammal', 'insect', 'amphibian', 'amphibian');
+ if ($ddmatchisinstalled) {
+ $expectedq->subanswers = array(
+ array('text' => 'mammal', 'format' => FORMAT_HTML),
+ array('text' => 'insect', 'format' => FORMAT_HTML),
+ array('text' => 'amphibian', 'format' => FORMAT_HTML),
+ array('text' => 'amphibian', 'format' => FORMAT_HTML),
+ );
+ } else {
+ $expectedq->subanswers = array('mammal', 'insect', 'amphibian', 'amphibian');
+ }
$this->assert(new question_check_specified_fields_expectation($expectedq), $q);
}
View
17 question/format/blackboard_six/tests/blackboardsixformatqti_test.php
@@ -53,8 +53,12 @@ public function test_import_match() {
$questions = $importer->readquestions($xml);
$q = $questions[3];
+ // If qtype_ddmatch is installed, the formatter produces ddmatch
+ // qtypes, not match ones.
+ $ddmatchisinstalled = question_bank::is_qtype_installed('ddmatch');
+
$expectedq = new stdClass();
- $expectedq->qtype = 'match';
+ $expectedq->qtype = $ddmatchisinstalled ? 'ddmatch' : 'match';
$expectedq->name = 'Classify the animals.';
$expectedq->questiontext = 'Classify the animals.';
$expectedq->questiontextformat = FORMAT_HTML;
@@ -75,7 +79,16 @@ public function test_import_match() {
array('text' => 'cat', 'format' => FORMAT_HTML),
array('text' => 'frog', 'format' => FORMAT_HTML),
array('text' => 'newt', 'format' => FORMAT_HTML));
- $expectedq->subanswers = array('insect', 'mammal', 'amphibian', 'amphibian');
+ if ($ddmatchisinstalled) {
+ $expectedq->subanswers = array(
+ array('text' => 'insect', 'format' => FORMAT_HTML),
+ array('text' => 'mammal', 'format' => FORMAT_HTML),
+ array('text' => 'amphibian', 'format' => FORMAT_HTML),
+ array('text' => 'amphibian', 'format' => FORMAT_HTML),
+ );
+ } else {
+ $expectedq->subanswers = array('insect', 'mammal', 'amphibian', 'amphibian');
+ }
$this->assert(new question_check_specified_fields_expectation($expectedq), $q);
}
View
1  repository/url/lang/en/repository_url.php
@@ -30,3 +30,4 @@
$string['url:view'] = 'Use URL downloader in file picker';
$string['validname'] = 'You must provide a valid file name';
$string['configplugin'] = 'URL repository type configuration';
+$string['validfiletype'] = 'You must provide a URL to an image file or a page containing images.';
View
2  repository/url/lib.php
@@ -168,6 +168,8 @@ protected function parse_file($baseurl, $relativeurl, &$list, $mainfile = false)
} else if (strstr($info['content_type'], 'image/')) {
// download this file
$this->add_image_to_list($info['url'], $info['url'], $list);
+ } else {
+ $list['error'] = get_string('validfiletype', 'repository_url');
}
// parse all found css styles
View
3  theme/canvas/style/core.css
@@ -35,8 +35,7 @@ body {
.errorbox,
.continuebutton,
.singlebutton,
-.buttons,
-.singleselect {
+.buttons {
text-align: center;
margin: 1em 0;
}
View
9 theme/formal_white/style/formal_white.css
@@ -239,14 +239,9 @@ form.loginform #rememberusername {
margin-right:0;
}
-/* RSS - MDL-29367 */
-.block_rss_client .list li:first-child {
- border-top-width: 0;
-}
-
+/* RSS - MDL-28561 */
.block_rss_client .list li {
- border-top: 1px solid #DDDDDD;
- padding: 5px;
+ border-top-color: #DDD;
}
/* Upcoming events - MDL-29367 */
View
3  theme/standard/style/blocks.css
@@ -77,8 +77,7 @@
/** RSS Client **/
.block_rss_client .image {text-align:center;}
-.block_rss_client .list li {padding:5px;font-size:0.85em;border-top:1px solid #DDD;}
-.block_rss_client .list li:first-child {border-top-width: 0px;}
+.block_rss_client .list li {font-size:0.85em;border-top-color:#DDD;}
.block_rss_client .list li .description {color:#555555;font-size:0.8em;padding-left:1em;}
/** Site main menu **/
View
4 version.php
@@ -29,11 +29,11 @@
defined('MOODLE_INTERNAL') || die();
-$version = 2012120306.00; // 20121203 = branching date YYYYMMDD - do not modify!
+$version = 2012120306.01; // 20121203 = branching date YYYYMMDD - do not modify!
// RR = release increments - 00 in DEV branches
// .XX = incremental changes
-$release = '2.4.6 (Build: 20130909)'; // Human-friendly version name
+$release = '2.4.6+ (Build: 20130913)'; // Human-friendly version name
$branch = '24'; // this version's branch
$maturity = MATURITY_STABLE; // this version's maturity level
Please sign in to comment.
Something went wrong with that request. Please try again.