Compare commits
195 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3966291cd5 | |||
| 0c9f0c4bbf | |||
| 35edd02d74 | |||
| be2c290b2f | |||
| 9ec4f4b386 | |||
| 52d90156aa | |||
| 44757023a1 | |||
| 061049e5cf | |||
| 1ce514e02f | |||
| 5eb65b8a7c | |||
| 2b41fcb73d | |||
| 5f2880ea13 | |||
| edd9c78756 | |||
| 7c3b3af98c | |||
| 3d3f842be3 | |||
| 4fd6963185 | |||
| 4e7263a65a | |||
| 5cb86be37b | |||
| a9cf9eb991 | |||
| 9269de8830 | |||
| 4d2b0e8e17 | |||
| 71a794bec6 | |||
| ba9ed2e56e | |||
| ae15c3d214 | |||
| 80c8402050 | |||
| 53e2ba10f2 | |||
| ccf93c9b86 | |||
| dfa1545e4c | |||
| 206a64a376 | |||
| 1a2eab4adb | |||
| 3a68cb5ec1 | |||
| 7b79251c63 | |||
| 8adb42acb7 | |||
| 3491e73f43 | |||
| 16fe869164 | |||
| 6b56bfbb2f | |||
| 6e37aba2f1 | |||
| ad38a2d971 | |||
| 5f47dc23ff | |||
| 70fe9e2361 | |||
| 3dada91163 | |||
| 34309b79a3 | |||
| 4f5a6d3c5b | |||
| 2eb2524353 | |||
| f669d7619b | |||
| 93c7b15257 | |||
| 88d3c6e72b | |||
| 3342f23b29 | |||
| d450f05832 | |||
| c5900cbe2e | |||
| 220d1d7a23 | |||
| b56058f1d5 | |||
| 27396dc954 | |||
| f489998aec | |||
| 8b2c1e4297 | |||
| 44f0e44d8b | |||
| 7251cc06d3 | |||
| 4f61b2974b | |||
| 88d166ba77 | |||
| 13a23c43aa | |||
| 4e3a28c454 | |||
| a0a0458154 | |||
| 58d1571e08 | |||
| 75283557ad | |||
| 7d23d3ae3a | |||
| af2c368089 | |||
| 3b7f2aa473 | |||
| 00bef0f91d | |||
| 26e53e8cc2 | |||
| be0dea2892 | |||
| e522e7fc67 | |||
| 7e19a2a640 | |||
| 724275abbc | |||
| ea79441d28 | |||
| ca580b25b9 | |||
| 2f785afb00 | |||
| 7b6fddd811 | |||
| ac77c1c217 | |||
| 71bbfc2495 | |||
| c56c08e9ce | |||
| 4c3df551a4 | |||
| 516b81954a | |||
| 4caed80b37 | |||
| 7f6e49af41 | |||
| 69cca28118 | |||
| 3e30033749 | |||
| d61b9111fa | |||
| 07a30d6650 | |||
| 6f25549278 | |||
| 5ee4098ce5 | |||
| 44956b2463 | |||
| e65075c421 | |||
| 3d95f94ca6 | |||
| 1b51d716e2 | |||
| 7602fa7ad9 | |||
| f2ef4c6808 | |||
| 757f0a56c9 | |||
| e22f3d47c2 | |||
| 1ef498d989 | |||
| 747fff61c4 | |||
| 0f368a42cc | |||
| 186284ec1f | |||
| cdfdfc30d9 | |||
| 6c95086bc9 | |||
| 45ef55471b | |||
| ac270cb26f | |||
| b2ba6624ce | |||
| b57eb5dd88 | |||
| 9bf42e7aad | |||
| 4318e21563 | |||
| 2a900d6ed9 | |||
| 385721f105 | |||
| 83c5af5001 | |||
| 1b995b811d | |||
| 52ad957d74 | |||
| edb68975d1 | |||
| 9d84286479 | |||
| 7b8be76dd9 | |||
| c2bcdedbd6 | |||
| ca40241461 | |||
| 5e7ec29c65 | |||
| 193e6b0fad | |||
| b7a8375e65 | |||
| 10e93d074b | |||
| 0e6246db29 | |||
| 58efa0fa10 | |||
| afc3bfc296 | |||
| 9af8958b03 | |||
| 896da8f473 | |||
| 90fa1113f2 | |||
| aaf985001e | |||
| 9b81be597c | |||
| 998f6ce060 | |||
| 881ad82c44 | |||
| 5c163fff89 | |||
| 1ac64c87f9 | |||
| ce35013ebf | |||
| 8de6b2d6f4 | |||
| 81fc25e7fa | |||
| 5efe1cbf3c | |||
| 5deff67cea | |||
| 14cb950ff3 | |||
| 374028b418 | |||
| f0133eaae1 | |||
| 18998a6051 | |||
| 00b94dec34 | |||
| 71269d9c8f | |||
| 61c44c40d8 | |||
| b05bd11a84 | |||
| 57fc983d37 | |||
| eef27680b9 | |||
| c57def5dd1 | |||
| 67c6b85e1f | |||
| 57daa7a932 | |||
| 4629c45815 | |||
| 0fcd9f04cc | |||
| 2342c3f0c8 | |||
| 5bf1fb6564 | |||
| 4a719ac83a | |||
| df1e1b6fb2 | |||
| dc57f7a253 | |||
| 509b1110d3 | |||
| 45cc6fe44d | |||
| 593e08c20d | |||
| d6841046f1 | |||
| e768e90859 | |||
| 0ad8ac1c3b | |||
| 8bd8b19e00 | |||
| 023694ac28 | |||
| ed789da14a | |||
| 0d78d3dde0 | |||
| 648f9ab53e | |||
| 99445f3724 | |||
| abe5b83ef4 | |||
| 244db143eb | |||
| baa20b3778 | |||
| 0e45b4e1e1 | |||
| 70fc4013bd | |||
| 75f6669217 | |||
| b498552116 | |||
| 346e9a792b | |||
| 0fe4411848 | |||
| f74a599586 | |||
| cbc56fd8f3 | |||
| b3e26daa43 | |||
| 737a3ea643 | |||
| 5742a54a93 | |||
| 30c1019ab3 | |||
| d328504273 | |||
| c89cedc548 | |||
| 38657e7cab | |||
| 92cab9906d | |||
| 2b58d92bac | |||
| 16c162352d | |||
| affa5dbfb3 |
@@ -19,7 +19,7 @@ env:
|
||||
|
||||
jobs:
|
||||
Grunt:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- name: Checking out code
|
||||
@@ -60,11 +60,12 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
- os: ubuntu-24.04
|
||||
php: 7.4
|
||||
extensions:
|
||||
db: mysqli
|
||||
- os: ubuntu-22.04
|
||||
- os: ubuntu-24.04
|
||||
extensions: mongodb-1.19.4
|
||||
php: 8.1
|
||||
db: pgsql
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
define('CLI_SCRIPT', true);
|
||||
define('IGNORE_COMPONENT_CACHE', true);
|
||||
|
||||
require(__DIR__.'/../../config.php');
|
||||
require_once($CFG->libdir.'/clilib.php');
|
||||
|
||||
@@ -4714,6 +4714,7 @@
|
||||
<VENDOR name="mysql" version="8.4" />
|
||||
<VENDOR name="postgres" version="14" />
|
||||
<VENDOR name="mssql" version="14.0" />
|
||||
<VENDOR name="auroramysql" version="8.0" />
|
||||
</DATABASE>
|
||||
<PHP version="8.2.0" level="required">
|
||||
</PHP>
|
||||
@@ -4893,6 +4894,208 @@
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_async_backup" level="recommended">
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_aurora_version" level="optional">
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
<MOODLE version="5.1" requires="4.2.3">
|
||||
<UNICODE level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unicoderequired" />
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mariadb" version="10.11.0" />
|
||||
<VENDOR name="mysql" version="8.4" />
|
||||
<VENDOR name="postgres" version="15" />
|
||||
<VENDOR name="mssql" version="14.0" />
|
||||
<VENDOR name="auroramysql" version="8.0" />
|
||||
</DATABASE>
|
||||
<PHP version="8.2.0" level="required">
|
||||
</PHP>
|
||||
<PCREUNICODE level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="pcreunicodewarning" />
|
||||
</FEEDBACK>
|
||||
</PCREUNICODE>
|
||||
<PHP_EXTENSIONS>
|
||||
<PHP_EXTENSION name="iconv" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="iconvrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="mbstring" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="mbstringrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="curl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="curlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="openssl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="opensslrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="tokenizer" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="tokenizerrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="soap" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="soaprecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="ctype" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="ctyperequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="zip" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="ziprequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="zlib" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="gd" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="gdrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="simplexml" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="simplexmlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="spl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="splrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="pcre" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="dom" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xml" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xmlreader" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="intl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="intlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="json" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="hash" level="required"/>
|
||||
<PHP_EXTENSION name="fileinfo" level="required"/>
|
||||
<PHP_EXTENSION name="sodium" level="required"/>
|
||||
<PHP_EXTENSION name="exif" level="optional"/>
|
||||
</PHP_EXTENSIONS>
|
||||
<PHP_SETTINGS>
|
||||
<PHP_SETTING name="memory_limit" value="96M" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="settingmemorylimit" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="file_uploads" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingfileuploads" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="opcache.enable" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="opcacherecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="zend.exception_ignore_args" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingzendexceptionignoreargs" />
|
||||
</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="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="sixtyfourbitsrequired" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_max_input_vars" level="optional">
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_admin_dir_usage" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="iscustomadminwarnings" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_xmlrpc_usage" level="optional">
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mod_assignment" level="required">
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_db_prefix_length" level="required">
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_async_backup" level="recommended">
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_aurora_version" level="optional">
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
</COMPATIBILITY_MATRIX>
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define('IGNORE_COMPONENT_CACHE', true);
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
|
||||
@@ -82,6 +82,8 @@ class behat_admin extends behat_base {
|
||||
|
||||
$this->execute('behat_forms::i_set_the_field_with_xpath_to', [$fieldxpath, $value]);
|
||||
$this->execute("behat_general::i_click_on", [get_string('savechanges'), 'button']);
|
||||
// Wait for the page to be redirected.
|
||||
$this->execute("behat_general::i_wait_to_be_redirected");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ Feature: Verify the breadcrumbs in webservice tokens site administration pages
|
||||
And "Manage tokens" "link" should exist in the ".breadcrumb" "css_element"
|
||||
And "Web services" "link" should exist in the ".breadcrumb" "css_element"
|
||||
And I set the field "User" to "John Doe"
|
||||
And I set the field "Service" to "Moodle mobile web service"
|
||||
And I press "Save changes"
|
||||
When I click on "Delete" "link"
|
||||
Then "Delete token" "text" should exist in the ".breadcrumb" "css_element"
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
@tool @tool_analytics
|
||||
Feature: Manager can obtain prediction models insights
|
||||
In order to view prediction models insights
|
||||
As a manager
|
||||
I should be able to obtain the prediction models insights
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| s1 | Student | One | s1@example.com |
|
||||
| m1 | Manager | One | m1@example.com |
|
||||
| m2 | Manager | Two | m2@example.com |
|
||||
| t1 | Teacher | One | t1@example.com |
|
||||
And the following "role assigns" exist:
|
||||
| user | role | contextlevel | reference |
|
||||
| m1 | manager | System | |
|
||||
| m2 | manager | System | |
|
||||
# To ensure that course start date is in the future, set course start date to "tomorrow".
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | startdate |
|
||||
| Course 1 | C1 | ##tomorrow## |
|
||||
| Course 2 | C2 | ##tomorrow## |
|
||||
| Course 3 | C3 | ##tomorrow## |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| s1 | C1 | student |
|
||||
| s1 | C2 | student |
|
||||
| s1 | C3 | student |
|
||||
| t1 | C3 | editingteacher |
|
||||
# Disable "Analytics processes execution via command line only".
|
||||
And the following config values are set as admin:
|
||||
| onlycli | 0 | analytics |
|
||||
|
||||
@javascript
|
||||
Scenario: Manager can obtain prediction models insights
|
||||
Given I log in as "m1"
|
||||
And I navigate to "Analytics > Analytics models" in site administration
|
||||
And I click on "Actions" "link" in the "Courses at risk of not starting" "table_row"
|
||||
And I click on "Execute scheduled analysis" "link" in the "Courses at risk of not starting" "table_row"
|
||||
And I press "Continue"
|
||||
When I select "All predictions" from the "contextid" singleselect
|
||||
# Confirm that only courses without teachers, Course 1 and Course 2, are listed.
|
||||
Then "Course 1" "text" should exist
|
||||
And "Course 2" "text" should exist
|
||||
And "Course 3" "text" should not exist
|
||||
And I click on "Select Course 1 for bulk action" "checkbox"
|
||||
And I press "Not applicable"
|
||||
And I press "Confirm"
|
||||
# After m1 marks Course 1 as Not applicable, only Course 2 should be listed in the predictions for manager 1.
|
||||
And "Course 1" "text" should not exist
|
||||
And "Course 2" "text" should exist
|
||||
And I log in as "m2"
|
||||
And I click on ".popover-region-notifications" "css_element"
|
||||
# Notification of new insight exists.
|
||||
And "Upcoming courses have no teachers or students" "text" should exist
|
||||
And I click on "View full notification" "link" in the ".popover-region-notifications" "css_element"
|
||||
And I click on "View insight" "link"
|
||||
# Course 1, previously marked as Not applicable by manager 1, is still listed for manager 2.
|
||||
And "Course 1" "text" should exist
|
||||
And I click on "View details" "link" in the "Course 1" "table_row"
|
||||
# Prediction details and indicators are displayed for the selected course.
|
||||
And the following should exist in the "insights-list" table:
|
||||
| Description |
|
||||
| Course 1 |
|
||||
And the following should exist in the "prediction-calculations" table:
|
||||
| -1- | -2- |
|
||||
| Teacher availability | No |
|
||||
| Student enrolments | Yes |
|
||||
# Date of prediction analysis execution.
|
||||
And "##today##%A, %d %B %Y##" "text" should exist in the "Time predicted" "table_row"
|
||||
And I click on "Select Course 1 for bulk action" "checkbox"
|
||||
And I press "Accept"
|
||||
And I press "Confirm"
|
||||
# Verify that you end up on the page listing predictions for 'No teaching'.
|
||||
And "Courses at risk of not starting" "text" should exist
|
||||
And "The following courses due to start in the upcoming days are at risk of not starting because they don't have teachers or students enrolled." "text" should exist
|
||||
And the following should not exist in the "insights-list" table:
|
||||
| Description |
|
||||
| Course 1 |
|
||||
@@ -36,6 +36,10 @@ if (function_exists('opcache_reset')) {
|
||||
define('CLI_SCRIPT', true);
|
||||
define('CACHE_DISABLE_ALL', true);
|
||||
|
||||
// It makes no sense to use BEHAT_CLI for this script (the Behat launch scripts expect to start
|
||||
// from the normal environment), so in case user has set tne environment variable, disable it.
|
||||
putenv('BEHAT_CLI=0');
|
||||
|
||||
// Basic functions.
|
||||
require_once(__DIR__ . '/../../../../lib/clilib.php');
|
||||
require_once(__DIR__ . '/../../../../lib/behat/lib.php');
|
||||
|
||||
@@ -31,6 +31,10 @@ define('ABORT_AFTER_CONFIG', true);
|
||||
define('CACHE_DISABLE_ALL', true);
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
|
||||
// It makes no sense to use BEHAT_CLI for this script (the Behat launch scripts expect to start
|
||||
// from the normal environment), so in case user has set tne environment variable, disable it.
|
||||
putenv('BEHAT_CLI=0');
|
||||
|
||||
require_once(__DIR__ .'/../../../../config.php');
|
||||
require_once(__DIR__.'/../../../../lib/clilib.php');
|
||||
require_once(__DIR__.'/../../../../lib/behat/lib.php');
|
||||
|
||||
@@ -39,6 +39,10 @@ define('NO_OUTPUT_BUFFERING', true);
|
||||
define('IGNORE_COMPONENT_CACHE', true);
|
||||
define('ABORT_AFTER_CONFIG', true);
|
||||
|
||||
// It makes no sense to use BEHAT_CLI for this script (the Behat launch scripts expect to start
|
||||
// from the normal environment), so in case user has set tne environment variable, disable it.
|
||||
putenv('BEHAT_CLI=0');
|
||||
|
||||
require_once(__DIR__ . '/../../../../lib/clilib.php');
|
||||
|
||||
// CLI options.
|
||||
|
||||
@@ -33,6 +33,10 @@ if (isset($_SERVER['REMOTE_ADDR'])) {
|
||||
die(); // No access from web!.
|
||||
}
|
||||
|
||||
// It makes no sense to use BEHAT_CLI for this script (the Behat launch scripts expect to start
|
||||
// from the normal environment), so in case user has set tne environment variable, disable it.
|
||||
putenv('BEHAT_CLI=0');
|
||||
|
||||
// Basic functions.
|
||||
require_once(__DIR__ . '/../../../../lib/clilib.php');
|
||||
require_once(__DIR__ . '/../../../../lib/behat/lib.php');
|
||||
|
||||
@@ -87,6 +87,7 @@ $action = optional_param('action', '', PARAM_ALPHA);
|
||||
// Handle any single operation actions.
|
||||
if ($action == 'requestanalysis') {
|
||||
if ($courseid != 0) {
|
||||
require_sesskey();
|
||||
scheduler::request_course_analysis($courseid);
|
||||
if ($courseid == SITEID) {
|
||||
redirect(accessibility::get_plugin_url());
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<?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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
namespace tool_capability;
|
||||
|
||||
// phpcs:disable moodle.PHPUnit.TestCaseProvider.dataProviderSyntaxMethodNotFound
|
||||
|
||||
/**
|
||||
* Detect common problems in capability definitions of plugins.
|
||||
*
|
||||
* @group plugin_checks
|
||||
* @package tool_capability
|
||||
* @copyright 2025 Petr Skoda
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
final class plugin_checks_test extends \core\tests\plugin_checks_testcase {
|
||||
/**
|
||||
* Verify contents of plugin db/access.php file.
|
||||
*
|
||||
* @dataProvider all_plugins_provider
|
||||
* @coversNothing
|
||||
*
|
||||
* @param string $component
|
||||
* @param string $plugintype
|
||||
* @param string $pluginname
|
||||
* @param string $dir
|
||||
*/
|
||||
public function test_db_access_file(string $component, string $plugintype, string $pluginname, string $dir): void {
|
||||
global $CFG;
|
||||
|
||||
$stringmanager = get_string_manager();
|
||||
$corerolefile = "$CFG->dirroot/lang/en/role.php";
|
||||
$langfile = "$dir/lang/en/$component.php";
|
||||
|
||||
$file = "$dir/db/access.php";
|
||||
$capabilities = $this->fetch_array_from_file($file, 'capabilities');
|
||||
if (!$capabilities) {
|
||||
$this->expectNotToPerformAssertions();
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($capabilities as $capname => $capability) {
|
||||
if ($plugintype === 'qbank' && str_starts_with($capname, 'moodle/question:')) {
|
||||
// Question bank capabilities are irregular.
|
||||
$strname = explode('/', $capname, 2)[1];
|
||||
$this->assertTrue($stringmanager->string_exists($strname, 'core_role'),
|
||||
"Missing capability name string '$strname' in $corerolefile");
|
||||
continue;
|
||||
}
|
||||
$this->assertMatchesRegularExpression("|^$plugintype/$pluginname:[a-z0-9_]+$|", $capname);
|
||||
$strname = substr($capname, strlen($plugintype) + 1);
|
||||
$this->assertTrue($stringmanager->string_exists($strname, $component),
|
||||
"Missing capability name string '$strname' in $langfile");
|
||||
$this->assertSame($capname, clean_param($capname, PARAM_CAPABILITY));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,13 +4,13 @@ Feature: See the competencies for an activity on the course competencies page.
|
||||
In order to see only the competencies for an activity in the course competencies page.
|
||||
|
||||
Background:
|
||||
Given the following lp "frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Test-Framework | ID-FW1 |
|
||||
And the following lp "competencies" exist:
|
||||
| shortname | framework |
|
||||
| Test-Comp1 | ID-FW1 |
|
||||
| Test-Comp2 | ID-FW1 |
|
||||
Given the following "core_competency > frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Test-Framework | ID-FW1 |
|
||||
And the following "core_competency > competencies" exist:
|
||||
| shortname | competencyframework |
|
||||
| Test-Comp1 | ID-FW1 |
|
||||
| Test-Comp2 | ID-FW1 |
|
||||
Given the following "courses" exist:
|
||||
| shortname | fullname | enablecompletion |
|
||||
| C1 | Course 1 | 1 |
|
||||
@@ -46,11 +46,11 @@ Feature: See the competencies for an activity on the course competencies page.
|
||||
When I follow "Competencies"
|
||||
Then I should see "Test-Comp1"
|
||||
And I should see "Test-Comp2"
|
||||
And I set the field "Filter competencies by resource or activity" to "PageName1"
|
||||
And I set the competency filter "Filter competencies by resource or activity" to "PageName1"
|
||||
And I press the enter key
|
||||
And I should see "Test-Comp1"
|
||||
And I should not see "Test-Comp2"
|
||||
And I set the field "Filter competencies by resource or activity" to "PageName2"
|
||||
And I set the competency filter "Filter competencies by resource or activity" to "PageName2"
|
||||
And I press the enter key
|
||||
And I should not see "Test-Comp1"
|
||||
And I should not see "Test-Comp2"
|
||||
|
||||
@@ -29,18 +29,18 @@ Feature: Manage competency frameworks
|
||||
And I should see "Science Year-1"
|
||||
|
||||
Scenario: Read a framework
|
||||
Given the following lp "frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Science Year-2 | sc-y-2 |
|
||||
Given the following "core_competency > frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Science Year-2 | sc-y-2 |
|
||||
And I navigate to "Competencies > Competency frameworks" in site administration
|
||||
And I should see "Science Year-2"
|
||||
When I click on "Science Year-2" "link"
|
||||
Then I should see "Science Year-2"
|
||||
|
||||
Scenario: Edit a framework
|
||||
Given the following lp "frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Science Year-3 | sc-y-3 |
|
||||
Given the following "core_competency > frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Science Year-3 | sc-y-3 |
|
||||
And I navigate to "Competencies > Competency frameworks" in site administration
|
||||
And I should see "Science Year-3"
|
||||
And I click on "Edit" of edit menu in the "Science Year-3" row
|
||||
@@ -52,9 +52,9 @@ Feature: Manage competency frameworks
|
||||
And I should see "sc-y-3"
|
||||
|
||||
Scenario: Delete a framework
|
||||
Given the following lp "frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Science Year-4 | sc-y-4 |
|
||||
Given the following "core_competency > frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Science Year-4 | sc-y-4 |
|
||||
And I navigate to "Competencies > Competency frameworks" in site administration
|
||||
And I should see "Science Year-4"
|
||||
And I should see "sc-y-4"
|
||||
@@ -70,24 +70,24 @@ Feature: Manage competency frameworks
|
||||
And I should not see "sc-y-4"
|
||||
|
||||
Scenario: Edit a framework with competencies in user competency
|
||||
Given the following lp "frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Science Year-5 | sc-y-5 |
|
||||
And the following lp "competencies" exist:
|
||||
| shortname | framework |
|
||||
| Comp1 | sc-y-5 |
|
||||
| Comp2 | sc-y-5 |
|
||||
And the following lp "plans" exist:
|
||||
| name | user | description |
|
||||
Given the following "core_competency > frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Science Year-5 | sc-y-5 |
|
||||
And the following "core_competency > competencies" exist:
|
||||
| shortname | competencyframework | idnumber |
|
||||
| Comp1 | sc-y-5 | Comp1 |
|
||||
| Comp2 | sc-y-5 | Comp2 |
|
||||
And the following "core_competency > plans" exist:
|
||||
| name | user | description |
|
||||
| Plan Science-5 | admin | Plan description |
|
||||
And the following lp "plancompetencies" exist:
|
||||
| plan | competency |
|
||||
| Plan Science-5 | Comp1 |
|
||||
| Plan Science-5 | Comp2 |
|
||||
And the following lp "usercompetencies" exist:
|
||||
| user | competency |
|
||||
| admin | Comp1 |
|
||||
| admin | Comp2 |
|
||||
And the following "core_competency > plan_competency" exist:
|
||||
| plan | competency |
|
||||
| Plan Science-5 | Comp1 |
|
||||
| Plan Science-5 | Comp2 |
|
||||
And the following "core_competency > user_competency" exist:
|
||||
| user | competency |
|
||||
| admin | Comp1 |
|
||||
| admin | Comp2 |
|
||||
And I navigate to "Competencies > Competency frameworks" in site administration
|
||||
And I should see "Science Year-5"
|
||||
And I click on "Edit" of edit menu in the "Science Year-5" row
|
||||
@@ -100,24 +100,24 @@ Feature: Manage competency frameworks
|
||||
And I should see "sc-y-5"
|
||||
|
||||
Scenario: Edit a framework with competencies in user competency plan
|
||||
Given the following lp "frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Science Year-6 | sc-y-6 |
|
||||
And the following lp "competencies" exist:
|
||||
| shortname | framework |
|
||||
| Comp1 | sc-y-6 |
|
||||
| Comp2 | sc-y-6 |
|
||||
And the following lp "plans" exist:
|
||||
| name | user | description |
|
||||
Given the following "core_competency > frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Science Year-6 | sc-y-6 |
|
||||
And the following "core_competency > competencies" exist:
|
||||
| shortname | competencyframework | idnumber |
|
||||
| Comp1 | sc-y-6 | Comp1 |
|
||||
| Comp2 | sc-y-6 | Comp2 |
|
||||
And the following "core_competency > plans" exist:
|
||||
| name | user | description |
|
||||
| Plan Science-6 | admin | Plan description |
|
||||
And the following lp "plancompetencies" exist:
|
||||
| plan | competency |
|
||||
| Plan Science-6 | Comp1 |
|
||||
| Plan Science-6 | Comp2 |
|
||||
And the following lp "usercompetencyplans" exist:
|
||||
| user | competency | plan |
|
||||
| admin | Comp1 | Plan Science-6 |
|
||||
| admin | Comp2 | Plan Science-6 |
|
||||
And the following "core_competency > plan_competency" exist:
|
||||
| plan | competency |
|
||||
| Plan Science-6 | Comp1 |
|
||||
| Plan Science-6 | Comp2 |
|
||||
And the following "core_competency > user_competency_plans" exist:
|
||||
| user | competency | plan |
|
||||
| admin | Comp1 | Plan Science-6 |
|
||||
| admin | Comp2 | Plan Science-6 |
|
||||
And I navigate to "Competencies > Competency frameworks" in site administration
|
||||
And I should see "Science Year-6"
|
||||
And I click on "Edit" of edit menu in the "Science Year-6" row
|
||||
@@ -130,12 +130,12 @@ Feature: Manage competency frameworks
|
||||
And I should see "sc-y-6"
|
||||
|
||||
Scenario: Duplicate a competency framework
|
||||
Given the following lp "frameworks" exist:
|
||||
Given the following "core_competency > frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| CF1 | CF1 |
|
||||
And the following lp "competencies" exist:
|
||||
| shortname | framework |
|
||||
| C1 | CF1 |
|
||||
And the following "core_competency > competencies" exist:
|
||||
| shortname | competencyframework |
|
||||
| C1 | CF1 |
|
||||
And I navigate to "Competencies > Competency frameworks" in site administration
|
||||
# Duplicate the selected competency framework
|
||||
When I click on "Duplicate" of edit menu in the "CF1" row
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
@tool @tool_lp @tool_lp_plan
|
||||
Feature: Admin can create learning plans from template
|
||||
In order to link and unlink a learning plan from a student
|
||||
As an admin
|
||||
I need to be able to create a learning plan from template
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| student1 | Student | One | student1@email.com |
|
||||
And the following "core_competency > frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| CF1 | CF1 |
|
||||
| CF2 | CF2 |
|
||||
And the following "core_competency > competencies" exist:
|
||||
| shortname | competencyframework | idnumber |
|
||||
| CF1 Competency 1 | CF1 | CF1C1 |
|
||||
| CF2 Competency 1 | CF2 | CF2C1 |
|
||||
And the following "core_competency > templates" exist:
|
||||
| shortname | description |
|
||||
| LPT1 | LPT 1 description |
|
||||
And the following "core_competency > template_competencies" exist:
|
||||
| template | competency |
|
||||
| LPT1 | CF1C1 |
|
||||
|
||||
@javascript
|
||||
Scenario: Admin can assign competencies from different frameworks to a learning plan
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Competencies > Learning plan templates" in site administration
|
||||
And I follow "LPT1"
|
||||
When I press "Add competencies to learning plan template"
|
||||
# Add another competency from a different framework in the learning plan template.
|
||||
And I set the field with xpath "//select[@data-action='chooseframework']" to "CF2 CF2"
|
||||
And I select "CF2 Competency 1" of the competency tree
|
||||
And I click on "Add" "button" in the "Competency picker" "dialogue"
|
||||
# Confirm that both competencies from different frameworks are successfully added to learning plan template.
|
||||
Then "LPT1" "text" should exist
|
||||
And "Learning plan template competencies" "text" should exist
|
||||
And "CF1 Competency 1" "text" should exist
|
||||
And "CF2 Competency 1" "text" should exist
|
||||
|
||||
@javascript
|
||||
Scenario: Admin can link and unlink learning plans created from template
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Competencies > Learning plan templates" in site administration
|
||||
# Initially, the number of learning plans is 0.
|
||||
And the following should exist in the "generaltable" table:
|
||||
| Name | Learning plans |
|
||||
| LPT1 | 0 |
|
||||
And I click on ".template-userplans" "css_element" in the "LPT1" "table_row"
|
||||
# Create a learning plan for selected student using template.
|
||||
When I set the field "Select users" to "student1"
|
||||
And I press "Create learning plans"
|
||||
# Confirm that selected student is now in the list of learning plans.
|
||||
Then "A learning plan was created" "text" should exist
|
||||
And the following should exist in the "generaltable" table:
|
||||
| Name | Email address |
|
||||
| LPT1 | student1@email.com |
|
||||
And I click on "LPT1" "link" in the "LPT1" "table_row"
|
||||
# Template title and Unlink from learning plan template link exists.
|
||||
And "Learning plan template" "text" should exist
|
||||
And "Unlink from learning plan template" "link" should exist
|
||||
# Unlink the template.
|
||||
And I click on "Unlink from learning plan template" "link"
|
||||
And I press "Unlink from learning plan template"
|
||||
# Learning plan still exists but Template name and Unlink from learning plan template link no longer exist.
|
||||
And "LPT1" "text" should exist
|
||||
And "Learning plan template" "text" should not exist
|
||||
And "Unlink from learning plan template" "link" should not exist
|
||||
@@ -22,8 +22,8 @@ Feature: Manage plearning plan
|
||||
And I should see "Science plan"
|
||||
|
||||
Scenario: Create a learning plan based on template
|
||||
Given the following lp "templates" exist:
|
||||
| shortname | description |
|
||||
Given the following "core_competency > templates" exist:
|
||||
| shortname | description |
|
||||
| Science template | science template description |
|
||||
And I am on homepage
|
||||
And I navigate to "Competencies > Learning plan templates" in site administration
|
||||
@@ -36,8 +36,8 @@ Feature: Manage plearning plan
|
||||
And I should see "Admin User" in the "Science template" "table_row"
|
||||
|
||||
Scenario: Create a learning plan from template cohort
|
||||
Given the following lp "templates" exist:
|
||||
| shortname | description |
|
||||
Given the following "core_competency > templates" exist:
|
||||
| shortname | description |
|
||||
| Science template cohort | science template description |
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
@@ -62,8 +62,8 @@ Feature: Manage plearning plan
|
||||
And I should see "Student 2"
|
||||
|
||||
Scenario: Read a learning plan
|
||||
Given the following lp "plans" exist:
|
||||
| name | user | description |
|
||||
Given the following "core_competency > plans" exist:
|
||||
| name | user | description |
|
||||
| Science plan Year-1 | admin | science plan description |
|
||||
And I follow "Learning plans"
|
||||
And I should see "Science plan Year-1"
|
||||
@@ -72,16 +72,16 @@ Feature: Manage plearning plan
|
||||
And I should see "Learning plan competencies"
|
||||
|
||||
Scenario: Manage a learning plan competencies
|
||||
Given the following lp "plans" exist:
|
||||
| name | user | description |
|
||||
Given the following "core_competency > plans" exist:
|
||||
| name | user | description |
|
||||
| Science plan Year-manage | admin | science plan description |
|
||||
And the following lp "frameworks" exist:
|
||||
And the following "core_competency > frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Framework 1 | sc-y-2 |
|
||||
And the following lp "competencies" exist:
|
||||
| shortname | framework |
|
||||
| comp1 | sc-y-2 |
|
||||
| comp2 | sc-y-2 |
|
||||
And the following "core_competency > competencies" exist:
|
||||
| shortname | competencyframework |
|
||||
| comp1 | sc-y-2 |
|
||||
| comp2 | sc-y-2 |
|
||||
And I follow "Learning plans"
|
||||
And I should see "Science plan Year-manage"
|
||||
And I follow "Science plan Year-manage"
|
||||
@@ -98,8 +98,8 @@ Feature: Manage plearning plan
|
||||
And "comp1" "table_row" should not exist
|
||||
|
||||
Scenario: Edit a learning plan
|
||||
Given the following lp "plans" exist:
|
||||
| name | user | description |
|
||||
Given the following "core_competency > plans" exist:
|
||||
| name | user | description |
|
||||
| Science plan Year-2 | admin | science plan description |
|
||||
| Science plan Year-3 | admin | science plan description |
|
||||
And I follow "Learning plans"
|
||||
@@ -113,8 +113,8 @@ Feature: Manage plearning plan
|
||||
And I should see "Science plan Year-3 Edited"
|
||||
|
||||
Scenario: Delete a learning plan
|
||||
Given the following lp "plans" exist:
|
||||
| name | user | description |
|
||||
Given the following "core_competency > plans" exist:
|
||||
| name | user | description |
|
||||
| Science plan Year-4 | admin | science plan description |
|
||||
And I follow "Learning plans"
|
||||
And I should see "Science plan Year-4"
|
||||
@@ -130,16 +130,16 @@ Feature: Manage plearning plan
|
||||
Then I should not see "Science plan Year-4"
|
||||
|
||||
Scenario: See a learning plan from a course
|
||||
Given the following lp "plans" exist:
|
||||
| name | user | description |
|
||||
Given the following "core_competency > plans" exist:
|
||||
| name | user | description |
|
||||
| Science plan Year-manage | admin | science plan description |
|
||||
And the following lp "frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Framework 1 | sc-y-2 |
|
||||
And the following lp "competencies" exist:
|
||||
| shortname | framework |
|
||||
| comp1 | sc-y-2 |
|
||||
| comp2 | sc-y-2 |
|
||||
And the following "core_competency > frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Framework 1 | sc-y-2 |
|
||||
And the following "core_competency > competencies" exist:
|
||||
| shortname | competencyframework |
|
||||
| comp1 | sc-y-2 |
|
||||
| comp2 | sc-y-2 |
|
||||
And I follow "Learning plans"
|
||||
And I should see "Science plan Year-manage"
|
||||
And I follow "Science plan Year-manage"
|
||||
|
||||
@@ -31,19 +31,19 @@ Feature: Manage plan workflow
|
||||
| user1 | usermanageowndraftplan | System | |
|
||||
| user2 | usermanageownplan | System | |
|
||||
| manager1 | manageplan | System | |
|
||||
And the following lp "frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Test-Framework | ID-FW1 |
|
||||
And the following lp "competencies" exist:
|
||||
| shortname | framework |
|
||||
| Test-Comp1 | ID-FW1 |
|
||||
| Test-Comp2 | ID-FW1 |
|
||||
And the following lp "plans" exist:
|
||||
| name | user | description |
|
||||
| Test-Plan1 | user1 | Description of plan for user 1 |
|
||||
| Test-Plan2 | user2 | Description of plan for user 2 |
|
||||
And the following lp "plancompetencies" exist:
|
||||
| plan | competency |
|
||||
And the following "core_competency > frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Test-Framework | ID-FW1 |
|
||||
And the following "core_competency > competencies" exist:
|
||||
| shortname | competencyframework | idnumber |
|
||||
| Test-Comp1 | ID-FW1 | Test-Comp1 |
|
||||
| Test-Comp2 | ID-FW1 | Test-Comp2 |
|
||||
And the following "core_competency > plans" exist:
|
||||
| name | user | description | reviewer | status |
|
||||
| Test-Plan1 | user1 | Description of plan for user 1 | user1 | draft |
|
||||
| Test-Plan2 | user2 | Description of plan for user 2 | user2 | draft |
|
||||
And the following "core_competency > plan_competency" exist:
|
||||
| plan | competency |
|
||||
| Test-Plan1 | Test-Comp1 |
|
||||
| Test-Plan1 | Test-Comp2 |
|
||||
| Test-Plan2 | Test-Comp1 |
|
||||
@@ -89,18 +89,18 @@ Feature: Manage plan workflow
|
||||
And I log out
|
||||
|
||||
Scenario: Manager can see learning plan with status waiting for review
|
||||
Given the following lp "plans" exist:
|
||||
| name | user | description | status |
|
||||
Given the following "core_competency > plans" exist:
|
||||
| name | user | description | status |
|
||||
| Test-Plan3 | user2 | Description of plan 3 for user 1 | waiting for review |
|
||||
| Test-Plan4 | user1 | Description of plan 3 for user 1 | draft |
|
||||
| Test-Plan4 | user1 | Description of plan 3 for user 1 | draft |
|
||||
When I log in as "manager1"
|
||||
Then I should see "Test-Plan3"
|
||||
And I should not see "Test-Plan4"
|
||||
And I log out
|
||||
|
||||
Scenario: Manager can start review of learning plan with status waiting for review
|
||||
Given the following lp "plans" exist:
|
||||
| name | user | description | status |
|
||||
Given the following "core_competency > plans" exist:
|
||||
| name | user | description | status |
|
||||
| Test-Plan3 | user1 | Description of plan 3 for user 1 | waiting for review |
|
||||
And I log in as "manager1"
|
||||
And I follow "Test-Plan3"
|
||||
@@ -111,8 +111,8 @@ Feature: Manage plan workflow
|
||||
And I log out
|
||||
|
||||
Scenario: Manager can reject a learning plan with status in review
|
||||
Given the following lp "plans" exist:
|
||||
| name | user | description | status | reviewer |
|
||||
Given the following "core_competency > plans" exist:
|
||||
| name | user | description | status | reviewer |
|
||||
| Test-Plan3 | user1 | Description of plan 3 for user 1 | in review | manager1 |
|
||||
And I log in as "manager1"
|
||||
And I follow "Test-Plan3"
|
||||
@@ -124,8 +124,8 @@ Feature: Manage plan workflow
|
||||
And I log out
|
||||
|
||||
Scenario: Manager can accept a learning plan with status in review
|
||||
Given the following lp "plans" exist:
|
||||
| name | user | description | status | reviewer |
|
||||
Given the following "core_competency > plans" exist:
|
||||
| name | user | description | status | reviewer |
|
||||
| Test-Plan3 | user1 | Description of plan 3 for user 1 | in review | manager1 |
|
||||
And I log in as "manager1"
|
||||
And I follow "Test-Plan3"
|
||||
@@ -137,8 +137,8 @@ Feature: Manage plan workflow
|
||||
And I log out
|
||||
|
||||
Scenario: Manager send back to draft an active learning plan
|
||||
Given the following lp "plans" exist:
|
||||
| name | user | description | status | reviewer |
|
||||
Given the following "core_competency > plans" exist:
|
||||
| name | user | description | status | reviewer |
|
||||
| Test-Plan3 | user1 | Description of plan 3 for user 1 | active | manager1 |
|
||||
| Test-Plan4 | user1 | Description of plan 4 for user 1 | active | manager1 |
|
||||
And I am on the "user1" "user > profile" page logged in as "manager1"
|
||||
@@ -153,8 +153,8 @@ Feature: Manage plan workflow
|
||||
And I log out
|
||||
|
||||
Scenario: Manager change an active learning plan to completed
|
||||
Given the following lp "plans" exist:
|
||||
| name | user | description | status | reviewer |
|
||||
Given the following "core_competency > plans" exist:
|
||||
| name | user | description | status | reviewer |
|
||||
| Test-Plan3 | user1 | Description of plan 3 for user 1 | active | manager1 |
|
||||
| Test-Plan4 | user1 | Description of plan 4 for user 1 | active | manager1 |
|
||||
And I am on the "user1" "user > profile" page logged in as "manager1"
|
||||
@@ -172,8 +172,8 @@ Feature: Manage plan workflow
|
||||
And I log out
|
||||
|
||||
Scenario: Manager reopen a complete learning plan
|
||||
Given the following lp "plans" exist:
|
||||
| name | user | description | status | reviewer |
|
||||
Given the following "core_competency > plans" exist:
|
||||
| name | user | description | status | reviewer |
|
||||
| Test-Plan3 | user1 | Description of plan 3 for user 1 | complete | manager1 |
|
||||
| Test-Plan4 | user1 | Description of plan 4 for user 1 | complete | manager1 |
|
||||
And I am on the "user1" "user > profile" page logged in as "manager1"
|
||||
|
||||
@@ -21,8 +21,8 @@ Feature: Manage plearning plan templates
|
||||
And I should see "Science template"
|
||||
|
||||
Scenario: Read a learning plan template
|
||||
Given the following lp "templates" exist:
|
||||
| shortname | description |
|
||||
Given the following "core_competency > templates" exist:
|
||||
| shortname | description |
|
||||
| Science template Year-2 | science template description |
|
||||
And I navigate to "Competencies > Learning plan templates" in site administration
|
||||
And I should see "Science template Year-2"
|
||||
@@ -31,8 +31,8 @@ Feature: Manage plearning plan templates
|
||||
And I should see "Learning plan template competencies"
|
||||
|
||||
Scenario: Edit a learning plan template
|
||||
Given the following lp "templates" exist:
|
||||
| shortname | description |
|
||||
Given the following "core_competency > templates" exist:
|
||||
| shortname | description |
|
||||
| Science template Year-3 | science template description |
|
||||
And I navigate to "Competencies > Learning plan templates" in site administration
|
||||
And I should see "Science template Year-3"
|
||||
@@ -44,8 +44,8 @@ Feature: Manage plearning plan templates
|
||||
And I should see "Science template Year-3 Edited"
|
||||
|
||||
Scenario: Delete a learning plan template
|
||||
Given the following lp "templates" exist:
|
||||
| shortname | description |
|
||||
Given the following "core_competency > templates" exist:
|
||||
| shortname | description |
|
||||
| Science template Year-4 | science template description |
|
||||
And I navigate to "Competencies > Learning plan templates" in site administration
|
||||
And I should see "Science template Year-4"
|
||||
|
||||
@@ -5,22 +5,22 @@ Feature: Manage competencies linked to evidence of prior learning
|
||||
I need to link and unlink competencies from evidence of prior learning
|
||||
|
||||
Background:
|
||||
Given the following lp "frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Test-Framework | ID-FW1 |
|
||||
And the following lp "competencies" exist:
|
||||
| shortname | framework |
|
||||
| Test-Comp1 | ID-FW1 |
|
||||
| Test-Comp2 | ID-FW1 |
|
||||
And the following lp "plans" exist:
|
||||
| name | user | description |
|
||||
Given the following "core_competency > frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Test-Framework | ID-FW1 |
|
||||
And the following "core_competency > competencies" exist:
|
||||
| shortname | competencyframework | idnumber |
|
||||
| Test-Comp1 | ID-FW1 | Test-Comp1 |
|
||||
| Test-Comp2 | ID-FW1 | Test-Comp2 |
|
||||
And the following "core_competency > plans" exist:
|
||||
| name | user | description |
|
||||
| Test-Plan | admin | Plan description |
|
||||
And the following lp "plancompetencies" exist:
|
||||
| plan | competency |
|
||||
And the following "core_competency > plan_competency" exist:
|
||||
| plan | competency |
|
||||
| Test-Plan | Test-Comp1 |
|
||||
| Test-Plan | Test-Comp2 |
|
||||
And the following lp "userevidence" exist:
|
||||
| name | description | user |
|
||||
And the following "core_competency > user_evidence" exist:
|
||||
| name | description | user |
|
||||
| Test-Evidence | Description evidence | admin |
|
||||
When I log in as "admin"
|
||||
And I follow "Profile" in the user menu
|
||||
@@ -51,12 +51,12 @@ Feature: Manage competencies linked to evidence of prior learning
|
||||
Then "Test-Comp2" "table_row" should exist
|
||||
|
||||
Scenario: Unlink competency from evidence of prior learning
|
||||
Given the following lp "userevidencecompetencies" exist:
|
||||
| userevidence | competency |
|
||||
Given the following "core_competency > user_evidence_competency" exist:
|
||||
| userevidence | competency |
|
||||
| Test-Evidence | Test-Comp1 |
|
||||
| Test-Evidence | Test-Comp2 |
|
||||
Given the following lp "usercompetencies" exist:
|
||||
| user | competency |
|
||||
And the following "core_competency > user_competency" exist:
|
||||
| user | competency |
|
||||
| admin | Test-Comp1 |
|
||||
| admin | Test-Comp2 |
|
||||
And I follow "Evidence of prior learning"
|
||||
|
||||
@@ -24,8 +24,8 @@ Feature: Manage evidence of prior learning
|
||||
And I should see "Evidence-1"
|
||||
|
||||
Scenario: Read an evidence of prior learning
|
||||
Given the following lp "userevidence" exist:
|
||||
| name | description | user |
|
||||
Given the following "core_competency > user_evidence" exist:
|
||||
| name | description | user |
|
||||
| Evidence-2 | Evidence-2 description | user1 |
|
||||
And I follow "Evidence of prior learning"
|
||||
And I should see "List of evidence"
|
||||
@@ -34,8 +34,8 @@ Feature: Manage evidence of prior learning
|
||||
Then I should see "Evidence-2"
|
||||
|
||||
Scenario: Edit an evidence of prior learning
|
||||
Given the following lp "userevidence" exist:
|
||||
| name | description | user |
|
||||
Given the following "core_competency > user_evidence" exist:
|
||||
| name | description | user |
|
||||
| Evidence-3 | Evidence-3 description | user1 |
|
||||
And I follow "Evidence of prior learning"
|
||||
And I should see "List of evidence"
|
||||
@@ -47,8 +47,8 @@ Feature: Manage evidence of prior learning
|
||||
And I should see "Evidence-3 Edited"
|
||||
|
||||
Scenario: Delete an evidence of prior learning
|
||||
Given the following lp "userevidence" exist:
|
||||
| name | description | user |
|
||||
Given the following "core_competency > user_evidence" exist:
|
||||
| name | description | user |
|
||||
| Evidence-4 | Evidence-4 description | user1 |
|
||||
And I follow "Evidence of prior learning"
|
||||
And I should see "List of evidence"
|
||||
@@ -62,10 +62,10 @@ Feature: Manage evidence of prior learning
|
||||
|
||||
Scenario: List evidences of prior learning
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
|user2 | User | 2 | user2@example.com |
|
||||
And the following lp "userevidence" exist:
|
||||
| name | description | user |
|
||||
| username | firstname | lastname | email |
|
||||
| user2 | User | 2 | user2@example.com |
|
||||
And the following "core_competency > user_evidence" exist:
|
||||
| name | description | user |
|
||||
| Evidence-5 | Evidence-5 description | user1 |
|
||||
| Evidence-6 | Evidence-6 description | user2 |
|
||||
And I follow "Evidence of prior learning"
|
||||
|
||||
@@ -40,9 +40,9 @@ Feature: View competencies
|
||||
| competency | relatedcompetency |
|
||||
| desserts | cakes |
|
||||
And the following "core_competency > plans" exist:
|
||||
| name | description | competencies | user |
|
||||
| Cookery | Cookery is important | salads, desserts, cakes | student1 |
|
||||
| Literacy | Literacy is important | reading, writing | student1 |
|
||||
| name | description | competencies | user | status |
|
||||
| Cookery | Cookery is important | salads, desserts, cakes | student1 | active |
|
||||
| Literacy | Literacy is important | reading, writing | student1 | active |
|
||||
And the following "core_competency > course_competencies" exist:
|
||||
| course | competency |
|
||||
| C1 | salads |
|
||||
|
||||
@@ -34,6 +34,10 @@ if (function_exists('opcache_reset')) {
|
||||
|
||||
define('IGNORE_COMPONENT_CACHE', true);
|
||||
|
||||
// It makes no sense to use BEHAT_CLI for this script (you cannot initialise PHPunit starting from
|
||||
// the Behat environment), so in case user has set tne environment variable, disable it.
|
||||
putenv('BEHAT_CLI=0');
|
||||
|
||||
require_once(__DIR__.'/../../../../lib/clilib.php');
|
||||
require_once(__DIR__.'/../../../../lib/phpunit/bootstraplib.php');
|
||||
require_once(__DIR__.'/../../../../lib/testing/lib.php');
|
||||
|
||||
@@ -30,6 +30,10 @@ if (isset($_SERVER['REMOTE_ADDR'])) {
|
||||
|
||||
define('IGNORE_COMPONENT_CACHE', true);
|
||||
|
||||
// It makes no sense to use BEHAT_CLI for this script (you cannot initialise PHPunit starting from
|
||||
// the Behat environment), so in case user has set tne environment variable, disable it.
|
||||
putenv('BEHAT_CLI=0');
|
||||
|
||||
require_once(__DIR__.'/../../../../lib/clilib.php');
|
||||
require_once(__DIR__.'/../../../../lib/phpunit/bootstraplib.php');
|
||||
require_once(__DIR__.'/../../../../lib/testing/lib.php');
|
||||
|
||||
@@ -218,12 +218,11 @@ class helper {
|
||||
* @return moodle_url The URL.
|
||||
*/
|
||||
public static function get_duplicate_tour_link($tourid) {
|
||||
$link = new \moodle_url('/admin/tool/usertours/configure.php', [
|
||||
return new \moodle_url('/admin/tool/usertours/configure.php', [
|
||||
'action' => manager::ACTION_DUPLICATETOUR,
|
||||
'id' => $tourid,
|
||||
'sesskey' => sesskey(),
|
||||
]);
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -512,8 +512,9 @@ class manager {
|
||||
* @param int $tourid The ID of the tour to duplicate.
|
||||
*/
|
||||
protected function duplicate_tour($tourid) {
|
||||
$tour = helper::get_tour($tourid);
|
||||
require_sesskey();
|
||||
|
||||
$tour = helper::get_tour($tourid);
|
||||
$export = $tour->to_record();
|
||||
// Remove the id.
|
||||
unset($export->id);
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
@tool @tool_xmldb
|
||||
Feature: The Reconcile XMLDB files report works and all the files are ok
|
||||
In order to ensure that all the XMLDB Editor xml files are generated properly
|
||||
As a developer
|
||||
I need to be able to run the Reconcile XMLDB files report and verify that everything is ok
|
||||
|
||||
Scenario: The Reconcile XMLDB files reports that all files are ok
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Development > XMLDB editor" in site administration
|
||||
When I follow "[Reconcile XMLDB files]"
|
||||
Then I should see "Look for XMLDB files needing reconciling"
|
||||
And I should see "All files are OK. No reconciling is needed."
|
||||
@@ -168,8 +168,7 @@ abstract class restore_qtype_plugin extends restore_plugin {
|
||||
$this->questionanswercacheid = $newquestionid;
|
||||
// Cache all cleaned answers for a simple text match.
|
||||
foreach ($answers as $answer) {
|
||||
// MDL-30018: Clean in the same way as {@link xml_writer::xml_safe_utf8()}.
|
||||
$clean = preg_replace('/[\x-\x8\xb-\xc\xe-\x1f\x7f]/is','', $answer->answer); // Clean CTRL chars.
|
||||
$clean = core_text::trim_ctrl_chars($answer->answer); // Clean CTRL chars.
|
||||
$clean = preg_replace("/\r\n|\r/", "\n", $clean); // Normalize line ending.
|
||||
$this->questionanswercache[$clean] = $answer->id;
|
||||
}
|
||||
|
||||
@@ -5154,8 +5154,7 @@ class restore_create_categories_and_questions extends restore_structure_step {
|
||||
$potentialhints = $DB->get_records('question_hints',
|
||||
array('questionid' => $newquestionid), '', 'id, hint');
|
||||
foreach ($potentialhints as $potentialhint) {
|
||||
// Clean in the same way than {@link xml_writer::xml_safe_utf8()}.
|
||||
$cleanhint = preg_replace('/[\x-\x8\xb-\xc\xe-\x1f\x7f]/is','', $potentialhint->hint); // Clean CTRL chars.
|
||||
$cleanhint = core_text::trim_ctrl_chars($potentialhint->hint); // Clean CTRL chars.
|
||||
$cleanhint = preg_replace("/\r\n|\r/", "\n", $cleanhint); // Normalize line ending.
|
||||
if ($cleanhint === $data->hint) {
|
||||
$newitemid = $data->id;
|
||||
|
||||
@@ -253,14 +253,14 @@ class xml_writer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform some UTF-8 cleaning, stripping the control chars (\x0-\x1f)
|
||||
* but tabs (\x9), newlines (\xa) and returns (\xd). The delete control
|
||||
* Perform some UTF-8 cleaning, stripping the control chars (\x00-\x1f)
|
||||
* but tabs (\x09), newlines (\xa) and returns (\xd). The delete control
|
||||
* char (\x7f) is also included. All them are forbiden in XML 1.0 specs.
|
||||
* The expression below seems to be UTF-8 safe too because it simply
|
||||
* ignores the rest of characters. Also normalize linefeeds and return chars.
|
||||
*/
|
||||
protected function xml_safe_utf8($content) {
|
||||
$content = preg_replace('/[\x-\x8\xb-\xc\xe-\x1f\x7f]/is', '', $content ?? ''); // clean CTRL chars.
|
||||
$content = core_text::trim_ctrl_chars($content ?? '');
|
||||
$content = preg_replace("/\r\n|\r/", "\n", $content); // Normalize line&return=>line
|
||||
return fix_utf8($content);
|
||||
}
|
||||
|
||||
+110
-58
@@ -60,6 +60,7 @@ if (!empty($issuedbadge->recipient->id)) {
|
||||
$assertionid = $assertion->get_assertion_hash();
|
||||
$assertionentityid = $assertiondata['id'];
|
||||
$badgeadded = false;
|
||||
$issuerexists = false;
|
||||
if (badges_open_badges_backpack_api() == OPEN_BADGES_V2) {
|
||||
$sitebackpack = badges_get_site_primary_backpack();
|
||||
$api = new \core_badges\backpack_api($sitebackpack);
|
||||
@@ -71,62 +72,75 @@ if (!empty($issuedbadge->recipient->id)) {
|
||||
$issuer = $assertion->get_issuer();
|
||||
if (!($issuerentityid = badges_external_get_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_ISSUER, $issuer['email']))) {
|
||||
$response = $api->put_issuer($issuer);
|
||||
if (!$response) {
|
||||
throw new moodle_exception('invalidrequest', 'error');
|
||||
if ($response) {
|
||||
$issuerexists = true;
|
||||
$issuerentityid = $response->id;
|
||||
badges_external_create_mapping(
|
||||
$sitebackpack->id,
|
||||
OPEN_BADGES_V2_TYPE_ISSUER,
|
||||
$issuer['email'],
|
||||
$issuerentityid,
|
||||
);
|
||||
}
|
||||
$issuerentityid = $response->id;
|
||||
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_ISSUER, $issuer['email'],
|
||||
$issuerentityid);
|
||||
}
|
||||
// Create badge.
|
||||
$badge = $assertion->get_badge_class(false);
|
||||
$badgeid = $assertion->get_badge_id();
|
||||
if (!($badgeentityid = badges_external_get_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_BADGE, $badgeid))) {
|
||||
$response = $api->put_badgeclass($issuerentityid, $badge);
|
||||
if (!$response) {
|
||||
throw new moodle_exception('invalidrequest', 'error');
|
||||
if ($issuerexists) {
|
||||
// Create badge.
|
||||
$badge = $assertion->get_badge_class(false);
|
||||
$badgeid = $assertion->get_badge_id();
|
||||
if (!($badgeentityid = badges_external_get_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_BADGE, $badgeid))) {
|
||||
$response = $api->put_badgeclass($issuerentityid, $badge);
|
||||
if ($response) {
|
||||
$badgeentityid = $response->id;
|
||||
badges_external_create_mapping(
|
||||
$sitebackpack->id,
|
||||
OPEN_BADGES_V2_TYPE_BADGE,
|
||||
$badgeid,
|
||||
$badgeentityid,
|
||||
);
|
||||
}
|
||||
}
|
||||
$badgeentityid = $response->id;
|
||||
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_BADGE, $badgeid,
|
||||
$badgeentityid);
|
||||
}
|
||||
|
||||
// Create assertion (Award the badge!).
|
||||
$assertionentityid = badges_external_get_mapping(
|
||||
$sitebackpack->id,
|
||||
OPEN_BADGES_V2_TYPE_ASSERTION,
|
||||
$assertionid
|
||||
);
|
||||
|
||||
if ($assertionentityid && strpos($sitebackpack->backpackapiurl, 'badgr')) {
|
||||
$assertionentityid = badges_generate_badgr_open_url(
|
||||
$sitebackpack,
|
||||
OPEN_BADGES_V2_TYPE_ASSERTION,
|
||||
$assertionentityid
|
||||
);
|
||||
}
|
||||
|
||||
// Create an assertion for the recipient in the issuer's account.
|
||||
if (!$assertionentityid) {
|
||||
$response = $api->put_badgeclass_assertion($badgeentityid, $assertiondata);
|
||||
if (!$response) {
|
||||
throw new moodle_exception('invalidrequest', 'error');
|
||||
}
|
||||
$assertionentityid = badges_generate_badgr_open_url($sitebackpack, OPEN_BADGES_V2_TYPE_ASSERTION, $response->id);
|
||||
$badgeadded = true;
|
||||
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_ASSERTION, $assertionid,
|
||||
$response->id);
|
||||
} else {
|
||||
// An assertion already exists. Make sure it's up to date.
|
||||
$internalid = badges_external_get_mapping(
|
||||
// Create assertion (Award the badge!).
|
||||
$assertionentityid = badges_external_get_mapping(
|
||||
$sitebackpack->id,
|
||||
OPEN_BADGES_V2_TYPE_ASSERTION,
|
||||
$assertionid,
|
||||
'externalid'
|
||||
$assertionid
|
||||
);
|
||||
$response = $api->update_assertion($internalid, $assertiondata);
|
||||
if (!$response) {
|
||||
throw new moodle_exception('invalidrequest', 'error');
|
||||
|
||||
if ($assertionentityid && strpos($sitebackpack->backpackapiurl, 'badgr')) {
|
||||
$assertionentityid = badges_generate_badgr_open_url(
|
||||
$sitebackpack,
|
||||
OPEN_BADGES_V2_TYPE_ASSERTION,
|
||||
$assertionentityid
|
||||
);
|
||||
}
|
||||
|
||||
// Create an assertion for the recipient in the issuer's account.
|
||||
if (!$assertionentityid) {
|
||||
$response = $api->put_badgeclass_assertion($badgeentityid, $assertiondata);
|
||||
if ($response) {
|
||||
$assertionentityid = badges_generate_badgr_open_url(
|
||||
$sitebackpack,
|
||||
OPEN_BADGES_V2_TYPE_ASSERTION,
|
||||
$response->id,
|
||||
);
|
||||
$badgeadded = true;
|
||||
badges_external_create_mapping(
|
||||
$sitebackpack->id,
|
||||
OPEN_BADGES_V2_TYPE_ASSERTION,
|
||||
$assertionid,
|
||||
$response->id,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// An assertion already exists. Make sure it's up to date.
|
||||
$internalid = badges_external_get_mapping(
|
||||
$sitebackpack->id,
|
||||
OPEN_BADGES_V2_TYPE_ASSERTION,
|
||||
$assertionid,
|
||||
'externalid'
|
||||
);
|
||||
$response = $api->update_assertion($internalid, $assertiondata);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,21 +150,59 @@ if (!empty($issuedbadge->recipient->id)) {
|
||||
// - If a user and site backpack have the same provider we can skip this as Badgr automatically maps recipients
|
||||
// based on email address.
|
||||
// - This is only needed when the backpacks are from different regions.
|
||||
if ($assertionentityid && !badges_external_get_mapping($userbackpack->id, OPEN_BADGES_V2_TYPE_ASSERTION, $assertionid)) {
|
||||
if (
|
||||
$assertionentityid
|
||||
&& (!$issuerexists || !badges_external_get_mapping($userbackpack->id, OPEN_BADGES_V2_TYPE_ASSERTION, $assertionid))
|
||||
) {
|
||||
$userapi = new \core_badges\backpack_api($userbackpack, $backpack);
|
||||
$userapi->authenticate();
|
||||
$response = $userapi->import_badge_assertion($assertionentityid);
|
||||
if (!$response) {
|
||||
throw new moodle_exception('invalidrequest', 'error');
|
||||
if ($response) {
|
||||
$assertionentityid = $response->id;
|
||||
$badgeadded = true;
|
||||
badges_external_create_mapping(
|
||||
$userbackpack->id,
|
||||
OPEN_BADGES_V2_TYPE_ASSERTION,
|
||||
$assertionid,
|
||||
$assertionentityid,
|
||||
);
|
||||
}
|
||||
$assertionentityid = $response->id;
|
||||
$badgeadded = true;
|
||||
badges_external_create_mapping($userbackpack->id, OPEN_BADGES_V2_TYPE_ASSERTION, $assertionid,
|
||||
$assertionentityid);
|
||||
}
|
||||
|
||||
$response = $badgeadded ? ['success' => 'addedtobackpack'] : ['warning' => 'existsinbackpack'];
|
||||
redirect(new moodle_url('/badges/mybadges.php', $response));
|
||||
$message = '';
|
||||
$messagetype = \core\output\notification::NOTIFY_INFO;
|
||||
if ($badgeadded) {
|
||||
$message = get_string('addedtobackpack', 'badges');
|
||||
$messagetype = \core\output\notification::NOTIFY_SUCCESS;
|
||||
} else {
|
||||
if (isset($userapi) && !empty($userapi->get_errors())) {
|
||||
// If the api used to import the badge to the backpack has errors, show them to inform the user.
|
||||
if (array_filter($userapi->get_errors(), fn($element) => str_contains($element, "DUPLICATE_BADGE"))) {
|
||||
// Duplicated badges are displayed as a warning.
|
||||
$message = get_string('existsinbackpack', 'badges');
|
||||
$messagetype = \core\output\notification::NOTIFY_WARNING;
|
||||
} else {
|
||||
// If the userapi has any other errors, we will use those to inform the user.
|
||||
$message = get_string(
|
||||
'error:cannotsendtobackpack',
|
||||
'badges',
|
||||
implode($userapi->get_errors()),
|
||||
);
|
||||
$messagetype = \core\output\notification::NOTIFY_ERROR;
|
||||
}
|
||||
} else if (isset($api) && !empty($api->get_errors())) {
|
||||
// If the api used to create/update the issuer has errors, show them to inform the user.
|
||||
$errors = $api->get_errors() ?? [get_string('invalidrequest', 'error')];
|
||||
$message = get_string(
|
||||
'error:cannotsendtobackpack',
|
||||
'badges',
|
||||
implode($errors),
|
||||
);
|
||||
$messagetype = \core\output\notification::NOTIFY_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
redirect(new moodle_url('/badges/mybadges.php'), $message, null, $messagetype);
|
||||
} else {
|
||||
redirect(new moodle_url('/badges/mybadges.php'));
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ if ($action == 'delete' && $confirm && confirm_sesskey()) {
|
||||
} else {
|
||||
$msg = get_string('sitebackpacknotdeleted', 'badges');
|
||||
}
|
||||
} else if ($action == 'moveup' || $action == 'movedown') {
|
||||
} else if (($action == 'moveup' || $action == 'movedown') && confirm_sesskey()) {
|
||||
// If no backpack has been selected, there isn't anything to move.
|
||||
if (empty($id)) {
|
||||
redirect($url);
|
||||
|
||||
@@ -667,6 +667,20 @@ class backpack_api {
|
||||
return backpack_api_mapping::get_authentication_error();
|
||||
}
|
||||
|
||||
/**
|
||||
* List all errors occurred during the requests to the backpack.
|
||||
*
|
||||
* @return array The list of errors.
|
||||
*/
|
||||
public function get_errors(): array {
|
||||
$errors = [];
|
||||
foreach ($this->mappings as $mapping) {
|
||||
$errors = array_merge($errors, $mapping->get_errors());
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of badges in a collection.
|
||||
*
|
||||
|
||||
@@ -79,6 +79,9 @@ class backpack_api_mapping {
|
||||
/** @var string Error string from authentication request. */
|
||||
private static $authenticationerror = '';
|
||||
|
||||
/** @var array Errors encountered during the request. */
|
||||
protected $errors = [];
|
||||
|
||||
/**
|
||||
* Create a mapping.
|
||||
*
|
||||
@@ -144,6 +147,26 @@ class backpack_api_mapping {
|
||||
return self::$authenticationerror;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the errors encountered during the request.
|
||||
*
|
||||
* @return array The list of errors.
|
||||
*/
|
||||
public function get_errors() {
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an error to the list of errors.
|
||||
*
|
||||
* @param string $error The error message.
|
||||
* @return self This instance for method chaining.
|
||||
*/
|
||||
public function add_error(string $error): self {
|
||||
$this->errors[] = $error;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the action match this mapping?
|
||||
*
|
||||
@@ -366,6 +389,23 @@ class backpack_api_mapping {
|
||||
$response = $curl->put($url, $post, $options);
|
||||
}
|
||||
$response = json_decode($response);
|
||||
if ($response === null) {
|
||||
$this->add_error(get_string('invalidrequest', 'error'));
|
||||
return null;
|
||||
}
|
||||
if (isset($response->status) && isset($response->status->success) && $response->status->success != true) {
|
||||
// If the response wasn't successful, store the errors and return null.
|
||||
if (isset($response->validationErrors)) {
|
||||
$error = implode(', ', $response->validationErrors);
|
||||
} else if (isset($response->status)) {
|
||||
$error = $response->status->description;
|
||||
} else {
|
||||
$error = get_string('invalidrequest', 'error');
|
||||
}
|
||||
$this->add_error($error);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isset($response->result)) {
|
||||
$response = $response->result;
|
||||
}
|
||||
|
||||
@@ -56,13 +56,13 @@
|
||||
<td> {{{backpackweburl}}} </td>
|
||||
<td>
|
||||
{{#canmoveup}}
|
||||
<a href="{{baseurl}}?id={{id}}&action=moveup">{{#pix}}t/up, core,{{#str}}moveup{{/str}}{{/pix}}</a>
|
||||
<a href="{{baseurl}}?id={{id}}&sesskey={{sesskey}}&action=moveup">{{#pix}}t/up, core,{{#str}}moveup{{/str}}{{/pix}}</a>
|
||||
{{/canmoveup}}
|
||||
{{^canmoveup}}
|
||||
{{#pix}}spacer, moodle{{/pix}}
|
||||
{{/canmoveup}}
|
||||
{{#canmovedown}}
|
||||
<a href="{{baseurl}}?id={{id}}&action=movedown">{{#pix}}t/down, core,{{#str}}movedown{{/str}}{{/pix}}</a>
|
||||
<a href="{{baseurl}}?id={{id}}&sesskey={{sesskey}}&action=movedown">{{#pix}}t/down, core,{{#str}}movedown{{/str}}{{/pix}}</a>
|
||||
{{/canmovedown}}
|
||||
{{^canmovedown}}
|
||||
{{#pix}}spacer, moodle{{/pix}}
|
||||
|
||||
@@ -14,13 +14,13 @@ Feature: Award badges based on competency completion
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| user1 | C1 | student |
|
||||
And the following lp "frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Framework 1 | sc-y-2 |
|
||||
And the following lp "competencies" exist:
|
||||
| shortname | framework |
|
||||
| comp1 | sc-y-2 |
|
||||
| comp2 | sc-y-2 |
|
||||
And the following "core_competency > frameworks" exist:
|
||||
| shortname | idnumber |
|
||||
| Framework 1 | sc-y-2 |
|
||||
And the following "core_competency > competencies" exist:
|
||||
| shortname | competencyframework |
|
||||
| comp1 | sc-y-2 |
|
||||
| comp2 | sc-y-2 |
|
||||
And I log in as "admin"
|
||||
|
||||
@javascript
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Script to let a user edit the properties of a particular RSS feed.
|
||||
* Script to let a user view the output of a particular RSS feed.
|
||||
*
|
||||
* @package block_rss_client
|
||||
* @copyright 2009 Tim Hunt
|
||||
@@ -26,9 +26,6 @@ require_once(__DIR__ . '/../../config.php');
|
||||
require_once($CFG->libdir .'/simplepie/moodle_simplepie.php');
|
||||
|
||||
require_login();
|
||||
if (isguestuser()) {
|
||||
throw new \moodle_exception('guestsarenotallowed');
|
||||
}
|
||||
|
||||
$returnurl = optional_param('returnurl', '', PARAM_LOCALURL);
|
||||
$courseid = optional_param('courseid', 0, PARAM_INT);
|
||||
@@ -46,6 +43,11 @@ if ($courseid) {
|
||||
$PAGE->set_context($context);
|
||||
}
|
||||
|
||||
$managesharedfeeds = has_capability('block/rss_client:manageanyfeeds', $context);
|
||||
if (!$managesharedfeeds) {
|
||||
require_capability('block/rss_client:manageownfeeds', $context);
|
||||
}
|
||||
|
||||
$urlparams = array('rssid' => $rssid);
|
||||
if ($courseid) {
|
||||
$urlparams['courseid'] = $courseid;
|
||||
@@ -56,10 +58,18 @@ if ($returnurl) {
|
||||
$PAGE->set_url('/blocks/rss_client/viewfeed.php', $urlparams);
|
||||
$PAGE->set_pagelayout('popup');
|
||||
|
||||
$rssrecord = $DB->get_record('block_rss_client', array('id' => $rssid), '*', MUST_EXIST);
|
||||
if ($managesharedfeeds) {
|
||||
$select = 'id = :id AND (userid = :userid OR shared = 1)';
|
||||
} else {
|
||||
$select = 'id = :id AND userid = :userid';
|
||||
}
|
||||
|
||||
$rssrecord = $DB->get_record_select('block_rss_client', $select, [
|
||||
'id' => $rssid,
|
||||
'userid' => $USER->id,
|
||||
], '*', MUST_EXIST);
|
||||
|
||||
$rss = new moodle_simplepie($rssrecord->url);
|
||||
|
||||
if ($rss->error()) {
|
||||
debugging($rss->error());
|
||||
throw new \moodle_exception('errorfetchingrssfeed');
|
||||
|
||||
@@ -55,11 +55,11 @@ class cohorts extends system_report {
|
||||
"{$entitymainalias}.component");
|
||||
|
||||
// Check if report needs to show a specific category.
|
||||
$contextid = $this->get_parameter('contextid', 0, PARAM_INT);
|
||||
$showall = $this->get_parameter('showall', true, PARAM_BOOL);
|
||||
if (!$showall) {
|
||||
if (!$this->get_context() instanceof context_system || !$this->get_parameter('showall', false, PARAM_BOOL)) {
|
||||
$paramcontextid = database::generate_param_name();
|
||||
$this->add_base_condition_sql("{$entitymainalias}.contextid = :$paramcontextid", [$paramcontextid => $contextid]);
|
||||
$this->add_base_condition_sql("{$entitymainalias}.contextid = :{$paramcontextid}", [
|
||||
$paramcontextid => $this->get_context()->id,
|
||||
]);
|
||||
}
|
||||
|
||||
// Now we can call our helper methods to add the content we want to include in the report.
|
||||
@@ -77,14 +77,7 @@ class cohorts extends system_report {
|
||||
* @return bool
|
||||
*/
|
||||
protected function can_view(): bool {
|
||||
$contextid = $this->get_parameter('contextid', 0, PARAM_INT);
|
||||
if ($contextid) {
|
||||
$context = context::instance_by_id($contextid, MUST_EXIST);
|
||||
} else {
|
||||
$context = context_system::instance();
|
||||
}
|
||||
|
||||
return has_any_capability(['moodle/cohort:manage', 'moodle/cohort:view'], $context);
|
||||
return has_any_capability(['moodle/cohort:manage', 'moodle/cohort:view'], $this->get_context());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,10 +91,8 @@ class cohorts extends system_report {
|
||||
public function add_columns(cohort $cohortentity): void {
|
||||
|
||||
$entitymainalias = $cohortentity->get_table_alias('cohort');
|
||||
$showall = $this->get_parameter('showall', false, PARAM_BOOL);
|
||||
|
||||
// Category column. An extra callback is appended in order to extend the current column formatting.
|
||||
if ($showall) {
|
||||
if ($this->get_context() instanceof context_system && $this->get_parameter('showall', false, PARAM_BOOL)) {
|
||||
$this->add_column_from_entity('cohort:context')
|
||||
->add_callback(static function(string $value, stdClass $cohort): string {
|
||||
$context = context::instance_by_id($cohort->contextid);
|
||||
@@ -195,10 +186,11 @@ class cohorts extends system_report {
|
||||
*/
|
||||
protected function add_actions(): void {
|
||||
|
||||
$contextid = $this->get_parameter('contextid', 0, PARAM_INT);
|
||||
$showall = $this->get_parameter('showall', true, PARAM_BOOL);
|
||||
$returnurl = (new moodle_url('/cohort/index.php',
|
||||
['id' => ':id', 'contextid' => $contextid, 'showall' => $showall]))->out(false);
|
||||
$returnurl = (new moodle_url('/cohort/index.php', [
|
||||
'id' => ':id',
|
||||
'contextid' => $this->get_context()->id,
|
||||
'showall' => $this->get_parameter('showall', false, PARAM_BOOL),
|
||||
]))->out(false);
|
||||
|
||||
// Hide action. It will be only shown if the property 'visible' is true and user has 'moodle/cohort:manage' capabillity.
|
||||
$this->add_action((new action(
|
||||
|
||||
+1
-2
@@ -104,8 +104,7 @@ if ($editcontrols = cohort_edit_controls($context, $baseurl)) {
|
||||
echo $OUTPUT->render($editcontrols);
|
||||
}
|
||||
|
||||
$reportparams = ['contextid' => $context->id, 'showall' => $showall];
|
||||
$report = system_report_factory::create(cohorts::class, $context, '', '', 0, $reportparams);
|
||||
$report = system_report_factory::create(cohorts::class, $context, '', '', 0, ['showall' => $showall]);
|
||||
|
||||
// Check if it needs to search by name.
|
||||
if (!empty($searchquery)) {
|
||||
|
||||
@@ -57,7 +57,13 @@ class behat_core_competency_generator extends behat_generator_base {
|
||||
'singular' => 'plan',
|
||||
'datagenerator' => 'plan',
|
||||
'required' => ['name'],
|
||||
'switchids' => ['user' => 'userid'],
|
||||
'switchids' => ['user' => 'userid', 'status' => 'status'],
|
||||
],
|
||||
'plan_competencies' => [
|
||||
'singular' => 'plan_competency',
|
||||
'datagenerator' => 'plan_competency',
|
||||
'required' => ['plan', 'competency'],
|
||||
'switchids' => ['competency' => 'competencyid', 'plan' => 'planid'],
|
||||
],
|
||||
'related_competencies' => [
|
||||
'singular' => 'related_competency',
|
||||
@@ -83,14 +89,38 @@ class behat_core_competency_generator extends behat_generator_base {
|
||||
'required' => ['plan', 'competency', 'user'],
|
||||
'switchids' => ['plan' => 'planid', 'competency' => 'competencyid', 'user' => 'userid'],
|
||||
],
|
||||
'user_evidence' => [
|
||||
'singular' => 'user_evidence',
|
||||
'datagenerator' => 'user_evidence',
|
||||
'required' => ['user', 'name'],
|
||||
'switchids' => ['user' => 'userid'],
|
||||
],
|
||||
'user_evidence_competency' => [
|
||||
'singular' => 'user_evidence_competency',
|
||||
'datagenerator' => 'user_evidence_competency',
|
||||
'required' => ['userevidence', 'competency'],
|
||||
'switchids' => ['userevidence' => 'userevidenceid', 'competency' => 'competencyid'],
|
||||
],
|
||||
'templates' => [
|
||||
'singular' => 'template',
|
||||
'datagenerator' => 'template',
|
||||
'required' => ['shortname'],
|
||||
'switchids' => ['context' => 'contextid'],
|
||||
],
|
||||
'template_competencies' => [
|
||||
'singular' => 'template_competency',
|
||||
'datagenerator' => 'template_competency',
|
||||
'required' => ['template', 'competency'],
|
||||
'switchids' => ['template' => 'templateid', 'competency' => 'competencyid'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the competecy framework id using an idnumber.
|
||||
* Get the competency framework id using an idnumber.
|
||||
*
|
||||
* @param string $idnumber
|
||||
* @return int The competecy framework id
|
||||
* @return int The competency framework id
|
||||
*/
|
||||
protected function get_competencyframework_id(string $idnumber): int {
|
||||
global $DB;
|
||||
@@ -103,10 +133,10 @@ class behat_core_competency_generator extends behat_generator_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the competecy id using an idnumber.
|
||||
* Get the competency id using an idnumber.
|
||||
*
|
||||
* @param string $idnumber
|
||||
* @return int The competecy id
|
||||
* @return int The competency id
|
||||
*/
|
||||
protected function get_competency_id(string $idnumber): int {
|
||||
global $DB;
|
||||
@@ -135,15 +165,31 @@ class behat_core_competency_generator extends behat_generator_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the related competecy id using an idnumber.
|
||||
* Get the related competency id using an idnumber.
|
||||
*
|
||||
* @param string $idnumber
|
||||
* @return int The related competecy id
|
||||
* @return int The related competency id
|
||||
*/
|
||||
protected function get_relatedcompetency_id(string $idnumber): int {
|
||||
return $this->get_competency_id($idnumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template id by shortname.
|
||||
*
|
||||
* @param string $shortname The template name.
|
||||
* @return int
|
||||
*/
|
||||
protected function get_template_id(string $shortname): int {
|
||||
global $DB;
|
||||
|
||||
if (!$id = $DB->get_field('competency_template', 'id', ['shortname' => $shortname])) {
|
||||
throw new Exception('The specified template with name "' . $shortname . '" could not be found.');
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a plan.
|
||||
*
|
||||
@@ -208,6 +254,8 @@ class behat_core_competency_generator extends behat_generator_base {
|
||||
* @return array Processed data.
|
||||
*/
|
||||
protected function preprocess_plan(array $data): array {
|
||||
global $DB, $USER;
|
||||
|
||||
if (isset($data['competencies'])) {
|
||||
$competencies = array_map('trim', str_getcsv($data['competencies']));
|
||||
$data['competencyids'] = array_map([$this, 'get_competency_id'], $competencies);
|
||||
@@ -215,11 +263,20 @@ class behat_core_competency_generator extends behat_generator_base {
|
||||
unset($data['competencies']);
|
||||
}
|
||||
|
||||
global $USER;
|
||||
if (isset($data['reviewer'])) {
|
||||
if (is_number($data['reviewer'])) {
|
||||
$data['reviewerid'] = $data['reviewer'];
|
||||
} else {
|
||||
if (!$userid = $DB->get_field('user', 'id', ['username' => $data['reviewer']])) {
|
||||
throw new Exception('The specified user "' . $data['reviewer'] . '" could not be found.');
|
||||
}
|
||||
$data['reviewerid'] = $userid;
|
||||
}
|
||||
unset($data['reviewer']);
|
||||
}
|
||||
|
||||
return $data + [
|
||||
'userid' => $USER->id,
|
||||
'status' => plan::STATUS_ACTIVE,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -258,4 +315,81 @@ class behat_core_competency_generator extends behat_generator_base {
|
||||
protected function get_data_generator(): core_competency_generator {
|
||||
return $this->componentdatagenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user evidence id using a name.
|
||||
*
|
||||
* @param string $name User evidence name.
|
||||
* @return int The user evidence id
|
||||
*/
|
||||
protected function get_userevidence_id(string $name): int {
|
||||
global $DB;
|
||||
|
||||
if (!$id = $DB->get_field('competency_userevidence', 'id', ['name' => $name])) {
|
||||
throw new Exception('The specified user evidence with name "' . $name . '" could not be found.');
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template competency id using a name.
|
||||
*
|
||||
* @param string $name Template competency name.
|
||||
* @return int The template competency id
|
||||
*/
|
||||
protected function get_templatecompetency_id(string $name): int {
|
||||
global $DB;
|
||||
|
||||
if (!$id = $DB->get_field('competency_template', 'id', ['name' => $name])) {
|
||||
throw new Exception('The specified template competency with name "' . $name . '" could not be found.');
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the context id using a contextid.
|
||||
*
|
||||
* @param string $contextid Context id.
|
||||
* @return int The context id
|
||||
*/
|
||||
protected function get_context_id(string $contextid): int {
|
||||
global $DB;
|
||||
|
||||
if (!$id = $DB->get_field('context', 'id', ['id' => $contextid])) {
|
||||
throw new Exception('The specified context with id "' . $contextid . '" could not be found.');
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status id by status name.
|
||||
*
|
||||
* @param string $name Status name.
|
||||
* @return int
|
||||
*/
|
||||
protected function get_status_id(string $name): int {
|
||||
|
||||
switch ($name) {
|
||||
case 'draft':
|
||||
$status = plan::STATUS_DRAFT;
|
||||
break;
|
||||
case 'in review':
|
||||
$status = plan::STATUS_IN_REVIEW;
|
||||
break;
|
||||
case 'waiting for review':
|
||||
$status = plan::STATUS_WAITING_FOR_REVIEW;
|
||||
break;
|
||||
case 'complete':
|
||||
$status = plan::STATUS_COMPLETE;
|
||||
break;
|
||||
default:
|
||||
$status = plan::STATUS_ACTIVE;
|
||||
break;
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-7
@@ -4127,7 +4127,7 @@ class core_course_external extends external_api {
|
||||
|
||||
self::validate_context($usercontext);
|
||||
|
||||
if ($userid != $USER->id and !has_capability('moodle/user:viewdetails', $usercontext)) {
|
||||
if ($userid != $USER->id && !has_capability('moodle/user:viewalldetails', $usercontext)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
@@ -4177,22 +4177,28 @@ class core_course_external extends external_api {
|
||||
* @param int $groupid Group id from which the users will be obtained
|
||||
* @param bool $onlyactive Whether to return only the active enrolled users or all enrolled users in the course.
|
||||
* @return array List of users
|
||||
* @throws invalid_parameter_exception
|
||||
*/
|
||||
public static function get_enrolled_users_by_cmid(int $cmid, int $groupid = 0, bool $onlyactive = false) {
|
||||
global $PAGE;
|
||||
global $PAGE;
|
||||
|
||||
$warnings = [];
|
||||
|
||||
self::validate_parameters(self::get_enrolled_users_by_cmid_parameters(), [
|
||||
'cmid' => $cmid,
|
||||
'groupid' => $groupid,
|
||||
'onlyactive' => $onlyactive,
|
||||
[
|
||||
'cmid' => $cmid,
|
||||
'groupid' => $groupid,
|
||||
'onlyactive' => $onlyactive,
|
||||
] = self::validate_parameters(self::get_enrolled_users_by_cmid_parameters(), [
|
||||
'cmid' => $cmid,
|
||||
'groupid' => $groupid,
|
||||
'onlyactive' => $onlyactive,
|
||||
]);
|
||||
|
||||
list($course, $cm) = get_course_and_cm_from_cmid($cmid);
|
||||
$coursecontext = context_course::instance($course->id);
|
||||
self::validate_context($coursecontext);
|
||||
|
||||
course_require_view_participants($coursecontext);
|
||||
|
||||
$enrolledusers = get_enrolled_users($coursecontext, '', $groupid, 'u.*', null, 0, 0, $onlyactive);
|
||||
|
||||
$users = array_map(function ($user) use ($PAGE) {
|
||||
|
||||
@@ -242,6 +242,9 @@ class stateactions {
|
||||
|
||||
foreach ($ids as $sectionid) {
|
||||
$section = $modinfo->get_section_info_by_id($sectionid, MUST_EXIST);
|
||||
if (!course_can_delete_section($course, $section)) {
|
||||
continue;
|
||||
}
|
||||
// Send all activity deletions.
|
||||
if (!empty($modinfo->sections[$section->section])) {
|
||||
foreach ($modinfo->sections[$section->section] as $modnumber) {
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace core_courseformat\external;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use core_courseformat\stateactions;
|
||||
use core_courseformat\stateupdates;
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
|
||||
|
||||
/**
|
||||
* Tests for the delete section test class.
|
||||
*
|
||||
* @package core_courseformat
|
||||
* @copyright 2025 Laurent David <laurent.david@moodle.com>
|
||||
* @category test
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \core_courseformat\stateactions
|
||||
*/
|
||||
final class delete_section_test extends \externallib_advanced_testcase {
|
||||
|
||||
/**
|
||||
* Setup to ensure that fixtures are loaded.
|
||||
*/
|
||||
public static function setupBeforeClass(): void { // phpcs:ignore
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/course/format/tests/fixtures/format_theunittestdelete.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the webservice can execute the section_delete action.
|
||||
*
|
||||
* @covers ::section_delete
|
||||
* @dataProvider section_delete_provider
|
||||
* @param int $sectionum
|
||||
* @param string $format
|
||||
* @param array $formatoptions
|
||||
* @param int $expectedsectionum
|
||||
*
|
||||
* @throws \moodle_exception
|
||||
*/
|
||||
public function test_delete_section(int $sectionum, string $format, array $formatoptions, int $expectedsectionum): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$course =
|
||||
$this->getDataGenerator()->create_course(array_merge(
|
||||
['numsections' => $sectionum, 'format' => $format],
|
||||
$formatoptions,
|
||||
));
|
||||
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
|
||||
// Execute the method.
|
||||
$courseformat = course_get_format($course->id);
|
||||
$updates = new stateupdates($courseformat);
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
$sections = $modinfo->get_section_info_all();
|
||||
$sectionsid = array_map(function ($section) {
|
||||
return $section->id;
|
||||
}, $sections);
|
||||
$actions = new stateactions();
|
||||
$this->setUser($teacher);
|
||||
$actions->section_delete(
|
||||
$updates,
|
||||
$course,
|
||||
$sectionsid
|
||||
);
|
||||
// Check result.
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
$sections = $modinfo->get_section_info_all();
|
||||
$this->assertCount($expectedsectionum, $sections);
|
||||
if ($format == 'theunittestdelete') {
|
||||
$this->assertDebuggingCalled();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for the test_delete_section method.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function section_delete_provider(): array {
|
||||
return [
|
||||
'format topic' => [
|
||||
'sectionum' => 1,
|
||||
'format' => 'topics',
|
||||
'formatoptions' => [],
|
||||
'expectedsectionum' => 1,
|
||||
],
|
||||
'format theunittestdelete' => [
|
||||
'sectionum' => 1,
|
||||
'format' => 'theunittestdelete',
|
||||
'formatoptions' => [],
|
||||
'expectedsectionum' => 2,
|
||||
],
|
||||
'format theunittestdelete can delete' => [
|
||||
'sectionum' => 1,
|
||||
'format' => 'theunittestdelete',
|
||||
'formatoptions' => ['can_delete_sections' => true],
|
||||
'expectedsectionum' => 1,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?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/>.
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
require_once(__DIR__ . '/format_theunittest.php');
|
||||
|
||||
/**
|
||||
* Fixture for fake course format testing course format API.
|
||||
*
|
||||
* @package core_courseformat
|
||||
* @copyright 2025 Laurent David <laurent.david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class format_theunittestdelete extends format_theunittest {
|
||||
|
||||
/**
|
||||
* Definitions of the additional options that format uses
|
||||
*
|
||||
* @param bool $foreditform
|
||||
* @return array of options
|
||||
*/
|
||||
public function course_format_options($foreditform = false) {
|
||||
static $courseformatoptions = false;
|
||||
if ($courseformatoptions === false) {
|
||||
$courseformatoptions = parent::course_format_options(true);
|
||||
$courseformatoptionsadditional = [
|
||||
'can_delete_sections' => [
|
||||
'default' => false,
|
||||
'type' => PARAM_BOOL,
|
||||
],
|
||||
];
|
||||
$courseformatoptions = array_merge_recursive($courseformatoptions, $courseformatoptionsadditional);
|
||||
}
|
||||
return $courseformatoptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this format allows to delete sections
|
||||
*
|
||||
* Here for test purpose we just can delete one section every two sections
|
||||
*
|
||||
* Do not call this function directly, instead use course_can_delete_section()
|
||||
*
|
||||
* @param int|stdClass|section_info $section
|
||||
* @return bool
|
||||
*/
|
||||
public function can_delete_section($section) {
|
||||
return $this->get_format_options()['can_delete_sections'] ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this course format uses sections
|
||||
*/
|
||||
public function uses_sections() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+8
-1
@@ -1757,7 +1757,14 @@ class core_course_renderer extends plugin_renderer_base {
|
||||
// This is a request for the course information.
|
||||
$courseid = required_param('courseid', PARAM_INT);
|
||||
|
||||
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
|
||||
$course = $DB->get_record('course', ['id' => $courseid], '*', IGNORE_MISSING);
|
||||
if ($course === false) {
|
||||
throw new \moodle_exception('invalidcourseid');
|
||||
}
|
||||
$coursecontext = context_course::instance($course->id, MUST_EXIST);
|
||||
if ($course->visible == 0 && !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
|
||||
throw new \moodle_exception('invalidcourseid');
|
||||
}
|
||||
|
||||
$chelper = new coursecat_helper();
|
||||
$chelper->set_show_courses(self::COURSECAT_SHOW_COURSES_EXPANDED);
|
||||
|
||||
@@ -3639,6 +3639,12 @@ final class externallib_test extends externallib_advanced_testcase {
|
||||
$this->assignUserCapability('moodle/user:viewdetails', $usercontext, $teacherroleid);
|
||||
|
||||
// Sorted by course id DESC.
|
||||
// User without moodle/user:viewalldetails capability will not be able to see the course details.
|
||||
$result = core_course_external::get_recent_courses($student->id);
|
||||
$this->assertCount(0, $result);
|
||||
|
||||
// User with moodle/user:viewalldetails capability will be able to see the course details.
|
||||
$this->assignUserCapability('moodle/user:viewalldetails', $usercontext, $teacherroleid);
|
||||
$result = core_course_external::get_recent_courses($student->id);
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals($courses[0]->id, array_shift($result)->id);
|
||||
@@ -3742,6 +3748,12 @@ final class externallib_test extends externallib_advanced_testcase {
|
||||
|
||||
$this->assertEquals(2, count($users['users']));
|
||||
$this->assertEquals($expectedusers, $users);
|
||||
|
||||
// Prohibit the capability for viewing course participants.
|
||||
$this->unassignUserCapability('moodle/course:viewparticipants', null, null, $course1->id);
|
||||
$this->expectException(required_capability_exception::class);
|
||||
$this->expectExceptionMessage('Sorry, but you do not currently have permissions to do that (View participants)');
|
||||
core_course_external::get_enrolled_users_by_cmid($forum1->cmid);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+10
-1
@@ -84,11 +84,20 @@ function filter_tex_sanitize_formula(string $texexp): string {
|
||||
'\afterassignment', '\expandafter', '\noexpand', '\special',
|
||||
'\let', '\futurelet', '\else', '\fi', '\chardef', '\makeatletter', '\afterground',
|
||||
'\noexpand', '\line', '\mathcode', '\item', '\section', '\mbox', '\declarerobustcommand',
|
||||
'\ExplSyntaxOn', '\pdffiledump',
|
||||
'\ExplSyntaxOn', '\pdffiledump', '\mathtex',
|
||||
];
|
||||
|
||||
$allowlist = ['inputenc'];
|
||||
|
||||
// Add encoded backslash (\) versions of backslashed items to deny list.
|
||||
$encodedslashdenylist = array_map(function($value) {
|
||||
$encoded = str_replace('\\', '\', $value);
|
||||
// Return an encoded slash version if a slash is found, otherwise null so we can filter it off.
|
||||
return $encoded != $value ? $encoded : null;
|
||||
}, $denylist);
|
||||
$encodedslashdenylist = array_filter($encodedslashdenylist);
|
||||
$denylist = array_merge($denylist, $encodedslashdenylist);
|
||||
|
||||
// Prepare the denylist for regular expression.
|
||||
$denylist = array_map(function($value){
|
||||
return '/' . preg_quote($value, '/') . '/i';
|
||||
|
||||
@@ -18,7 +18,7 @@ Feature: Teacher can edit a marking guide state
|
||||
| activity | course | name | advancedgradingmethod_submissions |
|
||||
| assign | C1 | Assign 1 | guide |
|
||||
|
||||
Scenario: Marking guide state can be changed to draft
|
||||
Scenario Outline: Marking guide state can be changed
|
||||
Given I am on the "Course 1" course page logged in as teacher1
|
||||
And I go to "Assign 1" advanced grading definition page
|
||||
And I set the following fields to these values:
|
||||
@@ -28,12 +28,12 @@ Feature: Teacher can edit a marking guide state
|
||||
| Criterion name | Description for students | Description for markers | Maximum score |
|
||||
| Grade Criteria 1 | Grade 1 description for students | Grade 1 description for markers | 70 |
|
||||
| Grade Criteria 2 | Grade 2 description for students | Grade 2 description for markers | 30 |
|
||||
And I press "Save marking guide and make it ready"
|
||||
And I should not see "Please note: the advanced grading form is not ready at the moment. Simple grading method will be used until the form has a valid status."
|
||||
And I should not see "Assign 1 marking guide Draft"
|
||||
And I should see "Assign 1 marking guide Ready for use"
|
||||
And I click on "Edit the current form definition" "link"
|
||||
When I press "Save as draft"
|
||||
Then I should see "Please note: the advanced grading form is not ready at the moment. Simple grading method will be used until the form has a valid status."
|
||||
And I should see "Assign 1 marking guide Draft"
|
||||
And I should not see "Assign 1 marking guide Ready for use"
|
||||
When I press "<buttonname>"
|
||||
Then I <drafttextvisibility> see "Please note: the advanced grading form is not ready at the moment. Simple grading method will be used until the form has a valid status."
|
||||
And I <drafttextvisibility> see "Assign 1 marking guide Draft"
|
||||
And I <readytextvisibility> see "Assign 1 marking guide Ready for use"
|
||||
|
||||
Examples:
|
||||
| buttonname | drafttextvisibility | readytextvisibility |
|
||||
| Save marking guide and make it ready | should not | should |
|
||||
| Save as draft | should | should not |
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
@gradingform @gradingform_guide
|
||||
Feature: Marking guide can handle maximum grade mismatches
|
||||
In order to handle maximum grade mismatches
|
||||
As a teacher
|
||||
I should be able to set the maximum grade
|
||||
|
||||
Background:
|
||||
Given the following "user" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname |
|
||||
| Course 1 | C1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
|
||||
Scenario Outline: Marking guide maximum grade handling
|
||||
Given the following "activities" exist:
|
||||
| activity | course | name | advancedgradingmethod_submissions |
|
||||
| assign | C1 | Assign 1 | guide |
|
||||
And I am on the "Course 1" course page logged in as teacher1
|
||||
And I go to "Assign 1" advanced grading definition page
|
||||
And I set the following fields to these values:
|
||||
| Name | Assign 1 marking guide |
|
||||
| Description | Marking guide description |
|
||||
And I define the following marking guide:
|
||||
| Criterion name | Description for students | Description for markers | Maximum score |
|
||||
| Grade Criteria 1 | Grade 1 description for students | Grade 1 description for markers | <maxscore> |
|
||||
| Grade Criteria 2 | Grade 2 description for students | Grade 2 description for markers | 30 |
|
||||
When I press "Save marking guide and make it ready"
|
||||
Then I should see "Assign 1 marking guide Ready for use"
|
||||
# Please note: We need to add the no-break space unicode character to the warning message otherwise it will fail.
|
||||
And I should see "WARNING: Your marking guide has a maximum grade of <totalmaxscore> points but the maximum grade set in your activity is 100 The maximum score set in your marking guide will be scaled to the maximum grade in the module."
|
||||
And I should see "Intermediate scores will be converted respectively and rounded to the nearest available grade."
|
||||
|
||||
Examples:
|
||||
# <totalmaxscore> value is derived from <maxscore> + maximum score assigned to criteria 2 (30).
|
||||
# Case 1: total > max score of 100.
|
||||
# Case 2: total < max score of 100.
|
||||
| maxscore | totalmaxscore |
|
||||
| 90 | 120 |
|
||||
| 50 | 80 |
|
||||
@@ -26,6 +26,7 @@ namespace gradereport_singleview\local\ui;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
use context_course;
|
||||
use grade_grade;
|
||||
|
||||
/**
|
||||
@@ -83,6 +84,10 @@ class exclude extends grade_attribute_format implements be_checked, be_disabled,
|
||||
* @return element
|
||||
*/
|
||||
public function determine_format(): element {
|
||||
if (($this->grade->is_hidden() || $this->grade->grade_item->is_hidden()) &&
|
||||
!has_capability('moodle/grade:viewhidden', context_course::instance($this->grade->grade_item->courseid))) {
|
||||
return new empty_element();
|
||||
}
|
||||
return new checkbox_attribute(
|
||||
$this->get_name(),
|
||||
$this->get_label(),
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
namespace gradereport_singleview\local\ui;
|
||||
|
||||
use context_course;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
/**
|
||||
@@ -104,6 +106,10 @@ class feedback extends grade_attribute_format implements unique_value, be_disabl
|
||||
* @return element
|
||||
*/
|
||||
public function determine_format(): element {
|
||||
if (($this->grade->is_hidden() || $this->grade->grade_item->is_hidden()) &&
|
||||
!has_capability('moodle/grade:viewhidden', context_course::instance($this->grade->grade_item->courseid))) {
|
||||
return new empty_element();
|
||||
}
|
||||
return new text_attribute(
|
||||
$this->get_name(),
|
||||
$this->get_value(),
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace gradereport_singleview\local\ui;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
use context_course;
|
||||
use stdClass;
|
||||
/**
|
||||
* UI element representing the finalgrade column.
|
||||
@@ -113,6 +114,11 @@ class finalgrade extends grade_attribute_format implements unique_value, be_disa
|
||||
* @return element
|
||||
*/
|
||||
public function determine_format(): element {
|
||||
if (($this->grade->is_hidden() || $this->grade->grade_item->is_hidden()) &&
|
||||
!has_capability('moodle/grade:viewhidden', context_course::instance($this->grade->grade_item->courseid))) {
|
||||
return new empty_element();
|
||||
}
|
||||
|
||||
if ($this->grade->grade_item->load_scale()) {
|
||||
$scale = $this->grade->grade_item->load_scale();
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
namespace gradereport_singleview\local\ui;
|
||||
|
||||
use context_course;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
/**
|
||||
@@ -94,7 +96,11 @@ class override extends grade_attribute_format implements be_checked, be_disabled
|
||||
* @return element
|
||||
*/
|
||||
public function determine_format(): element {
|
||||
if (!$this->grade->grade_item->is_overridable_item()) {
|
||||
// If the grade is hidden and the user does not have permission to view hidden grades,
|
||||
// then we don't show the override checkbox.
|
||||
$allowhiddenoverride = (!$this->grade->is_hidden() && !$this->grade->grade_item->is_hidden()) ||
|
||||
has_capability('moodle/grade:viewhidden', context_course::instance($this->grade->grade_item->courseid));
|
||||
if (!$allowhiddenoverride || !$this->grade->grade_item->is_overridable_item()) {
|
||||
return new empty_element();
|
||||
}
|
||||
return new checkbox_attribute(
|
||||
|
||||
@@ -482,7 +482,7 @@ class user extends grade_report {
|
||||
$gradegrade->load_grade_item();
|
||||
|
||||
// Hidden Items.
|
||||
if ($gradegrade->grade_item->is_hidden()) {
|
||||
if ($gradegrade->grade_item->is_hidden() && $this->canviewhidden) {
|
||||
$hidden = ' dimmed_text';
|
||||
}
|
||||
|
||||
@@ -548,7 +548,7 @@ class user extends grade_report {
|
||||
|
||||
$itemicon = \html_writer::div($this->gtree->get_element_icon($element), 'mr-1');
|
||||
$elementtype = $this->gtree->get_element_type_string($element);
|
||||
$itemtype = \html_writer::span($elementtype, 'd-block text-uppercase small dimmed_text',
|
||||
$itemtype = \html_writer::span($elementtype, 'd-block text-uppercase small ' . $hidden,
|
||||
['title' => $elementtype]);
|
||||
|
||||
if ($type == 'categoryitem' || $type == 'courseitem') {
|
||||
@@ -636,10 +636,11 @@ class user extends grade_report {
|
||||
);
|
||||
$gradeitemdata['gradehiddenbydate'] = true;
|
||||
} else if ($gradegrade->is_hidden()) {
|
||||
$data['grade']['class'] = $class.' dimmed_text';
|
||||
$data['grade']['class'] = $class;
|
||||
$data['grade']['content'] = '-';
|
||||
|
||||
if ($this->canviewhidden) {
|
||||
$data['grade']['class'] .= ' dimmed_text';
|
||||
$gradeitemdata['graderaw'] = $gradeval;
|
||||
$data['grade']['content'] = grade_format_gradevalue($gradeval,
|
||||
$gradegrade->grade_item,
|
||||
@@ -697,9 +698,10 @@ class user extends grade_report {
|
||||
$data['percentage']['class'] = $class.' gradingerror';
|
||||
$data['percentage']['content'] = get_string('error');
|
||||
} else if ($gradegrade->is_hidden()) {
|
||||
$data['percentage']['class'] = $class.' dimmed_text';
|
||||
$data['percentage']['class'] = $class;
|
||||
$data['percentage']['content'] = '-';
|
||||
if ($this->canviewhidden) {
|
||||
$data['percentage']['class'] .= ' dimmed_text';
|
||||
$data['percentage']['content'] = grade_format_gradevalue(
|
||||
$gradeval,
|
||||
$gradegrade->grade_item,
|
||||
@@ -726,8 +728,9 @@ class user extends grade_report {
|
||||
$data['lettergrade']['class'] = $class.' gradingerror';
|
||||
$data['lettergrade']['content'] = get_string('error');
|
||||
} else if ($gradegrade->is_hidden()) {
|
||||
$data['lettergrade']['class'] = $class.' dimmed_text';
|
||||
$data['lettergrade']['class'] = $class;
|
||||
if (!$this->canviewhidden) {
|
||||
$data['lettergrade']['class'] .= ' dimmed_text';
|
||||
$data['lettergrade']['content'] = '-';
|
||||
} else {
|
||||
$data['lettergrade']['content'] = grade_format_gradevalue(
|
||||
@@ -757,8 +760,11 @@ class user extends grade_report {
|
||||
$data['rank']['class'] = $class.' gradingerror';
|
||||
$data['rank']['content'] = get_string('error');
|
||||
} else if ($gradegrade->is_hidden()) {
|
||||
$data['rank']['class'] = $class.' dimmed_text';
|
||||
$data['rank']['class'] = $class;
|
||||
$data['rank']['content'] = '-';
|
||||
if ($this->canviewhidden) {
|
||||
$data['rank']['class'] .= ' dimmed_text';
|
||||
}
|
||||
} else if (is_null($gradeval)) {
|
||||
// No grade, o rank.
|
||||
$data['rank']['class'] = $class;
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Do not edit this file manually! It contains just a subset of strings
|
||||
* needed during the very first steps of installation. This file was
|
||||
* generated automatically by export-installer.php (which is part of AMOS
|
||||
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
|
||||
* list of strings defined in /install/stringnames.txt.
|
||||
* {@link https://moodledev.io/general/projects/api/amos}) using the
|
||||
* list of strings defined in install/stringnames.txt file.
|
||||
*
|
||||
* @package installer
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user