Merge branch 'MOODLE_25_STABLE' into install_25_STABLE
This commit is contained in:
@@ -32,6 +32,7 @@ if (($hassiteconfig || has_any_capability(array(
|
||||
'moodle/badges:createbadge',
|
||||
'moodle/badges:manageglobalsettings',
|
||||
'moodle/badges:awardbadge',
|
||||
'moodle/badges:configurecriteria',
|
||||
'moodle/badges:configuremessages',
|
||||
'moodle/badges:configuredetails',
|
||||
'moodle/badges:deletebadge'), $systemcontext))) {
|
||||
@@ -74,6 +75,7 @@ if (($hassiteconfig || has_any_capability(array(
|
||||
'moodle/badges:viewawarded',
|
||||
'moodle/badges:createbadge',
|
||||
'moodle/badges:awardbadge',
|
||||
'moodle/badges:configurecriteria',
|
||||
'moodle/badges:configuremessages',
|
||||
'moodle/badges:configuredetails',
|
||||
'moodle/badges:deletebadge'
|
||||
|
||||
@@ -38,6 +38,7 @@ $string['stepsdefinitionscontains'] = 'Contains';
|
||||
$string['stepsdefinitionsfilters'] = 'Steps definitions';
|
||||
$string['stepsdefinitionstype'] = 'Type';
|
||||
$string['theninfo'] = 'Then. Checkings to ensure the outcomes are the expected ones';
|
||||
$string['unknownexceptioninfo'] = 'There was a problem with Selenium or the browser, try to upgrade Selenium to the latest version. Error: ';
|
||||
$string['viewsteps'] = 'Filter';
|
||||
$string['wheninfo'] = 'When. Actions that provokes an event';
|
||||
$string['wrongbehatsetup'] = 'Something is wrong with behat setup, ensure:<ul>
|
||||
|
||||
+1
-1
@@ -137,7 +137,7 @@ class auth_plugin_cas extends auth_plugin_ldap {
|
||||
// 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);
|
||||
|
||||
@@ -35,13 +35,13 @@ $string['auth_dbfieldpass'] = 'Name of the field containing passwords';
|
||||
$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 @@ class restore_controller extends backup implements loggable {
|
||||
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,8 +475,9 @@ class restore_ui_stage_schema extends restore_ui_stage {
|
||||
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 @@ class restore_ui_stage_schema extends restore_ui_stage {
|
||||
$form->add_heading('coursesettings', get_string('coursesettings', 'backup'));
|
||||
$courseheading = true;
|
||||
}
|
||||
// First add each setting
|
||||
// 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_setting($setting, $task);
|
||||
}
|
||||
// The add all the dependencies
|
||||
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 @@ class restore_ui_stage_schema extends restore_ui_stage {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
+5
-1
@@ -95,7 +95,11 @@ if ($copy) {
|
||||
require_capability('moodle/badges:createbadge', $context);
|
||||
|
||||
$cloneid = $badge->make_clone();
|
||||
redirect(new moodle_url('/badges/edit.php', array('id' => $cloneid, 'action' => 'details')));
|
||||
// If a user can edit badge details, they will be redirected to the edit page.
|
||||
if (has_capability('moodle/badges:configuredetails', $context)) {
|
||||
redirect(new moodle_url('/badges/edit.php', array('id' => $cloneid, 'action' => 'details')));
|
||||
}
|
||||
redirect(new moodle_url('/badges/overview.php', array('id' => $cloneid)));
|
||||
}
|
||||
|
||||
if ($activate) {
|
||||
|
||||
+2
-1
@@ -40,6 +40,8 @@ $badge = new badge($badgeid);
|
||||
$context = $badge->get_context();
|
||||
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type));
|
||||
|
||||
require_capability('moodle/badges:configurecriteria', $context);
|
||||
|
||||
if ($badge->type == BADGE_TYPE_COURSE) {
|
||||
if (empty($CFG->badges_allowcoursebadges)) {
|
||||
print_error('coursebadgesdisabled', 'badges');
|
||||
@@ -66,7 +68,6 @@ $emsg = optional_param('emsg', '', PARAM_TEXT);
|
||||
|
||||
if ((($update == BADGE_CRITERIA_AGGREGATION_ALL) || ($update == BADGE_CRITERIA_AGGREGATION_ANY))) {
|
||||
require_sesskey();
|
||||
require_capability('moodle/badges:configurecriteria', $context);
|
||||
$obj = new stdClass();
|
||||
$obj->id = $badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->id;
|
||||
$obj->method = $update;
|
||||
|
||||
+5
-1
@@ -41,7 +41,11 @@ $badge = new badge($badgeid);
|
||||
$context = $badge->get_context();
|
||||
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type));
|
||||
|
||||
require_capability('moodle/badges:configuredetails', $context);
|
||||
if ($action == 'message') {
|
||||
require_capability('moodle/badges:configuremessages', $context);
|
||||
} else {
|
||||
require_capability('moodle/badges:configuredetails', $context);
|
||||
}
|
||||
|
||||
if ($badge->type == BADGE_TYPE_COURSE) {
|
||||
if (empty($CFG->badges_allowcoursebadges)) {
|
||||
|
||||
+5
-1
@@ -99,7 +99,11 @@ if ($form->is_cancelled()) {
|
||||
|
||||
$newbadge = new badge($newid);
|
||||
badges_process_badge_image($newbadge, $form->save_temp_file('image'));
|
||||
redirect(new moodle_url('/badges/criteria.php', array('id' => $newid)));
|
||||
// If a user can configure badge criteria, they will be redirected to the criteria page.
|
||||
if (has_capability('moodle/badges:configurecriteria', $PAGE->context)) {
|
||||
redirect(new moodle_url('/badges/criteria.php', array('id' => $newid)));
|
||||
}
|
||||
redirect(new moodle_url('/badges/overview.php', array('id' => $newid)));
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
+13
-9
@@ -326,19 +326,23 @@ class course_edit_form extends moodleform {
|
||||
|
||||
/// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -717,20 +717,14 @@ class core_course_external extends external_api {
|
||||
require_capability('moodle/course:changefullname', $context);
|
||||
}
|
||||
|
||||
// Check if the shortname already exist and user have capability.
|
||||
// Check if the user can change shortname.
|
||||
if (array_key_exists('shortname', $course) && ($oldcourse->shortname != $course['shortname'])) {
|
||||
require_capability('moodle/course:changeshortname', $context);
|
||||
if ($DB->record_exists('course', array('shortname' => $course['shortname']))) {
|
||||
throw new moodle_exception('shortnametaken');
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the id number already exist and user have capability.
|
||||
// Check if the user can change the idnumber.
|
||||
if (array_key_exists('idnumber', $course) && ($oldcourse->idnumber != $course['idnumber'])) {
|
||||
require_capability('moodle/course:changeidnumber', $context);
|
||||
if ($DB->record_exists('course', array('idnumber' => $course['idnumber']))) {
|
||||
throw new moodle_exception('idnumbertaken');
|
||||
}
|
||||
}
|
||||
|
||||
// Check if user can change summary.
|
||||
|
||||
+18
-1
@@ -2362,6 +2362,20 @@ function update_course($data, $editoroptions = NULL) {
|
||||
$data = file_postupdate_standard_filemanager($data, 'overviewfiles', $overviewfilesoptions, $context, 'course', 'overviewfiles', 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);
|
||||
@@ -2402,7 +2416,10 @@ 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();
|
||||
}
|
||||
|
||||
// purge appropriate caches in case fix_course_sortorder() did not change anything
|
||||
cache_helper::purge_by_event('changesincourse');
|
||||
if ($changesincoursecat) {
|
||||
|
||||
@@ -635,6 +635,52 @@ class courselib_testcase extends advanced_testcase {
|
||||
$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 @@ if ($ADMIN->fulltree) {
|
||||
|
||||
$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'));
|
||||
|
||||
|
||||
+1
-1
@@ -962,7 +962,7 @@ class enrol_ldap_plugin extends enrol_plugin {
|
||||
$template->groupmodeforce = $courseconfig->groupmodeforce;
|
||||
$template->visible = $courseconfig->visible;
|
||||
$template->lang = $courseconfig->lang;
|
||||
$template->groupmodeforce = $courseconfig->groupmodeforce;
|
||||
$template->enablecompletion = $courseconfig->enablecompletion;
|
||||
}
|
||||
$course = $template;
|
||||
|
||||
|
||||
+6
-1
@@ -46,7 +46,12 @@ class enrol_meta_plugin extends enrol_plugin {
|
||||
} 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);
|
||||
|
||||
+1
-1
@@ -193,7 +193,7 @@ class core_enrol_renderer extends plugin_renderer_base {
|
||||
if ($canassign and (is_siteadmin() or isset($assignableroles[$roleid])) and !$role['unchangeable']) {
|
||||
$strunassign = get_string('unassignarole', 'role', $role['text']);
|
||||
$icon = html_writer::empty_tag('img', array('alt'=>$strunassign, 'src'=>$iconenrolremove));
|
||||
$url = new moodle_url($pageurl, array('action'=>'unassign', 'role'=>$roleid, 'user'=>$userid));
|
||||
$url = new moodle_url($pageurl, array('action'=>'unassign', 'roleid'=>$roleid, 'user'=>$userid));
|
||||
$rolesoutput .= html_writer::tag('div', $role['text'] . html_writer::link($url, $icon, array('class'=>'unassignrolelink', 'rel'=>$roleid, 'title'=>$strunassign)), array('class'=>'role role_'.$roleid));
|
||||
} else {
|
||||
$rolesoutput .= html_writer::tag('div', $role['text'], array('class'=>'role unchangeable', 'rel'=>$roleid));
|
||||
|
||||
+2
-2
@@ -73,7 +73,7 @@ if ($action) {
|
||||
*/
|
||||
case 'unassign':
|
||||
if (has_capability('moodle/role:assign', $manager->get_context())) {
|
||||
$role = required_param('role', PARAM_INT);
|
||||
$role = required_param('roleid', PARAM_INT);
|
||||
$user = required_param('user', PARAM_INT);
|
||||
if ($confirm && $manager->unassign_role_from_user($user, $role)) {
|
||||
redirect($PAGE->url);
|
||||
@@ -81,7 +81,7 @@ if ($action) {
|
||||
$user = $DB->get_record('user', array('id'=>$user), '*', MUST_EXIST);
|
||||
$allroles = $manager->get_all_roles();
|
||||
$role = $allroles[$role];
|
||||
$yesurl = new moodle_url($PAGE->url, array('action'=>'unassign', 'role'=>$role->id, 'user'=>$user->id, 'confirm'=>1, 'sesskey'=>sesskey()));
|
||||
$yesurl = new moodle_url($PAGE->url, array('action'=>'unassign', 'roleid'=>$role->id, 'user'=>$user->id, 'confirm'=>1, 'sesskey'=>sesskey()));
|
||||
$message = get_string('unassignconfirm', 'role', array('user'=>fullname($user, true), 'role'=>$role->localname));
|
||||
$pagetitle = get_string('unassignarole', 'role', $role->localname);
|
||||
$pagecontent = $OUTPUT->confirm($message, $yesurl, $PAGE->url);
|
||||
|
||||
+2
-2
@@ -400,7 +400,7 @@ class core_files_renderer extends plugin_renderer_base {
|
||||
<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">
|
||||
@@ -699,7 +699,7 @@ class core_files_renderer extends plugin_renderer_base {
|
||||
<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">
|
||||
|
||||
+18
-27
@@ -895,38 +895,29 @@ function badges_add_course_navigation(navigation_node $coursenode, stdClass $cou
|
||||
|
||||
$coursecontext = context_course::instance($course->id);
|
||||
$isfrontpage = (!$coursecontext || $course->id == $SITE->id);
|
||||
$canmanage = has_any_capability(array('moodle/badges:viewawarded',
|
||||
'moodle/badges:createbadge',
|
||||
'moodle/badges:awardbadge',
|
||||
'moodle/badges:configurecriteria',
|
||||
'moodle/badges:configuremessages',
|
||||
'moodle/badges:configuredetails',
|
||||
'moodle/badges:deletebadge'), $coursecontext);
|
||||
|
||||
if (!empty($CFG->enablebadges) && !empty($CFG->badges_allowcoursebadges) && !$isfrontpage) {
|
||||
if (has_capability('moodle/badges:configuredetails', $coursecontext)) {
|
||||
$coursenode->add(get_string('coursebadges', 'badges'), null,
|
||||
navigation_node::TYPE_CONTAINER, null, 'coursebadges',
|
||||
new pix_icon('i/badge', get_string('coursebadges', 'badges')));
|
||||
if (!empty($CFG->enablebadges) && !empty($CFG->badges_allowcoursebadges) && !$isfrontpage && $canmanage) {
|
||||
$coursenode->add(get_string('coursebadges', 'badges'), null,
|
||||
navigation_node::TYPE_CONTAINER, null, 'coursebadges',
|
||||
new pix_icon('i/badge', get_string('coursebadges', 'badges')));
|
||||
|
||||
if (has_capability('moodle/badges:viewawarded', $coursecontext)) {
|
||||
$url = new moodle_url('/badges/index.php',
|
||||
array('type' => BADGE_TYPE_COURSE, 'id' => $course->id));
|
||||
$url = new moodle_url('/badges/index.php', array('type' => BADGE_TYPE_COURSE, 'id' => $course->id));
|
||||
|
||||
$coursenode->get('coursebadges')->add(get_string('managebadges', 'badges'), $url,
|
||||
navigation_node::TYPE_SETTING, null, 'coursebadges');
|
||||
}
|
||||
$coursenode->get('coursebadges')->add(get_string('managebadges', 'badges'), $url,
|
||||
navigation_node::TYPE_SETTING, null, 'coursebadges');
|
||||
|
||||
if (has_capability('moodle/badges:createbadge', $coursecontext)) {
|
||||
$url = new moodle_url('/badges/newbadge.php',
|
||||
array('type' => BADGE_TYPE_COURSE, 'id' => $course->id));
|
||||
if (has_capability('moodle/badges:createbadge', $coursecontext)) {
|
||||
$url = new moodle_url('/badges/newbadge.php', array('type' => BADGE_TYPE_COURSE, 'id' => $course->id));
|
||||
|
||||
$coursenode->get('coursebadges')->add(get_string('newbadge', 'badges'), $url,
|
||||
navigation_node::TYPE_SETTING, null, 'newbadge');
|
||||
}
|
||||
} else if (has_capability('moodle/badges:awardbadge', $coursecontext)) {
|
||||
$coursenode->add(get_string('coursebadges', 'badges'), null,
|
||||
navigation_node::TYPE_CONTAINER, null, 'coursebadges',
|
||||
new pix_icon('i/badge', get_string('coursebadges', 'badges')));
|
||||
|
||||
$url = new moodle_url('/badges/index.php',
|
||||
array('type' => BADGE_TYPE_COURSE, 'id' => $course->id));
|
||||
|
||||
$coursenode->get('coursebadges')->add(get_string('managebadges', 'badges'), $url,
|
||||
navigation_node::TYPE_SETTING, null, 'coursebadges');
|
||||
$coursenode->get('coursebadges')->add(get_string('newbadge', 'badges'), $url,
|
||||
navigation_node::TYPE_SETTING, null, 'newbadge');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,11 @@ require_once(__DIR__ . '/../../filelib.php');
|
||||
*/
|
||||
class behat_util extends testing_util {
|
||||
|
||||
/**
|
||||
* The behat test site fullname and shortname.
|
||||
*/
|
||||
const BEHATSITENAME = "Acceptance test site";
|
||||
|
||||
/**
|
||||
* @var array Files to skip when resetting dataroot folder
|
||||
*/
|
||||
@@ -70,8 +75,8 @@ class behat_util extends testing_util {
|
||||
$options = array();
|
||||
$options['adminuser'] = 'admin';
|
||||
$options['adminpass'] = 'admin';
|
||||
$options['fullname'] = 'Acceptance test site';
|
||||
$options['shortname'] = 'Acceptance test site';
|
||||
$options['fullname'] = self::BEHATSITENAME;
|
||||
$options['shortname'] = self::BEHATSITENAME;
|
||||
|
||||
install_cli_database($options, false);
|
||||
|
||||
|
||||
@@ -2137,12 +2137,11 @@ class course_in_list implements IteratorAggregate {
|
||||
public function has_course_overviewfiles() {
|
||||
global $CFG;
|
||||
if (empty($CFG->courseoverviewfileslimit)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
require_once($CFG->libdir. '/filestorage/file_storage.php');
|
||||
$fs = get_file_storage();
|
||||
$context = context_course::instance($this->id);
|
||||
return $fs->is_area_empty($context->id, 'course', 'overviewfiles');
|
||||
return !$fs->is_area_empty($context->id, 'course', 'overviewfiles');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+33
-2
@@ -261,10 +261,10 @@ abstract class moodleform {
|
||||
$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 @@ abstract class moodleform {
|
||||
$this->_form->updateSubmission($submission, $files);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
+1
-3
@@ -228,9 +228,7 @@ class oauth_helper {
|
||||
// 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)) {
|
||||
|
||||
@@ -34,6 +34,8 @@ use Behat\Behat\Event\SuiteEvent as SuiteEvent,
|
||||
Behat\Behat\Event\StepEvent as StepEvent,
|
||||
WebDriver\Exception\NoSuchWindow as NoSuchWindow,
|
||||
WebDriver\Exception\UnexpectedAlertOpen as UnexpectedAlertOpen,
|
||||
WebDriver\Exception\UnknownError as UnknownError,
|
||||
WebDriver\Exception\CurlExec as CurlExec,
|
||||
WebDriver\Exception\NoAlertOpenError as NoAlertOpenError;
|
||||
|
||||
/**
|
||||
@@ -103,7 +105,9 @@ class behat_hooks extends behat_base {
|
||||
}
|
||||
|
||||
if (!behat_util::is_server_running()) {
|
||||
throw new Exception($CFG->behat_wwwroot . ' is not available, ensure you started your PHP built-in server. More info in ' . behat_command::DOCS_URL . '#Running_tests');
|
||||
throw new Exception($CFG->behat_wwwroot .
|
||||
' is not available, ensure you started your PHP built-in server or your web server is correctly started and set up.' .
|
||||
' More info in ' . behat_command::DOCS_URL . '#Running_tests');
|
||||
}
|
||||
|
||||
// Prevents using outdated data, upgrade script would start and tests would fail.
|
||||
@@ -139,9 +143,23 @@ class behat_hooks extends behat_base {
|
||||
throw new coding_exception('Behat only can modify the test database and the test dataroot!');
|
||||
}
|
||||
|
||||
try {
|
||||
$session = $this->getSession();
|
||||
} catch (CurlExec $e) {
|
||||
// Exception thrown by WebDriver, so only @javascript tests will be caugth; in
|
||||
// behat_util::is_server_running() we already checked that the server is running.
|
||||
$moreinfo = 'More info in ' . behat_command::DOCS_URL . '#Running_tests';
|
||||
$msg = 'Selenium server is not running, you need to start it to run tests that involve Javascript. ' . $moreinfo;
|
||||
throw new Exception($msg);
|
||||
} catch (UnknownError $e) {
|
||||
// Generic 'I have no idea' Selenium error. Custom exception to provide more feedback about possible solutions.
|
||||
$this->throw_unknown_exception($e);
|
||||
}
|
||||
|
||||
|
||||
// We need the Mink session to do it and we do it only before the first scenario.
|
||||
if (self::is_first_scenario()) {
|
||||
behat_selectors::register_moodle_selectors($this->getSession());
|
||||
behat_selectors::register_moodle_selectors($session);
|
||||
}
|
||||
|
||||
// Avoid some notices / warnings.
|
||||
@@ -164,19 +182,25 @@ class behat_hooks extends behat_base {
|
||||
if (!empty($CFG->behat_restart_browser_after) && $this->running_javascript()) {
|
||||
$now = time();
|
||||
if (self::$lastbrowsersessionstart + $CFG->behat_restart_browser_after < $now) {
|
||||
$this->getSession()->restart();
|
||||
$session->restart();
|
||||
self::$lastbrowsersessionstart = $now;
|
||||
}
|
||||
}
|
||||
|
||||
// Start always in the the homepage.
|
||||
$this->getSession()->visit($this->locate_path('/'));
|
||||
try {
|
||||
// Let's be conservative as we never know when new upstream issues will affect us.
|
||||
$session->visit($this->locate_path('/'));
|
||||
} catch (UnknownError $e) {
|
||||
$this->throw_unknown_exception($e);
|
||||
}
|
||||
|
||||
|
||||
// Checking that the root path is a Moodle test site.
|
||||
if (self::is_first_scenario()) {
|
||||
$notestsiteexception = new Exception('The base URL (' . $CFG->wwwroot . ') is not a behat test site, ' .
|
||||
'ensure you started the built-in web server in the correct directory');
|
||||
$this->find("xpath", "//head/child::title[normalize-space(.)='Acceptance test site']", $notestsiteexception);
|
||||
'ensure you started the built-in web server in the correct directory or your web server is correctly started and set up');
|
||||
$this->find("xpath", "//head/child::title[normalize-space(.)='" . behat_util::BEHATSITENAME . "']", $notestsiteexception);
|
||||
|
||||
self::$initprocessesfinished = true;
|
||||
}
|
||||
@@ -184,7 +208,7 @@ class behat_hooks extends behat_base {
|
||||
// Closing JS dialogs if present. Otherwise they would block this scenario execution.
|
||||
if ($this->running_javascript()) {
|
||||
try {
|
||||
$this->getSession()->getDriver()->getWebDriverSession()->accept_alert();
|
||||
$session->getDriver()->getWebDriverSession()->accept_alert();
|
||||
} catch (NoAlertOpenError $e) {
|
||||
// All ok, there should not be JS dialogs in theory.
|
||||
}
|
||||
@@ -192,27 +216,6 @@ class behat_hooks extends behat_base {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures selenium is running.
|
||||
*
|
||||
* Is only executed in scenarios which requires Javascript to run,
|
||||
* it returns a direct error message about what's going on.
|
||||
*
|
||||
* @throws Exception
|
||||
* @BeforeScenario @javascript
|
||||
*/
|
||||
public function before_scenario_javascript($event) {
|
||||
|
||||
// Just trying if server responds.
|
||||
try {
|
||||
$this->getSession()->wait(0, false);
|
||||
} catch (Exception $e) {
|
||||
$moreinfo = 'More info in ' . behat_command::DOCS_URL . '#Running_tests';
|
||||
$msg = 'Selenium server is not running, you need to start it to run tests that involves Javascript. ' . $moreinfo;
|
||||
throw new Exception($msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that all DOM is ready.
|
||||
*
|
||||
@@ -246,6 +249,9 @@ class behat_hooks extends behat_base {
|
||||
|
||||
} catch (NoSuchWindow $e) {
|
||||
// If we were interacting with a popup window it will not exists after closing it.
|
||||
} catch (UnknownError $e) {
|
||||
// Custom exception to provide more feedback about possible solutions.
|
||||
$this->throw_unknown_exception($e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,4 +369,17 @@ class behat_hooks extends behat_base {
|
||||
protected static function is_first_scenario() {
|
||||
return !(self::$initprocessesfinished);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception after appending an extra info text.
|
||||
*
|
||||
* @throws Exception
|
||||
* @param UnknownError $exception
|
||||
* @return void
|
||||
*/
|
||||
protected function throw_unknown_exception(UnknownError $exception) {
|
||||
$text = get_string('unknownexceptioninfo', 'tool_behat');
|
||||
throw new Exception($text . PHP_EOL . $exception->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -532,4 +532,116 @@ class coursecatlib_testcase extends advanced_testcase {
|
||||
|
||||
$CFG->coursecontact = $oldcoursecontact;
|
||||
}
|
||||
}
|
||||
|
||||
public function test_overview_files() {
|
||||
global $CFG;
|
||||
$this->setAdminUser();
|
||||
$cat1 = coursecat::create(array('name' => 'Cat1'));
|
||||
|
||||
// Create course c1 with one image file.
|
||||
$dratid1 = $this->fill_draft_area(array('filename.jpg' => 'Test file contents1'));
|
||||
$c1 = $this->getDataGenerator()->create_course(array('category' => $cat1->id,
|
||||
'fullname' => 'Test 1', 'overviewfiles_filemanager' => $dratid1));
|
||||
// Create course c2 with two image files (only one file will be added because of settings).
|
||||
$dratid2 = $this->fill_draft_area(array('filename21.jpg' => 'Test file contents21', 'filename22.jpg' => 'Test file contents22'));
|
||||
$c2 = $this->getDataGenerator()->create_course(array('category' => $cat1->id,
|
||||
'fullname' => 'Test 2', 'overviewfiles_filemanager' => $dratid2));
|
||||
// Create course c3 without files.
|
||||
$c3 = $this->getDataGenerator()->create_course(array('category' => $cat1->id, 'fullname' => 'Test 3'));
|
||||
|
||||
// Change the settings to allow multiple files of any types.
|
||||
$CFG->courseoverviewfileslimit = 3;
|
||||
$CFG->courseoverviewfilesext = '*';
|
||||
// Create course c5 with two image files.
|
||||
$dratid4 = $this->fill_draft_area(array('filename41.jpg' => 'Test file contents41', 'filename42.jpg' => 'Test file contents42'));
|
||||
$c4 = $this->getDataGenerator()->create_course(array('category' => $cat1->id,
|
||||
'fullname' => 'Test 4', 'overviewfiles_filemanager' => $dratid4));
|
||||
// Create course c6 with non-image file.
|
||||
$dratid5 = $this->fill_draft_area(array('filename51.zip' => 'Test file contents51'));
|
||||
$c5 = $this->getDataGenerator()->create_course(array('category' => $cat1->id,
|
||||
'fullname' => 'Test 5', 'overviewfiles_filemanager' => $dratid5));
|
||||
|
||||
// Reset default settings.
|
||||
$CFG->courseoverviewfileslimit = 1;
|
||||
$CFG->courseoverviewfilesext = '.jpg,.gif,.png';
|
||||
|
||||
$courses = $cat1->get_courses();
|
||||
$this->assertTrue($courses[$c1->id]->has_course_overviewfiles());
|
||||
$this->assertTrue($courses[$c2->id]->has_course_overviewfiles());
|
||||
$this->assertFalse($courses[$c3->id]->has_course_overviewfiles());
|
||||
$this->assertTrue($courses[$c4->id]->has_course_overviewfiles());
|
||||
$this->assertTrue($courses[$c5->id]->has_course_overviewfiles()); // Does not validate the filetypes.
|
||||
|
||||
$this->assertEquals(1, count($courses[$c1->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(1, count($courses[$c2->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(0, count($courses[$c3->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(1, count($courses[$c4->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(0, count($courses[$c5->id]->get_course_overviewfiles())); // Validate the filetypes.
|
||||
|
||||
// Overview files are not allowed, all functions return empty values.
|
||||
$CFG->courseoverviewfileslimit = 0;
|
||||
|
||||
$this->assertFalse($courses[$c1->id]->has_course_overviewfiles());
|
||||
$this->assertFalse($courses[$c2->id]->has_course_overviewfiles());
|
||||
$this->assertFalse($courses[$c3->id]->has_course_overviewfiles());
|
||||
$this->assertFalse($courses[$c4->id]->has_course_overviewfiles());
|
||||
$this->assertFalse($courses[$c5->id]->has_course_overviewfiles());
|
||||
|
||||
$this->assertEquals(0, count($courses[$c1->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(0, count($courses[$c2->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(0, count($courses[$c3->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(0, count($courses[$c4->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(0, count($courses[$c5->id]->get_course_overviewfiles()));
|
||||
|
||||
// Multiple overview files are allowed but still limited to images.
|
||||
$CFG->courseoverviewfileslimit = 3;
|
||||
|
||||
$this->assertTrue($courses[$c1->id]->has_course_overviewfiles());
|
||||
$this->assertTrue($courses[$c2->id]->has_course_overviewfiles());
|
||||
$this->assertFalse($courses[$c3->id]->has_course_overviewfiles());
|
||||
$this->assertTrue($courses[$c4->id]->has_course_overviewfiles());
|
||||
$this->assertTrue($courses[$c5->id]->has_course_overviewfiles()); // Still does not validate the filetypes.
|
||||
|
||||
$this->assertEquals(1, count($courses[$c1->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(1, count($courses[$c2->id]->get_course_overviewfiles())); // Only 1 file was actually added.
|
||||
$this->assertEquals(0, count($courses[$c3->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(2, count($courses[$c4->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(0, count($courses[$c5->id]->get_course_overviewfiles()));
|
||||
|
||||
// Multiple overview files of any type are allowed.
|
||||
$CFG->courseoverviewfilesext = '*';
|
||||
|
||||
$this->assertTrue($courses[$c1->id]->has_course_overviewfiles());
|
||||
$this->assertTrue($courses[$c2->id]->has_course_overviewfiles());
|
||||
$this->assertFalse($courses[$c3->id]->has_course_overviewfiles());
|
||||
$this->assertTrue($courses[$c4->id]->has_course_overviewfiles());
|
||||
$this->assertTrue($courses[$c5->id]->has_course_overviewfiles());
|
||||
|
||||
$this->assertEquals(1, count($courses[$c1->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(1, count($courses[$c2->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(0, count($courses[$c3->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(2, count($courses[$c4->id]->get_course_overviewfiles()));
|
||||
$this->assertEquals(1, count($courses[$c5->id]->get_course_overviewfiles()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a draft area for current user and fills it with fake files
|
||||
*
|
||||
* @param array $files array of files that need to be added to filearea, filename => filecontents
|
||||
* @return int draftid for the filearea
|
||||
*/
|
||||
protected function fill_draft_area(array $files) {
|
||||
global $USER;
|
||||
$usercontext = context_user::instance($USER->id);
|
||||
$draftid = file_get_unused_draft_itemid();
|
||||
foreach ($files as $filename => $filecontents) {
|
||||
// Add actual file there.
|
||||
$filerecord = array('component' => 'user', 'filearea' => 'draft',
|
||||
'contextid' => $usercontext->id, 'itemid' => $draftid,
|
||||
'filename' => $filename, 'filepath' => '/');
|
||||
$fs = get_file_storage();
|
||||
$fs->create_file_from_string($filerecord, $filecontents);
|
||||
}
|
||||
return $draftid;
|
||||
}
|
||||
}
|
||||
|
||||
+40
-9
@@ -2650,11 +2650,13 @@ class assign {
|
||||
if ($teamsubmission) {
|
||||
$showsubmit = $showedit &&
|
||||
$teamsubmission &&
|
||||
($teamsubmission->status == ASSIGN_SUBMISSION_STATUS_DRAFT);
|
||||
($teamsubmission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) &&
|
||||
!$this->submission_empty($teamsubmission);
|
||||
} else {
|
||||
$showsubmit = $showedit &&
|
||||
$submission &&
|
||||
($submission->status == ASSIGN_SUBMISSION_STATUS_DRAFT);
|
||||
($submission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) &&
|
||||
!$this->submission_empty($submission);
|
||||
}
|
||||
if (!$this->get_instance()->submissiondrafts) {
|
||||
$showsubmit = false;
|
||||
@@ -3308,11 +3310,17 @@ class assign {
|
||||
}
|
||||
}
|
||||
|
||||
$showsubmit = ($submission || $teamsubmission) && $showlinks;
|
||||
if ($teamsubmission && ($teamsubmission->status != ASSIGN_SUBMISSION_STATUS_DRAFT)) {
|
||||
$showsubmit = ($submission || $teamsubmission) && $showlinks && $this->submissions_open($user->id);
|
||||
if ($teamsubmission && ($teamsubmission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED)) {
|
||||
$showsubmit = false;
|
||||
}
|
||||
if ($submission && ($submission->status != ASSIGN_SUBMISSION_STATUS_DRAFT)) {
|
||||
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) {
|
||||
@@ -4209,6 +4217,9 @@ class assign {
|
||||
require_once($CFG->dirroot . '/mod/assign/submissionconfirmform.php');
|
||||
require_sesskey();
|
||||
|
||||
if (!$this->submissions_open()) {
|
||||
return $this->view_student_error_message();
|
||||
}
|
||||
$instance = $this->get_instance();
|
||||
$data = new stdClass();
|
||||
$adminconfig = $this->get_admin_config();
|
||||
@@ -4745,6 +4756,25 @@ class assign {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@@ -4762,6 +4792,10 @@ class assign {
|
||||
// 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;
|
||||
}
|
||||
$instance = $this->get_instance();
|
||||
|
||||
$data = new stdClass();
|
||||
@@ -4789,7 +4823,6 @@ class assign {
|
||||
return true;
|
||||
}
|
||||
|
||||
$allempty = true;
|
||||
$pluginerror = false;
|
||||
foreach ($this->submissionplugins as $plugin) {
|
||||
if ($plugin->is_enabled() && $plugin->is_visible()) {
|
||||
@@ -4797,11 +4830,9 @@ class assign {
|
||||
$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');
|
||||
|
||||
@@ -292,6 +292,43 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
|
||||
$this->assertEquals($now, $instance->duedate);
|
||||
}
|
||||
|
||||
public function test_cannot_submit_empty() {
|
||||
global $PAGE;
|
||||
|
||||
$this->setUser($this->editingteachers[0]);
|
||||
$assign = $this->create_instance(array('submissiondrafts'=>1));
|
||||
|
||||
$PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
|
||||
|
||||
// Test you cannot see the submit button for an offline assignment regardless.
|
||||
$this->setUser($this->students[0]);
|
||||
$output = $assign->view_student_summary($this->students[0], true);
|
||||
$this->assertNotContains(get_string('submitassignment', 'assign'), $output, 'Can submit empty offline assignment');
|
||||
|
||||
// Test you cannot see the submit button for an online text assignment with no submission.
|
||||
$this->setUser($this->editingteachers[0]);
|
||||
$instance = $assign->get_instance();
|
||||
$instance->instance = $instance->id;
|
||||
$instance->assignsubmission_onlinetext_enabled = 1;
|
||||
|
||||
$assign->update_instance($instance);
|
||||
$this->setUser($this->students[0]);
|
||||
$output = $assign->view_student_summary($this->students[0], true);
|
||||
$this->assertNotContains(get_string('submitassignment', 'assign'), $output, 'Cannot submit empty onlinetext assignment');
|
||||
|
||||
// Simulate a submission.
|
||||
$submission = $assign->get_user_submission($this->students[0]->id, true);
|
||||
$data = new stdClass();
|
||||
$data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
|
||||
'text'=>'Submission text',
|
||||
'format'=>FORMAT_MOODLE);
|
||||
$plugin = $assign->get_submission_plugin_by_type('onlinetext');
|
||||
$plugin->save($submission, $data);
|
||||
// Test you can see the submit button for an online text assignment with a submission.
|
||||
$output = $assign->view_student_summary($this->students[0], true);
|
||||
$this->assertContains(get_string('submitassignment', 'assign'), $output, 'Can submit non empty onlinetext assignment');
|
||||
}
|
||||
|
||||
public function test_list_participants() {
|
||||
$this->create_extra_users();
|
||||
$this->setUser($this->editingteachers[0]);
|
||||
@@ -740,5 +777,48 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
|
||||
$grades = $assign->get_user_grades_for_gradebook($this->students[0]->id);
|
||||
$this->assertEquals(50, (int)$grades[$this->students[0]->id]->rawgrade);
|
||||
}
|
||||
|
||||
public function test_disable_submit_after_cutoff_date() {
|
||||
global $PAGE;
|
||||
|
||||
$this->setUser($this->editingteachers[0]);
|
||||
$now = time();
|
||||
$tomorrow = $now + 24*60*60;
|
||||
$lastweek = $now - 7*24*60*60;
|
||||
$yesterday = $now - 24*60*60;
|
||||
|
||||
$assign = $this->create_instance(array('duedate'=>$yesterday,
|
||||
'cutoffdate'=>$tomorrow,
|
||||
'assignsubmission_onlinetext_enabled'=>1));
|
||||
$PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id)));
|
||||
|
||||
// Student should be able to see an add submission button.
|
||||
$this->setUser($this->students[0]);
|
||||
$output = $assign->view_student_summary($this->students[0], true);
|
||||
$this->assertNotEquals(false, strpos($output, get_string('addsubmission', 'assign')));
|
||||
|
||||
// Add a submission but don't submit now.
|
||||
$submission = $assign->get_user_submission($this->students[0]->id, true);
|
||||
$data = new stdClass();
|
||||
$data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
|
||||
'text'=>'Submission text',
|
||||
'format'=>FORMAT_MOODLE);
|
||||
$plugin = $assign->get_submission_plugin_by_type('onlinetext');
|
||||
$plugin->save($submission, $data);
|
||||
|
||||
// Create another instance with cut-off and due-date already passed.
|
||||
$this->setUser($this->editingteachers[0]);
|
||||
$now = time();
|
||||
$assign = $this->create_instance(array('duedate'=>$lastweek,
|
||||
'cutoffdate'=>$yesterday,
|
||||
'assignsubmission_onlinetext_enabled'=>1));
|
||||
|
||||
$this->setUser($this->students[0]);
|
||||
$output = $assign->view_student_summary($this->students[0], true);
|
||||
$this->assertNotContains($output, get_string('editsubmission', 'assign'),
|
||||
'Should not be able to edit after cutoff date.');
|
||||
$this->assertNotContains($output, get_string('submitassignment', 'assign'),
|
||||
'Should not be able to submit after cutoff date.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -191,7 +191,7 @@ if (!$book->customtitles) {
|
||||
}
|
||||
}
|
||||
$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();
|
||||
|
||||
|
||||
+5
-45
@@ -3471,9 +3471,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('div', '('.get_string('numwords', 'moodle', count_words($post->message)).')',
|
||||
array('class'=>'post-word-count'));
|
||||
@@ -3817,50 +3818,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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,6 +33,11 @@ require_once($CFG->dirroot . '/mod/resource/backup/moodle2/backup_resource_steps
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@@ -53,18 +58,70 @@ class backup_resource_activity_task extends backup_activity_task {
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,4 +40,5 @@
|
||||
.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;}
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ Thanks very much.';
|
||||
$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.
|
||||
|
||||
|
||||
+23
-17
@@ -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> ";
|
||||
$qnum++;
|
||||
echo "<span class=\"preferthat smalltext\">$stripreferthat</span> ";
|
||||
echo "<span class=\"preferthat\">$stripreferthat</span> ";
|
||||
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> ";
|
||||
echo "<span class=\"foundthat smalltext\">$strifoundthat</span> ";
|
||||
echo "<span class=\"foundthat\">$strifoundthat</span> ";
|
||||
echo "<span class=\"option\">$q->text</span></th>\n";
|
||||
|
||||
$default = get_accesshide($strdefault);
|
||||
|
||||
@@ -56,8 +56,12 @@ class qformat_blackboard_six_pool_test extends question_testcase {
|
||||
|
||||
$q = $questions[5];
|
||||
|
||||
// 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 @@ class qformat_blackboard_six_pool_test extends question_testcase {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,8 +53,12 @@ class qformat_blackboard_six_qti_test extends question_testcase {
|
||||
$questions = $importer->readquestions($xml);
|
||||
$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 = 'Classify the animals.';
|
||||
$expectedq->questiontextformat = FORMAT_HTML;
|
||||
@@ -75,7 +79,16 @@ class qformat_blackboard_six_qti_test extends question_testcase {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -30,3 +30,4 @@ $string['url'] = 'URL';
|
||||
$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.';
|
||||
|
||||
@@ -168,6 +168,8 @@ EOD;
|
||||
} 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
|
||||
|
||||
@@ -119,6 +119,9 @@
|
||||
#searchform_search {
|
||||
width: auto;
|
||||
}
|
||||
.block_rss_client .list li {
|
||||
border-top-color: darken(@wellBackground, 7%);
|
||||
}
|
||||
|
||||
// Overide for RTL layout.
|
||||
.dir-rtl {
|
||||
|
||||
@@ -174,3 +174,12 @@ img.icon-pre {
|
||||
.opacity(100);
|
||||
display: inline;
|
||||
}
|
||||
|
||||
// Extends bootstrapbase/less/bootstrap/navbar.less
|
||||
// to enable scroll in longer menus especially language menu.
|
||||
|
||||
.open > .dropdown-menu {
|
||||
display: block;
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -35,8 +35,7 @@ body {
|
||||
.errorbox,
|
||||
.continuebutton,
|
||||
.singlebutton,
|
||||
.buttons,
|
||||
.singleselect {
|
||||
.buttons {
|
||||
text-align: center;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
@@ -236,14 +236,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 */
|
||||
|
||||
@@ -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 **/
|
||||
|
||||
+2
-2
@@ -29,11 +29,11 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2013051402.00; // 20130514 = branching date YYYYMMDD - do not modify!
|
||||
$version = 2013051402.01; // 20130514 = branching date YYYYMMDD - do not modify!
|
||||
// RR = release increments - 00 in DEV branches
|
||||
// .XX = incremental changes
|
||||
|
||||
$release = '2.5.2 (Build: 20130909)'; // Human-friendly version name
|
||||
$release = '2.5.2+ (Build: 20130913)'; // Human-friendly version name
|
||||
|
||||
$branch = '25'; // this version's branch
|
||||
$maturity = MATURITY_STABLE; // this version's maturity level
|
||||
|
||||
Reference in New Issue
Block a user