Compare commits

..

90 Commits

Author SHA1 Message Date
Jun Pataleta ac9e395ed6 Moodle release 4.0.1 2022-05-07 19:34:54 +08:00
Eloy Lafuente (stronk7) 99fc164199 weekly release 4.0+ 2022-05-06 15:58:28 +02:00
Jake Dallimore 9ec2c12f3d MDL-74602 mod_assign: fix js error with assign grader on classic 2022-05-06 16:48:29 +08:00
Jun Pataleta 6ec89f6374 Merge branch 'MDL-74584-400-v1' of https://github.com/mihailges/moodle into MOODLE_400_STABLE 2022-05-06 14:17:37 +08:00
Mihail Geshoski 834c80849c MDL-74584 mod_bigbluebuttonbn: Update behat tests 2022-05-06 13:32:14 +08:00
Mihail Geshoski 674198a799 MDL-74584 mod_bigbluebuttonbn: Update unit tests 2022-05-06 13:32:14 +08:00
Mihail Geshoski 66c32a3687 MDL-74584 course: New optional parameter in get_module_types_names()
Adds new parameter in get_module_types_names() to optionally reset
the $modnames static cache.
2022-05-06 13:32:13 +08:00
Mihail Geshoski 0118227509 MDL-74584 mod_bigbluebuttonbn: Add install script and new upgrade step
Adds a new install script for the BBB module and a new upgrade step.
The BBB module now will be disabled by default for new installations
and also it will be disabled for the existing sites that use the
default BBB server configuration. Admistrators will be required to
confirm the acceptance of the related DPA prior to (re)enabling the
plugin once again.
2022-05-06 12:19:56 +08:00
Mihail Geshoski 2e1478b094 MDL-74584 mod_bigbluebuttonbn: Add DPA info in the general setting page
Adds a note in the BBB general settings page to raise awareness about
the legal obligations related to the data processing agreement with the
service provider which is currently configured.
2022-05-06 12:19:56 +08:00
Mihail Geshoski 6961258bc2 MDL-74584 mod_bigbluebuttonbn: Implement 'pre_enable_plugin_actions'
Implements a function for the 'pre_enable_plugin_actions' callback.
When the default BBB server settings are used while the administrator
attempts to enable the BBB plugin, the function will prevent this
action and trigger a dynamic form requesting the admin to conifrm
their acceptance of the related data processing agreement. The process
of enabling the plugin will continue as usual in cases where the
admin has already confirmed the acceptance of the dpa or a different
BBB server configuration is used other than the default.
2022-05-06 12:19:56 +08:00
Mihail Geshoski b4f6816952 MDL-74584 admin: Add callback executed prior to enabling a module
Adds a callback xxx_pre_enable_plugin_actions in admin/modules.php
which plugins can use to force additional actions before enabling the
plugin. The return value (bool) from the plugin callback method
specifies whether the process of enabling the plugin should continue
after the added actions or not.
2022-05-06 12:19:56 +08:00
Andrew Nicols 16b30d920b MDL-74511 core: Add phpcs default config 2022-05-06 12:01:32 +08:00
Ilya Tregubov 61d140e99f Merge branch 'MDL-41498-400' of https://github.com/ilyatregubov/moodle into MOODLE_400_STABLE 2022-05-06 08:26:59 +06:00
Robert Schrenk cc5eb38cea MDL-41498 course: courses participant page 2022-05-06 08:26:08 +06:00
Víctor Déniz 3b7bba9e75 Merge branch 'MDL-74612-400' of https://github.com/paulholden/moodle into MOODLE_400_STABLE 2022-05-05 13:25:37 +01:00
Víctor Déniz 2e020b506a Merge branch 'MDL-74128-400' of https://github.com/paulholden/moodle into MOODLE_400_STABLE 2022-05-05 12:09:59 +01:00
Víctor Déniz 74cdb7c4c8 Merge branch 'MDL-74567-400' of https://github.com/paulholden/moodle into MOODLE_400_STABLE 2022-05-05 09:39:39 +01:00
Paul Holden ef8d381a2f MDL-74567 core: re-factor flickr libraries to use shared user-agent. 2022-05-05 09:21:22 +01:00
Jun Pataleta 39717b72b1 MDL-74317 blocks: Revert checking of block usage against page format 2022-05-05 10:04:01 +08:00
Jun Pataleta e7ff99758e Merge branch 'MDL-74576-400' of https://github.com/snake/moodle into MOODLE_400_STABLE 2022-05-05 09:55:45 +08:00
Jun Pataleta 26492d4979 Merge branch 'MDL-73981-400' of https://github.com/ilyatregubov/moodle into MOODLE_400_STABLE 2022-05-05 09:49:06 +08:00
Ilya Tregubov 3abbcd9976 Merge branch 'MDL-74602-400' of https://github.com/snake/moodle into MOODLE_400_STABLE 2022-05-05 07:46:55 +06:00
Jun Pataleta 1456551ba6 Merge branch 'MDL-74546-400' of https://github.com/snake/moodle into MOODLE_400_STABLE 2022-05-05 09:41:34 +08:00
Ilya Tregubov c1ebec7cbc MDL-73981 tool_uploadcourse: Validate enrolment role from csv. 2022-05-05 07:39:50 +06:00
Jun Pataleta 812c8b37e5 Merge branch 'MDL-74511-400' of https://github.com/andrewnicols/moodle into MOODLE_400_STABLE 2022-05-05 09:37:31 +08:00
Jake Dallimore f2ab11aa5b MDL-73736 core_auth: Fix concurrency issue in login_attempt_failed()
This patch wraps the login_failed_count logic in a resource lock and
forces a user preferences cache reload. Each thread must wait for the
lock and must fetch the current count before incrementing it. This
ensures that login_failed_count is correct across threads and that the
lockout threshold is correctly honoured.

Co-Authored-By: Sujith Haridasan <sujith@moodle.com>
2022-05-04 14:45:00 +06:00
Michael Hawkins 240b402523 MDL-74333 badges: Check profile criteria valid when reviewing 2022-05-04 12:58:02 +08:00
Ilya Tregubov 34c4b3ce0c Merge branch 'MDL-74563-400' of https://github.com/paulholden/moodle into MOODLE_400_STABLE 2022-05-04 09:26:06 +06:00
Ferran Recio 8b098b4a4e MDL-71623 core_search: fix user document visibility 2022-05-04 03:55:18 +02:00
Amaia Anabitarte 38a40c5e4b MDL-74318 core_user: Description field as hidden on profile 2022-05-04 03:55:18 +02:00
Paul Holden 72580a5413 MDL-74204 mod_assign: escape identity fields in allocate marker form. 2022-05-04 03:55:18 +02:00
Jun Pataleta 6253ab0170 Merge branch 'MDL-73878-40' of https://github.com/aanabit/moodle into MOODLE_400_STABLE 2022-05-04 09:44:28 +08:00
Amaia Anabitarte ff89abc311 MDL-73878 core_user: Creating a new category for social fields 2022-05-03 17:46:18 +02:00
Amaia Anabitarte 7878d79359 MDL-73878 core_user: Fixing social fields upgrading issue 2022-05-03 17:43:22 +02:00
Jun Pataleta 93319747b2 Merge branch 'MDL-74543_400' of https://github.com/timhunt/moodle into MOODLE_400_STABLE 2022-05-03 22:22:45 +08:00
Tim Hunt f46c1b4fa9 MDL-74543 quiz attemptlib: covert string comparison to ===
Where obviously safe.
2022-05-03 13:48:04 +01:00
Tim Hunt a0297df86e MDL-74543 quiz: correctly record time when overdue attempt submitted 2022-05-03 13:48:04 +01:00
Víctor Déniz da9ab8a2f9 Merge branch 'MDL-74611_400' of https://github.com/timhunt/moodle into MOODLE_400_STABLE 2022-05-03 13:00:59 +01:00
Ilya Tregubov 33829b8b68 Merge branch 'mdl65478-fix-400' of https://github.com/matthewhilton/moodle into MOODLE_400_STABLE 2022-05-03 15:43:59 +06:00
Tim Hunt f5f468f6e1 MDL-74611 course settigns: re-order Common module settings
All the group-related settings should be next to each other.
2022-05-03 10:36:01 +01:00
Jake Dallimore 6b4f55c91b Merge branch 'MDL-74441-400' of https://github.com/cameron1729/moodle into MOODLE_400_STABLE 2022-05-03 16:54:50 +08:00
Cameron Ball 63ed56bc7c MDL-74441 mod_forum: Fix overflow in unified grader 2022-05-03 15:52:26 +08:00
Ilya Tregubov 841214dab2 Merge branch 'MDL-74598-400' of https://github.com/roland04/moodle into MOODLE_400_STABLE 2022-05-03 11:57:07 +06:00
Jason den Dulk 43cbc05a2d MDL-65478 backup, course format: Handle editor elements in course format
Modified course format options reading and writing to be able to handle Editor elements by enabling them to split array values into
multiple values before inserting into database, and combining multiple values into an array when reading from the database.
Modified backup and restore code to use backup_nested_elements, and to interact directly with the database.

Co-authored-by: Jason den Dulk <jasondendulk@catalyst-au.net>
Co-authored-by: Matthew Hilton <matthewhilton@catalyst-au.net>
2022-05-03 14:23:15 +10:00
Ilya Tregubov 973ea46697 Merge branch 'MDL-74450-400' of https://github.com/mihailges/moodle into MOODLE_400_STABLE 2022-05-03 09:52:26 +06:00
Jake Dallimore 98dbb93589 MDL-74602 mod_wiki: disable activity header in wiki print view 2022-05-03 11:09:00 +08:00
Jake Dallimore 5fa19e43b3 MDL-74602 mod_chat: disable activity header in ajax chat interface 2022-05-03 11:09:00 +08:00
Jake Dallimore 0d3a2c9181 MDL-74602 mod_book: disable activity header on book print page 2022-05-03 11:09:00 +08:00
Jake Dallimore 4f7bd72f72 MDL-74602 mod_assign: disable activity header on embedded grader page 2022-05-03 11:09:00 +08:00
Jake Dallimore cc182408aa MDL-74602 theme_boost: fix missing activity header in embedded layout
The activity header, which includes things like dates and completion
information, was moved out of the page $OUTPUT and into a separate
template context variable in 4.0, meaning it was missing from any layout
which didn't actively add it back to the page output. This fixes this
problem for the embedded layout only by adding support for the activity
header in the embedded template.
2022-05-03 11:09:00 +08:00
Jun Pataleta 8b3913605a Merge branch 'MDL-74317-400' of https://github.com/dravek/moodle into MOODLE_400_STABLE 2022-05-02 17:24:23 +08:00
Jun Pataleta 8ff67c91de Merge branch 'MDL-74436-400' of https://github.com/paulholden/moodle into MOODLE_400_STABLE 2022-05-02 16:30:06 +08:00
Jake Dallimore 4cbd6a0c6a MDL-74576 enrol_lti: allow unsupported scopes in ags_info
Instead of hard blocking launches with extension scopes, just ignore
the unsupported scopes and continue.
2022-05-02 15:39:20 +08:00
Paul Holden 203a55f57a MDL-74128 reportbuilder: Behat helper for navigating to view page. 2022-04-29 17:18:06 +01:00
Paul Holden 5b05a9378c MDL-74612 cohort: use data generator for populating cohort members. 2022-04-29 16:23:32 +01:00
Ilya Tregubov 81e5d425c4 weekly release 4.0+ 2022-04-29 07:55:31 +06:00
Ilya Tregubov 6362d7b51c Merge branch 'install_400_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_400_STABLE 2022-04-29 07:55:27 +06:00
Mikel Martín 51d3df8d30 MDL-74598 reportbuilder: Fix action menus alignment to the right 2022-04-28 16:46:00 +02:00
Paul Holden a60a6d41a3 MDL-74567 repository_flickr: replace user-agent value for API calls.
Flickr doesn't like user agent that looks like a bot. Effectively the
same reasoning/fix as b8ee31a0.
2022-04-28 14:45:37 +01:00
Mihail Geshoski d6ba7724ae MDL-74450 admin: Use the context from admin_settingpage as page context
The defined context in admin_settingpage does not always relate to the
system context. One example is the 'frontpagesettings' admin setting
page which specifies front page as it's default context. Therefore, the
page context in admin/settings.php should be consisent with the defined
context in the related admin_settingpage object to make sure that the
expected navigation menus are being displayed and properly highlighted.
Additionally, the code in admin/settings.php related to the breadcrumb
structure specific to 'frontpagesettings' has been removed as it is no
longer relevant.
2022-04-28 13:23:57 +08:00
Jun Pataleta 4f1be71581 Merge branch 'MDL-74478-400' of https://github.com/mihailges/moodle into MOODLE_400_STABLE 2022-04-28 12:54:26 +08:00
Peter Dias 58ddfe84c2 MDL-74478 badges: Check completion_fail when awarding badge
Bring the award_criteria_activity checks in line with the observer checks
2022-04-28 12:16:19 +08:00
Jun Pataleta dd156a4160 Merge branch 'MDL-74461-400' of https://github.com/HuongNV13/moodle into MOODLE_400_STABLE 2022-04-28 11:39:59 +08:00
Huong Nguyen 3bc8fa20bf MDL-74461 Navigation: Add section anchor to activity breadcrumb 2022-04-28 10:05:17 +07:00
Ilya Tregubov 954ae33aa9 Merge branch 'MOODLE_400-MDL-74427-v4' of https://github.com/golenkovm/moodle into MOODLE_400_STABLE 2022-04-28 08:10:29 +06:00
Jun Pataleta 24dbcc0008 Merge branch 'MDL-74537-400-enfix' of https://github.com/vmdef/moodle into MOODLE_400_STABLE 2022-04-27 15:47:30 +06:00
Ilya Tregubov ebb96c2850 Merge branch 'MDL-74510_400' of https://github.com/stronk7/moodle into MOODLE_400_STABLE 2022-04-27 15:47:30 +06:00
Paul Holden 870c5ffbde MDL-74479 reportbuilder: account for custom field context in output. 2022-04-27 15:47:29 +06:00
Eloy Lafuente (stronk7) 049e27a805 MDL-74320 lesson: Remove tested elsewhere parts of the scenario
The scenario has not only grades related completion conditions
but also timing conditions or reach the end conditions that
shouldn't be tested by a grades feature.

More yet, those completion conditions are already tested by
other feature files, namely:
- reach the end: completion_condition_end_reached.feature
- visit and timing: lesson_activity_completion.feature

So we have removed all those parts that are being tested
by other features.

