Compare commits
225 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 77be1e3fe3 | |||
| de7b3e37b3 | |||
| ffd8dfcf27 | |||
| 8a82f51043 | |||
| 68cab31dba | |||
| 3f50c24fc3 | |||
| 9973646ca7 | |||
| f14420c739 | |||
| 70868d8648 | |||
| 8f45c9b6a5 | |||
| 1f5c6c6b7a | |||
| 26999dda23 | |||
| 022206f2fe | |||
| f9e0f61467 | |||
| c07bc83480 | |||
| 7d7d3520a7 | |||
| f34f8131ba | |||
| 85ba5d1d88 | |||
| e0b8a3b17a | |||
| 5577e472e5 | |||
| 571f508d4e | |||
| 764ec8d7fb | |||
| eb04dc8792 | |||
| 6fefb88819 | |||
| 1b2a8dad89 | |||
| ec63d3eab4 | |||
| 5f4250dc43 | |||
| b024306e5c | |||
| 0d285e9334 | |||
| bed212f61b | |||
| 14d58697a3 | |||
| e98103354d | |||
| d8dfb98417 | |||
| 3684d9e03c | |||
| 629ef7772f | |||
| 9e57c09d7b | |||
| 949d3f1c02 | |||
| 11524653b0 | |||
| f9b2f6634d | |||
| dafe4c5a78 | |||
| 550c4e1c42 | |||
| 0287928c4b | |||
| 701d27e5d9 | |||
| 13d5d3edb1 | |||
| abc8f149ce | |||
| c3a6437220 | |||
| c910982c49 | |||
| 4d5849b0e4 | |||
| cc0b18ec0e | |||
| 3c7ebda9a5 | |||
| 19401adbdd | |||
| a7fb29a8ff | |||
| c53861fd66 | |||
| 88d4a01089 | |||
| b71e7b79e8 | |||
| 6c7199a426 | |||
| 827f3cd471 | |||
| 0260074ba1 | |||
| edab811944 | |||
| 348ceb4631 | |||
| 5544dc1cc7 | |||
| c02d168cd7 | |||
| 53fde6278a | |||
| 25221f73a6 | |||
| b901252f6d | |||
| be73a0ed4e | |||
| e654258446 | |||
| 8c14984028 | |||
| dd6bbf3962 | |||
| 01e84ac720 | |||
| b423c5ad38 | |||
| f70cc95a13 | |||
| d9887f7350 | |||
| f2db42f921 | |||
| b85896f7bc | |||
| 6350a758d7 | |||
| a3ea0db227 | |||
| cd62c520e2 | |||
| 86d4aca10d | |||
| 40ba9d9cfa | |||
| 5c510b92e2 | |||
| 754ecb5768 | |||
| e7a122bba9 | |||
| 13edb4f9f9 | |||
| db394d5b08 | |||
| d18802eb2f | |||
| ead3a41240 | |||
| ae7b1be0b6 | |||
| cca393d2f6 | |||
| 69430157a3 | |||
| f077d9fbea | |||
| 8c20e76d43 | |||
| a0ac535549 | |||
| 11260d5f3f | |||
| 67fc9943b9 | |||
| 29a5f6eaa2 | |||
| a6fd7ada34 | |||
| c86c872db3 | |||
| 7b4848ca80 | |||
| d9e3c11834 | |||
| 1437e35d2d | |||
| 914d5ab82d | |||
| fbf0c8810b | |||
| 25da0b49ea | |||
| 70e47fdc2a | |||
| 3bfdc05d3a | |||
| d64a94713e | |||
| 8d7f1fd428 | |||
| a7268b4f8a | |||
| 4792cc508e | |||
| 7bc625d846 | |||
| 6dc25cc165 | |||
| 747000a2fe | |||
| bec0808b18 | |||
| 7f40272535 | |||
| f9735bbde7 | |||
| 4dc1413cc7 | |||
| 79b6a4acac | |||
| cf50c5f1cb | |||
| fc74a6e6d2 | |||
| a48bd1c4e3 | |||
| ee215ddd43 | |||
| f3e7533b9d | |||
| 921469db8f | |||
| b99f2bce77 | |||
| 7df9eb36cd | |||
| aee09a6357 | |||
| 8ae7a4ad68 | |||
| d911548cf4 | |||
| c8435454a7 | |||
| df2bda2f00 | |||
| bf52b2a3bc | |||
| f130c810f9 | |||
| d294483e9c | |||
| ca89aca702 | |||
| 7e561cc4a8 | |||
| 57d601bc23 | |||
| 7cdc332930 | |||
| 484eab15e3 | |||
| 0a0d55a3e1 | |||
| 773b1f738f | |||
| 96475f49de | |||
| 9a64cc2b0b | |||
| 56c570f68a | |||
| ab2bb07f2e | |||
| d0aa6bf098 | |||
| 132e638209 | |||
| 6713912510 | |||
| 96c48a5058 | |||
| d3de95f446 | |||
| 6d98038c8f | |||
| 83e5983a88 | |||
| 0ddd9c54bc | |||
| 39bd01c11a | |||
| 1e58e180d4 | |||
| 163bff4a18 | |||
| 910c2ab7b4 | |||
| fcf199b0ec | |||
| bb511f30d6 | |||
| 481ad40e0e | |||
| 031f3a1d4b | |||
| 5548689ead | |||
| f751a8edbe | |||
| 0de719024c | |||
| ac084982cf | |||
| d3158895a8 | |||
| 0e58303ea3 | |||
| f0d380703a | |||
| baf264ebc8 | |||
| e61f7ba324 | |||
| afda296526 | |||
| 6d6b14e8a4 | |||
| 27d6bd5de1 | |||
| 907db7f06b | |||
| 33bfd161cd | |||
| f88b4e9f81 | |||
| 114f0b612f | |||
| a5f1dd6cb1 | |||
| 283cd6db67 | |||
| 3eac4851e3 | |||
| 006ec3c96f | |||
| cabc1dafa9 | |||
| 1b4c878f48 | |||
| 91286bb138 | |||
| 71af7accff | |||
| ce97501b2b | |||
| dadb3cb372 | |||
| 5cb05d8b77 | |||
| e29b355121 | |||
| 95ca6f656e | |||
| fbd1829594 | |||
| 0c91305856 | |||
| c42b488aaf | |||
| 5bde4eb35e | |||
| 1943c03bbb | |||
| 0da427c800 | |||
| 7045a22f3a | |||
| c7f9c7ae0f | |||
| 751e4964b1 | |||
| 5a108a3064 | |||
| 417ff4f035 | |||
| d3a5df14f7 | |||
| 82853489ca | |||
| 9eaea6a7bf | |||
| f11b82df7c | |||
| 5d2f8bd98d | |||
| 023109f1b1 | |||
| 51bedcee13 | |||
| 7cec76396f | |||
| daed88e656 | |||
| 212595bbd0 | |||
| 6cff678c08 | |||
| 980193f55b | |||
| b4f9c2e906 | |||
| 93ed2a597c | |||
| a2c6a69070 | |||
| 7a68a37fda | |||
| 3c1b6ed7bd | |||
| 8ff55e3b1b | |||
| 7d05f78363 | |||
| d0a9211f51 | |||
| e2a0a42003 | |||
| 7e24491f2c | |||
| 4619c8a7e3 | |||
| 2aff0046c1 |
+16
-18
@@ -9,8 +9,6 @@ cache/stores/mongodb/MongoDB/
|
||||
enrol/lti/ims-blti/
|
||||
filter/algebra/AlgParser.pm
|
||||
filter/tex/mimetex.*
|
||||
h5p/h5plib/v124/joubel/core/
|
||||
h5p/h5plib/v124/joubel/editor/
|
||||
lib/editor/atto/plugins/html/yui/src/codemirror/
|
||||
lib/editor/atto/plugins/html/yui/src/beautify/
|
||||
lib/editor/atto/yui/src/rangy/js/*.*
|
||||
@@ -63,9 +61,9 @@ lib/amd/src/popper.js
|
||||
lib/geopattern-php/
|
||||
lib/php-jwt/
|
||||
lib/babel-polyfill/
|
||||
lib/polyfills/
|
||||
lib/mdn-polyfills/
|
||||
lib/emoji-data/
|
||||
lib/plist/
|
||||
lib/h5p/
|
||||
media/player/videojs/amd/src/video-lazy.js
|
||||
media/player/videojs/amd/src/Youtube-lazy.js
|
||||
media/player/videojs/videojs/
|
||||
@@ -74,19 +72,19 @@ media/player/videojs/videojs/video-js.swf
|
||||
mod/assign/feedback/editpdf/fpdi/
|
||||
repository/s3/S3.php
|
||||
theme/boost/scss/bootstrap/
|
||||
theme/boost/amd/src/bootstrap/alert.js
|
||||
theme/boost/amd/src/bootstrap/button.js
|
||||
theme/boost/amd/src/bootstrap/carousel.js
|
||||
theme/boost/amd/src/bootstrap/collapse.js
|
||||
theme/boost/amd/src/bootstrap/dropdown.js
|
||||
theme/boost/amd/src/bootstrap/index.js
|
||||
theme/boost/amd/src/bootstrap/modal.js
|
||||
theme/boost/amd/src/bootstrap/popover.js
|
||||
theme/boost/amd/src/bootstrap/tools/sanitizer.js
|
||||
theme/boost/amd/src/bootstrap/scrollspy.js
|
||||
theme/boost/amd/src/bootstrap/tab.js
|
||||
theme/boost/amd/src/bootstrap/toast.js
|
||||
theme/boost/amd/src/bootstrap/tooltip.js
|
||||
theme/boost/amd/src/bootstrap/util.js
|
||||
theme/boost/amd/src/alert.js
|
||||
theme/boost/amd/src/button.js
|
||||
theme/boost/amd/src/carousel.js
|
||||
theme/boost/amd/src/collapse.js
|
||||
theme/boost/amd/src/dropdown.js
|
||||
theme/boost/amd/src/index.js
|
||||
theme/boost/amd/src/modal.js
|
||||
theme/boost/amd/src/popover.js
|
||||
theme/boost/amd/src/sanitizer.js
|
||||
theme/boost/amd/src/scrollspy.js
|
||||
theme/boost/amd/src/tab.js
|
||||
theme/boost/amd/src/toast.js
|
||||
theme/boost/amd/src/tooltip.js
|
||||
theme/boost/amd/src/util.js
|
||||
theme/boost/amd/src/tether.js
|
||||
theme/boost/scss/fontawesome/
|
||||
+3
-7
@@ -3,8 +3,6 @@
|
||||
"Feature": 0,
|
||||
"Background": 2,
|
||||
"Scenario": 2,
|
||||
"Examples": 4,
|
||||
"example": 6,
|
||||
"Step": 4,
|
||||
"given": 4,
|
||||
"and": 4
|
||||
@@ -16,9 +14,7 @@
|
||||
"no-multiple-empty-lines": "on",
|
||||
"no-partially-commented-tag-lines": "on",
|
||||
"no-trailing-spaces": "on",
|
||||
"no-unnamed-features": "on",
|
||||
"no-unnamed-scenarios": "on",
|
||||
"no-scenario-outlines-without-examples": "on",
|
||||
"no-examples-in-scenarios": "on",
|
||||
"new-line-at-eof": ["on", "yes"]
|
||||
"no-unamed-features": "on",
|
||||
"no-unamed-scenarios": "on",
|
||||
"no-scenario-outlines-without-examples": "on"
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
# Primary donations pages.
|
||||
custom: ["https://moodle.com/donations/", moodle.org]
|
||||
@@ -1,71 +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/>.
|
||||
|
||||
/**
|
||||
* Template configuraton file for github actions CI/CD.
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2020 onwards Eloy Lafuente (stronk7) {@link https://stronk7.com}
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
// This cannot be used out from a github actions workflow, so just exit.
|
||||
getenv('GITHUB_WORKFLOW') || die; // phpcs:ignore moodle.Files.MoodleInternal.MoodleInternalGlobalState
|
||||
|
||||
unset($CFG);
|
||||
global $CFG;
|
||||
$CFG = new stdClass();
|
||||
|
||||
$CFG->dbtype = getenv('dbtype');
|
||||
$CFG->dblibrary = 'native';
|
||||
$CFG->dbhost = '127.0.0.1';
|
||||
$CFG->dbname = 'test';
|
||||
$CFG->dbuser = 'test';
|
||||
$CFG->dbpass = 'test';
|
||||
$CFG->prefix = 'm_';
|
||||
$CFG->dboptions = ['dbcollation' => 'utf8mb4_bin'];
|
||||
|
||||
$host = 'localhost';
|
||||
$CFG->wwwroot = "http://{$host}";
|
||||
$CFG->dataroot = realpath(dirname(__DIR__)) . '/moodledata';
|
||||
$CFG->admin = 'admin';
|
||||
$CFG->directorypermissions = 0777;
|
||||
|
||||
// Debug options - possible to be controlled by flag in future.
|
||||
$CFG->debug = (E_ALL | E_STRICT); // DEBUG_DEVELOPER.
|
||||
$CFG->debugdisplay = 1;
|
||||
$CFG->debugstringids = 1; // Add strings=1 to url to get string ids.
|
||||
$CFG->perfdebug = 15;
|
||||
$CFG->debugpageinfo = 1;
|
||||
$CFG->allowthemechangeonurl = 1;
|
||||
$CFG->passwordpolicy = 0;
|
||||
$CFG->cronclionly = 0;
|
||||
$CFG->pathtophp = getenv('pathtophp');
|
||||
|
||||
$CFG->phpunit_dataroot = realpath(dirname(__DIR__)) . '/phpunitdata';
|
||||
$CFG->phpunit_prefix = 't_';
|
||||
|
||||
define('TEST_EXTERNAL_FILES_HTTP_URL', 'http://localhost:8080');
|
||||
define('TEST_EXTERNAL_FILES_HTTPS_URL', 'http://localhost:8080');
|
||||
|
||||
define('TEST_SESSION_REDIS_HOST', 'localhost');
|
||||
define('TEST_CACHESTORE_REDIS_TESTSERVERS', 'localhost');
|
||||
|
||||
// TODO: add others (solr, mongodb, memcached, ldap...).
|
||||
|
||||
// Too much for now: define('PHPUNIT_LONGTEST', true); // Only leaves a few tests out and they are run later by CI.
|
||||
|
||||
require_once(__DIR__ . '/lib/setup.php');
|
||||
@@ -1,103 +0,0 @@
|
||||
name: Core
|
||||
|
||||
on: [push]
|
||||
|
||||
env:
|
||||
php: 7.4
|
||||
|
||||
jobs:
|
||||
Grunt:
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
steps:
|
||||
- name: Checking out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Configuring node & npm
|
||||
shell: bash -l {0}
|
||||
run: nvm install
|
||||
|
||||
- name: Installing node stuff
|
||||
run: npm install
|
||||
|
||||
- name: Running grunt
|
||||
run: npx grunt
|
||||
|
||||
- name: Looking for uncommitted changes
|
||||
# Add all files to the git index and then run diff --cached to see all changes.
|
||||
# This ensures that we get the status of all files, including new files.
|
||||
# We ignore npm-shrinkwrap.json to make the tasks immune to npm changes.
|
||||
run: |
|
||||
git add .
|
||||
git reset -- npm-shrinkwrap.json
|
||||
git diff --cached --exit-code
|
||||
|
||||
PHPUnit:
|
||||
runs-on: ${{ matrix.os }}
|
||||
services:
|
||||
exttests:
|
||||
image: moodlehq/moodle-exttests
|
||||
ports:
|
||||
- 8080:80
|
||||
redis:
|
||||
image: redis
|
||||
ports:
|
||||
- 6379:6379
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
php: 7.2
|
||||
db: mysqli
|
||||
- os: ubuntu-18.04
|
||||
php: 7.4
|
||||
db: pgsql
|
||||
|
||||
steps:
|
||||
- name: Setting up DB mysql
|
||||
if: ${{ matrix.db == 'mysqli' }}
|
||||
uses: johanmeiring/mysql-action@tmpfs-patch
|
||||
with:
|
||||
collation server: utf8mb4_bin
|
||||
mysql version: 5.7
|
||||
mysql database: test
|
||||
mysql user: test
|
||||
mysql password: test
|
||||
use tmpfs: true
|
||||
|
||||
- name: Setting up DB pgsql
|
||||
if: ${{ matrix.db == 'pgsql' }}
|
||||
uses: m4nu56/postgresql-action@v1
|
||||
with:
|
||||
postgresql version: 9.6
|
||||
postgresql db: test
|
||||
postgresql user: test
|
||||
postgresql password: test
|
||||
|
||||
- name: Configuring git vars
|
||||
uses: rlespinasse/github-slug-action@v3.x
|
||||
|
||||
- name: Setting up PHP ${{ matrix.php }}
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
coverage: none
|
||||
|
||||
- name: Checking out code from ${{ env.GITHUB_REF_SLUG }}
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setting up PHPUnit
|
||||
env:
|
||||
dbtype: ${{ matrix.db }}
|
||||
run: |
|
||||
echo "pathtophp=$(which php)" >> $GITHUB_ENV # Inject installed pathtophp to env. The template config needs it.
|
||||
cp .github/workflows/config-template.php config.php
|
||||
mkdir ../moodledata
|
||||
sudo locale-gen en_AU.UTF-8
|
||||
php admin/tool/phpunit/cli/init.php --no-composer-self-update
|
||||
|
||||
- name: Running PHPUnit tests
|
||||
env:
|
||||
dbtype: ${{ matrix.db }}
|
||||
run: vendor/bin/phpunit -v
|
||||
+16
-18
@@ -10,8 +10,6 @@ cache/stores/mongodb/MongoDB/
|
||||
enrol/lti/ims-blti/
|
||||
filter/algebra/AlgParser.pm
|
||||
filter/tex/mimetex.*
|
||||
h5p/h5plib/v124/joubel/core/
|
||||
h5p/h5plib/v124/joubel/editor/
|
||||
lib/editor/atto/plugins/html/yui/src/codemirror/
|
||||
lib/editor/atto/plugins/html/yui/src/beautify/
|
||||
lib/editor/atto/yui/src/rangy/js/*.*
|
||||
@@ -64,9 +62,9 @@ lib/amd/src/popper.js
|
||||
lib/geopattern-php/
|
||||
lib/php-jwt/
|
||||
lib/babel-polyfill/
|
||||
lib/polyfills/
|
||||
lib/mdn-polyfills/
|
||||
lib/emoji-data/
|
||||
lib/plist/
|
||||
lib/h5p/
|
||||
media/player/videojs/amd/src/video-lazy.js
|
||||
media/player/videojs/amd/src/Youtube-lazy.js
|
||||
media/player/videojs/videojs/
|
||||
@@ -75,19 +73,19 @@ media/player/videojs/videojs/video-js.swf
|
||||
mod/assign/feedback/editpdf/fpdi/
|
||||
repository/s3/S3.php
|
||||
theme/boost/scss/bootstrap/
|
||||
theme/boost/amd/src/bootstrap/alert.js
|
||||
theme/boost/amd/src/bootstrap/button.js
|
||||
theme/boost/amd/src/bootstrap/carousel.js
|
||||
theme/boost/amd/src/bootstrap/collapse.js
|
||||
theme/boost/amd/src/bootstrap/dropdown.js
|
||||
theme/boost/amd/src/bootstrap/index.js
|
||||
theme/boost/amd/src/bootstrap/modal.js
|
||||
theme/boost/amd/src/bootstrap/popover.js
|
||||
theme/boost/amd/src/bootstrap/tools/sanitizer.js
|
||||
theme/boost/amd/src/bootstrap/scrollspy.js
|
||||
theme/boost/amd/src/bootstrap/tab.js
|
||||
theme/boost/amd/src/bootstrap/toast.js
|
||||
theme/boost/amd/src/bootstrap/tooltip.js
|
||||
theme/boost/amd/src/bootstrap/util.js
|
||||
theme/boost/amd/src/alert.js
|
||||
theme/boost/amd/src/button.js
|
||||
theme/boost/amd/src/carousel.js
|
||||
theme/boost/amd/src/collapse.js
|
||||
theme/boost/amd/src/dropdown.js
|
||||
theme/boost/amd/src/index.js
|
||||
theme/boost/amd/src/modal.js
|
||||
theme/boost/amd/src/popover.js
|
||||
theme/boost/amd/src/sanitizer.js
|
||||
theme/boost/amd/src/scrollspy.js
|
||||
theme/boost/amd/src/tab.js
|
||||
theme/boost/amd/src/toast.js
|
||||
theme/boost/amd/src/tooltip.js
|
||||
theme/boost/amd/src/util.js
|
||||
theme/boost/amd/src/tether.js
|
||||
theme/boost/scss/fontawesome/
|
||||
+75
-48
@@ -2,59 +2,58 @@
|
||||
# process (which uses our internal CI system) this file is here for the benefit
|
||||
# of community developers git clones - see MDL-51458.
|
||||
|
||||
sudo: required
|
||||
|
||||
# We currently disable Travis notifications entirely until https://github.com/travis-ci/travis-ci/issues/4976
|
||||
# is fixed.
|
||||
notifications:
|
||||
email:
|
||||
if: env(MOODLE_EMAIL) != no
|
||||
email: false
|
||||
|
||||
language: php
|
||||
|
||||
os: linux
|
||||
|
||||
dist: xenial
|
||||
|
||||
services:
|
||||
- mysql
|
||||
- docker
|
||||
|
||||
php:
|
||||
# We only run the highest and lowest supported versions to reduce the load on travis-ci.org.
|
||||
- 7.3
|
||||
- 7.1.30 # Make this sticky because current default version (7.1.11) has a bug with redis-extension output (MDL-66062)
|
||||
|
||||
addons:
|
||||
postgresql: "9.6"
|
||||
|
||||
jobs:
|
||||
env:
|
||||
# Although we want to run these jobs and see failures as quickly as possible, we also want to get the slowest job to
|
||||
# start first so that the total run time is not too high.
|
||||
#
|
||||
# We only run MySQL on PHP 7.2, so run that first.
|
||||
# CI Tests should be second-highest in priority as these only take <= 60 seconds to run under normal circumstances.
|
||||
# Postgres is significantly is pretty reasonable in its run-time.
|
||||
|
||||
# Run CI Tests without running PHPUnit.
|
||||
- DB=none TASK=CITEST
|
||||
|
||||
# Run unit tests on Postgres
|
||||
- DB=pgsql TASK=PHPUNIT
|
||||
|
||||
# Perform an upgrade test too.
|
||||
- DB=pgsql TASK=UPGRADE
|
||||
|
||||
matrix:
|
||||
# Enable fast finish.
|
||||
# This will fail the build if a single job fails (except those in allow_failures).
|
||||
# It will not stop the jobs from running.
|
||||
fast_finish: true
|
||||
|
||||
include:
|
||||
# First all the lowest php ones (7.2)
|
||||
- php: 7.2
|
||||
env: DB=none TASK=CITEST
|
||||
- php: 7.2
|
||||
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.2
|
||||
env: DB=pgsql TASK=PHPUNIT
|
||||
|
||||
- if: env(MOODLE_DATABASE) = "mysqli" OR env(MOODLE_DATABASE) = "all"
|
||||
php: 7.2
|
||||
env: DB=mysqli TASK=PHPUNIT
|
||||
|
||||
# Then, conditionally, all the highest php ones (7.4)
|
||||
- if: env(MOODLE_PHP) = "all"
|
||||
php: 7.4
|
||||
env: DB=none TASK=CITEST
|
||||
- if: env(MOODLE_PHP) = "all"
|
||||
php: 7.4
|
||||
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: 7.4
|
||||
env: DB=pgsql TASK=PHPUNIT
|
||||
|
||||
- if: env(MOODLE_PHP) = "all" AND (env(MOODLE_DATABASE) = "mysqli" OR env(MOODLE_DATABASE) = "all")
|
||||
php: 7.4
|
||||
# Run mysql only on 7.3 - it's just too slow
|
||||
- php: 7.3
|
||||
env: DB=mysqli TASK=PHPUNIT
|
||||
# Run grunt/npm install on highest version ('node' is an alias for the latest node.js version.)
|
||||
- php: 7.2
|
||||
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
|
||||
|
||||
cache:
|
||||
directories:
|
||||
@@ -62,9 +61,8 @@ cache:
|
||||
- $HOME/.npm
|
||||
|
||||
before_install:
|
||||
- docker run -d -p 127.0.0.1:8080:80 --name exttests moodlehq/moodle-exttests
|
||||
# Avoid IPv6 default binding as service (causes redis not to start).
|
||||
- sudo service redis-server start --bind 127.0.0.1
|
||||
sudo service redis-server start --bind 127.0.0.1
|
||||
|
||||
install:
|
||||
- >
|
||||
@@ -114,7 +112,7 @@ install:
|
||||
before_script:
|
||||
- phpenv config-rm xdebug.ini
|
||||
- >
|
||||
if [ "$TASK" = 'PHPUNIT' ];
|
||||
if [ "$TASK" = 'PHPUNIT' -o "$TASK" = 'UPGRADE' ];
|
||||
then
|
||||
# Copy generic configuration in place.
|
||||
cp config-dist.php config.php ;
|
||||
@@ -171,12 +169,6 @@ before_script:
|
||||
-e "/require_once/i \\\$CFG->phpunit_dataroot = '\/home\/travis\/roots\/phpunit';" \
|
||||
-e "/require_once/i \\\$CFG->phpunit_prefix = 'p_';" \
|
||||
config.php ;
|
||||
# Enable test external resources
|
||||
sed -i \
|
||||
-e "/require_once/i \\define('TEST_EXTERNAL_FILES_HTTP_URL', 'http://127.0.0.1:8080');" \
|
||||
-e "/require_once/i \\define('TEST_EXTERNAL_FILES_HTTPS_URL', 'http://127.0.0.1:8080');" \
|
||||
config.php ;
|
||||
|
||||
# Redis cache store tests
|
||||
sed -i \
|
||||
-e "/require_once/i \\define('TEST_CACHESTORE_REDIS_TESTSERVERS', '127.0.0.1');" \
|
||||
@@ -214,7 +206,7 @@ before_script:
|
||||
# We need the official upstream for comparison
|
||||
git remote add upstream https://github.com/moodle/moodle.git;
|
||||
|
||||
git fetch upstream MOODLE_39_STABLE;
|
||||
git fetch upstream MOODLE_38_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`
|
||||
@@ -225,6 +217,32 @@ before_script:
|
||||
export phpcmd=`which php`;
|
||||
fi
|
||||
|
||||
########################################################################
|
||||
# Upgrade test
|
||||
########################################################################
|
||||
- >
|
||||
if [ "$TASK" = 'UPGRADE' ];
|
||||
then
|
||||
# We need the official upstream.
|
||||
git remote add upstream https://github.com/moodle/moodle.git;
|
||||
|
||||
# Checkout 30 STABLE branch (the first version compatible with PHP 7.x)
|
||||
git fetch upstream MOODLE_30_STABLE;
|
||||
git checkout MOODLE_30_STABLE;
|
||||
|
||||
# Perform the upgrade
|
||||
php admin/cli/install_database.php --agree-license --adminpass=Password --adminemail=admin@example.com --fullname="Upgrade test" --shortname=Upgrade;
|
||||
|
||||
# Return to the previous commit
|
||||
git checkout -;
|
||||
|
||||
# Perform the upgrade
|
||||
php admin/cli/upgrade.php --non-interactive --allow-unstable ;
|
||||
|
||||
# The local_ci repository can be used to check upgrade savepoints.
|
||||
git clone https://github.com/moodlehq/moodle-local_ci.git local/ci ;
|
||||
fi
|
||||
|
||||
script:
|
||||
- >
|
||||
if [ "$TASK" = 'PHPUNIT' ];
|
||||
@@ -250,10 +268,19 @@ script:
|
||||
git diff --cached --exit-code ;
|
||||
fi
|
||||
|
||||
after_script:
|
||||
########################################################################
|
||||
# Upgrade test
|
||||
########################################################################
|
||||
- >
|
||||
if [ "$TASK" = 'PHPUNIT' ];
|
||||
if [ "$TASK" = 'UPGRADE' ];
|
||||
then
|
||||
EXTTESTS_HITS=$(docker logs exttests 2>&1 | grep -Fv -e 'AH00558' -e '[pid 1]' | wc -l)
|
||||
echo -e "\nTest local resources number of hits: ${EXTTESTS_HITS}.\n"
|
||||
cp local/ci/check_upgrade_savepoints/check_upgrade_savepoints.php ./check_upgrade_savepoints.php
|
||||
result=`php check_upgrade_savepoints.php`;
|
||||
# Check if there are problems
|
||||
count=`echo "$result" | grep -P "ERROR|WARN" | wc -l` ;
|
||||
if (($count > 0));
|
||||
then
|
||||
echo "$result"
|
||||
exit 1 ;
|
||||
fi
|
||||
fi
|
||||
|
||||
+123
-335
@@ -20,136 +20,22 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Grunt configuration
|
||||
*/
|
||||
|
||||
/* eslint-env node */
|
||||
|
||||
/**
|
||||
* Calculate the cwd, taking into consideration the `root` option (for Windows).
|
||||
*
|
||||
* @param {Object} grunt
|
||||
* @returns {String} The current directory as best we can determine
|
||||
*/
|
||||
const getCwd = grunt => {
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
let cwd = fs.realpathSync(process.env.PWD || process.cwd());
|
||||
|
||||
// Windows users can't run grunt in a subdirectory, so allow them to set
|
||||
// the root by passing --root=path/to/dir.
|
||||
if (grunt.option('root')) {
|
||||
const root = grunt.option('root');
|
||||
if (grunt.file.exists(__dirname, root)) {
|
||||
cwd = fs.realpathSync(path.join(__dirname, root));
|
||||
grunt.log.ok('Setting root to ' + cwd);
|
||||
} else {
|
||||
grunt.fail.fatal('Setting root to ' + root + ' failed - path does not exist');
|
||||
}
|
||||
}
|
||||
|
||||
return cwd;
|
||||
};
|
||||
|
||||
/**
|
||||
* Register any stylelint tasks.
|
||||
*
|
||||
* @param {Object} grunt
|
||||
* @param {Array} files
|
||||
* @param {String} fullRunDir
|
||||
*/
|
||||
const registerStyleLintTasks = (grunt, files, fullRunDir) => {
|
||||
const getCssConfigForFiles = files => {
|
||||
return {
|
||||
stylelint: {
|
||||
css: {
|
||||
// Use a fully-qualified path.
|
||||
src: files,
|
||||
options: {
|
||||
configOverrides: {
|
||||
rules: {
|
||||
// These rules have to be disabled in .stylelintrc for scss compat.
|
||||
"at-rule-no-unknown": true,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const getScssConfigForFiles = files => {
|
||||
return {
|
||||
stylelint: {
|
||||
scss: {
|
||||
options: {syntax: 'scss'},
|
||||
src: files,
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
let hasCss = true;
|
||||
let hasScss = true;
|
||||
|
||||
if (files) {
|
||||
// Specific files were passed. Just set them up.
|
||||
grunt.config.merge(getCssConfigForFiles(files));
|
||||
grunt.config.merge(getScssConfigForFiles(files));
|
||||
} else {
|
||||
// The stylelint system does not handle the case where there was no file to lint.
|
||||
// Check whether there are any files to lint in the current directory.
|
||||
const glob = require('glob');
|
||||
|
||||
const scssSrc = [];
|
||||
glob.sync(`${fullRunDir}/**/*.scss`).forEach(path => scssSrc.push(path));
|
||||
|
||||
if (scssSrc.length) {
|
||||
grunt.config.merge(getScssConfigForFiles(scssSrc));
|
||||
} else {
|
||||
hasScss = false;
|
||||
}
|
||||
|
||||
const cssSrc = [];
|
||||
glob.sync(`${fullRunDir}/**/*.css`).forEach(path => cssSrc.push(path));
|
||||
|
||||
if (cssSrc.length) {
|
||||
grunt.config.merge(getCssConfigForFiles(cssSrc));
|
||||
} else {
|
||||
hasCss = false;
|
||||
}
|
||||
}
|
||||
|
||||
const scssTasks = ['sass'];
|
||||
if (hasScss) {
|
||||
scssTasks.unshift('stylelint:scss');
|
||||
}
|
||||
grunt.registerTask('scss', scssTasks);
|
||||
|
||||
const cssTasks = [];
|
||||
if (hasCss) {
|
||||
cssTasks.push('stylelint:css');
|
||||
}
|
||||
grunt.registerTask('rawcss', cssTasks);
|
||||
|
||||
grunt.registerTask('css', ['scss', 'rawcss']);
|
||||
};
|
||||
|
||||
/**
|
||||
* Grunt configuration.
|
||||
*
|
||||
* @param {Object} grunt
|
||||
*/
|
||||
module.exports = function(grunt) {
|
||||
const path = require('path');
|
||||
const tasks = {};
|
||||
const async = require('async');
|
||||
const DOMParser = require('xmldom').DOMParser;
|
||||
const xpath = require('xpath');
|
||||
const semver = require('semver');
|
||||
const watchman = require('fb-watchman');
|
||||
const watchmanClient = new watchman.Client();
|
||||
const fs = require('fs');
|
||||
const ComponentList = require(path.resolve('GruntfileComponents.js'));
|
||||
const sass = require('node-sass');
|
||||
var path = require('path'),
|
||||
tasks = {},
|
||||
cwd = process.env.PWD || process.cwd(),
|
||||
async = require('async'),
|
||||
DOMParser = require('xmldom').DOMParser,
|
||||
xpath = require('xpath'),
|
||||
semver = require('semver'),
|
||||
watchman = require('fb-watchman'),
|
||||
watchmanClient = new watchman.Client(),
|
||||
gruntFilePath = process.cwd();
|
||||
|
||||
// Verify the node version is new enough.
|
||||
var expected = semver.validRange(grunt.file.readJSON('package.json').engines.node);
|
||||
@@ -158,64 +44,34 @@ module.exports = function(grunt) {
|
||||
grunt.fail.fatal('Node version not satisfied. Require ' + expected + ', version installed: ' + actual);
|
||||
}
|
||||
|
||||
// Detect directories:
|
||||
// * gruntFilePath The real path on disk to this Gruntfile.js
|
||||
// * cwd The current working directory, which can be overridden by the `root` option
|
||||
// * relativeCwd The cwd, relative to the Gruntfile.js
|
||||
// * componentDirectory The root directory of the component if the cwd is in a valid component
|
||||
// * inComponent Whether the cwd is in a valid component
|
||||
// * runDir The componentDirectory or cwd if not in a component, relative to Gruntfile.js
|
||||
// * fullRunDir The full path to the runDir
|
||||
const gruntFilePath = fs.realpathSync(process.cwd());
|
||||
const cwd = getCwd(grunt);
|
||||
const relativeCwd = path.relative(gruntFilePath, cwd);
|
||||
const componentDirectory = ComponentList.getOwningComponentDirectory(relativeCwd);
|
||||
const inComponent = !!componentDirectory;
|
||||
const runDir = inComponent ? componentDirectory : relativeCwd;
|
||||
const fullRunDir = fs.realpathSync(gruntFilePath + path.sep + runDir);
|
||||
grunt.log.debug('============================================================================');
|
||||
grunt.log.debug(`= Node version: ${process.versions.node}`);
|
||||
grunt.log.debug(`= grunt version: ${grunt.package.version}`);
|
||||
grunt.log.debug(`= process.cwd: '` + process.cwd() + `'`);
|
||||
grunt.log.debug(`= process.env.PWD: '${process.env.PWD}'`);
|
||||
grunt.log.debug(`= path.sep '${path.sep}'`);
|
||||
grunt.log.debug('============================================================================');
|
||||
grunt.log.debug(`= gruntFilePath: '${gruntFilePath}'`);
|
||||
grunt.log.debug(`= relativeCwd: '${relativeCwd}'`);
|
||||
grunt.log.debug(`= componentDirectory: '${componentDirectory}'`);
|
||||
grunt.log.debug(`= inComponent: '${inComponent}'`);
|
||||
grunt.log.debug(`= runDir: '${runDir}'`);
|
||||
grunt.log.debug(`= fullRunDir: '${fullRunDir}'`);
|
||||
grunt.log.debug('============================================================================');
|
||||
|
||||
if (inComponent) {
|
||||
grunt.log.ok(`Running tasks for component directory ${componentDirectory}`);
|
||||
// Windows users can't run grunt in a subdirectory, so allow them to set
|
||||
// the root by passing --root=path/to/dir.
|
||||
if (grunt.option('root')) {
|
||||
var root = grunt.option('root');
|
||||
if (grunt.file.exists(__dirname, root)) {
|
||||
cwd = path.join(__dirname, root);
|
||||
grunt.log.ok('Setting root to ' + cwd);
|
||||
} else {
|
||||
grunt.fail.fatal('Setting root to ' + root + ' failed - path does not exist');
|
||||
}
|
||||
}
|
||||
|
||||
let files = null;
|
||||
var files = null;
|
||||
if (grunt.option('files')) {
|
||||
// Accept a comma separated list of files to process.
|
||||
files = grunt.option('files').split(',');
|
||||
}
|
||||
|
||||
// If the cwd is the amd directory in the current component then it will be empty.
|
||||
// If the cwd is a child of the component's AMD directory, the relative directory will not start with ..
|
||||
const inAMD = !path.relative(`${componentDirectory}/amd`, cwd).startsWith('..');
|
||||
var inAMD = path.basename(cwd) == 'amd';
|
||||
|
||||
// Globbing pattern for matching all AMD JS source files.
|
||||
let amdSrc = [];
|
||||
if (inComponent) {
|
||||
amdSrc.push(componentDirectory + "/amd/src/*.js");
|
||||
amdSrc.push(componentDirectory + "/amd/src/**/*.js");
|
||||
var amdSrc = [];
|
||||
if (inAMD) {
|
||||
amdSrc.push(cwd + "/src/*.js");
|
||||
amdSrc.push(cwd + "/src/**/*.js");
|
||||
} else {
|
||||
amdSrc = ComponentList.getAmdSrcGlobList();
|
||||
}
|
||||
|
||||
let yuiSrc = [];
|
||||
if (inComponent) {
|
||||
yuiSrc.push(componentDirectory + "/yui/src/**/*.js");
|
||||
} else {
|
||||
yuiSrc = ComponentList.getYuiSrcGlobList(gruntFilePath + '/');
|
||||
amdSrc.push("**/amd/src/*.js");
|
||||
amdSrc.push("**/amd/src/**/*.js");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,65 +97,40 @@ module.exports = function(grunt) {
|
||||
* @return {array} The list of thirdparty paths.
|
||||
*/
|
||||
var getThirdPartyPathsFromXML = function() {
|
||||
const thirdpartyfiles = ComponentList.getThirdPartyLibsList(gruntFilePath + '/');
|
||||
const libs = ['node_modules/', 'vendor/'];
|
||||
var thirdpartyfiles = grunt.file.expand('*/**/thirdpartylibs.xml');
|
||||
var libs = ['node_modules/', 'vendor/'];
|
||||
|
||||
thirdpartyfiles.forEach(function(file) {
|
||||
const dirname = path.dirname(file);
|
||||
var dirname = path.dirname(file);
|
||||
|
||||
const doc = new DOMParser().parseFromString(grunt.file.read(file));
|
||||
const nodes = xpath.select("/libraries/library/location/text()", doc);
|
||||
var doc = new DOMParser().parseFromString(grunt.file.read(file));
|
||||
var nodes = xpath.select("/libraries/library/location/text()", doc);
|
||||
|
||||
nodes.forEach(function(node) {
|
||||
let lib = path.posix.join(dirname, node.toString());
|
||||
if (grunt.file.isDir(lib)) {
|
||||
// Ensure trailing slash on dirs.
|
||||
lib = lib.replace(/\/?$/, '/');
|
||||
}
|
||||
nodes.forEach(function(node) {
|
||||
var lib = path.join(dirname, node.toString());
|
||||
if (grunt.file.isDir(lib)) {
|
||||
// Ensure trailing slash on dirs.
|
||||
lib = lib.replace(/\/?$/, '/');
|
||||
}
|
||||
|
||||
// Look for duplicate paths before adding to array.
|
||||
if (libs.indexOf(lib) === -1) {
|
||||
libs.push(lib);
|
||||
}
|
||||
});
|
||||
// Look for duplicate paths before adding to array.
|
||||
if (libs.indexOf(lib) === -1) {
|
||||
libs.push(lib);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return libs;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the list of feature files to pass to the gherkin linter.
|
||||
*
|
||||
* @returns {Array}
|
||||
*/
|
||||
const getGherkinLintTargets = () => {
|
||||
if (files) {
|
||||
// Specific files were requested. Only check these.
|
||||
return files;
|
||||
}
|
||||
|
||||
if (inComponent) {
|
||||
return [`${runDir}/tests/behat/*.feature`];
|
||||
}
|
||||
|
||||
return ['**/tests/behat/*.feature'];
|
||||
};
|
||||
|
||||
// Project configuration.
|
||||
grunt.initConfig({
|
||||
eslint: {
|
||||
// Even though warnings dont stop the build we don't display warnings by default because
|
||||
// at this moment we've got too many core warnings.
|
||||
// To display warnings call: grunt eslint --show-lint-warnings
|
||||
// To fail on warnings call: grunt eslint --max-lint-warnings=0
|
||||
// Also --max-lint-warnings=-1 can be used to display warnings but not fail.
|
||||
options: {
|
||||
quiet: (!grunt.option('show-lint-warnings')) && (typeof grunt.option('max-lint-warnings') === 'undefined'),
|
||||
maxWarnings: ((typeof grunt.option('max-lint-warnings') !== 'undefined') ? grunt.option('max-lint-warnings') : -1)
|
||||
},
|
||||
options: {quiet: !grunt.option('show-lint-warnings')},
|
||||
amd: {src: files ? files : amdSrc},
|
||||
// Check YUI module source files.
|
||||
yui: {src: files ? files : yuiSrc},
|
||||
yui: {src: files ? files : ['**/yui/src/**/*.js', '!*/**/yui/src/*/meta/*.js']}
|
||||
},
|
||||
babel: {
|
||||
options: {
|
||||
@@ -359,7 +190,6 @@ module.exports = function(grunt) {
|
||||
}
|
||||
},
|
||||
options: {
|
||||
implementation: sass,
|
||||
includePaths: ["theme/boost/scss/", "theme/classic/scss/"]
|
||||
}
|
||||
},
|
||||
@@ -368,72 +198,73 @@ module.exports = function(grunt) {
|
||||
nospawn: true // We need not to spawn so config can be changed dynamically.
|
||||
},
|
||||
amd: {
|
||||
files: inComponent
|
||||
? ['amd/src/*.js', 'amd/src/**/*.js']
|
||||
: ['**/amd/src/**/*.js'],
|
||||
files: ['**/amd/src/**/*.js'],
|
||||
tasks: ['amd']
|
||||
},
|
||||
boost: {
|
||||
files: [inComponent ? 'scss/**/*.scss' : 'theme/boost/scss/**/*.scss'],
|
||||
files: ['**/theme/boost/scss/**/*.scss'],
|
||||
tasks: ['scss']
|
||||
},
|
||||
rawcss: {
|
||||
files: [
|
||||
'**/*.css',
|
||||
],
|
||||
excludes: [
|
||||
'**/moodle.css',
|
||||
'**/editor.css',
|
||||
],
|
||||
files: ['**/*.css', '**/theme/**/!(moodle.css|editor.css)'],
|
||||
tasks: ['rawcss']
|
||||
},
|
||||
yui: {
|
||||
files: inComponent
|
||||
? ['yui/src/*.json', 'yui/src/**/*.js']
|
||||
: ['**/yui/src/**/*.js'],
|
||||
files: ['**/yui/src/**/*.js'],
|
||||
tasks: ['yui']
|
||||
},
|
||||
gherkinlint: {
|
||||
files: [inComponent ? 'tests/behat/*.feature' : '**/tests/behat/*.feature'],
|
||||
files: ['**/tests/behat/*.feature'],
|
||||
tasks: ['gherkinlint']
|
||||
}
|
||||
},
|
||||
shifter: {
|
||||
options: {
|
||||
recursive: true,
|
||||
// Shifter takes a relative path.
|
||||
paths: files ? files : [runDir]
|
||||
paths: files ? files : [cwd]
|
||||
}
|
||||
},
|
||||
gherkinlint: {
|
||||
options: {
|
||||
files: getGherkinLintTargets(),
|
||||
files: files ? files : ['**/tests/behat/*.feature'],
|
||||
}
|
||||
},
|
||||
stylelint: {
|
||||
scss: {
|
||||
options: {syntax: 'scss'},
|
||||
src: files ? files : ['*/**/*.scss']
|
||||
},
|
||||
css: {
|
||||
src: files ? files : ['*/**/*.css'],
|
||||
options: {
|
||||
configOverrides: {
|
||||
rules: {
|
||||
// These rules have to be disabled in .stylelintrc for scss compat.
|
||||
"at-rule-no-unknown": true,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Generate ignore files (utilising thirdpartylibs.xml data)
|
||||
*/
|
||||
tasks.ignorefiles = function() {
|
||||
// An array of paths to third party directories.
|
||||
const thirdPartyPaths = getThirdPartyPathsFromXML();
|
||||
// Generate .eslintignore.
|
||||
const eslintIgnores = [
|
||||
'# Generated by "grunt ignorefiles"',
|
||||
'*/**/yui/src/*/meta/',
|
||||
'*/**/build/',
|
||||
].concat(thirdPartyPaths);
|
||||
grunt.file.write('.eslintignore', eslintIgnores.join('\n'));
|
||||
|
||||
// Generate .stylelintignore.
|
||||
const stylelintIgnores = [
|
||||
'# Generated by "grunt ignorefiles"',
|
||||
'**/yui/build/*',
|
||||
'theme/boost/style/moodle.css',
|
||||
'theme/classic/style/moodle.css',
|
||||
].concat(thirdPartyPaths);
|
||||
grunt.file.write('.stylelintignore', stylelintIgnores.join('\n'));
|
||||
// An array of paths to third party directories.
|
||||
var thirdPartyPaths = getThirdPartyPathsFromXML();
|
||||
// Generate .eslintignore.
|
||||
var eslintIgnores = ['# Generated by "grunt ignorefiles"', '*/**/yui/src/*/meta/', '*/**/build/'].concat(thirdPartyPaths);
|
||||
grunt.file.write('.eslintignore', eslintIgnores.join('\n'));
|
||||
// Generate .stylelintignore.
|
||||
var stylelintIgnores = [
|
||||
'# Generated by "grunt ignorefiles"',
|
||||
'**/yui/build/*',
|
||||
'theme/boost/style/moodle.css',
|
||||
'theme/classic/style/moodle.css',
|
||||
].concat(thirdPartyPaths);
|
||||
grunt.file.write('.stylelintignore', stylelintIgnores.join('\n'));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -525,32 +356,19 @@ module.exports = function(grunt) {
|
||||
};
|
||||
|
||||
tasks.gherkinlint = function() {
|
||||
const done = this.async();
|
||||
const options = grunt.config('gherkinlint.options');
|
||||
var done = this.async(),
|
||||
options = grunt.config('gherkinlint.options');
|
||||
|
||||
// Grab the gherkin-lint linter and required scaffolding.
|
||||
const linter = require('gherkin-lint/dist/linter.js');
|
||||
const featureFinder = require('gherkin-lint/dist/feature-finder.js');
|
||||
const configParser = require('gherkin-lint/dist/config-parser.js');
|
||||
const formatter = require('gherkin-lint/dist/formatters/stylish.js');
|
||||
|
||||
// Run the linter.
|
||||
return linter.lint(
|
||||
featureFinder.getFeatureFiles(grunt.file.expand(options.files)),
|
||||
configParser.getConfiguration(configParser.defaultConfigFileName)
|
||||
)
|
||||
.then(results => {
|
||||
// Print the results out uncondtionally.
|
||||
formatter.printResults(results);
|
||||
|
||||
return results;
|
||||
})
|
||||
.then(results => {
|
||||
// Report on the results.
|
||||
// The done function takes a bool whereby a falsey statement causes the task to fail.
|
||||
return results.every(result => result.errors.length === 0);
|
||||
})
|
||||
.then(done); // eslint-disable-line promise/no-callback-in-promise
|
||||
var args = grunt.file.expand(options.files);
|
||||
args.unshift(path.normalize(__dirname + '/node_modules/.bin/gherkin-lint'));
|
||||
grunt.util.spawn({
|
||||
cmd: 'node',
|
||||
args: args,
|
||||
opts: {stdio: 'inherit', env: process.env}
|
||||
}, function(error, result, code) {
|
||||
// Propagate the exit code.
|
||||
done(code === 0);
|
||||
});
|
||||
};
|
||||
|
||||
tasks.startup = function() {
|
||||
@@ -610,7 +428,7 @@ module.exports = function(grunt) {
|
||||
grunt: true,
|
||||
// Run from current working dir and inherit stdio from process.
|
||||
opts: {
|
||||
cwd: fullRunDir,
|
||||
cwd: cwd,
|
||||
stdio: 'inherit'
|
||||
},
|
||||
args: [task, filesOption]
|
||||
@@ -636,26 +454,18 @@ module.exports = function(grunt) {
|
||||
);
|
||||
};
|
||||
|
||||
const originalWatchConfig = grunt.config.get(['watch']);
|
||||
const watchConfig = Object.keys(originalWatchConfig).reduce(function(carry, key) {
|
||||
var watchConfig = grunt.config.get(['watch']);
|
||||
watchConfig = Object.keys(watchConfig).reduce(function(carry, key) {
|
||||
if (key == 'options') {
|
||||
return carry;
|
||||
}
|
||||
|
||||
const value = originalWatchConfig[key];
|
||||
|
||||
const taskNames = value.tasks;
|
||||
const files = value.files;
|
||||
let excludes = [];
|
||||
if (value.excludes) {
|
||||
excludes = value.excludes;
|
||||
}
|
||||
var value = watchConfig[key];
|
||||
var fileGlobs = value.files;
|
||||
var taskNames = value.tasks;
|
||||
|
||||
taskNames.forEach(function(taskName) {
|
||||
carry[taskName] = {
|
||||
files,
|
||||
excludes,
|
||||
};
|
||||
carry[taskName] = fileGlobs;
|
||||
});
|
||||
|
||||
return carry;
|
||||
@@ -689,14 +499,12 @@ module.exports = function(grunt) {
|
||||
resp.files.forEach(function(file) {
|
||||
grunt.log.ok('File changed: ' + file.name);
|
||||
|
||||
var fullPath = fullRunDir + '/' + file.name;
|
||||
var fullPath = cwd + '/' + file.name;
|
||||
Object.keys(watchConfig).forEach(function(task) {
|
||||
|
||||
const fileGlobs = watchConfig[task].files;
|
||||
var match = fileGlobs.some(function(fileGlob) {
|
||||
return grunt.file.isMatch(`**/${fileGlob}`, fullPath);
|
||||
var fileGlobs = watchConfig[task];
|
||||
var match = fileGlobs.every(function(fileGlob) {
|
||||
return grunt.file.isMatch(fileGlob, fullPath);
|
||||
});
|
||||
|
||||
if (match) {
|
||||
// If we are watching a subdirectory then the file.name will be relative
|
||||
// to that directory. However the grunt tasks expect the file paths to be
|
||||
@@ -728,7 +536,7 @@ module.exports = function(grunt) {
|
||||
});
|
||||
|
||||
// Initiate the watch on the current directory.
|
||||
watchmanClient.command(['watch-project', fullRunDir], function(watchError, watchResponse) {
|
||||
watchmanClient.command(['watch-project', cwd], function(watchError, watchResponse) {
|
||||
if (watchError) {
|
||||
grunt.log.error('Error initiating watch:', watchError);
|
||||
watchTaskDone(1);
|
||||
@@ -750,40 +558,18 @@ module.exports = function(grunt) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate the expression query used by watchman.
|
||||
// Documentation is limited, but see https://facebook.github.io/watchman/docs/expr/allof.html for examples.
|
||||
// We generate an expression to match any value in the files list of all of our tasks, but excluding
|
||||
// all value in the excludes list of that task.
|
||||
//
|
||||
// [anyof, [
|
||||
// [allof, [
|
||||
// [anyof, [
|
||||
// ['match', validPath, 'wholename'],
|
||||
// ['match', validPath, 'wholename'],
|
||||
// ],
|
||||
// [not,
|
||||
// [anyof, [
|
||||
// ['match', invalidPath, 'wholename'],
|
||||
// ['match', invalidPath, 'wholename'],
|
||||
// ],
|
||||
// ],
|
||||
// ],
|
||||
var matchWholeName = fileGlob => ['match', fileGlob, 'wholename'];
|
||||
// Use the matching patterns specified in the watch config.
|
||||
var matches = Object.keys(watchConfig).map(function(task) {
|
||||
const matchAll = [];
|
||||
matchAll.push(['anyof'].concat(watchConfig[task].files.map(matchWholeName)));
|
||||
var fileGlobs = watchConfig[task];
|
||||
var fileGlobMatches = fileGlobs.map(function(fileGlob) {
|
||||
return ['match', fileGlob, 'wholename'];
|
||||
});
|
||||
|
||||
if (watchConfig[task].excludes.length) {
|
||||
matchAll.push(['not', ['anyof'].concat(watchConfig[task].excludes.map(matchWholeName))]);
|
||||
}
|
||||
|
||||
return ['allof'].concat(matchAll);
|
||||
return ['allof'].concat(fileGlobMatches);
|
||||
});
|
||||
|
||||
matches = ['anyof'].concat(matches);
|
||||
|
||||
var sub = {
|
||||
expression: matches,
|
||||
expression: ["anyof"].concat(matches),
|
||||
// Which fields we're interested in.
|
||||
fields: ["name", "size", "type"],
|
||||
// Add our time constraint.
|
||||
@@ -803,7 +589,7 @@ module.exports = function(grunt) {
|
||||
return;
|
||||
}
|
||||
|
||||
grunt.log.ok('Listening for changes to files in ' + fullRunDir);
|
||||
grunt.log.ok('Listening for changes to files in ' + cwd);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -848,8 +634,10 @@ module.exports = function(grunt) {
|
||||
grunt.registerTask('amd', ['eslint:amd', 'babel']);
|
||||
grunt.registerTask('js', ['amd', 'yui']);
|
||||
|
||||
// Register CSS tasks.
|
||||
registerStyleLintTasks(grunt, files, fullRunDir);
|
||||
// Register CSS taks.
|
||||
grunt.registerTask('css', ['stylelint:scss', 'sass', 'stylelint:css']);
|
||||
grunt.registerTask('scss', ['stylelint:scss', 'sass']);
|
||||
grunt.registerTask('rawcss', ['stylelint:css']);
|
||||
|
||||
// Register the startup task.
|
||||
grunt.registerTask('startup', 'Run the correct tasks for the current directory', tasks.startup);
|
||||
|
||||
@@ -1,188 +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/>.
|
||||
|
||||
/**
|
||||
* Helper functions for working with Moodle component names, directories, and sources.
|
||||
*
|
||||
* @copyright 2019 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
/* eslint-env node */
|
||||
|
||||
/** @var {Object} A list of subsystems in Moodle */
|
||||
const componentData = {};
|
||||
|
||||
/**
|
||||
* Load details of all moodle modules.
|
||||
*
|
||||
* @returns {object}
|
||||
*/
|
||||
const fetchComponentData = () => {
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const glob = require('glob');
|
||||
const gruntFilePath = process.cwd();
|
||||
|
||||
if (!Object.entries(componentData).length) {
|
||||
componentData.subsystems = {};
|
||||
componentData.pathList = [];
|
||||
|
||||
// Fetch the component definiitions from the distributed JSON file.
|
||||
const components = JSON.parse(fs.readFileSync(`${gruntFilePath}/lib/components.json`));
|
||||
|
||||
// Build the list of moodle subsystems.
|
||||
componentData.subsystems.lib = 'core';
|
||||
componentData.pathList.push(process.cwd() + path.sep + 'lib');
|
||||
for (const [component, thisPath] of Object.entries(components.subsystems)) {
|
||||
if (thisPath) {
|
||||
// Prefix "core_" to the front of the subsystems.
|
||||
componentData.subsystems[thisPath] = `core_${component}`;
|
||||
componentData.pathList.push(process.cwd() + path.sep + thisPath);
|
||||
}
|
||||
}
|
||||
|
||||
// The list of components incldues the list of subsystems.
|
||||
componentData.components = componentData.subsystems;
|
||||
|
||||
// Go through each of the plugintypes.
|
||||
Object.entries(components.plugintypes).forEach(([pluginType, pluginTypePath]) => {
|
||||
// We don't allow any code in this place..?
|
||||
glob.sync(`${pluginTypePath}/*/version.php`).forEach(versionPath => {
|
||||
const componentPath = fs.realpathSync(path.dirname(versionPath));
|
||||
const componentName = path.basename(componentPath);
|
||||
const frankenstyleName = `${pluginType}_${componentName}`;
|
||||
componentData.components[`${pluginTypePath}/${componentName}`] = frankenstyleName;
|
||||
componentData.pathList.push(componentPath);
|
||||
|
||||
// Look for any subplugins.
|
||||
const subPluginConfigurationFile = `${componentPath}/db/subplugins.json`;
|
||||
if (fs.existsSync(subPluginConfigurationFile)) {
|
||||
const subpluginList = JSON.parse(fs.readFileSync(fs.realpathSync(subPluginConfigurationFile)));
|
||||
|
||||
Object.entries(subpluginList.plugintypes).forEach(([subpluginType, subpluginTypePath]) => {
|
||||
glob.sync(`${subpluginTypePath}/*/version.php`).forEach(versionPath => {
|
||||
const componentPath = fs.realpathSync(path.dirname(versionPath));
|
||||
const componentName = path.basename(componentPath);
|
||||
const frankenstyleName = `${subpluginType}_${componentName}`;
|
||||
|
||||
componentData.components[`${subpluginTypePath}/${componentName}`] = frankenstyleName;
|
||||
componentData.pathList.push(componentPath);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return componentData;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the list of paths to build AMD sources.
|
||||
*
|
||||
* @returns {Array}
|
||||
*/
|
||||
const getAmdSrcGlobList = () => {
|
||||
const globList = [];
|
||||
fetchComponentData().pathList.forEach(componentPath => {
|
||||
globList.push(`${componentPath}/amd/src/*.js`);
|
||||
globList.push(`${componentPath}/amd/src/**/*.js`);
|
||||
});
|
||||
|
||||
return globList;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the list of paths to build YUI sources.
|
||||
*
|
||||
* @param {String} relativeTo
|
||||
* @returns {Array}
|
||||
*/
|
||||
const getYuiSrcGlobList = relativeTo => {
|
||||
const globList = [];
|
||||
fetchComponentData().pathList.forEach(componentPath => {
|
||||
const relativeComponentPath = componentPath.replace(relativeTo, '');
|
||||
globList.push(`${relativeComponentPath}/yui/src/**/*.js`);
|
||||
});
|
||||
|
||||
return globList;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the list of paths to thirdpartylibs.xml.
|
||||
*
|
||||
* @param {String} relativeTo
|
||||
* @returns {Array}
|
||||
*/
|
||||
const getThirdPartyLibsList = relativeTo => {
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
return fetchComponentData().pathList
|
||||
.map(componentPath => path.relative(relativeTo, componentPath) + '/thirdpartylibs.xml')
|
||||
.map(componentPath => componentPath.replace(/\\/g, '/'))
|
||||
.filter(path => fs.existsSync(path))
|
||||
.sort();
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the name of the component matching the specified path.
|
||||
*
|
||||
* @param {String} path
|
||||
* @returns {String|null} Name of matching component.
|
||||
*/
|
||||
const getComponentFromPath = path => {
|
||||
const componentList = fetchComponentData().components;
|
||||
|
||||
if (componentList.hasOwnProperty(path)) {
|
||||
return componentList[path];
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether the supplied path, relative to the Gruntfile.js, is in a known component.
|
||||
*
|
||||
* @param {String} checkPath The path to check. This can be with either Windows, or Linux directory separators.
|
||||
* @returns {String|null}
|
||||
*/
|
||||
const getOwningComponentDirectory = checkPath => {
|
||||
const path = require('path');
|
||||
|
||||
// Fetch all components into a reverse sorted array.
|
||||
// This ensures that components which are within the directory of another component match first.
|
||||
const pathList = Object.keys(fetchComponentData().components).sort().reverse();
|
||||
for (const componentPath of pathList) {
|
||||
// If the componentPath is the directory being checked, it will be empty.
|
||||
// If the componentPath is a parent of the directory being checked, the relative directory will not start with ..
|
||||
if (!path.relative(componentPath, checkPath).startsWith('..')) {
|
||||
return componentPath;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getAmdSrcGlobList,
|
||||
getComponentFromPath,
|
||||
getOwningComponentDirectory,
|
||||
getYuiSrcGlobList,
|
||||
getThirdPartyLibsList,
|
||||
};
|
||||
@@ -98,10 +98,8 @@ switch ($action) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
$new = implode(',', $activeantiviruses);
|
||||
add_to_config_log('antiviruses', $CFG->antiviruses, $new, 'core');
|
||||
set_config('antiviruses', $new);
|
||||
|
||||
set_config('antiviruses', implode(',', $activeantiviruses));
|
||||
core_plugin_manager::reset_caches();
|
||||
|
||||
redirect ($returnurl);
|
||||
redirect ($returnurl);
|
||||
@@ -178,7 +178,6 @@ class filesize extends \admin_setting {
|
||||
'id' => $this->get_id(),
|
||||
'name' => $this->get_full_name(),
|
||||
'value' => $data['v'],
|
||||
'readonly' => $this->is_readonly(),
|
||||
'options' => array_map(function($unit, $title) use ($data, $defaultunit) {
|
||||
return [
|
||||
'value' => $unit,
|
||||
|
||||
@@ -1,122 +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/>.
|
||||
|
||||
/**
|
||||
* Task executor for adhoc tasks.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage cli
|
||||
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @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(
|
||||
[
|
||||
'execute' => false,
|
||||
'help' => false,
|
||||
'keep-alive' => 0,
|
||||
'showsql' => false,
|
||||
'showdebugging' => false,
|
||||
'ignorelimits' => false,
|
||||
], [
|
||||
'h' => 'help',
|
||||
'e' => 'execute',
|
||||
'k' => 'keep-alive',
|
||||
'i' => 'ignorelimits',
|
||||
]
|
||||
);
|
||||
|
||||
if ($unrecognized) {
|
||||
$unrecognized = implode("\n ", $unrecognized);
|
||||
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
|
||||
}
|
||||
|
||||
if ($options['help'] or empty($options['execute'])) {
|
||||
$help = <<<EOT
|
||||
Ad hoc cron tasks.
|
||||
|
||||
Options:
|
||||
-h, --help Print out this help
|
||||
--showsql Show sql queries before they are executed
|
||||
--showdebugging Show developer level debugging information
|
||||
-e, --execute Run all queued adhoc tasks
|
||||
-k, --keep-alive=N Keep this script alive for N seconds and poll for new adhoc tasks
|
||||
-i --ignorelimits Ignore task_adhoc_concurrency_limit and task_adhoc_max_runtime limits
|
||||
|
||||
Example:
|
||||
\$sudo -u www-data /usr/bin/php admin/cli/adhoc_task.php --execute
|
||||
|
||||
EOT;
|
||||
|
||||
echo $help;
|
||||
die;
|
||||
}
|
||||
|
||||
if ($options['showdebugging']) {
|
||||
set_debugging(DEBUG_DEVELOPER, true);
|
||||
}
|
||||
|
||||
if ($options['showsql']) {
|
||||
$DB->set_debug(true);
|
||||
}
|
||||
|
||||
if (CLI_MAINTENANCE) {
|
||||
echo "CLI maintenance mode active, cron execution suspended.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (moodle_needs_upgrading()) {
|
||||
echo "Moodle upgrade pending, cron execution suspended.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (empty($options['execute'])) {
|
||||
exit(0);
|
||||
}
|
||||
if (empty($options['keep-alive'])) {
|
||||
$options['keep-alive'] = 0;
|
||||
}
|
||||
|
||||
if (!empty($CFG->showcronsql)) {
|
||||
$DB->set_debug(true);
|
||||
}
|
||||
if (!empty($CFG->showcrondebugging)) {
|
||||
set_debugging(DEBUG_DEVELOPER, true);
|
||||
}
|
||||
|
||||
$checklimits = empty($options['ignorelimits']);
|
||||
|
||||
core_php_time_limit::raise();
|
||||
|
||||
// Increase memory limit.
|
||||
raise_memory_limit(MEMORY_EXTRA);
|
||||
|
||||
// Emulate normal session - we use admin account by default.
|
||||
cron_setup_user();
|
||||
|
||||
$humantimenow = date('r', time());
|
||||
$keepalive = (int)$options['keep-alive'];
|
||||
|
||||
\core\local\cli\shutdown::script_supports_graceful_exit();
|
||||
|
||||
mtrace("Server Time: {$humantimenow}\n");
|
||||
cron_run_adhoc_tasks(time(), $keepalive, $checklimits);
|
||||
+1
-6
@@ -124,12 +124,7 @@ if ($options['unset'] || $options['set'] !== null) {
|
||||
cli_error('The configuration variable is hard-set in the config.php, unable to change.', 4);
|
||||
}
|
||||
|
||||
$new = $options['set'];
|
||||
$old = get_config($options['component'], $options['name']);
|
||||
if ($new !== $old) {
|
||||
set_config($options['name'], $options['set'], $options['component']);
|
||||
add_to_config_log($options['name'], $old, $new, $options['component']);
|
||||
}
|
||||
set_config($options['name'], $options['set'], $options['component']);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,171 +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 tool for system checks
|
||||
*
|
||||
* @package core
|
||||
* @category check
|
||||
* @copyright 2020 Brendan Heywood (brendan@catalyst-au.net)
|
||||
* @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');
|
||||
|
||||
use core\check\result;
|
||||
|
||||
list($options, $unrecognized) = cli_get_params([
|
||||
'help' => false,
|
||||
'filter' => '',
|
||||
'type' => 'status',
|
||||
'verbose' => false,
|
||||
], [
|
||||
'h' => 'help',
|
||||
'f' => 'filter',
|
||||
'v' => 'verbose',
|
||||
't' => 'type',
|
||||
]);
|
||||
|
||||
if ($unrecognized) {
|
||||
$unrecognized = implode("\n ", $unrecognized);
|
||||
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
|
||||
}
|
||||
|
||||
$checks = \core\check\manager::get_checks($options['type']);
|
||||
$types = join(', ', \core\check\manager::TYPES);
|
||||
|
||||
$help = "Run Moodle system checks
|
||||
|
||||
Options:
|
||||
-h, --help Print out this help
|
||||
-f, --filter Filter to a subset of checks
|
||||
-t, --type Which set of checks? Defaults to 'status'
|
||||
One of $types
|
||||
-v, --verbose Show details of all checks, not just failed checks
|
||||
|
||||
Example:
|
||||
|
||||
sudo -u www-data php admin/cli/checks.php
|
||||
sudo -u www-data php admin/cli/checks.php -v
|
||||
sudo -u www-data php admin/cli/checks.php -v --filter=environment
|
||||
|
||||
";
|
||||
|
||||
if ($options['help']) {
|
||||
echo $help;
|
||||
die();
|
||||
}
|
||||
|
||||
$filter = $options['filter'];
|
||||
if ($filter) {
|
||||
$checks = array_filter($checks, function($check, $key) use ($filter) {
|
||||
$ref = $check->get_ref();
|
||||
return (strpos($ref, $filter) !== false);
|
||||
}, 1);
|
||||
}
|
||||
|
||||
// These shell exit codes and labels align with the NRPE standard.
|
||||
$exitcodes = [
|
||||
result::NA => 0,
|
||||
result::OK => 0,
|
||||
result::INFO => 0,
|
||||
result::UNKNOWN => 3,
|
||||
result::WARNING => 1,
|
||||
result::ERROR => 2,
|
||||
result::CRITICAL => 2,
|
||||
];
|
||||
$exitlabel = [
|
||||
result::NA => 'OK',
|
||||
result::OK => 'OK',
|
||||
result::INFO => 'OK',
|
||||
result::UNKNOWN => 'UNKNOWN',
|
||||
result::WARNING => 'WARNING',
|
||||
result::ERROR => 'CRITICAL',
|
||||
result::CRITICAL => 'CRITICAL',
|
||||
];
|
||||
|
||||
$format = "% 10s| % -60s\n";
|
||||
$spacer = "----------+--------------------------------------------------------------------\n";
|
||||
$prefix = ' |';
|
||||
|
||||
$output = '';
|
||||
$header = $exitlabel[result::OK] . ': ' . get_string('checksok', '', $options['type']) . "\n";
|
||||
$exitcode = $exitcodes[result::OK];
|
||||
|
||||
foreach ($checks as $check) {
|
||||
$ref = $check->get_ref();
|
||||
$result = $check->get_result();
|
||||
|
||||
$status = $result->get_status();
|
||||
$checkexitcode = $exitcodes[$status];
|
||||
|
||||
// Summary is treated as html.
|
||||
$summary = $result->get_summary();
|
||||
$summary = html_to_text($summary, 60, false);
|
||||
|
||||
if ($checkexitcode > $exitcode) {
|
||||
$exitcode = $checkexitcode;
|
||||
$header = $exitlabel[$status] . ': ' . $check->get_name() . " (" . $check->get_ref() . ")\n";
|
||||
}
|
||||
|
||||
if (empty($messages[$status])) {
|
||||
$messages[$status] = $result;
|
||||
}
|
||||
|
||||
$len = strlen(get_string('status' . $status));
|
||||
|
||||
if ($options['verbose'] ||
|
||||
$status == result::WARNING ||
|
||||
$status == result::CRITICAL ||
|
||||
$status == result::ERROR) {
|
||||
|
||||
$output .= sprintf(
|
||||
$format,
|
||||
$OUTPUT->check_result($result),
|
||||
sprintf('%s (%s)', $check->get_name(), $ref)
|
||||
);
|
||||
|
||||
$summary = str_replace("\n", "\n" . $prefix . ' ', $summary);
|
||||
$output .= sprintf( $format, '', ' ' . $summary);
|
||||
|
||||
if ($options['verbose']) {
|
||||
$actionlink = $check->get_action_link();
|
||||
if ($actionlink) {
|
||||
$output .= sprintf( $format, '', ' ' . $actionlink->url);
|
||||
}
|
||||
$output .= sprintf( $format, '', '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print NRPE header.
|
||||
print $header;
|
||||
|
||||
// Only show the table header if there is anything to show.
|
||||
if ($output) {
|
||||
print sprintf($format,
|
||||
get_string('status'). ' ',
|
||||
get_string('check')
|
||||
) . $spacer;
|
||||
print $output;
|
||||
}
|
||||
|
||||
// NRPE shell exit code.
|
||||
exit($exitcode);
|
||||
|
||||
+2
-20
@@ -35,16 +35,8 @@ require_once($CFG->libdir.'/clilib.php'); // cli only functions
|
||||
require_once($CFG->libdir.'/cronlib.php');
|
||||
|
||||
// now get cli options
|
||||
list($options, $unrecognized) = cli_get_params(
|
||||
array(
|
||||
'help' => false,
|
||||
'stop' => false,
|
||||
),
|
||||
array(
|
||||
'h' => 'help',
|
||||
's' => 'stop',
|
||||
)
|
||||
);
|
||||
list($options, $unrecognized) = cli_get_params(array('help'=>false),
|
||||
array('h'=>'help'));
|
||||
|
||||
if ($unrecognized) {
|
||||
$unrecognized = implode("\n ", $unrecognized);
|
||||
@@ -57,7 +49,6 @@ if ($options['help']) {
|
||||
|
||||
Options:
|
||||
-h, --help Print out this help
|
||||
-s, --stop Notify all other running cron processes to stop after the current task
|
||||
|
||||
Example:
|
||||
\$sudo -u www-data /usr/bin/php admin/cli/cron.php
|
||||
@@ -67,13 +58,4 @@ Example:
|
||||
die;
|
||||
}
|
||||
|
||||
if ($options['stop']) {
|
||||
// By clearing the caches this signals to other running processes
|
||||
// to exit after finishing the current task.
|
||||
\core\task\manager::clear_static_caches();
|
||||
die;
|
||||
}
|
||||
|
||||
\core\local\cli\shutdown::script_supports_graceful_exit();
|
||||
|
||||
cron_run();
|
||||
|
||||
+97
-107
@@ -215,7 +215,6 @@ define('SITEID', 1);
|
||||
|
||||
//Database types
|
||||
$databases = array('mysqli' => moodle_database::get_driver_instance('mysqli', 'native'),
|
||||
'auroramysql' => moodle_database::get_driver_instance('auroramysql', 'native'),
|
||||
'mariadb'=> moodle_database::get_driver_instance('mariadb', 'native'),
|
||||
'pgsql' => moodle_database::get_driver_instance('pgsql', 'native'),
|
||||
'oci' => moodle_database::get_driver_instance('oci', 'native'),
|
||||
@@ -267,7 +266,6 @@ list($options, $unrecognized) = cli_get_params(
|
||||
);
|
||||
|
||||
$interactive = empty($options['non-interactive']);
|
||||
$skipdatabase = $options['skip-database'];
|
||||
|
||||
// set up language
|
||||
$lang = clean_param($options['lang'], PARAM_SAFEDIR);
|
||||
@@ -639,100 +637,96 @@ do {
|
||||
}
|
||||
} while ($hintdatabase !== '');
|
||||
|
||||
// If --skip-database option is provided, we do not need to ask for site fullname, shortname, adminuser, adminpass, adminemail.
|
||||
// These fields will be requested during the database install part.
|
||||
if (!$skipdatabase) {
|
||||
// Ask for fullname.
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
cli_heading(get_string('fullsitename', 'moodle'));
|
||||
// ask for fullname
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
cli_heading(get_string('fullsitename', 'moodle'));
|
||||
|
||||
if ($options['fullname'] !== '') {
|
||||
$prompt = get_string('clitypevaluedefault', 'admin', $options['fullname']);
|
||||
} else {
|
||||
$prompt = get_string('clitypevalue', 'admin');
|
||||
}
|
||||
|
||||
do {
|
||||
$options['fullname'] = cli_input($prompt, $options['fullname']);
|
||||
} while (empty($options['fullname']));
|
||||
if ($options['fullname'] !== '') {
|
||||
$prompt = get_string('clitypevaluedefault', 'admin', $options['fullname']);
|
||||
} else {
|
||||
if (empty($options['fullname'])) {
|
||||
$a = (object)['option' => 'fullname', 'value' => $options['fullname']];
|
||||
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
|
||||
}
|
||||
}
|
||||
|
||||
// Ask for shortname.
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
cli_heading(get_string('shortsitename', 'moodle'));
|
||||
|
||||
if ($options['shortname'] !== '') {
|
||||
$prompt = get_string('clitypevaluedefault', 'admin', $options['shortname']);
|
||||
} else {
|
||||
$prompt = get_string('clitypevalue', 'admin');
|
||||
}
|
||||
|
||||
do {
|
||||
$options['shortname'] = cli_input($prompt, $options['shortname']);
|
||||
} while (empty($options['shortname']));
|
||||
} else {
|
||||
if (empty($options['shortname'])) {
|
||||
$a = (object)['option' => 'shortname', 'value' => $options['shortname']];
|
||||
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
|
||||
}
|
||||
}
|
||||
|
||||
// Ask for admin user name.
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
cli_heading(get_string('cliadminusername', 'install'));
|
||||
if (!empty($options['adminuser'])) {
|
||||
$prompt = get_string('clitypevaluedefault', 'admin', $options['adminuser']);
|
||||
} else {
|
||||
$prompt = get_string('clitypevalue', 'admin');
|
||||
}
|
||||
do {
|
||||
$options['adminuser'] = cli_input($prompt, $options['adminuser']);
|
||||
} while (empty($options['adminuser']) or $options['adminuser'] === 'guest');
|
||||
} else {
|
||||
if ((empty($options['adminuser']) || $options['adminuser'] === 'guest')) {
|
||||
$a = (object)['option' => 'adminuser', 'value' => $options['adminuser']];
|
||||
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
|
||||
}
|
||||
}
|
||||
|
||||
// Ask for admin user password.
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
cli_heading(get_string('cliadminpassword', 'install'));
|
||||
$prompt = get_string('clitypevalue', 'admin');
|
||||
do {
|
||||
$options['adminpass'] = cli_input($prompt);
|
||||
} while (empty($options['adminpass']) or $options['adminpass'] === 'admin');
|
||||
} else {
|
||||
if ((empty($options['adminpass']) or $options['adminpass'] === 'admin')) {
|
||||
$a = (object)['option' => 'adminpass', 'value' => $options['adminpass']];
|
||||
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
|
||||
}
|
||||
}
|
||||
|
||||
// Ask for the admin email address.
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
cli_heading(get_string('cliadminemail', 'install'));
|
||||
$prompt = get_string('clitypevaluedefault', 'admin', $options['adminemail']);
|
||||
$options['adminemail'] = cli_input($prompt, $options['adminemail']);
|
||||
}
|
||||
|
||||
// Validate that the address provided was an e-mail address.
|
||||
if (!empty($options['adminemail']) && !validate_email($options['adminemail'])) {
|
||||
$a = (object)['option' => 'adminemail', 'value' => $options['adminemail']];
|
||||
do {
|
||||
$options['fullname'] = cli_input($prompt, $options['fullname']);
|
||||
} while (empty($options['fullname']));
|
||||
} else {
|
||||
if (empty($options['fullname'])) {
|
||||
$a = (object)array('option'=>'fullname', 'value'=>$options['fullname']);
|
||||
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
|
||||
}
|
||||
}
|
||||
|
||||
// ask for shortname
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
cli_heading(get_string('shortsitename', 'moodle'));
|
||||
|
||||
if ($options['shortname'] !== '') {
|
||||
$prompt = get_string('clitypevaluedefault', 'admin', $options['shortname']);
|
||||
} else {
|
||||
$prompt = get_string('clitypevalue', 'admin');
|
||||
}
|
||||
|
||||
do {
|
||||
$options['shortname'] = cli_input($prompt, $options['shortname']);
|
||||
} while (empty($options['shortname']));
|
||||
} else {
|
||||
if (empty($options['shortname'])) {
|
||||
$a = (object)array('option'=>'shortname', 'value'=>$options['shortname']);
|
||||
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
|
||||
}
|
||||
}
|
||||
|
||||
// ask for admin user name
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
cli_heading(get_string('cliadminusername', 'install'));
|
||||
if (!empty($options['adminuser'])) {
|
||||
$prompt = get_string('clitypevaluedefault', 'admin', $options['adminuser']);
|
||||
} else {
|
||||
$prompt = get_string('clitypevalue', 'admin');
|
||||
}
|
||||
do {
|
||||
$options['adminuser'] = cli_input($prompt, $options['adminuser']);
|
||||
} while (empty($options['adminuser']) or $options['adminuser'] === 'guest');
|
||||
} else {
|
||||
if (empty($options['adminuser']) or $options['adminuser'] === 'guest') {
|
||||
$a = (object)array('option'=>'adminuser', 'value'=>$options['adminuser']);
|
||||
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
|
||||
}
|
||||
}
|
||||
|
||||
// ask for admin user password
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
cli_heading(get_string('cliadminpassword', 'install'));
|
||||
$prompt = get_string('clitypevalue', 'admin');
|
||||
do {
|
||||
$options['adminpass'] = cli_input($prompt);
|
||||
} while (empty($options['adminpass']) or $options['adminpass'] === 'admin');
|
||||
} else {
|
||||
if (empty($options['adminpass']) or $options['adminpass'] === 'admin') {
|
||||
$a = (object)array('option'=>'adminpass', 'value'=>$options['adminpass']);
|
||||
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
|
||||
}
|
||||
}
|
||||
|
||||
// Ask for the admin email address.
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
cli_heading(get_string('cliadminemail', 'install'));
|
||||
$prompt = get_string('clitypevaluedefault', 'admin', $options['adminemail']);
|
||||
$options['adminemail'] = cli_input($prompt, $options['adminemail']);
|
||||
}
|
||||
|
||||
// Validate that the address provided was an e-mail address.
|
||||
if (!empty($options['adminemail']) && !validate_email($options['adminemail'])) {
|
||||
$a = (object) array('option' => 'adminemail', 'value' => $options['adminemail']);
|
||||
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
|
||||
}
|
||||
|
||||
// Ask for the upgrade key.
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
@@ -751,27 +745,23 @@ if ($options['upgradekey'] !== '') {
|
||||
$CFG->upgradekey = $options['upgradekey'];
|
||||
}
|
||||
|
||||
// The user does not also need to pass agree-license when --skip-database is provided as the user will need to accept
|
||||
// the license again in the database install part.
|
||||
if (!$skipdatabase) {
|
||||
if ($interactive) {
|
||||
if (!$options['agree-license']) {
|
||||
cli_separator();
|
||||
cli_heading(get_string('copyrightnotice'));
|
||||
echo "Moodle - Modular Object-Oriented Dynamic Learning Environment\n";
|
||||
echo get_string('gpl3')."\n\n";
|
||||
echo get_string('doyouagree')."\n";
|
||||
$prompt = get_string('cliyesnoprompt', 'admin');
|
||||
$input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin')));
|
||||
if ($input == get_string('clianswerno', 'admin')) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!$options['agree-license'] && !$skipdatabase) {
|
||||
cli_error(get_string('climustagreelicense', 'install'));
|
||||
if ($interactive) {
|
||||
if (!$options['agree-license']) {
|
||||
cli_separator();
|
||||
cli_heading(get_string('copyrightnotice'));
|
||||
echo "Moodle - Modular Object-Oriented Dynamic Learning Environment\n";
|
||||
echo get_string('gpl3')."\n\n";
|
||||
echo get_string('doyouagree')."\n";
|
||||
$prompt = get_string('cliyesnoprompt', 'admin');
|
||||
$input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin')));
|
||||
if ($input == get_string('clianswerno', 'admin')) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!$options['agree-license']) {
|
||||
cli_error(get_string('climustagreelicense', 'install'));
|
||||
}
|
||||
}
|
||||
|
||||
// Finally we have all info needed for config.php
|
||||
@@ -819,7 +809,7 @@ if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
|
||||
cli_error(get_string('pluginschecktodo', 'admin'));
|
||||
}
|
||||
|
||||
if (!$skipdatabase) {
|
||||
if (!$options['skip-database']) {
|
||||
install_cli_database($options, $interactive);
|
||||
// This needs to happen at the end to ensure it occurs after all caches
|
||||
// have been purged for the last time.
|
||||
|
||||
@@ -1,151 +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 task execution.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage cli
|
||||
* @copyright 2014 Petr Skoda
|
||||
* @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(
|
||||
array('help' => false, 'list' => false, 'execute' => false, 'showsql' => false, 'showdebugging' => false),
|
||||
array('h' => 'help')
|
||||
);
|
||||
|
||||
if ($unrecognized) {
|
||||
$unrecognized = implode("\n ", $unrecognized);
|
||||
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
|
||||
}
|
||||
|
||||
if ($options['help'] or (!$options['list'] and !$options['execute'])) {
|
||||
$help =
|
||||
"Scheduled cron tasks.
|
||||
|
||||
Options:
|
||||
--execute=\\some\\task Execute scheduled task manually
|
||||
--list List all scheduled tasks
|
||||
--showsql Show sql queries before they are executed
|
||||
--showdebugging Show developer level debugging information
|
||||
-h, --help Print out this help
|
||||
|
||||
Example:
|
||||
\$sudo -u www-data /usr/bin/php admin/cli/scheduled_task.php --execute=\\core\\task\\session_cleanup_task
|
||||
|
||||
";
|
||||
|
||||
echo $help;
|
||||
die;
|
||||
}
|
||||
|
||||
if ($options['showdebugging']) {
|
||||
set_debugging(DEBUG_DEVELOPER, true);
|
||||
}
|
||||
|
||||
if ($options['showsql']) {
|
||||
$DB->set_debug(true);
|
||||
}
|
||||
if ($options['list']) {
|
||||
cli_heading("List of scheduled tasks ($CFG->wwwroot)");
|
||||
|
||||
$shorttime = get_string('strftimedatetimeshort');
|
||||
|
||||
$tasks = \core\task\manager::get_all_scheduled_tasks();
|
||||
echo str_pad(get_string('scheduledtasks', 'tool_task'), 50, ' ') . ' ' . str_pad(get_string('runpattern', 'tool_task'), 17, ' ')
|
||||
. ' ' . str_pad(get_string('lastruntime', 'tool_task'), 40, ' ') . get_string('nextruntime', 'tool_task') . "\n";
|
||||
foreach ($tasks as $task) {
|
||||
$class = '\\' . get_class($task);
|
||||
$schedule = $task->get_minute() . ' '
|
||||
. $task->get_hour() . ' '
|
||||
. $task->get_day() . ' '
|
||||
. $task->get_day_of_week() . ' '
|
||||
. $task->get_month() . ' '
|
||||
. $task->get_day_of_week();
|
||||
$nextrun = $task->get_next_run_time();
|
||||
$lastrun = $task->get_last_run_time();
|
||||
|
||||
$plugininfo = core_plugin_manager::instance()->get_plugin_info($task->get_component());
|
||||
$plugindisabled = $plugininfo && $plugininfo->is_enabled() === false && !$task->get_run_if_component_disabled();
|
||||
|
||||
if ($plugindisabled) {
|
||||
$nextrun = get_string('plugindisabled', 'tool_task');
|
||||
} else if ($task->get_disabled()) {
|
||||
$nextrun = get_string('taskdisabled', 'tool_task');
|
||||
} else if ($nextrun > time()) {
|
||||
$nextrun = userdate($nextrun);
|
||||
} else {
|
||||
$nextrun = get_string('asap', 'tool_task');
|
||||
}
|
||||
|
||||
if ($lastrun) {
|
||||
$lastrun = userdate($lastrun);
|
||||
} else {
|
||||
$lastrun = get_string('never');
|
||||
}
|
||||
|
||||
echo str_pad($class, 50, ' ') . ' ' . str_pad($schedule, 17, ' ') .
|
||||
' ' . str_pad($lastrun, 40, ' ') . ' ' . $nextrun . "\n";
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($execute = $options['execute']) {
|
||||
if (!$task = \core\task\manager::get_scheduled_task($execute)) {
|
||||
mtrace("Task '$execute' not found");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (moodle_needs_upgrading()) {
|
||||
mtrace("Moodle upgrade pending, cannot execute tasks.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Increase memory limit.
|
||||
raise_memory_limit(MEMORY_EXTRA);
|
||||
|
||||
// Emulate normal session - we use admin account by default.
|
||||
cron_setup_user();
|
||||
|
||||
// Execute the task.
|
||||
\core\local\cli\shutdown::script_supports_graceful_exit();
|
||||
$cronlockfactory = \core\lock\lock_config::get_lock_factory('cron');
|
||||
if (!$cronlock = $cronlockfactory->get_lock('core_cron', 10)) {
|
||||
mtrace('Cannot obtain cron lock');
|
||||
exit(129);
|
||||
}
|
||||
if (!$lock = $cronlockfactory->get_lock('\\' . get_class($task), 10)) {
|
||||
$cronlock->release();
|
||||
mtrace('Cannot obtain task lock');
|
||||
exit(130);
|
||||
}
|
||||
|
||||
$task->set_lock($lock);
|
||||
if (!$task->is_blocking()) {
|
||||
$cronlock->release();
|
||||
} else {
|
||||
$task->set_cron_lock($cronlock);
|
||||
}
|
||||
|
||||
cron_run_inner_scheduled_task($task);
|
||||
}
|
||||
@@ -34,7 +34,6 @@ $help = "Command line tool to uninstall plugins.
|
||||
Options:
|
||||
-h --help Print this help.
|
||||
--show-all Displays a list of all installed plugins.
|
||||
--show-contrib Displays a list of all third-party installed plugins.
|
||||
--show-missing Displays a list of plugins missing from disk.
|
||||
--purge-missing Uninstall all missing from disk plugins.
|
||||
--plugins=<plugin name> A comma separated list of plugins to be uninstalled. E.g. mod_assign,mod_forum
|
||||
@@ -45,9 +44,6 @@ Examples:
|
||||
# php uninstall_plugins.php --show-all
|
||||
Prints tab-separated list of all installed plugins.
|
||||
|
||||
# php uninstall_plugins.php --show-contrib
|
||||
Prints tab-separated list of all third-party installed plugins.
|
||||
|
||||
# php uninstall_plugins.php --show-missing
|
||||
Prints tab-separated list of all missing from disk plugins.
|
||||
|
||||
@@ -67,7 +63,6 @@ Examples:
|
||||
list($options, $unrecognised) = cli_get_params([
|
||||
'help' => false,
|
||||
'show-all' => false,
|
||||
'show-contrib' => false,
|
||||
'show-missing' => false,
|
||||
'purge-missing' => false,
|
||||
'plugins' => false,
|
||||
@@ -89,15 +84,12 @@ if ($options['help']) {
|
||||
$pluginman = core_plugin_manager::instance();
|
||||
$plugininfo = $pluginman->get_plugins();
|
||||
|
||||
if ($options['show-all'] || $options['show-missing'] || $options['show-contrib']) {
|
||||
if ($options['show-all'] || $options['show-missing']) {
|
||||
foreach ($plugininfo as $type => $plugins) {
|
||||
foreach ($plugins as $name => $plugin) {
|
||||
if ($options['show-contrib'] && $plugin->is_standard()) {
|
||||
continue;
|
||||
}
|
||||
$pluginstring = $plugin->component . "\t" . $plugin->displayname;
|
||||
|
||||
if ($options['show-all'] || $options['show-contrib']) {
|
||||
if ($options['show-all']) {
|
||||
cli_writeln($pluginstring);
|
||||
} else {
|
||||
if ($plugin->get_status() === core_plugin_manager::PLUGIN_STATUS_MISSING) {
|
||||
|
||||
@@ -137,7 +137,7 @@ if (!$envstatus) {
|
||||
|
||||
// Test plugin dependencies.
|
||||
$failed = array();
|
||||
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed, $CFG->branch)) {
|
||||
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
|
||||
cli_problem(get_string('pluginscheckfailed', 'admin', array('pluginslist' => implode(', ', array_unique($failed)))));
|
||||
cli_error(get_string('pluginschecktodo', 'admin'));
|
||||
}
|
||||
|
||||
@@ -1,84 +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/>.
|
||||
|
||||
/**
|
||||
* Content bank and its plugins settings.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage contentbank
|
||||
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
$action = required_param('action', PARAM_ALPHANUMEXT);
|
||||
$name = required_param('name', PARAM_PLUGIN);
|
||||
|
||||
$syscontext = context_system::instance();
|
||||
$PAGE->set_url('/admin/contentbank.php');
|
||||
$PAGE->set_context($syscontext);
|
||||
|
||||
require_admin();
|
||||
require_sesskey();
|
||||
|
||||
$return = new moodle_url('/admin/settings.php', array('section' => 'managecontentbanktypes'));
|
||||
|
||||
$plugins = core_plugin_manager::instance()->get_plugins_of_type('contenttype');
|
||||
$sortorder = array_flip(array_keys($plugins));
|
||||
|
||||
if (!isset($plugins[$name])) {
|
||||
print_error('contenttypenotfound', 'error', $return, $name);
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'disable':
|
||||
if ($plugins[$name]->is_enabled()) {
|
||||
set_config('disabled', 1, 'contentbank_'. $name);
|
||||
}
|
||||
break;
|
||||
case 'enable':
|
||||
if (!$plugins[$name]->is_enabled()) {
|
||||
unset_config('disabled', 'contentbank_'. $name);
|
||||
}
|
||||
break;
|
||||
case 'up':
|
||||
if ($sortorder[$name]) {
|
||||
$currentindex = $sortorder[$name];
|
||||
$seq = array_keys($plugins);
|
||||
$seq[$currentindex] = $seq[$currentindex - 1];
|
||||
$seq[$currentindex - 1] = $name;
|
||||
set_config('contentbank_plugins_sortorder', implode(',', $seq));
|
||||
}
|
||||
break;
|
||||
case 'down':
|
||||
if ($sortorder[$name] < count($sortorder) - 1) {
|
||||
$currentindex = $sortorder[$name];
|
||||
$seq = array_keys($plugins);
|
||||
$seq[$currentindex] = $seq[$currentindex + 1];
|
||||
$seq[$currentindex + 1] = $name;
|
||||
set_config('contentbank_plugins_sortorder', implode(',', $seq));
|
||||
}
|
||||
break;
|
||||
}
|
||||
core_plugin_manager::reset_caches();
|
||||
$cache = cache::make('core', 'contentbank_enabled_extensions');
|
||||
$cache->purge();
|
||||
$cache = cache::make('core', 'contentbank_context_extensions');
|
||||
$cache->purge();
|
||||
|
||||
redirect($return);
|
||||
@@ -2815,7 +2815,6 @@
|
||||
<VENDOR name="oracle" version="11.2" />
|
||||
</DATABASE>
|
||||
<PHP version="7.1.0" level="required">
|
||||
<RESTRICT function="restrict_php_version_80" message="unsupportedphpversion80" />
|
||||
</PHP>
|
||||
<PCREUNICODE level="optional">
|
||||
<FEEDBACK>
|
||||
@@ -2997,7 +2996,6 @@
|
||||
<VENDOR name="oracle" version="11.2" />
|
||||
</DATABASE>
|
||||
<PHP version="7.2.0" level="required">
|
||||
<RESTRICT function="restrict_php_version_80" message="unsupportedphpversion80" />
|
||||
</PHP>
|
||||
<PCREUNICODE level="optional">
|
||||
<FEEDBACK>
|
||||
@@ -3165,368 +3163,4 @@
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
<MOODLE version="3.10" requires="3.5">
|
||||
<UNICODE level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unicoderequired" />
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mariadb" version="10.2.29" />
|
||||
<VENDOR name="mysql" version="5.7" />
|
||||
<VENDOR name="postgres" version="9.6" />
|
||||
<VENDOR name="mssql" version="11.0" />
|
||||
<VENDOR name="oracle" version="11.2" />
|
||||
</DATABASE>
|
||||
<PHP version="7.2.0" level="required">
|
||||
<RESTRICT function="restrict_php_version_80" message="unsupportedphpversion80" />
|
||||
</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="xmlrpc" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="xmlrpcrecommended" />
|
||||
</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_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_CHECKS>
|
||||
</MOODLE>
|
||||
<MOODLE version="3.11" requires="3.6">
|
||||
<UNICODE level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unicoderequired" />
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mariadb" version="10.2.29" />
|
||||
<VENDOR name="mysql" version="5.7" />
|
||||
<VENDOR name="postgres" version="9.6" />
|
||||
<VENDOR name="mssql" version="14.0" />
|
||||
<VENDOR name="oracle" version="11.2" />
|
||||
</DATABASE>
|
||||
<PHP version="7.3.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="xmlrpc" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="xmlrpcrecommended" />
|
||||
</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="required"/>
|
||||
</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_CHECKS>
|
||||
</MOODLE>
|
||||
</COMPATIBILITY_MATRIX>
|
||||
|
||||
+16
-43
@@ -226,7 +226,7 @@ if (!core_tables_exist()) {
|
||||
}
|
||||
if (empty($confirmrelease)) {
|
||||
require_once($CFG->libdir.'/environmentlib.php');
|
||||
list($envstatus, $environmentresults) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
|
||||
list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
|
||||
$strcurrentrelease = get_string('currentrelease');
|
||||
|
||||
$PAGE->navbar->add($strcurrentrelease);
|
||||
@@ -235,13 +235,13 @@ if (!core_tables_exist()) {
|
||||
$PAGE->set_cacheable(false);
|
||||
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->install_environment_page($maturity, $envstatus, $environmentresults, $release);
|
||||
echo $output->install_environment_page($maturity, $envstatus, $environment_results, $release);
|
||||
die();
|
||||
}
|
||||
|
||||
// check plugin dependencies
|
||||
$failed = array();
|
||||
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed, $CFG->branch)) {
|
||||
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
|
||||
$PAGE->navbar->add(get_string('pluginscheck', 'admin'));
|
||||
$PAGE->set_title($strinstallation);
|
||||
$PAGE->set_heading($strinstallation . ' - Moodle ' . $CFG->target_release);
|
||||
@@ -358,9 +358,9 @@ if (!$cache and $version > $CFG->version) { // upgrade
|
||||
echo $output->upgrade_confirm_page($a->newversion, $maturity, $testsite);
|
||||
die();
|
||||
|
||||
} else if (empty($confirmrelease)) {
|
||||
} else if (empty($confirmrelease)){
|
||||
require_once($CFG->libdir.'/environmentlib.php');
|
||||
list($envstatus, $environmentresults) = check_moodle_environment($release, ENV_SELECT_RELEASE);
|
||||
list($envstatus, $environment_results) = check_moodle_environment($release, ENV_SELECT_RELEASE);
|
||||
$strcurrentrelease = get_string('currentrelease');
|
||||
|
||||
$PAGE->navbar->add($strcurrentrelease);
|
||||
@@ -368,7 +368,7 @@ if (!$cache and $version > $CFG->version) { // upgrade
|
||||
$PAGE->set_heading($strcurrentrelease);
|
||||
$PAGE->set_cacheable(false);
|
||||
|
||||
echo $output->upgrade_environment_page($release, $envstatus, $environmentresults);
|
||||
echo $output->upgrade_environment_page($release, $envstatus, $environment_results);
|
||||
die();
|
||||
|
||||
} else if (empty($confirmplugins)) {
|
||||
@@ -508,9 +508,8 @@ if (!$cache and $version > $CFG->version) { // upgrade
|
||||
} else {
|
||||
// Always verify plugin dependencies!
|
||||
$failed = array();
|
||||
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed, $CFG->branch)) {
|
||||
echo $output->unsatisfied_dependencies_page($version, $failed, new moodle_url($PAGE->url,
|
||||
array('confirmplugincheck' => 0)));
|
||||
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
|
||||
echo $output->unsatisfied_dependencies_page($version, $failed, $PAGE->url);
|
||||
die();
|
||||
}
|
||||
unset($failed);
|
||||
@@ -534,10 +533,7 @@ if (!$cache and $branch <> $CFG->branch) { // Update the branch
|
||||
|
||||
if (!$cache and moodle_needs_upgrading()) {
|
||||
|
||||
$PAGE->set_url(new moodle_url($PAGE->url, array(
|
||||
'confirmrelease' => $confirmrelease,
|
||||
'confirmplugincheck' => $confirmplugins,
|
||||
)));
|
||||
$PAGE->set_url(new moodle_url($PAGE->url, array('confirmplugincheck' => $confirmplugins)));
|
||||
|
||||
check_upgrade_key($upgradekeyhash);
|
||||
|
||||
@@ -547,21 +543,7 @@ if (!$cache and moodle_needs_upgrading()) {
|
||||
$pluginman = core_plugin_manager::instance();
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
|
||||
if (empty($confirmrelease)) {
|
||||
require_once($CFG->libdir . '/environmentlib.php');
|
||||
|
||||
list($envstatus, $environmentresults) = check_moodle_environment($release, ENV_SELECT_RELEASE);
|
||||
$strcurrentrelease = get_string('currentrelease');
|
||||
|
||||
$PAGE->navbar->add($strcurrentrelease);
|
||||
$PAGE->set_title($strcurrentrelease);
|
||||
$PAGE->set_heading($strcurrentrelease);
|
||||
$PAGE->set_cacheable(false);
|
||||
|
||||
echo $output->upgrade_environment_page($release, $envstatus, $environmentresults);
|
||||
die();
|
||||
|
||||
} else if (!$confirmplugins) {
|
||||
if (!$confirmplugins) {
|
||||
$strplugincheck = get_string('plugincheck');
|
||||
|
||||
$PAGE->navbar->add($strplugincheck);
|
||||
@@ -700,10 +682,9 @@ if (!$cache and moodle_needs_upgrading()) {
|
||||
|
||||
// Make sure plugin dependencies are always checked.
|
||||
$failed = array();
|
||||
if (!$pluginman->all_plugins_ok($version, $failed, $CFG->branch)) {
|
||||
if (!$pluginman->all_plugins_ok($version, $failed)) {
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->unsatisfied_dependencies_page($version, $failed, new moodle_url($PAGE->url,
|
||||
array('confirmplugincheck' => 0)));
|
||||
echo $output->unsatisfied_dependencies_page($version, $failed, $PAGE->url);
|
||||
die();
|
||||
}
|
||||
unset($failed);
|
||||
@@ -821,7 +802,7 @@ $SESSION->admin_critical_warning = ($insecuredataroot==INSECURE_DATAROOT_ERROR);
|
||||
$adminroot = admin_get_root();
|
||||
|
||||
// Check if there are any new admin settings which have still yet to be set
|
||||
if (any_new_admin_settings($adminroot)) {
|
||||
if (any_new_admin_settings($adminroot)){
|
||||
redirect('upgradesettings.php');
|
||||
}
|
||||
|
||||
@@ -845,9 +826,8 @@ $errorsdisplayed = defined('WARN_DISPLAY_ERRORS_ENABLED');
|
||||
$lastcron = get_config('tool_task', 'lastcronstart');
|
||||
$cronoverdue = ($lastcron < time() - 3600 * 24);
|
||||
$lastcroninterval = get_config('tool_task', 'lastcroninterval');
|
||||
|
||||
$expectedfrequency = $CFG->expectedcronfrequency ?? MINSECS;
|
||||
$croninfrequent = !$cronoverdue && ($lastcroninterval > ($expectedfrequency + MINSECS) || $lastcron < time() - $expectedfrequency);
|
||||
$expectedfrequency = $CFG->expectedcronfrequency ?? 200;
|
||||
$croninfrequent = !$cronoverdue && ($lastcroninterval > $expectedfrequency || $lastcron < time() - $expectedfrequency);
|
||||
$dbproblems = $DB->diagnose();
|
||||
$maintenancemode = !empty($CFG->maintenance_enabled);
|
||||
|
||||
@@ -901,12 +881,6 @@ if (empty($CFG->disabledevlibdirscheck) && (is_dir($CFG->dirroot.'/vendor') || i
|
||||
// Check if the site is being foced onto ssl.
|
||||
$overridetossl = !empty($CFG->overridetossl);
|
||||
|
||||
// Check if moodle campaign content setting is enabled or not.
|
||||
$showcampaigncontent = !isset($CFG->showcampaigncontent) || $CFG->showcampaigncontent;
|
||||
|
||||
// Encourage admins to enable the user feedback feature if it is not enabled already.
|
||||
$showfeedbackencouragement = empty($CFG->enableuserfeedback);
|
||||
|
||||
admin_externalpage_setup('adminnotifications');
|
||||
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
@@ -914,5 +888,4 @@ $output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed, $cronoverdue, $dbproblems,
|
||||
$maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb,
|
||||
$registered, $cachewarnings, $eventshandlers, $themedesignermode, $devlibdir,
|
||||
$mobileconfigured, $overridetossl, $invalidforgottenpasswordurl, $croninfrequent,
|
||||
$showcampaigncontent, $showfeedbackencouragement);
|
||||
$mobileconfigured, $overridetossl, $invalidforgottenpasswordurl, $croninfrequent);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@@ -15,32 +16,41 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* License manager page.
|
||||
*
|
||||
* @package tool_licensemanager
|
||||
* @copyright 2019 Tom Dickman <tomdickman@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* Allows admin to configure licenses.
|
||||
*/
|
||||
|
||||
require_once('../../../config.php');
|
||||
require_once($CFG->libdir . '/adminlib.php');
|
||||
require_once($CFG->libdir . '/licenselib.php');
|
||||
require_once('../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir.'/licenselib.php');
|
||||
|
||||
require_admin();
|
||||
|
||||
$returnurl = \tool_licensemanager\helper::get_licensemanager_url();
|
||||
$returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=managelicenses";
|
||||
|
||||
$action = optional_param('action', '', PARAM_ALPHANUMEXT);
|
||||
$license = optional_param('license', '', PARAM_SAFEDIR);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// process actions
|
||||
|
||||
if (!confirm_sesskey()) {
|
||||
redirect($returnurl);
|
||||
}
|
||||
|
||||
// Route via the manager.
|
||||
$licensemanager = new \tool_licensemanager\manager();
|
||||
$PAGE->set_context(context_system::instance());
|
||||
$PAGE->set_url(\tool_licensemanager\helper::get_licensemanager_url());
|
||||
$PAGE->set_title(get_string('licensemanager', 'tool_licensemanager'));
|
||||
$return = true;
|
||||
switch ($action) {
|
||||
case 'disable':
|
||||
license_manager::disable($license);
|
||||
break;
|
||||
|
||||
$licensemanager->execute($action, $license);
|
||||
case 'enable':
|
||||
license_manager::enable($license);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ($return) {
|
||||
redirect ($returnurl);
|
||||
}
|
||||
+1
-1
@@ -83,7 +83,7 @@ if (($form = data_submitted()) && confirm_sesskey()) {
|
||||
}
|
||||
} else {
|
||||
$newsettings = array();
|
||||
if (property_exists($form, $componentprovidersetting)) {
|
||||
if (array_key_exists($componentprovidersetting, $form)) {
|
||||
// We must be processing loggedin or loggedoff checkboxes.
|
||||
// Store defained comma-separated processors as setting value.
|
||||
// Using array_filter eliminates elements set to 0 above.
|
||||
|
||||
@@ -156,7 +156,7 @@ class mnet_review_host_form extends moodleform {
|
||||
if ($mnet_peer && !empty($mnet_peer->deleted)) {
|
||||
$radioarray = array();
|
||||
$radioarray[] = $mform->createElement('static', 'deletedinfo', '',
|
||||
$OUTPUT->container(get_string('deletedhostinfo', 'mnet'), 'alert alert-warning'));
|
||||
$OUTPUT->container(get_string('deletedhostinfo', 'mnet'), 'deletedhostinfo'));
|
||||
$radioarray[] = $mform->createElement('radio', 'deleted', '', get_string('yes'), 1);
|
||||
$radioarray[] = $mform->createElement('radio', 'deleted', '', get_string('no'), 0);
|
||||
$mform->addGroup($radioarray, 'radioar', get_string('deleted'), array(' ', ' '), false);
|
||||
|
||||
+2
-4
@@ -49,7 +49,6 @@
|
||||
array($module->id));
|
||||
core_plugin_manager::reset_caches();
|
||||
admin_get_root(true, false); // settings not required - only pages
|
||||
redirect(new moodle_url('/admin/modules.php'));
|
||||
}
|
||||
|
||||
if (!empty($show) and confirm_sesskey()) {
|
||||
@@ -67,7 +66,6 @@
|
||||
array($module->id));
|
||||
core_plugin_manager::reset_caches();
|
||||
admin_get_root(true, false); // settings not required - only pages
|
||||
redirect(new moodle_url('/admin/modules.php'));
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
@@ -123,8 +121,8 @@
|
||||
$count = -1;
|
||||
}
|
||||
if ($count>0) {
|
||||
$countlink = $OUTPUT->action_link(new moodle_url('/course/search.php', ['modulelist' => $module->name]),
|
||||
$count, null, ['title' => $strshowmodulecourse]);
|
||||
$countlink = "<a href=\"{$CFG->wwwroot}/course/search.php?modulelist=$module->name" .
|
||||
"&sesskey=".sesskey()."\" title=\"$strshowmodulecourse\">$count</a>";
|
||||
} else if ($count < 0) {
|
||||
$countlink = get_string('error');
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -53,6 +53,7 @@ $pageurl = new moodle_url('/admin/plugins.php', $pageparams);
|
||||
$pluginman = core_plugin_manager::instance();
|
||||
|
||||
if ($uninstall) {
|
||||
require_sesskey();
|
||||
|
||||
if (!$confirmed) {
|
||||
admin_externalpage_setup('pluginsoverview', '', $pageparams);
|
||||
@@ -91,7 +92,6 @@ if ($uninstall) {
|
||||
exit();
|
||||
|
||||
} else {
|
||||
require_sesskey();
|
||||
$SESSION->pluginuninstallreturn = $pluginfo->get_return_url_after_uninstall($return);
|
||||
$progress = new progress_trace_buffer(new text_progress_trace(), false);
|
||||
$pluginman->uninstall_plugin($pluginfo->component, $progress);
|
||||
|
||||
@@ -170,7 +170,7 @@ foreach ($sortedbehaviours as $behaviour => $behaviourname) {
|
||||
if ($version) {
|
||||
$row[] = $version;
|
||||
} else {
|
||||
$row[] = html_writer::tag('span', get_string('nodatabase', 'admin'), array('class' => 'text-muted'));
|
||||
$row[] = html_writer::tag('span', get_string('nodatabase', 'admin'), array('class' => 'disabled'));
|
||||
}
|
||||
|
||||
// Other question types required by this one.
|
||||
|
||||
+1
-1
@@ -172,7 +172,7 @@ foreach ($sortedqtypes as $qtypename => $localname) {
|
||||
if ($version) {
|
||||
$row[] = $version;
|
||||
} else {
|
||||
$row[] = html_writer::tag('span', get_string('nodatabase', 'admin'), array('class' => 'text-muted'));
|
||||
$row[] = html_writer::tag('span', get_string('nodatabase', 'admin'), array('class' => 'disabled'));
|
||||
}
|
||||
|
||||
// Other question types required by this one.
|
||||
|
||||
@@ -45,7 +45,7 @@ $error = optional_param('error', '', PARAM_ALPHANUM);
|
||||
|
||||
admin_externalpage_setup('registrationmoodleorg');
|
||||
|
||||
if (parse_url($url, PHP_URL_HOST) !== parse_url(HUB_MOODLEORGHUBURL, PHP_URL_HOST)) {
|
||||
if ($url !== HUB_MOODLEORGHUBURL) {
|
||||
// Allow other plugins to confirm registration on custom hubs. Plugins implementing this
|
||||
// callback need to redirect or exit. See https://docs.moodle.org/en/Hub_registration .
|
||||
$callbacks = get_plugins_with_function('hub_registration');
|
||||
|
||||
@@ -39,7 +39,7 @@ $token = optional_param('token', '', PARAM_TEXT);
|
||||
|
||||
admin_externalpage_setup('registrationmoodleorg');
|
||||
|
||||
if (parse_url($url, PHP_URL_HOST) !== parse_url(HUB_MOODLEORGHUBURL, PHP_URL_HOST)) {
|
||||
if ($url !== HUB_MOODLEORGHUBURL) {
|
||||
// Allow other plugins to renew registration on custom hubs. Plugins implementing this
|
||||
// callback need to redirect or exit. See https://docs.moodle.org/en/Hub_registration .
|
||||
$callbacks = get_plugins_with_function('hub_registration');
|
||||
|
||||
+79
-141
@@ -253,7 +253,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$out .= $this->output->container(get_string('cancelinstallinfodir', 'core_plugin', $pluginfo->rootdir));
|
||||
if ($repotype = $pluginman->plugin_external_source($pluginfo->component)) {
|
||||
$out .= $this->output->container(get_string('uninstalldeleteconfirmexternal', 'core_plugin', $repotype),
|
||||
'alert alert-warning mt-2');
|
||||
'uninstalldeleteconfirmexternal');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,8 +282,6 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
* @param bool $overridetossl Whether or not ssl is being forced.
|
||||
* @param bool $invalidforgottenpasswordurl Whether the forgotten password URL does not link to a valid URL.
|
||||
* @param bool $croninfrequent If true, warn that cron hasn't run in the past few minutes
|
||||
* @param bool $showcampaigncontent Whether the campaign content should be visible or not.
|
||||
* @param bool $showfeedbackencouragement Whether the feedback encouragement content should be displayed or not.
|
||||
*
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
@@ -291,9 +289,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch,
|
||||
$buggyiconvnomb, $registered, array $cachewarnings = array(), $eventshandlers = 0,
|
||||
$themedesignermode = false, $devlibdir = false, $mobileconfigured = false,
|
||||
$overridetossl = false, $invalidforgottenpasswordurl = false, $croninfrequent = false,
|
||||
$showcampaigncontent = false, bool $showfeedbackencouragement = false) {
|
||||
|
||||
$overridetossl = false, $invalidforgottenpasswordurl = false, $croninfrequent = false) {
|
||||
global $CFG;
|
||||
$output = '';
|
||||
|
||||
@@ -316,8 +312,6 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$output .= $this->registration_warning($registered);
|
||||
$output .= $this->mobile_configuration_warning($mobileconfigured);
|
||||
$output .= $this->forgotten_password_url_warning($invalidforgottenpasswordurl);
|
||||
$output .= $this->userfeedback_encouragement($showfeedbackencouragement);
|
||||
$output .= $this->campaign_content($showcampaigncontent);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//// IT IS ILLEGAL AND A VIOLATION OF THE GPL TO HIDE, REMOVE OR MODIFY THIS COPYRIGHT NOTICE ///
|
||||
@@ -367,15 +361,14 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$output = '';
|
||||
|
||||
if ($checker->enabled()) {
|
||||
$output .= $this->container_start('checkforupdates mb-4');
|
||||
$output .= $this->container_start('checkforupdates');
|
||||
$output .= $this->single_button(
|
||||
new moodle_url($reloadurl, array('fetchupdates' => 1)),
|
||||
get_string('checkforupdates', 'core_plugin')
|
||||
);
|
||||
if ($timefetched = $checker->get_last_timefetched()) {
|
||||
$timefetched = userdate($timefetched, get_string('strftimedatetime', 'core_langconfig'));
|
||||
$output .= $this->container(get_string('checkforupdateslast', 'core_plugin', $timefetched),
|
||||
'lasttimefetched small text-muted mt-1');
|
||||
$output .= $this->container(get_string('checkforupdateslast', 'core_plugin', $timefetched), 'lasttimefetched');
|
||||
}
|
||||
$output .= $this->container_end();
|
||||
}
|
||||
@@ -439,7 +432,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
|
||||
if ($repotype = $pluginman->plugin_external_source($pluginfo->component)) {
|
||||
$confirm .= $this->output->container(get_string('uninstalldeleteconfirmexternal', 'core_plugin', $repotype),
|
||||
'alert alert-warning mt-2');
|
||||
'uninstalldeleteconfirmexternal');
|
||||
}
|
||||
|
||||
// After any uninstall we must execute full upgrade to finish the cleanup!
|
||||
@@ -518,7 +511,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
protected function warning($message, $type = 'warning') {
|
||||
return $this->box($message, 'generalbox alert alert-' . $type);
|
||||
return $this->box($message, 'generalbox admin' . $type);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -533,7 +526,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
return $this->warning(get_string('datarootsecuritywarning', 'admin', $CFG->dataroot));
|
||||
|
||||
} else if ($insecuredataroot == INSECURE_DATAROOT_ERROR) {
|
||||
return $this->warning(get_string('datarootsecurityerror', 'admin', $CFG->dataroot), 'danger');
|
||||
return $this->warning(get_string('datarootsecurityerror', 'admin', $CFG->dataroot), 'error');
|
||||
|
||||
} else {
|
||||
return '';
|
||||
@@ -551,7 +544,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
if ($devlibdir) {
|
||||
$moreinfo = new moodle_url('/report/security/index.php');
|
||||
$warning = get_string('devlibdirpresent', 'core_admin', ['moreinfourl' => $moreinfo->out()]);
|
||||
return $this->warning($warning, 'danger');
|
||||
return $this->warning($warning, 'error');
|
||||
|
||||
} else {
|
||||
return '';
|
||||
@@ -608,9 +601,19 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
return '';
|
||||
}
|
||||
|
||||
$check = new \tool_task\check\cronrunning();
|
||||
$result = $check->get_result();
|
||||
return $this->warning($result->get_summary() . ' ' . $this->help_icon('cron', 'admin'));
|
||||
if (empty($CFG->cronclionly)) {
|
||||
$url = new moodle_url('/admin/cron.php');
|
||||
if (!empty($CFG->cronremotepassword)) {
|
||||
$url = new moodle_url('/admin/cron.php', array('password' => $CFG->cronremotepassword));
|
||||
}
|
||||
|
||||
return $this->warning(get_string('cronwarning', 'admin', $url->out()) . ' ' .
|
||||
$this->help_icon('cron', 'admin'));
|
||||
}
|
||||
|
||||
// $CFG->cronclionly is not empty: cron can run only from CLI.
|
||||
return $this->warning(get_string('cronwarningcli', 'admin') . ' ' .
|
||||
$this->help_icon('cron', 'admin'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -626,9 +629,9 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
return '';
|
||||
}
|
||||
|
||||
$check = new \tool_task\check\cronrunning();
|
||||
$result = $check->get_result();
|
||||
return $this->warning($result->get_summary() . ' ' . $this->help_icon('cron', 'admin'));
|
||||
$expectedfrequency = $CFG->expectedcronfrequency ?? 200;
|
||||
return $this->warning(get_string('croninfrequent', 'admin', $expectedfrequency) . ' ' .
|
||||
$this->help_icon('cron', 'admin'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -718,7 +721,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
return $this->warning(
|
||||
$this->container(get_string('maturitycorewarning', 'admin', $maturitylevel)) .
|
||||
$this->container($this->doc_link('admin/versions', get_string('morehelp'))),
|
||||
'danger');
|
||||
'error');
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -734,7 +737,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
|
||||
$warning = (get_string('testsiteupgradewarning', 'admin', $testsite));
|
||||
return $this->warning($warning, 'danger');
|
||||
return $this->warning($warning, 'error');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -769,7 +772,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$level = 'warning';
|
||||
|
||||
if ($maturity == MATURITY_ALPHA) {
|
||||
$level = 'danger';
|
||||
$level = 'error';
|
||||
}
|
||||
|
||||
$maturitylevel = get_string('maturity' . $maturity, 'admin');
|
||||
@@ -820,7 +823,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
}
|
||||
|
||||
$updateinfo .= $this->container_start('checkforupdates mt-1');
|
||||
$updateinfo .= $this->container_start('checkforupdates');
|
||||
$fetchurl = new moodle_url('/admin/index.php', array('fetchupdates' => 1, 'sesskey' => sesskey(), 'cache' => 0));
|
||||
$updateinfo .= $this->single_button($fetchurl, get_string('checkforupdates', 'core_plugin'));
|
||||
if ($fetch) {
|
||||
@@ -884,20 +887,6 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display campaign content.
|
||||
*
|
||||
* @param bool $showcampaigncontent Whether the campaign content should be visible or not.
|
||||
* @return string the campaign content raw html.
|
||||
*/
|
||||
protected function campaign_content(bool $showcampaigncontent): string {
|
||||
if (!$showcampaigncontent) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->render_from_template('core/campaign_content', ['lang' => current_language()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a warning about the forgotten password URL not linking to a valid URL.
|
||||
*
|
||||
@@ -923,7 +912,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
*/
|
||||
protected function moodle_available_update_info(\core\update\info $updateinfo) {
|
||||
|
||||
$boxclasses = 'moodleupdateinfo mb-2';
|
||||
$boxclasses = 'moodleupdateinfo';
|
||||
$info = array();
|
||||
|
||||
if (isset($updateinfo->release)) {
|
||||
@@ -943,8 +932,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
|
||||
if (isset($updateinfo->download)) {
|
||||
$info[] = html_writer::link($updateinfo->download, get_string('download'),
|
||||
array('class' => 'info download btn btn-secondary'));
|
||||
$info[] = html_writer::link($updateinfo->download, get_string('download'), array('class' => 'info download'));
|
||||
}
|
||||
|
||||
if (isset($updateinfo->url)) {
|
||||
@@ -952,9 +940,9 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
array('class' => 'info more'));
|
||||
}
|
||||
|
||||
$box = $this->output->container_start($boxclasses);
|
||||
$box .= $this->output->container(implode(html_writer::tag('span', ' | ', array('class' => 'separator')), $info), '');
|
||||
$box .= $this->output->container_end();
|
||||
$box = $this->output->box_start($boxclasses);
|
||||
$box .= $this->output->box(implode(html_writer::tag('span', ' ', array('class' => 'separator')), $info), '');
|
||||
$box .= $this->output->box_end();
|
||||
|
||||
return $box;
|
||||
}
|
||||
@@ -966,7 +954,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
protected function release_notes_link() {
|
||||
$releasenoteslink = get_string('releasenoteslink', 'admin', 'http://docs.moodle.org/dev/Releases');
|
||||
$releasenoteslink = str_replace('target="_blank"', 'onclick="this.target=\'_blank\'"', $releasenoteslink); // extremely ugly validation hack
|
||||
return $this->box($releasenoteslink, 'generalbox alert alert-info');
|
||||
return $this->box($releasenoteslink, 'generalbox releasenoteslink');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -995,7 +983,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
* @return string HTML code
|
||||
*/
|
||||
public function plugins_check_table(core_plugin_manager $pluginman, $version, array $options = array()) {
|
||||
global $CFG;
|
||||
|
||||
$plugininfo = $pluginman->get_plugins();
|
||||
|
||||
if (empty($plugininfo)) {
|
||||
@@ -1066,7 +1054,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$displayname = new html_table_cell(
|
||||
$icon.
|
||||
html_writer::span($plugin->displayname, 'pluginname').
|
||||
html_writer::div($plugin->get_dir(), 'plugindir text-muted small')
|
||||
html_writer::div($plugin->get_dir(), 'plugindir')
|
||||
);
|
||||
|
||||
$versiondb = new html_table_cell($plugin->versiondb);
|
||||
@@ -1081,10 +1069,8 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
|
||||
$coredependency = $plugin->is_core_dependency_satisfied($version);
|
||||
$incompatibledependency = $plugin->is_core_compatible_satisfied($CFG->branch);
|
||||
|
||||
$otherpluginsdependencies = $pluginman->are_dependencies_satisfied($plugin->get_other_required_plugins());
|
||||
$dependenciesok = $coredependency && $otherpluginsdependencies && $incompatibledependency;
|
||||
$dependenciesok = $coredependency && $otherpluginsdependencies;
|
||||
|
||||
$statuscode = $plugin->get_status();
|
||||
$row->attributes['class'] .= ' status-' . $statuscode;
|
||||
@@ -1103,17 +1089,17 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
break;
|
||||
case core_plugin_manager::PLUGIN_STATUS_NODB:
|
||||
case core_plugin_manager::PLUGIN_STATUS_UPTODATE:
|
||||
$statusclass .= $dependenciesok ? 'badge-light' : 'badge-warning';
|
||||
$statusclass .= $dependenciesok ? '' : 'badge-warning';
|
||||
break;
|
||||
}
|
||||
$status = html_writer::span(get_string('status_' . $statuscode, 'core_plugin'), $statusclass);
|
||||
|
||||
if (!empty($installabortable[$plugin->component])) {
|
||||
$status .= $this->output->single_button(
|
||||
new moodle_url($this->page->url, array('abortinstall' => $plugin->component, 'confirmplugincheck' => 0)),
|
||||
new moodle_url($this->page->url, array('abortinstall' => $plugin->component)),
|
||||
get_string('cancelinstallone', 'core_plugin'),
|
||||
'post',
|
||||
array('class' => 'actionbutton cancelinstallone d-block mt-1')
|
||||
array('class' => 'actionbutton cancelinstallone')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1122,7 +1108,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
new moodle_url($this->page->url, array('abortupgrade' => $plugin->component)),
|
||||
get_string('cancelupgradeone', 'core_plugin'),
|
||||
'post',
|
||||
array('class' => 'actionbutton cancelupgradeone d-block mt-1')
|
||||
array('class' => 'actionbutton cancelupgradeone')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1134,11 +1120,8 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
|
||||
$status = new html_table_cell($sourcelabel.' '.$status);
|
||||
if ($plugin->pluginsupported != null) {
|
||||
$requires = new html_table_cell($this->required_column($plugin, $pluginman, $version, $CFG->branch));
|
||||
} else {
|
||||
$requires = new html_table_cell($this->required_column($plugin, $pluginman, $version));
|
||||
}
|
||||
|
||||
$requires = new html_table_cell($this->required_column($plugin, $pluginman, $version));
|
||||
|
||||
$statusisboring = in_array($statuscode, array(
|
||||
core_plugin_manager::PLUGIN_STATUS_NODB, core_plugin_manager::PLUGIN_STATUS_UPTODATE));
|
||||
@@ -1195,7 +1178,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
}
|
||||
|
||||
$out .= $this->output->container_start('actions mb-2');
|
||||
$out .= $this->output->container_start('actions');
|
||||
|
||||
$installableupdates = $pluginman->filter_installable($pluginman->available_updates());
|
||||
if ($installableupdates) {
|
||||
@@ -1203,16 +1186,16 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
new moodle_url($this->page->url, array('installupdatex' => 1)),
|
||||
get_string('updateavailableinstallall', 'core_admin', count($installableupdates)),
|
||||
'post',
|
||||
array('class' => 'singlebutton updateavailableinstallall mr-1')
|
||||
array('class' => 'singlebutton updateavailableinstallall')
|
||||
);
|
||||
}
|
||||
|
||||
if ($installabortable) {
|
||||
$out .= $this->output->single_button(
|
||||
new moodle_url($this->page->url, array('abortinstallx' => 1, 'confirmplugincheck' => 0)),
|
||||
new moodle_url($this->page->url, array('abortinstallx' => 1)),
|
||||
get_string('cancelinstallall', 'core_plugin', count($installabortable)),
|
||||
'post',
|
||||
array('class' => 'singlebutton cancelinstallall mr-1')
|
||||
array('class' => 'singlebutton cancelinstallall')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1221,17 +1204,15 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
new moodle_url($this->page->url, array('abortupgradex' => 1)),
|
||||
get_string('cancelupgradeall', 'core_plugin', count($upgradeabortable)),
|
||||
'post',
|
||||
array('class' => 'singlebutton cancelupgradeall mr-1')
|
||||
array('class' => 'singlebutton cancelupgradeall')
|
||||
);
|
||||
}
|
||||
|
||||
$out .= html_writer::div(html_writer::link(new moodle_url($this->page->url, array('showallplugins' => 0)),
|
||||
get_string('plugincheckattention', 'core_plugin')).' '.html_writer::span($sumattention, 'badge badge-light'),
|
||||
'btn btn-link mr-1');
|
||||
get_string('plugincheckattention', 'core_plugin')).' '.html_writer::span($sumattention, 'badge'));
|
||||
|
||||
$out .= html_writer::div(html_writer::link(new moodle_url($this->page->url, array('showallplugins' => 1)),
|
||||
get_string('plugincheckall', 'core_plugin')).' '.html_writer::span($sumtotal, 'badge badge-light'),
|
||||
'btn btn-link mr-1');
|
||||
get_string('plugincheckall', 'core_plugin')).' '.html_writer::span($sumtotal, 'badge'));
|
||||
|
||||
$out .= $this->output->container_end(); // End of .actions container.
|
||||
$out .= $this->output->container_end(); // End of #plugins-check-info container.
|
||||
@@ -1299,13 +1280,12 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
}
|
||||
|
||||
$out = $this->output->container_start('plugins-check-dependencies mb-4');
|
||||
$out = $this->output->container_start('plugins-check-dependencies');
|
||||
|
||||
if ($unavailable or $unknown) {
|
||||
$out .= $this->output->heading(get_string('misdepsunavail', 'core_plugin'));
|
||||
if ($unknown) {
|
||||
$out .= $this->output->render((new \core\output\notification(get_string('misdepsunknownlist', 'core_plugin',
|
||||
implode(', ', $unknown))))->set_show_closebutton(false));
|
||||
$out .= $this->output->notification(get_string('misdepsunknownlist', 'core_plugin', implode($unknown, ', ')));
|
||||
}
|
||||
if ($unavailable) {
|
||||
$unavailablelist = array();
|
||||
@@ -1319,18 +1299,18 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
$unavailablelist[] = $unavailablelistitem;
|
||||
}
|
||||
$out .= $this->output->render((new \core\output\notification(get_string('misdepsunavaillist', 'core_plugin',
|
||||
implode(', ', $unavailablelist))))->set_show_closebutton(false));
|
||||
$out .= $this->output->notification(get_string('misdepsunavaillist', 'core_plugin',
|
||||
implode($unavailablelist, ', ')));
|
||||
}
|
||||
$out .= $this->output->container_start('plugins-check-dependencies-actions mb-4');
|
||||
$out .= $this->output->container_start('plugins-check-dependencies-actions');
|
||||
$out .= ' '.html_writer::link(new moodle_url('/admin/tool/installaddon/'),
|
||||
get_string('dependencyuploadmissing', 'core_plugin'), array('class' => 'btn btn-secondary'));
|
||||
get_string('dependencyuploadmissing', 'core_plugin'));
|
||||
$out .= $this->output->container_end(); // End of .plugins-check-dependencies-actions container.
|
||||
}
|
||||
|
||||
if ($available) {
|
||||
$out .= $this->output->heading(get_string('misdepsavail', 'core_plugin'));
|
||||
$out .= $this->output->container_start('plugins-check-dependencies-actions mb-2');
|
||||
$out .= $this->output->container_start('plugins-check-dependencies-actions');
|
||||
|
||||
$installable = $pluginman->filter_installable($available);
|
||||
if ($installable) {
|
||||
@@ -1338,13 +1318,12 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
new moodle_url($this->page->url, array('installdepx' => 1)),
|
||||
get_string('dependencyinstallmissing', 'core_plugin', count($installable)),
|
||||
'post',
|
||||
array('class' => 'singlebutton dependencyinstallmissing d-inline-block mr-1')
|
||||
array('class' => 'singlebutton dependencyinstallmissing')
|
||||
);
|
||||
}
|
||||
|
||||
$out .= html_writer::div(html_writer::link(new moodle_url('/admin/tool/installaddon/'),
|
||||
get_string('dependencyuploadmissing', 'core_plugin'), array('class' => 'btn btn-link')),
|
||||
'dependencyuploadmissing d-inline-block mr-1');
|
||||
get_string('dependencyuploadmissing', 'core_plugin')), 'dependencyuploadmissing');
|
||||
|
||||
$out .= $this->output->container_end(); // End of .plugins-check-dependencies-actions container.
|
||||
|
||||
@@ -1385,7 +1364,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
if ($CFG->branch == str_replace('.', '', $moodle->release)) {
|
||||
$supportedmoodles[] = html_writer::span($moodle->release, 'badge badge-success');
|
||||
} else {
|
||||
$supportedmoodles[] = html_writer::span($moodle->release, 'badge badge-light');
|
||||
$supportedmoodles[] = html_writer::span($moodle->release, 'label');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1399,7 +1378,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
$info = html_writer::div(
|
||||
get_string('requiredby', 'core_plugin', implode(', ', $requriedby)),
|
||||
'requiredby mb-1'
|
||||
'requiredby'
|
||||
);
|
||||
} else {
|
||||
$info = '';
|
||||
@@ -1410,39 +1389,38 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$info .= html_writer::div(
|
||||
html_writer::link('https://moodle.org/plugins/view.php?plugin='.$plugin->component,
|
||||
get_string('misdepinfoplugin', 'core_plugin')),
|
||||
'misdepinfoplugin d-inline-block mr-3 mb-1'
|
||||
'misdepinfoplugin'
|
||||
);
|
||||
|
||||
$info .= html_writer::div(
|
||||
html_writer::link('https://moodle.org/plugins/pluginversion.php?id='.$plugin->version->id,
|
||||
get_string('misdepinfoversion', 'core_plugin')),
|
||||
'misdepinfoversion d-inline-block mr-3 mb-1'
|
||||
'misdepinfoversion'
|
||||
);
|
||||
|
||||
$info .= html_writer::div(html_writer::link($plugin->version->downloadurl, get_string('download')),
|
||||
'misdepdownload d-inline-block mr-3 mb-1');
|
||||
$info .= html_writer::div(html_writer::link($plugin->version->downloadurl, get_string('download')), 'misdepdownload');
|
||||
|
||||
if ($pluginman->is_remote_plugin_installable($plugin->component, $plugin->version->version, $reason)) {
|
||||
$info .= $this->output->single_button(
|
||||
new moodle_url($this->page->url, array('installdep' => $plugin->component)),
|
||||
get_string('dependencyinstall', 'core_plugin'),
|
||||
'post',
|
||||
array('class' => 'singlebutton dependencyinstall mr-3 mb-1')
|
||||
array('class' => 'singlebutton dependencyinstall')
|
||||
);
|
||||
} else {
|
||||
$reasonhelp = $this->info_remote_plugin_not_installable($reason);
|
||||
if ($reasonhelp) {
|
||||
$info .= html_writer::div($reasonhelp, 'reasonhelp dependencyinstall d-inline-block mr-3 mb-1');
|
||||
$info .= html_writer::div($reasonhelp, 'reasonhelp dependencyinstall');
|
||||
}
|
||||
}
|
||||
|
||||
$info .= $this->output->container_end(); // End of .actions container.
|
||||
|
||||
$table->data[] = array(
|
||||
html_writer::div($plugin->name, 'name').' '.html_writer::div($plugin->component, 'component text-muted small'),
|
||||
html_writer::div($plugin->name, 'name').' '.html_writer::div($plugin->component, 'component'),
|
||||
$plugin->version->release,
|
||||
$plugin->version->version,
|
||||
implode(' ', $supportedmoodles),
|
||||
implode($supportedmoodles, ' '),
|
||||
$info
|
||||
);
|
||||
}
|
||||
@@ -1474,38 +1452,24 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
* @param \core\plugininfo\base $plugin the plugin we are rendering the row for.
|
||||
* @param core_plugin_manager $pluginman provides data on all the plugins.
|
||||
* @param string $version
|
||||
* @param int $branch the current Moodle branch
|
||||
* @return string HTML code
|
||||
*/
|
||||
protected function required_column(\core\plugininfo\base $plugin, core_plugin_manager $pluginman, $version, $branch = null) {
|
||||
protected function required_column(\core\plugininfo\base $plugin, core_plugin_manager $pluginman, $version) {
|
||||
|
||||
$requires = array();
|
||||
$displayuploadlink = false;
|
||||
$displayupdateslink = false;
|
||||
|
||||
$requirements = $pluginman->resolve_requirements($plugin, $version, $branch);
|
||||
foreach ($requirements as $reqname => $reqinfo) {
|
||||
foreach ($pluginman->resolve_requirements($plugin, $version) as $reqname => $reqinfo) {
|
||||
if ($reqname === 'core') {
|
||||
if ($reqinfo->status == $pluginman::REQUIREMENT_STATUS_OK) {
|
||||
$class = 'requires-ok text-muted';
|
||||
$class = 'requires-ok';
|
||||
$label = '';
|
||||
} else {
|
||||
$class = 'requires-failed';
|
||||
$label = html_writer::span(get_string('dependencyfails', 'core_plugin'), 'badge badge-danger');
|
||||
}
|
||||
|
||||
if ($branch != null && !$plugin->is_core_compatible_satisfied($branch)) {
|
||||
$requires[] = html_writer::tag('li',
|
||||
html_writer::span(get_string('incompatibleversion', 'core_plugin', $branch), 'dep dep-core').
|
||||
' '.$label, array('class' => $class));
|
||||
|
||||
} else if ($branch != null && $plugin->pluginsupported != null) {
|
||||
$requires[] = html_writer::tag('li',
|
||||
html_writer::span(get_string('moodlebranch', 'core_plugin',
|
||||
array('min' => $plugin->pluginsupported[0], 'max' => $plugin->pluginsupported[1])), 'dep dep-core').
|
||||
' '.$label, array('class' => $class));
|
||||
|
||||
} else if ($reqinfo->reqver != ANY_VERSION) {
|
||||
if ($reqinfo->reqver != ANY_VERSION) {
|
||||
$requires[] = html_writer::tag('li',
|
||||
html_writer::span(get_string('moodleversion', 'core_plugin', $plugin->versionrequires), 'dep dep-core').
|
||||
' '.$label, array('class' => $class));
|
||||
@@ -1516,7 +1480,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
|
||||
if ($reqinfo->status == $pluginman::REQUIREMENT_STATUS_OK) {
|
||||
$label = '';
|
||||
$class = 'requires-ok text-muted';
|
||||
$class = 'requires-ok';
|
||||
|
||||
} else if ($reqinfo->status == $pluginman::REQUIREMENT_STATUS_MISSING) {
|
||||
if ($reqinfo->availability == $pluginman::REQUIREMENT_AVAILABLE) {
|
||||
@@ -1570,14 +1534,13 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
return '';
|
||||
}
|
||||
|
||||
$out = html_writer::tag('ul', implode("\n", $requires), array('class' => 'm-0'));
|
||||
$out = html_writer::tag('ul', implode("\n", $requires));
|
||||
|
||||
if ($displayuploadlink) {
|
||||
$out .= html_writer::div(
|
||||
html_writer::link(
|
||||
new moodle_url('/admin/tool/installaddon/'),
|
||||
get_string('dependencyuploadmissing', 'core_plugin'),
|
||||
array('class' => 'btn btn-secondary btn-sm m-1')
|
||||
get_string('dependencyuploadmissing', 'core_plugin')
|
||||
),
|
||||
'dependencyuploadmissing'
|
||||
);
|
||||
@@ -1587,20 +1550,12 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$out .= html_writer::div(
|
||||
html_writer::link(
|
||||
new moodle_url($this->page->url, array('sesskey' => sesskey(), 'fetchupdates' => 1)),
|
||||
get_string('checkforupdates', 'core_plugin'),
|
||||
array('class' => 'btn btn-secondary btn-sm m-1')
|
||||
get_string('checkforupdates', 'core_plugin')
|
||||
),
|
||||
'checkforupdates'
|
||||
);
|
||||
}
|
||||
|
||||
// Check if supports is present, and $branch is not in, only if $incompatible check was ok.
|
||||
if ($plugin->pluginsupported != null && $class == 'requires-ok' && $branch != null) {
|
||||
if ($pluginman->check_explicitly_supported($plugin, $branch) == $pluginman::VERSION_NOT_SUPPORTED) {
|
||||
$out .= html_writer::div(get_string('notsupported', 'core_plugin', $branch));
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
|
||||
}
|
||||
@@ -1947,7 +1902,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
get_string('status'),
|
||||
);
|
||||
$servertable->colclasses = array('centeralign name', 'centeralign info', 'leftalign report', 'leftalign plugin', 'centeralign status');
|
||||
$servertable->attributes['class'] = 'admintable environmenttable generaltable table-sm';
|
||||
$servertable->attributes['class'] = 'admintable environmenttable generaltable';
|
||||
$servertable->id = 'serverstatus';
|
||||
|
||||
$serverdata = array('ok'=>array(), 'warn'=>array(), 'error'=>array());
|
||||
@@ -1960,7 +1915,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
get_string('status'),
|
||||
);
|
||||
$othertable->colclasses = array('aligncenter info', 'alignleft report', 'alignleft plugin', 'aligncenter status');
|
||||
$othertable->attributes['class'] = 'admintable environmenttable generaltable table-sm';
|
||||
$othertable->attributes['class'] = 'admintable environmenttable generaltable';
|
||||
$othertable->id = 'otherserverstatus';
|
||||
|
||||
$otherdata = array('ok'=>array(), 'warn'=>array(), 'error'=>array());
|
||||
@@ -2056,7 +2011,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
if (empty($CFG->docroot) or $environment_result->plugin) {
|
||||
$report = get_string($stringtouse, 'admin', $rec);
|
||||
} else {
|
||||
$report = $this->doc_link(join('/', $linkparts), get_string($stringtouse, 'admin', $rec), true);
|
||||
$report = $this->doc_link(join($linkparts, '/'), get_string($stringtouse, 'admin', $rec), true);
|
||||
}
|
||||
// Enclose report text in div so feedback text will be displayed underneath it.
|
||||
$report = html_writer::div($report);
|
||||
@@ -2180,21 +2135,4 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
|
||||
return $this->output->box($out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display message about benefits of enabling the user feedback feature.
|
||||
*
|
||||
* @param bool $showfeedbackencouragement Whether the encouragement content should be displayed or not
|
||||
* @return string
|
||||
*/
|
||||
protected function userfeedback_encouragement(bool $showfeedbackencouragement): string {
|
||||
$output = '';
|
||||
|
||||
if ($showfeedbackencouragement) {
|
||||
$settingslink = new moodle_url('/admin/settings.php', ['section' => 'userfeedback']);
|
||||
$output .= $this->warning(get_string('userfeedbackencouragement', 'admin', $settingslink->out()), 'info');
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ abstract class core_role_capability_table_base {
|
||||
protected $id;
|
||||
|
||||
/** Added to the class="" attribute on output. */
|
||||
protected $classes = array('rolecap table-hover');
|
||||
protected $classes = array('rolecap');
|
||||
|
||||
/** Default number of capabilities in the table for the search UI to be shown. */
|
||||
const NUM_CAPS_FOR_SEARCH = 12;
|
||||
|
||||
@@ -50,7 +50,6 @@ class core_role_check_capability_table extends core_role_capability_table_base {
|
||||
$this->contextname = $contextname;
|
||||
$this->stryes = get_string('yes');
|
||||
$this->strno = get_string('no');
|
||||
$this->add_classes(['table-striped']);
|
||||
}
|
||||
|
||||
protected function add_header_cells() {
|
||||
|
||||
@@ -55,7 +55,6 @@ class core_role_define_role_table_advanced extends core_role_capability_table_wi
|
||||
foreach ($levels as $level => $classname) {
|
||||
$this->allcontextlevels[$level] = context_helper::get_level_name($level);
|
||||
}
|
||||
$this->add_classes(['table-striped']);
|
||||
}
|
||||
|
||||
protected function load_current_permissions() {
|
||||
|
||||
@@ -66,9 +66,9 @@ class core_role_override_permissions_table_advanced extends core_role_capability
|
||||
$rowattributes = parent::get_row_attributes($capability);
|
||||
if ($this->permissions[$capability->name] !== 0) {
|
||||
if (empty($rowattributes['class'])) {
|
||||
$rowattributes['class'] = "overriddenpermission table-warning";
|
||||
$rowattributes['class'] = "overriddenpermission";
|
||||
} else {
|
||||
$rowattributes['class'] .= " overriddenpermission table-warning";
|
||||
$rowattributes['class'] .= " overriddenpermission";
|
||||
}
|
||||
}
|
||||
return $rowattributes;
|
||||
|
||||
@@ -131,10 +131,15 @@ if ($hassiteconfig && \core_analytics\manager::is_analytics_enabled()) {
|
||||
$timesplittingdefaults, $timesplittingoptions)
|
||||
);
|
||||
|
||||
// Predictions processor output dir - specify default in setting description (used if left blank).
|
||||
$defaultmodeloutputdir = \core_analytics\model::default_output_dir();
|
||||
// Predictions processor output dir.
|
||||
$defaultmodeloutputdir = rtrim($CFG->dataroot, '/') . DIRECTORY_SEPARATOR . 'models';
|
||||
if (empty(get_config('analytics', 'modeloutputdir')) && !file_exists($defaultmodeloutputdir) &&
|
||||
is_writable($defaultmodeloutputdir)) {
|
||||
// Automatically create the dir for them so users don't see the invalid value red cross.
|
||||
mkdir($defaultmodeloutputdir, $CFG->directorypermissions, true);
|
||||
}
|
||||
$settings->add(new admin_setting_configdirectory('analytics/modeloutputdir', new lang_string('modeloutputdir', 'analytics'),
|
||||
new lang_string('modeloutputdirwithdefaultinfo', 'analytics', $defaultmodeloutputdir), ''));
|
||||
new lang_string('modeloutputdirinfo', 'analytics'), $defaultmodeloutputdir));
|
||||
|
||||
// Disable web interface evaluation and get predictions.
|
||||
$settings->add(new admin_setting_configcheckbox('analytics/onlycli', new lang_string('onlycli', 'analytics'),
|
||||
|
||||
@@ -25,12 +25,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) { // sp
|
||||
$temp->add(new admin_setting_configcheckbox('allowcohortthemes', new lang_string('allowcohortthemes', 'admin'), new lang_string('configallowcohortthemes', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('allowthemechangeonurl', new lang_string('allowthemechangeonurl', 'admin'), new lang_string('configallowthemechangeonurl', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('allowuserblockhiding', new lang_string('allowuserblockhiding', 'admin'), new lang_string('configallowuserblockhiding', 'admin'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('langmenuinsecurelayout',
|
||||
new lang_string('langmenuinsecurelayout', 'admin'),
|
||||
new lang_string('langmenuinsecurelayout_desc', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('logininfoinsecurelayout',
|
||||
new lang_string('logininfoinsecurelayout', 'admin'),
|
||||
new lang_string('logininfoinsecurelayout_desc', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configtextarea('custommenuitems', new lang_string('custommenuitems', 'admin'),
|
||||
new lang_string('configcustommenuitems', 'admin'), '', PARAM_RAW, '50', '10'));
|
||||
$temp->add(new admin_setting_configtextarea(
|
||||
|
||||
@@ -59,12 +59,8 @@ if (($hassiteconfig || has_any_capability(array(
|
||||
|
||||
$backpacks = badges_get_site_backpacks();
|
||||
$choices = array();
|
||||
$defaultchoice = 0;
|
||||
foreach ($backpacks as $backpack) {
|
||||
$choices[$backpack->id] = $backpack->backpackweburl;
|
||||
if ($backpack->backpackweburl == BADGRIO_BACKPACKWEBURL) {
|
||||
$defaultchoice = $backpack->id;
|
||||
}
|
||||
}
|
||||
|
||||
$globalsettings->add(new admin_setting_configcheckbox('badges_allowcoursebadges',
|
||||
@@ -107,7 +103,14 @@ if (($hassiteconfig || has_any_capability(array(
|
||||
$backpacksettings->add(new admin_setting_configselect('badges_site_backpack',
|
||||
new lang_string('sitebackpack', 'badges'),
|
||||
new lang_string('sitebackpack_help', 'badges'),
|
||||
$defaultchoice, $choices));
|
||||
1, $choices));
|
||||
|
||||
$warning = badges_verify_site_backpack();
|
||||
if (!empty($warning)) {
|
||||
$backpacksettings->add(new admin_setting_description('badges_site_backpack_verify',
|
||||
new lang_string('sitebackpackverify', 'badges'),
|
||||
$warning));
|
||||
}
|
||||
|
||||
$ADMIN->add('badges', $backpacksettings);
|
||||
|
||||
|
||||
@@ -181,30 +181,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
$CFG->wwwroot . '/course/pending.php', array('moodle/site:approvecourse')));
|
||||
}
|
||||
|
||||
// Add a category for the Activity Chooser.
|
||||
$ADMIN->add('courses', new admin_category('activitychooser', new lang_string('activitychoosercategory', 'course')));
|
||||
$temp = new admin_settingpage('activitychoosersettings', new lang_string('activitychoosersettings', 'course'));
|
||||
$temp->add(
|
||||
new admin_setting_configselect(
|
||||
'activitychoosertabmode',
|
||||
new lang_string('activitychoosertabmode', 'course'),
|
||||
new lang_string('activitychoosertabmode_desc', 'course'),
|
||||
0,
|
||||
[
|
||||
0 => new lang_string('activitychoosertabmodeone', 'course'),
|
||||
1 => new lang_string('activitychoosertabmodetwo', 'course'),
|
||||
2 => new lang_string('activitychoosertabmodethree', 'course'),
|
||||
]
|
||||
)
|
||||
);
|
||||
$ADMIN->add('activitychooser', $temp);
|
||||
$ADMIN->add('activitychooser',
|
||||
new admin_externalpage('activitychooserrecommended', new lang_string('activitychooserrecommendations', 'course'),
|
||||
new moodle_url('/course/recommendations.php'),
|
||||
array('moodle/course:recommendactivity')
|
||||
)
|
||||
);
|
||||
|
||||
// Add a category for backups.
|
||||
$ADMIN->add('courses', new admin_category('backups', new lang_string('backups','admin')));
|
||||
|
||||
@@ -253,11 +229,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
new lang_string('generalgroups', 'backup'), new lang_string('configgeneralgroups', 'backup'),
|
||||
array('value' => 1, 'locked' => 0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_competencies', new lang_string('generalcompetencies','backup'), new lang_string('configgeneralcompetencies','backup'), array('value'=>1, 'locked'=>0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_contentbankcontent',
|
||||
new lang_string('generalcontentbankcontent', 'backup'),
|
||||
new lang_string('configgeneralcontentbankcontent', 'backup'),
|
||||
['value' => 1, 'locked' => 0])
|
||||
);
|
||||
|
||||
$ADMIN->add('backups', $temp);
|
||||
|
||||
@@ -279,12 +250,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
new lang_string('generalgroups', 'backup'), new lang_string('configgeneralgroups', 'backup'),
|
||||
array('value' => 1, 'locked' => 0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_import_competencies', new lang_string('generalcompetencies','backup'), new lang_string('configgeneralcompetencies','backup'), array('value'=>1, 'locked'=>0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock(
|
||||
'backup/backup_import_contentbankcontent',
|
||||
new lang_string('generalcontentbankcontent', 'backup'),
|
||||
new lang_string('configgeneralcontentbankcontent', 'backup'),
|
||||
['value' => 1, 'locked' => 0])
|
||||
);
|
||||
|
||||
$ADMIN->add('backups', $temp);
|
||||
|
||||
@@ -311,8 +276,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
$maxkeptoptions = array(
|
||||
0 => new lang_string('all'), 1 => '1',
|
||||
2 => '2',
|
||||
3 => '3',
|
||||
4 => '4',
|
||||
5 => '5',
|
||||
10 => '10',
|
||||
20 => '20',
|
||||
@@ -404,12 +367,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_groups', new lang_string('generalgroups', 'backup'),
|
||||
new lang_string('configgeneralgroups', 'backup'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_competencies', new lang_string('generalcompetencies','backup'), new lang_string('configgeneralcompetencies','backup'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox(
|
||||
'backup/backup_auto_contentbankcontent',
|
||||
new lang_string('generalcontentbankcontent', 'backup'),
|
||||
new lang_string('configgeneralcontentbankcontent', 'backup'),
|
||||
1)
|
||||
);
|
||||
|
||||
//$temp->add(new admin_setting_configcheckbox('backup/backup_auto_messages', new lang_string('messages', 'message'), new lang_string('backupmessageshelp','message'), 0));
|
||||
//$temp->add(new admin_setting_configcheckbox('backup/backup_auto_blogs', new lang_string('blogs', 'blog'), new lang_string('backupblogshelp','blog'), 0));
|
||||
@@ -470,9 +427,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('restore/restore_general_competencies',
|
||||
new lang_string('generalcompetencies', 'backup'),
|
||||
new lang_string('configrestorecompetencies', 'backup'), array('value' => 1, 'locked' => 0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('restore/restore_general_contentbankcontent',
|
||||
new lang_string('generalcontentbankcontent', 'backup'),
|
||||
new lang_string('configrestorecontentbankcontent', 'backup'), array('value' => 1, 'locked' => 0)));
|
||||
|
||||
// Restore defaults when merging into another course.
|
||||
$temp->add(new admin_setting_heading('mergerestoredefaults', new lang_string('mergerestoredefaults', 'backup'), ''));
|
||||
|
||||
@@ -10,6 +10,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$temp = new admin_settingpage('experimentalsettings', new lang_string('experimentalsettings', 'admin'));
|
||||
//TODO: Re-enable cc-import once re-implemented in 2.0.x
|
||||
//$temp->add(new admin_setting_configcheckbox('enableimsccimport', new lang_string('enable_cc_import', 'imscc'), new lang_string('enable_cc_import_description', 'imscc'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('enablesafebrowserintegration', new lang_string('enablesafebrowserintegration', 'admin'), new lang_string('configenablesafebrowserintegration', 'admin'), 0));
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox('dndallowtextandlinks', new lang_string('dndallowtextandlinks', 'admin'), new lang_string('configdndallowtextandlinks', 'admin'), 0));
|
||||
|
||||
|
||||
+2
-17
@@ -24,21 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
// H5P overview.
|
||||
$ADMIN->add('h5p', new admin_externalpage('h5poverview', get_string('h5poverview', 'core_h5p'),
|
||||
new moodle_url('/h5p/overview.php'), ['moodle/site:config']));
|
||||
|
||||
// Manage H5P libraries page.
|
||||
$ADMIN->add('h5p', new admin_externalpage('h5pmanagelibraries', get_string('h5pmanage', 'core_h5p'),
|
||||
// Settings page.
|
||||
$ADMIN->add('h5p', new admin_externalpage('h5psettings', get_string('h5pmanage', 'core_h5p'),
|
||||
new moodle_url('/h5p/libraries.php'), ['moodle/site:config', 'moodle/h5p:updatelibraries']));
|
||||
|
||||
// H5P settings.
|
||||
$defaulth5plib = \core_h5p\local\library\autoloader::get_default_handler_library();
|
||||
if (!empty($defaulth5plib)) {
|
||||
// As for now this page only has this setting, it will be hidden if there isn't any H5P libraries handler defined.
|
||||
$settings = new admin_settingpage('h5psettings', new lang_string('h5psettings', 'core_h5p'));
|
||||
$ADMIN->add('h5p', $settings);
|
||||
|
||||
$settings->add(new admin_settings_h5plib_handler_select('h5plibraryhandler', new lang_string('h5plibraryhandler', 'core_h5p'),
|
||||
new lang_string('h5plibraryhandler_help', 'core_h5p'), $defaulth5plib));
|
||||
}
|
||||
|
||||
@@ -1,45 +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/>.
|
||||
|
||||
/**
|
||||
* This file defines the settings pages for licenses.
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2020 Tom Dickman <tomdickman@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir . '/licenselib.php');
|
||||
|
||||
if ($hassiteconfig) {
|
||||
|
||||
$temp = new admin_settingpage('licensesettings', new lang_string('licensesettings', 'admin'));
|
||||
|
||||
$licenses = license_manager::get_active_licenses_as_array();
|
||||
|
||||
$temp->add(new admin_setting_configselect('sitedefaultlicense',
|
||||
new lang_string('configsitedefaultlicense', 'admin'),
|
||||
new lang_string('configsitedefaultlicensehelp', 'admin'),
|
||||
'unknown',
|
||||
$licenses));
|
||||
$temp->add(new admin_setting_configcheckbox('rememberuserlicensepref',
|
||||
new lang_string('rememberuserlicensepref', 'admin'),
|
||||
new lang_string('rememberuserlicensepref_help', 'admin'),
|
||||
1));
|
||||
$ADMIN->add('license', $temp);
|
||||
}
|
||||
+14
-50
@@ -1,57 +1,21 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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/>.
|
||||
|
||||
/**
|
||||
* Define administration settings on the Location settings page.
|
||||
*
|
||||
* @package core
|
||||
* @category admin
|
||||
* @copyright 2006 Martin Dougiamas <martin@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
// "locations" settingpage
|
||||
$temp = new admin_settingpage('locationsettings', new lang_string('locationsettings', 'admin'));
|
||||
$temp->add(new admin_setting_servertimezone());
|
||||
$temp->add(new admin_setting_forcetimezone());
|
||||
$temp->add(new admin_settings_country_select('country', new lang_string('country', 'admin'), new lang_string('configcountry', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configtext('defaultcity', new lang_string('defaultcity', 'admin'), new lang_string('defaultcity_help', 'admin'), ''));
|
||||
|
||||
if ($hassiteconfig) {
|
||||
$temp = new admin_settingpage('locationsettings', new lang_string('locationsettings', 'core_admin'));
|
||||
$temp->add(new admin_setting_heading('iplookup', new lang_string('iplookup', 'admin'), new lang_string('iplookupinfo', 'admin')));
|
||||
$temp->add(new admin_setting_configfile('geoip2file', new lang_string('geoipfile', 'admin'),
|
||||
new lang_string('configgeoipfile', 'admin', $CFG->dataroot.'/geoip/'), $CFG->dataroot.'/geoip/GeoLite2-City.mmdb'));
|
||||
$temp->add(new admin_setting_configtext('googlemapkey3', new lang_string('googlemapkey3', 'admin'), new lang_string('googlemapkey3_help', 'admin'), '', PARAM_RAW, 60));
|
||||
|
||||
if ($ADMIN->fulltree) {
|
||||
$temp->add(new admin_setting_servertimezone());
|
||||
|
||||
$temp->add(new admin_setting_forcetimezone());
|
||||
|
||||
$temp->add(new admin_settings_country_select('country', new lang_string('country', 'core_admin'),
|
||||
new lang_string('configcountry', 'core_admin'), 0));
|
||||
|
||||
$temp->add(new admin_setting_configtext('defaultcity', new lang_string('defaultcity', 'core_admin'),
|
||||
new lang_string('defaultcity_help', 'core_admin'), ''));
|
||||
|
||||
$temp->add(new admin_setting_heading('iplookup', new lang_string('iplookup', 'core_admin'),
|
||||
new lang_string('iplookupinfo', 'core_admin')));
|
||||
|
||||
$temp->add(new admin_setting_configfile('geoip2file', new lang_string('geoipfile', 'core_admin'),
|
||||
new lang_string('configgeoipfile', 'core_admin', $CFG->dataroot . '/geoip/'),
|
||||
$CFG->dataroot . '/geoip/GeoLite2-City.mmdb'));
|
||||
|
||||
$temp->add(new admin_setting_configtext('googlemapkey3', new lang_string('googlemapkey3', 'core_admin'),
|
||||
new lang_string('googlemapkey3_help', 'core_admin'), '', PARAM_RAW, 60));
|
||||
|
||||
$temp->add(new admin_setting_countrycodes('allcountrycodes', new lang_string('allcountrycodes', 'core_admin'),
|
||||
new lang_string('configallcountrycodes', 'core_admin')));
|
||||
}
|
||||
$temp->add(new admin_setting_configtext('allcountrycodes', new lang_string('allcountrycodes', 'admin'), new lang_string('configallcountrycodes', 'admin'), '', '/^(?:\w+(?:,\w+)*)?$/'));
|
||||
|
||||
$ADMIN->add('location', $temp);
|
||||
}
|
||||
|
||||
} // end of speedup
|
||||
|
||||
+14
-13
@@ -182,6 +182,20 @@ if ($hassiteconfig) {
|
||||
$plugin->load_settings($ADMIN, 'mlbackendsettings', $hassiteconfig);
|
||||
}
|
||||
|
||||
/// License types
|
||||
$ADMIN->add('modules', new admin_category('licensesettings', new lang_string('licenses')));
|
||||
$temp = new admin_settingpage('managelicenses', new lang_string('managelicenses', 'admin'));
|
||||
|
||||
require_once($CFG->libdir . '/licenselib.php');
|
||||
$licenses = array();
|
||||
$array = explode(',', $CFG->licenses);
|
||||
foreach ($array as $value) {
|
||||
$licenses[$value] = new lang_string($value, 'license');
|
||||
}
|
||||
$temp->add(new admin_setting_configselect('sitedefaultlicense', new lang_string('configsitedefaultlicense','admin'), new lang_string('configsitedefaultlicensehelp','admin'), 'allrightsreserved', $licenses));
|
||||
$temp->add(new admin_setting_managelicenses());
|
||||
$ADMIN->add('licensesettings', $temp);
|
||||
|
||||
/// Filter plugins
|
||||
$ADMIN->add('modules', new admin_category('filtersettings', new lang_string('managefilters')));
|
||||
|
||||
@@ -643,19 +657,6 @@ if ($hassiteconfig) {
|
||||
}
|
||||
}
|
||||
|
||||
// Content bank content types.
|
||||
if ($hassiteconfig) {
|
||||
$ADMIN->add('modules', new admin_category('contentbanksettings', new lang_string('contentbank')));
|
||||
$temp = new admin_settingpage('managecontentbanktypes', new lang_string('managecontentbanktypes'));
|
||||
$temp->add(new admin_setting_managecontentbankcontenttypes());
|
||||
$ADMIN->add('contentbanksettings', $temp);
|
||||
$plugins = core_plugin_manager::instance()->get_plugins_of_type('contenttype');
|
||||
foreach ($plugins as $plugin) {
|
||||
/** @var \core\plugininfo\contentbank $plugin */
|
||||
$plugin->load_settings($ADMIN, 'contentbanksettings', $hassiteconfig);
|
||||
}
|
||||
}
|
||||
|
||||
/// Add all local plugins - must be always last!
|
||||
if ($hassiteconfig) {
|
||||
$ADMIN->add('modules', new admin_category('localplugins', new lang_string('localplugins')));
|
||||
|
||||
@@ -100,9 +100,6 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$temp->add(new admin_setting_configtext('minpasswordupper', new lang_string('minpasswordupper', 'admin'), new lang_string('configminpasswordupper', 'admin'), 1, PARAM_INT));
|
||||
$temp->add(new admin_setting_configtext('minpasswordnonalphanum', new lang_string('minpasswordnonalphanum', 'admin'), new lang_string('configminpasswordnonalphanum', 'admin'), 1, PARAM_INT));
|
||||
$temp->add(new admin_setting_configtext('maxconsecutiveidentchars', new lang_string('maxconsecutiveidentchars', 'admin'), new lang_string('configmaxconsecutiveidentchars', 'admin'), 0, PARAM_INT));
|
||||
$temp->add(new admin_setting_configcheckbox('passwordpolicycheckonlogin',
|
||||
new lang_string('passwordpolicycheckonlogin', 'admin'),
|
||||
new lang_string('configpasswordpolicycheckonlogin', 'admin'), 0));
|
||||
|
||||
$temp->add(new admin_setting_configtext('passwordreuselimit',
|
||||
new lang_string('passwordreuselimit', 'admin'),
|
||||
|
||||
@@ -44,10 +44,15 @@ $temp = new admin_settingpage('sessionhandling', new lang_string('sessionhandlin
|
||||
if (empty($CFG->session_handler_class) and $DB->session_lock_supported()) {
|
||||
$temp->add(new admin_setting_configcheckbox('dbsessions', new lang_string('dbsessions', 'admin'), new lang_string('configdbsessions', 'admin'), 0));
|
||||
}
|
||||
|
||||
$temp->add(new admin_setting_configduration('sessiontimeout', new lang_string('sessiontimeout', 'admin'),
|
||||
new lang_string('configsessiontimeout', 'admin'), 8 * 60 * 60));
|
||||
|
||||
$temp->add(new admin_setting_configselect('sessiontimeout', new lang_string('sessiontimeout', 'admin'), new lang_string('configsessiontimeout', 'admin'), 7200, array(14400 => new lang_string('numhours', '', 4),
|
||||
10800 => new lang_string('numhours', '', 3),
|
||||
7200 => new lang_string('numhours', '', 2),
|
||||
5400 => new lang_string('numhours', '', '1.5'),
|
||||
3600 => new lang_string('numminutes', '', 60),
|
||||
2700 => new lang_string('numminutes', '', 45),
|
||||
1800 => new lang_string('numminutes', '', 30),
|
||||
900 => new lang_string('numminutes', '', 15),
|
||||
300 => new lang_string('numminutes', '', 5))));
|
||||
$temp->add(new admin_setting_configtext('sessioncookie', new lang_string('sessioncookie', 'admin'), new lang_string('configsessioncookie', 'admin'), '', PARAM_ALPHANUM));
|
||||
$temp->add(new admin_setting_configtext('sessioncookiepath', new lang_string('sessioncookiepath', 'admin'), new lang_string('configsessioncookiepath', 'admin'), '', PARAM_RAW));
|
||||
$temp->add(new admin_setting_configtext('sessioncookiedomain', new lang_string('sessioncookiedomain', 'admin'), new lang_string('configsessioncookiedomain', 'admin'), '', PARAM_RAW, 50));
|
||||
@@ -92,10 +97,7 @@ $options = array(
|
||||
GETREMOTEADDR_SKIP_HTTP_CLIENT_IP => 'HTTP_X_FORWARDED_FOR, REMOTE_ADDR',
|
||||
GETREMOTEADDR_SKIP_HTTP_X_FORWARDED_FOR => 'HTTP_CLIENT, REMOTE_ADDR',
|
||||
GETREMOTEADDR_SKIP_HTTP_X_FORWARDED_FOR|GETREMOTEADDR_SKIP_HTTP_CLIENT_IP => 'REMOTE_ADDR');
|
||||
$temp->add(new admin_setting_configselect('getremoteaddrconf', new lang_string('getremoteaddrconf', 'admin'),
|
||||
new lang_string('configgetremoteaddrconf', 'admin'),
|
||||
GETREMOTEADDR_SKIP_DEFAULT, $options));
|
||||
$temp->add(new admin_setting_configtext('reverseproxyignore', new lang_string('reverseproxyignore', 'admin'), new lang_string('configreverseproxyignore', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configselect('getremoteaddrconf', new lang_string('getremoteaddrconf', 'admin'), new lang_string('configgetremoteaddrconf', 'admin'), 0, $options));
|
||||
|
||||
$temp->add(new admin_setting_heading('webproxy', new lang_string('webproxy', 'admin'), new lang_string('webproxyinfo', 'admin')));
|
||||
$temp->add(new admin_setting_configtext('proxyhost', new lang_string('proxyhost', 'admin'), new lang_string('configproxyhost', 'admin'), '', PARAM_HOST));
|
||||
|
||||
@@ -20,9 +20,6 @@ $moodleservices = new admin_settingpage('moodleservices', new lang_string('moodl
|
||||
'admin'));
|
||||
$ADMIN->add('root', $moodleservices);
|
||||
|
||||
$userfeedback = new admin_settingpage('userfeedback', new lang_string('feedbacksettings', 'admin'));
|
||||
$ADMIN->add('root', $userfeedback);
|
||||
|
||||
if ($hassiteconfig) {
|
||||
$optionalsubsystems = new admin_settingpage('optionalsubsystems', new lang_string('advancedfeatures', 'admin'));
|
||||
$ADMIN->add('root', $optionalsubsystems);
|
||||
@@ -35,7 +32,6 @@ $ADMIN->add('root', new admin_category('analytics', new lang_string('analytics',
|
||||
$ADMIN->add('root', new admin_category('competencies', new lang_string('competencies', 'core_competency')));
|
||||
$ADMIN->add('root', new admin_category('badges', new lang_string('badges'), empty($CFG->enablebadges)));
|
||||
$ADMIN->add('root', new admin_category('h5p', new lang_string('h5p', 'core_h5p')));
|
||||
$ADMIN->add('root', new admin_category('license', new lang_string('license')));
|
||||
$ADMIN->add('root', new admin_category('location', new lang_string('location','admin')));
|
||||
$ADMIN->add('root', new admin_category('language', new lang_string('language')));
|
||||
$ADMIN->add('root', new admin_category('messaging', new lang_string('messagingcategory', 'admin')));
|
||||
|
||||
@@ -1,49 +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/>.
|
||||
|
||||
/**
|
||||
* This file contains call to feedback settings
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
if ($hassiteconfig) {
|
||||
|
||||
$userfeedback->add(new admin_setting_configcheckbox('enableuserfeedback',
|
||||
new lang_string('enableuserfeedback', 'admin'),
|
||||
new lang_string('enableuserfeedback_desc', 'admin'), 0, 1, 0));
|
||||
|
||||
$options = [
|
||||
core_userfeedback::REMIND_AFTER_UPGRADE => new lang_string('userfeedbackafterupgrade', 'admin'),
|
||||
core_userfeedback::REMIND_PERIODICALLY => new lang_string('userfeedbackperiodically', 'admin'),
|
||||
core_userfeedback::REMIND_NEVER => new lang_string('never'),
|
||||
];
|
||||
$userfeedback->add(new admin_setting_configselect('userfeedback_nextreminder',
|
||||
new lang_string('userfeedbacknextreminder', 'admin'),
|
||||
new lang_string('userfeedbacknextreminder_desc', 'admin'), 1, $options));
|
||||
$userfeedback->hide_if('userfeedback_nextreminder', 'enableuserfeedback');
|
||||
|
||||
$userfeedback->add(new admin_setting_configtext('userfeedback_remindafter',
|
||||
new lang_string('userfeedbackremindafter', 'admin'),
|
||||
new lang_string('userfeedbackremindafter_desc', 'admin'), 90, PARAM_INT));
|
||||
$userfeedback->hide_if('userfeedback_remindafter', 'enableuserfeedback');
|
||||
$userfeedback->hide_if('userfeedback_remindafter', 'userfeedback_nextreminder', 'eq', 3);
|
||||
|
||||
}
|
||||
@@ -186,7 +186,6 @@ if ($hassiteconfig
|
||||
'email' => new lang_string('email'),
|
||||
'city' => new lang_string('city'),
|
||||
'country' => new lang_string('country'),
|
||||
'moodlenetprofile' => new lang_string('moodlenetprofile', 'user'),
|
||||
'timezone' => new lang_string('timezone'),
|
||||
'webpage' => new lang_string('webpage'),
|
||||
'icqnumber' => new lang_string('icqnumber'),
|
||||
@@ -261,28 +260,10 @@ if ($hassiteconfig) {
|
||||
$temp->add($setting);
|
||||
|
||||
// See {@link https://gdpr-info.eu/art-8-gdpr/}.
|
||||
// See {@link https://www.betterinternetforkids.eu/web/portal/practice/awareness/detail?articleId=3017751}.
|
||||
$ageofdigitalconsentmap = implode(PHP_EOL, [
|
||||
'*, 16',
|
||||
'AT, 14',
|
||||
'BE, 13',
|
||||
'BG, 14',
|
||||
'CY, 14',
|
||||
'CZ, 15',
|
||||
'DK, 13',
|
||||
'EE, 13',
|
||||
'ES, 14',
|
||||
'FI, 13',
|
||||
'FR, 15',
|
||||
'GB, 13',
|
||||
'GR, 15',
|
||||
'IT, 14',
|
||||
'LT, 14',
|
||||
'LV, 13',
|
||||
'MT, 13',
|
||||
'NO, 13',
|
||||
'PT, 13',
|
||||
'SE, 13',
|
||||
'US, 13'
|
||||
]);
|
||||
$setting = new admin_setting_agedigitalconsentmap('agedigitalconsentmap',
|
||||
|
||||
+1
-5
@@ -32,7 +32,6 @@ $result = optional_param('result', null, PARAM_INT);
|
||||
|
||||
$pageurl = new \moodle_url('/admin/tasklogs.php');
|
||||
$pageurl->param('filter', $filter);
|
||||
$pageurl->param('result', $result);
|
||||
|
||||
$PAGE->set_url($pageurl);
|
||||
$PAGE->set_context(context_system::instance());
|
||||
@@ -63,11 +62,9 @@ if (null !== $logid) {
|
||||
$renderer = $PAGE->get_renderer('tool_task');
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
// Output the search form.
|
||||
echo $OUTPUT->render_from_template('core_admin/tasklogs', (object) [
|
||||
'action' => $pageurl->out(),
|
||||
'filter' => htmlentities($filter),
|
||||
'filter' => $filter,
|
||||
'resultfilteroptions' => [
|
||||
(object) [
|
||||
'value' => -1,
|
||||
@@ -87,7 +84,6 @@ echo $OUTPUT->render_from_template('core_admin/tasklogs', (object) [
|
||||
],
|
||||
]);
|
||||
|
||||
// Output any matching logs.
|
||||
$table = new \core_admin\task_log_table($filter, $result);
|
||||
$table->baseurl = $pageurl;
|
||||
$table->out(100, false);
|
||||
|
||||
@@ -49,28 +49,15 @@
|
||||
}}
|
||||
<div class="form-item row" id="{{id}}">
|
||||
<div class="form-label col-sm-3 text-sm-right">
|
||||
{{#customcontrol}}
|
||||
<p {{#labelfor}}id="{{labelfor}}_label"{{/labelfor}}>
|
||||
{{{title}}}
|
||||
{{#override}}
|
||||
<div class="alert alert-info">{{override}}</div>
|
||||
{{/override}}
|
||||
{{#warning}}
|
||||
<div class="alert alert-warning">{{warning}}</div>
|
||||
{{/warning}}
|
||||
</p>
|
||||
{{/customcontrol}}
|
||||
{{^customcontrol}}
|
||||
<label {{#labelfor}}for="{{labelfor}}"{{/labelfor}}>
|
||||
{{{title}}}
|
||||
{{#override}}
|
||||
<div class="alert alert-info">{{override}}</div>
|
||||
{{/override}}
|
||||
{{#warning}}
|
||||
<div class="alert alert-warning">{{warning}}</div>
|
||||
{{/warning}}
|
||||
</label>
|
||||
{{/customcontrol}}
|
||||
<label {{#labelfor}}for="{{labelfor}}"{{/labelfor}}>
|
||||
{{{title}}}
|
||||
{{#override}}
|
||||
<div class="form-overridden">{{override}}</div>
|
||||
{{/override}}
|
||||
{{#warning}}
|
||||
<div class="form-warning">{{warning}}</div>
|
||||
{{/warning}}
|
||||
</label>
|
||||
<span class="form-shortname d-block small text-muted">{{{name}}}</span>
|
||||
</div>
|
||||
<div class="form-setting col-sm-9">
|
||||
@@ -85,16 +72,3 @@
|
||||
{{#dependenton}}<div class="form-dependenton mb-4 text-muted">{{{.}}}</div>{{/dependenton}}
|
||||
</div>
|
||||
</div>
|
||||
{{#customcontrol}}
|
||||
{{#js}}
|
||||
require(['jquery'], function($) {
|
||||
$('#{{id}}_label').css('cursor', 'default');
|
||||
$('#{{id}}_label').click(function() {
|
||||
$('#{{id}}')
|
||||
.find('button, a, input:not([type="hidden"]), select, textarea, [tabindex]')
|
||||
.filter(':not([disabled]):not([tabindex="0"]):not([tabindex="-1"])')
|
||||
.first().focus();
|
||||
});
|
||||
});
|
||||
{{/js}}
|
||||
{{/customcontrol}}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
* value - yes value
|
||||
* id - element id
|
||||
* checked - boole
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
@@ -33,11 +32,10 @@
|
||||
"no": "False",
|
||||
"value": "True",
|
||||
"id": "test0",
|
||||
"checked": "checked",
|
||||
"readonly": false
|
||||
"checked": "checked"
|
||||
}
|
||||
}}
|
||||
<div class="form-checkbox defaultsnext">
|
||||
<input type="hidden" name="{{name}}" value="{{no}}">
|
||||
<input {{#readonly}}disabled{{/readonly}} type="checkbox" name="{{name}}" value="{{value}}" id="{{id}}" {{#checked}}checked{{/checked}}>
|
||||
<input type="checkbox" name="{{name}}" value="{{value}}" id="{{id}}" {{#checked}}checked{{/checked}}>
|
||||
</div>
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
* id - element id
|
||||
* value - element value
|
||||
* haspreviewconfig - show preview of selected color
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
@@ -33,7 +32,6 @@
|
||||
"name": "name0",
|
||||
"id": "id0",
|
||||
"value": "#555655",
|
||||
"readonly": false,
|
||||
"haspreviewconfig": false
|
||||
}
|
||||
}}
|
||||
@@ -46,7 +44,7 @@
|
||||
{{>core/pix_icon}}
|
||||
{{/icon}}
|
||||
</div>
|
||||
<input type="text" name="{{name}}" id="{{id}}" value="{{value}}" size="12" class="form-control text-ltr" {{#readonly}}disabled{{/readonly}}>
|
||||
<input type="text" name="{{name}}" id="{{id}}" value="{{value}}" size="12" class="form-control text-ltr">
|
||||
{{#haspreviewconfig}}
|
||||
<input type="button" id="{{id}}_preview" value={{#quote}}{{#str}}preview{{/str}}{{/quote}} class="admin_colourpicker_preview">
|
||||
{{/haspreviewconfig}}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"name": "test",
|
||||
"value": "/my-super-secret-path/",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"readonly": true,
|
||||
"showvalidity": true,
|
||||
"valid": false
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
* name - form element name
|
||||
* options - list of options for units containing name, value, selected
|
||||
* value - yes
|
||||
* readonly - bool
|
||||
* id - element id
|
||||
|
||||
Example context (json):
|
||||
@@ -31,7 +30,6 @@
|
||||
"name": "test",
|
||||
"value": "5",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"options": [ { "name": "Minutes", "value": "mins", "selected": true } ]
|
||||
}
|
||||
}}
|
||||
@@ -40,9 +38,9 @@
|
||||
}}
|
||||
<div class="form-duration defaultsnext">
|
||||
<div class="form-inline">
|
||||
<input type="text" size="5" id="{{id}}v" name="{{name}}[v]" value="{{value}}" class="form-control text-ltr" {{#readonly}}disabled{{/readonly}}>
|
||||
<input type="text" size="5" id="{{id}}v" name="{{name}}[v]" value="{{value}}" class="form-control text-ltr">
|
||||
<label class="sr-only" for="{{id}}u">{{#str}}durationunits, admin{{/str}}</label>
|
||||
<select id="{{id}}u" name="{{name}}[u]" class="form-control custom-select" {{#readonly}}disabled{{/readonly}}>
|
||||
<select id="{{id}}u" name="{{name}}[u]" class="form-control custom-select">
|
||||
{{#options}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/options}}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"name": "test",
|
||||
"value": "/usr/bin/cowsay",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"readonly": true,
|
||||
"showvalidity": true,
|
||||
"valid": false
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
* readonly - Make the field readonly
|
||||
* value - value
|
||||
* showvalidity - Show a green check if the path is readable
|
||||
* readonly - bool
|
||||
* valid - True if the path is readable
|
||||
|
||||
Example context (json):
|
||||
@@ -34,9 +33,8 @@
|
||||
"name": "test",
|
||||
"value": "/my-super-secret-path/file",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"readonly": true,
|
||||
"showvalidity": true,
|
||||
"readonly": false,
|
||||
"valid": false
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -24,14 +24,12 @@
|
||||
* options - list of options for units containing name, value, selected
|
||||
* value - yes
|
||||
* id - element id
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"value": "5",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"options": [ { "name": "KB", "value": "1024", "selected": true } ]
|
||||
}
|
||||
}}
|
||||
@@ -40,9 +38,9 @@
|
||||
}}
|
||||
<div class="form-filesize defaultsnext">
|
||||
<div class="form-inline">
|
||||
<input type="text" size="5" id="{{id}}v" name="{{name}}[v]" value="{{value}}" class="form-control text-ltr" {{#readonly}}disabled{{/readonly}}>
|
||||
<input type="text" size="5" id="{{id}}v" name="{{name}}[v]" value="{{value}}" class="form-control text-ltr">
|
||||
<label class="sr-only" for="{{id}}u">{{#str}}filesizeunits, admin{{/str}}</label>
|
||||
<select id="{{id}}u" name="{{name}}[u]" class="form-control custom-select" {{#readonly}}disabled{{/readonly}}>
|
||||
<select id="{{id}}u" name="{{name}}[u]" class="form-control custom-select">
|
||||
{{#options}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/options}}
|
||||
|
||||
@@ -24,13 +24,11 @@
|
||||
* id - element id
|
||||
* size - element size
|
||||
* options - list of options containing name, value, selected
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"size": "3",
|
||||
"options": [ { "name": "Option 1", "value": "V", "selected": true },
|
||||
{ "name": "Option 2", "value": "V", "selected": true } ]
|
||||
@@ -41,7 +39,7 @@
|
||||
}}
|
||||
<div class="form-select">
|
||||
<input type="hidden" name="{{name}}[xxxxx]" value="1">
|
||||
<select {{#readonly}}disabled{{/readonly}} id="{{id}}" name="{{name}}[]" size="{{size}}" class="form-control" multiple>
|
||||
<select id="{{id}}" name="{{name}}[]" size="{{size}}" class="form-control" multiple>
|
||||
{{#options}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/options}}
|
||||
|
||||
@@ -25,13 +25,11 @@
|
||||
* size - element size
|
||||
* options - list of options not grouped
|
||||
* optgroups - list of options grouped containing the group label and for each option: name, value, selected
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"size": "3",
|
||||
"options": [
|
||||
{ "name": "Option 1", "value": "V", "selected": false },
|
||||
@@ -60,7 +58,7 @@
|
||||
}}
|
||||
<div class="form-select">
|
||||
<input type="hidden" name="{{name}}[xxxxx]" value="1">
|
||||
<select {{#readonly}}disabled{{/readonly}} id="{{id}}" name="{{name}}[]" size="{{size}}" class="form-control" multiple>
|
||||
<select id="{{id}}" name="{{name}}[]" size="{{size}}" class="form-control" multiple>
|
||||
{{#options}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/options}}
|
||||
|
||||
@@ -24,30 +24,15 @@
|
||||
* size - form element size
|
||||
* value - form element value
|
||||
* id - element id
|
||||
* readonly - has value been defined in config.php
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"size": "8",
|
||||
"value": "secret",
|
||||
"readonly": false
|
||||
"value": "secret"
|
||||
}
|
||||
}}
|
||||
{{#readonly}}
|
||||
<div class="form-password">
|
||||
<input type="text"
|
||||
name = "{{ name }}"
|
||||
id="{{ id }}"
|
||||
value="********"
|
||||
size="{{ size }}"
|
||||
class="form-control"
|
||||
disabled
|
||||
>
|
||||
</div>
|
||||
{{/readonly}}
|
||||
{{^readonly}}
|
||||
<div class="form-password">
|
||||
<span data-passwordunmask="wrapper" data-passwordunmaskid="{{ id }}">
|
||||
<span data-passwordunmask="editor">
|
||||
@@ -76,4 +61,3 @@ require(['core_form/passwordunmask'], function(PasswordUnmask) {
|
||||
new PasswordUnmask("{{ id }}");
|
||||
});
|
||||
{{/js}}
|
||||
{{/readonly}}
|
||||
|
||||
@@ -23,13 +23,11 @@
|
||||
* name - form element name
|
||||
* id - element id
|
||||
* options - list of options containing name, value, selected
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"options": [
|
||||
{ "name": "Option 1", "value": "V", "selected": true },
|
||||
{ "name": "Option 2", "value": "V", "selected": true }
|
||||
@@ -40,7 +38,7 @@
|
||||
Setting configselect.
|
||||
}}
|
||||
<div class="form-select defaultsnext">
|
||||
<select {{#readonly}}disabled{{/readonly}} id="{{id}}" name="{{name}}" class="custom-select">
|
||||
<select id="{{id}}" name="{{name}}" class="custom-select">
|
||||
{{#options}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/options}}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
Context variables required for this template:
|
||||
* name - form element name
|
||||
* id - element id
|
||||
* readonly - bool
|
||||
* options - list of options (not grouped)
|
||||
* optgroups - list of options grouped containing the group label and for each option: name, value, selected
|
||||
|
||||
@@ -30,7 +29,6 @@
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"options": [
|
||||
{ "name": "Option 1", "value": "V", "selected": false },
|
||||
{ "name": "Option 2", "value": "V", "selected": false }
|
||||
@@ -57,7 +55,7 @@
|
||||
Setting configselect with optgroup support.
|
||||
}}
|
||||
<div class="form-select defaultsnext">
|
||||
<select {{#readonly}}disabled{{/readonly}} id="{{id}}" name="{{name}}" class="custom-select">
|
||||
<select id="{{id}}" name="{{name}}" class="custom-select">
|
||||
{{#options}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/options}}
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
* size - element size
|
||||
* forceltr - always display as ltr
|
||||
* attributes - list of additional attributes containing name, value
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
@@ -35,7 +34,6 @@
|
||||
"value": "A tall, dark stranger will have more fun than you.",
|
||||
"size": "21",
|
||||
"forceltr": false,
|
||||
"readonly": false,
|
||||
"attributes": [ { "name": "readonly", "value": "readonly" } ]
|
||||
}
|
||||
}}
|
||||
@@ -43,5 +41,5 @@
|
||||
Setting configtext.
|
||||
}}
|
||||
<div class="form-text defaultsnext">
|
||||
<input type="text" name="{{name}}" value="{{value}}" size="{{size}}" id="{{id}}" class="form-control {{#forceltr}}text-ltr{{/forceltr}}" {{#readonly}}disabled{{/readonly}}>
|
||||
<input type="text" name="{{name}}" value="{{value}}" size="{{size}}" id="{{id}}" class="form-control {{#forceltr}}text-ltr{{/forceltr}}">
|
||||
</div>
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
"cols": "30",
|
||||
"rows": "3",
|
||||
"value": "Excellent day for putting Slinkies on an escalator.",
|
||||
"readonly": false,
|
||||
"id": "test0"
|
||||
}
|
||||
}}
|
||||
@@ -41,5 +40,5 @@
|
||||
Setting configtextarea.
|
||||
}}
|
||||
<div class="form-textarea">
|
||||
<textarea {{#readonly}}disabled{{/readonly}} rows="{{rows}}" cols="{{cols}}" id="{{id}}" name="{{name}}" spellcheck="true" class="form-control {{#forceltr}}text-ltr{{/forceltr}}">{{value}}</textarea>
|
||||
<textarea rows="{{rows}}" cols="{{cols}}" id="{{id}}" name="{{name}}" spellcheck="true" class="form-control {{#forceltr}}text-ltr{{/forceltr}}">{{value}}</textarea>
|
||||
</div>
|
||||
|
||||
@@ -24,13 +24,11 @@
|
||||
* id - element id
|
||||
* hours - list of valid hour options containing name, value, selected
|
||||
* minutes - list of valid minute options containing name, value, selected
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"minutes": [
|
||||
{ "name": "00", "value": "0", "selected": true },
|
||||
{ "name": "01", "value": "1", "selected": false }
|
||||
@@ -47,13 +45,13 @@
|
||||
<div class="form-time defaultsnext">
|
||||
<div class="form-inline text-ltr">
|
||||
<label class="sr-only" for="{{id}}h">{{#str}}hours{{/str}}</label>
|
||||
<select id="{{id}}h" name="{{name}}[h]" class="custom-select" {{#readonly}}disabled{{/readonly}}>
|
||||
<select id="{{id}}h" name="{{name}}[h]" class="custom-select">
|
||||
{{#hours}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/hours}}
|
||||
</select>:
|
||||
<label class="sr-only" for="{{id}}m">{{#str}}minutes{{/str}}</label>
|
||||
<select id="{{id}}m" name="{{name}}[m]" class="custom-select" {{#readonly}}disabled{{/readonly}}>
|
||||
<select id="{{id}}m" name="{{name}}[m]" class="custom-select">
|
||||
{{#minutes}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/minutes}}
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<h3 class="adminpagetitle"><a href="{{url}}">{{{title}}}</a></h3>
|
||||
<ul class="adminpagepath" aria-label="{{#str}} pagepath, core {{/str}}">
|
||||
{{#path}}
|
||||
<li class="small text-muted">{{.}}</li>
|
||||
<li>{{.}}</li>
|
||||
{{/path}}
|
||||
</ul>
|
||||
<fieldset class="adminsettings">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
{{!
|
||||
@template core_admin/tasklogs
|
||||
|
||||
This is the template for the search form which appears above the task logs report.
|
||||
Task Logs template.
|
||||
}}
|
||||
<form class="form-inline" method="GET" action="{{{action}}}">
|
||||
<label class="sr-only" for="tasklog-filter">{{#str}}filter{{/str}}</label>
|
||||
|
||||
@@ -46,8 +46,7 @@ if ($data) {
|
||||
$emailuser->email = $data->recipient;
|
||||
$emailuser->id = -99;
|
||||
|
||||
$subject = get_string('testoutgoingmailconf_subject', 'admin',
|
||||
format_string($SITE->fullname, true, ['context' => context_system::instance()]));
|
||||
$subject = get_string('testoutgoingmailconf_subject', 'admin', $SITE->fullname);
|
||||
$messagetext = get_string('testoutgoingmailconf_message', 'admin');
|
||||
|
||||
// Manage Moodle debugging options.
|
||||
|
||||
@@ -6,11 +6,11 @@ Feature: An administrator can filter user accounts by role, cohort and other pro
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email | auth | confirmed | lastip | institution | department |
|
||||
| user1 | User | One | one@example.com | manual | 0 | 127.0.1.1 | moodle | red |
|
||||
| user2 | User | Two | two@example.com | ldap | 1 | 0.0.0.0 | moodle | blue |
|
||||
| user3 | User | Three | three@example.com | manual | 1 | 0.0.0.0 | | |
|
||||
| user4 | User | Four | four@example.com | ldap | 0 | 127.0.1.2 | | |
|
||||
| username | firstname | lastname | email | auth | confirmed | lastip |
|
||||
| user1 | User | One | one@example.com | manual | 0 | 127.0.1.1 |
|
||||
| user2 | User | Two | two@example.com | ldap | 1 | 0.0.0.0 |
|
||||
| user3 | User | Three | three@example.com | manual | 1 | 0.0.0.0 |
|
||||
| user4 | User | Four | four@example.com | ldap | 0 | 127.0.1.2 |
|
||||
And the following "cohorts" exist:
|
||||
| name | idnumber |
|
||||
| Cohort 1 | CH1 |
|
||||
@@ -104,15 +104,3 @@ Feature: An administrator can filter user accounts by role, cohort and other pro
|
||||
And I should see "User Two"
|
||||
And I should see "User Three"
|
||||
And I should see "User Four"
|
||||
|
||||
Scenario: Filter users by institution and department
|
||||
When I set the field "id_institution" to "moodle"
|
||||
And I press "Add filter"
|
||||
Then I should see "User One"
|
||||
And I should see "User Two"
|
||||
And I should not see "User Three"
|
||||
And I should not see "User Four"
|
||||
And I set the field "id_department" to "red"
|
||||
And I press "Add filter"
|
||||
And I should see "User One"
|
||||
And I should not see "User Two"
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
@core @core_admin
|
||||
Feature: Administrator is warned and when trying to set invalid allcountrycodes value.
|
||||
In order to avoid misconfiguration of the country selector fields
|
||||
As an admin
|
||||
I want to be warned when I try to set an invalid country code in the allcountrycodes field
|
||||
|
||||
Scenario: Attempting to set allcountrycodes field with valid country codes
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Location > Location settings" in site administration
|
||||
When I set the following administration settings values:
|
||||
| All country codes | CZ,BE,GB,ES |
|
||||
Then I should not see "Invalid country code"
|
||||
|
||||
Scenario: Attempting to set allcountrycodes field with invalid country code
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Location > Location settings" in site administration
|
||||
When I set the following administration settings values:
|
||||
| All country codes | CZ,BE,FOOBAR,GB,ES |
|
||||
Then I should see "Invalid country code: FOOBAR"
|
||||
|
||||
Scenario: Attempting to unset allcountrycodes field
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Location > Location settings" in site administration
|
||||
And I set the following administration settings values:
|
||||
| All country codes | CZ,BE,GB,ES |
|
||||
And I navigate to "Location > Location settings" in site administration
|
||||
When I set the following administration settings values:
|
||||
| All country codes | |
|
||||
Then I should not see "Invalid country code"
|
||||
@@ -1,34 +0,0 @@
|
||||
@core @core_admin
|
||||
Feature: Configure language settings for the site
|
||||
In order to configure language settings for the site
|
||||
As an admin
|
||||
I want to set language settings relevant to my site users
|
||||
|
||||
Scenario: Set languages on language menu
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language > Language settings" in site administration
|
||||
When I set the field "Languages on language menu" to "en"
|
||||
And I press "Save changes"
|
||||
Then I should not see "Invalid language code"
|
||||
|
||||
Scenario: Reset languages on language menu
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language > Language settings" in site administration
|
||||
When I set the field "Languages on language menu" to ""
|
||||
And I press "Save changes"
|
||||
Then I should not see "Invalid language code"
|
||||
|
||||
Scenario Outline: Set languages on language menu with invalid language
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language > Language settings" in site administration
|
||||
When I set the field "Languages on language menu" to "<fieldvalue>"
|
||||
And I press "Save changes"
|
||||
Then I should see "Invalid language code: <invalidlang>"
|
||||
Examples:
|
||||
| fieldvalue | invalidlang |
|
||||
| xx | xx |
|
||||
| xx\|Bad | xx |
|
||||
| en,qq | qq |
|
||||
| en,qq\|Bad | qq |
|
||||
| en$$ | en$$ |
|
||||
| en$$\|Bad | en$$ |
|
||||
@@ -27,7 +27,8 @@ namespace tool_analytics\output;
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use plugin_renderer_base;
|
||||
|
||||
use templatable;
|
||||
use renderable;
|
||||
|
||||
/**
|
||||
* Renderer class.
|
||||
@@ -73,12 +74,14 @@ class renderer extends plugin_renderer_base {
|
||||
* @return string HTML
|
||||
*/
|
||||
public function render_evaluate_results($results, $logs = array()) {
|
||||
global $OUTPUT;
|
||||
|
||||
$output = '';
|
||||
|
||||
foreach ($results as $timesplittingid => $result) {
|
||||
|
||||
if (!CLI_SCRIPT) {
|
||||
$output .= $this->output->box_start('generalbox mb-3');
|
||||
$output .= $OUTPUT->box_start('generalbox mb-3');
|
||||
}
|
||||
|
||||
// Check that the array key is a string, not all results depend on time splitting methods (e.g. general errors).
|
||||
@@ -87,48 +90,47 @@ class renderer extends plugin_renderer_base {
|
||||
$langstrdata = (object)array('name' => $timesplitting->get_name(), 'id' => $timesplittingid);
|
||||
|
||||
if (CLI_SCRIPT) {
|
||||
$output .= $this->output->heading(get_string('scheduledanalysisresultscli', 'tool_analytics', $langstrdata), 3);
|
||||
$output .= $OUTPUT->heading(get_string('scheduledanalysisresultscli', 'tool_analytics', $langstrdata), 3);
|
||||
} else {
|
||||
$output .= $this->output->heading(get_string('scheduledanalysisresults', 'tool_analytics', $langstrdata), 3);
|
||||
$output .= $OUTPUT->heading(get_string('scheduledanalysisresults', 'tool_analytics', $langstrdata), 3);
|
||||
}
|
||||
}
|
||||
|
||||
if ($result->status == 0) {
|
||||
$output .= $this->output->notification(get_string('goodmodel', 'tool_analytics'),
|
||||
$output .= $OUTPUT->notification(get_string('goodmodel', 'tool_analytics'),
|
||||
\core\output\notification::NOTIFY_SUCCESS);
|
||||
} else if ($result->status === \core_analytics\model::NO_DATASET) {
|
||||
$output .= $this->output->notification(get_string('nodatatoevaluate', 'tool_analytics'),
|
||||
$output .= $OUTPUT->notification(get_string('nodatatoevaluate', 'tool_analytics'),
|
||||
\core\output\notification::NOTIFY_WARNING);
|
||||
}
|
||||
|
||||
if (isset($result->score)) {
|
||||
// Score.
|
||||
$output .= $this->output->heading(get_string('accuracy', 'tool_analytics') . ': ' .
|
||||
$output .= $OUTPUT->heading(get_string('accuracy', 'tool_analytics') . ': ' .
|
||||
round(floatval($result->score), 4) * 100 . '%', 4);
|
||||
}
|
||||
|
||||
if (!empty($result->info)) {
|
||||
foreach ($result->info as $message) {
|
||||
$output .= $this->output->notification($message, \core\output\notification::NOTIFY_WARNING);
|
||||
$output .= $OUTPUT->notification($message, \core\output\notification::NOTIFY_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
if (!CLI_SCRIPT) {
|
||||
$output .= $this->output->box_end();
|
||||
$output .= $OUTPUT->box_end();
|
||||
}
|
||||
}
|
||||
|
||||
// Info logged during evaluation.
|
||||
if (!empty($logs) && debugging()) {
|
||||
$output .= $this->output->heading(get_string('extrainfo', 'tool_analytics'), 3);
|
||||
$output .= $OUTPUT->heading(get_string('extrainfo', 'tool_analytics'), 3);
|
||||
foreach ($logs as $log) {
|
||||
$output .= $this->output->notification($log, \core\output\notification::NOTIFY_WARNING);
|
||||
$output .= $OUTPUT->notification($log, \core\output\notification::NOTIFY_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
if (!CLI_SCRIPT) {
|
||||
$output .= $this->output->single_button(new \moodle_url('/admin/tool/analytics/index.php'),
|
||||
get_string('continue'), 'get');
|
||||
$output .= $OUTPUT->single_button(new \moodle_url('/admin/tool/analytics/index.php'), get_string('continue'), 'get');
|
||||
}
|
||||
|
||||
return $output;
|
||||
@@ -145,68 +147,62 @@ class renderer extends plugin_renderer_base {
|
||||
* @return string HTML
|
||||
*/
|
||||
public function render_get_predictions_results($trainresults = false, $trainlogs = array(), $predictresults = false, $predictlogs = array()) {
|
||||
global $OUTPUT;
|
||||
|
||||
$output = '';
|
||||
|
||||
if ($trainresults || (!empty($trainlogs) && debugging())) {
|
||||
$output .= $this->output->heading(get_string('trainingresults', 'tool_analytics'), 3);
|
||||
$output .= $OUTPUT->heading(get_string('trainingresults', 'tool_analytics'), 3);
|
||||
}
|
||||
|
||||
if ($trainresults) {
|
||||
if ($trainresults->status == 0) {
|
||||
$output .= $this->output->notification(
|
||||
get_string('trainingprocessfinished', 'tool_analytics'),
|
||||
$output .= $OUTPUT->notification(get_string('trainingprocessfinished', 'tool_analytics'),
|
||||
\core\output\notification::NOTIFY_SUCCESS);
|
||||
} else if ($trainresults->status === \core_analytics\model::NO_DATASET ||
|
||||
$trainresults->status === \core_analytics\model::NOT_ENOUGH_DATA) {
|
||||
$output .= $this->output->notification(
|
||||
get_string('nodatatotrain', 'tool_analytics'),
|
||||
$output .= $OUTPUT->notification(get_string('nodatatotrain', 'tool_analytics'),
|
||||
\core\output\notification::NOTIFY_WARNING);
|
||||
} else {
|
||||
$output .= $this->output->notification(
|
||||
get_string('generalerror', 'tool_analytics', $trainresults->status),
|
||||
$output .= $OUTPUT->notification(get_string('generalerror', 'tool_analytics', $trainresults->status),
|
||||
\core\output\notification::NOTIFY_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($trainlogs) && debugging()) {
|
||||
$output .= $this->output->heading(get_string('extrainfo', 'tool_analytics'), 4);
|
||||
$output .= $OUTPUT->heading(get_string('extrainfo', 'tool_analytics'), 4);
|
||||
foreach ($trainlogs as $log) {
|
||||
$output .= $this->output->notification($log, \core\output\notification::NOTIFY_WARNING);
|
||||
$output .= $OUTPUT->notification($log, \core\output\notification::NOTIFY_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
if ($predictresults || (!empty($predictlogs) && debugging())) {
|
||||
$output .= $this->output->heading(
|
||||
get_string('predictionresults', 'tool_analytics'), 3, 'main mt-3');
|
||||
$output .= $OUTPUT->heading(get_string('predictionresults', 'tool_analytics'), 3, 'main mt-3');
|
||||
}
|
||||
|
||||
if ($predictresults) {
|
||||
if ($predictresults->status == 0) {
|
||||
$output .= $this->output->notification(
|
||||
get_string('predictionprocessfinished', 'tool_analytics'),
|
||||
$output .= $OUTPUT->notification(get_string('predictionprocessfinished', 'tool_analytics'),
|
||||
\core\output\notification::NOTIFY_SUCCESS);
|
||||
} else if ($predictresults->status === \core_analytics\model::NO_DATASET ||
|
||||
$predictresults->status === \core_analytics\model::NOT_ENOUGH_DATA) {
|
||||
$output .= $this->output->notification(
|
||||
get_string('nodatatopredict', 'tool_analytics'),
|
||||
$output .= $OUTPUT->notification(get_string('nodatatopredict', 'tool_analytics'),
|
||||
\core\output\notification::NOTIFY_WARNING);
|
||||
} else {
|
||||
$output .= $this->output->notification(
|
||||
get_string('generalerror', 'tool_analytics', $predictresults->status),
|
||||
$output .= $OUTPUT->notification(get_string('generalerror', 'tool_analytics', $predictresults->status),
|
||||
\core\output\notification::NOTIFY_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($predictlogs) && debugging()) {
|
||||
$output .= $this->output->heading(get_string('extrainfo', 'tool_analytics'), 4);
|
||||
$output .= $OUTPUT->heading(get_string('extrainfo', 'tool_analytics'), 4);
|
||||
foreach ($predictlogs as $log) {
|
||||
$output .= $this->output->notification($log, \core\output\notification::NOTIFY_WARNING);
|
||||
$output .= $OUTPUT->notification($log, \core\output\notification::NOTIFY_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
if (!CLI_SCRIPT) {
|
||||
$output .= $this->output->single_button(new \moodle_url('/admin/tool/analytics/index.php'),
|
||||
get_string('continue'), 'get');
|
||||
$output .= $OUTPUT->single_button(new \moodle_url('/admin/tool/analytics/index.php'), get_string('continue'), 'get');
|
||||
}
|
||||
|
||||
return $output;
|
||||
@@ -240,18 +236,17 @@ class renderer extends plugin_renderer_base {
|
||||
* @return string HTML
|
||||
*/
|
||||
public function render_analytics_disabled() {
|
||||
global $FULLME;
|
||||
global $OUTPUT, $PAGE, $FULLME;
|
||||
|
||||
$this->page->set_url($FULLME);
|
||||
$this->page->set_title(get_string('pluginname', 'tool_analytics'));
|
||||
$this->page->set_heading(get_string('pluginname', 'tool_analytics'));
|
||||
$PAGE->set_url($FULLME);
|
||||
$PAGE->set_title(get_string('pluginname', 'tool_analytics'));
|
||||
$PAGE->set_heading(get_string('pluginname', 'tool_analytics'));
|
||||
|
||||
$output = $this->output->header();
|
||||
$output .= $this->output->notification(get_string('analyticsdisabled', 'analytics'),
|
||||
\core\output\notification::NOTIFY_INFO);
|
||||
$output = $OUTPUT->header();
|
||||
$output .= $OUTPUT->notification(get_string('analyticsdisabled', 'analytics'), \core\output\notification::NOTIFY_INFO);
|
||||
$output .= \html_writer::tag('a', get_string('continue'), ['class' => 'btn btn-primary',
|
||||
'href' => (new \moodle_url('/'))->out()]);
|
||||
$output .= $this->output->footer();
|
||||
$output .= $OUTPUT->footer();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2020061500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2020060900; // Requires this Moodle version.
|
||||
$plugin->version = 2019111800; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2019111200; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_analytics'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2020061500;
|
||||
$plugin->requires = 2020060900;
|
||||
$plugin->version = 2019111800;
|
||||
$plugin->requires = 2019111200;
|
||||
$plugin->component = 'tool_availabilityconditions';
|
||||
|
||||
@@ -164,8 +164,6 @@ if ($options['install']) {
|
||||
mtrace("Acceptance tests site installed");
|
||||
}
|
||||
|
||||
// Note: Do not build the themes here. This is done during the 'enable' stage.
|
||||
|
||||
} else if ($options['drop']) {
|
||||
// Ensure no tests are running.
|
||||
test_lock::acquire('behat');
|
||||
@@ -184,10 +182,6 @@ if ($options['install']) {
|
||||
// Enable test mode.
|
||||
behat_util::start_test_mode($options['add-core-features-to-theme'], $options['optimize-runs'], $parallel, $run);
|
||||
|
||||
// Themes are only built in the 'enable' command.
|
||||
behat_util::build_themes();
|
||||
mtrace("Testing environment themes built");
|
||||
|
||||
// This is only displayed once for parallel install.
|
||||
if (empty($run)) {
|
||||
// Notify user that 2.5 profile has been converted to 3.5.
|
||||
|
||||
@@ -32,7 +32,7 @@ require_once($CFG->libdir . '/behat/classes/behat_config_manager.php');
|
||||
// systems, but let's allow room for expansion.
|
||||
core_php_time_limit::raise(300);
|
||||
|
||||
$filter = optional_param('filter', '', PARAM_NOTAGS);
|
||||
$filter = optional_param('filter', '', PARAM_ALPHANUMEXT);
|
||||
$type = optional_param('type', false, PARAM_ALPHAEXT);
|
||||
$component = optional_param('component', '', PARAM_ALPHAEXT);
|
||||
|
||||
|
||||
@@ -24,7 +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['errorapproot'] = '$CFG->behat_ionic_dirroot is not pointing to a valid Moodle Mobile 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.';
|
||||
@@ -46,7 +46,6 @@ $string['stepsdefinitionstype'] = 'Type';
|
||||
$string['theninfo'] = 'Then. Checkings to ensure the outcomes are the expected ones';
|
||||
$string['unknownexceptioninfo'] = 'There was a problem with Selenium or your browser. Please ensure you are using the latest version of Selenium. Error:';
|
||||
$string['viewsteps'] = 'Filter';
|
||||
$string['warndirrootconfigfound'] = 'A configuration file was found at {$a}. This file is not automatically updated and may become stale. We recommend removing this file.';
|
||||
$string['wheninfo'] = 'When. Action that provokes an event';
|
||||
$string['wrongbehatsetup'] = 'Something is wrong with the behat setup and so step definitions cannot be listed: <b>{$a->errormsg}</b><br/><br/>Please check:<ul>
|
||||
<li>$CFG->behat_dataroot, $CFG->behat_prefix and $CFG->behat_wwwroot are set in config.php with different values from $CFG->dataroot, $CFG->prefix and $CFG->wwwroot.</li>
|
||||
|
||||
@@ -55,13 +55,13 @@ class tool_behat {
|
||||
// The loaded steps depends on the component specified.
|
||||
behat_config_manager::update_config_file($component, false);
|
||||
|
||||
// The Moodle\BehatExtension\Definition\Printer\ConsoleDefinitionInformationPrinter will parse this search format.
|
||||
// The Moodle\BehatExtension\HelpPrinter\MoodleDefinitionsPrinter will parse this search format.
|
||||
if ($type) {
|
||||
$filter .= '&&' . $type;
|
||||
}
|
||||
|
||||
if ($filter) {
|
||||
$filteroption = ' -d ' . escapeshellarg($filter);
|
||||
$filteroption = ' -d "' . $filter . '"';
|
||||
} else {
|
||||
$filteroption = ' -di';
|
||||
}
|
||||
|
||||
@@ -44,9 +44,13 @@ class tool_behat_renderer extends plugin_renderer_base {
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/behat/classes/behat_selectors.php');
|
||||
|
||||
$html = $this->output->header();
|
||||
$html .= $this->output->heading(get_string('pluginname', 'tool_behat'));
|
||||
$html .= $form->render();
|
||||
$html = $this->generic_info();
|
||||
|
||||
// Form.
|
||||
ob_start();
|
||||
$form->display();
|
||||
$html .= ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
if (empty($stepsdefinitions)) {
|
||||
$stepsdefinitions = get_string('nostepsdefinitions', 'tool_behat');
|
||||
@@ -124,9 +128,7 @@ class tool_behat_renderer extends plugin_renderer_base {
|
||||
*/
|
||||
public function render_error($msg) {
|
||||
|
||||
$html = $this->output->header();
|
||||
$html .= $this->output->heading(get_string('pluginname', 'tool_behat'));
|
||||
$html .= $this->generic_info();
|
||||
$html = $this->generic_info();
|
||||
|
||||
$a = new stdClass();
|
||||
$a->errormsg = $msg;
|
||||
@@ -151,7 +153,13 @@ class tool_behat_renderer extends plugin_renderer_base {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generic_info() {
|
||||
protected function generic_info() {
|
||||
|
||||
$title = get_string('pluginname', 'tool_behat');
|
||||
|
||||
// Header.
|
||||
$html = $this->output->header();
|
||||
$html .= $this->output->heading($title);
|
||||
|
||||
// Info.
|
||||
$installurl = behat_command::DOCS_URL;
|
||||
@@ -167,7 +175,8 @@ class tool_behat_renderer extends plugin_renderer_base {
|
||||
);
|
||||
|
||||
// List of steps.
|
||||
$html = $this->output->box_start();
|
||||
$html .= $this->output->box_start();
|
||||
$html .= html_writer::tag('h3', get_string('infoheading', 'tool_behat'));
|
||||
$html .= html_writer::tag('div', get_string('aim', 'tool_behat'));
|
||||
$html .= html_writer::start_tag('div');
|
||||
$html .= html_writer::start_tag('ul');
|
||||
|
||||
@@ -40,14 +40,8 @@ class steps_definitions_form extends moodleform {
|
||||
* @return void
|
||||
*/
|
||||
public function definition() {
|
||||
global $PAGE;
|
||||
|
||||
$mform = $this->_form;
|
||||
$output = $PAGE->get_renderer('tool_behat');
|
||||
|
||||
$mform->addElement('header', 'info', get_string('infoheading', 'tool_behat'));
|
||||
$mform->setExpanded('info', false);
|
||||
$mform->addElement('html', $output->generic_info());
|
||||
|
||||
$mform->addElement('header', 'filters', get_string('stepsdefinitionsfilters', 'tool_behat'));
|
||||
|
||||
|
||||
+14
-20
@@ -1,31 +1,25 @@
|
||||
#page-admin-tool-behat-index .steps-definitions {
|
||||
margin: 1rem auto;
|
||||
.steps-definitions {
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #bbb;
|
||||
padding: 5px;
|
||||
margin: auto;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
#page-admin-tool-behat-index .steps-definitions .step {
|
||||
margin: 1rem 0 0 0;
|
||||
border: 1px solid #eee;
|
||||
padding: 1rem;
|
||||
.steps-definitions .step {
|
||||
margin: 10px 0 10px 0;
|
||||
}
|
||||
|
||||
#page-admin-tool-behat-index .steps-definitions .stepdescription {
|
||||
font-style: italic;
|
||||
.steps-definitions .stepdescription {
|
||||
color: #bf8c12;
|
||||
}
|
||||
|
||||
#page-admin-tool-behat-index .steps-definitions .stepcontent {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
#page-admin-tool-behat-index .steps-definitions .steptype {
|
||||
.steps-definitions .steptype {
|
||||
color: #1467a6;
|
||||
margin-right: 1ex;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#page-admin-tool-behat-index .steps-definitions .stepapipath {
|
||||
font-family: monospace;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
#page-admin-tool-behat-index .steps-definitions .stepregex {
|
||||
.steps-definitions .stepregex {
|
||||
color: #060;
|
||||
}
|
||||
|
||||
@@ -143,20 +143,20 @@ Feature: Set up contextual data for tests
|
||||
And I log out
|
||||
And I log in as "user2"
|
||||
And I am on "Course 1" course homepage
|
||||
And "Turn editing on" "button" should exist
|
||||
And "Turn editing on" "link" should exist in current page administration
|
||||
And I log out
|
||||
And I log in as "user3"
|
||||
And I am on "Course 1" course homepage
|
||||
And "Turn editing on" "button" should exist
|
||||
And "Turn editing on" "link" should exist in current page administration
|
||||
And I log out
|
||||
And I log in as "user4"
|
||||
And I am on "Course 1" course homepage
|
||||
And "Turn editing on" "button" should exist
|
||||
And "Turn editing on" "link" should exist in current page administration
|
||||
And I log out
|
||||
And I log in as "user5"
|
||||
And I should see "You are logged in as"
|
||||
And I am on "Course 1" course homepage
|
||||
And I should see "You cannot enrol yourself in this course."
|
||||
And I should see "You can not enrol yourself in this course."
|
||||
|
||||
Scenario: Add modules
|
||||
Given the following "courses" exist:
|
||||
@@ -259,9 +259,9 @@ Feature: Set up contextual data for tests
|
||||
Then the "groups" select box should contain "Group 1 (1)"
|
||||
And the "groups" select box should contain "Group 2 (1)"
|
||||
And I set the field "groups" to "Group 1 (1)"
|
||||
And the "members" select box should contain "Student 1 (student1@example.com)"
|
||||
And the "members" select box should contain "Student 1"
|
||||
And I set the field "groups" to "Group 2 (1)"
|
||||
And the "members" select box should contain "Student 2 (student2@example.com)"
|
||||
And the "members" select box should contain "Student 2"
|
||||
|
||||
Scenario: Add cohorts and cohort members with data generator
|
||||
Given the following "categories" exist:
|
||||
|
||||
@@ -6,18 +6,14 @@ Feature: Edit capabilities
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname |
|
||||
| teacher1 | Teacher | 1 |
|
||||
| tutor | Teaching | Assistant |
|
||||
| student | Student | One |
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname |
|
||||
| Course 1 | C1 |
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| tutor | C1 | teacher |
|
||||
| student | C1 | student |
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
|
||||
Scenario: Default system capabilities modification
|
||||
Given I log in as "admin"
|
||||
@@ -64,25 +60,3 @@ Feature: Edit capabilities
|
||||
Then "mod/forum:deleteanypost" capability has "Prohibit" permission
|
||||
And "mod/forum:editanypost" capability has "Prevent" permission
|
||||
And "mod/forum:addquestion" capability has "Allow" permission
|
||||
|
||||
@javascript
|
||||
Scenario: Edit permissions escapes role names correctly
|
||||
When I am on the "C1" "Course" page logged in as "admin"
|
||||
And I navigate to "Edit settings" in current page administration
|
||||
And I set the following fields to these values:
|
||||
| Your word for 'Teacher' | Teacher >= editing |
|
||||
| Your word for 'Non-editing teacher' | Teacher < "editing" |
|
||||
| Your word for 'Student' | Studier & 'learner' |
|
||||
And I press "Save and display"
|
||||
And I navigate to course participants
|
||||
Then I should see "Teacher >= editing" in the "Teacher 1" "table_row"
|
||||
And I should see "Teacher < \"editing\"" in the "Teaching Assistant" "table_row"
|
||||
And I should see "Studier & 'learner'" in the "Student One" "table_row"
|
||||
And I navigate to "Users > Permissions" in current page administration
|
||||
And I should see "Teacher >= editing" in the "mod/forum:replypost" "table_row"
|
||||
And I should see "Teacher < \"editing\"" in the "mod/forum:replypost" "table_row"
|
||||
And I should see "Studier & 'learner'" in the "mod/forum:replypost" "table_row"
|
||||
And I follow "Prohibit"
|
||||
And "Teacher >= editing" "button" in the "Prohibit role" "dialogue" should be visible
|
||||
And "Teacher < \"editing\"" "button" in the "Prohibit role" "dialogue" should be visible
|
||||
And "Studier & 'learner'" "button" in the "Prohibit role" "dialogue" should be visible
|
||||
|
||||
@@ -147,13 +147,13 @@ Feature: Verify that all form fields values can be get and set
|
||||
And I navigate to "Users > Groups" in current page administration
|
||||
# Select (multi-select & AJAX) - Checking "I set the field" and "select box should contain".
|
||||
And I set the field "groups" to "Group 2"
|
||||
And the "members" select box should contain "Student 2 (s2@example.com)"
|
||||
And the "members" select box should contain "Student 3 (s3@example.com)"
|
||||
And the "members" select box should not contain "Student 1 (s1@example.com)"
|
||||
And the "members" select box should contain "Student 2"
|
||||
And the "members" select box should contain "Student 3"
|
||||
And the "members" select box should not contain "Student 1"
|
||||
And I set the field "groups" to "Group 1"
|
||||
And the "members" select box should contain "Student 1 (s1@example.com)"
|
||||
And the "members" select box should contain "Student 2 (s2@example.com)"
|
||||
And the "members" select box should not contain "Student 3 (s3@example.com)"
|
||||
And the "members" select box should contain "Student 1"
|
||||
And the "members" select box should contain "Student 2"
|
||||
And the "members" select box should not contain "Student 3"
|
||||
# Checkbox (AJAX) - Checking "I set the field" and "I set the following fields to these values".
|
||||
And I am on "Course 1" course homepage
|
||||
And I add a "Lesson" to section "1"
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
@tool_behat
|
||||
Feature: Verify that the inplace editable field works as expected
|
||||
In order to use behat step definitions
|
||||
As a test write
|
||||
I need to ensure that the inplace editable works in forms
|
||||
|
||||
Background:
|
||||
Given the following "course" exists:
|
||||
| fullname | Course 1 |
|
||||
| shortname | C1 |
|
||||
And the following "activities" exist:
|
||||
| activity | course | name | idnumber |
|
||||
| forum | C1 | My first forum | forum1 |
|
||||
| assign | C1 | My first assignment | assign1 |
|
||||
| quiz | C1 | My first quiz | quiz1 |
|
||||
And I log in as "admin"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
|
||||
@javascript
|
||||
Scenario: Using an inplace editable updates the name of an activity
|
||||
When I set the field "Edit title" in the "My first assignment" "activity" to "Coursework submission"
|
||||
Then I should see "Coursework submission"
|
||||
And I should not see "My first assignment"
|
||||
But I should see "My first forum"
|
||||
And I should see "My first quiz"
|
||||
And I set the field "Edit title" in the "Coursework submission" "activity" to "My first assignment"
|
||||
And I should not see "Coursework submission"
|
||||
But I should see "My first assignment"
|
||||
And I should see "My first forum"
|
||||
And I should see "My first quiz"
|
||||
@@ -1,52 +0,0 @@
|
||||
@tool_behat
|
||||
Feature: Verify that keyboard steps work as expected
|
||||
In order to use behat step definitions
|
||||
As a test writer
|
||||
I need to verify that the keyboard steps work as expected
|
||||
|
||||
@javascript
|
||||
Scenario: Typing keys into a field causes them to be input
|
||||
Given the following "users" exist:
|
||||
| username | email | firstname | lastname | password |
|
||||
| saffronr | saffron.rutledge@example.com | Saffron | Rutledge | flowerpower |
|
||||
Given I click on "Log in" "link"
|
||||
And I click on "Username" "field"
|
||||
When I type "saffronr"
|
||||
And I press the tab key
|
||||
And I type "flowerpower"
|
||||
And I press enter
|
||||
Then I should see "You are logged in as Saffron Rutledge"
|
||||
|
||||
@javascript
|
||||
Scenario: Using tab changes focus to the next or previous field
|
||||
Given I click on "Log in" "link"
|
||||
And I click on "Username" "field"
|
||||
And the focused element is "Username" "field"
|
||||
When I press the tab key
|
||||
Then the focused element is "Password" "field"
|
||||
|
||||
And I press the shift tab key
|
||||
And the focused element is "Username" "field"
|
||||
|
||||
@javascript
|
||||
Scenario: Using the arrow keys allows me to navigate through menus
|
||||
Given the following "users" exist:
|
||||
| username | email | firstname | lastname |
|
||||
| saffronr | saffron.rutledge@example.com | Saffron | Rutledge |
|
||||
And I log in as "saffronr"
|
||||
And I click on "Saffron Rutledge" "link" in the ".usermenu" "css_element"
|
||||
When I press the up key
|
||||
Then the focused element is "Log out" "link"
|
||||
|
||||
@javascript
|
||||
Scenario: The escape key can be used to close a dialogue
|
||||
Given the following "course" exists:
|
||||
| fullname | C1|
|
||||
| shortname | C1 |
|
||||
And I log in as "admin"
|
||||
And I am on "C1" course homepage
|
||||
And I navigate to course participants
|
||||
And I press "Enrol users"
|
||||
And "Enrol users" "dialogue" should be visible
|
||||
When I press the escape key
|
||||
Then "Enrol users" "dialogue" should not be visible
|
||||
@@ -26,11 +26,3 @@ Feature: List the system steps definitions
|
||||
Given I set the field "Contains" to "homepage"
|
||||
When I press "Filter"
|
||||
Then I should see "Opens Moodle homepage."
|
||||
|
||||
@javascript
|
||||
Scenario: Filtering by the multiple words pattern
|
||||
Given I set the field "Contains" to "should exist"
|
||||
When I press "Filter"
|
||||
Then I should not see "There aren't steps definitions matching this filter"
|
||||
And I should see "Checks the provided element and selector type exists in the current page."
|
||||
And I should see "Checks that an element and selector type exists in another element and selector type on the current page."
|
||||
|
||||
@@ -14,6 +14,8 @@ Feature: Forms manipulation
|
||||
Then the field "First name" matches value "Field value"
|
||||
And the "Select a country" select box should contain "Japan"
|
||||
And the field "New password" matches value "TestPass"
|
||||
And I take focus off "Update profile" "button"
|
||||
And I press "Update profile"
|
||||
|
||||
@javascript
|
||||
Scenario: Expand all fieldsets and advanced elements
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2020061500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2020060900; // Requires this Moodle version
|
||||
$plugin->version = 2019111800; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2019111200; // Requires this Moodle version
|
||||
$plugin->component = 'tool_behat'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -60,12 +60,7 @@ class tool_capability_settings_form extends moodleform {
|
||||
$form->addElement('select', 'roles', get_string('roleslabel', 'tool_capability'), $roles, $attributes);
|
||||
$form->setType('roles', PARAM_TEXT);
|
||||
|
||||
$filters = [];
|
||||
$filters[] = $form->createElement('checkbox', 'onlydiff', get_string('onlydiff', 'tool_capability'));
|
||||
$form->setType('onlydiff', PARAM_BOOL);
|
||||
$form->addGroup($filters, 'filters', get_string('filters', 'tool_capability'), array('<br>'), false);
|
||||
|
||||
$form->addElement('submit', 'submitbutton', get_string('getreport', 'tool_capability'));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,6 @@ $capabilities = array();
|
||||
$rolestoshow = array();
|
||||
$roleids = array('0');
|
||||
$cleanedroleids = array();
|
||||
$onlydiff = false;
|
||||
if ($data = $form->get_data()) {
|
||||
|
||||
$roleids = array();
|
||||
@@ -91,10 +90,6 @@ if ($data = $form->get_data()) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($data->onlydiff)) {
|
||||
$onlydiff = $data->onlydiff;
|
||||
}
|
||||
}
|
||||
|
||||
\tool_capability\event\report_viewed::create()->trigger();
|
||||
@@ -108,7 +103,7 @@ $form->display();
|
||||
// If we have a capability, generate the report.
|
||||
if (count($capabilities) && count($rolestoshow)) {
|
||||
/* @var tool_capability_renderer $renderer */
|
||||
echo $renderer->capability_comparison_table($capabilities, $context->id, $rolestoshow, $onlydiff);
|
||||
echo $renderer->capability_comparison_table($capabilities, $context->id, $rolestoshow);
|
||||
}
|
||||
|
||||
// Footer.
|
||||
@@ -143,7 +138,7 @@ function print_report_tree($contextid, $contexts, $allroles) {
|
||||
// If there are any role overrides here, print them.
|
||||
if (!empty($contexts[$contextid]->rolecapabilities)) {
|
||||
$rowcounter = 0;
|
||||
echo '<table class="generaltable table-striped"><tbody>';
|
||||
echo '<table class="generaltable rolecaps"><tbody>';
|
||||
foreach ($allroles as $role) {
|
||||
if (isset($contexts[$contextid]->rolecapabilities[$role->id])) {
|
||||
$permission = $contexts[$contextid]->rolecapabilities[$role->id];
|
||||
|
||||
@@ -22,18 +22,15 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['onlydiff'] = 'Show differences only';
|
||||
$string['capabilitylabel'] = 'Capability:';
|
||||
$string['capabilityreport'] = 'Capability overview';
|
||||
$string['eventreportviewed'] = 'Report viewed';
|
||||
$string['filters'] = 'Filter results';
|
||||
$string['forroles'] = 'For roles {$a}';
|
||||
$string['getreport'] = 'Get the overview';
|
||||
$string['changeoverrides'] = 'Change overrides in this context';
|
||||
$string['changeroles'] = 'Change role definitions';
|
||||
$string['intro'] = 'This report shows, for a particular capability, what permission that capability has in the definition of every role (or a selection of roles), and everywhere in the site where that capability is overridden.';
|
||||
$string['pluginname'] = 'Capability overview';
|
||||
$string['nodifferences'] = 'There are no differences to show between selected roles in this context';
|
||||
$string['reportforcapability'] = 'Report for capability \'{$a}\'';
|
||||
$string['reportsettings'] = 'Report settings';
|
||||
$string['roleslabel'] = 'Roles:';
|
||||
|
||||
@@ -53,12 +53,7 @@ function tool_capability_calculate_role_data($capability, array $roles) {
|
||||
$sql = 'SELECT DISTINCT con.path, 1
|
||||
FROM {context} con
|
||||
JOIN {role_capabilities} rc ON rc.contextid = con.id
|
||||
WHERE capability = ? ' .
|
||||
$sqlroletest .
|
||||
// Context path should never be null, but can happen in old database with
|
||||
// bad data (e.g. a course_module where the corresponding course no longer exists).
|
||||
// We need to leave these out of the report to prevent errors.
|
||||
' AND con.path IS NOT NULL';
|
||||
WHERE capability = ? '.$sqlroletest;
|
||||
$relevantpaths = $DB->get_records_sql_menu($sql, $params);
|
||||
$requiredcontexts = array($systemcontext->id);
|
||||
foreach ($relevantpaths as $path => $notused) {
|
||||
@@ -93,10 +88,6 @@ function tool_capability_calculate_role_data($capability, array $roles) {
|
||||
|
||||
// Put the role capabilities into the context tree.
|
||||
foreach ($rolecaps as $rolecap) {
|
||||
if (!isset($contexts[$rolecap->contextid])) {
|
||||
// Skip capabilities in orphaned contexts that are not in the tree.
|
||||
continue;
|
||||
}
|
||||
$contexts[$rolecap->contextid]->rolecapabilities[$rolecap->roleid] = $rolecap->permission;
|
||||
}
|
||||
|
||||
@@ -108,4 +99,4 @@ function tool_capability_calculate_role_data($capability, array $roles) {
|
||||
}
|
||||
|
||||
return $contexts;
|
||||
}
|
||||
}
|
||||
@@ -72,11 +72,9 @@ class tool_capability_renderer extends plugin_renderer_base {
|
||||
* @param array $capabilities An array of capabilities to show comparison for.
|
||||
* @param int $contextid The context we are displaying for.
|
||||
* @param array $roles An array of roles to show comparison for.
|
||||
* @param bool $onlydiff show only different permissions
|
||||
* @return string
|
||||
*/
|
||||
public function capability_comparison_table(array $capabilities, $contextid, array $roles, $onlydiff=false) {
|
||||
static $capabilitycontexts = array();
|
||||
public function capability_comparison_table(array $capabilities, $contextid, array $roles) {
|
||||
|
||||
$strpermissions = $this->get_permission_strings();
|
||||
$permissionclasses = $this->get_permission_classes();
|
||||
@@ -94,39 +92,25 @@ class tool_capability_renderer extends plugin_renderer_base {
|
||||
}
|
||||
$table->data = array();
|
||||
|
||||
$childcontextsids = [];
|
||||
foreach ($capabilities as $capability) {
|
||||
if (empty($capabilitycontexts[$capability])) {
|
||||
$capabilitycontexts[$capability] = tool_capability_calculate_role_data($capability, $roles);
|
||||
}
|
||||
$contexts = $capabilitycontexts[$capability];
|
||||
|
||||
$contexts = tool_capability_calculate_role_data($capability, $roles);
|
||||
$captitle = new html_table_cell(get_capability_string($capability) . html_writer::span($capability));
|
||||
$captitle->header = true;
|
||||
|
||||
$row = new html_table_row(array($captitle));
|
||||
|
||||
$permissiontypes = array();
|
||||
foreach ($roles as $role) {
|
||||
if (isset($contexts[$contextid]->rolecapabilities[$role->id])) {
|
||||
$permission = $contexts[$contextid]->rolecapabilities[$role->id];
|
||||
} else {
|
||||
$permission = CAP_INHERIT;
|
||||
}
|
||||
if (!in_array($permission, $permissiontypes)) {
|
||||
$permissiontypes[] = $permission;
|
||||
}
|
||||
$cell = new html_table_cell($strpermissions[$permission]);
|
||||
$cell->attributes['class'] = $permissionclasses[$permission];
|
||||
$row->cells[] = $cell;
|
||||
}
|
||||
if (!$onlydiff || count($permissiontypes) > 1) {
|
||||
$table->data[] = $row;
|
||||
}
|
||||
if (!empty($contexts[$contextid]->children)) {
|
||||
$childcontextsids = array_merge($childcontextsids, $contexts[$contextid]->children);
|
||||
$childcontextsids = array_unique($childcontextsids);
|
||||
}
|
||||
|
||||
$table->data[] = $row;
|
||||
}
|
||||
|
||||
// Start the list item, and print the context name as a link to the place to make changes.
|
||||
@@ -141,15 +125,11 @@ class tool_capability_renderer extends plugin_renderer_base {
|
||||
$title = get_string('permissionsincontext', 'core_role', $context->get_context_name());
|
||||
|
||||
$html = $this->output->heading(html_writer::link($url, $title), 3);
|
||||
if (!empty($table->data)) {
|
||||
$html .= html_writer::table($table);
|
||||
} else {
|
||||
$html .= html_writer::tag('p', get_string('nodifferences', 'tool_capability'));
|
||||
}
|
||||
$html .= html_writer::table($table);
|
||||
// If there are any child contexts, print them recursively.
|
||||
if (!empty($childcontextsids)) {
|
||||
foreach ($childcontextsids as $childcontextid) {
|
||||
$html .= $this->capability_comparison_table($capabilities, $childcontextid, $roles, $onlydiff);
|
||||
if (!empty($contexts[$contextid]->children)) {
|
||||
foreach ($contexts[$contextid]->children as $childcontextid) {
|
||||
$html .= $this->capability_comparison_table($capabilities, $childcontextid, $roles, true);
|
||||
}
|
||||
}
|
||||
return $html;
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
@tool @tool_capability
|
||||
Feature: show capabilities for selected roles
|
||||
In order to check roles capabilities
|
||||
As an admin
|
||||
I need to be able to customize capabilities report viewing only specific roles and capabilities
|
||||
|
||||
Background:
|
||||
Given the following "roles" exist:
|
||||
| shortname | name | archetype |
|
||||
| studenteq | Studenteq | student |
|
||||
| studentdf | Studentdf | student |
|
||||
And the following "permission overrides" exist:
|
||||
| capability | permission | role | contextlevel | reference |
|
||||
| moodle/course:changefullname | Allow | studentdf | System | |
|
||||
| moodle/course:changeshortname | Prohibit | studentdf | System | |
|
||||
| moodle/course:changeidnumber | Prevent | studentdf | System | |
|
||||
And I log in as "admin"
|
||||
And I navigate to "Users > Permissions > Capability overview" in site administration
|
||||
|
||||
Scenario: visualize capabilities table with a limited number of capabilities
|
||||
When I set the following fields to these values:
|
||||
| Capability: | moodle/course:changefullname, moodle/course:changeshortname |
|
||||
| Roles: | Studentdf |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "moodle/course:changefullname" in the "comparisontable" "table"
|
||||
And I should see "moodle/course:changeshortname" in the "comparisontable" "table"
|
||||
And I should not see "moodle/course:changecategory" in the "comparisontable" "table"
|
||||
|
||||
Scenario: visualize an allow capability
|
||||
When I set the following fields to these values:
|
||||
| Capability: | moodle/course:changefullname |
|
||||
| Roles: | Studentdf |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Allow" in the "comparisontable" "table"
|
||||
And I should not see "Prevent" in the "comparisontable" "table"
|
||||
And I should not see "Prohibit" in the "comparisontable" "table"
|
||||
And I should not see "Not set" in the "comparisontable" "table"
|
||||
|
||||
Scenario: visualize a prohibit capability
|
||||
When I set the following fields to these values:
|
||||
| Capability: | moodle/course:changeshortname |
|
||||
| Roles: | Studentdf |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should not see "Allow" in the "comparisontable" "table"
|
||||
And I should not see "Prevent" in the "comparisontable" "table"
|
||||
And I should see "Prohibit" in the "comparisontable" "table"
|
||||
And I should not see "Not set" in the "comparisontable" "table"
|
||||
|
||||
Scenario: visualize a not set capability
|
||||
When I set the following fields to these values:
|
||||
| Capability: | moodle/course:changecategory |
|
||||
| Roles: | Studentdf |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should not see "Allow" in the "comparisontable" "table"
|
||||
And I should not see "Prevent" in the "comparisontable" "table"
|
||||
And I should not see "Prohibit" in the "comparisontable" "table"
|
||||
And I should see "Not set" in the "comparisontable" "table"
|
||||
|
||||
Scenario: visualize more than one role
|
||||
When I set the following fields to these values:
|
||||
| Capability: | moodle/course:changecategory |
|
||||
| Roles: | Student, Studentdf |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Student" in the "comparisontable" "table"
|
||||
And I should see "Studentdf" in the "comparisontable" "table"
|
||||
And I should not see "Teacher" in the "comparisontable" "table"
|
||||
|
||||
Scenario: visualize all roles without selecting any role
|
||||
When I set the following fields to these values:
|
||||
| Capability: | moodle/course:changecategory |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Student" in the "comparisontable" "table"
|
||||
And I should see "Studentdf" in the "comparisontable" "table"
|
||||
And I should see "Teacher" in the "comparisontable" "table"
|
||||
|
||||
Scenario: visualize all roles by selecting All option
|
||||
When I set the following fields to these values:
|
||||
| Capability: | moodle/course:changecategory |
|
||||
| Roles: | All |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Student" in the "comparisontable" "table"
|
||||
And I should see "Studentdf" in the "comparisontable" "table"
|
||||
And I should see "Teacher" in the "comparisontable" "table"
|
||||
|
||||
@javascript
|
||||
Scenario: filter capability list using javascript
|
||||
Given I should see "moodle/site:config" in the "Capability" "field"
|
||||
And I should see "moodle/course:change" in the "Capability" "field"
|
||||
When I wait until the page is ready
|
||||
And I set the field "capabilitysearch" to "moodle/course:change"
|
||||
Then I should see "moodle/course:change" in the "Capability" "field"
|
||||
And I should not see "moodle/site:config" in the "Capability" "field"
|
||||
|
||||
@javascript
|
||||
Scenario: selecting capabilities using filters
|
||||
Given I should see "moodle/course:change" in the "Capability" "field"
|
||||
When I wait until the page is ready
|
||||
And I set the field "capabilitysearch" to "moodle/course:change"
|
||||
When I set the following fields to these values:
|
||||
| Capability: | moodle/course:changecategory |
|
||||
| Roles: | Student |
|
||||
And I set the field "capabilitysearch" to ""
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "moodle/course:changecategory" in the "comparisontable" "table"
|
||||
@@ -1,133 +0,0 @@
|
||||
@tool @tool_capability
|
||||
Feature: Show capabilities for multiple contexts
|
||||
In order to check roles capabilities
|
||||
As an admin
|
||||
I need to be able to see capability overrides on several contexts
|
||||
|
||||
Background:
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
| Course 2 | C2 | 0 |
|
||||
And the following "permission overrides" exist:
|
||||
| capability | permission | role | contextlevel | reference |
|
||||
| enrol/category:config | Allow | student | Course | C1 |
|
||||
| enrol/cohort:unenrol | Allow | student | Course | C2 |
|
||||
And I log in as "admin"
|
||||
And I navigate to "Users > Permissions > Capability overview" in site administration
|
||||
|
||||
Scenario: Show capabilities table with one capability with overrides
|
||||
When I set the following fields to these values:
|
||||
| Capability: | enrol/category:config |
|
||||
| Roles: | Student |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Permissions in System"
|
||||
And I should see "Permissions in Category: Miscellaneous"
|
||||
And I should see "Permissions in Course: Course 1"
|
||||
And I should not see "Permissions in Course: Course 2"
|
||||
|
||||
Scenario: Show capabilities table with one capability without overrides
|
||||
When I set the following fields to these values:
|
||||
| Capability: | enrol/cohort:config |
|
||||
| Roles: | Student |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Permissions in System"
|
||||
And I should not see "Permissions in Category: Miscellaneous"
|
||||
And I should not see "Permissions in Course: Course 1"
|
||||
And I should not see "Permissions in Course: Course 2"
|
||||
|
||||
Scenario: Show capabilities table with two capabilities, 1st without overrides and 2nd with
|
||||
When I set the following fields to these values:
|
||||
| Capability: | enrol/category:synchronised, enrol/category:config |
|
||||
| Roles: | Student |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Permissions in System"
|
||||
And I should see "Permissions in Category: Miscellaneous"
|
||||
And I should see "Permissions in Course: Course 1"
|
||||
And I should not see "Permissions in Course: Course 2"
|
||||
|
||||
Scenario: Show capabilities table with two capabilities, 1st with overrides and 2nd without
|
||||
When I set the following fields to these values:
|
||||
| Capability: | enrol/category:config, enrol/cohort:config |
|
||||
| Roles: | Student |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Permissions in System"
|
||||
And I should see "Permissions in Category: Miscellaneous"
|
||||
And I should see "Permissions in Course: Course 1"
|
||||
And I should not see "Permissions in Course: Course 2"
|
||||
|
||||
Scenario: Show capabilities table with two capabilities, none with overrides
|
||||
When I set the following fields to these values:
|
||||
| Capability: | enrol/category:synchronised, enrol/cohort:config |
|
||||
| Roles: | Student |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Permissions in System"
|
||||
And I should not see "Permissions in Category: Miscellaneous"
|
||||
And I should not see "Permissions in Course: Course 1"
|
||||
And I should not see "Permissions in Course: Course 2"
|
||||
|
||||
Scenario: Show capabilities table with capability with override and no role selected
|
||||
When I set the following fields to these values:
|
||||
| Capability: | enrol/category:config |
|
||||
| Roles: | |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Permissions in System"
|
||||
And I should see "Permissions in Category: Miscellaneous"
|
||||
And I should see "Permissions in Course: Course 1"
|
||||
And I should not see "Permissions in Course: Course 2"
|
||||
|
||||
Scenario: Show capabilities table with capability without override and no role selected
|
||||
When I set the following fields to these values:
|
||||
| Capability: | enrol/cohort:config |
|
||||
| Roles: | |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Permissions in System"
|
||||
And I should not see "Permissions in Category: Miscellaneous"
|
||||
And I should not see "Permissions in Course: Course 1"
|
||||
And I should not see "Permissions in Course: Course 2"
|
||||
|
||||
Scenario: Show capabilities table with capability with two overrides on different contexts
|
||||
When I set the following fields to these values:
|
||||
| Capability: | enrol/category:config, enrol/cohort:unenrol |
|
||||
| Roles: | |
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Permissions in System"
|
||||
And I should see "Permissions in Category: Miscellaneous"
|
||||
And I should see "Permissions in Course: Course 1"
|
||||
And I should see "Permissions in Course: Course 2"
|
||||
|
||||
Scenario: Show capabilities table with capability with override and only diff
|
||||
When I set the following fields to these values:
|
||||
| Capability: | enrol/category:config |
|
||||
| Roles: | Student, Teacher |
|
||||
And I set the field "Show differences only" to "1"
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Permissions in System"
|
||||
And I should see "Permissions in Category: Miscellaneous"
|
||||
And I should see "There are no differences to show between selected roles in this context"
|
||||
And I should see "Permissions in Course: Course 1"
|
||||
And I should not see "Permissions in Course: Course 2"
|
||||
|
||||
Scenario: Show capabilities table with capability without override and only diff and same capability
|
||||
When I set the following fields to these values:
|
||||
| Capability: | enrol/category:synchronised |
|
||||
| Roles: | Student, Teacher |
|
||||
And I set the field "Show differences only" to "1"
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Permissions in System"
|
||||
And I should see "There are no differences to show between selected roles in this context"
|
||||
And I should not see "Permissions in Category: Miscellaneous"
|
||||
And I should not see "Permissions in Course: Course 1"
|
||||
And I should not see "Permissions in Course: Course 2"
|
||||
|
||||
Scenario: Show capabilities table with two capabilities only one override and only diff checked
|
||||
When I set the following fields to these values:
|
||||
| Capability: | enrol/category:config, enrol/cohort:config |
|
||||
| Roles: | Student, Teacher |
|
||||
And I set the field "Show differences only" to "1"
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "Permissions in System"
|
||||
And I should see "Permissions in Category: Miscellaneous"
|
||||
And I should see "There are no differences to show between selected roles in this context"
|
||||
And I should see "Permissions in Course: Course 1"
|
||||
And I should not see "Permissions in Course: Course 2"
|
||||
@@ -1,67 +0,0 @@
|
||||
@tool @tool_capability
|
||||
Feature: show only differences between roles for selected capabilities
|
||||
In order to check roles capabilities
|
||||
As an admin
|
||||
I need to be able to filter capabilities report viewing only role differences
|
||||
|
||||
Background:
|
||||
Given the following "roles" exist:
|
||||
| shortname | name | archetype |
|
||||
| studenteq | Studenteq | student |
|
||||
| studentdf | Studentdf | student |
|
||||
And the following "permission overrides" exist:
|
||||
| capability | permission | role | contextlevel | reference |
|
||||
| moodle/course:changefullname | Allow | studentdf | System | |
|
||||
| moodle/course:changeshortname | Prohibit | studentdf | System | |
|
||||
And I log in as "admin"
|
||||
And I navigate to "Users > Permissions > Capability overview" in site administration
|
||||
|
||||
Scenario: Compare identical roles
|
||||
When I set the following fields to these values:
|
||||
| Capability: | moodle/course:changefullname, moodle/course:changeshortname, moodle/course:changeidnumber, moodle/course:changesummary |
|
||||
| Roles: | Student, Studenteq |
|
||||
And I set the field "Show differences only" to "1"
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "There are no differences to show between selected roles in this context"
|
||||
|
||||
Scenario: Compare different roles
|
||||
When I set the following fields to these values:
|
||||
| Capability: | moodle/course:changefullname, moodle/course:changeshortname, moodle/course:changeidnumber, moodle/course:changesummary |
|
||||
| Roles: | Student, Studentdf |
|
||||
And I set the field "Show differences only" to "1"
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should not see "There are no differences to show between selected roles in this context"
|
||||
And I should see "moodle/course:changefullname" in the "comparisontable" "table"
|
||||
And I should see "moodle/course:changeshortname" in the "comparisontable" "table"
|
||||
And I should not see "moodle/course:changesummary" in the "comparisontable" "table"
|
||||
|
||||
Scenario: Compare different roles but comparing capabilities that are equals on both
|
||||
When I set the following fields to these values:
|
||||
| Capability: | moodle/course:changeidnumber, moodle/course:changesummary |
|
||||
| Roles: | Student, Studentdf |
|
||||
And I set the field "Show differences only" to "1"
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "There are no differences to show between selected roles in this context"
|
||||
|
||||
Scenario: Compare all roles without selecting specific role
|
||||
When I set the following fields to these values:
|
||||
| Capability: | moodle/course:changefullname, moodle/site:config |
|
||||
And I set the field "Show differences only" to "1"
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should not see "moodle/site:config" in the "comparisontable" "table"
|
||||
And I should see "moodle/course:changefullname" in the "comparisontable" "table"
|
||||
|
||||
Scenario: Compare all roles without selecting specific role on not defined capability
|
||||
When I set the following fields to these values:
|
||||
| Capability: | moodle/site:config |
|
||||
And I set the field "Show differences only" to "1"
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "There are no differences to show between selected roles in this context"
|
||||
|
||||
Scenario: Comparing only one role
|
||||
When I set the following fields to these values:
|
||||
| Capability: | moodle/course:changefullname, moodle/course:changeshortname, moodle/course:changeidnumber, moodle/course:changesummary |
|
||||
| Roles: | Student |
|
||||
And I set the field "Show differences only" to "1"
|
||||
And I click on "Get the overview" "button"
|
||||
Then I should see "There are no differences to show between selected roles in this context"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user