--errors=errors,duplicate-properties
--warnings=known-properties,display-property-grouping,empty-rules,important
---exclude-list=vendor/,lib/editor/tinymce/,lib/yuilib/,theme/bootstrapbase/style/
+--exclude-list=vendor/,node_modules/,lib/editor/tinymce/,lib/yuilib/,theme/bootstrapbase/style/,lib/jquery/,lib/htmlpurifier,theme/clean/style/custom.css,theme/more/style/custom.css,
},
'rules': {
// See http://eslint.org/docs/rules/ for all rules and explanations of all
- // rules. Commented out rules with 'DEFINE POLICY' are rules Dan P has flagged
- // for discussion and possible enable soon.
+ // rules.
+
// === Possible Errors ===
- // DEFINE POLICY: 'comma-dangle': ['off', 'always'],
+ 'comma-dangle': 'off',
'no-cond-assign': 'error',
'no-console': 'error',
'no-constant-condition': 'error',
'no-dupe-args': 'error',
'no-dupe-keys': 'error',
'no-duplicate-case': 'error',
- // Disabled for YUI rollups, enabled by grunt for AMD: 'no-empty': 'error',
+ 'no-empty': 'warn',
'no-empty-character-class': 'error',
'no-ex-assign': 'error',
'no-extra-boolean-cast': 'error',
// === Best Practices ===
// (these mostly match our jshint config)
+ 'array-callback-return': 'warn',
+ 'block-scoped-var': 'warn',
+ 'complexity': 'warn',
+ 'consistent-return': 'warn',
'curly': 'error',
'dot-notation': 'warn',
'no-alert': 'warn',
'no-caller': 'error',
'no-case-declarations': 'error',
+ 'no-div-regex': 'error',
'no-empty-pattern': 'error',
'no-empty-function': 'warn',
- //DEFINE POLICY: 'no-eq-null': 'warn',
+ 'no-eq-null': 'error',
'no-eval': 'error',
- //DEFINE POLICY: 'no-extra-bind': 'warn',
+ 'no-extend-native': 'error',
+ 'no-extra-bind': 'warn',
'no-fallthrough': 'error',
- //DEFINE POLICY: 'no-implicit-globals': 'warn',
+ 'no-floating-decimal': 'warn',
+ // Enabled by grunt for AMD modules: 'no-implicit-globals': 'error',
'no-implied-eval': 'error',
'no-invalid-this': 'error',
'no-iterator': 'error',
'no-native-reassign': 'warn',
'no-new-func': 'error',
'no-new-wrappers': 'error',
- // DEFINE POLICY: no-octal: "error"
- // DEFINE POLICY: no-octal-escape: "error"
+ 'no-octal': 'error',
+ 'no-octal-escape': 'error',
'no-proto': 'error',
'no-redeclare': 'warn',
'no-return-assign': 'error',
'no-script-url': 'error',
'no-self-assign': 'error',
'no-self-compare': 'error',
+ 'no-sequences': 'warn',
+ 'no-throw-literal': 'warn',
'no-unmodified-loop-condition': 'error',
- // Disabled for YUI rollups, enabled by grunt for AMD: 'no-unused-expressions': 'error',
+ 'no-unused-expressions': 'error',
'no-unused-labels': 'error',
- //DEFINE POLICY: 'no-useless-call': 'error',
+ 'no-useless-call': 'warn',
'no-useless-escape': 'warn',
- //DEFINE POLICY: 'no-with': 'error',
+ 'no-with': 'error',
'wrap-iife': ['error', 'any'],
// === Variables ===
'no-delete-var': 'error',
- // Disabled for YUI rollups, enabled by grunt for AMD: 'no-undef': 'off',
- //DEFINE POLICY: 'no-undef-init': 'error',
- // Disabled for YUI rollups, enabled by grunt for AMD: 'no-unused-vars': 'error',
+ 'no-undef': 'error',
+ 'no-undef-init': 'error',
+ 'no-unused-vars': ['error', { 'caughtErrors': 'none', 'argsIgnorePattern': "(e|event)" }],
// === Stylistic Issues ===
'array-bracket-spacing': 'warn',
'lines-around-comment': 'off',
'max-len': ['error', 132],
'max-lines': 'off',
- // DEFINE POLICY: turn on some of these max values?
- 'max-depth': 'off',
- 'max-nested-callbacks': 'off',
+ 'max-depth': 'warn',
+ 'max-nested-callbacks': ['warn', 5],
'max-params': 'off',
'max-statements': 'off',
- 'max-statements-per-line': 'off',
+ 'max-statements-per-line': ['warn', { max: 2 }],
'new-cap': ['warn', { 'properties': false }],
'new-parens': 'warn',
'newline-after-var': 'off',
'newline-before-return': 'off',
- // REVIST POLICY: 'newline-per-chained-call': 'warn',
+ 'newline-per-chained-call': 'off',
'no-array-constructor': 'off',
'no-bitwise': 'error',
'no-continue': 'off',
'no-ternary': 'off',
'no-trailing-spaces': 'error',
'no-underscore-dangle': 'off',
- // DEFINE POLICY: 'no-unneeded-ternary': 'off',
+ 'no-unneeded-ternary': 'off',
'no-whitespace-before-property': 'warn',
- // DEFINE POLICY: 'object-curly-newline': 'off,
- // DEFINE POLICY: 'object-curly-spacing': 'off',
- // DEFINE POLICY: 'object-property-newline': 'off',
+ 'object-curly-newline': 'off',
+ 'object-curly-spacing': 'warn',
+ 'object-property-newline': 'off',
'one-var': 'off',
- // DEFINE POLICY: 'one-var-declaration-per-line': 'off',
+ 'one-var-declaration-per-line': ['warn', 'initializations'],
'operator-assignment': 'off',
'operator-linebreak': 'off',
'padded-blocks': 'off',
- // DEFINE POLICY: 'quote-props': 'off',
+ 'quote-props': ['warn', 'as-needed', {'unnecessary': false, 'keywords': true, 'numbers': true}],
'quotes': 'off',
'require-jsdoc': 'warn',
'semi': 'error',
# Perform an upgrade test too.
- DB=pgsql TASK=UPGRADE
- # Run a check for unbuilt files with Grunt.
- - DB=none TASK=GRUNT
-
matrix:
# Enable fast finish.
# This will fail the build if a single job fails (except those in allow_failures).
# It will not stop the jobs from running.
fast_finish: true
+ include:
+ # Run grunt/npm install on lowest supported npm version
+ - php: 7
+ env: DB=none TASK=GRUNT NVM_VERSION='4'
+ # Run grunt/npm install on highest version ('node' is an alias for the latest node.js version.)
+ - php: 7
+ env: DB=none TASK=GRUNT NVM_VERSION='node'
+
exclude:
# MySQL - it's just too slow.
# Exclude it on all versions except for 7.0
- env: DB=mysqli TASK=PHPUNIT
php: 5.6
- # One grunt execution is enough.
- - env: DB=none TASK=GRUNT
- php: 5.6
-
# Moodle 2.7 is not compatible with PHP 7 for the upgrade test.
- env: DB=pgsql TASK=UPGRADE
php: 7.0
# Disable xdebug. We aren't generating code coverage, and it has a huge impact upon test performance.
- rm /home/travis/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini
- # Set the encrypted GITHUB_TOKEN if it's available to raise the API limit.
- - if [ -n "$GITHUB_APITOKEN" ]; then composer config github-oauth.github.com $GITHUB_APITOKEN; fi
- - echo 'auth.json' >> .git/info/exclude
+ - >
+ if [ "$TASK" = 'PHPUNIT' ];
+ then
+ if [ -n "$GITHUB_APITOKEN" ]; then
+ composer config github-oauth.github.com $GITHUB_APITOKEN;
+ echo 'auth.json' >> .git/info/exclude
+ fi
+
+ # Install composer dependencies.
+ # We need --no-interaction in case we hit API limits for composer. This causes it to fall back to a standard clone.
+ # Typically it should be able to use the Composer cache if any other job has already completed before we started here.
+ travis_retry composer install --prefer-dist --no-interaction;
+ fi
- # Install composer dependencies.
- # We need --no-interaction in case we hit API limits for composer. This causes it to fall back to a standard clone.
- # Typically it should be able to use the Composer cache if any other job has already completed before we started here.
- - travis_retry composer install --prefer-dist --no-interaction
+ - >
+ if [ "$TASK" = 'GRUNT' ];
+ then
+ nvm install $NVM_VERSION ;
+ nvm use $NVM_VERSION ;
+ fi
before_script:
- >
- >
if [ "$TASK" = 'GRUNT' ];
then
- npm install ;
- npm install -g grunt ;
- grunt ;
+ npm install --no-spin;
+ npm install --no-spin -g grunt ;
fi
########################################################################
- >
if [ "$TASK" = 'GRUNT' ];
then
+ grunt ;
# Add all files to the git index and then run diff --cached to see all changes.
# This ensures that we get the status of all files, including new files.
git add . ;
eslint: {
// Even though warnings dont stop the build we don't display warnings by default because
// at this moment we've got too many core warnings.
- options: { quiet: !grunt.option('show-lint-warnings') },
- // Check AMD files. We add some stricter rules which we can't apply to the default configuration due
- // to YUI rollups.
+ options: {quiet: !grunt.option('show-lint-warnings')},
amd: {
src: amdSrc,
- options: {
- rules: {'no-undef': 'error', 'no-unused-vars': 'error', 'no-empty': 'error', 'no-unused-expressions': 'error'}
+ // Check AMD with some slightly stricter rules.
+ rules: {
+ 'no-unused-vars': 'error',
+ 'no-implicit-globals': 'error'
}
},
// Check YUI module source files.
yui: {
src: ['**/yui/src/**/*.js', '!*/**/yui/src/*/meta/*.js'],
+ options: {
+ // Disable some rules which we can't safely define for YUI rollups.
+ rules: {
+ 'no-undef': 'off',
+ 'no-unused-vars': 'off',
+ 'no-unused-expressions': 'off'
+ }
+ }
}
},
uglify: {
expand: true,
src: amdSrc,
rename: uglifyRename
- }]
+ }],
+ options: {report: 'none'}
}
},
less: {
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php'); // cli only functions
+// Define the input options.
+$longparams = array(
+ 'help' => false,
+ 'username' => '',
+ 'password' => '',
+ 'ignore-password-policy' => false
+);
+
+$shortparams = array(
+ 'h' => 'help',
+ 'u' => 'username',
+ 'p' => 'password',
+ 'i' => 'ignore-password-policy'
+);
// now get cli options
-list($options, $unrecognized) = cli_get_params(array('help'=>false),
- array('h'=>'help'));
+list($options, $unrecognized) = cli_get_params($longparams, $shortparams);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
execute this file may execute any PHP too.
Options:
--h, --help Print out this help
+-h, --help Print out this help
+-u, --username=username Specify username to change
+-p, --password=newpassword Specify new password
+--ignore-password-policy Ignore password policy when setting password
Example:
\$sudo -u www-data /usr/bin/php admin/cli/reset_password.php
+\$sudo -u www-data /usr/bin/php admin/cli/reset_password.php --username=rosaura --password=jiu3jiu --ignore-password-policy
"; //TODO: localize - to be translated later when everything is finished
echo $help;
die;
}
-cli_heading('Password reset'); // TODO: localize
-$prompt = "enter username (manual authentication only)"; // TODO: localize
-$username = cli_input($prompt);
+if ($options['username'] == '' ) {
+ cli_heading('Password reset'); // TODO: localize.
+ $prompt = "enter username (manual authentication only)"; // TODO: localize.
+ $username = cli_input($prompt);
+} else {
+ $username = $options['username'];
+}
if (!$user = $DB->get_record('user', array('auth'=>'manual', 'username'=>$username, 'mnethostid'=>$CFG->mnet_localhost_id))) {
cli_error("Can not find user '$username'");
}
-$prompt = "Enter new password"; // TODO: localize
-$password = cli_input($prompt);
+if ($options['password'] == '' ) {
+ $prompt = "Enter new password"; // TODO: localize.
+ $password = cli_input($prompt);
+} else {
+ $password = $options['password'];
+}
$errmsg = '';//prevent eclipse warning
-if (!check_password_policy($password, $errmsg)) {
- cli_error($errmsg);
+if (!$options['ignore-password-policy'] ) {
+ if (!check_password_policy($password, $errmsg)) {
+ cli_error($errmsg);
+ }
}
$hashedpassword = hash_internal_user_password($password);
echo "Password changed\n";
-exit(0); // 0 means success
\ No newline at end of file
+exit(0); // 0 means success.
die();
}
+// Make sure xml extension is available.
+if (!extension_loaded('xml')) {
+ echo 'Moodle requires the xml PHP extension. Please install or enable the xml extension.';
+ die();
+}
+
define('NO_OUTPUT_BUFFERING', true);
if (isset($_POST['upgradekey'])) {
--- /dev/null
+<?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/>.
+
+/**
+ * Manage global search areas.
+ *
+ * @package core_search
+ * @copyright 2016 Dan Poltawski <dan@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+require_once(__DIR__ . '/../config.php');
+require_once($CFG->libdir . '/adminlib.php');
+
+admin_externalpage_setup('searchareas');
+
+$areaid = optional_param('areaid', null, PARAM_ALPHAEXT);
+$action = optional_param('action', null, PARAM_ALPHA);
+
+try {
+ $searchmanager = \core_search\manager::instance();
+} catch (core_search\engine_exception $searchmanagererror) {
+ // Continue, we return an error later depending on the requested action.
+}
+
+echo $OUTPUT->header();
+
+if ($action) {
+ require_sesskey();
+
+ if ($areaid) {
+ // We need to check that the area exists.
+ $area = \core_search\manager::get_search_area($areaid);
+ if ($area === false) {
+ throw new moodle_exception('invalidrequest');
+ }
+ }
+
+ // All actions but enable/disable need the search engine to be ready.
+ if ($action !== 'enable' && $action !== 'disable') {
+ if (!empty($searchmanagererror)) {
+ throw $searchmanagererror;
+ }
+ }
+
+ switch ($action) {
+ case 'enable':
+ $area->set_enabled(true);
+ echo $OUTPUT->notification(get_string('searchareaenabled', 'admin'), \core\output\notification::NOTIFY_SUCCESS);
+ break;
+ case 'disable':
+ $area->set_enabled(false);
+ echo $OUTPUT->notification(get_string('searchareadisabled', 'admin'), \core\output\notification::NOTIFY_SUCCESS);
+ break;
+ case 'delete':
+ $search = \core_search\manager::instance();
+ $search->delete_index($areaid);
+ echo $OUTPUT->notification(get_string('searchindexdeleted', 'admin'), \core\output\notification::NOTIFY_SUCCESS);
+ break;
+ case 'indexall':
+ $searchmanager->index();
+ echo $OUTPUT->notification(get_string('searchindexupdated', 'admin'), \core\output\notification::NOTIFY_SUCCESS);
+ break;
+ case 'reindexall':
+ $searchmanager->index(true);
+ echo $OUTPUT->notification(get_string('searchreindexed', 'admin'), \core\output\notification::NOTIFY_SUCCESS);
+ break;
+ case 'deleteall':
+ $searchmanager->delete_index();
+ echo $OUTPUT->notification(get_string('searchalldeleted', 'admin'), \core\output\notification::NOTIFY_SUCCESS);
+ break;
+ default:
+ throw new moodle_exception('invalidaction');
+ break;
+ }
+}
+
+$searchareas = \core_search\manager::get_search_areas_list();
+if (empty($searchmanagererror)) {
+ $areasconfig = $searchmanager->get_areas_config($searchareas);
+} else {
+ $areasconfig = false;
+}
+
+if (!empty($searchmanagererror)) {
+ $errorstr = get_string($searchmanagererror->errorcode, $searchmanagererror->module);
+ echo $OUTPUT->notification($errorstr, \core\output\notification::NOTIFY_ERROR);
+} else {
+ echo $OUTPUT->notification(get_string('indexinginfo', 'admin'), \core\output\notification::NOTIFY_INFO);
+}
+
+$table = new html_table();
+$table->id = 'core-search-areas';
+
+$table->head = array(get_string('searcharea', 'search'), get_string('enable'), get_string('newestdocindexed', 'admin'),
+ get_string('searchlastrun', 'admin'), get_string('searchindexactions', 'admin'));
+
+foreach ($searchareas as $area) {
+ $areaid = $area->get_area_id();
+ $columns = array(new html_table_cell($area->get_visible_name()));
+
+ if ($area->is_enabled()) {
+ $columns[] = $OUTPUT->action_icon(admin_searcharea_action_url('disable', $areaid),
+ new pix_icon('t/hide', get_string('disable'), 'moodle', array('title' => '', 'class' => 'iconsmall')),
+ null, array('title' => get_string('disable')));
+
+ if ($areasconfig) {
+ $columns[] = $areasconfig[$areaid]->lastindexrun;
+
+ if ($areasconfig[$areaid]->indexingstart) {
+ $timediff = $areasconfig[$areaid]->indexingend - $areasconfig[$areaid]->indexingstart;
+ $laststatus = $timediff . ' , ' .
+ $areasconfig[$areaid]->docsprocessed . ' , ' .
+ $areasconfig[$areaid]->recordsprocessed . ' , ' .
+ $areasconfig[$areaid]->docsignored;
+ } else {
+ $laststatus = '';
+ }
+ $columns[] = $laststatus;
+ $columns[] = html_writer::link(admin_searcharea_action_url('delete', $areaid), 'Delete index');
+
+ } else {
+ $blankrow = new html_table_cell(get_string('searchnotavailable', 'admin'));
+ $blankrow->colspan = 3;
+ $columns[] = $blankrow;
+ }
+
+ } else {
+ $columns[] = $OUTPUT->action_icon(admin_searcharea_action_url('enable', $areaid),
+ new pix_icon('t/show', get_string('enable'), 'moodle', array('title' => '', 'class' => 'iconsmall')),
+ null, array('title' => get_string('enable')));
+
+ $blankrow = new html_table_cell(get_string('searchareadisabled', 'admin'));
+ $blankrow->colspan = 3;
+ $columns[] = $blankrow;
+ }
+ $row = new html_table_row($columns);
+ $table->data[] = $row;
+}
+
+// Cross-search area tasks.
+$options = array();
+if (!empty($searchmanagererror)) {
+ $options['disabled'] = true;
+}
+echo $OUTPUT->box_start('search-areas-actions');
+echo $OUTPUT->single_button(admin_searcharea_action_url('indexall'), get_string('searchupdateindex', 'admin'), 'get', $options);
+echo $OUTPUT->single_button(admin_searcharea_action_url('reindexall'), get_string('searchreindexindex', 'admin'), 'get', $options);
+echo $OUTPUT->single_button(admin_searcharea_action_url('deleteall'), get_string('searchdeleteindex', 'admin'), 'get', $options);
+echo $OUTPUT->box_end();
+
+echo html_writer::table($table);
+echo $OUTPUT->footer();
+
+/**
+ * Helper for generating url for management actions.
+ *
+ * @param string $action
+ * @param string $areaid
+ * @return moodle_url
+ */
+function admin_searcharea_action_url($action, $areaid = false) {
+ $params = array('action' => $action, 'sesskey' => sesskey());
+ if ($areaid) {
+ $params['areaid'] = $areaid;
+ }
+ return new moodle_url('/admin/searchareas.php', $params);
+}
$temp->add(new admin_setting_configselect('searchengine',
new lang_string('selectsearchengine', 'admin'), '', 'solr', $engines));
- // Enable search areas.
- $temp->add(new admin_setting_heading('searchareasheading', new lang_string('availablesearchareas', 'admin'), ''));
- $searchareas = \core_search\manager::get_search_areas_list();
- foreach ($searchareas as $areaid => $searcharea) {
- list($componentname, $varname) = $searcharea->get_config_var_name();
- $temp->add(new admin_setting_configcheckbox($componentname . '/' . $varname . '_enabled', $searcharea->get_visible_name(true),
- '', 1, 1, 0));
- }
$ADMIN->add('searchplugins', $temp);
+ $ADMIN->add('searchplugins', new admin_externalpage('searchareas', new lang_string('searchareas', 'admin'),
+ new moodle_url('/admin/searchareas.php')));
core_collator::asort_objects_by_property($pages, 'visiblename');
foreach ($pages as $page) {
self._selectedValue = $("input[type='radio']:checked").val();
self._find('[data-action="action-selector-confirm"]').removeAttr('disabled');
self._refresh.bind(self);
- }.bind(self));
+ });
// Add listener for cancel.
self._find('[data-action="action-selector-cancel"]').click(function(e) {
e.preventDefault();
self.close();
- }.bind(self));
+ });
// Add listener for confirm.
self._find('[data-action="action-selector-confirm"]').click(function(e) {
if (!self._selectedValue.length) {
return;
}
- self._trigger('save', { action: self._selectedValue });
+ self._trigger('save', {action: self._selectedValue});
self.close();
- }.bind(self));
+ });
};
/**
html,
self._afterRender.bind(self)
);
- }.bind(self)).fail(Notification.exception);
+ }).fail(Notification.exception);
};
/**
return self._render().then(function(html) {
self._find('[data-region="action-selector"]').replaceWith(html);
self._afterRender();
- }.bind(self));
+ });
};
/**
function(movestring) {
dragdrop.dragdrop('movecompetency',
movestring,
- { identifier: 'movecompetency', component: 'tool_lp'},
- { identifier: 'movecompetencyafter', component: 'tool_lp'},
+ {identifier: 'movecompetency', component: 'tool_lp'},
+ {identifier: 'movecompetencyafter', component: 'tool_lp'},
'drag-samenode',
'drag-parentnode',
'drag-handlecontainer',
function(drag, drop) {
- localthis.handleDrop.call(localthis, drag, drop);
+ localthis.handleDrop(drag, drop);
});
}
).fail(notification.exception);
requests = ajax.call([
{
methodname: 'core_competency_reorder_course_competency',
- args: { courseid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid }
+ args: {courseid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid}
}
]);
} else if (localthis.itemtype == 'template') {
requests = ajax.call([
{
methodname: 'core_competency_reorder_template_competency',
- args: { templateid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid }
+ args: {templateid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid}
}
]);
} else if (localthis.itemtype == 'plan') {
requests = ajax.call([
{
methodname: 'core_competency_reorder_plan_competency',
- args: { planid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid }
+ args: {planid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid}
}
]);
} else {
$.each(compIds, function(index, compId) {
requests.push({
methodname: 'core_competency_add_competency_to_course',
- args: { courseid: self.itemid, competencyid: compId }
+ args: {courseid: self.itemid, competencyid: compId}
});
});
requests.push({
methodname: 'tool_lp_data_for_course_competencies_page',
- args: { courseid: self.itemid }
+ args: {courseid: self.itemid}
});
pagerender = 'tool_lp/course_competencies_page';
$.each(compIds, function(index, compId) {
requests.push({
methodname: 'core_competency_add_competency_to_template',
- args: { templateid: self.itemid, competencyid: compId }
+ args: {templateid: self.itemid, competencyid: compId}
});
});
requests.push({
methodname: 'tool_lp_data_for_template_competencies_page',
- args: { templateid: self.itemid, pagecontext: { contextid: self.pageContextId }}
+ args: {templateid: self.itemid, pagecontext: {contextid: self.pageContextId}}
});
pagerender = 'tool_lp/template_competencies_page';
pageregion = 'templatecompetenciespage';
$.each(compIds, function(index, compId) {
requests.push({
methodname: 'core_competency_add_competency_to_plan',
- args: { planid: self.itemid, competencyid: compId }
+ args: {planid: self.itemid, competencyid: compId}
});
});
requests.push({
methodname: 'tool_lp_data_for_plan_page',
- args: { planid: self.itemid}
+ args: {planid: self.itemid}
});
pagerender = 'tool_lp/plan_page';
pageregion = 'plan-page';
// Delete the link and reload the page template.
if (localthis.itemtype == 'course') {
requests = ajax.call([
- { methodname: 'core_competency_remove_competency_from_course',
- args: { courseid: localthis.itemid, competencyid: deleteid } },
- { methodname: 'tool_lp_data_for_course_competencies_page',
- args: { courseid: localthis.itemid } }
+ {methodname: 'core_competency_remove_competency_from_course',
+ args: {courseid: localthis.itemid, competencyid: deleteid}},
+ {methodname: 'tool_lp_data_for_course_competencies_page',
+ args: {courseid: localthis.itemid}}
]);
pagerender = 'tool_lp/course_competencies_page';
pageregion = 'coursecompetenciespage';
} else if (localthis.itemtype == 'template') {
requests = ajax.call([
- { methodname: 'core_competency_remove_competency_from_template',
- args: { templateid: localthis.itemid, competencyid: deleteid } },
- { methodname: 'tool_lp_data_for_template_competencies_page',
- args: { templateid: localthis.itemid, pagecontext: { contextid: localthis.pageContextId } } }
+ {methodname: 'core_competency_remove_competency_from_template',
+ args: {templateid: localthis.itemid, competencyid: deleteid}},
+ {methodname: 'tool_lp_data_for_template_competencies_page',
+ args: {templateid: localthis.itemid, pagecontext: {contextid: localthis.pageContextId}}}
]);
pagerender = 'tool_lp/template_competencies_page';
pageregion = 'templatecompetenciespage';
} else if (localthis.itemtype == 'plan') {
requests = ajax.call([
- { methodname: 'core_competency_remove_competency_from_plan',
- args: { planid: localthis.itemid, competencyid: deleteid } },
- { methodname: 'tool_lp_data_for_plan_page',
- args: { planid: localthis.itemid } }
+ {methodname: 'core_competency_remove_competency_from_plan',
+ args: {planid: localthis.itemid, competencyid: deleteid}},
+ {methodname: 'tool_lp_data_for_plan_page',
+ args: {planid: localthis.itemid}}
]);
pagerender = 'tool_lp/plan_page';
pageregion = 'plan-page';
requests = ajax.call([{
methodname: 'core_competency_read_competency',
- args: { id: deleteid }
+ args: {id: deleteid}
}]);
requests[0].done(function(competency) {
str.get_strings([
- { key: 'confirm', component: 'moodle' },
- { key: message, component: 'tool_lp', param: competency.shortname },
- { key: 'confirm', component: 'moodle' },
- { key: 'cancel', component: 'moodle' }
+ {key: 'confirm', component: 'moodle'},
+ {key: message, component: 'tool_lp', param: competency.shortname},
+ {key: 'confirm', component: 'moodle'},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
var coursecompetencyid = $(e.target).data('id');
var ruleoutcome = $(e.target).val();
requests = ajax.call([
- { methodname: 'core_competency_set_course_competency_ruleoutcome',
- args: { coursecompetencyid: coursecompetencyid, ruleoutcome: ruleoutcome } },
- { methodname: 'tool_lp_data_for_course_competencies_page',
- args: { courseid: localthis.itemid } }
+ {methodname: 'core_competency_set_course_competency_ruleoutcome',
+ args: {coursecompetencyid: coursecompetencyid, ruleoutcome: ruleoutcome}},
+ {methodname: 'tool_lp_data_for_course_competencies_page',
+ args: {courseid: localthis.itemid}}
]);
requests[1].done(function(context) {
getAll: function() {
var self = this;
return Str.get_strings([
- { key: 'competencyoutcome_none', component: 'tool_lp' },
- { key: 'competencyoutcome_evidence', component: 'tool_lp' },
- { key: 'competencyoutcome_recommend', component: 'tool_lp' },
- { key: 'competencyoutcome_complete', component: 'tool_lp' },
+ {key: 'competencyoutcome_none', component: 'tool_lp'},
+ {key: 'competencyoutcome_evidence', component: 'tool_lp'},
+ {key: 'competencyoutcome_recommend', component: 'tool_lp'},
+ {key: 'competencyoutcome_complete', component: 'tool_lp'},
]).then(function(strings) {
var outcomes = {};
- outcomes[self.NONE] = { code: self.NONE, name: strings[0] };
- outcomes[self.EVIDENCE] = { code: self.EVIDENCE, name: strings[1] };
- outcomes[self.RECOMMEND] = { code: self.RECOMMEND, name: strings[2] };
- outcomes[self.COMPLETE] = { code: self.COMPLETE, name: strings[3] };
+ outcomes[self.NONE] = {code: self.NONE, name: strings[0]};
+ outcomes[self.EVIDENCE] = {code: self.EVIDENCE, name: strings[1]};
+ outcomes[self.RECOMMEND] = {code: self.RECOMMEND, name: strings[2]};
+ outcomes[self.COMPLETE] = {code: self.COMPLETE, name: strings[3]};
return outcomes;
});
},
children = this._tree.getChildren(this._competency.id),
context,
config = {
- base: { points: 2 },
+ base: {points: 2},
competencies: []
};
if (parent !== null && treeModel.hasRule(parent.id)) {
str.get_strings([
- { key: 'confirm', component: 'moodle' },
- { key: 'addingcompetencywillresetparentrule', component: 'tool_lp', param: parent.shortname },
- { key: 'yes', component: 'core' },
- { key: 'no', component: 'core' }
+ {key: 'confirm', component: 'moodle'},
+ {key: 'addingcompetencywillresetparentrule', component: 'tool_lp', param: parent.shortname},
+ {key: 'yes', component: 'core'},
+ {key: 'no', component: 'core'}
]).done(function(strings) {
notification.confirm(
strings[0],
var frameworkid = $('[data-region="filtercompetencies"]').data('frameworkid');
var requests = ajax.call([{
methodname: 'core_competency_set_parent_competency',
- args: { competencyid: moveSource, parentid: moveTarget }
+ args: {competencyid: moveSource, parentid: moveTarget}
}, {
methodname: 'tool_lp_data_for_competencies_manage_page',
- args: { competencyframeworkid: frameworkid,
- search: $('[data-region="filtercompetencies"] input').val() }
+ args: {competencyframeworkid: frameworkid,
+ search: $('[data-region="filtercompetencies"] input').val()}
}]);
requests[1].done(reloadPage).fail(notification.exception);
};
// Show confirm, and/or do the things.
if (showConfirm) {
str.get_strings([
- { key: 'confirm', component: 'moodle' },
- { key: confirmMessage, component: 'tool_lp' },
- { key: 'yes', component: 'moodle' },
- { key: 'no', component: 'moodle' }
+ {key: 'confirm', component: 'moodle'},
+ {key: confirmMessage, component: 'tool_lp'},
+ {key: 'yes', component: 'moodle'},
+ {key: 'no', component: 'moodle'}
]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
$.when.apply(null, requests).done(function(competencies, framework) {
// Expand the list of competencies into a tree.
- var i, competenciestree = [];
+ var i;
+ var competenciestree = [];
for (i = 0; i < competencies.length; i++) {
var onecompetency = competencies[i];
if (onecompetency.parentid == "0") {
}
str.get_strings([
- { key: 'movecompetency', component: 'tool_lp', param: competency.shortname },
- { key: 'move', component: 'tool_lp' },
- { key: 'cancel', component: 'moodle' }
+ {key: 'movecompetency', component: 'tool_lp', param: competency.shortname},
+ {key: 'move', component: 'tool_lp'},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
var context = {
var requests = ajax.call([{
methodname: 'tool_lp_data_for_competencies_manage_page',
- args: { competencyframeworkid: frameworkid,
- search: $('[data-region="filtercompetencies"] input').val() }
+ args: {competencyframeworkid: frameworkid,
+ search: $('[data-region="filtercompetencies"] input').val()}
}]);
requests[0].done(reloadPage).fail(notification.exception);
};
var competency = $('[data-region="competencyactions"]').data('competency');
var requests = ajax.call([{
methodname: 'core_competency_move_up_competency',
- args: { id: competency.id }
+ args: {id: competency.id}
}, {
methodname: 'tool_lp_data_for_competencies_manage_page',
- args: { competencyframeworkid: competency.competencyframeworkid,
- search: $('[data-region="filtercompetencies"] input').val() }
+ args: {competencyframeworkid: competency.competencyframeworkid,
+ search: $('[data-region="filtercompetencies"] input').val()}
}]);
requests[1].done(reloadPage).fail(notification.exception);
};
var competency = $('[data-region="competencyactions"]').data('competency');
var requests = ajax.call([{
methodname: 'core_competency_move_down_competency',
- args: { id: competency.id }
+ args: {id: competency.id}
}, {
methodname: 'tool_lp_data_for_competencies_manage_page',
- args: { competencyframeworkid: competency.competencyframeworkid,
- search: $('[data-region="filtercompetencies"] input').val() }
+ args: {competencyframeworkid: competency.competencyframeworkid,
+ search: $('[data-region="filtercompetencies"] input').val()}
}]);
requests[1].done(reloadPage).fail(notification.exception);
};
var requests = ajax.call([{
methodname: 'tool_lp_list_courses_using_competency',
- args: { id: competency.id }
+ args: {id: competency.id}
}]);
requests[0].done(function(courses) {
$.each(compIds, function(index, value) {
calls.push({
methodname: 'core_competency_add_related_competency',
- args: { competencyid: value, relatedcompetencyid: relatedTarget.id }
+ args: {competencyid: value, relatedcompetencyid: relatedTarget.id}
});
});
calls.push({
methodname: 'tool_lp_data_for_related_competencies_section',
- args: { competencyid: relatedTarget.id }
+ args: {competencyid: relatedTarget.id}
});
var promises = ajax.call(calls);
};
var promise = ajax.call([{
methodname: 'core_competency_update_competency',
- args: { competency: update }
+ args: {competency: update}
}]);
promise[0].then(function(result) {
if (result) {
var competency = $('[data-region="competencyactions"]').data('competency');
var requests = ajax.call([{
methodname: 'core_competency_delete_competency',
- args: { id: competency.id }
+ args: {id: competency.id}
}, {
methodname: 'tool_lp_data_for_competencies_manage_page',
- args: { competencyframeworkid: competency.competencyframeworkid,
- search: $('[data-region="filtercompetencies"] input').val() }
+ args: {competencyframeworkid: competency.competencyframeworkid,
+ search: $('[data-region="filtercompetencies"] input').val()}
}]);
requests[0].done(function(success) {
if (success === false) {
str.get_strings([
- { key: 'competencycannotbedeleted', component: 'tool_lp', param: competency.shortname },
- { key: 'cancel', component: 'moodle' }
+ {key: 'competencycannotbedeleted', component: 'tool_lp', param: competency.shortname},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
notification.alert(
null,
}
str.get_strings([
- { key: 'confirm', component: 'moodle' },
- { key: confirmMessage, component: 'tool_lp', param: competency.shortname },
- { key: 'delete', component: 'moodle' },
- { key: 'cancel', component: 'moodle' }
+ {key: 'confirm', component: 'moodle'},
+ {key: confirmMessage, component: 'tool_lp', param: competency.shortname},
+ {key: 'delete', component: 'moodle'},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
var relatedid = this.id.substr(11);
var competency = $('[data-region="competencyactions"]').data('competency');
var removeRelated = ajax.call([
- { methodname: 'core_competency_remove_related_competency',
- args: { relatedcompetencyid: relatedid, competencyid: competency.id } },
- { methodname: 'tool_lp_data_for_related_competencies_section',
- args: { competencyid: competency.id } }
+ {methodname: 'core_competency_remove_related_competency',
+ args: {relatedcompetencyid: relatedid, competencyid: competency.id}},
+ {methodname: 'tool_lp_data_for_related_competencies_section',
+ args: {competencyid: competency.id}}
]);
removeRelated[1].done(function(context) {
templates.render('tool_lp/related_competencies', context).done(function(html) {
$('[data-region="relatedcompetencies"]').replaceWith(html);
updatedRelatedCompetencies();
- }.bind(this)).fail(notification.exception);
- }.bind(this)).fail(notification.exception);
+ }).fail(notification.exception);
+ }).fail(notification.exception);
};
/**
selectedCompetencyId = competency.id;
ajax.call([{
methodname: 'core_competency_competency_viewed',
- args: { id: competency.id }
+ args: {id: competency.id}
}]);
}
};
}).done(function() {
ajax.call([{
methodname: 'tool_lp_data_for_related_competencies_section',
- args: { competencyid: competency.id },
+ args: {competencyid: competency.id},
done: function(context) {
return templates.render('tool_lp/related_competencies', context).done(function(html, js) {
$('[data-region="relatedcompetencies"]').replaceWith(html);
Competencydialogue.prototype.triggerCompetencyViewedEvent = function(competencyId) {
ajax.call([{
methodname: 'core_competency_competency_viewed',
- args: { id: competencyId }
+ args: {id: competencyId}
}]);
};
Competencydialogue.prototype.getCompetencyDataPromise = function(competencyid, options) {
var requests = ajax.call([
- { methodname: 'tool_lp_data_for_competency_summary',
- args: { competencyid: competencyid,
+ {methodname: 'tool_lp_data_for_competency_summary',
+ args: {competencyid: competencyid,
includerelated: options.includerelated || false,
includecourses: options.includecourses || false
}
// Instantiate the one instance and delegate event on the body.
instance = new Competencydialogue();
- $('body').delegate('[data-action="competency-dialogue"]', 'click', { compdialogue: instance },
+ $('body').delegate('[data-action="competency-dialogue"]', 'click', {compdialogue: instance},
instance.clickEventHandler.bind(instance));
}
};
if (valid) {
validIds.push(compId);
}
- }.bind(self));
+ });
self._selectedCompetencies = validIds;
} else {
self._find('[data-region="competencylinktree"] [data-action="add"]').removeAttr('disabled');
}
- }.bind(self));
+ });
// Add listener for framework change.
if (!self._singleFramework) {
self._find('[data-action="chooseframework"]').change(function(e) {
self._frameworkId = $(e.target).val();
self._loadCompetencies().then(self._refresh.bind(self));
- }.bind(self));
+ });
}
// Add listener for search.
return self._refresh().always(function() {
$(e.target).removeAttr('disabled');
});
- }.bind(self));
+ });
// Add listener for cancel.
self._find('[data-region="competencylinktree"] [data-action="cancel"]').click(function(e) {
e.preventDefault();
self.close();
- }.bind(self));
+ });
// Add listener for add.
self._find('[data-region="competencylinktree"] [data-action="add"]').click(function(e) {
}
if (self._multiSelect) {
- self._trigger('save', { competencyIds: self._selectedCompetencies });
+ self._trigger('save', {competencyIds: self._selectedCompetencies});
} else {
// We checked above that the array has at least one value.
- self._trigger('save', { competencyId: self._selectedCompetencies[0] });
+ self._trigger('save', {competencyId: self._selectedCompetencies[0]});
}
self.close();
- }.bind(self));
+ });
// The list of selected competencies will be modified while looping (because of the listeners above).
var currentItems = self._selectedCompetencies.slice(0);
tree.toggleItem(node);
tree.updateFocus(node);
}
- }.bind(self));
+ });
};
html,
self._afterRender.bind(self)
);
- }.bind(self));
- }.bind(self)).fail(Notification.exception);
+ });
+ }).fail(Notification.exception);
};
/**
var self = this;
return Ajax.call([
- { methodname: 'core_competency_search_competencies', args: {
+ {methodname: 'core_competency_search_competencies', args: {
searchtext: searchText,
competencyframeworkid: frameworkId
}}
}
// Expand the list of competencies into a tree.
- var i, tree = [], comp;
+ var i, comp;
+ var tree = [];
for (i = 0; i < competencies.length; i++) {
comp = competencies[i];
if (comp.parentid == "0") { // Loose check for now, because WS returns a string.
self._competencies = tree;
- }.bind(self)).fail(Notification.exception);
+ }).fail(Notification.exception);
};
/**
$.each(this._frameworks, function(i, f) {
if (f.id == fid) {
frm = f;
- return false;
+ return;
}
});
return frm;
if (self._singleFramework) {
promise = Ajax.call([
- { methodname: 'core_competency_read_competency_framework', args: {
+ {methodname: 'core_competency_read_competency_framework', args: {
id: this._frameworkId
}}
])[0].then(function(framework) {
});
} else {
promise = Ajax.call([
- { methodname: 'core_competency_list_competency_frameworks', args: {
+ {methodname: 'core_competency_list_competency_frameworks', args: {
sort: 'shortname',
- context: { contextid: self._pageContextId },
+ context: {contextid: self._pageContextId},
includes: self._pageContextIncludes,
onlyvisible: self._onlyVisible
}}
}
return self._loadCompetencies();
- }.bind(self));
+ });
};
/**
return self._render().then(function(html) {
self._find('[data-region="competencylinktree"]').replaceWith(html);
self._afterRender();
- }.bind(self));
+ });
};
/**
};
return Templates.render('tool_lp/competency_picker', context);
- }.bind(self));
+ });
};
/**
self._find('[data-action="chooseplan"]').change(function(e) {
self._planId = $(e.target).val();
self._loadCompetencies().then(self._refresh.bind(self));
- }.bind(self));
+ });
}
};
var self = this;
return Ajax.call([
- { methodname: 'core_competency_list_plan_competencies', args: {
+ {methodname: 'core_competency_list_plan_competencies', args: {
id: planId
}}
])[0].done(function(competencies) {
// Expand the list of competencies into a fake tree.
- var i, tree = [], comp;
+ var i, comp;
+ var tree = [];
for (i = 0; i < competencies.length; i++) {
comp = competencies[i].competency;
if (comp.shortname.toLowerCase().indexOf(searchText.toLowerCase()) < 0) {
$.each(this._plans, function(i, f) {
if (f.id == id) {
plan = f;
- return false;
+ return;
}
});
return plan;
if (self._singlePlan) {
promise = Ajax.call([
- { methodname: 'core_competency_read_plan', args: {
+ {methodname: 'core_competency_read_plan', args: {
id: this._planId
}}
])[0].then(function(plan) {
});
} else {
promise = Ajax.call([
- { methodname: 'core_competency_list_user_plans', args: {
+ {methodname: 'core_competency_list_user_plans', args: {
userid: self._userId
}}
])[0];
}
return self._loadCompetencies();
- }.bind(self));
+ });
};
/**
};
return Templates.render('tool_lp/competency_picker_user_plans', context);
- }.bind(self));
+ });
};
return /** @alias module:tool_lp/competencypicker_user_plans */ Picker;
$.each(this._rules, function(index, rule) {
if (rule.canConfig()) {
can = true;
- return false;
+ return;
}
});
return can;
RuleConfig.prototype.display = function() {
var self = this;
if (!self._competency) {
- return;
+ return false;
}
return self._render().then(function(html) {
return Str.get_string('competencyrule', 'tool_lp').then(function(title) {
$.each(this._rules, function(index, rule) {
if (rule.getType() == type) {
result = rule;
- return false;
+ return;
}
});
$.each(self._rulesModules, function(index, modInfo) {
if (modInfo.type == type) {
name = modInfo.name;
- return false;
+ return;
}
});
return name;
var currentValue = $(e.target).closest('a').data('pushratingstouserplans');
var context = {
courseid: courseid,
- settings: { pushratingstouserplans: currentValue }
+ settings: {pushratingstouserplans: currentValue}
};
e.preventDefault();
var newValue = this._find('input[name="pushratingstouserplans"]:checked').val();
var courseId = this._find('input[name="courseid"]').val();
- var settings = { pushratingstouserplans: newValue };
+ var settings = {pushratingstouserplans: newValue};
ajax.call([
- { methodname: 'core_competency_update_course_competency_settings',
- args: { courseid: courseId, settings: settings } }
+ {methodname: 'core_competency_update_course_competency_settings',
+ args: {courseid: courseId, settings: settings}}
])[0].done(function() {
this.refreshCourseCompetenciesPage();
}.bind(this)).fail(notification.exception);
var courseId = this._find('input[name="courseid"]').val();
ajax.call([
- { methodname: 'tool_lp_data_for_course_competencies_page',
- args: { courseid: courseId } }
+ {methodname: 'tool_lp_data_for_course_competencies_page',
+ args: {courseid: courseId}}
])[0].done(function(context) {
templates.render('tool_lp/course_competencies_page', context).done(function(html, js) {
$('[data-region="coursecompetenciespage"]').replaceWith(html);
// Here we are wrapping YUI. This allows us to start transitioning, but
// wait for a good alternative without having inconsistent UIs.
str.get_strings([
- { key: 'emptydragdropregion', component: 'moodle' },
- { key: 'movecontent', component: 'moodle' },
- { key: 'tocontent', component: 'moodle' },
+ {key: 'emptydragdropregion', component: 'moodle'},
+ {key: 'movecontent', component: 'moodle'},
+ {key: 'tocontent', component: 'moodle'},
]).done(function() {
Y.use('moodle-tool_lp-dragdrop-reorder', function() {
e.stopPropagation();
Str.get_strings([
- { key: 'confirm', component: 'moodle' },
- { key: 'areyousure', component: 'moodle' },
- { key: 'delete', component: 'moodle' },
- { key: 'cancel', component: 'moodle' }
+ {key: 'confirm', component: 'moodle'},
+ {key: 'areyousure', component: 'moodle'},
+ {key: 'delete', component: 'moodle'},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
Notification.confirm(
strings[0], // Confirm.
methodname: 'tool_lp_search_cohorts',
args: {
query: query,
- context: { contextid: contextid },
+ context: {contextid: contextid},
includes: includes
}
}]);
// We are chaining ajax requests here.
var requests = ajax.call([{
methodname: 'core_competency_duplicate_competency_framework',
- args: { id: frameworkid }
+ args: {id: frameworkid}
}, {
methodname: 'tool_lp_data_for_competency_frameworks_manage_page',
args: {
// We are chaining ajax requests here.
var requests = ajax.call([{
methodname: 'core_competency_delete_competency_framework',
- args: { id: frameworkid }
+ args: {id: frameworkid}
}, {
methodname: 'tool_lp_data_for_competency_frameworks_manage_page',
args: {
if (success === false) {
var req = ajax.call([{
methodname: 'core_competency_read_competency_framework',
- args: { id: frameworkid }
+ args: {id: frameworkid}
}]);
req[0].done(function(framework) {
str.get_strings([
- { key: 'frameworkcannotbedeleted', component: 'tool_lp', param: framework.shortname },
- { key: 'cancel', component: 'moodle' }
+ {key: 'frameworkcannotbedeleted', component: 'tool_lp', param: framework.shortname},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
notification.alert(
null,
var requests = ajax.call([{
methodname: 'core_competency_read_competency_framework',
- args: { id: frameworkid }
+ args: {id: frameworkid}
}]);
requests[0].done(function(framework) {
str.get_strings([
- { key: 'confirm', component: 'moodle' },
- { key: 'deletecompetencyframework', component: 'tool_lp', param: framework.shortname },
- { key: 'delete', component: 'moodle' },
- { key: 'cancel', component: 'moodle' }
+ {key: 'confirm', component: 'moodle'},
+ {key: 'deletecompetencyframework', component: 'tool_lp', param: framework.shortname},
+ {key: 'delete', component: 'moodle'},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
methodname: self._methodName,
args: args,
done: function(evidence) {
- self._trigger('competencyupdated', { args: args, evidence: evidence });
- }.bind(self),
+ self._trigger('competencyupdated', {args: args, evidence: evidence});
+ },
fail: notification.exception
}]);
- }.bind(self));
+ });
}).fail(notification.exception);
};
if (this.handlers) {
$.each(this.handlers, function(selector, handler) {
if (eventHandled) {
- return false;
+ return;
}
if (item.find(selector).length > 0) {
var callable = $.proxy(handler, anchor);
if (data.competencyId !== 0) {
ajax.call([
- { methodname: 'core_competency_read_competency', args: {
+ {methodname: 'core_competency_read_competency', args: {
id: data.competencyId
}}
])[0].done(function(competency) {
};
return Templates.render('tool_lp/competency_picker_competencyform', context);
- }.bind(self));
+ });
};
// On selected competency.
picker.on('save', function(e, data) {
self.setParent(data);
- }.bind(self));
+ });
picker.display();
});
.done(function(newhtml, newjs) {
$(self._region).replaceWith(newhtml);
templates.runTemplateJS(newjs);
- }.bind(self))
+ })
.fail(notification.exception);
};
// Apply all the promises, and refresh when the last one is resolved.
return $.when.apply($.when, ajax.call(calls))
.then(function() {
- self._renderView.call(self, arguments[arguments.length - 1]);
+ self._renderView(arguments[arguments.length - 1]);
})
.fail(notification.exception);
};
var self = this,
calls = [{
methodname: 'core_competency_delete_plan',
- args: { id: planData.id }
+ args: {id: planData.id}
}];
self._callAndRefresh(calls, planData);
};
requests = ajax.call([{
methodname: 'core_competency_read_plan',
- args: { id: planData.id }
+ args: {id: planData.id}
}]);
requests[0].done(function(plan) {
str.get_strings([
- { key: 'confirm', component: 'moodle' },
- { key: 'deleteplan', component: 'tool_lp', param: plan.name },
- { key: 'delete', component: 'moodle' },
- { key: 'cancel', component: 'moodle' }
+ {key: 'confirm', component: 'moodle'},
+ {key: 'deleteplan', component: 'tool_lp', param: plan.name},
+ {key: 'delete', component: 'moodle'},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[3], // Cancel.
function() {
self._doDelete(planData);
- }.bind(self)
+ }
);
}).fail(notification.exception);
}).fail(notification.exception);
var self = this,
calls = [{
methodname: 'core_competency_reopen_plan',
- args: { planid: planData.id}
+ args: {planid: planData.id}
}];
self._callAndRefresh(calls, planData);
};
var self = this,
requests = ajax.call([{
methodname: 'core_competency_read_plan',
- args: { id: planData.id }
+ args: {id: planData.id}
}]);
requests[0].done(function(plan) {
str.get_strings([
- { key: 'confirm', component: 'moodle' },
- { key: 'reopenplanconfirm', component: 'tool_lp', param: plan.name },
- { key: 'reopenplan', component: 'tool_lp' },
- { key: 'cancel', component: 'moodle' }
+ {key: 'confirm', component: 'moodle'},
+ {key: 'reopenplanconfirm', component: 'tool_lp', param: plan.name},
+ {key: 'reopenplan', component: 'tool_lp'},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[3], // Cancel.
function() {
self._doReopenPlan(planData);
- }.bind(self)
+ }
);
}).fail(notification.exception);
}).fail(notification.exception);
var self = this,
calls = [{
methodname: 'core_competency_complete_plan',
- args: { planid: planData.id}
+ args: {planid: planData.id}
}];
self._callAndRefresh(calls, planData);
};
var self = this,
requests = ajax.call([{
methodname: 'core_competency_read_plan',
- args: { id: planData.id }
+ args: {id: planData.id}
}]);
requests[0].done(function(plan) {
str.get_strings([
- { key: 'confirm', component: 'moodle' },
- { key: 'completeplanconfirm', component: 'tool_lp', param: plan.name },
- { key: 'completeplan', component: 'tool_lp' },
- { key: 'cancel', component: 'moodle' }
+ {key: 'confirm', component: 'moodle'},
+ {key: 'completeplanconfirm', component: 'tool_lp', param: plan.name},
+ {key: 'completeplan', component: 'tool_lp'},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[3], // Cancel.
function() {
self._doCompletePlan(planData);
- }.bind(self)
+ }
);
}).fail(notification.exception);
}).fail(notification.exception);
var self = this,
calls = [{
methodname: 'core_competency_unlink_plan_from_template',
- args: { planid: planData.id}
+ args: {planid: planData.id}
}];
self._callAndRefresh(calls, planData);
};
var self = this,
requests = ajax.call([{
methodname: 'core_competency_read_plan',
- args: { id: planData.id }
+ args: {id: planData.id}
}]);
requests[0].done(function(plan) {
str.get_strings([
- { key: 'confirm', component: 'moodle' },
- { key: 'unlinkplantemplateconfirm', component: 'tool_lp', param: plan.name },
- { key: 'unlinkplantemplate', component: 'tool_lp' },
- { key: 'cancel', component: 'moodle' }
+ {key: 'confirm', component: 'moodle'},
+ {key: 'unlinkplantemplateconfirm', component: 'tool_lp', param: plan.name},
+ {key: 'unlinkplantemplate', component: 'tool_lp'},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[3], // Cancel.
function() {
self._doUnlinkPlan(planData);
- }.bind(self)
+ }
);
}).fail(notification.exception);
}).fail(notification.exception);
var competencyid = $(e.target).data('id');
var requests = ajax.call([{
methodname: 'tool_lp_list_courses_using_competency',
- args: { id: competencyid }
+ args: {id: competencyid}
}]);
requests[0].done(function(courses) {
}.bind(this));
body.on('click', '[data-action="cancel"]', function() {
popup.close();
- }.bind(this));
+ });
};
/**
ScaleConfig.prototype.setScaleConfig = function() {
var body = $(this.popup.getContent());
// Get the data.
- var data = [{ scaleid: this.scaleid}];
+ var data = [{scaleid: this.scaleid}];
this.scalevalues.forEach(function(value) {
var scaledefault = 0;
var proficient = 0;
// We are chaining ajax requests here.
var requests = ajax.call([{
methodname: 'core_competency_delete_template',
- args: { id: templateid,
- deleteplans: deleteplans }
+ args: {id: templateid,
+ deleteplans: deleteplans}
}, {
methodname: 'tool_lp_data_for_templates_manage_page',
args: {
// We are chaining ajax requests here.
var requests = ajax.call([{
methodname: 'core_competency_duplicate_template',
- args: { id: templateid }
+ args: {id: templateid}
}, {
methodname: 'tool_lp_data_for_templates_manage_page',
args: {
var requests = ajax.call([{
methodname: 'core_competency_read_template',
- args: { id: templateid }
+ args: {id: templateid}
}, {
methodname: 'core_competency_template_has_related_data',
- args: { id: templateid }
+ args: {id: templateid}
}]);
requests[0].done(function(template) {
requests[1].done(function(templatehasrelateddata) {
if (templatehasrelateddata) {
str.get_strings([
- { key: 'deletetemplate', component: 'tool_lp', param: template.shortname },
- { key: 'deletetemplatewithplans', component: 'tool_lp' },
- { key: 'deleteplans', component: 'tool_lp' },
- { key: 'unlinkplanstemplate', component: 'tool_lp' },
- { key: 'confirm', component: 'moodle' },
- { key: 'cancel', component: 'moodle' }
+ {key: 'deletetemplate', component: 'tool_lp', param: template.shortname},
+ {key: 'deletetemplatewithplans', component: 'tool_lp'},
+ {key: 'deleteplans', component: 'tool_lp'},
+ {key: 'unlinkplanstemplate', component: 'tool_lp'},
+ {key: 'confirm', component: 'moodle'},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
var actions = [{'text': strings[2], 'value': 'delete'},
{'text': strings[3], 'value': 'unlink'}];
}).fail(notification.exception);
} else {
str.get_strings([
- { key: 'confirm', component: 'moodle' },
- { key: 'deletetemplate', component: 'tool_lp', param: template.shortname },
- { key: 'delete', component: 'moodle' },
- { key: 'cancel', component: 'moodle' }
+ {key: 'confirm', component: 'moodle'},
+ {key: 'deletetemplate', component: 'tool_lp', param: template.shortname},
+ {key: 'delete', component: 'moodle'},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
if (!this.multiSelect) {
allSelected = allSelected.first();
}
- this.treeRoot.trigger('selectionchanged', { selected: allSelected });
+ this.treeRoot.trigger('selectionchanged', {selected: allSelected});
};
/**
* @param {Event} e The event.
* @return {Boolean}
*/
+ // This function should be simplified. In the meantime..
+ // eslint-disable-next-line complexity
Tree.prototype.handleKeyDown = function(item, e) {
var currentIndex = this.visibleItems.index(item);
var newItem = null;
if (this._planId) {
this._methodName = 'tool_lp_data_for_user_competency_summary_in_plan';
- this._args = { competencyid: this._competencyId, planid: this._planId };
+ this._args = {competencyid: this._competencyId, planid: this._planId};
this._templateName = 'tool_lp/user_competency_summary_in_plan';
} else if (this._courseId) {
this._methodName = 'tool_lp_data_for_user_competency_summary_in_course';
- this._args = { userid: this._userId, competencyid: this._competencyId, courseid: this._courseId };
+ this._args = {userid: this._userId, competencyid: this._competencyId, courseid: this._courseId};
this._templateName = 'tool_lp/user_competency_summary_in_course';
} else {
this._methodName = 'tool_lp_data_for_user_competency_summary';
- this._args = { userid: this._userId, competencyid: this._competencyId };
+ this._args = {userid: this._userId, competencyid: this._competencyId};
this._templateName = 'tool_lp/user_competency_summary';
}
};
var requests = ajax.call([{
methodname: 'tool_lp_data_for_user_competency_summary_in_plan',
- args: { competencyid: competencyId, planid: planId },
+ args: {competencyid: competencyId, planid: planId},
done: this._contextLoaded.bind(this),
fail: notification.exception
}]);
ajax.call([{
methodname: 'tool_lp_data_for_plan_page',
- args: { planid: planId},
+ args: {planid: planId},
done: this._pageContextLoaded.bind(this),
fail: notification.exception
}]);
templates.render(self._template, context)
.done(function(newhtml, newjs) {
templates.replaceNode($(self._region), newhtml, newjs);
- }.bind(self))
+ })
.fail(notification.exception);
};
// Apply all the promises, and refresh when the last one is resolved.
return $.when.apply($.when, ajax.call(calls))
.then(function() {
- self._renderView.call(self, arguments[arguments.length - 1]);
+ self._renderView(arguments[arguments.length - 1]);
})
.fail(notification.exception);
};
var self = this,
calls = [{
methodname: 'core_competency_delete_user_evidence',
- args: { id: evidenceData.id }
+ args: {id: evidenceData.id}
}];
self._callAndRefresh(calls, evidenceData);
};
requests = ajax.call([{
methodname: 'core_competency_read_user_evidence',
- args: { id: evidenceData.id }
+ args: {id: evidenceData.id}
}]);
requests[0].done(function(evidence) {
str.get_strings([
- { key: 'confirm', component: 'moodle' },
- { key: 'deleteuserevidence', component: 'tool_lp', param: evidence.name },
- { key: 'delete', component: 'moodle' },
- { key: 'cancel', component: 'moodle' }
+ {key: 'confirm', component: 'moodle'},
+ {key: 'deleteuserevidence', component: 'tool_lp', param: evidence.name},
+ {key: 'delete', component: 'moodle'},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[3], // Cancel.
function() {
self._doDelete(evidenceData);
- }.bind(self)
+ }
);
}).fail(notification.exception);
}).fail(notification.exception);
picker.on('save', function(e, data) {
var competencyIds = data.competencyIds;
self._doCreateUserEvidenceCompetency(evidenceData, competencyIds, data.requestReview);
- }.bind(self));
+ });
picker.display();
};
var self = this,
calls = [{
methodname: 'core_competency_request_review_of_user_evidence_linked_competencies',
- args: { id: evidenceData.id }
+ args: {id: evidenceData.id}
}];
self._callAndRefresh(calls, evidenceData);
};
requests = ajax.call([{
methodname: 'core_competency_read_user_evidence',
- args: { id: evidenceData.id }
+ args: {id: evidenceData.id}
}]);
requests[0].done(function(evidence) {
str.get_strings([
- { key: 'confirm', component: 'moodle' },
- { key: 'sendallcompetenciestoreview', component: 'tool_lp', param: evidence.name },
- { key: 'confirm', component: 'moodle' },
- { key: 'cancel', component: 'moodle' }
+ {key: 'confirm', component: 'moodle'},
+ {key: 'sendallcompetenciestoreview', component: 'tool_lp', param: evidence.name},
+ {key: 'confirm', component: 'moodle'},
+ {key: 'cancel', component: 'moodle'}
]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[3], // Cancel.
function() {
self._doReviewUserEvidenceCompetencies(evidenceData);
- }.bind(self)
+ }
);
}).fail(notification.exception);
}).fail(notification.exception);
* @param \stdClass $course The course record.
*/
function tool_recyclebin_pre_course_delete($course) {
+ // It is possible that the course deletion which triggered this hook
+ // was from an in progress course restore. In that case we do not want
+ // it in the recycle bin.
+ if (isset($course->deletesource) && $course->deletesource == 'restore') {
+ return;
+ }
// Delete all the items in the course recycle bin, regardless if it enabled or not.
// It may have been enabled, then disabled later on, so may still have content.
$coursebin = new \tool_recyclebin\course_bin($course->id);
*/
protected $course;
+ /**
+ * @var stdClass $coursebeingrestored
+ */
+ protected $coursebeingrestored;
+
/**
* Setup for each test.
*/
public function test_pre_course_delete_hook() {
global $DB;
+ // This simulates a temporary course being cleaned up by a course restore.
+ $this->coursebeingrestored = $this->getDataGenerator()->create_course();
+ $this->coursebeingrestored->deletesource = 'restore';
+
// Should have nothing in the recycle bin.
$this->assertEquals(0, $DB->count_records('tool_recyclebin_category'));
delete_course($this->course, false);
+ // This should not be added to the recycle bin.
+ delete_course($this->coursebeingrestored, false);
// Check the course is now in the recycle bin.
$this->assertEquals(1, $DB->count_records('tool_recyclebin_category'));
* @param {String[]} templateList List of template ids.
*/
var reloadListTemplate = function(templateList) {
- templates.render('tool_templatelibrary/search_results', { templates: templateList })
+ templates.render('tool_templatelibrary/search_results', {templates: templateList})
.done(function(result, js) {
templates.replaceNode($('[data-region="searchresults"]'), result, js);
}).fail(notification.exception);
// Trigger the search.
ajax.call([
- { methodname: 'tool_templatelibrary_list_templates',
- args: { component: componentStr, search: searchStr },
+ {methodname: 'tool_templatelibrary_list_templates',
+ args: {component: componentStr, search: searchStr},
done: reloadListTemplate,
- fail: notification.exception }
+ fail: notification.exception}
], true, false);
};
* Delete course which is created by restore process
*/
public function cleanup() {
+ global $DB;
$courseid = $this->controller->get_courseid();
- if ($this->is_temporary_course_created($courseid)) {
- delete_course($courseid, false);
+ if ($this->is_temporary_course_created($courseid) && $course = $DB->get_record('course', array('id' => $courseid))) {
+ $course->deletesource = 'restore';
+ delete_course($course, false);
}
}
$this->title = get_string('pluginname', 'block_activity_results');
}
+ /**
+ * Allow the block to have a configuration page
+ *
+ * @return boolean
+ */
+ public function has_config() {
+ return true;
+ }
+
/**
* Core function, specifies where the block can be used.
* @return array
protected function specific_definition($mform) {
global $DB;
+ // Load defaults.
+ $blockconfig = get_config('block_activity_results');
+
// Fields for editing activity_results block title and contents.
$mform->addElement('header', 'configheader', get_string('blocksettings', 'block'));
$mform->addElement('text', 'config_showbest',
get_string('config_show_best', 'block_activity_results'), array('size' => 3));
- $mform->setDefault('config_showbest', 3);
+ $mform->setDefault('config_showbest', $blockconfig->config_showbest);
$mform->setType('config_showbest', PARAM_INT);
+ if ($blockconfig->config_showbest_locked) {
+ $mform->freeze('config_showbest');
+ }
$mform->addElement('text', 'config_showworst',
get_string('config_show_worst', 'block_activity_results'), array('size' => 3));
- $mform->setDefault('config_showworst', 0);
+ $mform->setDefault('config_showworst', $blockconfig->config_showworst);
$mform->setType('config_showworst', PARAM_INT);
+ if ($blockconfig->config_showworst_locked) {
+ $mform->freeze('config_showworst');
+ }
$mform->addElement('selectyesno', 'config_usegroups', get_string('config_use_groups', 'block_activity_results'));
+ $mform->setDefault('config_usegroups', $blockconfig->config_usegroups);
+ if ($blockconfig->config_usegroups_locked) {
+ $mform->freeze('config_usegroups');
+ }
$nameoptions = array(
B_ACTIVITYRESULTS_NAME_FORMAT_FULL => get_string('config_names_full', 'block_activity_results'),
);
$mform->addElement('select', 'config_nameformat',
get_string('config_name_format', 'block_activity_results'), $nameoptions);
- $mform->setDefault('config_nameformat', B_ACTIVITYRESULTS_NAME_FORMAT_FULL);
+ $mform->setDefault('config_nameformat', $blockconfig->config_nameformat);
+ if ($blockconfig->config_nameformat_locked) {
+ $mform->freeze('config_nameformat');
+ }
$gradeeoptions = array(
B_ACTIVITYRESULTS_GRADE_FORMAT_PCT => get_string('config_format_percentage', 'block_activity_results'),
);
$mform->addElement('select', 'config_gradeformat',
get_string('config_grade_format', 'block_activity_results'), $gradeeoptions);
- $mform->setDefault('config_gradeformat', B_ACTIVITYRESULTS_GRADE_FORMAT_PCT);
+ $mform->setDefault('config_gradeformat', $blockconfig->config_gradeformat);
+ if ($blockconfig->config_gradeformat_locked) {
+ $mform->freeze('config_gradeformat');
+ }
$options = array();
for ($i = 0; $i <= 5; $i++) {
}
$mform->addElement('select', 'config_decimalpoints', get_string('config_decimalplaces', 'block_activity_results'),
$options);
- $mform->setDefault('config_decimalpoints', 2);
+ $mform->setDefault('config_decimalpoints', $blockconfig->config_decimalpoints);
$mform->setType('config_decimalpoints', PARAM_INT);
+ if ($blockconfig->config_decimalpoints_locked) {
+ $mform->freeze('config_decimalpoints');
+ }
}
}
\ No newline at end of file
$string['config_show_worst'] = 'How many of the lowest grades should be shown (0 to disable)?';
$string['configuredtoshownothing'] = 'This block\'s configuration currently does not allow it to show any results.';
$string['config_use_groups'] = 'Show groups instead of students (only if the activity supports groups)?';
+$string['defaulthighestgrades'] = 'Default highest grades shown';
+$string['defaulthighestgrades_desc'] = 'How many of the highest grades should be shown by default?';
+$string['defaultlowestgrades'] = 'Default lowest grades shown';
+$string['defaultlowestgrades_desc'] = 'How many of the lowest grades should be shown by default?';
+$string['defaultshowgroups'] = 'Default show groups';
+$string['defaultnameoptions'] = 'Privacy of results';
+$string['defaultnameoptions_desc'] = 'How should the students be identified by default?';
+$string['defaultshowgroups_desc'] = 'Show groups instead of students by default (only if the activity supports groups)';
+$string['defaultgradedisplay'] = 'Display grades as';
+$string['defaultgradedisplay_desc'] = 'How should the grades be displayed by default?';
+$string['defaultdecimalplaces'] = 'Decimal places';
+$string['defaultdecimalplaces_desc'] = 'Number of decimal places to display by default';
$string['error_emptyactivityid'] = 'Please configure this block and select which activity it should display results from.';
$string['error_emptyactivityrecord'] = 'Error: the selected activity does not exist in the database.';
$string['error_nogroupsexist'] = 'Error: the block is set to display grades in group mode, but there are no groups defined.';
--- /dev/null
+<?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/>.
+
+/**
+ * Defines the form for editing activity results block instances.
+ *
+ * @package block_activity_results
+ * @copyright 2016 Stephen Bourget
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die;
+
+if ($ADMIN->fulltree) {
+
+ // Default high scores.
+ $setting = new admin_setting_configtext('block_activity_results/config_showbest',
+ new lang_string('defaulthighestgrades', 'block_activity_results'),
+ new lang_string('defaulthighestgrades_desc', 'block_activity_results'), 3, PARAM_INT);
+ $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
+ $settings->add($setting);
+
+ // Default low scores.
+ $setting = new admin_setting_configtext('block_activity_results/config_showworst',
+ new lang_string('defaultlowestgrades', 'block_activity_results'),
+ new lang_string('defaultlowestgrades_desc', 'block_activity_results'), 0, PARAM_INT);
+ $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
+ $settings->add($setting);
+
+ // Default group display.
+ $yesno = array(0 => get_string('no'), 1 => get_string('yes'));
+ $setting = new admin_setting_configselect('block_activity_results/config_usegroups',
+ new lang_string('defaultshowgroups', 'block_activity_results'),
+ new lang_string('defaultshowgroups_desc', 'block_activity_results'), 0, $yesno);
+ $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
+ $settings->add($setting);
+
+ // Default privacy settings.
+ $nameoptions = array(
+ B_ACTIVITYRESULTS_NAME_FORMAT_FULL => get_string('config_names_full', 'block_activity_results'),
+ B_ACTIVITYRESULTS_NAME_FORMAT_ID => get_string('config_names_id', 'block_activity_results'),
+ B_ACTIVITYRESULTS_NAME_FORMAT_ANON => get_string('config_names_anon', 'block_activity_results')
+ );
+ $setting = new admin_setting_configselect('block_activity_results/config_nameformat',
+ new lang_string('defaultnameoptions', 'block_activity_results'),
+ new lang_string('defaultnameoptions_desc', 'block_activity_results'), B_ACTIVITYRESULTS_NAME_FORMAT_FULL, $nameoptions);
+ $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
+ $settings->add($setting);
+
+ // Default grade display settings.
+ $gradeoptions = array(
+ B_ACTIVITYRESULTS_GRADE_FORMAT_PCT => get_string('config_format_percentage', 'block_activity_results'),
+ B_ACTIVITYRESULTS_GRADE_FORMAT_FRA => get_string('config_format_fraction', 'block_activity_results'),
+ B_ACTIVITYRESULTS_GRADE_FORMAT_ABS => get_string('config_format_absolute', 'block_activity_results')
+ );
+ $setting = new admin_setting_configselect('block_activity_results/config_gradeformat',
+ new lang_string('defaultgradedisplay', 'block_activity_results'),
+ new lang_string('defaultgradedisplay_desc', 'block_activity_results'), B_ACTIVITYRESULTS_GRADE_FORMAT_PCT, $gradeoptions);
+ $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
+ $settings->add($setting);
+
+ // Default decimal places.
+ $places = array();
+ for ($i = 0; $i <= 5; $i++) {
+ $places[$i] = $i;
+ }
+ $setting = new admin_setting_configselect('block_activity_results/config_decimalpoints',
+ new lang_string('defaultdecimalplaces', 'block_activity_results'),
+ new lang_string('defaultdecimalplaces_desc', 'block_activity_results'), 2, $places);
+ $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
+ $settings->add($setting);
+
+}
--- /dev/null
+@block @block_activity_results
+Feature: The activity results block can have administrator set defaults
+ In order to be customize the activity results block
+ As an admin
+ I need can assign some site wide defaults
+
+ Background:
+ Given the following "users" exist:
+ | username | firstname | lastname | email | idnumber |
+ | teacher1 | Teacher | 1 | teacher1@example.com | T1 |
+ | student1 | Student | 1 | student1@example.com | S1 |
+ And the following "courses" exist:
+ | fullname | shortname | category |
+ | Course 1 | C1 | 0 |
+ And the following "course enrolments" exist:
+ | user | course | role |
+ | teacher1 | C1 | editingteacher |
+ | student1 | C1 | student |
+
+ Scenario: Assign some site-wide defaults to the block.
+ Given the following config values are set as admin:
+ | config_showbest | 0 | block_activity_results |
+ | config_showworst | 0 | block_activity_results |
+ | config_gradeformat | 2 | block_activity_results |
+ | config_nameformat | 2 | block_activity_results |
+ And I log in as "teacher1"
+ And I follow "Course 1"
+ And I turn editing mode on
+ And I add a "Assignment" to section "1" and I fill the form with:
+ | Assignment name | Test assignment |
+ | Description | Offline text |
+ | assignsubmission_file_enabled | 0 |
+ And I follow "Course 1"
+ And I add the "Activity results" block
+ When I configure the "Activity results" block
+ And the following fields match these values:
+ | id_config_showbest | 0 |
+ | id_config_showworst | 0 |
+ | id_config_gradeformat | Fractions |
+ | id_config_nameformat | Display only ID numbers |
+ And I press "Save changes"
+ Then I should see "This block's configuration currently does not allow it to show any results." in the "Activity results" "block"
+
+ Scenario: Assign some site-wide defaults to the block and lock them.
+ Given the following config values are set as admin:
+ | config_showbest | 0 | block_activity_results |
+ | config_showbest_locked | 1 | block_activity_results |
+ | config_showworst | 0 | block_activity_results |
+ | config_showworst_locked | 1 | block_activity_results |
+ And I log in as "teacher1"
+ And I follow "Course 1"
+ And I turn editing mode on
+ And I add a "Assignment" to section "1" and I fill the form with:
+ | Assignment name | Test assignment |
+ | Description | Offline text |
+ | assignsubmission_file_enabled | 0 |
+ And I follow "Course 1"
+ And I add the "Activity results" block
+ When I configure the "Activity results" block
+ And the following fields match these values:
+ | id_config_showbest | 0 |
+ | id_config_showworst | 0 |
+ And the "id_config_showbest" "field" should be readonly
+ And the "id_config_showworst" "field" should be readonly
+ And I press "Save changes"
+ Then I should see "This block's configuration currently does not allow it to show any results." in the "Activity results" "block"
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2016052300; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version = 2016070400; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2016051900; // Requires this Moodle version.
$plugin->component = 'block_activity_results'; // Full name of the plugin (used for diagnostics).
\ No newline at end of file
continue;
}
- $id = $item->id ? $item->id : uniqid();
+ $id = $item->id ? $item->id : html_writer::random_id();
$content = $item->get_content();
$title = $item->get_title();
$ulattr = ['id' => $id . '_group', 'role' => 'group'];
}
$content = $this->output->render($item);
- $id = $item->id ? $item->id : uniqid();
+ $id = $item->id ? $item->id : html_writer::random_id();
$ulattr = ['id' => $id . '_group', 'role' => 'group'];
$liattr = ['class' => [$item->get_css_type(), 'depth_'.$depth], 'tabindex' => '-1'];
$pattr = ['class' => ['tree_item'], 'role' => 'treeitem'];
if ($this->properties->eventtype != 'user' && $this->properties->eventtype != 'course'
&& $this->properties->eventtype != 'site' && $this->properties->eventtype != 'group') {
// We don't have a context here, do a normal format_text.
- return array(format_text($this->properties->description, $this->properties->format), $this->properties->format);
+ return external_format_text($this->properties->description, $this->properties->format, $this->editorcontext->id);
}
}
$wheresql = array();
+ $dbparams = array();
foreach ($params as $var=>$value) {
if (!in_array($var, $instance->required_fields) and !array_key_exists($var, $instance->optional_fields)) {
continue;
$wheresql[] = " $var IS NULL ";
} else {
$wheresql[] = " $var = ? ";
- $params[] = $value;
+ $dbparams[] = $value;
}
}
}
global $DB;
- if ($datas = $DB->get_records_select($table, $wheresql, $params)) {
+ if ($datas = $DB->get_records_select($table, $wheresql, $dbparams)) {
$result = array();
foreach($datas as $data) {
*/
public function get_recordset_by_timestamp($modifiedfrom = 0) {
global $DB;
- return $DB->get_recordset_select('course', 'timemodified >= ?', array($modifiedfrom));
+ return $DB->get_recordset_select('course', 'timemodified >= ?', array($modifiedfrom), 'timemodified ASC');
}
/**
require_once($CFG->libdir.'/completionlib.php');
$id = optional_param('id', 0, PARAM_INT);
- $name = optional_param('name', '', PARAM_RAW);
+ $name = optional_param('name', '', PARAM_TEXT);
$edit = optional_param('edit', -1, PARAM_BOOL);
$hide = optional_param('hide', 0, PARAM_INT);
$show = optional_param('show', 0, PARAM_INT);
+/* eslint-disable no-unused-vars */
/**
* Drag and Drop for course sections and course modules.
*
+/* global Item */
+
/**
* A managed category.
*
+/* global DragDrop, Category, Course */
+
/**
* Provides drop down menus for list of action links.
*
+/* global Item */
+
/**
* A managed course.
*
+/* global Console */
+
/**
* Drag and Drop handler
*
+/* global TOOLBOX, BODY, SELECTOR, INDENTLIMITS */
+
/**
* Resource and activity toolbox class.
*
+/* global SELECTOR, TOOLBOX */
+
/**
* Resource and activity toolbox class.
*
+/* eslint-disable no-unused-vars */
/**
* Resource and activity toolbox class.
*
}
}
);
-
.enrolpanel .container .header {border-bottom:1px solid #999;}
.enrolpanel .container .header h2 {font-size:90%;text-align:center;margin:5px;}
.enrolpanel .container .header .close {width:25px;height:15px;position:absolute;top:5px;right:1em;cursor:pointer;background:url("sprite.png") no-repeat scroll 0 0 transparent;}
-.enrolpanel .container .content {}
.enrolpanel .container .content input {margin:5px;font-size:10px;}
.enrolpanel.roleassign.visible .container {width:auto;}
}
if ($hasinline || $hasdisplay || $hasextra) {
$PAGE->requires->yui_module('moodle-filter_mathjaxloader-loader', 'M.filter_mathjaxloader.typeset');
- return '<span class="nolink"><span class="filter_mathjaxloader_equation">' . $text . '</span></span>';
+ if ($hasextra) {
+ // If custom dilimeters are used, wrap whole text to prevent autolinking.
+ $text = '<span class="nolink">' + $text + '</span>';
+ } else {
+ if ($hasinline) {
+ // If the default inline TeX delimiters \( \) are present, wrap each pair in nolink.
+ $text = preg_replace('/\\\\\\([\S\s]*?\\\\\\)/u',
+ '<span class="nolink">\0</span>', $text);
+ }
+ if ($hasdisplay) {
+ // If default display TeX is used, wrap $$ $$ or \[ \] individually.
+ $text = preg_replace('/\$\$[\S\s]*?\$\$|\\\\\\[[\S\s]*?\\\\\\]/u',
+ '<span class="nolink">\0</span>', $text);
+ }
+ }
+ return '<span class="filter_mathjaxloader_equation">' . $text . '</span>';
}
return $text;
}
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
-$PAGE->requires->js_call_amd('grades/edittree_index', 'enhance');
+$PAGE->requires->js_call_amd('core_grades/edittree_index', 'enhance');
/// return tracking object
$gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'tree', 'courseid'=>$courseid));
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+/* global SELECTORS */
/**
* @module moodle-gradereport_grader-gradereporttable
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+/* eslint-disable no-unused-vars */
/**
* Grader Report Functionality.
$string['availablelangs'] = 'Llista d\'idiomes disponibles';
$string['chooselanguagehead'] = 'Trieu un idioma';
$string['chooselanguagesub'] = 'Trieu un idioma per a la instal·lació. S\'utilitzarà també com a idioma per defecte del lloc, tot i que després podeu canviar-lo.';
-$string['clialreadyconfigured'] = 'El fitxer config.php ja existeix, feu servir dmin/cli/install_database.php si voleu instal·lar aquest lloc web.';
+$string['clialreadyconfigured'] = 'El fitxer config.php ja existeix, feu servir admin/cli/install_database.php si voleu instal·lar el Moodle en aquest lloc web.';
$string['clialreadyinstalled'] = 'El fitxer de configuració config.php ja existeix. Feu servir admin/cli/upgrade.php si voleu actualitzar Moodle per a aquest lloc web.';
$string['cliinstallheader'] = 'Programa d\'instal·lació de lÃnia d\'ordres de Moodle {$a}';
$string['databasehost'] = 'Servidor de base de dades:';
$string['pathsrodataroot'] = 'No es pot escriure en el directori dataroot.';
$string['pathsroparentdataroot'] = 'No es pot escriure en el directori pare ({$a->parent}). L\'instal·lador no pot crear el directori ({$a->dataroot}).';
$string['pathssubadmindir'] = 'Alguns serveis d\'allotjament web (pocs) utilitzen /admin com a URL especial perquè accediu a un tauler de control o quelcom semblant. Malauradament, això entra en conflicte amb la ubicació està ndard de les pà gines d\'administració de Moodle. Podeu arreglar aquest problema canviant el nom del directori d\'administració de Moodle en la vostra instal·lació i posant el nou nom aquÃ. Per exemple: <em>moodleadmin</em>. Això arreglarà els enllaços d\'administració de Moodle.';
-$string['pathssubdataroot'] = 'Necessiteu un espai on Moodle pugui desar els fitxers penjats. Aquest directori hauria de tenir permisos de lectura I ESCRIPTURA per a l\'usuari del servidor web (normalment \'nobody\' o \'apache\'), però no cal que sigui accessible directament via web. L\'instal·lador provarà de crear-lo si no existeix.';
+$string['pathssubdataroot'] = '<p>Directori on el Moodle emmagatzemarà els materials pujats pels usuaris.</p>
+<p>Aquest directori hauria de tenir permisos de lectura i escriptura per a l\'usuari del servidor web (normalment \'www-data\', \'nobody\', or \'apache\').</p>
+<p>No ha de ser accessible directament via web.</p>
+<p>L\'instal·lador provarà de crear-lo si no existeix.</p>';
$string['pathssubdirroot'] = 'Camà complet del directori d\'instal·lació de Moodle.';
$string['pathssubwwwroot'] = '<p>L\'adreça web completa on s\'accedirà a Moodle; per exemple, l\'adreça que els usuaris introduiran a la barra d\'adreces del navegador per accedir a Moodle.</p> <p> No és possible accedir a Moodle utilitzant diferents adreces. Si el vostre lloc és accessible a través de diferents adreces, trieu-ne la més fà cil i configureu una redirecció permanent per a cadascuna de les altres adreces.</p> <p>
Si el vostre lloc és accessible tant des d\'Internet com des d\'una xarxa interna (anomenada de vegades intranet), utilitzeu l\'adreça pública aquÃ.</p> <p>Si l\'adreça actual no és correcta, canvieu l\'URL a la barra d\'adreces del navegador i reinicieu la instal·lació.';
$string['authsettings'] = 'Manage authentication';
$string['autolang'] = 'Language autodetect';
$string['autologinguests'] = 'Auto-login guests';
-$string['availablesearchareas'] = 'Available areas for search';
+$string['searchareas'] = 'Search areas';
$string['availableto'] = 'Available to';
$string['availablelicenses'] = 'Available licences';
$string['backgroundcolour'] = 'Transparent colour';
$string['includemoduleuserdata'] = 'Include module user data';
$string['incompatibleblocks'] = 'Incompatible blocks';
$string['indexdata'] = 'Index data';
+$string['indexinginfo'] = 'The recommended way to index your site\'s contents is using "Global search indexing" scheduled task which runs automatically by Cron.';
$string['installhijacked'] = 'Installation must be finished from the original IP address, sorry.';
$string['installsessionerror'] = 'Can not initialise PHP session, please verify that your browser accepts cookies.';
$string['intlrecommended'] = 'Intl extension is used to improve internationalization support, such as locale aware sorting.';
$string['navsortmycoursessort'] = 'Sort my courses';
$string['navsortmycoursessort_help'] = 'This determines whether courses are listed under My courses according to the sort order (i.e. the order set in Site administration > Courses > Manage courses and categories) or alphabetically by course setting.';
$string['neverdeleteruns'] = 'Never delete runs';
+$string['newestdocindexed'] = 'Newest document indexed';
$string['nobookmarksforuser'] = 'You do not have any bookmarks.';
$string['nodatabase'] = 'No database';
$string['nohttpsformobilewarning'] = 'It is recommended to enable HTTPS with a valid certificate. The Moodle app will always try to use a secured connection first.';
$string['save'] = 'Save';
$string['savechanges'] = 'Save changes';
$string['search'] = 'Search';
+$string['searchalldeleted'] = 'All indexed contents have been deleted';
+$string['searchareaenabled'] = 'Search area enabled';
+$string['searchareadisabled'] = 'Search area disabled';
+$string['searchdeleteindex'] = 'Delete all indexed contents';
$string['searchengine'] = 'Search engine';
+$string['searchindexactions'] = 'Index actions';
+$string['searchindexdeleted'] = 'Index deleted';
+$string['searchindexupdated'] = 'Search engine contents have been updated';
$string['searchinsettings'] = 'Search in settings';
+$string['searchlastrun'] = 'Last run (time, # docs, # records, # ignores)';
+$string['searchnotavailable'] = 'Search is not available';
+$string['searchreindexed'] = 'All site\'s contents have been reindexed';
+$string['searchreindexindex'] = 'Reindex all site contents';
$string['searchresults'] = 'Search results';
$string['searchsetupinfo'] = 'Search setup';
+$string['searchupdateindex'] = 'Update indexed contents';
$string['sectionerror'] = 'Section error!';
$string['secureforms'] = 'Use additional form security';
$string['security'] = 'Security';
$DB->delete_records('event', array('modulename' => $pluginname));
// Delete scheduled tasks.
- $DB->delete_records('task_scheduled', array('component' => $pluginname));
+ $DB->delete_records('task_scheduled', array('component' => $component));
// Delete Inbound Message datakeys.
$DB->delete_records_select('messageinbound_datakeys',
- 'handler IN (SELECT id FROM {messageinbound_handlers} WHERE component = ?)', array($pluginname));
+ 'handler IN (SELECT id FROM {messageinbound_handlers} WHERE component = ?)', array($component));
// Delete Inbound Message handlers.
- $DB->delete_records('messageinbound_handlers', array('component' => $pluginname));
+ $DB->delete_records('messageinbound_handlers', array('component' => $component));
// delete all the logs
$DB->delete_records('log', array('module' => $pluginname));
// Available areas.
$row = array();
- $url = new moodle_url('/admin/settings.php?section=manageglobalsearch#admin-searchengine');
+ $url = new moodle_url('/admin/searchareas.php');
$row[0] = '2. ' . html_writer::tag('a', get_string('enablesearchareas', 'admin'),
array('href' => $url));
// Indexed data.
$row = array();
- $url = new moodle_url('/report/search/index.php#searchindexform');
+ $url = new moodle_url('/admin/searchareas.php');
$row[0] = '4. ' . html_writer::tag('a', get_string('indexdata', 'admin'), array('href' => $url));
if ($anyindexed) {
$status = html_writer::tag('span', get_string('yes'), array('class' => 'statusok'));
var yuiNodes = new Y.NodeList(nodes.get());
// And again for YUI.
- Y.fire(M.core.event.FILTER_CONTENT_UPDATED, { nodes: yuiNodes });
+ Y.fire(M.core.event.FILTER_CONTENT_UPDATED, {nodes: yuiNodes});
});
},
}
originalSelect.children('option').each(function(index, ele) {
if ($(ele).prop('selected')) {
- items.push({ label: $(ele).html(), value: $(ele).attr('value') });
+ items.push({label: $(ele).html(), value: $(ele).attr('value')});
}
});
- var context = $.extend({ items: items }, options, state);
+ var context = $.extend({items: items}, options, state);
// Render the template.
templates.render('core/form_autocomplete_selection', context).done(function(newHTML) {
var suggestions = [];
originalSelect.children('option').each(function(index, option) {
if ($(option).prop('selected') !== true) {
- suggestions[suggestions.length] = { label: option.innerHTML, value: $(option).attr('value') };
+ suggestions[suggestions.length] = {label: option.innerHTML, value: $(option).attr('value')};
}
});
// Re-render the list of suggestions.
var searchquery = state.caseSensitive ? query : query.toLocaleLowerCase();
- var context = $.extend({ options: suggestions}, options, state);
+ var context = $.extend({options: suggestions}, options, state);
templates.render(
'core/form_autocomplete_suggestions',
context
// Create the new markup and insert it after the select.
var suggestions = [];
originalSelect.children('option').each(function(index, option) {
- suggestions[index] = { label: option.innerHTML, value: $(option).attr('value') };
+ suggestions[index] = {label: option.innerHTML, value: $(option).attr('value')};
});
// Render all the parts of our UI.
// Public variables and functions.
processResults: function(selector, data) {
// Mangle the results into an array of objects.
- var results = [], i = 0;
+ var results = [];
+ var i = 0;
var excludelist = String($(selector).data('exclude')).split(',');
for (i = 0; i < data.courses.length; i++) {
if (excludelist.indexOf(String(data.courses[i].id)) === -1) {
- results.push({ value: data.courses[i].id, label: data.courses[i].displayname });
+ results.push({value: data.courses[i].id, label: data.courses[i].displayname});
}
}
return results;
allScript += ' ' + scriptNode.text();
}
}
- }.bind(this));
+ });
promise.resolve(data.html, allScript);
}).fail(function(ex) {
promise.reject(ex);
// From http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery.
/* jshint bitwise: false */
/* eslint no-bitwise: "off" */
- var hash = 0, i, chr, len;
+ var hash = 0;
+ var i, chr, len;
if (source.length === 0) {
return hash;
}
setupTargetRegion: function() {
var targetRegion = $('#' + notificationModule.fieldName);
if (targetRegion.length) {
- return;
+ return false;
}
var newRegion = $('<span>').attr('id', notificationModule.fieldName);
var promises = ajax.call([{
methodname: 'core_tag_get_tagindex',
- args: { tagindex: args }
+ args: {tagindex: args}
}], true);
$.when.apply($, promises)
var form = $(this).closest('form').get(0),
cnt = $(form).find("input[type=checkbox]:checked").length;
if (!cnt) {
- return false;
+ return;
}
var tempElement = $("<input type='hidden'/>").attr('name', this.name);
e.preventDefault();
notification.alert(s[0], s[1], s[2]);
}
);
- return false;
+ return;
}
var tempElement = $("<input type='hidden'/>").attr('name', this.name);
str.get_strings([
var href = $(this).attr('data-url') + '&sesskey=' + M.cfg.sesskey;
str.get_strings([
{key: 'delete'},
- {key: 'suredeletecoll', component: 'tag', param: $(this).attr('data-collname') },
+ {key: 'suredeletecoll', component: 'tag', param: $(this).attr('data-collname')},
{key: 'yes'},
{key: 'no'},
]).done(function(s) {
/** @var {string[]} requiredStrings - Collection of strings found during the rendering of one template */
var requiredStrings = [];
- /** @var {string[]} requiredJS - Collection of js blocks found during the rendering of one template */
- var requiredJS = [];
-
/** @var {Number} uniqid Incrementing value that is changed for every call to render */
var uniqid = 1;
var templatecontext = {
attributes: [
- { name: 'src', value: url},
- { name: 'alt', value: helper(text)},
- { name: 'class', value: 'smallicon'}
+ {name: 'src', value: url},
+ {name: 'alt', value: helper(text)},
+ {name: 'class', value: 'smallicon'}
]
};
// We forced loading of this early, so it will be in the cache.
* @return {string}
*/
var jsHelper = function(sectionText, helper) {
- requiredJS.push(helper(sectionText, this));
+ this.jsBlocks.push(helper(sectionText, this));
return '';
};
var addHelpers = function(context, themeName) {
currentThemeName = themeName;
requiredStrings = [];
- requiredJS = [];
context.uniqid = uniqid++;
context.str = function() {
return stringHelper;
context.quote = function() {
return quoteHelper;
};
- context.globals = { config: config };
+ context.globals = {config: config};
+ context.jsBlocks = [];
context.currentTheme = themeName;
};
*/
var getJS = function(strings) {
var js = '';
- if (requiredJS.length > 0) {
- js = requiredJS.join(";\n");
+ if (this.jsBlocks.length > 0) {
+ js = this.jsBlocks.join(";\n");
}
// Re-render to get the final strings.
// and cause the template to die on the second pass (unbalanced).
result = treatStringsInContent(result, strings);
- deferred.resolve(result, getJS(strings));
+ deferred.resolve(result, getJS.bind(context)(strings));
})
.fail(deferred.reject);
} else {
- deferred.resolve(result.trim(), getJS([]));
+ deferred.resolve(result.trim(), getJS.bind(context)([]));
}
}
).fail(deferred.reject);
* @param {Event} e The event.
* @return {Boolean}
*/
+ // This function should be simplified. In the meantime..
+ // eslint-disable-next-line complexity
Tree.prototype.handleKeyDown = function(item, e) {
var currentIndex = this.getVisibleItems().index(item);
*
* @return external_function_parameters
* @since Moodle 2.7
+ * @deprecated Moodle 3.2 MDL-51373 - Please do not call this function any more.
+ * @see gradereport_user_external::get_grades_table for a similar function
*/
public static function get_grades_parameters() {
return new external_function_parameters(
* @param array $userids Array of user ids
* @return array Array of grades
* @since Moodle 2.7
+ * @deprecated Moodle 3.2 MDL-51373 - Please do not call this function any more.
+ * @see gradereport_user_external::get_grades_table for a similar function
*/
public static function get_grades($courseid, $component = null, $activityid = null, $userids = array()) {
global $CFG, $USER, $DB;
* @param int $iteminstance Item instance
* @param int $itemnumber Item number
* @return grade_item A grade_item instance
+ * @deprecated Moodle 3.2 MDL-51373 - Please do not call this function any more.
+ * @see gradereport_user_external::get_grades_table for a similar function
*/
private static function get_grade_item($courseid, $itemtype, $itemmodule = null, $iteminstance = null, $itemnumber = null) {
$gradeiteminstance = null;
*
* @return external_description
* @since Moodle 2.7
+ * @deprecated Moodle 3.2 MDL-51373 - Please do not call this function any more.
+ * @see gradereport_user_external::get_grades_table for a similar function
*/
public static function get_grades_returns() {
return new external_single_structure(
}
+ /**
+ * Marking the method as deprecated.
+ *
+ * @return bool
+ */
+ public static function get_grades_is_deprecated() {
+ return true;
+ }
+
/**
* Returns description of method parameters
*
$plugins = array(
'qformat' => array('blackboard', 'learnwise'),
'enrol' => array('authorize'),
+ 'report' => array('search'),
'tinymce' => array('dragmath'),
'tool' => array('bloglevelupgrade', 'qeupgradehelper', 'timezoneimport'),
'theme' => array('mymobile', 'afterburner', 'anomaly', 'arialist', 'binarius', 'boxxie', 'brick', 'formal_white',
'report' => array(
'backups', 'competency', 'completion', 'configlog', 'courseoverview', 'eventlist',
- 'log', 'loglive', 'outline', 'participation', 'progress', 'questioninstances', 'search',
+ 'log', 'loglive', 'outline', 'participation', 'progress', 'questioninstances',
'security', 'stats', 'performance', 'usersessions'
),
$subsystems = core_component::get_core_subsystems();
foreach ($subsystems as $subsystem => $dir) {
if (!empty($dir) && is_dir($dir . '/amd')) {
- $jsdirs[$subsystem] = $dir . '/amd';
+ $jsdirs['core_' . $subsystem] = $dir . '/amd';
}
}
$plugintypes = core_component::get_plugin_types();
'core_grades_get_grades' => array(
'classname' => 'core_grades_external',
'methodname' => 'get_grades',
- 'description' => 'Returns student course total grade and grades for activities.
+ 'description' => '** DEPRECATED ** Please do not call this function any more.
+ Returns student course total grade and grades for activities.
This function does not return category or manual items.
This function is suitable for managers or teachers not students.',
'type' => 'read',
// Moodle v3.1.0 release upgrade line.
// Put any upgrade step following this.
+ if ($oldversion < 2016070700.01) {
+
+ // If someone is emotionally attached to it let's leave the config (basically the version) there.
+ if (!file_exists($CFG->dirroot . '/report/search/classes/output/form.php')) {
+ unset_all_config_for_plugin('report_search');
+ }
+
+ // Savepoint reached.
+ upgrade_main_savepoint(true, 2016070700.01);
+ }
+
return true;
}
$systemcontext = context_system::instance();
$systemneedsfreeze = upgrade_letter_boundary_needs_freeze($systemcontext);
+ // Check the setting for showing the letter grade in a column (default is false).
+ $usergradelettercolumnsetting = 0;
+ if (isset($CFG->grade_report_user_showlettergrade)) {
+ $usergradelettercolumnsetting = (int)$CFG->grade_report_user_showlettergrade;
+ }
+ $lettercolumnsql = '';
+ if ($usergradelettercolumnsetting) {
+ // the system default is to show a column with letters (and the course uses the defaults).
+ $lettercolumnsql = '(gss.value is NULL OR ' . $DB->sql_compare_text('gss.value') . ' <> \'0\')';
+ } else {
+ // the course displays a column with letters.
+ $lettercolumnsql = $DB->sql_compare_text('gss.value') . ' = \'1\'';
+ }
+
// 3, 13, 23, 31, and 32 are the grade display types that incorporate showing letters. See lib/grade/constants/php.
- $systemletters = (isset($CFG->grade_displaytype) && in_array($CFG->grade_displaytype, array(3, 13, 23, 31, 32)));
+ $systemusesletters = (int) (isset($CFG->grade_displaytype) && in_array($CFG->grade_displaytype, array(3, 13, 23, 31, 32)));
+ $systemletters = $systemusesletters || $usergradelettercolumnsetting;
$contextselect = context_helper::get_preload_record_columns_sql('ctx');
JOIN {grade_items} gi ON c.id = gi.courseid
JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel
LEFT JOIN {grade_settings} gs ON gs.courseid = c.id AND gs.name = 'displaytype'
+ LEFT JOIN {grade_settings} gss ON gss.courseid = c.id AND gss.name = 'report_user_showlettergrade'
LEFT JOIN {grade_letters} gl ON gl.contextid = ctx.id
- WHERE gi.display = 0 AND (gs.value is NULL)
+ WHERE gi.display = 0
+ AND ((gs.value is NULL)
+ AND ($lettercolumnsql))
AND gl.id is NULL $coursesql";
$affectedcourseids = $DB->get_recordset_sql($sql, $params);
foreach ($affectedcourseids as $courseid) {
set_config('gradebook_calculations_freeze_' . $courseid->courseid, 20160518);
}
$affectedcourseids->close();
-
}
- if ($systemletters || $systemneedsfreeze) {
-
- // If the system letter boundary is okay proceed to check grade item and course grade display settings.
- $sql = "SELECT DISTINCT c.id AS courseid, $contextselect
- FROM {course} c
- JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel
- JOIN {grade_items} gi ON c.id = gi.courseid
- LEFT JOIN {grade_settings} gs ON c.id = gs.courseid AND gs.name = 'displaytype'
- LEFT JOIN {grade_letters} gl ON gl.contextid = ctx.id
- WHERE gi.display IN (3, 13, 23, 31, 32)
- OR (" . $DB->sql_compare_text('gs.value') . " IN ('3', '13', '23', '31', '32'))
- OR gl.id is NOT NULL
- $coursesql";
- } else {
-
- // There is no site setting for letter grades. Just check the modified letter boundaries.
- $sql = "SELECT DISTINCT c.id AS courseid, $contextselect
- FROM {grade_letters} l, {course} c
- JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel
- WHERE l.contextid = ctx.id
- AND ctx.instanceid = c.id
- $coursesql";
- }
+ // If the system letter boundary is okay proceed to check grade item and course grade display settings.
+ $sql = "SELECT DISTINCT c.id AS courseid, $contextselect
+ FROM {course} c
+ JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel
+ JOIN {grade_items} gi ON c.id = gi.courseid
+ LEFT JOIN {grade_settings} gs ON c.id = gs.courseid AND gs.name = 'displaytype'
+ LEFT JOIN {grade_settings} gss ON gss.courseid = c.id AND gss.name = 'report_user_showlettergrade'
+ WHERE
+ (
+ -- A grade item is using letters
+ (gi.display IN (3, 13, 23, 31, 32))
+ -- OR the course is using letters
+ OR (" . $DB->sql_compare_text('gs.value') . " IN ('3', '13', '23', '31', '32')
+ -- OR the course using the system default which is letters
+ OR (gs.value IS NULL AND $systemusesletters = 1)
+ )
+ OR ($lettercolumnsql)
+ )
+ -- AND the course matches
+ $coursesql";
$potentialcourses = $DB->get_recordset_sql($sql, $params);
if (!empty($letters)) {
foreach ($letters as $boundary => $notused) {
$standardisedboundary = upgrade_standardise_score($boundary, 0, 100, 0, 100);
- if ($boundary != $standardisedboundary) {
+ if ($standardisedboundary < $boundary) {
return true;
}
}
margin: 0;
border-radius: 0;
cursor: pointer;
- line-height: initial;
}
div.editor_atto_toolbar button + button {
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+/* global NOTIFY_WARNING, NOTIFY_INFO */
+/* eslint-disable no-unused-vars */
/**
* A autosave function for the Atto editor.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+/* global LOGNAME */
/**
* @module moodle-editor_atto-editor
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+/* global YUI */
/**
* @module moodle-editor_atto-plugin
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+/* eslint-disable no-unused-vars */
/**
* The Atto WYSIWG pluggable editor, written for Moodle.
+++ /dev/null
-/* globals rangy */
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+/* global rangy */
/**
* @module moodle-editor_atto-editor
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+/* global rangy */
/**
* @module moodle-editor_atto-editor
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+/* global LOGNAME */
/**
* @module moodle-editor_atto-editor
* returned. Default false.
* allowid : If true then id attributes will not be removed, even when using htmlpurifier. Default (different from
* format_text) true. Default changed id attributes are commonly needed.
+ * blanktarget : If true all <a> tags will have target="_blank" added unless target is explicitly specified.
* </pre>
*
* @param string $text The content that may contain ULRs in need of rewriting.
* @param object/array $options text formatting options
* @return array text + textformat
* @since Moodle 2.3
+ * @since Moodle 3.2 component, filearea and itemid are optional parameters
*/
-function external_format_text($text, $textformat, $contextid, $component, $filearea, $itemid, $options = null) {
+function external_format_text($text, $textformat, $contextid, $component = null, $filearea = null, $itemid = null,
+ $options = null) {
global $CFG;
// Get settings (singleton).
$settings = external_settings::get_instance();
- if ($settings->get_fileurl()) {
+ if ($component and $filearea and $settings->get_fileurl()) {
require_once($CFG->libdir . "/filelib.php");
$text = file_rewrite_pluginfile_urls($text, $settings->get_file(), $contextid, $component, $filearea, $itemid);
}
+/* global CALENDAR, MOODLECALENDAR */
+
/**
* Add some custom methods to the node class to make our lives a little
* easier within this module.
$coursenode = $parent->add($coursename, $url, self::TYPE_COURSE, $shortname, $course->id);
$coursenode->hidden = (!$course->visible);
- // We need to decode &'s here as they will have been added by format_string above and attributes will be encoded again
- // later.
- $coursenode->title(str_replace('&', '&', $fullname));
+ $coursenode->title(format_string($course->fullname, true, array('context' => $coursecontext, 'escape' => false)));
if ($canexpandcourse) {
// This course can be expanded by the user, make it a branch to make the system aware that its expandable by ajax.
$coursenode->nodetype = self::NODETYPE_BRANCH;
$test = '$$ \pi $$';
$testformat = FORMAT_MARKDOWN;
- $correct = array('<span class="nolink"><span class="filter_mathjaxloader_equation"><p>$$ \pi $$</p>
-</span></span>', FORMAT_HTML);
+ $correct = array('<span class="filter_mathjaxloader_equation"><p><span class="nolink">$$ \pi $$</span></p>
+</span>', FORMAT_HTML);
$this->assertSame(external_format_text($test, $testformat, $context->id, 'core', '', 0), $correct);
// Filters can be opted out from by the developer.
$correct = 'ENFR hi there%';
$this->assertSame($correct, external_format_string($test, $context->id, false, ['filter' => false]));
+ $this->assertSame("& < > \" '", format_string("& < > \" '", true, ['escape' => false]));
$settings->set_raw($currentraw);
$settings->set_filter($currentfilter);
--- /dev/null
+<?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/>.
+
+/**
+ * Unit tests for requirejs loader.
+ *
+ * @package core
+ * @author Damyon Wiese <damyon@moodle.com>
+ * @copyright 2016 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Unit tests for requirejs.
+ *
+ * @package core
+ * @author Damyon Wiese <damyon@moodle.com>
+ * @copyright 2016 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class core_requirejs_testcase extends advanced_testcase {
+
+ /**
+ * Test requirejs loader
+ */
+ public function test_requirejs() {
+ global $CFG;
+
+ // Find a core module.
+ $result = core_requirejs::find_one_amd_module('core', 'templates', false);
+ $expected = ['core/templates' => $CFG->dirroot . '/lib/amd/build/templates.min.js'];
+ $this->assertEquals($expected, $result);
+
+ $result = core_requirejs::find_one_amd_module('core', 'templates', true);
+ $expected = ['core/templates' => $CFG->dirroot . '/lib/amd/src/templates.js'];
+ $this->assertEquals($expected, $result);
+
+ // Find a subsystem module (none exist yet).
+ $result = core_requirejs::find_one_amd_module('core_group', 'doesnotexist', false);
+ $expected = [];
+ $this->assertEquals($expected, $result);
+
+ // Find a plugin module.
+ $result = core_requirejs::find_one_amd_module('mod_assign', 'grading_panel', true);
+ $expected = ['mod_assign/grading_panel' => $CFG->dirroot . '/mod/assign/amd/src/grading_panel.js'];
+ $this->assertEquals($expected, $result);
+
+ // Find all modules - no debugging.
+ $result = core_requirejs::find_all_amd_modules(true);
+ foreach ($result as $key => $path) {
+ // Lets verify the first part of the key is a valid component name and the second part correctly contains "min" or not.
+ list($component, $template) = explode('/', $key, 2);
+ // Can we resolve it to a valid dir?
+ $dir = core_component::get_component_directory($component);
+ $this->assertNotEmpty($dir);
+
+ // Only "core" is allowed to have no _ in component names.
+ if (strpos($component, '_') === false) {
+ $this->assertEquals('core', $component);
+ }
+ $this->assertNotContains('.min', $path);
+ }
+
+ // Find all modules - debugging.
+ $result = core_requirejs::find_all_amd_modules(false);
+ foreach ($result as $key => $path) {
+ // Lets verify the first part of the key is a valid component name and the second part correctly contains "min" or not.
+ list($component, $template) = explode('/', $key, 2);
+ $dir = core_component::get_component_directory($component);
+ $this->assertNotEmpty($dir);
+ // Only "core" is allowed to have no _ in component names.
+ if (strpos($component, '_') === false) {
+ $this->assertEquals('core', $component);
+ }
+
+ $this->assertContains('.min', $path);
+ }
+
+ }
+}
// Create some courses.
$courses = array();
$contexts = array();
- for ($i = 0; $i < 37; $i++) {
+ for ($i = 0; $i < 45; $i++) {
$course = $this->getDataGenerator()->create_course();
$context = context_course::instance($course->id);
if (in_array($i, array(2, 5, 10, 13, 14, 19, 23, 25, 30, 34, 36))) {
$this->assign_bad_letter_boundary($context->id);
}
- if (in_array($i, array(9, 10, 11, 18, 19, 20, 29, 30, 31))) {
+ if (in_array($i, array(3, 9, 10, 11, 18, 19, 20, 29, 30, 31, 40))) {
grade_set_setting($course->id, 'displaytype', '3');
} else if (in_array($i, array(8, 17, 28))) {
grade_set_setting($course->id, 'displaytype', '2');
}
- if ($i >= 7) {
- $assignrow = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'name' => 'Test!'));
- $gi = grade_item::fetch(
- array('itemtype' => 'mod',
- 'itemmodule' => 'assign',
- 'iteminstance' => $assignrow->id,
- 'courseid' => $course->id));
- if (in_array($i, array(13, 14, 15, 23, 24, 34, 35, 36))) {
- grade_item::set_properties($gi, array('display', 3));
- $gi->update();
- } else if (in_array($i, array(12, 21, 32))) {
- grade_item::set_properties($gi, array('display', 2));
- $gi->update();
- }
- $gradegrade = new grade_grade();
- $gradegrade->itemid = $gi->id;
- $gradegrade->userid = $user->id;
- $gradegrade->rawgrade = 55.5563;
- $gradegrade->finalgrade = 55.5563;
- $gradegrade->rawgrademax = 100;
- $gradegrade->rawgrademin = 0;
- $gradegrade->timecreated = time();
- $gradegrade->timemodified = time();
- $gradegrade->insert();
+ if (in_array($i, array(37, 43))) {
+ // Show.
+ grade_set_setting($course->id, 'report_user_showlettergrade', '1');
+ } else if (in_array($i, array(38, 42))) {
+ // Hide.
+ grade_set_setting($course->id, 'report_user_showlettergrade', '0');
}
+ $assignrow = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'name' => 'Test!'));
+ $gi = grade_item::fetch(
+ array('itemtype' => 'mod',
+ 'itemmodule' => 'assign',
+ 'iteminstance' => $assignrow->id,
+ 'courseid' => $course->id));
+ if (in_array($i, array(6, 13, 14, 15, 23, 24, 34, 35, 36, 41))) {
+ grade_item::set_properties($gi, array('display' => 3));
+ $gi->update();
+ } else if (in_array($i, array(12, 21, 32))) {
+ grade_item::set_properties($gi, array('display' => 2));
+ $gi->update();
+ }
+ $gradegrade = new grade_grade();
+ $gradegrade->itemid = $gi->id;
+ $gradegrade->userid = $user->id;
+ $gradegrade->rawgrade = 55.5563;
+ $gradegrade->finalgrade = 55.5563;
+ $gradegrade->rawgrademax = 100;
+ $gradegrade->rawgrademin = 0;
+ $gradegrade->timecreated = time();
+ $gradegrade->timemodified = time();
+ $gradegrade->insert();
+
$contexts[] = $context;
$courses[] = $course;
}
// System setting for grade letter boundaries (default).
set_config('grade_displaytype', '3');
- for ($i = 0; $i < 37; $i++) {
+ for ($i = 0; $i < 45; $i++) {
unset_config('gradebook_calculations_freeze_' . $courses[$i]->id);
}
upgrade_course_letter_boundary();
// System setting for grade letter boundaries (custom with problem).
$systemcontext = context_system::instance();
$this->assign_bad_letter_boundary($systemcontext->id);
- for ($i = 0; $i < 37; $i++) {
+ for ($i = 0; $i < 45; $i++) {
unset_config('gradebook_calculations_freeze_' . $courses[$i]->id);
}
upgrade_course_letter_boundary();
// System setting not showing letters.
set_config('grade_displaytype', '2');
- for ($i = 0; $i < 37; $i++) {
+ for ($i = 0; $i < 45; $i++) {
unset_config('gradebook_calculations_freeze_' . $courses[$i]->id);
}
upgrade_course_letter_boundary();
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[35]->id});
// [36] A course with grade display settings of letters with modified and good boundary (not 57) Should not be frozen.
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[36]->id}));
+
+ // Previous site conditions still exist.
+ for ($i = 0; $i < 45; $i++) {
+ unset_config('gradebook_calculations_freeze_' . $courses[$i]->id);
+ }
+ upgrade_course_letter_boundary();
+
+ // [37] Site setting for not showing the letter column and course setting set to show (frozen).
+ $this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[37]->id});
+ // [38] Site setting for not showing the letter&n