Specially the visit and timing ones, because they lead to
random failures in slow environments and they have been
fixed in the lesson_activity_completion.feature scenarios
by MDL-72698.
2022-04-27 15:47:29 +06:00
Laurent David 6c7fa91d59 MDL-74514 mod_bigbluebuttonbn: BBB server is polled too often
* Fix issue with the roomupdater that should not force the updatecache flag
for get_meeting_info API
* Fix issue when meeting is not started (and does not exist) and bigbluebutton_proxy::get_meeting_info
throws an exception, skipping the cache and then polling the server every second.
2022-04-27 15:47:29 +06:00
Claude Vervoort 7c84b92be3 MDL-74481 mod_lti: fix role lookup for LTI 1.3 2022-04-27 15:47:29 +06:00
Mikhail Golenkov bb36c3a1bb MDL-74427 question: Re-use get_real_question_ids_in_category() 2022-04-27 12:35:08 +10:00
Mikhail Golenkov 990bfee024 MDL-74427 question: Implement get_real_question_ids_in_category() 2022-04-27 12:34:55 +10:00
David Matamoros 17584f9c92 MDL-74317 blocks: Blocks can be added to profile pages
- Fixed method user_can_addto to take into account that
blocks can also be added to user profile pages
2022-04-26 14:34:45 +02:00
David Matamoros f551072f9e MDL-74317 output: Remove capability checks in edit mode WS
- Removed validation on the change edit mode WS. Permission should
be handled where the edit button is rendered in order to show or not
the button.
2022-04-26 14:33:34 +02:00
Helen Foster 3447ab640c MDL-74537 lang: Import fixed English strings (en_fix) 2022-04-26 11:24:27 +01:00
Paul Holden 3dbad11471 MDL-74563 reportbuilder: cast operator parameter in number filter.
Add missing form labels, too.
2022-04-25 21:44:48 +01:00
Paul Holden 43b4b87fbf MDL-74436 calendar: validate course/category field during import. 2022-04-25 18:02:00 +01:00
Paul Holden 7d33385a1d MDL-74477 reportbuilder: sortable custom user profile field columns. 2022-04-25 13:40:12 +06:00
AMOS bot 657617ac21 Automatically generated installer lang files 2022-04-23 00:07:39 +00:00
Eloy Lafuente (stronk7) 205e4152cc MDL-74510 upgrade: add the 4.0.0 separation line to all upgrade scripts 2022-04-22 18:45:16 +02:00
Eloy Lafuente (stronk7) e36fb751e5 weekly release 4.0+ 2022-04-22 18:03:47 +02:00
Jake Dallimore a0c1acd7fd MDL-74546 enrol_lti: add missing d-flex to table to fix safari layout 2022-04-22 10:19:08 +08:00
Ilya Tregubov 2184ea5b64 Merge branch 'MDL-74394_400' of https://github.com/aolley/moodle into MOODLE_400_STABLE 2022-04-22 08:01:09 +06:00
Víctor Déniz c81b3dc384 Merge branch 'MDL-74312-400' of https://github.com/snake/moodle into MOODLE_400_STABLE 2022-04-21 16:39:51 +01:00
Adam Olley ca6a4b1953 MDL-74394 mnet: Better check for openssl_get_publickey() failure
In PHP8, this func now returns an object of type OpenSSLAsymmetricKey, not a
resource.

Reference:
https://www.php.net/manual/en/function.openssl-pkey-get-public.php
2022-04-21 22:08:20 +09:30
Jake Dallimore 20cefd70e2 MDL-74312 enrol_lti: fix copytoclipboard trigger element
This should be a button given it's an action, and making it a button
means it can be activated using either the space or enter keys, instead
of just enter.
2022-04-20 09:49:35 +08:00
Sara Arjona bc87d55a1f Merge branch 'MDL-74512_400' of https://github.com/stronk7/moodle into MOODLE_400_STABLE 2022-04-19 12:55:29 +02:00
Andrew Nicols 51c376cfca MDL-74511 core: Add phpcs config generator 2022-04-19 11:15:27 +08:00
Eloy Lafuente (stronk7) e0034b0566 MDL-74512 behat: Skip tests requiring lang install/upgrade
By adding the step:

Given remote langimport tests are enabled

We make the execution of scenarios requiring to install /
upgrade lang packs optional, based in the existence of the constant:

TOOL_LANGIMPORT_REMOTE_TESTS

That way, when we are skipping language upgrades with the CFG var:

$CFG->skiplangupgrade = true

We can decide not not execute those tests.

With other words, putting something like this in the config.php
file we will be controlling when to execute or no the behat tests:

    // Disable lang updates on upgrade.
    $CFG->skiplangupgrade = true;
    if (empty($CFG->skiplangupgrade)) {
        // Define it only if we aren't skipping lang upgrades.
        define('TOOL_LANGIMPORT_REMOTE_TESTS', true);
    }
