Merge branch 'MOODLE_25_STABLE' into install_25_STABLE
This commit is contained in:
+3
-1
@@ -1001,9 +1001,11 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
} else {
|
||||
$str = 'otherplugin';
|
||||
}
|
||||
$componenturl = new moodle_url('https://moodle.org/plugins/view.php?plugin='.$component);
|
||||
$componenturl = html_writer::tag('a', $component, array('href' => $componenturl->out()));
|
||||
$requires[] = html_writer::tag('li',
|
||||
get_string($str, 'core_plugin',
|
||||
array('component' => $component, 'version' => $requiredversion)),
|
||||
array('component' => $componenturl, 'version' => $requiredversion)),
|
||||
array('class' => $class));
|
||||
}
|
||||
|
||||
|
||||
@@ -143,8 +143,10 @@ if (($action == 'edit') || ($action == 'new')) {
|
||||
$success = $repositorytype->update_options($settings);
|
||||
} else {
|
||||
$type = new repository_type($plugin, (array)$fromform, $visible);
|
||||
$type->create();
|
||||
$success = true;
|
||||
if (!$repoid = $type->create()) {
|
||||
$success = false;
|
||||
}
|
||||
$data = data_submitted();
|
||||
}
|
||||
if ($success) {
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/behat/classes/behat_command.php');
|
||||
require_once($CFG->libdir . '/behat/classes/behat_selectors.php');
|
||||
|
||||
/**
|
||||
* Renderer for behat tool web features
|
||||
@@ -92,7 +92,7 @@ class tool_behat_renderer extends plugin_renderer_base {
|
||||
// Replace text selector type arguments with a user-friendly select.
|
||||
$stepsdefinitions = preg_replace_callback('/(TEXT_SELECTOR\d?_STRING)/',
|
||||
function ($matches) {
|
||||
return html_writer::select(behat_command::$allowedtextselectors, uniqid());
|
||||
return html_writer::select(behat_selectors::get_allowed_text_selectors(), uniqid());
|
||||
},
|
||||
$stepsdefinitions
|
||||
);
|
||||
@@ -100,7 +100,7 @@ class tool_behat_renderer extends plugin_renderer_base {
|
||||
// Replace selector type arguments with a user-friendly select.
|
||||
$stepsdefinitions = preg_replace_callback('/(SELECTOR\d?_STRING)/',
|
||||
function ($matches) {
|
||||
return html_writer::select(behat_command::$allowedselectors, uniqid());
|
||||
return html_writer::select(behat_selectors::get_allowed_selectors(), uniqid());
|
||||
},
|
||||
$stepsdefinitions
|
||||
);
|
||||
|
||||
@@ -35,7 +35,7 @@ Feature: Page contents assertions
|
||||
| Course 1 | C1 | 0 |
|
||||
And I log in as "admin"
|
||||
And I follow "Course 1"
|
||||
When I click on "Move this to the dock" "button" in the ".block_settings" "css_element"
|
||||
When I click on "Move this to the dock" "button" in the "Administration" "block"
|
||||
Then I should not see "Question bank"
|
||||
And I click on "//div[@id='dock']/descendant::h2[normalize-space(.)='Administration']" "xpath_element"
|
||||
|
||||
@@ -45,5 +45,5 @@ Feature: Page contents assertions
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And I log in as "admin"
|
||||
When I click on "Move this to the dock" "button" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' block_settings ')]" "xpath_element"
|
||||
When I click on "Move this to the dock" "button" in the "Administration" "block"
|
||||
Then I should not see "Turn editing on"
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['install'] = 'Install selected language pack';
|
||||
$string['install'] = 'Install selected language pack(s)';
|
||||
$string['installedlangs'] = 'Installed language packs';
|
||||
$string['langimport'] = 'Language import utility';
|
||||
$string['langimportdisabled'] = 'Language import feature has been disabled. You have to update your language packs manually at the file-system level. Do not forget to purge string caches after you do so.';
|
||||
@@ -38,7 +38,7 @@ $string['nolangupdateneeded'] = 'All your language packs are up to date, no upda
|
||||
$string['pluginname'] = 'Language packs';
|
||||
$string['purgestringcaches'] = 'Purge string caches';
|
||||
$string['remotelangnotavailable'] = 'Because Moodle cannot connect to download.moodle.org, it is not possible for language packs to be installed automatically. Please download the appropriate ZIP file(s) from <a href="http://download.moodle.org/langpack/">download.moodle.org/langpack</a>, copy them to your {$a} directory and unzip them manually.';
|
||||
$string['uninstall'] = 'Uninstall selected language pack';
|
||||
$string['uninstall'] = 'Uninstall selected language pack(s)';
|
||||
$string['uninstallconfirm'] = 'You are about to completely uninstall language pack {$a}, are you sure?';
|
||||
$string['updatelangs'] = 'Update all installed language packs';
|
||||
|
||||
|
||||
@@ -33,24 +33,38 @@ $string['confirmdeleteindex'] = 'Are you absolutely sure that you want to delete
|
||||
$string['confirmdeletekey'] = 'Are you absolutely sure that you want to delete the key:';
|
||||
$string['confirmdeletetable'] = 'Are you absolutely sure that you want to delete the table:';
|
||||
$string['confirmdeletexmlfile'] = 'Are you absolutely sure that you want to delete the file:';
|
||||
$string['confirmcheckbigints'] = 'This functionality will search for <a href="http://tracker.moodle.org/browse/MDL-11038">potential wrong integer fields</a> in your Moodle server, generating (but not executing!) automatically the needed SQL statements to have all the integers in your DB properly defined.<br /><br />
|
||||
Once generated you can copy such statements and execute them safely with your favourite SQL interface (don\'t forget to backup your data before doing that).<br /><br />
|
||||
It\'s highly recommended to be running the latest (+ version) available of your Moodle release (1.8, 1.9, 2.x ...) before executing the search of wrong integers.<br /><br />
|
||||
$string['confirmcheckbigints'] = 'This functionality will search for <a href="http://tracker.moodle.org/browse/MDL-11038">potential wrong integer fields</a> in your Moodle server, generating (but not executing!) automatically the needed SQL statements to have all the integers in your DB properly defined.
|
||||
|
||||
Once generated you can copy such statements and execute them safely with your favourite SQL interface (don\'t forget to backup your data before doing that).
|
||||
|
||||
It\'s highly recommended to be running the latest (+ version) available of your Moodle release before executing the search of wrong integers.
|
||||
|
||||
This functionality doesn\'t perform any action against the DB (just reads from it), so can be safely executed at any moment.';
|
||||
$string['confirmcheckdefaults'] = 'This functionality will search for inconsistent default values in your Moodle server, generating (but not executing!) the needed SQL statements to have all the default values properly defined.<br /><br />
|
||||
Once generated you can copy such statements and execute them safely with your favourite SQL interface (don\'t forget to backup your data before doing that).<br /><br />
|
||||
It\'s highly recommended to be running the latest (+ version) available of your Moodle release (1.8, 1.9, 2.x ...) before executing the search of inconsistent default values.<br /><br />
|
||||
$string['confirmcheckdefaults'] = 'This functionality will search for inconsistent default values in your Moodle server, generating (but not executing!) the needed SQL statements to have all the default values properly defined.
|
||||
|
||||
Once generated you can copy such statements and execute them safely with your favourite SQL interface (don\'t forget to backup your data before doing that).
|
||||
|
||||
It\'s highly recommended to be running the latest (+ version) available of your Moodle release before executing the search of inconsistent default values.
|
||||
|
||||
This functionality doesn\'t perform any action against the DB (just reads from it), so can be safely executed at any moment.';
|
||||
$string['confirmcheckforeignkeys'] = 'This functionality will search for potential violations of the foreign keys defined in the install.xml definitions. (Moodle does not currently generate actual foreign key constraints in the database, which is why invalid data may be present.)<br /><br />
|
||||
It\'s highly recommended to be running the latest (+ version) available of your Moodle release (1.8, 1.9, 2.x ...) before executing the search of missing indexes.<br /><br />
|
||||
$string['confirmcheckforeignkeys'] = 'This functionality will search for potential violations of the foreign keys defined in the install.xml definitions. (Moodle does not currently generate actual foreign key constraints in the database, which is why invalid data may be present.)
|
||||
|
||||
It\'s highly recommended to be running the latest (+ version) available of your Moodle release before executing the search of missing indexes.
|
||||
|
||||
This functionality doesn\'t perform any action against the DB (just reads from it), so can be safely executed at any moment.';
|
||||
$string['confirmcheckindexes'] = 'This functionality will search for potential missing indexes in your Moodle server, generating (but not executing!) automatically the needed SQL statements to keep everything updated.<br /><br />
|
||||
Once generated you can copy such statements and execute them safely with your favourite SQL interface (don\'t forget to backup your data before doing that).<br /><br />
|
||||
It\'s highly recommended to be running the latest (+ version) available of your Moodle release (1.8, 1.9, 2.x ...) before executing the search of missing indexes.<br /><br />
|
||||
$string['confirmcheckindexes'] = 'This functionality will search for potential missing indexes in your Moodle server, generating (but not executing!) automatically the needed SQL statements to keep everything updated.
|
||||
|
||||
Once generated you can copy such statements and execute them safely with your favourite SQL interface (don\'t forget to backup your data before doing that).
|
||||
|
||||
It\'s highly recommended to be running the latest (+ version) available of your Moodle release before executing the search of missing indexes.
|
||||
|
||||
This functionality doesn\'t perform any action against the DB (just reads from it), so can be safely executed at any moment.';
|
||||
$string['confirmcheckoraclesemantics'] = 'This functionality will search for <a href="http://tracker.moodle.org/browse/MDL-29322">Oracle varchar2 columns using BYTE semantics</a> in your Moodle server, generating (but not executing!) automatically the needed SQL statements to have all the columns converted to use CHAR semantics instead (better for cross-db compatibility and increased contents max. length).<br /><br />
|
||||
Once generated you can copy such statements and execute them safely with your favourite SQL interface (don\'t forget to backup your data before doing that).<br /><br />
|
||||
It\'s highly recommended to be running the latest (+ version) available of your Moodle release (2.2, 2.3, 2.x ...) before executing the search of BYTE semantics.<br /><br />
|
||||
$string['confirmcheckoraclesemantics'] = 'This functionality will search for <a href="http://tracker.moodle.org/browse/MDL-29322">Oracle varchar2 columns using BYTE semantics</a> in your Moodle server, generating (but not executing!) automatically the needed SQL statements to have all the columns converted to use CHAR semantics instead (better for cross-db compatibility and increased contents max. length).
|
||||
|
||||
Once generated you can copy such statements and execute them safely with your favourite SQL interface (don\'t forget to backup your data before doing that).
|
||||
|
||||
It\'s highly recommended to be running the latest (+ version) available of your Moodle release before executing the search of BYTE semantics.
|
||||
|
||||
This functionality doesn\'t perform any action against the DB (just reads from it), so can be safely executed at any moment.';
|
||||
$string['confirmrevertchanges'] = 'Are you absolutely sure that you want to revert changes performed over:';
|
||||
$string['create'] = 'Create';
|
||||
|
||||
@@ -13,8 +13,9 @@ Feature: Backup Moodle courses
|
||||
@javascript
|
||||
Scenario: Backup a course providing options
|
||||
When I backup "Course 1" course using this options:
|
||||
| Filename | test_backup.mbz |
|
||||
Then I should see "Restore"
|
||||
And I click on "Restore" "link" in the ".backup-files-table" "css_element"
|
||||
And I click on "Restore" "link" in the "test_backup.mbz" "table_row"
|
||||
And I should see "URL of backup"
|
||||
And I should see "Anonymize user information"
|
||||
|
||||
@@ -27,11 +28,11 @@ Feature: Backup Moodle courses
|
||||
| setting_section_section_5_userinfo | 0 |
|
||||
| setting_section_section_5_included | 0 |
|
||||
Then I should see "Restore"
|
||||
And I click on "Restore" "link" in the ".backup-files-table" "css_element"
|
||||
And I click on "Restore" "link" in the "test_backup.mbz" "table_row"
|
||||
And I should not see "Section 3"
|
||||
And I press "Continue"
|
||||
And I click on "Continue" "button" in the ".bcs-current-course" "css_element"
|
||||
And "//div[contains(concat(' ', normalize-space(@class), ' '), ' fitem ')][contains(., 'Include calendar events')]/descendant::img" "xpath_element" should exists
|
||||
And I check "Include course logs"
|
||||
And I press "Cancel"
|
||||
And I click on "Cancel" "button" in the ".confirmation-dialogue" "css_element"
|
||||
And I click on "Cancel" "button" in the "Cancel backup" "dialogue"
|
||||
|
||||
+48
-3
@@ -27,14 +27,59 @@
|
||||
require_once(dirname(dirname(__FILE__)) . '/config.php');
|
||||
require_once($CFG->libdir . '/badgeslib.php');
|
||||
|
||||
$json = required_param('badge', PARAM_RAW);
|
||||
$json = optional_param('badge', null, PARAM_RAW);
|
||||
// Redirect to homepage if users are trying to access external badge through old url.
|
||||
if ($json) {
|
||||
redirect($CFG->wwwroot, get_string('invalidrequest', 'error'), 3);
|
||||
}
|
||||
|
||||
$hash = required_param('hash', PARAM_ALPHANUM);
|
||||
$userid = required_param('user', PARAM_INT);
|
||||
|
||||
$PAGE->set_url(new moodle_url('/badges/external.php', array('hash' => $hash, 'user' => $userid)));
|
||||
|
||||
// Using the same setting as user profile page.
|
||||
if (!empty($CFG->forceloginforprofiles)) {
|
||||
require_login();
|
||||
if (isguestuser()) {
|
||||
$SESSION->wantsurl = $PAGE->url->out(false);
|
||||
redirect(get_login_url());
|
||||
}
|
||||
} else if (!empty($CFG->forcelogin)) {
|
||||
require_login();
|
||||
}
|
||||
|
||||
// Get all external badges of a user.
|
||||
$out = get_backpack_settings($userid);
|
||||
|
||||
// If we didn't find any badges then print an error.
|
||||
if (is_null($out)) {
|
||||
print_error('error:externalbadgedoesntexist', 'badges');
|
||||
}
|
||||
|
||||
$badges = $out->badges;
|
||||
|
||||
// The variable to store the badge we want.
|
||||
$badge = '';
|
||||
|
||||
// Loop through the badges and check if supplied badge hash exists in user external badges.
|
||||
foreach ($badges as $b) {
|
||||
if ($hash == hash("md5", $b->hostedUrl)) {
|
||||
$badge = $b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find the badge a user might be trying to replace the userid parameter.
|
||||
if (empty($badge)) {
|
||||
print_error('error:externalbadgedoesntexist', 'badges');
|
||||
}
|
||||
|
||||
$PAGE->set_context(context_system::instance());
|
||||
$output = $PAGE->get_renderer('core', 'badges');
|
||||
|
||||
$badge = new external_badge(unserialize($json));
|
||||
$badge = new external_badge($badge, $userid);
|
||||
|
||||
$PAGE->set_url('/badges/external.php');
|
||||
$PAGE->set_pagelayout('base');
|
||||
$PAGE->set_title(get_string('issuedbadge', 'badges'));
|
||||
|
||||
|
||||
@@ -53,11 +53,13 @@ $PAGE->set_heading($title);
|
||||
$PAGE->set_pagelayout('mydashboard');
|
||||
|
||||
$backpack = $DB->get_record('badge_backpack', array('userid' => $USER->id));
|
||||
$badgescache = cache::make('core', 'externalbadges');
|
||||
|
||||
if ($disconnect && $backpack) {
|
||||
require_sesskey();
|
||||
$DB->delete_records('badge_external', array('backpackid' => $backpack->id));
|
||||
$DB->delete_records('badge_backpack', array('userid' => $USER->id));
|
||||
$badgescache->delete($USER->id);
|
||||
redirect(new moodle_url('/badges/mybackpack.php'));
|
||||
}
|
||||
|
||||
@@ -103,6 +105,7 @@ if ($backpack) {
|
||||
$DB->insert_record('badge_external', $obj);
|
||||
}
|
||||
}
|
||||
$badgescache->delete($USER->id);
|
||||
redirect(new moodle_url('/badges/mybadges.php'));
|
||||
}
|
||||
} else {
|
||||
|
||||
+85
-14
@@ -81,9 +81,10 @@ class core_badges_renderer extends plugin_renderer_base {
|
||||
$url = new moodle_url('badge.php', array('hash' => $badge->uniquehash));
|
||||
} else {
|
||||
if (!$external) {
|
||||
$url = new moodle_url($CFG->wwwroot . '/badges/badge.php', array('hash' => $badge->uniquehash));
|
||||
$url = new moodle_url('/badges/badge.php', array('hash' => $badge->uniquehash));
|
||||
} else {
|
||||
$url = new moodle_url($CFG->wwwroot . '/badges/external.php', array('badge' => serialize($badge)));
|
||||
$hash = hash('md5', $badge->hostedUrl);
|
||||
$url = new moodle_url('/badges/external.php', array('hash' => $hash, 'user' => $userid));
|
||||
}
|
||||
}
|
||||
$actions = html_writer::tag('div', $push . $download . $status, array('class' => 'badge-actions'));
|
||||
@@ -276,6 +277,7 @@ class core_badges_renderer extends plugin_renderer_base {
|
||||
protected function render_issued_badge(issued_badge $ibadge) {
|
||||
global $USER, $CFG, $DB;
|
||||
$issued = $ibadge->issued;
|
||||
$userinfo = $ibadge->recipient;
|
||||
$badge = new badge($ibadge->badgeid);
|
||||
$today_date = date('Y-m-d');
|
||||
$today = strtotime($today_date);
|
||||
@@ -286,7 +288,7 @@ class core_badges_renderer extends plugin_renderer_base {
|
||||
$imagetable = new html_table();
|
||||
$imagetable->attributes = array('class' => 'clearfix badgeissuedimage');
|
||||
$imagetable->data[] = array(html_writer::empty_tag('img', array('src' => $issued['badge']['image'])));
|
||||
if ($USER->id == $ibadge->recipient && !empty($CFG->enablebadges)) {
|
||||
if ($USER->id == $userinfo->id && !empty($CFG->enablebadges)) {
|
||||
$imagetable->data[] = array($this->output->single_button(
|
||||
new moodle_url('/badges/badge.php', array('hash' => $ibadge->hash, 'bake' => true)),
|
||||
get_string('download'),
|
||||
@@ -307,11 +309,20 @@ class core_badges_renderer extends plugin_renderer_base {
|
||||
$datatable = new html_table();
|
||||
$datatable->attributes = array('class' => 'badgeissuedinfo');
|
||||
$datatable->colclasses = array('bfield', 'bvalue');
|
||||
|
||||
// Recipient information.
|
||||
$datatable->data[] = array($this->output->heading(get_string('recipientdetails', 'badges'), 3), '');
|
||||
$datatable->data[] = array(get_string('name'), fullname($userinfo));
|
||||
if (empty($userinfo->backpackemail)) {
|
||||
$datatable->data[] = array(get_string('email'), obfuscate_mailto($userinfo->accountemail));
|
||||
} else {
|
||||
$datatable->data[] = array(get_string('email'), obfuscate_mailto($userinfo->backpackemail));
|
||||
}
|
||||
|
||||
$datatable->data[] = array($this->output->heading(get_string('issuerdetails', 'badges'), 3), '');
|
||||
$datatable->data[] = array(get_string('issuername', 'badges'), $badge->issuername);
|
||||
if (isset($badge->issuercontact) && !empty($badge->issuercontact)) {
|
||||
$datatable->data[] = array(get_string('contact', 'badges'),
|
||||
html_writer::tag('a', $badge->issuercontact, array('href' => 'mailto:' . $badge->issuercontact)));
|
||||
$datatable->data[] = array(get_string('contact', 'badges'), obfuscate_mailto($badge->issuercontact));
|
||||
}
|
||||
$datatable->data[] = array($this->output->heading(get_string('badgedetails', 'badges'), 3), '');
|
||||
$datatable->data[] = array(get_string('name'), $badge->name);
|
||||
@@ -347,7 +358,7 @@ class core_badges_renderer extends plugin_renderer_base {
|
||||
|
||||
// Print evidence.
|
||||
$agg = $badge->get_aggregation_methods();
|
||||
$evidence = $badge->get_criteria_completions($ibadge->recipient);
|
||||
$evidence = $badge->get_criteria_completions($userinfo->id);
|
||||
$eids = array_map(create_function('$o', 'return $o->critid;'), $evidence);
|
||||
unset($badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]);
|
||||
|
||||
@@ -378,6 +389,7 @@ class core_badges_renderer extends plugin_renderer_base {
|
||||
$issued = $ibadge->issued;
|
||||
$assertion = $issued->assertion;
|
||||
$issuer = $assertion->badge->issuer;
|
||||
$userinfo = $ibadge->recipient;
|
||||
$table = new html_table();
|
||||
|
||||
$imagetable = new html_table();
|
||||
@@ -387,13 +399,29 @@ class core_badges_renderer extends plugin_renderer_base {
|
||||
$datatable = new html_table();
|
||||
$datatable->attributes = array('class' => 'badgeissuedinfo');
|
||||
$datatable->colclasses = array('bfield', 'bvalue');
|
||||
|
||||
// Recipient information.
|
||||
$datatable->data[] = array($this->output->heading(get_string('recipientdetails', 'badges'), 3), '');
|
||||
// Technically, we should alway have a user at this point, but added an extra check just in case.
|
||||
if ($userinfo) {
|
||||
$datatable->data[] = array(get_string('name'), fullname($userinfo));
|
||||
if (!$ibadge->valid) {
|
||||
$notify = $this->output->notification(get_string('recipientvalidationproblem', 'badges'), 'notifynotice');
|
||||
$datatable->data[] = array(get_string('email'), obfuscate_mailto($userinfo->email) . $notify);
|
||||
} else {
|
||||
$datatable->data[] = array(get_string('email'), obfuscate_mailto($userinfo->email));
|
||||
}
|
||||
} else {
|
||||
$notify = $this->output->notification(get_string('recipientidentificationproblem', 'badges'), 'notifynotice');
|
||||
$datatable->data[] = array(get_string('name'), $notify);
|
||||
}
|
||||
|
||||
$datatable->data[] = array($this->output->heading(get_string('issuerdetails', 'badges'), 3), '');
|
||||
$datatable->data[] = array(get_string('issuername', 'badges'), $issuer->name);
|
||||
$datatable->data[] = array(get_string('issuerurl', 'badges'),
|
||||
html_writer::tag('a', $issuer->origin, array('href' => $issuer->origin)));
|
||||
if (isset($issuer->contact)) {
|
||||
$datatable->data[] = array(get_string('contact', 'badges'),
|
||||
html_writer::tag('a', $issuer->contact, array('href' => 'mailto:' . $issuer->contact)));
|
||||
$datatable->data[] = array(get_string('contact', 'badges'), obfuscate_mailto($issuer->contact));
|
||||
}
|
||||
$datatable->data[] = array($this->output->heading(get_string('badgedetails', 'badges'), 3), '');
|
||||
$datatable->data[] = array(get_string('name'), $assertion->badge->name);
|
||||
@@ -875,7 +903,7 @@ class issued_badge implements renderable {
|
||||
public $issued;
|
||||
|
||||
/** @var badge recipient */
|
||||
public $recipient = 0;
|
||||
public $recipient;
|
||||
|
||||
/** @var badge visibility to others */
|
||||
public $visible = 0;
|
||||
@@ -901,7 +929,12 @@ class issued_badge implements renderable {
|
||||
WHERE ' . $DB->sql_compare_text('uniquehash', 40) . ' = ' . $DB->sql_compare_text(':hash', 40),
|
||||
array('hash' => $hash), IGNORE_MISSING);
|
||||
if ($rec) {
|
||||
$this->recipient = $rec->userid;
|
||||
// Get a recipient from database.
|
||||
$user = $DB->get_record_sql('SELECT u.id, u.lastname, u.firstname,
|
||||
u.email AS accountemail, b.email AS backpackemail
|
||||
FROM {user} u LEFT JOIN {badge_backpack} b ON u.id = b.userid
|
||||
WHERE u.id = :userid', array('userid' => $rec->userid));
|
||||
$this->recipient = $user;
|
||||
$this->visible = $rec->visible;
|
||||
$this->badgeid = $rec->badgeid;
|
||||
}
|
||||
@@ -915,13 +948,51 @@ class external_badge implements renderable {
|
||||
/** @var issued badge */
|
||||
public $issued;
|
||||
|
||||
/** @var User ID */
|
||||
public $recipient;
|
||||
|
||||
/** @var validation of external badge */
|
||||
public $valid = true;
|
||||
|
||||
/**
|
||||
* Initializes the badge to display
|
||||
*
|
||||
* @param string $json External badge information.
|
||||
* @param object $badge External badge information.
|
||||
* @param int $recipient User id.
|
||||
*/
|
||||
public function __construct($json) {
|
||||
$this->issued = $json;
|
||||
public function __construct($badge, $recipient) {
|
||||
global $DB;
|
||||
// At this point a user has connected a backpack. So, we are going to get
|
||||
// their backpack email rather than their account email.
|
||||
$user = $DB->get_record_sql('SELECT u.lastname, u.firstname, b.email
|
||||
FROM {user} u INNER JOIN {badge_backpack} b ON u.id = b.userid
|
||||
WHERE userid = :userid', array('userid' => $recipient), IGNORE_MISSING);
|
||||
|
||||
$this->issued = $badge;
|
||||
$this->recipient = $user;
|
||||
|
||||
// Check if recipient is valid.
|
||||
// There is no way to be 100% sure that a badge belongs to a user.
|
||||
// Backpack does not return any recipient information.
|
||||
// All we can do is compare that backpack email hashed using salt
|
||||
// provided in the assertion matches a badge recipient from the assertion.
|
||||
if ($user) {
|
||||
if (validate_email($badge->assertion->recipient) && $badge->assertion->recipient == $user->email) {
|
||||
// If we have email, compare emails.
|
||||
$this->valid = true;
|
||||
} else if ($badge->assertion->recipient == 'sha256$' . hash('sha256', $user->email)) {
|
||||
// If recipient is hashed, but no salt, compare hashes without salt.
|
||||
$this->valid = true;
|
||||
} else if ($badge->assertion->recipient == 'sha256$' . hash('sha256', $user->email . $badge->assertion->salt)) {
|
||||
// If recipient is hashed, compare hashes.
|
||||
$this->valid = true;
|
||||
} else {
|
||||
// Otherwise, we cannot be sure that this user is a recipient.
|
||||
$this->valid = false;
|
||||
}
|
||||
} else {
|
||||
$this->valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1016,7 +1087,7 @@ class badge_user_collection extends badge_collection implements renderable {
|
||||
parent::__construct($badges);
|
||||
|
||||
if (!empty($CFG->badges_allowexternalbackpack)) {
|
||||
$this->backpack = get_backpack_settings($userid);
|
||||
$this->backpack = get_backpack_settings($userid, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
$string['adminview'] = 'Admin view';
|
||||
$string['allcourses'] = 'Admin user sees all courses';
|
||||
$string['configadminview'] = 'What should the admin see in the course list block?';
|
||||
$string['confighideallcourseslink'] = 'Hide "All courses" link at the bottom of the block. Link hiding does not affects Admin\'s view';
|
||||
$string['confighideallcourseslink'] = 'Remove the \'All courses\' link under the list of courses. (This setting does not affect the admin view.)';
|
||||
$string['course_list:addinstance'] = 'Add a new courses block';
|
||||
$string['course_list:myaddinstance'] = 'Add a new courses block to My home';
|
||||
$string['hideallcourseslink'] = 'Hide All courses link';
|
||||
$string['hideallcourseslink'] = 'Hide \'All courses\' link';
|
||||
$string['owncourses'] = 'Admin user sees own courses';
|
||||
$string['pluginname'] = 'Courses';
|
||||
|
||||
@@ -38,14 +38,14 @@ Feature: View my courses in navigation block
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
When I follow "My home"
|
||||
Then I should not see "cat1" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should not see "cat2" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should see "c1" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should see "c31" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should see "c331" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should not see "c2" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should not see "c32" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should not see "c332" in the "div.block_navigation .type_system" "css_element"
|
||||
Then I should not see "cat1" in the "Navigation" "block"
|
||||
And I should not see "cat2" in the "Navigation" "block"
|
||||
And I should see "c1" in the "Navigation" "block"
|
||||
And I should see "c31" in the "Navigation" "block"
|
||||
And I should see "c331" in the "Navigation" "block"
|
||||
And I should not see "c2" in the "Navigation" "block"
|
||||
And I should not see "c32" in the "Navigation" "block"
|
||||
And I should not see "c332" in the "Navigation" "block"
|
||||
|
||||
@javascript
|
||||
Scenario: The nested list of enrolled courses is shown
|
||||
@@ -54,18 +54,18 @@ Feature: View my courses in navigation block
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
When I follow "My home"
|
||||
Then I should see "cat1" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should see "cat3" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should not see "cat2" in the "div.block_navigation .type_system" "css_element"
|
||||
Then I should see "cat1" in the "Navigation" "block"
|
||||
And I should see "cat3" in the "Navigation" "block"
|
||||
And I should not see "cat2" in the "Navigation" "block"
|
||||
And I expand "cat3" node
|
||||
And I wait "2" seconds
|
||||
And I should see "cat31" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should see "cat33" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should not see "cat32" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should see "cat31" in the "Navigation" "block"
|
||||
And I should see "cat33" in the "Navigation" "block"
|
||||
And I should not see "cat32" in the "Navigation" "block"
|
||||
And I expand "cat31" node
|
||||
And I wait "2" seconds
|
||||
And I should see "c31" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should see "c31" in the "Navigation" "block"
|
||||
And I expand "cat33" node
|
||||
And I wait "2" seconds
|
||||
And I should see "c331" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should not see "c332" in the "div.block_navigation .type_system" "css_element"
|
||||
And I should see "c331" in the "Navigation" "block"
|
||||
And I should not see "c332" in the "Navigation" "block"
|
||||
|
||||
+12
-6
@@ -110,6 +110,16 @@ define('CALENDAR_IMPORT_EVENT_UPDATED', 1);
|
||||
*/
|
||||
define('CALENDAR_IMPORT_EVENT_INSERTED', 2);
|
||||
|
||||
/**
|
||||
* CALENDAR_SUBSCRIPTION_UPDATE - Used to represent update action for subscriptions in various forms.
|
||||
*/
|
||||
define('CALENDAR_SUBSCRIPTION_UPDATE', 1);
|
||||
|
||||
/**
|
||||
* CALENDAR_SUBSCRIPTION_REMOVE - Used to represent remove action for subscriptions in various forms.
|
||||
*/
|
||||
define('CALENDAR_SUBSCRIPTION_REMOVE', 2);
|
||||
|
||||
/**
|
||||
* Return the days of the week
|
||||
*
|
||||
@@ -2894,17 +2904,13 @@ function calendar_add_icalendar_event($event, $courseid, $subscriptionid) {
|
||||
* @return string A log of the import progress, including errors
|
||||
*/
|
||||
function calendar_process_subscription_row($subscriptionid, $pollinterval, $action) {
|
||||
global $DB;
|
||||
|
||||
// Fetch the subscription from the database making sure it exists.
|
||||
$sub = calendar_get_subscription($subscriptionid);
|
||||
|
||||
$strupdate = get_string('update');
|
||||
$strremove = get_string('remove');
|
||||
|
||||
// Update or remove the subscription, based on action.
|
||||
switch ($action) {
|
||||
case $strupdate:
|
||||
case CALENDAR_SUBSCRIPTION_UPDATE:
|
||||
// Skip updating file subscriptions.
|
||||
if (empty($sub->url)) {
|
||||
break;
|
||||
@@ -2915,7 +2921,7 @@ function calendar_process_subscription_row($subscriptionid, $pollinterval, $acti
|
||||
// Update the events.
|
||||
return "<p>".get_string('subscriptionupdated', 'calendar', $sub->name)."</p>" . calendar_update_subscription_events($subscriptionid);
|
||||
|
||||
case $strremove:
|
||||
case CALENDAR_SUBSCRIPTION_REMOVE:
|
||||
calendar_delete_subscription($subscriptionid);
|
||||
return get_string('subscriptionremoved', 'calendar', $sub->name);
|
||||
break;
|
||||
|
||||
@@ -33,7 +33,7 @@ $courseid = optional_param('course', SITEID, PARAM_INT);
|
||||
// Used for processing subscription actions.
|
||||
$subscriptionid = optional_param('id', 0, PARAM_INT);
|
||||
$pollinterval = optional_param('pollinterval', 0, PARAM_INT);
|
||||
$action = optional_param('action', '', PARAM_ALPHA);
|
||||
$action = optional_param('action', '', PARAM_INT);
|
||||
|
||||
$url = new moodle_url('/calendar/managesubscriptions.php');
|
||||
if ($courseid != SITEID) {
|
||||
|
||||
@@ -836,9 +836,11 @@ class core_calendar_renderer extends plugin_renderer_base {
|
||||
$html .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'course', 'value' => $courseid));
|
||||
$html .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'id', 'value' => $subscription->id));
|
||||
if (!empty($subscription->url)) {
|
||||
$html .= html_writer::empty_tag('input', array('type' => 'submit', 'name' => 'action', 'value' => get_string('update')));
|
||||
$html .= html_writer::tag('button', get_string('update'), array('type' => 'submit', 'name' => 'action',
|
||||
'value' => CALENDAR_SUBSCRIPTION_UPDATE));
|
||||
}
|
||||
$html .= html_writer::empty_tag('input', array('type' => 'submit', 'name' => 'action', 'value' => get_string('remove')));
|
||||
$html .= html_writer::tag('button', get_string('remove'), array('type' => 'submit', 'name' => 'action',
|
||||
'value' => CALENDAR_SUBSCRIPTION_REMOVE));
|
||||
$html .= html_writer::end_tag('div');
|
||||
$html .= html_writer::end_tag('form');
|
||||
return $html;
|
||||
|
||||
@@ -74,8 +74,8 @@ Feature: Course activity controls works as expected
|
||||
And section "1" should be visible
|
||||
And I add the "Section links" block
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
And I should see "1 2 3 4 5" in the ".block_section_links" "css_element"
|
||||
And I click on "2" "link" in the ".block_section_links" "css_element"
|
||||
And I should see "1 2 3 4 5" in the "Section links" "block"
|
||||
And I click on "2" "link" in the "Section links" "block"
|
||||
And I <should_see_other_sections_following_block_sections_links> see "Test forum name 2"
|
||||
|
||||
Examples:
|
||||
@@ -148,8 +148,8 @@ Feature: Course activity controls works as expected
|
||||
And section "1" should be visible
|
||||
And I add the "Section links" block
|
||||
And "#section-2" "css_element" <should_see_other_sections> exists
|
||||
And I should see "1 2 3 4 5" in the ".block_section_links" "css_element"
|
||||
And I click on "2" "link" in the ".block_section_links" "css_element"
|
||||
And I should see "1 2 3 4 5" in the "Section links" "block"
|
||||
And I click on "2" "link" in the "Section links" "block"
|
||||
And I <should_see_other_sections_following_block_sections_links> see "Test forum name 2"
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -53,6 +53,7 @@ $string['course_summary_key'] = 'Summary';
|
||||
$string['createcourseextid'] = 'CREATE User enrolled to a nonexistant course \'{$a->courseextid}\'';
|
||||
$string['createnotcourseextid'] = 'User enrolled to a nonexistant course \'{$a->courseextid}\'';
|
||||
$string['creatingcourse'] = 'Creating course \'{$a}\'...';
|
||||
$string['duplicateshortname'] = "Course creation failed. Duplicate short name. Skipping course with idnumber '{\$a->idnumber}'...";
|
||||
$string['editlock'] = 'Lock value';
|
||||
$string['emptyenrolment'] = "Empty enrolment for role '{\$a->role_shortname}' in course '{\$a->course_shortname}'\n";
|
||||
$string['enrolname'] = 'LDAP';
|
||||
|
||||
@@ -990,6 +990,12 @@ class enrol_ldap_plugin extends enrol_plugin {
|
||||
$course->summary = $course_ext[$this->get_config('course_summary')][0];
|
||||
}
|
||||
|
||||
// Check if the shortname already exists if it does - skip course creation.
|
||||
if ($DB->record_exists('course', array('shortname' => $course->shortname))) {
|
||||
$trace->output(get_string('duplicateshortname', 'enrol_ldap', $course));
|
||||
return false;
|
||||
}
|
||||
|
||||
$newcourse = create_course($course);
|
||||
return $newcourse->id;
|
||||
}
|
||||
|
||||
+1
-1
@@ -49,9 +49,9 @@
|
||||
header("Status: 404 Not Found");
|
||||
|
||||
$PAGE->set_url('/error/');
|
||||
$PAGE->set_context(get_system_context());
|
||||
$PAGE->set_title($site->fullname .':Error');
|
||||
$PAGE->set_heading($site->fullname .': Error 404');
|
||||
$PAGE->set_context(get_system_context());
|
||||
$PAGE->navbar->add('Error 404 - File not Found');
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->box(get_string('pagenotexist', 'error'). '<br />'.s($requesturi), 'generalbox boxaligncenter');
|
||||
|
||||
+5
-5
@@ -201,9 +201,9 @@ class core_files_renderer extends plugin_renderer_base {
|
||||
<div class="fp-navbar">
|
||||
<div class="filemanager-toolbar">
|
||||
<div class="fp-toolbar">
|
||||
<div class="{!}fp-btn-add"><a href="#"><img src="'.$this->pix_url('a/add_file').'" /> '.$straddfile.'</a></div>
|
||||
<div class="{!}fp-btn-mkdir"><a href="#"><img src="'.$this->pix_url('a/create_folder').'" /> '.$strmakedir.'</a></div>
|
||||
<div class="{!}fp-btn-download"><a href="#"><img src="'.$this->pix_url('a/download_all').'" /> '.$strdownload.'</a></div>
|
||||
<div class="{!}fp-btn-add"><a role="button" href="#"><img src="'.$this->pix_url('a/add_file').'" /> '.$straddfile.'</a></div>
|
||||
<div class="{!}fp-btn-mkdir"><a role="button" href="#"><img src="'.$this->pix_url('a/create_folder').'" /> '.$strmakedir.'</a></div>
|
||||
<div class="{!}fp-btn-download"><a role="button" href="#"><img src="'.$this->pix_url('a/download_all').'" /> '.$strdownload.'</a></div>
|
||||
</div>
|
||||
<div class="{!}fp-viewbar">
|
||||
<a title="'. get_string('displayicons', 'repository') .'" class="{!}fp-vb-icons" href="#"></a>
|
||||
@@ -521,10 +521,10 @@ class core_files_renderer extends plugin_renderer_base {
|
||||
*/
|
||||
private function fp_js_template_generallayout() {
|
||||
$rv = '
|
||||
<div class="file-picker fp-generallayout">
|
||||
<div tabindex="0" class="file-picker fp-generallayout" role="dialog" aria-live="assertive">
|
||||
<div class="fp-repo-area">
|
||||
<ul class="fp-list">
|
||||
<li class="{!}fp-repo"><a href="#"><img class="{!}fp-repo-icon" alt="'. get_string('repositoryicon', 'repository') .'" width="16" height="16" /> <span class="{!}fp-repo-name"></span></a></li>
|
||||
<li class="{!}fp-repo"><a href="#"><img class="{!}fp-repo-icon" alt=" " width="16" height="16" /> <span class="{!}fp-repo-name"></span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="fp-repo-items" tabindex="0">
|
||||
|
||||
@@ -189,7 +189,7 @@ abstract class grade_export {
|
||||
$name .= ' ('.get_string('feedback').')';
|
||||
}
|
||||
|
||||
return strip_tags($name);
|
||||
return html_to_text($name, 0, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+8
-8
@@ -119,7 +119,7 @@ $string['commonfiltersettings'] = 'Common filter settings';
|
||||
$string['commonsettings'] = 'Common settings';
|
||||
$string['componentinstalled'] = 'Component installed';
|
||||
$string['computedfromlogs'] = 'Computed from logs since {$a}.';
|
||||
$string['condifmodeditdefaults'] = 'The values you set here define the default values that are used in the activity settings form when you create a new activity. You can also configure which activity settings are considered advanced.';
|
||||
$string['condifmodeditdefaults'] = 'Default values are used in the settings form when creating a new activity or resource.';
|
||||
$string['confeditorhidebuttons'] = 'Select the buttons that should be hidden in the HTML editor.';
|
||||
$string['configallcountrycodes'] = 'This is the list of countries that may be selected in various places, for example in a user\'s profile. If blank (the default) the list in countries.php in the standard English language pack is used. That is the list from ISO 3166-1. Otherwise, you can specify a comma-separated list of codes, for example \'GB,FR,ES\'. If you add new, non-standard codes here, you will need to add them to countries.php in \'en\' and your language pack.';
|
||||
$string['configallowassign'] = 'You can allow people who have the roles on the left side to assign some of the column roles to other people';
|
||||
@@ -163,15 +163,15 @@ $string['configcronremotepassword'] = 'This means that the cron.php script canno
|
||||
http://site.example.com/admin/cron.php?password=opensesame
|
||||
</pre>If this is left empty, no password is required.';
|
||||
$string['configcurlcache'] = 'Time-to-live for cURL cache, in seconds.';
|
||||
$string['configcustommenuitems'] = 'You can configure a custom menu here to be shown by themes. Each line consists of some menu text, a link URL (optional) and a tooltip title (optional), separated by pipe characters. You can specify a structure using hyphens. For example:
|
||||
$string['configcustommenuitems'] = 'You can configure a custom menu here to be shown by themes. Each line consists of some menu text, a link URL (optional), a tooltip title (optional) and a language code or comma-separated list of codes (optional, for displaying the line to users of the specified language only), separated by pipe characters. You can specify a structure using hyphens. For example:
|
||||
<pre>
|
||||
Moodle community|http://moodle.org
|
||||
-Moodle free support|http://moodle.org/support
|
||||
-Moodle development|http://moodle.org/development
|
||||
--Moodle Tracker|http://tracker.moodle.org
|
||||
--Moodle Docs|http://docs.moodle.org
|
||||
-Moodle News|http://moodle.org/news
|
||||
Moodle company
|
||||
--Moodle Docs|http://docs.moodle.org|Moodle Docs in German
|
||||
--German Moodle Docs|http://docs.moodle.org/de|Documentation in German|de
|
||||
-Moodle News|http://moodle.org/news Moodle company
|
||||
-Moodle commercial hosting|http://moodle.com/hosting
|
||||
-Moodle commercial support|http://moodle.com/support
|
||||
</pre>';
|
||||
@@ -530,10 +530,10 @@ $string['filters'] = 'Filters';
|
||||
$string['filtersettings'] = 'Manage filters';
|
||||
$string['filtersettingsgeneral'] = 'General filter settings';
|
||||
$string['filteruploadedfiles'] = 'Filter uploaded files';
|
||||
$string['forcelogin'] = 'Force users to login';
|
||||
$string['forceloginforprofileimage'] = 'Force users to login to view user pictures';
|
||||
$string['forcelogin'] = 'Force users to log in';
|
||||
$string['forceloginforprofileimage'] = 'Force users to log in to view user pictures';
|
||||
$string['forceloginforprofileimage_help'] = 'If enabled, users must login in order to view user profile pictures and the default user picture will be used in all notification emails.';
|
||||
$string['forceloginforprofiles'] = 'Force users to login for profiles';
|
||||
$string['forceloginforprofiles'] = 'Force users to log in for profiles';
|
||||
$string['forcetimezone'] = 'Force default timezone';
|
||||
$string['formatuninstallwithcourses'] = 'There are {$a->count} courses using {$a->format}. Their format will be changed to {$a->defaultformat} (default format for this site). Some format-specific data may be lost. Are you sure you want to proceed?';
|
||||
$string['formatuninstallconfirm'] = '{$a} will be uninstalled. No courses currently use it. Continue?';
|
||||
|
||||
+7
-1
@@ -101,7 +101,9 @@ $string['badgeprivacysetting_help'] = 'Badges you earn can be displayed on your
|
||||
You can still control individual badge privacy settings on your "My badges" page.';
|
||||
$string['badgeprivacysetting_str'] = 'Automatically show badges I earn on my profile page';
|
||||
$string['badgesalt'] = 'Salt for hashing the recepient\'s email address';
|
||||
$string['badgesalt_desc'] = 'Using a hash allows backpack services to confirm the badge earner without having to expose their email address. This setting should only use numbers and letters.';
|
||||
$string['badgesalt_desc'] = 'Using a hash allows backpack services to confirm the badge earner without having to expose their email address. This setting should only use numbers and letters.
|
||||
|
||||
Note: For recipient verification purposes, please avoid changing this setting once you start issuing badges.';
|
||||
$string['badgesdisabled'] = 'Badges are not enabled on this site.';
|
||||
$string['badgesearned'] = 'Number of badges earned: {$a}';
|
||||
$string['badgesettings'] = 'Badges settings';
|
||||
@@ -203,6 +205,7 @@ $string['error:cannotact'] = 'Cannot activate the badge. ';
|
||||
$string['error:cannotawardbadge'] = 'Cannot award badge to a user.';
|
||||
$string['error:clone'] = 'Cannot clone the badge.';
|
||||
$string['error:duplicatename'] = 'Badge with such name already exists in the system.';
|
||||
$string['error:externalbadgedoesntexist'] = 'Badge not found';
|
||||
$string['error:invalidbadgeurl'] = 'Invalid badge issuer URL format.';
|
||||
$string['error:invalidcriteriatype'] = 'Invalid criteria type.';
|
||||
$string['error:invalidexpiredate'] = 'Expiry date has to be in the future.';
|
||||
@@ -305,6 +308,9 @@ $string['numawardstat'] = 'This badge has been issued {$a} user(s).';
|
||||
$string['overallcrit'] = 'of the selected criteria are complete.';
|
||||
$string['potentialrecipients'] = 'Potential badge recipients';
|
||||
$string['recipients'] = 'Badge recipients';
|
||||
$string['recipientdetails'] = 'Recipient details';
|
||||
$string['recipientidentificationproblem'] = 'Cannot find a recipient of this badge among the existing users.';
|
||||
$string['recipientvalidationproblem'] = 'Current user cannot be verified as a recipient of this badge.';
|
||||
$string['relative'] = 'Relative date';
|
||||
$string['requiredcourse'] = 'At least one course should be added to the courseset criterion.';
|
||||
$string['reviewbadge'] = 'Review badge criteria';
|
||||
|
||||
@@ -44,6 +44,7 @@ $string['cachedef_coursecontacts'] = 'List of course contacts';
|
||||
$string['cachedef_coursecattree'] = 'Course categories tree';
|
||||
$string['cachedef_databasemeta'] = 'Database meta information';
|
||||
$string['cachedef_eventinvalidation'] = 'Event invalidation';
|
||||
$string['cachedef_externalbadges'] = 'External badges for particular user';
|
||||
$string['cachedef_groupdata'] = 'Course group information';
|
||||
$string['cachedef_htmlpurifier'] = 'HTML Purifier - cleaned content';
|
||||
$string['cachedef_locking'] = 'Locking';
|
||||
|
||||
@@ -70,7 +70,7 @@ $string['completionenabled'] = 'Enabled, control via completion and activity set
|
||||
$string['completionexpected'] = 'Expect completed on';
|
||||
$string['completionexpected_help'] = 'This setting specifies the date when the activity is expected to be completed. The date is not shown to students and is only displayed in the activity completion report.';
|
||||
$string['completionicons'] = 'Completion tick boxes';
|
||||
$string['completionicons_help'] = 'A tick next an activity name may be used to indicate when the activity is complete.
|
||||
$string['completionicons_help'] = 'A tick next to an activity name may be used to indicate when the activity is complete.
|
||||
|
||||
If a box with a dotted border is shown, a tick will appear automatically when you have completed the activity according to conditions set by the teacher.
|
||||
|
||||
|
||||
+1
-1
@@ -219,7 +219,7 @@ $string['duplicaterolename'] = 'There is already a role with this name!';
|
||||
$string['duplicateroleshortname'] = 'There is already a role with this short name!';
|
||||
$string['duplicateusername'] = 'Duplicate username - skipping record';
|
||||
$string['emailfail'] = 'Emailing failed';
|
||||
$string['error'] = 'Error occured';
|
||||
$string['error'] = 'Error occurred';
|
||||
$string['errorcleaningdirectory'] = 'Error cleaning directory "{$a}"';
|
||||
$string['errorcopyingfiles'] = 'Error copying files';
|
||||
$string['errorcreatingdirectory'] = 'Error creating directory "{$a}"';
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ $string['admindirsettingsub'] = 'A very few webhosts use /admin as a special URL
|
||||
renaming the admin directory in your installation, and putting that
|
||||
new name here. For example: <br /> <br /><b>moodleadmin</b><br /> <br />
|
||||
This will fix admin links in Moodle.';
|
||||
$string['availablelangs'] = 'List of available languages';
|
||||
$string['availablelangs'] = 'Available language packs';
|
||||
$string['caution'] = 'Caution';
|
||||
$string['cliadminpassword'] = 'New admin user password';
|
||||
$string['cliadminusername'] = 'Admin account username';
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['anunexpectederroroccured'] = 'an unexpected error occured';
|
||||
$string['anunexpectederroroccured'] = 'an unexpected error occurred';
|
||||
$string['cannotassigntoconstant'] = 'cannot assign to constant \'{$a}\'';
|
||||
$string['cannotredefinebuiltinfunction'] = 'cannot redefine built-in function \'{$a}()\'';
|
||||
$string['divisionbyzero'] = 'division by zero';
|
||||
|
||||
@@ -333,6 +333,7 @@ $string['courselegacyfiles_help'] = 'The course files area provides some backwar
|
||||
|
||||
If you use this area to store course files, you can expose yourself to a number of privacy and security issues, as well as experiencing missing files in backups, course imports and any time content is shared or re-used. It is therefore recommended that you do not use this area unless you really know what you are doing.';
|
||||
$string['courselegacyfiles_link'] = 'coursefiles2';
|
||||
$string['courselegacyfilesofcourse'] = 'Legacy course files: {$a}';
|
||||
$string['courseoverview'] = 'Course overview';
|
||||
$string['courseoverviewgraph'] = 'Course overview graph';
|
||||
$string['courseprofiles'] = 'Course profiles';
|
||||
|
||||
@@ -106,7 +106,7 @@ $string['errornotyourfile'] = 'You cannot pick file which is not added by your';
|
||||
$string['erroruniquename'] = 'Repository instance name should be unique';
|
||||
$string['errorpostmaxsize'] = 'The uploaded file may exceed the post_max_size directive in php.ini.';
|
||||
$string['errorwhilecommunicatingwith'] = 'Error while communicating with the repository \'{$a}\'.';
|
||||
$string['errorwhiledownload'] = 'An error occured while downloading the file: {$a}';
|
||||
$string['errorwhiledownload'] = 'An error occurred while downloading the file: {$a}';
|
||||
$string['existingrepository'] = 'This repository already exists';
|
||||
$string['federatedsearch'] = 'Federated search';
|
||||
$string['fileexists'] = 'File name already being used, please use another name';
|
||||
|
||||
+14
-1
@@ -1167,13 +1167,25 @@ function badges_bake($hash, $badgeid, $userid = 0, $pathhash = false) {
|
||||
/**
|
||||
* Returns external backpack settings and badges from this backpack.
|
||||
*
|
||||
* This function first checks if badges for the user are cached and
|
||||
* tries to retrieve them from the cache. Otherwise, badges are obtained
|
||||
* through curl request to the backpack.
|
||||
*
|
||||
* @param int $userid Backpack user ID.
|
||||
* @param boolean $refresh Refresh badges collection in cache.
|
||||
* @return null|object Returns null is there is no backpack or object with backpack settings.
|
||||
*/
|
||||
function get_backpack_settings($userid) {
|
||||
function get_backpack_settings($userid, $refresh = false) {
|
||||
global $DB;
|
||||
require_once(dirname(dirname(__FILE__)) . '/badges/lib/backpacklib.php');
|
||||
|
||||
// Try to get badges from cache first.
|
||||
$badgescache = cache::make('core', 'externalbadges');
|
||||
$out = $badgescache->get($userid);
|
||||
if ($out !== false && !$refresh) {
|
||||
return $out;
|
||||
}
|
||||
// Get badges through curl request to the backpack.
|
||||
$record = $DB->get_record('badge_backpack', array('userid' => $userid));
|
||||
if ($record) {
|
||||
$backpack = new OpenBadgesBackpackHandler($record);
|
||||
@@ -1198,6 +1210,7 @@ function get_backpack_settings($userid) {
|
||||
$out->totalcollections = 0;
|
||||
}
|
||||
|
||||
$badgescache->set($userid, $out);
|
||||
return $out;
|
||||
}
|
||||
|
||||
|
||||
@@ -367,22 +367,13 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
|
||||
*/
|
||||
protected function transform_selector($selectortype, $element) {
|
||||
|
||||
// Here we don't know if a $allowedtextselector is used.
|
||||
if (!isset(behat_command::$allowedselectors[$selectortype])) {
|
||||
// Here we don't know if an allowed text selector is being used.
|
||||
$selectors = behat_selectors::get_allowed_selectors();
|
||||
if (!isset($selectors[$selectortype])) {
|
||||
throw new ExpectationException('The "' . $selectortype . '" selector type does not exist', $this->getSession());
|
||||
}
|
||||
|
||||
// CSS and XPath selectors locator is one single argument.
|
||||
if ($selectortype == 'css_element' || $selectortype == 'xpath_element') {
|
||||
$selector = str_replace('_element', '', $selectortype);
|
||||
$locator = $element;
|
||||
} else {
|
||||
// Named selectors uses arrays as locators including the type of named selector.
|
||||
$locator = array($selectortype, $this->getSession()->getSelectorsHandler()->xpathLiteral($element));
|
||||
$selector = 'named';
|
||||
}
|
||||
|
||||
return array($selector, $locator);
|
||||
return behat_selectors::get_behat_selector($selectortype, $element, $this->getSession());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -398,7 +389,8 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
|
||||
*/
|
||||
protected function transform_text_selector($selectortype, $element) {
|
||||
|
||||
if ($selectortype != 'css_element' && $selectortype != 'xpath_element') {
|
||||
$selectors = behat_selectors::get_allowed_text_selectors();
|
||||
if (empty($selectors[$selectortype])) {
|
||||
throw new ExpectationException('The "' . $selectortype . '" selector can not be used to select text nodes', $this->getSession());
|
||||
}
|
||||
|
||||
|
||||
@@ -42,34 +42,6 @@ class behat_command {
|
||||
*/
|
||||
const DOCS_URL = 'http://docs.moodle.org/dev/Acceptance_testing';
|
||||
|
||||
/**
|
||||
* @var Allowed types when using text selectors arguments.
|
||||
*/
|
||||
public static $allowedtextselectors = array(
|
||||
'css_element' => 'css_element',
|
||||
'xpath_element' => 'xpath_element'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var Allowed types when using selector arguments.
|
||||
*/
|
||||
public static $allowedselectors = array(
|
||||
'link' => 'link',
|
||||
'button' => 'button',
|
||||
'link_or_button' => 'link_or_button',
|
||||
'select' => 'select',
|
||||
'checkbox' => 'checkbox',
|
||||
'radio' => 'radio',
|
||||
'file' => 'file',
|
||||
'optgroup' => 'optgroup',
|
||||
'option' => 'option',
|
||||
'table' => 'table',
|
||||
'field' => 'field',
|
||||
'fieldset' => 'fieldset',
|
||||
'css_element' => 'css_element',
|
||||
'xpath_element' => 'xpath_element'
|
||||
);
|
||||
|
||||
/**
|
||||
* Ensures the behat dir exists in moodledata
|
||||
* @return string Full path
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Moodle-specific selectors.
|
||||
*
|
||||
* @package core
|
||||
* @category test
|
||||
* @copyright 2013 David Monllaó
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Moodle selectors manager.
|
||||
*
|
||||
* @package core
|
||||
* @category test
|
||||
* @copyright 2013 David Monllaó
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_selectors {
|
||||
|
||||
/**
|
||||
* @var Allowed types when using text selectors arguments.
|
||||
*/
|
||||
protected static $allowedtextselectors = array(
|
||||
'dialogue' => 'dialogue',
|
||||
'block' => 'block',
|
||||
'region' => 'region',
|
||||
'table_row' => 'table_row',
|
||||
'table' => 'table',
|
||||
'fieldset' => 'fieldset',
|
||||
'css_element' => 'css_element',
|
||||
'xpath_element' => 'xpath_element'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var Allowed types when using selector arguments.
|
||||
*/
|
||||
protected static $allowedselectors = array(
|
||||
'dialogue' => 'dialogue',
|
||||
'block' => 'block',
|
||||
'region' => 'region',
|
||||
'table_row' => 'table_row',
|
||||
'link' => 'link',
|
||||
'button' => 'button',
|
||||
'link_or_button' => 'link_or_button',
|
||||
'select' => 'select',
|
||||
'checkbox' => 'checkbox',
|
||||
'radio' => 'radio',
|
||||
'file' => 'file',
|
||||
'optgroup' => 'optgroup',
|
||||
'option' => 'option',
|
||||
'table' => 'table',
|
||||
'field' => 'field',
|
||||
'fieldset' => 'fieldset',
|
||||
'css_element' => 'css_element',
|
||||
'xpath_element' => 'xpath_element'
|
||||
);
|
||||
|
||||
/**
|
||||
* Behat by default comes with XPath, CSS and named selectors,
|
||||
* named selectors are a mapping between names (like button) and
|
||||
* xpaths that represents that names and includes a placeholder that
|
||||
* will be replaced by the locator. These are Moodle's own xpaths.
|
||||
*
|
||||
* @var XPaths for moodle elements.
|
||||
*/
|
||||
protected static $moodleselectors = array(
|
||||
'dialogue' => <<<XPATH
|
||||
.//div[contains(concat(' ', normalize-space(@class), ' '), ' moodle-dialogue ')]/descendant::h1[normalize-space(.) = %locator%]/ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' moodle-dialogue ')]
|
||||
XPATH
|
||||
, 'block' => <<<XPATH
|
||||
.//div[contains(concat(' ', normalize-space(@class), ' '), concat(' ', %locator%, ' '))] | .//div[contains(concat(' ', normalize-space(@class), ' '), ' block ')]/descendant::h2[normalize-space(.) = %locator%]/ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' block ')]
|
||||
XPATH
|
||||
, 'region' => <<<XPATH
|
||||
.//div[./@id = %locator%]
|
||||
XPATH
|
||||
, 'table_row' => <<<XPATH
|
||||
.//tr[contains(normalize-space(.), %locator%)]
|
||||
XPATH
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the behat selector and locator for a given moodle selector and locator
|
||||
*
|
||||
* @param string $selectortype The moodle selector type, which includes moodle selectors
|
||||
* @param string $element The locator we look for in that kind of selector
|
||||
* @param Session $session The Mink opened session
|
||||
* @return array Contains the selector and the locator expected by Mink.
|
||||
*/
|
||||
public static function get_behat_selector($selectortype, $element, Behat\Mink\Session $session) {
|
||||
|
||||
// CSS and XPath selectors locator is one single argument.
|
||||
if ($selectortype == 'css_element' || $selectortype == 'xpath_element') {
|
||||
$selector = str_replace('_element', '', $selectortype);
|
||||
$locator = $element;
|
||||
} else {
|
||||
// Named selectors uses arrays as locators including the type of named selector.
|
||||
$locator = array($selectortype, $session->getSelectorsHandler()->xpathLiteral($element));
|
||||
$selector = 'named';
|
||||
}
|
||||
|
||||
return array($selector, $locator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds moodle selectors as behat named selectors.
|
||||
*
|
||||
* @param Session $session The mink session
|
||||
* @return void
|
||||
*/
|
||||
public static function register_moodle_selectors(Behat\Mink\Session $session) {
|
||||
|
||||
foreach (self::get_moodle_selectors() as $name => $xpath) {
|
||||
$session->getSelectorsHandler()->getSelector('named')->registerNamedXpath($name, $xpath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allowed selectors getter.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_allowed_selectors() {
|
||||
return self::$allowedselectors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allowed text selectors getter.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_allowed_text_selectors() {
|
||||
return self::$allowedtextselectors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moodle selectors attribute accessor.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function get_moodle_selectors() {
|
||||
return self::$moodleselectors;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -993,7 +993,7 @@ class block_manager {
|
||||
*
|
||||
* @param string $region The name of the region to check
|
||||
*/
|
||||
protected function ensure_content_created($region, $output) {
|
||||
public function ensure_content_created($region, $output) {
|
||||
$this->ensure_instances_exist($region);
|
||||
if (!array_key_exists($region, $this->visibleblockcontent)) {
|
||||
$contents = array();
|
||||
|
||||
@@ -95,6 +95,9 @@ function min_fix_utf8($value) {
|
||||
error_reporting($olderror ^ E_NOTICE);
|
||||
}
|
||||
|
||||
// No null bytes expected in our data, so let's remove it.
|
||||
$value = str_replace("\0", '', $value);
|
||||
|
||||
static $buggyiconv = null;
|
||||
if ($buggyiconv === null) {
|
||||
$buggyiconv = (!function_exists('iconv') or iconv('UTF-8', 'UTF-8//IGNORE', '100'.chr(130).'€') !== '100€');
|
||||
|
||||
@@ -236,4 +236,10 @@ $definitions = array(
|
||||
'mode' => cache_store::MODE_REQUEST,
|
||||
'persistent' => true,
|
||||
),
|
||||
// Used to store external badges.
|
||||
'externalbadges' => array(
|
||||
'mode' => cache_store::MODE_APPLICATION,
|
||||
'simplekeys' => true,
|
||||
'ttl' => 3600,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -648,6 +648,7 @@ class mssql_native_moodle_database extends moodle_database {
|
||||
|
||||
} else {
|
||||
$param = str_replace("'", "''", $param);
|
||||
$param = str_replace("\0", "", $param);
|
||||
$return .= "N'$param'";
|
||||
}
|
||||
|
||||
|
||||
@@ -727,6 +727,7 @@ class sqlsrv_native_moodle_database extends moodle_database {
|
||||
$return .= $param;
|
||||
} else {
|
||||
$param = str_replace("'", "''", $param);
|
||||
$param = str_replace("\0", "", $param);
|
||||
$return .= "N'$param'";
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,13 @@ M.editor_tinymce.init_editor = function(Y, editorid, options) {
|
||||
ed.contentDocument.addEventListener('keydown', function() {
|
||||
ed.contentWindow.focus();
|
||||
});
|
||||
|
||||
// Whenever a touch event is registered against the content document,
|
||||
// reapply focus. This works around an issue with the location caret not
|
||||
// being focusable without use of the Loupe.
|
||||
ed.contentDocument.addEventListener('touchend', function() {
|
||||
ed.contentWindow.focus();
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
+5
-3
@@ -247,9 +247,11 @@ function ldap_find_userdn($ldapconnection, $username, $contexts, $objectclass, $
|
||||
}
|
||||
|
||||
if ($search_sub) {
|
||||
$ldap_result = ldap_search($ldapconnection, $context,
|
||||
'(&'.$objectclass.'('.$search_attrib.'='.ldap_filter_addslashes($username).'))',
|
||||
array($search_attrib));
|
||||
if (!$ldap_result = @ldap_search($ldapconnection, $context,
|
||||
'(&'.$objectclass.'('.$search_attrib.'='.ldap_filter_addslashes($username).'))',
|
||||
array($search_attrib))) {
|
||||
break; // Not found in this context.
|
||||
}
|
||||
} else {
|
||||
$ldap_result = ldap_list($ldapconnection, $context,
|
||||
'(&'.$objectclass.'('.$search_attrib.'='.ldap_filter_addslashes($username).'))',
|
||||
|
||||
+3
-2
@@ -1274,7 +1274,8 @@ class cm_info extends stdClass {
|
||||
}
|
||||
|
||||
// You are blocked if you don't have the capability.
|
||||
return !has_capability($capability, context_module::instance($this->id));
|
||||
$userid = $this->modinfo->get_user_id();
|
||||
return !has_capability($capability, context_module::instance($this->id), $userid);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1283,7 +1284,7 @@ class cm_info extends stdClass {
|
||||
* @return bool True if the user cannot see the module. False if the activity is either available or should be greyed out.
|
||||
*/
|
||||
public function is_user_access_restricted_by_conditional_access() {
|
||||
global $CFG, $USER;
|
||||
global $CFG;
|
||||
|
||||
if (empty($CFG->enableavailability)) {
|
||||
return false;
|
||||
|
||||
@@ -1181,6 +1181,8 @@ function fix_utf8($value) {
|
||||
// shortcut
|
||||
return $value;
|
||||
}
|
||||
// No null bytes expected in our data, so let's remove it.
|
||||
$value = str_replace("\0", '', $value);
|
||||
|
||||
// Lower error reporting because glibc throws bogus notices.
|
||||
$olderror = error_reporting();
|
||||
|
||||
@@ -345,6 +345,16 @@ class core_renderer extends renderer_base {
|
||||
*/
|
||||
public function standard_head_html() {
|
||||
global $CFG, $SESSION;
|
||||
|
||||
// Before we output any content, we need to ensure that certain
|
||||
// page components are set up.
|
||||
|
||||
// Blocks must be set up early as they may require javascript which
|
||||
// has to be included in the page header before output is created.
|
||||
foreach ($this->page->blocks->get_regions() as $region) {
|
||||
$this->page->blocks->ensure_content_created($region, $this);
|
||||
}
|
||||
|
||||
$output = '';
|
||||
$output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' . "\n";
|
||||
$output .= '<meta name="keywords" content="moodle, ' . $this->page->title . '" />' . "\n";
|
||||
|
||||
@@ -89,6 +89,7 @@ class behat_hooks extends behat_base {
|
||||
|
||||
// Now that we are MOODLE_INTERNAL.
|
||||
require_once(__DIR__ . '/../../behat/classes/behat_command.php');
|
||||
require_once(__DIR__ . '/../../behat/classes/behat_selectors.php');
|
||||
require_once(__DIR__ . '/../../behat/classes/util.php');
|
||||
require_once(__DIR__ . '/../../testing/classes/test_lock.php');
|
||||
require_once(__DIR__ . '/../../testing/classes/nasty_strings.php');
|
||||
@@ -138,6 +139,11 @@ class behat_hooks extends behat_base {
|
||||
throw new coding_exception('Behat only can modify the test database and the test dataroot!');
|
||||
}
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
// Avoid some notices / warnings.
|
||||
$SESSION = new stdClass();
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class core_configonlylib_testcase extends advanced_testcase {
|
||||
*/
|
||||
public function test_min_fix_utf8() {
|
||||
$this->assertSame('abc', min_fix_utf8('abc'));
|
||||
$this->assertSame("žlutý koníček přeskočil potůček \n\t\r\0", min_fix_utf8("žlutý koníček přeskočil potůček \n\t\r\0"));
|
||||
$this->assertSame("žlutý koníček přeskočil potůček \n\t\r", min_fix_utf8("žlutý koníček přeskočil potůček \n\t\r\0"));
|
||||
$this->assertSame('aš', min_fix_utf8('a'.chr(130).'š'), 'This fails with buggy iconv() when mbstring extenstion is not available as fallback.');
|
||||
}
|
||||
|
||||
|
||||
@@ -176,6 +176,61 @@ class modinfolib_testcase extends advanced_testcase {
|
||||
$this->assertFalse($cm_info->is_user_access_restricted_by_conditional_access());
|
||||
}
|
||||
|
||||
public function test_is_user_access_restricted_by_capability() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Create a course and a mod_assign instance.
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$assign = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id));
|
||||
|
||||
// Create and enrol a student.
|
||||
$coursecontext = context_course::instance($course->id);
|
||||
$studentrole = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
|
||||
$student = $this->getDataGenerator()->create_user();
|
||||
role_assign($studentrole->id, $student->id, $coursecontext);
|
||||
$enrolplugin = enrol_get_plugin('manual');
|
||||
$enrolinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'));
|
||||
$enrolplugin->enrol_user($enrolinstance, $student->id);
|
||||
$this->setUser($student);
|
||||
|
||||
// Make sure student can see the module.
|
||||
$cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
|
||||
$this->assertTrue($cm->uservisible);
|
||||
$this->assertFalse($cm->is_user_access_restricted_by_capability());
|
||||
|
||||
// Prohibit student to view mod_assign for the course.
|
||||
role_change_permission($studentrole->id, $coursecontext, 'mod/assign:view', CAP_PROHIBIT);
|
||||
get_fast_modinfo($course->id, 0, true);
|
||||
$cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
|
||||
$this->assertFalse($cm->uservisible);
|
||||
$this->assertTrue($cm->is_user_access_restricted_by_capability());
|
||||
|
||||
// Restore permission to student to view mod_assign for the course.
|
||||
role_change_permission($studentrole->id, $coursecontext, 'mod/assign:view', CAP_INHERIT);
|
||||
get_fast_modinfo($course->id, 0, true);
|
||||
$cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
|
||||
$this->assertTrue($cm->uservisible);
|
||||
$this->assertFalse($cm->is_user_access_restricted_by_capability());
|
||||
|
||||
// Prohibit student to view mod_assign for the particular module.
|
||||
role_change_permission($studentrole->id, context_module::instance($cm->id), 'mod/assign:view', CAP_PROHIBIT);
|
||||
get_fast_modinfo($course->id, 0, true);
|
||||
$cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
|
||||
$this->assertFalse($cm->uservisible);
|
||||
$this->assertTrue($cm->is_user_access_restricted_by_capability());
|
||||
|
||||
// Check calling get_fast_modinfo() for different user:
|
||||
$this->setAdminUser();
|
||||
$cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
|
||||
$this->assertTrue($cm->uservisible);
|
||||
$this->assertFalse($cm->is_user_access_restricted_by_capability());
|
||||
$cm = get_fast_modinfo($course->id, $student->id)->instances['assign'][$assign->id];
|
||||
$this->assertFalse($cm->uservisible);
|
||||
$this->assertTrue($cm->is_user_access_restricted_by_capability());
|
||||
}
|
||||
|
||||
private function refresh_cm_info($course, $assign) {
|
||||
get_fast_modinfo(0, 0, true);
|
||||
return get_fast_modinfo($course)->instances['assign'][$assign->id];
|
||||
|
||||
@@ -486,7 +486,7 @@ class moodlelib_testcase extends advanced_testcase {
|
||||
$this->assertEquals($object, fix_utf8($object));
|
||||
|
||||
// valid utf8 string
|
||||
$this->assertSame("žlutý koníček přeskočil potůček \n\t\r\0", fix_utf8("žlutý koníček přeskočil potůček \n\t\r\0"));
|
||||
$this->assertSame("žlutý koníček přeskočil potůček \n\t\r", fix_utf8("žlutý koníček přeskočil potůček \n\t\r\0"));
|
||||
|
||||
// invalid utf8 string
|
||||
$this->assertSame('aš', fix_utf8('a'.chr(130).'š'), 'This fails with buggy iconv() when mbstring extenstion is not available as fallback.');
|
||||
|
||||
@@ -2,6 +2,8 @@ This files describes API changes in core libraries and APIs,
|
||||
information provided here is intended especially for developers.
|
||||
=== 2.5.2 ===
|
||||
* Use new function moodleform::mock_submit() to simulate form submission in unit tests.
|
||||
* Use behat_selectors::get_allowed_text_selectors() and behat_selectors::get_allowed_selectors() instead of
|
||||
behat_command::$allowedtextselectors and behat_command::$allowedselectors
|
||||
|
||||
=== 2.5.1 ===
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ $PAGE->set_context(context_system::instance());
|
||||
if ($return) {
|
||||
// this redirect prevents security warning because https can not POST to http pages
|
||||
if (empty($SESSION->wantsurl)
|
||||
or stripos(str_replace('https://', 'http://', $SESSION->wantsurl), str_replace('https://', 'http://', $CFG->wwwroot.'/login/change_password.php') === 0)) {
|
||||
or stripos(str_replace('https://', 'http://', $SESSION->wantsurl), str_replace('https://', 'http://', $CFG->wwwroot.'/login/change_password.php')) === 0) {
|
||||
$returnto = "$CFG->wwwroot/user/view.php?id=$USER->id&course=$id";
|
||||
} else {
|
||||
$returnto = $SESSION->wantsurl;
|
||||
|
||||
@@ -94,6 +94,10 @@ class restore_assign_activity_structure_step extends restore_activity_structure_
|
||||
$data->cutoffdate = $this->apply_date_offset($data->cutoffdate);
|
||||
}
|
||||
|
||||
if ($data->grade < 0) { // Scale found, get mapping.
|
||||
$data->grade = -($this->get_mappingid('scale', abs($data->grade)));
|
||||
}
|
||||
|
||||
$newitemid = $DB->insert_record('assign', $data);
|
||||
|
||||
$this->apply_activity_instance($newitemid);
|
||||
|
||||
@@ -3660,9 +3660,10 @@ class assign {
|
||||
$team = groups_get_members($submission->groupid, 'u.id');
|
||||
|
||||
foreach ($team as $member) {
|
||||
$submission->groupid = 0;
|
||||
$submission->userid = $member->id;
|
||||
$this->gradebook_item_update($submission, null);
|
||||
$membersubmission = clone $submission;
|
||||
$membersubmission->groupid = 0;
|
||||
$membersubmission->userid = $member->id;
|
||||
$this->gradebook_item_update($membersubmission, null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -5324,7 +5325,7 @@ class assign {
|
||||
|
||||
// Give each submission plugin a chance to process the locking.
|
||||
$plugins = $this->get_submission_plugins();
|
||||
$submission = $this->get_user_submission($userid, false);
|
||||
$submission = $this->get_user_submission($userid, true);
|
||||
foreach ($plugins as $plugin) {
|
||||
if ($plugin->is_enabled() && $plugin->is_visible()) {
|
||||
$plugin->lock($submission);
|
||||
@@ -5361,7 +5362,7 @@ class assign {
|
||||
}
|
||||
// Give each submission plugin a chance to process the unlocking.
|
||||
$plugins = $this->get_submission_plugins();
|
||||
$submission = $this->get_user_submission($userid, false);
|
||||
$submission = $this->get_user_submission($userid, true);
|
||||
foreach ($plugins as $plugin) {
|
||||
if ($plugin->is_enabled() && $plugin->is_visible()) {
|
||||
$plugin->unlock($submission);
|
||||
|
||||
@@ -194,7 +194,8 @@ class moodle1_mod_assignment_handler extends moodle1_mod_handler {
|
||||
}
|
||||
|
||||
if (!isset($this->subpluginhandlers[$subplugin])) {
|
||||
throw new moodle1_convert_exception('unsupported_subplugin', 'assignment_'.$subplugin);
|
||||
// Generic handling, prevents breaking conversion process...
|
||||
$this->subpluginhandlers[$subplugin] = new moodle1_assignment_unsupported_subplugin_handler($this, $subplugin);
|
||||
}
|
||||
|
||||
return $this->subpluginhandlers[$subplugin];
|
||||
@@ -236,4 +237,10 @@ abstract class moodle1_assignment_subplugin_handler extends moodle1_submod_handl
|
||||
|
||||
//you will probably want to do stuff with $this->xmlwriter here (within your overridden method) to write plugin specific data.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class handles subplugins that do not exist or that are not supported
|
||||
*/
|
||||
class moodle1_assignment_unsupported_subplugin_handler extends moodle1_assignment_subplugin_handler {
|
||||
}
|
||||
@@ -72,6 +72,11 @@ class restore_assignment_activity_structure_step extends restore_activity_struct
|
||||
$newitemid = $DB->insert_record('assignment', $data);
|
||||
// immediately after inserting "activity" record, call this
|
||||
$this->apply_activity_instance($newitemid);
|
||||
|
||||
// Hide unsupported sub-plugins
|
||||
if (!$this->is_valid_assignment_subplugin($data->assignmenttype)) {
|
||||
$DB->set_field('course_modules', 'visible', 0, array('id' => $this->get_task()->get_moduleid()));
|
||||
}
|
||||
}
|
||||
|
||||
protected function process_assignment_submission($data) {
|
||||
@@ -100,4 +105,19 @@ class restore_assignment_activity_structure_step extends restore_activity_struct
|
||||
$this->add_related_files('mod_assignment', 'submission', 'assignment_submission');
|
||||
$this->add_related_files('mod_assignment', 'response', 'assignment_submission');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a sub-plugin is supported or not
|
||||
*
|
||||
* @param string $type
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_valid_assignment_subplugin($type) {
|
||||
static $subplugins = null;
|
||||
|
||||
if (is_null($subplugins)) {
|
||||
$subplugins = get_plugin_list('assignment');
|
||||
}
|
||||
return array_key_exists($type, $subplugins);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,3 +223,4 @@ $string['viewfeedback'] = 'View assignment grades and feedback';
|
||||
$string['viewmysubmission'] = 'View my submission';
|
||||
$string['viewsubmissions'] = 'View {$a} submitted assignments';
|
||||
$string['yoursubmission'] = 'Your submission';
|
||||
$string['unsupportedsubplugin'] = 'The assignment type of \'{$a}\' is not currently supported. You may wait until the assignment type is made available, or delete the assignment.';
|
||||
|
||||
@@ -3948,7 +3948,12 @@ function assignment_extend_settings_navigation(settings_navigation $settings, na
|
||||
global $PAGE, $DB, $USER, $CFG;
|
||||
|
||||
$assignmentrow = $DB->get_record("assignment", array("id" => $PAGE->cm->instance));
|
||||
require_once "$CFG->dirroot/mod/assignment/type/$assignmentrow->assignmenttype/assignment.class.php";
|
||||
|
||||
$classfile = "$CFG->dirroot/mod/assignment/type/$assignmentrow->assignmenttype/assignment.class.php";
|
||||
if (!file_exists($classfile)) {
|
||||
return;
|
||||
}
|
||||
require_once($classfile);
|
||||
|
||||
$assignmentclass = 'assignment_'.$assignmentrow->assignmenttype;
|
||||
$assignmentinstance = new $assignmentclass($PAGE->cm->id, $assignmentrow, $PAGE->cm, $PAGE->course);
|
||||
|
||||
@@ -9,7 +9,7 @@ class mod_assignment_mod_form extends moodleform_mod {
|
||||
protected $_assignmentinstance = null;
|
||||
|
||||
function definition() {
|
||||
global $CFG, $DB, $PAGE;
|
||||
global $CFG, $DB, $PAGE, $COURSE;
|
||||
$mform =& $this->_form;
|
||||
|
||||
// this hack is needed for different settings of each subtype
|
||||
@@ -29,7 +29,11 @@ class mod_assignment_mod_form extends moodleform_mod {
|
||||
$mform->setType('type', PARAM_ALPHA);
|
||||
$mform->setDefault('type', $type);
|
||||
|
||||
require_once($CFG->dirroot.'/mod/assignment/type/'.$type.'/assignment.class.php');
|
||||
$classfile = $CFG->dirroot.'/mod/assignment/type/'.$type.'/assignment.class.php';
|
||||
if (!file_exists($classfile)) {
|
||||
throw new moodle_exception('unsupportedsubplugin', 'assignment', new moodle_url('/course/view.php', array('id' => $COURSE->id)), $type);
|
||||
}
|
||||
require_once($classfile);
|
||||
$assignmentclass = 'assignment_'.$type;
|
||||
$assignmentinstance = new $assignmentclass();
|
||||
|
||||
|
||||
@@ -40,7 +40,11 @@ require_login($course, true, $cm);
|
||||
|
||||
$PAGE->requires->js('/mod/assignment/assignment.js');
|
||||
|
||||
require ("$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php");
|
||||
$classfile = "$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php";
|
||||
if (!file_exists($classfile)) {
|
||||
throw new moodle_exception('unsupportedsubplugin', 'assignment', new moodle_url('/course/view.php', array('id' => $course->id)), $assignment->assignmenttype);
|
||||
}
|
||||
require ($classfile);
|
||||
$assignmentclass = "assignment_$assignment->assignmenttype";
|
||||
$assignmentinstance = new $assignmentclass($cm->id, $assignment, $cm, $course);
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ $string['drop_feedback'] = 'Remove from this course';
|
||||
$string['edit_item'] = 'Edit question';
|
||||
$string['edit_items'] = 'Edit questions';
|
||||
$string['email_notification'] = 'Enable notification of submissions';
|
||||
$string['email_notification_help'] = 'If enabled, administrators receive email notification of feedback submissions.';
|
||||
$string['email_notification_help'] = 'If enabled, teachers will receive notification of feedback submissions.';
|
||||
$string['emailteachermail'] = '{$a->username} has completed feedback activity : \'{$a->feedback}\'
|
||||
|
||||
You can view it here:
|
||||
|
||||
@@ -411,14 +411,14 @@ $string['tracking'] = 'Track';
|
||||
$string['trackingoff'] = 'Off';
|
||||
$string['trackingon'] = 'On';
|
||||
$string['trackingoptional'] = 'Optional';
|
||||
$string['trackingtype'] = 'Read tracking for this forum?';
|
||||
$string['trackingtype_help'] = 'If enabled, participants can track read and unread messages in the forum and in discussions.
|
||||
$string['trackingtype'] = 'Read tracking';
|
||||
$string['trackingtype_help'] = 'If enabled, participants can track read and unread posts in the forum and in discussions. There are three options:
|
||||
|
||||
There are three options:
|
||||
|
||||
* Optional - Participants can choose whether to turn tracking on or off
|
||||
* Optional - Participants can choose whether to turn tracking on or off via a link in the administration block
|
||||
* On - Tracking is always on
|
||||
* Off - Tracking is always off';
|
||||
* Off - Read and unread posts are not tracked
|
||||
|
||||
Note: Forum tracking must also be enabled in the user\'s profile settings.';
|
||||
$string['unread'] = 'Unread';
|
||||
$string['unreadposts'] = 'Unread posts';
|
||||
$string['unreadpostsnumber'] = '{$a} unread posts';
|
||||
|
||||
@@ -24,7 +24,7 @@ Feature: A teacher can set one of 3 possible options for tracking read forum pos
|
||||
| Forum name | Test forum name |
|
||||
| Forum type | Standard forum for general use |
|
||||
| Description | Test forum description |
|
||||
| Read tracking for this forum | On |
|
||||
| Read tracking | On |
|
||||
And I add a new discussion to "Test forum name" forum with:
|
||||
| Subject | Test post subject |
|
||||
| Message | Test post message |
|
||||
@@ -45,7 +45,7 @@ Feature: A teacher can set one of 3 possible options for tracking read forum pos
|
||||
| Forum name | Test forum name |
|
||||
| Forum type | Standard forum for general use |
|
||||
| Description | Test forum description |
|
||||
| Read tracking for this forum | Off |
|
||||
| Read tracking | Off |
|
||||
And I add a new discussion to "Test forum name" forum with:
|
||||
| Subject | Test post subject |
|
||||
| Message | Test post message |
|
||||
@@ -63,7 +63,7 @@ Feature: A teacher can set one of 3 possible options for tracking read forum pos
|
||||
| Forum name | Test forum name |
|
||||
| Forum type | Standard forum for general use |
|
||||
| Description | Test forum description |
|
||||
| Read tracking for this forum | Optional |
|
||||
| Read tracking | Optional |
|
||||
And I add a new discussion to "Test forum name" forum with:
|
||||
| Subject | Test post subject |
|
||||
| Message | Test post message |
|
||||
|
||||
@@ -236,7 +236,7 @@ $string['maxgrade'] = 'Maximum grade';
|
||||
$string['maxgrade_help'] = 'This setting specifies the maximum grade for the lesson. If set to 0, the lesson does not appear in the grades pages.';
|
||||
$string['maxhighscores'] = 'Number of high scores displayed';
|
||||
$string['maximumnumberofanswersbranches'] = 'Maximum number of answers';
|
||||
$string['maximumnumberofanswersbranches_help'] = 'This setting specifies the maximum number of answers that may be used in the lesson. If only true/false questions are used, it can be set to 2. The setting may be changed at any time, since it only effects what the teacher sees, not the data.';
|
||||
$string['maximumnumberofanswersbranches_help'] = 'This setting specifies the maximum number of answers that may be used in the lesson. If only true/false questions are used, it can be set to 2. The setting may be changed at any time, since it only affects what the teacher sees, not the data.';
|
||||
$string['maximumnumberofattempts'] = 'Maximum number of attempts';
|
||||
$string['maximumnumberofattempts_help'] = 'This setting specifies the maximum number of attempts allowed for each question. If answered incorrectly repeatedly, when the maximum is reached, the next page of the lesson is displayed.';
|
||||
$string['maximumnumberofattemptsreached'] = 'Maximum number of attempts reached - Moving to next page';
|
||||
|
||||
@@ -224,7 +224,7 @@ $string['lti:requesttooladd'] = 'Request a tool is configured site-wide';
|
||||
$string['lti:view'] = 'Launch external tool activities';
|
||||
$string['lti_administration'] = 'LTI Administration';
|
||||
$string['lti_errormsg'] = 'The tool returned the following error message: "{$a}"';
|
||||
$string['lti_launch_error'] = 'An error occured when launching the external tool: ';
|
||||
$string['lti_launch_error'] = 'An error occurred when launching the external tool:';
|
||||
$string['lti_launch_error_tool_request'] = '<p>
|
||||
To submit a request for an administrator to complete the tool configuration, click <a href="{$a->admin_request_url}" target="_top">here</a>.
|
||||
</p>';
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
function xmldb_portfolio_googledocs_upgrade($oldversion) {
|
||||
global $CFG, $DB;
|
||||
require_once(__DIR__.'/upgradelib.php');
|
||||
|
||||
$dbman = $DB->get_manager();
|
||||
|
||||
@@ -53,28 +54,3 @@ function xmldb_portfolio_googledocs_upgrade($oldversion) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function portfolio_googledocs_admin_upgrade_notification() {
|
||||
$admins = get_admins();
|
||||
|
||||
if (empty($admins)) {
|
||||
return;
|
||||
}
|
||||
$a = new stdClass;
|
||||
$a->docsurl = get_docs_url('Google_OAuth_2.0_setup');
|
||||
|
||||
foreach ($admins as $admin) {
|
||||
$message = new stdClass();
|
||||
$message->component = 'moodle';
|
||||
$message->name = 'notices';
|
||||
$message->userfrom = get_admin();
|
||||
$message->userto = $admin;
|
||||
$message->smallmessage = get_string('oauth2upgrade_message_small', 'portfolio_googledocs');
|
||||
$message->subject = get_string('oauth2upgrade_message_subject', 'portfolio_googledocs');
|
||||
$message->fullmessage = get_string('oauth2upgrade_message_content', 'portfolio_googledocs', $a);
|
||||
$message->fullmessagehtml = get_string('oauth2upgrade_message_content', 'portfolio_googledocs', $a);
|
||||
$message->fullmessageformat = FORMAT_PLAIN;
|
||||
$message->notification = 1;
|
||||
message_send($message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Googledocs portfolio upgrade script.
|
||||
*
|
||||
* @package portfolio_googledocs
|
||||
* @copyright 2013 Dan Poltawski <dan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Inform admins about setup required for googledocs change.
|
||||
*/
|
||||
function portfolio_googledocs_admin_upgrade_notification() {
|
||||
$admins = get_admins();
|
||||
|
||||
if (empty($admins)) {
|
||||
return;
|
||||
}
|
||||
$a = new stdClass;
|
||||
$a->docsurl = get_docs_url('Google_OAuth_2.0_setup');
|
||||
|
||||
foreach ($admins as $admin) {
|
||||
$message = new stdClass();
|
||||
$message->component = 'moodle';
|
||||
$message->name = 'notices';
|
||||
$message->userfrom = get_admin();
|
||||
$message->userto = $admin;
|
||||
$message->smallmessage = get_string('oauth2upgrade_message_small', 'portfolio_googledocs');
|
||||
$message->subject = get_string('oauth2upgrade_message_subject', 'portfolio_googledocs');
|
||||
$message->fullmessage = get_string('oauth2upgrade_message_content', 'portfolio_googledocs', $a);
|
||||
$message->fullmessagehtml = get_string('oauth2upgrade_message_content', 'portfolio_googledocs', $a);
|
||||
$message->fullmessageformat = FORMAT_PLAIN;
|
||||
$message->notification = 1;
|
||||
message_send($message);
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
function xmldb_portfolio_picasa_upgrade($oldversion) {
|
||||
global $CFG, $DB;
|
||||
require_once(__DIR__.'/upgradelib.php');
|
||||
|
||||
$dbman = $DB->get_manager();
|
||||
|
||||
@@ -53,28 +54,3 @@ function xmldb_portfolio_picasa_upgrade($oldversion) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function portfolio_picasa_admin_upgrade_notification() {
|
||||
$admins = get_admins();
|
||||
|
||||
if (empty($admins)) {
|
||||
return;
|
||||
}
|
||||
$a = new stdClass;
|
||||
$a->docsurl = get_docs_url('Google_OAuth_2.0_setup');
|
||||
|
||||
foreach ($admins as $admin) {
|
||||
$message = new stdClass();
|
||||
$message->component = 'moodle';
|
||||
$message->name = 'notices';
|
||||
$message->userfrom = get_admin();
|
||||
$message->userto = $admin;
|
||||
$message->smallmessage = get_string('oauth2upgrade_message_small', 'portfolio_picasa');
|
||||
$message->subject = get_string('oauth2upgrade_message_subject', 'portfolio_picasa');
|
||||
$message->fullmessage = get_string('oauth2upgrade_message_content', 'portfolio_picasa', $a);
|
||||
$message->fullmessagehtml = get_string('oauth2upgrade_message_content', 'portfolio_picasa', $a);
|
||||
$message->fullmessageformat = FORMAT_PLAIN;
|
||||
$message->notification = 1;
|
||||
message_send($message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Picasa portfolio upgrade script.
|
||||
*
|
||||
* @package portfolio_picasa
|
||||
* @copyright 2013 Dan Poltawski <dan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Inform admins about setup required for picasa change.
|
||||
*/
|
||||
function portfolio_picasa_admin_upgrade_notification() {
|
||||
$admins = get_admins();
|
||||
|
||||
if (empty($admins)) {
|
||||
return;
|
||||
}
|
||||
$a = new stdClass;
|
||||
$a->docsurl = get_docs_url('Google_OAuth_2.0_setup');
|
||||
|
||||
foreach ($admins as $admin) {
|
||||
$message = new stdClass();
|
||||
$message->component = 'moodle';
|
||||
$message->name = 'notices';
|
||||
$message->userfrom = get_admin();
|
||||
$message->userto = $admin;
|
||||
$message->smallmessage = get_string('oauth2upgrade_message_small', 'portfolio_picasa');
|
||||
$message->subject = get_string('oauth2upgrade_message_subject', 'portfolio_picasa');
|
||||
$message->fullmessage = get_string('oauth2upgrade_message_content', 'portfolio_picasa', $a);
|
||||
$message->fullmessagehtml = get_string('oauth2upgrade_message_content', 'portfolio_picasa', $a);
|
||||
$message->fullmessageformat = FORMAT_PLAIN;
|
||||
$message->notification = 1;
|
||||
message_send($message);
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir . '/filelib.php');
|
||||
require_once(dirname(__FILE__) . '/questionusage.php');
|
||||
require_once(dirname(__FILE__) . '/questionattempt.php');
|
||||
require_once(dirname(__FILE__) . '/questionattemptstep.php');
|
||||
|
||||
@@ -85,7 +85,7 @@ $string['check_noauth_details'] = '<p>The <em>No authentication</em> plugin is n
|
||||
$string['check_noauth_error'] = 'The No authentication plugin cannot be used on production sites.';
|
||||
$string['check_noauth_name'] = 'No authentication';
|
||||
$string['check_noauth_ok'] = 'No authentication plugin is disabled.';
|
||||
$string['check_openprofiles_details'] = '<p>Open user profiles can be abused by spammers. It is recommended that either <code>Force users to login for profiles</code> or <code>Force users to login</code> are enabled.</p>';
|
||||
$string['check_openprofiles_details'] = 'Open user profiles can be abused by spammers. It is recommended that either <code>Force users to log in for profiles</code> or <code>Force users to log in</code> are enabled.';
|
||||
$string['check_openprofiles_error'] = 'Anyone can may view user profiles without logging in.';
|
||||
$string['check_openprofiles_name'] = 'Open user profiles';
|
||||
$string['check_openprofiles_ok'] = 'Login is required before viewing user profiles.';
|
||||
|
||||
@@ -180,10 +180,15 @@ class repository_coursefiles extends repository {
|
||||
return parent::is_visible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the repository name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_name() {
|
||||
list($context, $course, $cm) = get_context_info_array($this->context->id);
|
||||
if (!empty($course)) {
|
||||
return get_string('courselegacyfiles') . format_string($course->shortname, true, array('context' => get_course_context($context)));
|
||||
$context = $this->context->get_course_context(false);
|
||||
if ($context) {
|
||||
return get_string('courselegacyfilesofcourse', 'moodle', $context->get_context_name(false, true));
|
||||
} else {
|
||||
return get_string('courselegacyfiles');
|
||||
}
|
||||
|
||||
@@ -502,6 +502,7 @@ M.core_filepicker.show = function(Y, options) {
|
||||
M.core_filepicker.init(Y, options);
|
||||
}
|
||||
M.core_filepicker.instances[options.client_id].show();
|
||||
document.getElementById("filepicker-"+ options.client_id).focus();
|
||||
};
|
||||
|
||||
M.core_filepicker.set_templates = function(Y, templates) {
|
||||
@@ -1294,11 +1295,14 @@ M.core_filepicker.init = function(Y, options) {
|
||||
},
|
||||
render: function() {
|
||||
var client_id = this.options.client_id;
|
||||
var fpid = "filepicker-"+ client_id;
|
||||
var labelid = 'fp-dialog-label_'+ client_id;
|
||||
this.fpnode = Y.Node.createWithFilesSkin(M.core_filepicker.templates.generallayout).
|
||||
set('id', 'filepicker-'+client_id);
|
||||
set('id', fpid).set('aria-labelledby', labelid);
|
||||
|
||||
this.mainui = new Y.Panel({
|
||||
srcNode : this.fpnode,
|
||||
headerContent: M.str.repository.filepicker,
|
||||
headerContent: '<span id="'+ labelid +'">'+ M.str.repository.filepicker +'</span>',
|
||||
zIndex : 7500,
|
||||
centered : true,
|
||||
modal : true,
|
||||
@@ -1309,6 +1313,7 @@ M.core_filepicker.init = function(Y, options) {
|
||||
maxHeight : this.fpnode.getStylePx('maxHeight'),
|
||||
render : true
|
||||
});
|
||||
|
||||
// allow to move the panel dragging it by it's header:
|
||||
this.mainui.plug(Y.Plugin.Drag,{handles:['#filepicker-'+client_id+' .yui3-widget-hd']});
|
||||
this.mainui.show();
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
function xmldb_repository_googledocs_upgrade($oldversion) {
|
||||
global $CFG, $DB;
|
||||
require_once(__DIR__.'/upgradelib.php');
|
||||
|
||||
$dbman = $DB->get_manager();
|
||||
|
||||
@@ -56,28 +57,3 @@ function xmldb_repository_googledocs_upgrade($oldversion) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function repository_googledocs_admin_upgrade_notification() {
|
||||
$admins = get_admins();
|
||||
|
||||
if (empty($admins)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$a = new stdClass;
|
||||
$a->docsurl = get_docs_url('Google_OAuth_2.0_setup');
|
||||
foreach ($admins as $admin) {
|
||||
$message = new stdClass();
|
||||
$message->component = 'moodle';
|
||||
$message->name = 'notices';
|
||||
$message->userfrom = get_admin();
|
||||
$message->userto = $admin;
|
||||
$message->smallmessage = get_string('oauth2upgrade_message_small', 'repository_googledocs');
|
||||
$message->subject = get_string('oauth2upgrade_message_subject', 'repository_googledocs');
|
||||
$message->fullmessage = get_string('oauth2upgrade_message_content', 'repository_googledocs', $a);
|
||||
$message->fullmessagehtml = get_string('oauth2upgrade_message_content', 'repository_googledocs', $a);
|
||||
$message->fullmessageformat = FORMAT_PLAIN;
|
||||
$message->notification = 1;
|
||||
message_send($message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Googledocs repository upgrade script.
|
||||
*
|
||||
* @package repository_googledocs
|
||||
* @copyright 2013 Dan Poltawski <dan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Inform admins about setup required for googledocs change.
|
||||
*/
|
||||
function repository_googledocs_admin_upgrade_notification() {
|
||||
$admins = get_admins();
|
||||
|
||||
if (empty($admins)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$a = new stdClass;
|
||||
$a->docsurl = get_docs_url('Google_OAuth_2.0_setup');
|
||||
foreach ($admins as $admin) {
|
||||
$message = new stdClass();
|
||||
$message->component = 'moodle';
|
||||
$message->name = 'notices';
|
||||
$message->userfrom = get_admin();
|
||||
$message->userto = $admin;
|
||||
$message->smallmessage = get_string('oauth2upgrade_message_small', 'repository_googledocs');
|
||||
$message->subject = get_string('oauth2upgrade_message_subject', 'repository_googledocs');
|
||||
$message->fullmessage = get_string('oauth2upgrade_message_content', 'repository_googledocs', $a);
|
||||
$message->fullmessagehtml = get_string('oauth2upgrade_message_content', 'repository_googledocs', $a);
|
||||
$message->fullmessageformat = FORMAT_PLAIN;
|
||||
$message->notification = 1;
|
||||
message_send($message);
|
||||
}
|
||||
}
|
||||
+3
-10
@@ -255,6 +255,7 @@ class repository_type implements cacheable_object {
|
||||
}
|
||||
//run plugin_init function
|
||||
if (!repository::static_function($this->_typename, 'plugin_init')) {
|
||||
$this->update_visibility(false);
|
||||
if (!$silent) {
|
||||
throw new repository_exception('cannotinitplugin', 'repository');
|
||||
}
|
||||
@@ -1139,7 +1140,7 @@ abstract class repository implements cacheable_object {
|
||||
*
|
||||
* @static
|
||||
* @param string $plugin repository plugin name
|
||||
* @param string $function funciton name
|
||||
* @param string $function function name
|
||||
* @return mixed
|
||||
*/
|
||||
public static function static_function($plugin, $function) {
|
||||
@@ -1152,14 +1153,6 @@ abstract class repository implements cacheable_object {
|
||||
return false;
|
||||
}
|
||||
|
||||
$pname = null;
|
||||
if (is_object($plugin) || is_array($plugin)) {
|
||||
$plugin = (object)$plugin;
|
||||
$pname = $plugin->name;
|
||||
} else {
|
||||
$pname = $plugin;
|
||||
}
|
||||
|
||||
$args = func_get_args();
|
||||
if (count($args) <= 2) {
|
||||
$args = array();
|
||||
@@ -2437,7 +2430,7 @@ abstract class repository implements cacheable_object {
|
||||
|
||||
/**
|
||||
* For oauth like external authentication, when external repository direct user back to moodle,
|
||||
* this funciton will be called to set up token and token_secret
|
||||
* this function will be called to set up token and token_secret
|
||||
*/
|
||||
public function callback() {
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
function xmldb_repository_picasa_upgrade($oldversion) {
|
||||
global $CFG, $DB;
|
||||
require_once(__DIR__.'/upgradelib.php');
|
||||
|
||||
$dbman = $DB->get_manager();
|
||||
|
||||
@@ -56,28 +57,3 @@ function xmldb_repository_picasa_upgrade($oldversion) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function repository_picasa_admin_upgrade_notification() {
|
||||
$admins = get_admins();
|
||||
|
||||
if (empty($admins)) {
|
||||
return;
|
||||
}
|
||||
$a = new stdClass;
|
||||
$a->docsurl = get_docs_url('Google_OAuth_2.0_setup');
|
||||
|
||||
foreach ($admins as $admin) {
|
||||
$message = new stdClass();
|
||||
$message->component = 'moodle';
|
||||
$message->name = 'notices';
|
||||
$message->userfrom = get_admin();
|
||||
$message->userto = $admin;
|
||||
$message->smallmessage = get_string('oauth2upgrade_message_small', 'repository_picasa');
|
||||
$message->subject = get_string('oauth2upgrade_message_subject', 'repository_picasa');
|
||||
$message->fullmessage = get_string('oauth2upgrade_message_content', 'repository_picasa', $a);
|
||||
$message->fullmessagehtml = get_string('oauth2upgrade_message_content', 'repository_picasa', $a);
|
||||
$message->fullmessageformat = FORMAT_PLAIN;
|
||||
$message->notification = 1;
|
||||
message_send($message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Picasa repository upgrade script.
|
||||
*
|
||||
* @package repository_picasa
|
||||
* @copyright 2013 Dan Poltawski <dan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Inform admins about setup required for google picasa change.
|
||||
*/
|
||||
function repository_picasa_admin_upgrade_notification() {
|
||||
$admins = get_admins();
|
||||
|
||||
if (empty($admins)) {
|
||||
return;
|
||||
}
|
||||
$a = new stdClass;
|
||||
$a->docsurl = get_docs_url('Google_OAuth_2.0_setup');
|
||||
|
||||
foreach ($admins as $admin) {
|
||||
$message = new stdClass();
|
||||
$message->component = 'moodle';
|
||||
$message->name = 'notices';
|
||||
$message->userfrom = get_admin();
|
||||
$message->userto = $admin;
|
||||
$message->smallmessage = get_string('oauth2upgrade_message_small', 'repository_picasa');
|
||||
$message->subject = get_string('oauth2upgrade_message_subject', 'repository_picasa');
|
||||
$message->fullmessage = get_string('oauth2upgrade_message_content', 'repository_picasa', $a);
|
||||
$message->fullmessagehtml = get_string('oauth2upgrade_message_content', 'repository_picasa', $a);
|
||||
$message->fullmessageformat = FORMAT_PLAIN;
|
||||
$message->notification = 1;
|
||||
message_send($message);
|
||||
}
|
||||
}
|
||||
@@ -60,10 +60,12 @@ class behat_filepicker extends behat_files {
|
||||
|
||||
// Setting the folder name in the modal window.
|
||||
$exception = new ExpectationException('The dialog to enter the folder name does not appear', $this->getSession());
|
||||
$dialoginput = $this->find('css', '.fp-mkdir-dlg-text input');
|
||||
$dialoginput = $this->find('css', '.fp-mkdir-dlg-text input', $exception);
|
||||
$dialoginput->setValue($foldername);
|
||||
|
||||
$this->getSession()->getPage()->pressButton(get_string('makeafolder'));
|
||||
$exception = new ExpectationException('The button for the create folder dialog can not be located', $this->getSession());
|
||||
$buttonnode = $this->find('css', '.fp-dlg-butcreate', $exception);
|
||||
$buttonnode->click();
|
||||
|
||||
// Wait until the process finished and modal windows are hidden.
|
||||
$this->wait_until_return_to_form();
|
||||
|
||||
@@ -346,6 +346,7 @@ input#id_externalurl {direction:ltr;}
|
||||
.groupmanagementtable #potentialcell {width: 42%;}
|
||||
.groupmanagementtable #buttonscell {width: 16%;}
|
||||
.groupmanagementtable #buttonscell input {width: 80%;}
|
||||
.groupmanagementtable #buttonscell p.arrow_button input {width: auto;min-width: 80%;margin: 0 auto;}
|
||||
.groupmanagementtable #removeselect_wrapper,
|
||||
.groupmanagementtable #addselect_wrapper {width: 100%;}
|
||||
.groupmanagementtable #removeselect_wrapper label,
|
||||
|
||||
@@ -388,6 +388,11 @@ a.skip:active {
|
||||
.groupmanagementtable #buttonscell {
|
||||
width: 16%;
|
||||
}
|
||||
.groupmanagementtable #buttonscell p.arrow_button input {
|
||||
width: auto;
|
||||
min-width: 80%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.groupmanagementtable #removeselect_wrapper,
|
||||
.groupmanagementtable #addselect_wrapper {
|
||||
width: 100%;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -58,13 +58,12 @@ if ($deluser !== 0) {
|
||||
$url->param('deluser', $deluser);
|
||||
}
|
||||
$PAGE->set_url($url);
|
||||
$PAGE->set_context(context_system::instance());
|
||||
|
||||
if (!$course = $DB->get_record('course', array('id'=>$id))) {
|
||||
print_error('invalidcourseid');
|
||||
}
|
||||
|
||||
require_login();
|
||||
require_login($course);
|
||||
|
||||
$coursecontext = context_course::instance($id); // Course context
|
||||
$systemcontext = context_system::instance(); // SYSTEM context
|
||||
|
||||
@@ -23,4 +23,4 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['pluginname'] = 'Menu of choices';
|
||||
$string['pluginname'] = 'Dropdown menu';
|
||||
|
||||
+2
-2
@@ -29,11 +29,11 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2013051401.12; // 20130514 = branching date YYYYMMDD - do not modify!
|
||||
$version = 2013051401.14; // 20130514 = branching date YYYYMMDD - do not modify!
|
||||
// RR = release increments - 00 in DEV branches
|
||||
// .XX = incremental changes
|
||||
|
||||
$release = '2.5.1+ (Build: 20130830)'; // Human-friendly version name
|
||||
$release = '2.5.1+ (Build: 20130905)'; // 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