2022-04-17 20:35:02 +02:00
5242 changed files with 86192 additions and 284233 deletions
+10 -11
View File
@@ -13,14 +13,14 @@ env:
jobs:
Grunt:
runs-on: ubuntu-22.04
runs-on: ubuntu-18.04
steps:
- name: Checking out code
uses: actions/checkout@v3
uses: actions/checkout@v2
- name: Configuring node & npm
uses: actions/setup-node@v3
uses: actions/setup-node@v2
with:
node-version-file: '.nvmrc'
@@ -54,11 +54,11 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
php: 7.4
- os: ubuntu-18.04
php: 7.3
extensions:
db: mysqli
- os: ubuntu-22.04
- os: ubuntu-18.04
php: 8.0
db: pgsql
extensions: xmlrpc-beta
@@ -79,13 +79,13 @@ jobs:
if: ${{ matrix.db == 'pgsql' }}
uses: m4nu56/postgresql-action@v1
with:
postgresql version: 12
postgresql version: 10
postgresql db: test
postgresql user: test
postgresql password: test
- name: Configuring git vars
uses: rlespinasse/github-slug-action@v4
uses: rlespinasse/github-slug-action@v3.x
- name: Setting up PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
@@ -96,7 +96,7 @@ jobs:
coverage: none
- name: Checking out code from ${{ env.GITHUB_REF_SLUG }}
uses: actions/checkout@v3
uses: actions/checkout@v2
- name: Setting up PHPUnit
env:
@@ -111,5 +111,4 @@ jobs:
- name: Running PHPUnit tests
env:
dbtype: ${{ matrix.db }}
phpunit_options: ${{ secrets.phpunit_options }}
run: vendor/bin/phpunit $phpunit_options
run: vendor/bin/phpunit -v
-1
View File
@@ -55,4 +55,3 @@ moodle-plugin-ci.phar
/admin/tool/componentlibrary/hugo/site/data/my-index.json
.hugo_build.lock
.phpcs.xml
jsconfig.json
-1
View File
@@ -233,7 +233,6 @@ const getOwningComponentDirectory = checkPath => {
};
module.exports = {
fetchComponentData,
getAmdSrcGlobList,
getComponentFromPath,
getComponentPaths,
-3
View File
@@ -47,9 +47,6 @@ module.exports = grunt => {
// Load ESLint.
require('./eslint')(grunt);
// Load jsconfig.
require('./jsconfig')(grunt);
// Load JSDoc.
require('./jsdoc')(grunt);
-53
View File
@@ -1,53 +0,0 @@
// 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/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* @copyright 2022 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
const configuration = {
compilerOptions: {
baseUrl: ".",
paths: {
},
target: "es2015",
allowSyntheticDefaultImports: false,
},
exclude: [
"node_modules",
],
include: [],
};
module.exports = (grunt) => {
const handler = () => {
const jsconfigData = Object.assign({}, configuration);
const path = require('path');
const {fetchComponentData} = require(path.join(process.cwd(), '.grunt', 'components.js'));
const componentData = fetchComponentData().components;
for (const [thisPath, component] of Object.entries(componentData)) {
jsconfigData.compilerOptions.paths[`${component}/*`] = [`${thisPath}/amd/src/*`];
jsconfigData.include.push(`${thisPath}/amd/src/**/*`);
}
grunt.file.write('jsconfig.json', JSON.stringify(jsconfigData, null, " ") + "\n");
};
grunt.registerTask('jsconfig', 'Generate a jsconfig configuration compatible with the LSP', handler);
};
+15 -25
View File
@@ -10,18 +10,14 @@ language: php
os: linux
dist: focal
dist: bionic
services:
- mysql
- docker
addons:
postgresql: "12"
apt:
packages:
- postgresql-12
- postgresql-client-12
postgresql: "10"
branches:
except:
@@ -36,18 +32,18 @@ jobs:
fast_finish: true
include:
# First all the lowest php ones (7.4)
- php: 7.4
# First all the lowest php ones (7.3)
- php: 7.3
env: DB=none TASK=CITEST
- php: 7.4
env: DB=none TASK=GRUNT
- php: 7.3
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
- if: env(MOODLE_DATABASE) = "pgsql" OR env(MOODLE_DATABASE) = "all" OR env(MOODLE_DATABASE) IS NOT present
php: 7.4
php: 7.3
env: DB=pgsql TASK=PHPUNIT
- if: env(MOODLE_DATABASE) = "mysqli" OR env(MOODLE_DATABASE) = "all"
php: 7.4
php: 7.3
env: DB=mysqli TASK=PHPUNIT
# Then, conditionally, all the highest php ones (8.0)
@@ -56,7 +52,7 @@ jobs:
env: DB=none TASK=CITEST
- if: env(MOODLE_PHP) = "all"
php: 8.0
env: DB=none TASK=GRUNT
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
- if: env(MOODLE_PHP) = "all" AND (env(MOODLE_DATABASE) = "pgsql" OR env(MOODLE_DATABASE) = "all" OR env(MOODLE_DATABASE) IS NOT present)
php: 8.0
@@ -76,11 +72,6 @@ before_install:
# Avoid IPv6 default binding as service (causes redis not to start).
- sudo service redis-server start --bind 127.0.0.1
env:
global:
- PGVER=12
- PGPORT=5433
install:
- >
if [ "$DB" = 'mysqli' ];
@@ -100,7 +91,7 @@ install:
sudo service postgresql stop
sudo mv /var/lib/postgresql /mnt/ramdisk
sudo ln -s /mnt/ramdisk/postgresql /var/lib/postgresql
sudo service postgresql start
sudo service postgresql start 9.6
fi
- >
if [ "$TASK" = 'PHPUNIT' ];
@@ -122,8 +113,8 @@ install:
- >
if [ "$TASK" = 'GRUNT' ];
then
nvm install
nvm use
nvm install $NVM_VERSION ;
nvm use $NVM_VERSION ;
fi
before_script:
@@ -155,11 +146,10 @@ before_script:
then
# Postgres-specific setup.
sed -i \
-e "s%= 'username'%= 'travis'%" \
-e "s%'dbsocket' => false%'dbsocket' => true%" \
-e "s%= 'username'%= 'postgres'%" \
config.php ;
psql -c 'CREATE DATABASE travis_ci_test;' -U travis;
psql -c 'CREATE DATABASE travis_ci_test;' -U postgres;
fi
if [ "$DB" = 'mysqli' ];
@@ -231,7 +221,7 @@ before_script:
# We need the official upstream for comparison
git remote add upstream https://github.com/moodle/moodle.git;
git fetch upstream master;
git fetch upstream MOODLE_400_STABLE;
export GIT_PREVIOUS_COMMIT="`git merge-base FETCH_HEAD $TRAVIS_COMMIT`";
export GIT_COMMIT="$TRAVIS_COMMIT";
export UPSTREAM_FETCH_HEAD=`git rev-parse FETCH_HEAD`
+3 -3
View File
@@ -28,7 +28,7 @@ if (empty($CFG->auth)) {
}
if (!empty($auth) and !exists_auth_plugin($auth)) {
throw new \moodle_exception('pluginnotinstalled', 'auth', $returnurl, $auth);
print_error('pluginnotinstalled', 'auth', $returnurl, $auth);
}
////////////////////////////////////////////////////////////////////////////////
@@ -55,7 +55,7 @@ switch ($action) {
$key = array_search($auth, $authsenabled);
// check auth plugin is valid
if ($key === false) {
throw new \moodle_exception('pluginnotenabled', 'auth', $returnurl, $auth);
print_error('pluginnotenabled', 'auth', $returnurl, $auth);
}
// move down the list
if ($key < (count($authsenabled) - 1)) {
@@ -72,7 +72,7 @@ switch ($action) {
$key = array_search($auth, $authsenabled);
// check auth is valid
if ($key === false) {
throw new \moodle_exception('pluginnotenabled', 'auth', $returnurl, $auth);
print_error('pluginnotenabled', 'auth', $returnurl, $auth);
}
// move up the list
if ($key >= 1) {
+1 -1
View File
@@ -75,7 +75,7 @@
/// Get and sort the existing blocks
if (!$blocks = $DB->get_records('block', array(), 'name ASC')) {
throw new \moodle_exception('noblocks', 'error'); // Should never happen.
print_error('noblocks', 'error'); // Should never happen
}
$incompatible = array();
+2 -2
View File
@@ -41,11 +41,11 @@ $adminroot = admin_get_root(); // need all settings
$settingspage = $adminroot->locate($category, true);
if (empty($settingspage) or !($settingspage instanceof admin_category)) {
throw new \moodle_exception('categoryerror', 'error', "$CFG->wwwroot/$CFG->admin/");
print_error('categoryerror', 'admin', "$CFG->wwwroot/$CFG->admin/");
}
if (!($settingspage->check_access())) {
throw new \moodle_exception('accessdenied', 'admin');
print_error('accessdenied', 'admin');
}
$hassiteconfig = has_capability('moodle/site:config', $PAGE->context);
@@ -14,21 +14,18 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\reportbuilder\local\entities;
namespace core_admin\local\entities;
use core_reportbuilder\local\filters\date;
use core_reportbuilder\local\filters\duration;
use core_reportbuilder\local\filters\number;
use core_reportbuilder\local\filters\select;
use core_reportbuilder\local\filters\text;
use core_reportbuilder\local\filters\autocomplete;
use core_reportbuilder\local\helpers\format;
use lang_string;
use core_reportbuilder\local\entities\base;
use core_reportbuilder\local\report\column;
use core_reportbuilder\local\report\filter;
use stdClass;
use core_collator;
/**
* Task log entity class implementation
@@ -63,6 +60,15 @@ class task_log extends base {
return new lang_string('entitytasklog', 'admin');
}
/**
* The default machine-readable name for this entity that will be used in the internal names of the columns/filters
*
* @return string
*/
protected function get_default_entity_name(): string {
return 'task_log';
}
/**
* Initialise the entity
*
@@ -74,12 +80,9 @@ class task_log extends base {
$this->add_column($column);
}
// All the filters defined by the entity can also be used as conditions.
$filters = $this->get_all_filters();
foreach ($filters as $filter) {
$this
->add_filter($filter)
->add_condition($filter);
$this->add_filter($filter);
}
return $this;
@@ -91,7 +94,6 @@ class task_log extends base {
* @return column[]
*/
protected function get_all_columns(): array {
global $DB;
$tablealias = $this->get_table_alias('task_log');
@@ -105,31 +107,20 @@ class task_log extends base {
->set_type(column::TYPE_TEXT)
->add_field("$tablealias.classname")
->set_is_sortable(true)
->add_callback(static function(string $classname): string {
->add_callback(static function(string $value): string {
$output = '';
if (class_exists($classname)) {
$task = new $classname;
if ($task instanceof \core\task\task_base) {
if (class_exists($value)) {
$task = new $value;
if ($task instanceof \core\task\scheduled_task) {
$output = $task->get_name();
}
}
$output .= \html_writer::tag('div', "\\{$classname}", [
'class' => 'small text-muted',
$output .= \html_writer::tag('div', "\\{$value}", [
'class' => 'task-class',
]);
return $output;
});
// Component column.
$columns[] = (new column(
'component',
new lang_string('plugin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("{$tablealias}.component")
->set_is_sortable(true);
// Type column.
$columns[] = (new column(
'type',
@@ -137,11 +128,11 @@ class task_log extends base {
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->set_type(column::TYPE_INTEGER)
->add_field("{$tablealias}.type")
->set_is_sortable(true)
->add_callback(static function($value): string {
if (\core\task\database_logger::TYPE_SCHEDULED === (int) $value) {
->add_callback(static function(int $value): string {
if (\core\task\database_logger::TYPE_SCHEDULED === $value) {
return get_string('task_type:scheduled', 'admin');
}
return get_string('task_type:adhoc', 'admin');
@@ -159,18 +150,6 @@ class task_log extends base {
->set_is_sortable(true)
->add_callback([format::class, 'userdate'], get_string('strftimedatetimeshortaccurate', 'core_langconfig'));
// End time column.
$columns[] = (new column(
'endtime',
new lang_string('task_endtime', 'admin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TIMESTAMP)
->add_field("{$tablealias}.timeend")
->set_is_sortable(true)
->add_callback([format::class, 'userdate'], get_string('strftimedatetimeshortaccurate', 'core_langconfig'));
// Duration column.
$columns[] = (new column(
'duration',
@@ -211,9 +190,7 @@ class task_log extends base {
->add_joins($this->get_joins())
->set_type(column::TYPE_INTEGER)
->add_field("{$tablealias}.pid")
->set_is_sortable(true)
// Although this is an integer column, it doesn't make sense to perform numeric aggregation on it.
->set_disabled_aggregation(['avg', 'count', 'countdistinct', 'max', 'min', 'sum']);
->set_is_sortable(true);
// Database column.
$columns[] = (new column(
@@ -224,37 +201,13 @@ class task_log extends base {
->add_joins($this->get_joins())
->set_type(column::TYPE_INTEGER)
->add_fields("{$tablealias}.dbreads, {$tablealias}.dbwrites")
->set_is_sortable(true, ["{$tablealias}.dbreads", "{$tablealias}.dbwrites"])
->set_is_sortable(true)
->add_callback(static function(int $value, stdClass $row): string {
$output = '';
$output .= \html_writer::div(get_string('task_stats:dbreads', 'admin', $row->dbreads));
$output .= \html_writer::div(get_string('task_stats:dbwrites', 'admin', $row->dbwrites));
return $output;
})
// Although this is an integer column, it doesn't make sense to perform numeric aggregation on it.
->set_disabled_aggregation(['avg', 'count', 'countdistinct', 'max', 'min', 'sum']);
// Database reads column.
$columns[] = (new column(
'dbreads',
new lang_string('task_dbreads', 'admin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_INTEGER)
->add_fields("{$tablealias}.dbreads")
->set_is_sortable(true);
// Database writes column.
$columns[] = (new column(
'dbwrites',
new lang_string('task_dbwrites', 'admin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_INTEGER)
->add_fields("{$tablealias}.dbwrites")
->set_is_sortable(true);
});
// Result column.
$columns[] = (new column(
@@ -263,12 +216,11 @@ class task_log extends base {
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_BOOLEAN)
// For accurate aggregation, we need to return boolean success = true by xor'ing the field value.
->add_field($DB->sql_bitxor("{$tablealias}.result", 1), 'success')
->set_type(column::TYPE_INTEGER)
->add_field("$tablealias.result")
->set_is_sortable(true)
->add_callback(static function(bool $success): string {
if (!$success) {
->add_callback(static function(int $value): string {
if ($value) {
return get_string('task_result:failed', 'admin');
}
return get_string('success');
@@ -283,128 +235,27 @@ class task_log extends base {
* @return filter[]
*/
protected function get_all_filters(): array {
global $DB;
$filters = [];
$tablealias = $this->get_table_alias('task_log');
// Name filter (Filter by classname).
$filters[] = (new filter(
autocomplete::class,
text::class,
'name',
new lang_string('classname', 'tool_task'),
$this->get_entity_name(),
"{$tablealias}.classname"
))
->add_joins($this->get_joins())
->set_options_callback(static function(): array {
global $DB;
$classnames = $DB->get_fieldset_sql('SELECT DISTINCT classname FROM {task_log} ORDER BY classname ASC');
$options = [];
foreach ($classnames as $classname) {
if (class_exists($classname)) {
$task = new $classname;
$options[$classname] = $task->get_name();
}
}
core_collator::asort($options);
return $options;
});
// Component filter.
$filters[] = (new filter(
text::class,
'component',
new lang_string('plugin'),
$this->get_entity_name(),
"{$tablealias}.component"
))
->add_joins($this->get_joins());
// Type filter.
$filters[] = (new filter(
select::class,
'type',
new lang_string('tasktype', 'admin'),
$this->get_entity_name(),
"{$tablealias}.type"
))
->add_joins($this->get_joins())
->set_options([
\core\task\database_logger::TYPE_ADHOC => new lang_string('task_type:adhoc', 'admin'),
\core\task\database_logger::TYPE_SCHEDULED => new lang_string('task_type:scheduled', 'admin'),
]);
// Output filter (Filter by task output).
$filters[] = (new filter(
text::class,
'output',
new lang_string('task_logoutput', 'admin'),
$this->get_entity_name(),
$DB->sql_cast_to_char("{$tablealias}.output")
))
->add_joins($this->get_joins());
// Start time filter.
$filters[] = (new filter(
date::class,
'timestart',
new lang_string('task_starttime', 'admin'),
$this->get_entity_name(),
"{$tablealias}.timestart"
))
->add_joins($this->get_joins())
->set_limited_operators([
date::DATE_ANY,
date::DATE_RANGE,
date::DATE_PREVIOUS,
date::DATE_CURRENT,
]);
// End time.
$filters[] = (new filter(
date::class,
'timeend',
new lang_string('task_endtime', 'admin'),
$this->get_entity_name(),
"{$tablealias}.timeend"
))
->add_joins($this->get_joins())
->set_limited_operators([
date::DATE_ANY,
date::DATE_RANGE,
date::DATE_PREVIOUS,
date::DATE_CURRENT,
]);
// Duration filter.
$filters[] = (new filter(
duration::class,
'duration',
new lang_string('task_duration', 'admin'),
$this->get_entity_name(),
"{$tablealias}.timeend - {$tablealias}.timestart"
))
->add_joins($this->get_joins());
// Database reads.
$filters[] = (new filter(
number::class,
'dbreads',
new lang_string('task_dbreads', 'admin'),
$this->get_entity_name(),
"{$tablealias}.dbreads"
))
->add_joins($this->get_joins());
// Database writes.
$filters[] = (new filter(
number::class,
'dbwrites',
new lang_string('task_dbwrites', 'admin'),
$this->get_entity_name(),
"{$tablealias}.dbwrites"
"{$tablealias}.output"
))
->add_joins($this->get_joins());
@@ -422,6 +273,32 @@ class task_log extends base {
self::FAILED => get_string('task_result:failed', 'admin'),
]);
// Start time filter.
$filters[] = (new filter(
date::class,
'timestart',
new lang_string('task_starttime', 'admin'),
$this->get_entity_name(),
"{$tablealias}.timestart"
))
->add_joins($this->get_joins())
->set_limited_operators([
date::DATE_ANY,
date::DATE_RANGE,
date::DATE_PREVIOUS,
date::DATE_CURRENT,
]);
// Duration filter.
$filters[] = (new filter(
duration::class,
'duration',
new lang_string('task_duration', 'admin'),
$this->get_entity_name(),
"${tablealias}.timeend - {$tablealias}.timestart"
))
->add_joins($this->get_joins());
return $filters;
}
}
@@ -14,10 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\reportbuilder\local\systemreports;
namespace core_admin\local\systemreports;
use context_system;
use core_admin\reportbuilder\local\entities\task_log;
use core_admin\local\entities\task_log;
use core_reportbuilder\local\entities\user;
use core_reportbuilder\local\report\action;
use lang_string;
@@ -121,7 +121,6 @@ class task_logs extends system_report {
protected function add_filters(): void {
$filters = [
'task_log:name',
'task_log:type',
'task_log:output',
'task_log:result',
'task_log:timestart',
@@ -1,117 +0,0 @@
<?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/>.
declare(strict_types=1);
namespace core_admin\reportbuilder\datasource;
use core_admin\reportbuilder\local\entities\task_log;
use core_reportbuilder\datasource;
use core_reportbuilder\local\entities\user;
use core_reportbuilder\local\filters\select;
/**
* Task logs datasource
*
* @package core_admin
* @copyright 2022 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class task_logs extends datasource {
/**
* Return user friendly name of the report source
*
* @return string
*/
public static function get_name(): string {
return get_string('tasklogs', 'core_admin');
}
/**
* Initialise report
*/
protected function initialise(): void {
$tasklogentity = new task_log();
$tasklogalias = $tasklogentity->get_table_alias('task_log');
$this->set_main_table('task_log', $tasklogalias);
$this->add_entity($tasklogentity);
// Join the user entity to represent the associated user.
$userentity = new user();
$useralias = $userentity->get_table_alias('user');
$this->add_entity($userentity->add_join("
LEFT JOIN {user} {$useralias}
ON {$useralias}.id = {$tasklogalias}.userid")
);
// Add report elements from each of the entities we added to the report.
$this->add_all_from_entities();
}
/**
* Return the columns that will be added to the report upon creation
*
* @return string[]
*/
public function get_default_columns(): array {
return [
'task_log:name',
'task_log:starttime',
'task_log:duration',
'task_log:result',
];
}
/**
* Return the filters that will be added to the report upon creation
*
* @return string[]
*/
public function get_default_filters(): array {
return [
'task_log:timestart',
'task_log:result',
];
}
/**
* Return the conditions that will be added to the report upon creation
*
* @return string[]
*/
public function get_default_conditions(): array {
return [
'task_log:type',
'task_log:timestart',
'task_log:result',
];
}
/**
* Return the condition values that will be set for the report upon creation
*
* @return array
*/
public function get_default_condition_values(): array {
return [
'task_log:type_operator' => select::EQUAL_TO,
'task_log:type_value' => \core\task\database_logger::TYPE_SCHEDULED,
];
}
}
-124
View File
@@ -1,124 +0,0 @@
<?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/>.
/**
* CLI script to delete a course.
*
* @package core
* @subpackage cli
* @author Mikhail Golenkov <mikhailgolenkov@catalyst-au.net>
* @copyright 2022 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/clilib.php');
require_once($CFG->libdir . '/cronlib.php');
list($options, $unrecognized) = cli_get_params(
[
'courseid' => false,
'help' => false,
'showsql' => false,
'showdebugging' => false,
'disablerecyclebin' => false,
'non-interactive' => false,
], [
'c' => 'courseid',
'h' => 'help',
]
);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
if ($options['help'] || empty($options['courseid'])) {
$help = <<<EOT
CLI script to delete a course.
Options:
-h, --help Print out this help
--showsql Show sql queries before they are executed
--showdebugging Show developer level debugging information
--disablerecyclebin Skip backing up the course
--non-interactive No interactive questions or confirmations
-c, --courseid Course id to be deleted
Example:
\$sudo -u www-data /usr/bin/php admin/cli/delete_course.php --courseid=123456
\$sudo -u www-data /usr/bin/php admin/cli/delete_course.php --courseid=123456 --showdebugging
\$sudo -u www-data /usr/bin/php admin/cli/delete_course.php --courseid=123456 --disablerecyclebin
EOT;
echo $help;
die;
}
$interactive = empty($options['non-interactive']);
if ($options['showdebugging']) {
mtrace('Enabling debugging...');
set_debugging(DEBUG_DEVELOPER, true);
}
if ($options['showsql']) {
mtrace('Enabling SQL debugging...');
$DB->set_debug(true);
}
if (CLI_MAINTENANCE) {
cli_error('CLI maintenance mode active, CLI execution suspended');
}
if (moodle_needs_upgrading()) {
cli_error('Moodle upgrade pending, CLI execution suspended');
}
$course = $DB->get_record('course', array('id' => $options['courseid']));
if (empty($course)) {
cli_error('Course not found');
}
mtrace('Deleting course id ' . $course->id);
mtrace('Course name: ' . $course->fullname);
mtrace('Short name: ' . $course->shortname);
if ($interactive) {
mtrace('');
$input = cli_input('Are you sure you wish to delete this course? (y/N)', 'N', ['y', 'Y', 'n', 'N']);
if (strtolower($input) != 'y') {
exit(0);
}
}
if ($options['disablerecyclebin']) {
mtrace('Disabling recycle bin...');
$overrideconfig = ['tool_recyclebin' => ['coursebinenable' => false, 'categorybinenable' => false]];
$CFG->forced_plugin_settings = array_merge($CFG->forced_plugin_settings, $overrideconfig);
}
core_php_time_limit::raise();
delete_course($course);
mtrace('Updating course count in categories...');
fix_course_sortorder();
mtrace('Done!');
+4 -4
View File
@@ -69,15 +69,15 @@ if ($options['showdebugging']) {
}
if (!$admin = get_admin()) {
throw new \moodle_exception('noadmins');
print_error('noadmins');
}
if (!file_exists($options['file'])) {
throw new \moodle_exception('filenotfound');
print_error('filenotfound');
}
if (!$category = $DB->get_record('course_categories', ['id' => $options['categoryid']], 'id')) {
throw new \moodle_exception('invalidcategoryid');
print_error('invalidcategoryid');
}
$backupdir = "restore_" . uniqid();
@@ -102,7 +102,7 @@ try {
} catch (Exception $e) {
cli_heading(get_string('cleaningtempdata'));
fulldelete($path);
throw new \moodle_exception('generalexceptionmessage', 'error', '', $e->getMessage());
print_error('generalexceptionmessage', 'error', '', $e->getMessage());
}
cli_heading(get_string('restoredcourseid', 'backup', $courseid));
+2 -2
View File
@@ -69,11 +69,11 @@ if ($options['help'] or (!$options['list'] and !$options['execute'])) {
die;
}
if ($options['showdebugging'] || !empty($CFG->showcrondebugging)) {
if ($options['showdebugging']) {
set_debugging(DEBUG_DEVELOPER, true);
}
if ($options['showsql'] || !empty($CFG->showcronsql)) {
if ($options['showsql']) {
$DB->set_debug(true);
}
if ($options['list']) {
+1 -1
View File
@@ -42,7 +42,7 @@ $plugins = core_plugin_manager::instance()->get_plugins_of_type('contenttype');
$sortorder = array_flip(array_keys($plugins));
if (!isset($plugins[$name])) {
throw new \moodle_exception('contenttypenotfound', 'error', $return, $name);
print_error('contenttypenotfound', 'error', $return, $name);
}
switch ($action) {
+1 -1
View File
@@ -41,7 +41,7 @@ $formatplugins = core_plugin_manager::instance()->get_plugins_of_type('format');
$sortorder = array_flip(array_keys($formatplugins));
if (!isset($formatplugins[$formatname])) {
throw new \moodle_exception('courseformatnotfound', 'error', $return, $formatname);
print_error('courseformatnotfound', 'error', $return, $formatname);
}
switch ($action) {
+2 -2
View File
@@ -58,7 +58,7 @@ require_once($CFG->libdir.'/cronlib.php');
// check if execution allowed
if (!empty($CFG->cronclionly)) {
// This script can only be run via the cli.
throw new \moodle_exception('cronerrorclionly', 'admin');
print_error('cronerrorclionly', 'admin');
exit;
}
// This script is being called via the web, so check the password if there is one.
@@ -66,7 +66,7 @@ if (!empty($CFG->cronremotepassword)) {
$pass = optional_param('password', '', PARAM_RAW);
if ($pass != $CFG->cronremotepassword) {
// wrong password.
throw new \moodle_exception('cronerrorpassword', 'admin');
print_error('cronerrorpassword', 'admin');
exit;
}
}
+1 -1
View File
@@ -41,7 +41,7 @@ $customfieldplugins = core_plugin_manager::instance()->get_plugins_of_type('cust
$sortorder = array_flip(array_keys($customfieldplugins));
if (!isset($customfieldplugins[$customfieldname])) {
throw new \moodle_exception('customfieldnotfound', 'error', $return, $customfieldname);
print_error('customfieldnotfound', 'error', $return, $customfieldname);
}
switch ($action) {
+1 -1
View File
@@ -42,7 +42,7 @@ $plugins = core_plugin_manager::instance()->get_plugins_of_type('dataformat');
$sortorder = array_flip(array_keys($plugins));
if (!isset($plugins[$name])) {
throw new \moodle_exception('courseformatnotfound', 'error', $return, $name);
print_error('courseformatnotfound', 'error', $return, $name);
}
switch ($action) {
+2 -2
View File
@@ -55,11 +55,11 @@ if ($action == 'updatecomponent' && confirm_sesskey()) {
$a = new stdClass();
$a->url = 'https://download.moodle.org/environment/environment.zip';
$a->dest = $CFG->dataroot . '/';
throw new \moodle_exception($cd->get_error(), 'error', $PAGE->url, $a);
print_error($cd->get_error(), 'error', $PAGE->url, $a);
die();
} else {
throw new \moodle_exception($cd->get_error(), 'error', $PAGE->url);
print_error($cd->get_error(), 'error', $PAGE->url);
die();
}
-189
View File
@@ -3539,8 +3539,6 @@
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_max_input_vars" level="optional">
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_xmlrpc_usage" level="optional">
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
<MOODLE version="4.0" requires="3.6">
@@ -3735,191 +3733,4 @@
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
<MOODLE version="4.1" requires="3.9">
<UNICODE level="required">
<FEEDBACK>
<ON_ERROR message="unicoderequired" />
</FEEDBACK>
</UNICODE>
<DATABASE level="required">
<VENDOR name="mariadb" version="10.4" />
<VENDOR name="mysql" version="5.7" />
<VENDOR name="postgres" version="12" />
<VENDOR name="mssql" version="14.0" />
<VENDOR name="oracle" version="19" />
</DATABASE>
<PHP version="7.4.0" level="required">
</PHP>
<PCREUNICODE level="optional">
<FEEDBACK>
<ON_CHECK message="pcreunicodewarning" />
</FEEDBACK>
</PCREUNICODE>
<PHP_EXTENSIONS>
<PHP_EXTENSION name="iconv" level="required">
<FEEDBACK>
<ON_ERROR message="iconvrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="mbstring" level="required">
<FEEDBACK>
<ON_ERROR message="mbstringrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="curl" level="required">
<FEEDBACK>
<ON_ERROR message="curlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="openssl" level="required">
<FEEDBACK>
<ON_ERROR message="opensslrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="tokenizer" level="optional">
<FEEDBACK>
<ON_CHECK message="tokenizerrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="soap" level="optional">
<FEEDBACK>
<ON_CHECK message="soaprecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="ctype" level="required">
<FEEDBACK>
<ON_ERROR message="ctyperequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="zip" level="required">
<FEEDBACK>
<ON_ERROR message="ziprequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="zlib" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="gd" level="required">
<FEEDBACK>
<ON_ERROR message="gdrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="simplexml" level="required">
<FEEDBACK>
<ON_ERROR message="simplexmlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="spl" level="required">
<FEEDBACK>
<ON_ERROR message="splrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="pcre" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="dom" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="xml" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="xmlreader" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="intl" level="required">
<FEEDBACK>
<ON_ERROR message="intlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="json" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="hash" level="required"/>
<PHP_EXTENSION name="fileinfo" level="required"/>
<PHP_EXTENSION name="sodium" level="optional"/>
<PHP_EXTENSION name="exif" level="optional"/>
</PHP_EXTENSIONS>
<PHP_SETTINGS>
<PHP_SETTING name="memory_limit" value="96M" level="required">
<FEEDBACK>
<ON_ERROR message="settingmemorylimit" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="file_uploads" value="1" level="optional">
<FEEDBACK>
<ON_CHECK message="settingfileuploads" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="opcache.enable" value="1" level="optional">
<FEEDBACK>
<ON_CHECK message="opcacherecommended" />
</FEEDBACK>
</PHP_SETTING>
</PHP_SETTINGS>
<CUSTOM_CHECKS>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_storage_engine" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbstorageengine" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="question/engine/upgrade/upgradelib.php" function="quiz_attempts_upgraded" level="required">
<FEEDBACK>
<ON_ERROR message="quizattemptsupgradedmessage" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_slasharguments" level="optional">
<FEEDBACK>
<ON_CHECK message="slashargumentswarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_tables_row_format" level="optional">
<FEEDBACK>
<ON_CHECK message="unsupporteddbtablerowformat" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_unoconv_version" level="optional">
<FEEDBACK>
<ON_CHECK message="unoconvwarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
<FEEDBACK>
<ON_CHECK message="libcurlwarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_format" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbfileformat" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_per_table" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbfilepertable" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_large_prefix" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddblargeprefix" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_is_https" level="optional">
<FEEDBACK>
<ON_CHECK message="ishttpswarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_incomplete_unicode_support" level="optional">
<FEEDBACK>
<ON_CHECK message="incompleteunicodesupport" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_sixtyfour_bits" level="optional">
<FEEDBACK>
<ON_CHECK message="sixtyfourbitswarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_max_input_vars" level="optional">
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_admin_dir_usage" level="optional">
<FEEDBACK>
<ON_CHECK message="iscustomadminwarnings" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_xmlrpc_usage" level="optional">
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
</COMPATIBILITY_MATRIX>
+8 -10
View File
@@ -174,17 +174,15 @@ $documentationlink = '<a href="http://docs.moodle.org/en/Installation">Installat
// Check some PHP server settings
if (ini_get_bool('session.auto_start')) {
throw new \moodle_exception('phpvaroff', 'debug', '',
(object)array('name' => 'session.auto_start', 'link' => $documentationlink));
print_error('phpvaroff', 'debug', '', (object)array('name'=>'session.auto_start', 'link'=>$documentationlink));
}
if (!ini_get_bool('file_uploads')) {
throw new \moodle_exception('phpvaron', 'debug', '',
(object)array('name' => 'file_uploads', 'link' => $documentationlink));
print_error('phpvaron', 'debug', '', (object)array('name'=>'file_uploads', 'link'=>$documentationlink));
}
if (is_float_problem()) {
throw new \moodle_exception('phpfloatproblem', 'admin', '', $documentationlink);
print_error('phpfloatproblem', 'admin', '', $documentationlink);
}
// Set some necessary variables during set-up to avoid PHP warnings later on this page
@@ -205,7 +203,7 @@ require("$CFG->dirroot/version.php"); // defines $version, $release, $bran
$CFG->target_release = $release; // used during installation and upgrades
if (!$version or !$release) {
throw new \moodle_exception('withoutversion', 'debug'); // Without version, stop.
print_error('withoutversion', 'debug'); // without version, stop
}
if (!core_tables_exist()) {
@@ -277,7 +275,7 @@ if (!core_tables_exist()) {
if (!$DB->setup_is_unicodedb()) {
if (!$DB->change_db_encoding()) {
// If could not convert successfully, throw error, and prevent installation
throw new \moodle_exception('unicoderequired', 'admin');
print_error('unicoderequired', 'admin');
}
}
@@ -299,7 +297,7 @@ $stradministration = get_string('administration');
$PAGE->set_context(context_system::instance());
if (empty($CFG->version)) {
throw new \moodle_exception('missingconfigversion', 'debug');
print_error('missingconfigversion', 'debug');
}
// Detect config cache inconsistency, this happens when you switch branches on dev servers.
@@ -750,7 +748,7 @@ if (during_initial_install()) {
redirect("index.php?sessionstarted=1&sessionverify=1&lang=$CFG->lang");
} else {
if (empty($SESSION->sessionverify)) {
throw new \moodle_exception('installsessionerror', 'admin', "index.php?sessionstarted=1&lang=$CFG->lang");
print_error('installsessionerror', 'admin', "index.php?sessionstarted=1&lang=$CFG->lang");
}
unset($SESSION->sessionverify);
}
@@ -767,7 +765,7 @@ if (during_initial_install()) {
if ($adminuser->password === 'adminsetuppending') {
// prevent installation hijacking
if ($adminuser->lastip !== getremoteaddr()) {
throw new \moodle_exception('installhijacked', 'admin');
print_error('installhijacked', 'admin');
}
// login user and let him set password and admin details
$adminuser->newadminuser = 1;
+1 -1
View File
@@ -55,7 +55,7 @@ function admin_page_type_list($pagetype, $parentcontext, $currentcontext) {
function core_admin_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) {
global $CFG;
if (in_array($filearea, ['logo', 'logocompact', 'favicon'])) {
if (in_array($filearea, ['logo', 'logocompact'])) {
$size = array_shift($args); // The path hides the size.
$itemid = clean_param(array_shift($args), PARAM_INT);
$filename = clean_param(array_shift($args), PARAM_FILE);
+7 -6
View File
@@ -15,7 +15,7 @@ $action = trim(strtolower(optional_param('action', '', PARAM_ALPHA)));
admin_externalpage_setup('ssoaccesscontrol');
if (!extension_loaded('openssl')) {
throw new \moodle_exception('requiresopenssl', 'mnet');
print_error('requiresopenssl', 'mnet');
}
$sitecontext = context_system::instance();
@@ -35,13 +35,13 @@ if (!empty($action) and confirm_sesskey()) {
// boot if insufficient permission
if (!has_capability('moodle/user:delete', $sitecontext)) {
throw new \moodle_exception('nomodifyacl', 'mnet');
print_error('nomodifyacl','mnet');
}
// fetch the record in question
$id = required_param('id', PARAM_INT);
if (!$idrec = $DB->get_record('mnet_sso_access_control', array('id'=>$id))) {
throw new \moodle_exception('recordnoexists', 'mnet', "$CFG->wwwroot/$CFG->admin/mnet/access_control.php");
print_error('recordnoexists','mnet', "$CFG->wwwroot/$CFG->admin/mnet/access_control.php");
}
switch ($action) {
@@ -56,7 +56,7 @@ if (!empty($action) and confirm_sesskey()) {
// require the access parameter, and it must be 'allow' or 'deny'
$accessctrl = trim(strtolower(required_param('accessctrl', PARAM_ALPHA)));
if ($accessctrl != 'allow' and $accessctrl != 'deny') {
throw new \moodle_exception('invalidaccessparam', 'mnet', "$CFG->wwwroot/$CFG->admin/mnet/access_control.php");
print_error('invalidaccessparam', 'mnet', "$CFG->wwwroot/$CFG->admin/mnet/access_control.php");
}
if (mnet_update_sso_access_control($idrec->username, $idrec->mnet_host_id, $accessctrl)) {
@@ -71,7 +71,7 @@ if (!empty($action) and confirm_sesskey()) {
break;
default:
throw new \moodle_exception('invalidactionparam', 'mnet', "$CFG->wwwroot/$CFG->admin/mnet/access_control.php");
print_error('invalidactionparam', 'mnet', "$CFG->wwwroot/$CFG->admin/mnet/access_control.php");
}
}
@@ -82,7 +82,7 @@ if ($form = data_submitted() and confirm_sesskey()) {
// check permissions and verify form input
if (!has_capability('moodle/user:delete', $sitecontext)) {
throw new \moodle_exception('nomodifyacl', 'mnet', "$CFG->wwwroot/$CFG->admin/mnet/access_control.php");
print_error('nomodifyacl','mnet', "$CFG->wwwroot/$CFG->admin/mnet/access_control.php");
}
if (empty($form->username)) {
$formerror['username'] = get_string('enterausername','mnet');
@@ -117,6 +117,7 @@ if ($form = data_submitted() and confirm_sesskey()) {
}
echo $OUTPUT->header();
echo $OUTPUT->render(mnet_get_deprecation_notice());
// Explain
echo $OUTPUT->box(get_string('ssoacldescr','mnet'));
+6 -5
View File
@@ -17,13 +17,13 @@
if (!extension_loaded('openssl')) {
echo $OUTPUT->header();
set_config('mnet_dispatcher_mode', 'off');
throw new \moodle_exception('requiresopenssl', 'mnet');
print_error('requiresopenssl', 'mnet');
}
if (!function_exists('curl_init') ) {
echo $OUTPUT->header();
set_config('mnet_dispatcher_mode', 'off');
throw new \moodle_exception('nocurl', 'mnet');
print_error('nocurl', 'mnet');
}
if (!isset($CFG->mnet_dispatcher_mode)) {
@@ -37,7 +37,7 @@
if (set_config('mnet_dispatcher_mode', $form->mode)) {
redirect('index.php', get_string('changessaved'));
} else {
throw new \moodle_exception('invalidaction', '', 'index.php');
print_error('invalidaction', '', 'index.php');
}
}
} elseif (!empty($form->submit) && $form->submit == get_string('delete')) {
@@ -63,13 +63,13 @@
if($time < time() - 60) {
// fail - you're out of time.
throw new \moodle_exception ('deleteoutoftime', 'mnet', 'index.php');
print_error ('deleteoutoftime', 'mnet', 'index.php');
exit;
}
if ($key != md5(sha1($mnet->keypair['keypair_PEM']))) {
// fail - you're being attacked?
throw new \moodle_exception ('deletewrongkeyvalue', 'mnet', 'index.php');
print_error ('deletewrongkeyvalue', 'mnet', 'index.php');
exit;
}
@@ -81,6 +81,7 @@
$hosts = $DB->get_records_select('mnet_host', "id <> ? AND deleted = 0", array($CFG->mnet_localhost_id), 'wwwroot ASC');
echo $OUTPUT->header();
echo $OUTPUT->render(mnet_get_deprecation_notice());
?>
<form method="post" action="index.php">
<table align="center" width="635" class="generaltable" border="0" cellpadding="5" cellspacing="0">
+3 -2
View File
@@ -59,8 +59,9 @@ class mnet_simple_host_form extends moodleform {
$wwwroot = 'http://'.$wwwroot;
}
if ($host = $DB->get_record('mnet_host', array('wwwroot' => $wwwroot))) {
$str = get_string('hostexists', 'mnet', (new moodle_url('/admin/mnet/peers.php', ['hostid' => $host->id]))->out());
return array('wwwroot' => $str);
global $CFG;
return array('wwwroot' => get_string('hostexists', 'mnet',
new moodle_url('/admin/mnet/peers.php', array('hostid' => $host->id))));
}
return array();
}
+12 -3
View File
@@ -51,12 +51,18 @@ if ($hostid && $DB->get_field('mnet_host', 'deleted', array('id' => $hostid)) !=
$PAGE->set_url('/admin/mnet/peers.php');
admin_externalpage_setup($adminsection);
$deprecatenotify = mnet_get_deprecation_notice();
if (!extension_loaded('openssl')) {
throw new \moodle_exception('requiresopenssl', 'mnet');
print_error('requiresopenssl', 'mnet');
}
if (!function_exists('curl_init') ) {
throw new \moodle_exception('nocurl', 'mnet');
print_error('nocurl', 'mnet');
}
if (!function_exists('xmlrpc_encode_request')) {
print_error('xmlrpc-missing', 'mnet');
}
if (!isset($CFG->mnet_dispatcher_mode)) {
@@ -86,6 +92,7 @@ if ($formdata = $simpleform->get_data()) {
$formdata->oldpublickey = $mnet_peer->public_key; // set this so we can confirm on form post without having to recreate the mnet_peer object
$reviewform->set_data($mnet_peer);
echo $OUTPUT->header();
echo $OUTPUT->render($deprecatenotify);
echo $OUTPUT->box_start();
$reviewform->display();
echo $OUTPUT->box_end();
@@ -169,10 +176,11 @@ if ($formdata = $reviewform->get_data()) {
if ($mnet_peer->commit()) {
redirect(new moodle_url('/admin/mnet/peers.php', array('hostid' => $mnet_peer->id)), get_string('changessaved'));
} else {
throw new \moodle_exception('invalidaction', 'error', 'index.php');
print_error('invalidaction', 'error', 'index.php');
}
} else if ($reviewform->is_submitted()) { // submitted, but errors
echo $OUTPUT->header();
echo $OUTPUT->render($deprecatenotify);
echo $OUTPUT->box_start();
$reviewform->display();
echo $OUTPUT->box_end();
@@ -183,6 +191,7 @@ if ($formdata = $reviewform->get_data()) {
// normal flow - just display all hosts with links
echo $OUTPUT->header();
echo $OUTPUT->render($deprecatenotify);
$hosts = mnet_get_hosts(true);
// print the table to display the register all hosts setting
+1
View File
@@ -44,4 +44,5 @@ if (isset($mnet_peer->id) && $mnet_peer->id > 0) {
} else {
$tabs[] = new tabobject('mnetdetails', '#', $strmnetedithost, $strmnetedithost, false);
}
echo $OUTPUT->render(mnet_get_deprecation_notice());
print_tabs(array($tabs), $currenttab);
+2 -2
View File
@@ -18,7 +18,7 @@ require_once($CFG->libdir.'/adminlib.php');
include_once($CFG->dirroot.'/mnet/lib.php');
if ($CFG->mnet_dispatcher_mode === 'off') {
throw new \moodle_exception('mnetdisabled', 'mnet');
print_error('mnetdisabled', 'mnet');
}
admin_externalpage_setup('mnettestclient');
@@ -27,7 +27,7 @@ error_reporting(DEBUG_ALL);
echo $OUTPUT->header();
if (!extension_loaded('openssl')) {
throw new \moodle_exception('requiresopenssl', 'mnet', '', null, true);
print_error('requiresopenssl', 'mnet', '', NULL, true);
}
// optional drilling down parameters
+1
View File
@@ -1,5 +1,6 @@
<?php
echo $OUTPUT->header();
echo $OUTPUT->render(mnet_get_deprecation_notice());
?>
<div id="trustedhosts"><!-- See theme/standard/styles_layout.css #trustedhosts .generaltable for rules -->
<table cellspacing="0" cellpadding="5" class="generaltable generalbox" >
+1 -1
View File
@@ -10,7 +10,7 @@
if (!extension_loaded('openssl')) {
echo $OUTPUT->header();
throw new \moodle_exception('requiresopenssl', 'mnet', '', null, true);
print_error('requiresopenssl', 'mnet', '', NULL, true);
}
$site = get_site();
+1 -1
View File
@@ -62,7 +62,7 @@
/// Get and sort the existing modules
if (!$modules = $DB->get_records('modules', array(), 'name ASC')) {
throw new \moodle_exception('moduledoesnotexist', 'error');
print_error('moduledoesnotexist', 'error');
}
/// Print the table of all modules
+2 -2
View File
@@ -116,13 +116,13 @@ if (($action == 'edit') || ($action == 'new')) {
$instance = portfolio_instance($portfolio);
if ($sure) {
if (!confirm_sesskey()) {
throw new \moodle_exception('confirmsesskeybad', '', $baseurl);
print_error('confirmsesskeybad', '', $baseurl);
}
if ($instance->delete()) {
$deletedstr = get_string('instancedeleted', 'portfolio');
redirect($baseurl, $deletedstr, 1);
} else {
throw new \moodle_exception('instancenotdeleted', 'portfolio', $baseurl);
print_error('instancenotdeleted', 'portfolio', $baseurl);
}
exit;
} else {
+5 -5
View File
@@ -84,7 +84,7 @@ if (!empty($config->disabledbehaviours)) {
// Disable.
if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (!isset($behaviours[$disable])) {
throw new \moodle_exception('unknownbehaviour', 'question', $thispageurl, $disable);
print_error('unknownbehaviour', 'question', $thispageurl, $disable);
}
if (array_search($disable, $disabledbehaviours) === false) {
@@ -97,11 +97,11 @@ if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey(
// Enable.
if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (!isset($behaviours[$enable])) {
throw new \moodle_exception('unknownbehaviour', 'question', $thispageurl, $enable);
print_error('unknownbehaviour', 'question', $thispageurl, $enable);
}
if (!$archetypal[$enable]) {
throw new \moodle_exception('cannotenablebehaviour', 'question', $thispageurl, $enable);
print_error('cannotenablebehaviour', 'question', $thispageurl, $enable);
}
if (($key = array_search($enable, $disabledbehaviours)) !== false) {
@@ -114,7 +114,7 @@ if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey())
// Move up in order.
if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (!isset($behaviours[$up])) {
throw new \moodle_exception('unknownbehaviour', 'question', $thispageurl, $up);
print_error('unknownbehaviour', 'question', $thispageurl, $up);
}
// This function works fine for behaviours, as well as qtypes.
@@ -126,7 +126,7 @@ if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
// Move down in order.
if (($down = optional_param('down', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (!isset($behaviours[$down])) {
throw new \moodle_exception('unknownbehaviour', 'question', $thispageurl, $down);
print_error('unknownbehaviour', 'question', $thispageurl, $down);
}
// This function works fine for behaviours, as well as qtypes.
+5 -5
View File
@@ -106,7 +106,7 @@ $sortedqtypes = question_bank::sort_qtype_array($sortedqtypes, $config);
// Disable.
if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (!isset($qtypes[$disable])) {
throw new \moodle_exception('unknownquestiontype', 'question', $thispageurl, $disable);
print_error('unknownquestiontype', 'question', $thispageurl, $disable);
}
$class = \core_plugin_manager::resolve_plugininfo_class('qtype');
@@ -117,11 +117,11 @@ if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey(
// Enable.
if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (!isset($qtypes[$enable])) {
throw new \moodle_exception('unknownquestiontype', 'question', $thispageurl, $enable);
print_error('unknownquestiontype', 'question', $thispageurl, $enable);
}
if (!$qtypes[$enable]->menu_name()) {
throw new \moodle_exception('cannotenable', 'question', $thispageurl, $enable);
print_error('cannotenable', 'question', $thispageurl, $enable);
}
$class = \core_plugin_manager::resolve_plugininfo_class('qtype');
@@ -132,7 +132,7 @@ if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey())
// Move up in order.
if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (!isset($qtypes[$up])) {
throw new \moodle_exception('unknownquestiontype', 'question', $thispageurl, $up);
print_error('unknownquestiontype', 'question', $thispageurl, $up);
}
$neworder = question_reorder_qtypes($sortedqtypes, $up, -1);
@@ -143,7 +143,7 @@ if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
// Move down in order.
if (($down = optional_param('down', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (!isset($qtypes[$down])) {
throw new \moodle_exception('unknownquestiontype', 'question', $thispageurl, $down);
print_error('unknownquestiontype', 'question', $thispageurl, $down);
}
$neworder = question_reorder_qtypes($sortedqtypes, $down, +1);
+1 -1
View File
@@ -2080,7 +2080,7 @@ class core_admin_renderer extends plugin_renderer_base {
$errorline = true;
} else {
if ($status) { //Handle ok result (ok)
$status = get_string('statusok');
$status = get_string('ok');
} else {
if ($environment_result->getLevel() == 'optional') {//Handle check result (warning)
$status = get_string('check');
+5 -5
View File
@@ -152,7 +152,7 @@ if (($action == 'edit') || ($action == 'new')) {
core_plugin_manager::reset_caches();
redirect($baseurl);
} else {
throw new \moodle_exception('instancenotsaved', 'repository', $baseurl);
print_error('instancenotsaved', 'repository', $baseurl);
}
exit;
} else {
@@ -183,14 +183,14 @@ if (($action == 'edit') || ($action == 'new')) {
}
} else if ($action == 'show') {
if (!confirm_sesskey()) {
throw new \moodle_exception('confirmsesskeybad', '', $baseurl);
print_error('confirmsesskeybad', '', $baseurl);
}
$class = \core_plugin_manager::resolve_plugininfo_class('repository');
$class::enable_plugin($repository, 1);
$return = true;
} else if ($action == 'hide') {
if (!confirm_sesskey()) {
throw new \moodle_exception('confirmsesskeybad', '', $baseurl);
print_error('confirmsesskeybad', '', $baseurl);
}
$class = \core_plugin_manager::resolve_plugininfo_class('repository');
$class::enable_plugin($repository, 0);
@@ -200,7 +200,7 @@ if (($action == 'edit') || ($action == 'new')) {
if ($sure) {
$PAGE->set_pagetype('admin-repository-' . $repository);
if (!confirm_sesskey()) {
throw new \moodle_exception('confirmsesskeybad', '', $baseurl);
print_error('confirmsesskeybad', '', $baseurl);
}
if ($repositorytype->delete($downloadcontents)) {
@@ -209,7 +209,7 @@ if (($action == 'edit') || ($action == 'new')) {
core_plugin_manager::reset_caches();
redirect($baseurl);
} else {
throw new \moodle_exception('instancenotdeleted', 'repository', $baseurl);
print_error('instancenotdeleted', 'repository', $baseurl);
}
exit;
} else {
+2 -2
View File
@@ -104,7 +104,7 @@ if (!empty($edit) || !empty($new)) {
core_plugin_manager::reset_caches();
redirect($parenturl);
} else {
throw new \moodle_exception('instancenotsaved', 'repository', $parenturl);
print_error('instancenotsaved', 'repository', $parenturl);
}
exit;
} else {
@@ -134,7 +134,7 @@ if (!empty($edit) || !empty($new)) {
core_plugin_manager::reset_caches();
redirect($parenturl, $deletedstr, 3);
} else {
throw new \moodle_exception('instancenotdeleted', 'repository', $parenturl);
print_error('instancenotdeleted', 'repository', $parenturl);
}
exit;
}
+1 -1
View File
@@ -33,7 +33,7 @@ $classformode = array(
'view' => 'core_role_allow_view_page'
);
if (!isset($classformode[$mode])) {
throw new \moodle_exception('invalidmode', '', '', $mode);
print_error('invalidmode', '', '', $mode);
}
$baseurl = new moodle_url('/admin/roles/allow.php', array('mode'=>$mode));
+1 -1
View File
@@ -75,7 +75,7 @@ if ($roleid && !isset($assignableroles[$roleid])) {
$a = new stdClass;
$a->roleid = $roleid;
$a->context = $contextname;
throw new \moodle_exception('cannotassignrolehere', '', $context->get_url(), $a);
print_error('cannotassignrolehere', '', $context->get_url(), $a);
}
// Work out an appropriate page title.
+1 -1
View File
@@ -48,7 +48,7 @@ if ($course) {
// Security first.
require_login($course, false, $cm);
if (!has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride', 'moodle/role:override', 'moodle/role:manage'), $context)) {
throw new \moodle_exception('nopermissions', 'error', '', get_string('checkpermissions', 'core_role'));
print_error('nopermissions', 'error', '', get_string('checkpermissions', 'core_role'));
}
navigation_node::override_active_url($url);
@@ -38,28 +38,24 @@ class core_role_admins_existing_selector extends user_selector_base {
$name = 'removeselect';
}
$options['multiselect'] = false;
$options['includecustomfields'] = true;
parent::__construct($name, $options);
}
public function find_users($search) {
global $DB, $CFG;
list($wherecondition, $params) = $this->search_sql($search, '');
[$wherecondition, $params] = $this->search_sql($search, 'u');
$params = array_merge($params, $this->userfieldsparams);
$fields = 'SELECT u.id, ' . $this->userfieldsselects;
$fields = 'SELECT ' . $this->required_fields_sql('');
if ($wherecondition) {
$wherecondition = "$wherecondition AND u.id IN ($CFG->siteadmins)";
$wherecondition = "$wherecondition AND id IN ($CFG->siteadmins)";
} else {
$wherecondition = "u.id IN ($CFG->siteadmins)";
$wherecondition = "id IN ($CFG->siteadmins)";
}
$sql = " FROM {user} u
$this->userfieldsjoin
$sql = " FROM {user}
WHERE $wherecondition";
[$sort, $sortparams] = users_order_by_sql('u', $search, $this->accesscontext, $this->userfieldsmappings);
list($sort, $sortparams) = users_order_by_sql('', $search, $this->accesscontext);
$params = array_merge($params, $sortparams);
// Sort first by email domain and then by normal name order.
@@ -91,12 +87,8 @@ class core_role_admins_existing_selector extends user_selector_base {
} else {
$groupnameprefix = get_string('extusers', 'core_role');
foreach ($availableusers as $user) {
if (isset($user->email)) {
$domain = substr($user->email, strpos($user->email, '@'));
$groupname = "$groupnameprefix $domain";
} else {
$groupname = $groupnameprefix;
}
$domain = substr($user->email, strpos($user->email, '@'));
$groupname = "$groupnameprefix $domain";
$result[$groupname][] = $user;
}
}
@@ -39,28 +39,24 @@ class core_role_admins_potential_selector extends user_selector_base {
$name = 'addselect';
}
$options['multiselect'] = false;
$options['includecustomfields'] = true;
$options['exclude'] = explode(',', $CFG->siteadmins);
parent::__construct($name, $options);
}
public function find_users($search) {
global $CFG, $DB;
list($wherecondition, $params) = $this->search_sql($search, '');
[$wherecondition, $params] = $this->search_sql($search, 'u');
$params = array_merge($params, $this->userfieldsparams);
$fields = 'SELECT u.id, ' . $this->userfieldsselects;
$fields = 'SELECT ' . $this->required_fields_sql('');
$countfields = 'SELECT COUNT(1)';
$sql = " FROM {user} u
$this->userfieldsjoin
$sql = " FROM {user}
WHERE $wherecondition AND mnethostid = :localmnet";
// It could be dangerous to make remote users admins and also this could lead to other problems.
$params['localmnet'] = $CFG->mnet_localhost_id;
[$sort, $sortparams] = users_order_by_sql('u', $search, $this->accesscontext, $this->userfieldsmappings);
list($sort, $sortparams) = users_order_by_sql('', $search, $this->accesscontext);
$order = ' ORDER BY ' . $sort;
// Check to see if there are too many to show sensibly.
+6 -6
View File
@@ -68,7 +68,7 @@ $confirmed = (optional_param('confirm', false, PARAM_BOOL) && data_submitted() &
switch ($action) {
case 'delete':
if (isset($undeletableroles[$roleid])) {
throw new \moodle_exception('cannotdeletethisrole', '', $baseurl);
print_error('cannotdeletethisrole', '', $baseurl);
}
if (!$confirmed) {
// Show confirmation.
@@ -89,7 +89,7 @@ switch ($action) {
}
if (!delete_role($roleid)) {
// The delete failed.
throw new \moodle_exception('cannotdeleterolewithid', 'error', $baseurl, $roleid);
print_error('cannotdeleterolewithid', 'error', $baseurl, $roleid);
}
// Deleted a role sitewide...
redirect($baseurl);
@@ -108,10 +108,10 @@ switch ($action) {
}
}
if (is_null($thisrole) || is_null($prevrole)) {
throw new \moodle_exception('cannotmoverolewithid', 'error', '', $roleid);
print_error('cannotmoverolewithid', 'error', '', $roleid);
}
if (!switch_roles($thisrole, $prevrole)) {
throw new \moodle_exception('cannotmoverolewithid', 'error', '', $roleid);
print_error('cannotmoverolewithid', 'error', '', $roleid);
}
}
@@ -131,10 +131,10 @@ switch ($action) {
}
}
if (is_null($nextrole)) {
throw new \moodle_exception('cannotmoverolewithid', 'error', '', $roleid);
print_error('cannotmoverolewithid', 'error', '', $roleid);
}
if (!switch_roles($thisrole, $nextrole)) {
throw new \moodle_exception('cannotmoverolewithid', 'error', '', $roleid);
print_error('cannotmoverolewithid', 'error', '', $roleid);
}
}
+2 -2
View File
@@ -93,7 +93,7 @@ $PAGE->set_title($title);
$PAGE->navbar->add($straction);
switch ($context->contextlevel) {
case CONTEXT_SYSTEM:
throw new \moodle_exception('cannotoverridebaserole', 'error');
print_error('cannotoverridebaserole', 'error');
break;
case CONTEXT_USER:
$fullname = fullname($user, has_capability('moodle/site:viewfullnames', $context));
@@ -124,7 +124,7 @@ if (empty($overridableroles[$roleid])) {
$a = new stdClass;
$a->roleid = $roleid;
$a->context = $contextname;
throw new \moodle_exception('cannotoverriderolehere', '', $context->get_url(), $a);
print_error('cannotoverriderolehere', '', $context->get_url(), $a);
}
// If we are actually overriding a role, create the table object, and save changes if appropriate.
+1 -1
View File
@@ -100,7 +100,7 @@ $PAGE->set_title($title);
$PAGE->activityheader->disable();
switch ($context->contextlevel) {
case CONTEXT_SYSTEM:
throw new \moodle_exception('cannotoverridebaserole', 'error');
print_error('cannotoverridebaserole', 'error');
break;
case CONTEXT_USER:
$fullname = fullname($user, has_capability('moodle/site:viewfullnames', $context));
+7 -7
View File
@@ -14,19 +14,19 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_role;
use core_role_preset;
/**
* Role XML presets test case.
*
* @package core_role
* @category test
* @category phpunit
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class preset_test extends \advanced_testcase {
defined('MOODLE_INTERNAL') || die();
class core_role_preset_testcase extends advanced_testcase {
public function test_xml() {
global $DB;
@@ -61,7 +61,7 @@ class preset_test extends \advanced_testcase {
FROM {role_capabilities}
WHERE contextid = :syscontext AND roleid = :roleid
ORDER BY capability ASC",
array('syscontext' => \context_system::instance()->id, 'roleid' => $role->id));
array('syscontext'=>context_system::instance()->id, 'roleid'=>$role->id));
foreach ($capabilities as $cap) {
$this->assertEquals($cap->permission, $info['permissions'][$cap->capability]);
+13 -13
View File
@@ -190,48 +190,48 @@ class provider_test extends provider_testcase {
if ($data = $writer->get_data($subcontextstudent)) {
$this->assertEquals($user->id, reset($data)->userid);
}
if ($data = (array)$writer->get_data($subcontextrc)) {
if ($data = $writer->get_data($subcontextrc)) {
$this->assertEquals('moodle/backup:backupactivity', reset($data)->capability);
$this->assertEquals($strpermissions[CAP_ALLOW], reset($data)->permission);
}
}
if ($context->contextlevel == CONTEXT_COURSE) {
if ($data = (array)$writer->get_data($subcontextstudent)) {
if ($data = $writer->get_data($subcontextstudent)) {
$this->assertEquals($user->id, reset($data)->userid);
}
if ($data = (array)$writer->get_data($subcontextrc)) {
if ($data = $writer->get_data($subcontextrc)) {
$this->assertEquals('moodle/backup:backupcourse', reset($data)->capability);
}
}
if ($context->contextlevel == CONTEXT_COURSECAT) {
if ($data = (array)$writer->get_data($subcontextmanager)) {
if ($data = $writer->get_data($subcontextmanager)) {
$this->assertEquals($user->id, reset($data)->modifierid);
}
if ($data = (array)$writer->get_data($subcontextrc)) {
if ($data = $writer->get_data($subcontextrc)) {
$this->assertEquals('moodle/category:manage', reset($data)->capability);
}
}
if ($context->contextlevel == CONTEXT_SYSTEM) {
if ($data = (array)$writer->get_data($subcontextmanager)) {
if ($data = $writer->get_data($subcontextmanager)) {
$this->assertEquals($user->id, reset($data)->modifierid);
}
if ($data = (array)$writer->get_data($subcontextrc)) {
if ($data = $writer->get_data($subcontextrc)) {
$this->assertEquals('moodle/backup:backupcourse', reset($data)->capability);
}
}
if ($context->contextlevel == CONTEXT_BLOCK) {
if ($data = (array)$writer->get_data($subcontextstudent)) {
if ($data = $writer->get_data($subcontextstudent)) {
$this->assertEquals($user->id, reset($data)->userid);
}
if ($data = (array)$writer->get_data($subcontextrc)) {
if ($data = $writer->get_data($subcontextrc)) {
$this->assertEquals('moodle/block:edit', reset($data)->capability);
}
}
if ($context->contextlevel == CONTEXT_USER) {
if ($data = (array)$writer->get_data($subcontextmanager)) {
if ($data = $writer->get_data($subcontextmanager)) {
$this->assertEquals($user->id, reset($data)->userid);
}
if ($data = (array)$writer->get_data($subcontextrc)) {
if ($data = $writer->get_data($subcontextrc)) {
$this->assertEquals('moodle/competency:evidencedelete', reset($data)->capability);
}
}
@@ -415,7 +415,7 @@ class provider_test extends provider_testcase {
provider::export_user_role_to_cohort($user->id);
$writer = writer::with_context($contextuserassignover);
$this->assertTrue($writer->has_any_data());
$exported = (array)$writer->get_related_data($subcontextteacher, 'cohortroles');
$exported = $writer->get_related_data($subcontextteacher, 'cohortroles');
$this->assertEquals($user->id, reset($exported)->userid);
// Test User is member of a cohort which User2 is assigned to role to this cohort.
@@ -432,7 +432,7 @@ class provider_test extends provider_testcase {
provider::export_user_role_to_cohort($user->id);
$writer = writer::with_context($contextuser);
$this->assertTrue($writer->has_any_data());
$exported = (array)$writer->get_related_data($subcontextteacher, 'cohortroles');
$exported = $writer->get_related_data($subcontextteacher, 'cohortroles');
$this->assertEquals($user2->id, reset($exported)->userid);
}
+1 -1
View File
@@ -55,7 +55,7 @@ if ($course->id == SITEID) {
$canview = has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride',
'moodle/role:override', 'moodle/role:manage'), $usercontext);
if (!$canview) {
throw new \moodle_exception('nopermissions', 'error', '', get_string('checkpermissions', 'core_role'));
print_error('nopermissions', 'error', '', get_string('checkpermissions', 'core_role'));
}
if ($userid != $USER->id) {
-1
View File
@@ -163,7 +163,6 @@ $table->head = [
];
$searchareas = \core_search\manager::get_search_areas_list();
core_collator::asort_objects_by_method($searchareas, 'get_visible_name');
$areasconfig = isset($searchmanager) ? $searchmanager->get_areas_config($searchareas) : false;
foreach ($searchareas as $area) {
$areaid = $area->get_area_id();
+2 -2
View File
@@ -23,13 +23,13 @@ if (empty($settingspage) or !($settingspage instanceof admin_settingpage)) {
if (moodle_needs_upgrading()) {
redirect(new moodle_url('/admin/index.php'));
} else {
throw new \moodle_exception('sectionerror', 'admin', "$CFG->wwwroot/$CFG->admin/");
print_error('sectionerror', 'admin', "$CFG->wwwroot/$CFG->admin/");
}
die;
}
if (!($settingspage->check_access())) {
throw new \moodle_exception('accessdenied', 'admin');
print_error('accessdenied', 'admin');
die;
}
-8
View File
@@ -82,14 +82,6 @@ reports,core_reportbuilder|/reportbuilder/index.php',
$setting->set_updatedcallback('theme_reset_all_caches');
$temp->add($setting);
// Favicon file setting.
$title = get_string('favicon', 'admin');
$description = get_string('favicon_desc', 'admin');
$setting = new admin_setting_configstoredfile('core_admin/favicon', $title, $description, 'favicon', 0,
['maxfiles' => 1, 'accepted_types' => ['image']]);
$setting->set_updatedcallback('theme_reset_all_caches');
$temp->add($setting);
$ADMIN->add('appearance', $temp);
// Course colours section.
+2
View File
@@ -49,6 +49,8 @@ $ADMIN->add('mnet', new admin_externalpage('trustedhosts', new lang_string('trus
if (isset($CFG->mnet_dispatcher_mode) and $CFG->mnet_dispatcher_mode !== 'off') {
$profilefields = new admin_settingpage('mnetprofilefields', new lang_string('profilefields', 'mnet'),
'moodle/site:config');
$profilefields->add(new admin_setting_heading('mnetprofilefields/xmlrpcmnet', '',
$OUTPUT->render(mnet_get_deprecation_notice())));
$ADMIN->add('mnet', $profilefields);
$fields = mnet_profile_field_options();
+1 -4
View File
@@ -527,10 +527,7 @@ if ($hassiteconfig && !empty($CFG->enableplagiarism)) {
$plugin->load_settings($ADMIN, 'plagiarism', $hassiteconfig);
}
}
// Comments report, note this page is really just a means to delete comments so check that.
$ADMIN->add('reports', new admin_externalpage('comments', new lang_string('comments'), $CFG->wwwroot . '/comment/index.php',
'moodle/comment:delete'));
$ADMIN->add('reports', new admin_externalpage('comments', new lang_string('comments'), $CFG->wwwroot.'/comment/', 'moodle/site:viewreports'));
// Course reports settings
if ($hassiteconfig) {
-15
View File
@@ -49,18 +49,3 @@ $ADMIN->add(
empty($CFG->enablecustomreports)
)
);
$settings = new admin_settingpage('reportbuildersettings', get_string('customreportssettings', 'core_reportbuilder'),
'moodle/site:config', empty($CFG->enablecustomreports));
$settings->add(new admin_setting_configtext(
'customreportslimit',
new lang_string('customreportslimit', 'core_reportbuilder'),
new lang_string('customreportslimit_desc', 'core_reportbuilder'), 0, PARAM_INT));
$settings->add(new admin_setting_configcheckbox(
'customreportsliveediting',
new lang_string('customreportsliveediting', 'core_reportbuilder'),
new lang_string('customreportsliveediting_desc', 'core_reportbuilder'), 1));
$ADMIN->add('reportbuilder', $settings);
-41
View File
@@ -61,16 +61,6 @@ if ($hassiteconfig) {
$temp->add($setting);
$temp->add(new admin_setting_configtext('supportpage', new lang_string('supportpage', 'admin'),
new lang_string('configsupportpage', 'admin'), '', PARAM_URL));
$temp->add(new admin_setting_configselect('supportavailability', new lang_string('supportavailability', 'admin'),
new lang_string('configsupportavailability', 'admin'), CONTACT_SUPPORT_AUTHENTICATED,
[
CONTACT_SUPPORT_ANYONE => new lang_string('availabletoanyone', 'admin'),
CONTACT_SUPPORT_AUTHENTICATED => new lang_string('availabletoauthenticated', 'admin'),
CONTACT_SUPPORT_DISABLED => new lang_string('disabled', 'admin'),
]
));
$ADMIN->add('server', $temp);
// Session handling.
@@ -182,11 +172,6 @@ if ($hassiteconfig) {
new lang_string('configproxypassword', 'admin'), ''));
$temp->add(new admin_setting_configtext('proxybypass', new lang_string('proxybypass', 'admin'),
new lang_string('configproxybypass', 'admin'), 'localhost, 127.0.0.1'));
$temp->add(new admin_setting_configcheckbox('proxylogunsafe', new lang_string('proxylogunsafe', 'admin'),
new lang_string('configproxylogunsafe_help', 'admin'), 0));
$temp->add(new admin_setting_configcheckbox('proxyfixunsafe', new lang_string('proxyfixunsafe', 'admin'),
new lang_string('configproxyfixunsafe_help', 'admin'), 0));
$ADMIN->add('server', $temp);
$temp = new admin_settingpage('maintenancemode', new lang_string('sitemaintenancemode', 'admin'));
@@ -452,35 +437,9 @@ if ($hassiteconfig) {
'CRAM-MD5' => 'CRAM-MD5',
];
// Get all the issuers.
$issuers = \core\oauth2\api::get_all_issuers();
$enabledissuers = [];
foreach ($issuers as $issuer) {
// Get the enabled issuer only.
if ($issuer->get('enabled')) {
$enabledissuers[] = $issuer;
}
}
if (count($enabledissuers) > 0) {
$authtypeoptions['XOAUTH2'] = 'XOAUTH2';
}
$temp->add(new admin_setting_configselect('smtpauthtype', new lang_string('smtpauthtype', 'admin'),
new lang_string('configsmtpauthtype', 'admin'), 'LOGIN', $authtypeoptions));
if (count($enabledissuers) > 0) {
$oauth2services = [
'' => new lang_string('none', 'admin'),
];
foreach ($enabledissuers as $issuer) {
$oauth2services[$issuer->get('id')] = s($issuer->get('name'));
}
$temp->add(new admin_setting_configselect('smtpoauthservice', new lang_string('issuer', 'auth_oauth2'),
new lang_string('configsmtpoauthservice', 'admin'), '', $oauth2services));
}
$temp->add(new admin_setting_configtext('smtpuser', new lang_string('smtpuser', 'admin'),
new lang_string('configsmtpuser', 'admin'), '', PARAM_NOTAGS));
+1 -2
View File
@@ -240,8 +240,7 @@ if ($hassiteconfig
if ($field->param2 > 255 || $field->datatype != 'text') {
continue;
}
$fields['profile_field_' . $field->shortname] = format_string($field->name, true,
['context' => context_system::instance()]) . ' *';
$fields['profile_field_' . $field->shortname] = $field->name . ' *';
}
return $fields;
+3 -2
View File
@@ -25,7 +25,7 @@
require_once(__DIR__ . '/../config.php');
require_once("{$CFG->libdir}/adminlib.php");
use core_admin\reportbuilder\local\systemreports\task_logs;
use core_admin\local\systemreports\task_logs;
use core_reportbuilder\system_report_factory;
$PAGE->set_url(new \moodle_url('/admin/tasklogs.php'));
@@ -60,7 +60,8 @@ $report = system_report_factory::create(task_logs::class, context_system::instan
if (!empty($filter)) {
$report->set_filter_values([
'task_log:name_values' => $filter,
'task_log:name_operator' => \core_reportbuilder\local\filters\text::IS_EQUAL_TO,
'task_log:name_value' => $filter,
]);
}
-29
View File
@@ -1,29 +0,0 @@
@core @core_admin
Feature: Outgoing mail configuration
In order to send email from Moodle
As a Moodle administrator
I need to set mail configuration
Background:
Given I log in as "admin"
Scenario: SMTP Auth Type without OAuth 2 Service setup yet
Given I navigate to "Server > Email > Outgoing mail configuration" in site administration
And I should not see "XOAUTH2" in the "SMTP Auth Type" "select"
And I should see "LOGIN" in the "SMTP Auth Type" "select"
And I should see "PLAIN" in the "SMTP Auth Type" "select"
Scenario: SMTP Auth Type with OAuth 2 Service setup
Given I navigate to "Server > OAuth 2 services" in site administration
And I press "Google"
And I should see "Create new service: Google"
And I set the following fields to these values:
| Name | Testing service |
| Client ID | thisistheclientid |
| Client secret | supersecret |
And I press "Save changes"
When I navigate to "Server > Email > Outgoing mail configuration" in site administration
Then I should see "XOAUTH2" in the "SMTP Auth Type" "select"
And I should see "LOGIN" in the "SMTP Auth Type" "select"
And I should see "PLAIN" in the "SMTP Auth Type" "select"
And I should see "Testing service" in the "OAuth 2 Service" "select"
+5 -4
View File
@@ -15,6 +15,7 @@ Feature: View task logs report and use its filters
And I navigate to "Server > Tasks > Task logs" in site administration
When I click on "Filters" "button"
And I set the following fields in the "Class name" "core_reportbuilder > Filter" to these values:
| Class name operator | Contains |
| Class name value | <name> |
And I click on "Apply" "button" in the "[data-region='report-filters']" "css_element"
Then I should see "Filters applied"
@@ -26,9 +27,9 @@ Feature: View task logs report and use its filters
| Type | Name |
| Scheduled | <nonmatch> |
Examples:
| name | match | nonmatch |
| Cleanup event monitor events | Cleanup event monitor events | Incoming email pickup |
| Incoming email pickup | Incoming email pickup | Cleanup event monitor events |
| name | match | nonmatch |
| task\\clean_events | Cleanup event monitor events | Incoming email pickup |
| task\\pickup_task | Incoming email pickup | Cleanup event monitor events |
@javascript
# Task duration is dependent on many factors, we are asserting here that no task has a duration >2 minutes.
@@ -62,7 +63,7 @@ Feature: View task logs report and use its filters
Then I should see "Filters applied"
And I should see "Filters (1)" in the "#dropdownFiltersButton" "css_element"
And I should see "Nothing to display"
And I click on "Reset all" "button" in the "[data-region='report-filters']" "css_element"
And I click on "Reset" "button" in the "[data-region='report-filters']" "css_element"
And I should see "Filters reset"
And I should not see "Filters (1)" in the "#dropdownFiltersButton" "css_element"
And I should see "Filters" in the "#dropdownFiltersButton" "css_element"
@@ -1,278 +0,0 @@
<?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/>.
declare(strict_types=1);
namespace core_admin\reportbuilder\datasource;
use core\task\database_logger;
use core_reportbuilder_generator;
use core_reportbuilder_testcase;
use core_reportbuilder\local\filters\{boolean_select, date, duration, number, select, text};
use core_reportbuilder\task\send_schedules;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once("{$CFG->dirroot}/reportbuilder/tests/helpers.php");
/**
* Unit tests for task logs datasource
*
* @package core_admin
* @covers \core_admin\reportbuilder\datasource\task_logs
* @copyright 2022 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class task_logs_test extends core_reportbuilder_testcase {
/**
* Test default datasource
*/
public function test_datasource_default(): void {
$this->resetAfterTest();
$this->generate_task_log_data(true, 3, 2, 1654038000, 1654038060);
/** @var core_reportbuilder_generator $generator */
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
$report = $generator->create_report(['name' => 'Tasks', 'source' => task_logs::class, 'default' => 1]);
$content = $this->get_custom_report_content($report->get('id'));
$this->assertCount(1, $content);
// Default columns are name, starttime, duration, result.
[$name, $timestart, $duration, $result] = array_values($content[0]);
$this->assertStringContainsString(send_schedules::class, $name);
$this->assertEquals('1/06/22, 07:00:00', $timestart);
$this->assertEquals('1 min', $duration);
$this->assertEquals('Success', $result);
}
/**
* Test datasource columns that aren't added by default
*/
public function test_datasource_non_default_columns(): void {
$this->resetAfterTest();
$this->generate_task_log_data(true, 3, 2, 1654038000, 1654038060, 'hi', 'core_reportbuilder', 'test', 43);
/** @var core_reportbuilder_generator $generator */
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
$report = $generator->create_report(['name' => 'Tasks', 'source' => task_logs::class, 'default' => 0]);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:component']);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:type']);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:endtime']);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:hostname']);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:pid']);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:database']);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:dbreads']);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:dbwrites']);
$content = $this->get_custom_report_content($report->get('id'));
$this->assertCount(1, $content);
$this->assertEquals([
'core_reportbuilder',
'Scheduled',
'1/06/22, 07:01:00',
'test',
'43',
'<div>3 reads</div><div>2 writes</div>',
'3',
'2',
], array_values($content[0]));
}
/**
* Data provider for {@see test_datasource_filters}
*
* @return array[]
*/
public function datasource_filters_provider(): array {
return [
'Filter name' => ['task_log:name', [
'task_log:name_values' => [send_schedules::class],
], true],
'Filter name (no match)' => ['task_log:name', [
'task_log:name_values' => ['invalid'],
], false],
'Filter component' => ['task_log:component', [
'task_log:component_operator' => select::EQUAL_TO,
'task_log:component_value' => 'core_reportbuilder',
], true],
'Filter component (no match)' => ['task_log:component', [
'task_log:component_operator' => select::NOT_EQUAL_TO,
'task_log:component_value' => 'core_reportbuilder',
], false],
'Filter type' => ['task_log:type', [
'task_log:type_operator' => select::EQUAL_TO,
'task_log:type_value' => database_logger::TYPE_SCHEDULED,
], true],
'Filter type (no match)' => ['task_log:type', [
'task_log:type_operator' => select::EQUAL_TO,
'task_log:type_value' => database_logger::TYPE_ADHOC,
], false],
'Filter output' => ['task_log:output', [
'task_log:output_operator' => text::IS_NOT_EMPTY,
], true],
'Filter output (no match)' => ['task_log:output', [
'task_log:output_operator' => text::IS_EMPTY,
], false],
'Filter result' => ['task_log:result', [
'task_log:result_operator' => boolean_select::CHECKED,
], true],
'Filter result (no match)' => ['task_log:result', [
'task_log:result_operator' => boolean_select::NOT_CHECKED,
], false],
'Filter time start' => ['task_log:timestart', [
'task_log:timestart_operator' => date::DATE_RANGE,
'task_log:timestart_from' => 1622502000,
], true],
'Filter time start (no match)' => ['task_log:timestart', [
'task_log:timestart_operator' => date::DATE_RANGE,
'task_log:timestart_to' => 1622502000,
], false],
'Filter time end' => ['task_log:timeend', [
'task_log:timeend_operator' => date::DATE_RANGE,
'task_log:timeend_from' => 1622502000,
], true],
'Filter time end (no match)' => ['task_log:timeend', [
'task_log:timeend_operator' => date::DATE_RANGE,
'task_log:timeend_to' => 1622502000,
], false],
'Filter duration' => ['task_log:duration', [
'task_log:duration_operator' => duration::DURATION_MAXIMUM,
'task_log:duration_unit' => MINSECS,
'task_log:duration_value' => 2,
], true],
'Filter duration (no match)' => ['task_log:duration', [
'task_log:duration_operator' => duration::DURATION_MINIMUM,
'task_log:duration_unit' => MINSECS,
'task_log:duration_value' => 2,
], false],
'Filter database reads' => ['task_log:dbreads', [
'task_log:dbreads_operator' => number::LESS_THAN,
'task_log:dbreads_value1' => 4,
], true],
'Filter database reads (no match)' => ['task_log:dbreads', [
'task_log:dbreads_operator' => number::GREATER_THAN,
'task_log:dbreads_value1' => 4,
], false],
'Filter database writes' => ['task_log:dbwrites', [
'task_log:dbwrites_operator' => number::LESS_THAN,
'task_log:dbwrites_value1' => 4,
], true],
'Filter database writes (no match)' => ['task_log:dbwrites', [
'task_log:dbwrites_operator' => number::GREATER_THAN,
'task_log:dbwrites_value1' => 4,
], false],
];
}
/**
* Test datasource filters
*
* @param string $filtername
* @param array $filtervalues
* @param bool $expectmatch
*
* @dataProvider datasource_filters_provider
*/
public function test_datasource_filters(
string $filtername,
array $filtervalues,
bool $expectmatch
): void {
$this->resetAfterTest();
$this->generate_task_log_data(true, 3, 2, 1654038000, 1654038060, 'hi', 'core_reportbuilder', 'test', 43);
/** @var core_reportbuilder_generator $generator */
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
// Create report containing single component column, and given filter.
$report = $generator->create_report(['name' => 'Tasks', 'source' => task_logs::class, 'default' => 0]);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:component']);
// Add filter, set it's values.
$generator->create_filter(['reportid' => $report->get('id'), 'uniqueidentifier' => $filtername]);
$content = $this->get_custom_report_content($report->get('id'), 0, $filtervalues);
if ($expectmatch) {
$this->assertCount(1, $content);
$this->assertEquals('core_reportbuilder', reset($content[0]));
} else {
$this->assertEmpty($content);
}
}
/**
* Stress test datasource
*
* In order to execute this test PHPUNIT_LONGTEST should be defined as true in phpunit.xml or directly in config.php
*/
public function test_stress_datasource(): void {
if (!PHPUNIT_LONGTEST) {
$this->markTestSkipped('PHPUNIT_LONGTEST is not defined');
}
$this->resetAfterTest();
$this->generate_task_log_data(true, 3, 2, 1654038000, 1654038060, 'hi', 'core_reportbuilder', 'test', 43);
$this->datasource_stress_test_columns(task_logs::class);
$this->datasource_stress_test_columns_aggregation(task_logs::class);
$this->datasource_stress_test_conditions(task_logs::class, 'task_log:name');
}
/**
* Helper to generate some task logs data
*
* @param bool $success
* @param int $dbreads
* @param int $dbwrites
* @param float $timestart
* @param float $timeend
* @param string $logoutput
* @param string $component
* @param string $hostname
* @param int $pid
*/
private function generate_task_log_data(
bool $success,
int $dbreads,
int $dbwrites,
float $timestart,
float $timeend,
string $logoutput = 'hello',
string $component = 'moodle',
string $hostname = 'phpunit',
int $pid = 42
): void {
$logpath = make_request_directory() . '/log.txt';
file_put_contents($logpath, $logoutput);
$task = new send_schedules();
$task->set_component($component);
$task->set_hostname($hostname);
$task->set_pid($pid);
database_logger::store_log_for_task($task, $logpath, !$success, $dbreads, $dbwrites, $timestart, $timeend);
}
}
@@ -1,20 +1,18 @@
@tool @tool_admin_presets
Feature: I can download a preset
Background:
Given the following "tool_admin_presets > preset" exist:
Given I log in as "admin"
And the following "tool_admin_presets > preset" exist:
| name |
| Custom preset |
And I navigate to "Site admin presets" in site administration
@javascript
Scenario: Custom preset settings can be downloaded
Scenario: Core and custom preset settings can be downloaded
Given I log in as "admin"
And I navigate to "Site admin presets" in site administration
When I open the action menu in "Custom preset" "table_row"
Then following "Download" "link" in the "Custom preset" "table_row" should download between "0" and "5000" bytes
@javascript
Scenario: Core preset settings can be downloaded
Given I log in as "admin"
And I navigate to "Site admin presets" in site administration
When I open the action menu in "Starter" "table_row"
Then following "Download" "link" in the "Starter" "table_row" should download between "0" and "5000" bytes
And I open the action menu in "Starter" "table_row"
And following "Download" "link" in the "Starter" "table_row" should download between "0" and "5000" bytes
@@ -23,7 +23,7 @@ namespace tool_admin_presets\event;
* @category test
* @copyright 2021 Sara Arjona (sara@moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \tool_admin_presets\event\preset_deleted
* @coversDefaultClass \tool_admin_presets\event\preset_deleted
*/
class preset_deleted_test extends \advanced_testcase {
@@ -23,7 +23,7 @@ namespace tool_admin_presets\event;
* @category test
* @copyright 2021 Sara Arjona (sara@moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \tool_admin_presets\event\preset_downloaded
* @coversDefaultClass \tool_admin_presets\event\preset_downloaded
*/
class preset_downloaded_test extends \advanced_testcase {
@@ -23,7 +23,7 @@ namespace tool_admin_presets\event;
* @category test
* @copyright 2021 Sara Arjona (sara@moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \tool_admin_presets\event\preset_exported
* @coversDefaultClass \tool_admin_presets\event\preset_exported
*/
class preset_exported_test extends \advanced_testcase {
@@ -23,7 +23,7 @@ namespace tool_admin_presets\event;
* @category test
* @copyright 2021 Sara Arjona (sara@moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \tool_admin_presets\event\preset_imported
* @coversDefaultClass \tool_admin_presets\event\preset_imported
*/
class preset_imported_test extends \advanced_testcase {
@@ -23,7 +23,7 @@ namespace tool_admin_presets\event;
* @category test
* @copyright 2021 Sara Arjona (sara@moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \tool_admin_presets\event\preset_loaded
* @coversDefaultClass \tool_admin_presets\event\preset_loaded
*/
class preset_loaded_test extends \advanced_testcase {
@@ -23,7 +23,7 @@ namespace tool_admin_presets\event;
* @category test
* @copyright 2021 Sara Arjona (sara@moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \tool_admin_presets\event\preset_previewed
* @coversDefaultClass \tool_admin_presets\event\preset_previewed
*/
class preset_previewed_test extends \advanced_testcase {
@@ -23,7 +23,7 @@ namespace tool_admin_presets\event;
* @category test
* @copyright 2021 Sara Arjona (sara@moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \tool_admin_presets\event\preset_reverted
* @coversDefaultClass \tool_admin_presets\event\preset_reverted
*/
class preset_reverted_test extends \advanced_testcase {
@@ -23,7 +23,7 @@ namespace tool_admin_presets\event;
* @category test
* @copyright 2021 Sara Arjona (sara@moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \tool_admin_presets\event\presets_listed
* @coversDefaultClass \tool_admin_presets\event\presets_listed
*/
class presets_listed_test extends \advanced_testcase {
+1 -1
View File
@@ -47,7 +47,7 @@ $pageurl = new moodle_url('/' . $CFG->admin . '/tool/availabilityconditions/');
if (($plugin = optional_param('plugin', '', PARAM_PLUGIN))) {
require_sesskey();
if (!array_key_exists($plugin, $plugins)) {
throw new \moodle_exception('invalidcomponent', 'error', $pageurl);
print_error('invalidcomponent', 'error', $pageurl);
}
$action = required_param('action', PARAM_ALPHA);
switch ($action) {
+1
View File
@@ -24,6 +24,7 @@
$string['aim'] = 'This administration tool helps developers and test writers to create .feature files describing Moodle\'s functionalities and run them automatically. Step definitions available for use in .feature files are listed below.';
$string['allavailablesteps'] = 'All available step definitions';
$string['errorapproot'] = '$CFG->behat_ionic_dirroot is not pointing to a valid Moodle app developer install.';
$string['errorbehatcommand'] = 'Error running behat CLI command. Try running "{$a} --help" manually from CLI to find out more about the problem.';
$string['errorcomposer'] = 'Composer dependencies are not installed.';
$string['errordataroot'] = '$CFG->behat_dataroot is not set or is invalid.';
@@ -1,4 +1,4 @@
@tool @tool_behat @javascript
@tool @tool_behat
Feature: Set up contextual data for tests
In order to write tests quickly
As a developer
@@ -14,6 +14,7 @@ Feature: Set up contextual data for tests
When I log in as "testuser2"
Then I should see "TestFirstname"
@javascript
Scenario: Add a bunch of courses and categories
Given the following "categories" exist:
| name | category | idnumber |
@@ -42,6 +43,7 @@ Feature: Set up contextual data for tests
And I follow "Category 1"
And I should see "Course 3"
@javascript
Scenario: Add a bunch of groups and groupings
Given the following "courses" exist:
| fullname | shortname |
@@ -62,6 +64,7 @@ Feature: Set up contextual data for tests
And I should see "Grouping 1"
And I should see "Grouping 2"
@javascript
Scenario: Role overrides
Given the following "users" exist:
| username | firstname | lastname | email |
@@ -221,6 +224,7 @@ Feature: Set up contextual data for tests
And I follow "Settings"
And the field "Type" matches value "Scale"
@javascript
Scenario: Add relations between users and groups
Given the following "users" exist:
| username | firstname | lastname | email |
@@ -280,16 +284,16 @@ Feature: Set up contextual data for tests
| student1 | CHC |
When I log in as "admin"
And I navigate to "Users > Accounts > Cohorts" in site administration
Then the following should exist in the "reportbuilder-table" table:
Then the following should exist in the "cohorts" table:
| Name | Cohort size |
| System cohort A | 1 |
| System cohort B | 2 |
And I should not see "Cohort in category"
And I am on course index
And I follow "Cat 1"
And I navigate to "Cohorts" in current page administration
And I follow "Cohorts"
And I should not see "System cohort"
And the following should exist in the "reportbuilder-table" table:
And the following should exist in the "cohorts" table:
| Name | Cohort size |
| Cohort in category | 1 |
| Empty cohort | 0 |
@@ -331,22 +335,19 @@ Feature: Set up contextual data for tests
And I am on "Course 1" course homepage
And I navigate to "Setup > Gradebook setup" in the course gradebook
Then I should see "Test Grade Item 1"
And I open the action menu in "Test Grade Item 1" "table_row"
And I choose "Edit" in the open action menu
And I follow "Edit Test Grade Item 1"
And I expand all fieldsets
And I should see "Course 1"
And I press "Cancel"
And I should see "Grade category 1"
And I should see "Test Grade Item 2"
And I open the action menu in "Test Grade Item 2" "table_row"
And I choose "Edit" in the open action menu
And I follow "Edit Test Grade Item 2"
And I expand all fieldsets
And I should see "Grade category 1"
And I press "Cancel"
And I should see "Grade sub category 2"
And I should see "Test Grade Item 3"
And I open the action menu in "Test Grade Item 3" "table_row"
And I choose "Edit" in the open action menu
And I follow "Edit Test Grade Item 3"
And I expand all fieldsets
And I should see "Grade sub category 2"
And I press "Cancel"
@@ -411,8 +412,7 @@ Feature: Set up contextual data for tests
And I am on "Course 1" course homepage
And I navigate to "Setup > Gradebook setup" in the course gradebook
Then I should see "Test Outcome Grade Item 1"
And I open the action menu in "Test Outcome Grade Item 1" "table_row"
And I choose "Edit" in the open action menu
And I follow "Edit Test Outcome Grade Item 1"
And the field "Outcome" matches value "Grade outcome 1"
And I expand all fieldsets
And I should see "Grade category 1" in the "Grade category" "form_row"
@@ -7,8 +7,8 @@ Feature: Behat steps for interacting with form work
@javascript
Scenario: Test fields in containers
Given the following "courses" exist:
| fullname | shortname | summary | summaryformat |
| Course 1 | C1 | Red | 1 |
| fullname | shortname |
| Course 1 | C1 |
When I log in as "admin"
And I am on "Course 1" course homepage
# Just get to any form.
@@ -17,15 +17,11 @@ Feature: Behat steps for interacting with form work
And I set the following fields in the "Appearance" "fieldset" to these values:
| Show activity reports | Yes |
| Number of announcements | 1 |
And I set the following fields in the "Description" "fieldset" to these values:
| Course summary | Green |
Then the field "Show activity reports" in the "Appearance" "fieldset" matches value "Yes"
And the field "Show activity reports" in the "Appearance" "fieldset" does not match value "No"
And the following fields in the "region-main" "region" match these values:
| Course full name | Frog |
| Number of announcements | 1 |
| Course summary | Green |
And the following fields in the "region-main" "region" do not match these values:
| Course full name | Course 1 |
| Number of announcements | 5 |
| Course summary | Red |
@@ -20,10 +20,9 @@ Feature: Forms manipulation
Given the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "activities" exist:
| activity | course | section | name |
| quiz | C1 | 1 | Quiz 1 |
And I am on the "Quiz 1" "quiz activity editing" page logged in as admin
And I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
And I add a "Quiz" to section "1"
When I expand all fieldsets
Then I should see "Close the quiz"
And I should see "Group mode"
@@ -323,7 +323,7 @@ class accessibility {
/**
* This function runs one specified check on the html item
*
* @param string|null $html The html string to be analysed; might be NULL.
* @param string $html The html string to be analysed; might be NULL.
* @param int $contentid The content area ID
* @param int $errid The error ID
* @param string $check The check name to run
@@ -333,7 +333,7 @@ class accessibility {
* @throws \dml_exception
*/
public static function run_one_check(
?string $html,
string $html = null,
int $contentid,
int $errid,
string $check,
@@ -19,7 +19,6 @@ The parameters for the template context are:
* checked: If the initial status is checked.
* disabled: If toggle input is disabled.
* dataattributes: Array of name/value elements added as data-attributes.
* title: Title text.
* label: Label text.
* labelclasses: Any extra classes added to the label container.
@@ -36,7 +35,6 @@ Checked toggle and with "sr-only" label.
"name": "action",
"value": "toggle-status"
}],
"title": "Toggle Enabled",
"label": "Enable/disable status",
"labelclasses": "sr-only"
}
@@ -54,7 +52,6 @@ Disabled toggle with extra classes.
"name": "action",
"value": "toggle-status"
}],
"title": "Toggle Disabled",
"label": "Enable/disable status"
}
{{< /mustache >}}
@@ -71,7 +68,6 @@ The parameters that you can define are:
* disabled
* labelmarkup: Label element code block.
* Should include *class="custom-control-label"*.
* title: Title text.
* label: Label text.
* labelclasses: Any extra classes added to the label container.
@@ -3,9 +3,8 @@
<library>
<location>amd/src/lunr.js</location>
<name>lunr - http://lunrjs.com</name>
<description>Provide a great search experience without the need for external, server-side, search services.</description>
<version>2.3.8</version>
<license>MIT</license>
<repository>https://github.com/olivernn/lunr.js</repository>
<version>2.3.8</version>
<licenseversion></licenseversion>
</library>
</libraries>
@@ -44,7 +44,7 @@ class export extends \moodleform {
// The export button only appears if a local lang is present.
if (!check_dir_exists($langdir) || !count(glob("$langdir/*"))) {
throw new \moodle_exception('nolocallang', 'tool_customlang');
print_error('nolocallang', 'tool_customlang');
}
$langfiles = scandir($langdir);
+5 -6
View File
@@ -36,7 +36,7 @@ Useful for uploading custom langstrings to AMOS or importing or syncing them to
Options:
-l, --lang Comma seperated language ids to export, default: all
-c, --components Comma seperated components to export, default: all
-t, --target Target directory to copy the zip files to, default: $CFG->tempdir/customlang
-t, --target Target to copy the zip files to, default: $CFG->tempdir/customlang
-o, --overwrite Overwrite existing files in the target folder.
Note: If the target is not set, the files are always overwritten!
-h, --help Print out this help
@@ -73,10 +73,9 @@ if ($options['help']) {
echo $usage;
die;
}
// Ensure target directory exists.
$options['target'] = rtrim($options['target'], '/') . '/';
check_dir_exists($options['target']);
if (!file_exists($options['target'])) {
mkdir($options['target'], 0777, true);
}
cli_writeln(get_string('cliexportheading', 'tool_customlang'));
$langs = [];
@@ -91,7 +90,7 @@ foreach ($langs as $lang) {
$filename = $options['target'] . get_string('exportzipfilename', 'tool_customlang', ['lang' => $lang]);
// If the file exists and we are not using the temp folder it requires an ovewrite.
if ($options['target'] != $dafaulttarget && file_exists($filename) && !$options['overwrite']) {
cli_problem(get_string('cliexportfileexists', 'tool_customlang', ['lang' => $lang]));
cli_problem(get_string('cliexportfileexists', 'tool_customlang', $lang));
continue;
}
cli_heading(get_string('cliexportstartexport', 'tool_customlang', $lang));
-10
View File
@@ -160,16 +160,6 @@ foreach ($langfiles as $lng => $files) {
cli_heading(get_string('clifiles', 'tool_customlang', $lng));
// If we intend to check in any changes, we must first check them out.
if ($checkin) {
cli_writeln(get_string('checkout', 'tool_customlang'));
$progressbar = new progress_bar();
$progressbar->create();
tool_customlang_utils::checkout($lng, $progressbar);
}
foreach ($files as $file) {
// Generate a valid stored_file from this file.
$record = (object)[
+9
View File
@@ -29,6 +29,15 @@ defined('MOODLE_INTERNAL') || die();
function xmldb_tool_customlang_upgrade($oldversion) {
global $CFG;
// Automatically generated Moodle v3.6.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v3.7.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v3.8.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v3.9.0 release upgrade line.
// Put any upgrade step following this.
+1 -1
View File
@@ -46,7 +46,7 @@ $PAGE->navbar->add(get_string('editlangpack', 'tool_customlang'), $PAGE->url);
if (empty($lng)) {
// PARAM_LANG validation failed
throw new \moodle_exception('missingparameter');
print_error('missingparameter');
}
// pre-output processing
+2 -2
View File
@@ -47,7 +47,7 @@ if ($action === 'checkout') {
require_sesskey();
require_capability('tool/customlang:edit', context_system::instance());
if (empty($lng)) {
throw new \moodle_exception('missingparameter');
print_error('missingparameter');
}
$PAGE->set_cacheable(false); // progress bar is used here
@@ -70,7 +70,7 @@ if ($action === 'checkin') {
require_sesskey();
require_capability('tool/customlang:edit', context_system::instance());
if (empty($lng)) {
throw new \moodle_exception('missingparameter');
print_error('missingparameter');
}
if (!$confirm) {
@@ -50,7 +50,6 @@ $string['customlang:export'] = 'Export local translation';
$string['customlang:view'] = 'View local translation';
$string['export'] = 'Export custom strings';
$string['exportfilter'] = 'Select component(s) to export';
$string['exportzipfilename'] = 'customlang-export-{$a->lang}.zip';
$string['editlangpack'] = 'Edit language pack';
$string['filter'] = 'Filter strings';
$string['filtercomponent'] = 'Show strings of these components';
+1 -3
View File
@@ -89,9 +89,7 @@ class tool_customlang_utils {
* @param progress_bar $progressbar optionally, the given progress bar can be updated
*/
public static function checkout($lang, progress_bar $progressbar = null) {
global $DB, $CFG;
require_once("{$CFG->libdir}/adminlib.php");
global $DB;
// For behat executions we are going to load only a few components in the
// language customisation structures. Using the whole "en" langpack is
+1 -13
View File
@@ -786,18 +786,6 @@ class api {
return true;
}
/**
* Check if user has permission to create data download request for themselves
*
* @param int|null $userid
* @return bool
*/
public static function can_create_data_download_request_for_self(int $userid = null): bool {
global $USER;
$userid = $userid ?: $USER->id;
return has_capability('tool/dataprivacy:downloadownrequest', \context_user::instance($userid), $userid);
}
/**
* Check if user has permisson to create data deletion request for themselves.
*
@@ -859,7 +847,7 @@ class api {
$usercontext = \context_user::instance($userid);
// If it's your own and you have the right capability, you can download it.
if ($userid == $downloaderid && self::can_create_data_download_request_for_self($downloaderid)) {
if ($userid == $downloaderid && has_capability('tool/dataprivacy:downloadownrequest', $usercontext, $downloaderid)) {
return true;
}
// If you can download anyone's in that context, you can download it.
@@ -53,7 +53,7 @@ class page_helper {
require_login();
if (isguestuser()) {
throw new \moodle_exception('noguest');
print_error('noguest');
}
// TODO Check that data privacy is enabled.
@@ -79,16 +79,6 @@ class provider implements
'privacy:metadata:request'
);
// Regarding this block, we are unable to export or purge this data, as
// it would damage the privacy data across the whole site.
$collection->add_database_table(
'tool_dataprivacy_purposerole',
[
'usermodified' => 'privacy:metadata:purpose:usermodified',
],
'privacy:metadata:purpose'
);
$collection->add_user_preference(tool_helper::PREF_REQUEST_FILTERS,
'privacy:metadata:preference:tool_dataprivacy_request-filters');
$collection->add_user_preference(tool_helper::PREF_REQUEST_PERPAGE,
+1 -6
View File
@@ -35,7 +35,7 @@ $PAGE->set_url($url);
require_login();
if (isguestuser()) {
throw new \moodle_exception('noguest');
print_error('noguest');
}
// Return URL and context.
@@ -96,11 +96,6 @@ if ($data = $mform->get_data()) {
throw new moodle_exception('nopermissions', 'error', '',
get_string('errorcannotrequestdeleteforother', 'tool_dataprivacy'));
}
} else if ($data->type == \tool_dataprivacy\api::DATAREQUEST_TYPE_EXPORT) {
if ($data->userid == $USER->id && !\tool_dataprivacy\api::can_create_data_download_request_for_self()) {
throw new moodle_exception('nopermissions', 'error', '',
get_string('errorcannotrequestexportforself', 'tool_dataprivacy'));
}
}
\tool_dataprivacy\api::create_data_request($data->userid, $data->type, $data->comments);
@@ -97,11 +97,10 @@ class tool_dataprivacy_data_request_form extends \core\form\persistent {
$mform->setType('userid', PARAM_INT);
// Subject access request type.
$options = [];
if ($this->manage || api::can_create_data_download_request_for_self()) {
$options[api::DATAREQUEST_TYPE_EXPORT] = get_string('requesttypeexport', 'tool_dataprivacy');
}
$options[api::DATAREQUEST_TYPE_DELETE] = get_string('requesttypedelete', 'tool_dataprivacy');
$options = [
api::DATAREQUEST_TYPE_EXPORT => get_string('requesttypeexport', 'tool_dataprivacy'),
api::DATAREQUEST_TYPE_DELETE => get_string('requesttypedelete', 'tool_dataprivacy')
];
$mform->addElement('select', 'type', get_string('requesttype', 'tool_dataprivacy'), $options);
$mform->addHelpButton('type', 'requesttype', 'tool_dataprivacy');
@@ -175,7 +174,7 @@ class tool_dataprivacy_data_request_form extends \core\form\persistent {
$errors['type'] = get_string('errorrequestalreadyexists', 'tool_dataprivacy');
}
// Check if current user can create data requests.
// Check if current user can create data deletion request.
if ($data->type == api::DATAREQUEST_TYPE_DELETE) {
if ($userid == $USER->id) {
if (!api::can_create_data_deletion_request_for_self()) {
@@ -185,10 +184,6 @@ class tool_dataprivacy_data_request_form extends \core\form\persistent {
&& !api::can_create_data_deletion_request_for_children($userid)) {
$errors['type'] = get_string('errorcannotrequestdeleteforother', 'tool_dataprivacy');
}
} else if ($data->type == api::DATAREQUEST_TYPE_EXPORT) {
if ($userid == $USER->id && !api::can_create_data_download_request_for_self()) {
$errors['type'] = get_string('errorcannotrequestexportforself', 'tool_dataprivacy');
}
}
return $errors;
+1 -2
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="admin/tool/dataprivacy/db" VERSION="20220530" COMMENT="XMLDB file for Moodle tool/dataprivacy"
<XMLDB PATH="admin/tool/dataprivacy/db" VERSION="20191217" COMMENT="XMLDB file for Moodle tool/dataprivacy"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
>
@@ -130,7 +130,6 @@
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="purposepurposeid" TYPE="foreign" FIELDS="purposeid" REFTABLE="tool_dataprivacy_purpose" REFFIELDS="id"/>
<KEY NAME="puproseroleid" TYPE="foreign" FIELDS="roleid" REFTABLE="role" REFFIELDS="id"/>
<KEY NAME="usermodified" TYPE="foreign" FIELDS="usermodified" REFTABLE="user" REFFIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="purposerole" UNIQUE="true" FIELDS="purposeid, roleid"/>
+9 -12
View File
@@ -35,6 +35,15 @@ function xmldb_tool_dataprivacy_upgrade($oldversion) {
$dbman = $DB->get_manager();
// Automatically generated Moodle v3.6.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v3.7.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v3.8.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v3.9.0 release upgrade line.
// Put any upgrade step following this.
@@ -71,18 +80,6 @@ function xmldb_tool_dataprivacy_upgrade($oldversion) {
// Automatically generated Moodle v4.0.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2022053000) {
// Define key usermodified (foreign) to be added to tool_dataprivacy_purposerole.
$table = new xmldb_table('tool_dataprivacy_purposerole');
$key = new xmldb_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']);
// Launch add key usermodified.
$dbman->add_key($table, $key);
// Dataprivacy savepoint reached.
upgrade_plugin_savepoint(true, 2022053000, 'tool', 'dataprivacy');
}
return true;
}
@@ -135,7 +135,6 @@ $string['effectiveretentionperioduser'] = '{$a} (since the last time the user ac
$string['emailsalutation'] = 'Dear {$a},';
$string['errorcannotrequestdeleteforself'] = 'You don\'t have permission to create deletion request for yourself.';
$string['errorcannotrequestdeleteforother'] = 'You don\'t have permission to create deletion request for this user.';
$string['errorcannotrequestexportforself'] = 'You don\'t have permission to create export request for yourself.';
$string['errorcontactdpodisabled'] = 'The option to contact the privacy officer is disabled.';
$string['errorinvalidrequestcomments'] = 'The comments field may contain plain text only.';
$string['errorinvalidrequestcreationmethod'] = 'Invalid request creation method!';
@@ -232,8 +231,6 @@ $string['privacy'] = 'Privacy';
$string['privacyofficeronly'] = 'Only users who are assigned a privacy officer role ({$a}) have access to this content';
$string['privacy:metadata:preference:tool_dataprivacy_request-filters'] = 'The filters currently applied to the data requests page.';
$string['privacy:metadata:preference:tool_dataprivacy_request-perpage'] = 'The number of data requests the user prefers to see on one page';
$string['privacy:metadata:purpose'] = 'Information from data purposes made for this site.';
$string['privacy:metadata:purpose:usermodified'] = 'The ID of the user who modified the purpose';
$string['privacy:metadata:request'] = 'Information from personal data requests (subject access and deletion requests) made for this site.';
$string['privacy:metadata:request:comments'] = 'Any user comments accompanying the request.';
$string['privacy:metadata:request:userid'] = 'The ID of the user to whom the request belongs';
+2 -3
View File
@@ -68,9 +68,8 @@ function tool_dataprivacy_myprofile_navigation(tree $tree, $user, $iscurrentuser
// Check if the user has an ongoing data export request.
$hasexportrequest = \tool_dataprivacy\api::has_ongoing_request($user->id, \tool_dataprivacy\api::DATAREQUEST_TYPE_EXPORT);
// Show data export link only if the user doesn't have an ongoing data export request and has permission
// to download own data.
if (!$hasexportrequest && \tool_dataprivacy\api::can_create_data_download_request_for_self()) {
// Show data export link only if the user doesn't have an ongoing data export request.
if (!$hasexportrequest) {
$exportparams = ['type' => \tool_dataprivacy\api::DATAREQUEST_TYPE_EXPORT];
$exporturl = new moodle_url('/admin/tool/dataprivacy/createdatarequest.php', $exportparams);
$exportnode = new core_user\output\myprofile\node('privacyandpolicies', 'requestdataexport',

Some files were not shown because too many files have changed in this diff Show More