Compare commits

..

116 Commits

Author SHA1 Message Date
Eloy Lafuente (stronk7) aba54964ab Moodle release 2.8.12 2016-05-08 00:23:44 +02:00
Eloy Lafuente (stronk7) 5f84553fab Merge branch 'install_28_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_28_STABLE 2016-05-08 00:23:39 +02:00
Simey Lameze f6b0de1361 MDL-53913 core_user: make parameters consistent across versions 2016-05-06 09:49:14 +08:00
Andrew Nicols 20e9dac8cb MDL-53589 badges: Correct context 2016-05-06 09:49:14 +08:00
Eloy Lafuente (stronk7) 71c7374d5d MDL-54018 timezones: Updated to 2016d 2016-05-06 09:49:13 +08:00
Frederic Massart 897f31a5d0 MDL-51369 course: Adding tests to cover restoring course info 2016-05-06 09:49:13 +08:00
Frederic Massart 12c2857486 MDL-51369 backup: Respect capabilities when restoring course info
In short, when a user is creating a new course they can set
the ID number, shortname, fullname and summary. However, when
they merge a backup into a course they need the permissions to do so.
2016-05-06 09:49:12 +08:00
Frederic Massart fada069133 MDL-53954 user: Prevent locked profile fields from being edited 2016-05-06 09:49:12 +08:00
Andrew Nicols 7873e36f0c MDL-53755 forum: Check session when marking posts 2016-05-06 09:49:11 +08:00
Andrew Nicols 6336c56259 MDL-53696 forum: Check discussion in forum 2016-05-06 09:49:11 +08:00
Dan Marsden aca2ff0ad1 MDL-53546 SCORM: Set window.opener to null 2016-05-06 09:49:11 +08:00
AMOS bot 33a358331f Automatically generated installer lang files 2016-05-05 00:05:01 +08:00
David Monllao 28908d2d6a MDL-54008 tz: Avoid using Caracas tz
Changed in May 2016.
2016-05-02 16:37:29 +08:00
AMOS bot fc8c321aa9 Automatically generated installer lang files 2016-05-02 00:04:46 +08:00
AMOS bot 5b4be737f9 Automatically generated installer lang files 2016-04-30 00:07:20 +08:00
Dan Poltawski 0e38101745 weekly release 2.8.11+ 2016-04-29 15:38:05 +01:00
Dan Poltawski 54196b7acd Merge branch 'install_28_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_28_STABLE 2016-04-29 15:38:03 +01:00
Eloy Lafuente (stronk7) 89724d0c1c MDL-53928 environment: add xmlreader requirement for 3.1 2016-04-24 01:37:37 +02:00
AMOS bot 8bc54c07a2 Automatically generated installer lang files 2016-04-13 00:04:44 +08:00
AMOS bot 7c54533cdc Automatically generated installer lang files 2016-04-07 00:05:29 +08:00
AMOS bot 34e8b2dbd0 Automatically generated installer lang files 2016-04-01 00:05:19 +08:00
Dan Poltawski d4f2c87bca weekly release 2.8.11+ 2016-03-31 14:06:48 +08:00
Dan Poltawski 2a6ff0c2be Merge branch 'install_28_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_28_STABLE 2016-03-31 14:06:45 +08:00
AMOS bot 685a238e8d Automatically generated installer lang files 2016-03-30 00:04:45 +08:00
AMOS bot c9e71927d4 Automatically generated installer lang files 2016-03-29 00:04:45 +08:00
AMOS bot 19eb7b80fa Automatically generated installer lang files 2016-03-25 00:05:00 +08:00
Eloy Lafuente (stronk7) df74d3d557 MDL-53585 timezones: Updated to 2016b 2016-03-23 13:21:50 +01:00
Eloy Lafuente (stronk7) 3ed9d1c176 Moodle release 2.8.11 2016-03-12 00:37:54 +01:00
Eloy Lafuente (stronk7) 488087cb69 Merge branch 'install_28_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_28_STABLE 2016-03-12 00:37:50 +01:00
Eloy Lafuente (stronk7) 4e5732e7fe MDL-51167 tool_monitor: fix too strict condition 2016-03-10 00:14:11 +01:00
Simey Lameze d9d8e9c3fe MDL-50705 auth_db: apply standard cleaning to all fields
Also unit tests were added to cover the new clean_data() method.
2016-03-09 18:29:09 +01:00
Simey Lameze 4ee7394c8b MDL-50705 core_user: introduce new fill_properties_cache()
Also the get_property_definition() was created to get the property without retrieve the whole definition cache and
    unit tests were created to tests those new methods.
2016-03-09 18:29:07 +01:00
Simey Lameze a0cd21cd5c MDL-53031 mod_assign: add session check on assignment plugins management 2016-03-08 19:54:43 +01:00
Jun Pataleta a0034bb017 MDL-52433 user: Remove unnecessary capability check 2016-03-08 12:24:46 +01:00
Simey Lameze 89b97390d0 MDL-51167 tool_monitor: check course visibility and user 2016-03-08 03:09:57 +01:00
Cameron Ball 190757854d MDL-52651 htmlpurifier: Append rel=noreferrer to links.
Thank you to Zachary Durber for originally working on this issue.
2016-03-08 02:10:17 +01:00
Krista Koivisto dc8421575f MDL-52774 ajax: Require authentication when getting nav branch
When getting the navigation branch data through AJAX, require
login if forcelogin is set.
2016-03-08 00:38:52 +01:00
Juan Leyva 0f989a4c70 MDL-52901 mod_assign: Check due dates in external save_submission 2016-03-08 00:14:31 +01:00
David Monllao b74d0f8404 MDL-52378 singleview: Using is_disabled instead of is_locked 2016-03-07 23:01:35 +01:00
Travis Noll 71beedee8c MDL-52378 Singleview: Exclude Grade Attribute Permissions
Singleview users must have Manage Grade permission to modify the
Exclude grade attribute.
2016-03-07 23:01:25 +01:00
Juan Leyva d63ac148b9 MDL-52808 calendar: Do not return events for hidden activities 2016-03-07 22:31:49 +01:00
David Mudrák 8f95eac163 MDL-52727 mod_data: Improve output of the form fields values
This issue mostly affects the search form fields. Submitted values for
these fields are typically obtained via optional_param() with
PARAM_NOTAGS specified as the parameter type - see parse_search_field()
methods. Such values themselves are not safe enough to be printed back
directly into the HTML as they might contain malicious code.

While working on the patch, some other places with weak protection were
detected and fixed.

In case of the itemid parameters, the s() seems to be unnecessary but it
was added anyway as an extra protection (just in case the code flow
changes or the parts of the code are re-used elsewhere).
2016-03-07 22:07:17 +01:00
AMOS bot 8e12ce7e28 Automatically generated installer lang files 2016-03-03 22:24:34 +08:00
AMOS bot 3703791954 Automatically generated installer lang files 2016-03-03 22:24:33 +08:00
AMOS bot a457f23484 Automatically generated installer lang files 2016-03-03 00:04:39 +08:00
AMOS bot 608beccda3 Automatically generated installer lang files 2016-02-28 00:04:35 +08:00
AMOS bot 51eb1032de Automatically generated installer lang files 2016-02-25 00:12:05 +08:00
AMOS bot b7d5dffc77 Automatically generated installer lang files 2016-02-24 00:04:51 +08:00
Dan Poltawski d3142bcdbe weekly release 2.8.10+ 2016-02-22 09:10:51 +00:00
Dan Poltawski 75066aabb0 Merge branch 'install_28_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_28_STABLE 2016-02-22 09:10:48 +00:00
AMOS bot 16fce86c8b Automatically generated installer lang files 2016-02-13 00:04:48 +08:00
Eloy Lafuente (stronk7) 22277cfabf MDL-51580 environment: 3.1 requirements added
Only important change is that Moodle 2.7 installed is
required to be able to upgrade to 3.1. See the issue
for opinions, votes and agreed outcomes.
2016-02-10 18:28:53 +01:00
AMOS bot 02d953d1b2 Automatically generated installer lang files 2016-02-10 00:04:34 +08:00
AMOS bot 03fb8a8769 Automatically generated installer lang files 2016-02-06 00:04:34 +08:00
AMOS bot 962bf40a1e Automatically generated installer lang files 2016-02-04 00:04:41 +08:00
AMOS bot 00c165d8f3 Automatically generated installer lang files 2016-01-28 00:04:47 +08:00
AMOS bot 54ba33e91b Automatically generated installer lang files 2016-01-26 00:04:31 +08:00
AMOS bot e96ea8d846 Automatically generated installer lang files 2016-01-25 00:04:33 +08:00
AMOS bot 3edce27167 Automatically generated installer lang files 2016-01-23 00:04:43 +08:00
AMOS bot ac60c71cb6 Automatically generated installer lang files 2016-01-19 00:05:16 +08:00
AMOS bot 63e9112aec Automatically generated installer lang files 2016-01-13 00:04:26 +08:00
Eloy Lafuente (stronk7) 2e8e92b0f1 Moodle release 2.8.10 2016-01-09 00:49:45 +01:00
Eloy Lafuente (stronk7) cd654c06a7 Merge branch 'install_28_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_28_STABLE 2016-01-09 00:49:41 +01:00
AMOS bot b25f428173 Automatically generated installer lang files 2016-01-06 00:04:28 +08:00
Juan Leyva 535fd9678f MDL-52072 enrol: Fix course visibility checks in external functions 2016-01-05 10:31:39 +00:00
Dan Poltawski 627e723096 MDL-52552 course management: insufficient cleaning of search output 2016-01-05 10:51:43 +08:00
AMOS bot 81f444886a Automatically generated installer lang files 2016-01-04 00:04:48 +08:00
AMOS bot fe3db63c77 Automatically generated installer lang files 2015-12-25 00:04:31 +08:00
AMOS bot 0b08576ea7 Automatically generated installer lang files 2015-12-20 00:05:42 +08:00
Dan Poltawski 71d630fd59 weekly release 2.8.9+ 2015-12-18 12:27:29 +00:00
Dan Poltawski ae9a34b2d4 Merge branch 'install_28_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_28_STABLE 2015-12-18 12:27:27 +00:00
Marina Glancy e0db7da9e2 MDL-52438 core: allow Moodle 3.0 to be used with PHP7 2015-12-10 17:58:01 +08:00
AMOS bot 32ea431a2f Automatically generated installer lang files 2015-12-05 00:04:59 +08:00
Eloy Lafuente (stronk7) 56068f1aeb weekly release 2.8.9+ 2015-12-03 19:41:02 +01:00
Eloy Lafuente (stronk7) bd696650b7 Merge branch 'install_28_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_28_STABLE 2015-12-03 19:40:54 +01:00
AMOS bot 9157b95733 Automatically generated installer lang files 2015-12-04 00:04:59 +08:00
AMOS bot 025ed8a332 Automatically generated installer lang files 2015-11-28 00:05:17 +08:00
John Okely 397f50e376 MDL-52260 user: Fix error when saving profile with locked field 2015-11-27 11:03:12 +08:00
AMOS bot 4a702ed500 Automatically generated installer lang files 2015-11-25 00:04:45 +08:00
Dan Poltawski b6e2489fd3 weekly release 2.8.9+ 2015-11-19 09:20:36 +00:00
Dan Poltawski fc542633e8 Merge branch 'wip-MDL-52194-m28' of https://github.com/marinaglancy/moodle into MOODLE_28_STABLE 2015-11-19 06:49:55 +00:00
Marina Glancy f988f63bc6 MDL-52194 flowplayer: do not check request
$_REQUEST variable may contain cookies in some php configurations. See also MDL-48085
2015-11-18 15:38:04 +08:00
David Monllao f0f739f4be weekly release 2.8.9+ 2015-11-13 15:27:46 +08:00
David Monllao df2527eb4a Merge branch 'install_28_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_28_STABLE 2015-11-13 15:27:44 +08:00
Eloy Lafuente (stronk7) ade73d44bf Merge branch 'MDL-51495-m28' of https://github.com/NeillM/moodle into MOODLE_28_STABLE 2015-11-11 16:17:26 +00:00
David Monllao 0fae5133a0 Merge branch 'MDL-51913_statistics_dup_1st_column_MDL28' of git://github.com/barrysspace/moodle into MOODLE_28_STABLE 2015-11-11 16:17:25 +00:00
David Monllao ff65861526 Merge branch 'MDL-51935-28' of git://github.com/dpalou/moodle into MOODLE_28_STABLE 2015-11-11 16:17:24 +00:00
Eloy Lafuente (stronk7) 7920d1f08b Merge branch 'wip-mdl-52077-m28' of https://github.com/rajeshtaneja/moodle into MOODLE_28_STABLE 2015-11-11 16:17:24 +00:00
Eloy Lafuente (stronk7) 6193543174 Merge branch 'wip-mdl-52066-m28' of https://github.com/rajeshtaneja/moodle into MOODLE_28_STABLE 2015-11-11 16:17:23 +00:00
Eloy Lafuente (stronk7) 097fe73bab Merge branch 'MDL-51686-28' of git://github.com/damyon/moodle into MOODLE_28_STABLE 2015-11-11 16:17:23 +00:00
Eloy Lafuente (stronk7) b4f7f20a74 Merge branch 'MDL-50781-28' of git://github.com/danpoltawski/moodle into MOODLE_28_STABLE 2015-11-11 16:17:22 +00:00
Eloy Lafuente (stronk7) 9856eadb1b Merge branch 'MDL-51720-28' of git://github.com/damyon/moodle into MOODLE_28_STABLE 2015-11-11 16:17:22 +00:00
AMOS bot 027baac82e Automatically generated installer lang files 2015-11-12 00:04:25 +08:00
Neill Magill 8102ded93a MDL-51495 calendar: E_WARNING in core_calendar_get_calendar_events
If a user does not have the 'moodle/calendar:manageentries' capability then an E_WARNING
can be generated by the core_calendar_external::get_calendar_events() method, that an
expected array is null

This patch creates an array that is missing when a user does not have the capability.
2015-11-11 15:23:13 +00:00
Neill Magill 7cd705334e MDL-51495 calendar: Unit test to get an individual course event
If is user requests a single event on a course via the web service they should be able to retrieve it.
2015-11-11 15:22:47 +00:00
Eloy Lafuente (stronk7) 86eaf83174 weekly release 2.8.9+ 2015-11-10 10:49:58 +01:00
Eloy Lafuente (stronk7) e8f0c133eb Merge branch 'install_28_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_28_STABLE 2015-11-10 10:49:50 +01:00
Dan Poltawski 8535cc180e MDL-52063 forum: Moved notification is not a problem
The default behaviour of $OUTPUT->notification() is to indiciate a
problem.
2015-11-10 09:38:23 +00:00
Dan Poltawski e74ff55ff5 Merge branch 'MDL-52063-28' of git://github.com/xow/moodle into MOODLE_28_STABLE 2015-11-10 09:21:33 +00:00
Dani Palou 5d2e3c1b97 MDL-51935 wiki: Add missing strings in wiki 2015-11-10 10:11:19 +01:00
Rajesh Taneja 120b3ad637 MDL-52077 unittest: Fixed string typo 2015-11-10 13:54:46 +08:00
Rajesh Taneja ed611437a6 MDL-52066 unittest: Use ics file from external repo 2015-11-10 13:43:40 +08:00
John Okely c1c1dc7a58 MDL-52063 forum: Display message when moving forum 2015-11-10 10:24:29 +08:00
AMOS bot 7511a99d0b Automatically generated installer lang files 2015-11-10 00:04:28 +08:00
Dan Poltawski 3afbdcb211 Merge branch 'MDL-51837-28' of git://github.com/junpataleta/moodle into MOODLE_28_STABLE 2015-11-09 11:33:03 +00:00
Dan Poltawski 4d47398bdc Merge branch 'MDL-51628-28' of git://github.com/damyon/moodle into MOODLE_28_STABLE 2015-11-09 11:01:43 +00:00
David Monllao f8c0d18110 Merge branch 'MDL-40245_28' of git://github.com/SWiT/moodle into MOODLE_28_STABLE 2015-11-09 16:13:46 +08:00
David Monllao d84ddfda00 Merge branch 'MDL-49473-28' of git://github.com/danpoltawski/moodle into MOODLE_28_STABLE 2015-11-09 15:13:22 +08:00
Damyon Wiese c03882584d MDL-51720 assign: Always fallback on userid as a default sort
Even when the table has no userid column (this is normally the edit column).
2015-11-05 15:36:30 +08:00
Matt Switlik d7b80c7dd4 MDL-40245 assignment: download all submissions raise time limit 2015-11-04 16:29:25 -05:00
Dan Poltawski 992591e0e1 MDL-49473 logs: ensure exported logs contain year 2015-11-03 11:38:37 +00:00
Dan Poltawski efb26ed011 MDL-50781 user: do not print useless table cell
Thanks to Maurício Severo da Silva for the patch
2015-11-03 10:53:22 +00:00
Barry Oosthuizen 9486c3fe5c MDL-51913 report_stats: Make first column unique 2015-10-26 17:27:52 +00:00
Jun Pataleta 37ccc13b0f MDL-51837 user: Check if user email is set on validation
Add a check if the user's email is set before performing validation on
the user's email address. This is to prevent the warning messages to
be shown in the case of a pending email change which causes the user's
email field to be not included in the Edit profile form.
2015-10-19 16:52:57 -05:00
Damyon Wiese cce2034d5e MDL-51628 assign: invalid hardcoded capability check
Use existing function to do the check instead.
2015-10-09 15:01:08 +08:00
Damyon Wiese 8ffc94ff69 MDL-51686 assign: Apply admin default for comment inline 2015-10-09 13:42:29 +08:00
95 changed files with 3556 additions and 2377 deletions
+140 -1
View File
@@ -1434,7 +1434,6 @@
<VENDOR name="oracle" version="10.2" />
</DATABASE>
<PHP version="5.4.4" level="required">
<RESTRICT function="restrict_php_version_7" message="unsupportedphpversion7" />
</PHP>
<PCREUNICODE level="optional">
<FEEDBACK>
@@ -1559,4 +1558,144 @@
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
<MOODLE version="3.1" requires="2.7">
<UNICODE level="required">
<FEEDBACK>
<ON_ERROR message="unicoderequired" />
</FEEDBACK>
</UNICODE>
<DATABASE level="required">
<VENDOR name="mariadb" version="5.5.31" />
<VENDOR name="mysql" version="5.5.31" />
<VENDOR name="postgres" version="9.1" />
<VENDOR name="mssql" version="10.0" />
<VENDOR name="oracle" version="10.2" />
</DATABASE>
<PHP version="5.4.4" 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="optional">
<FEEDBACK>
<ON_CHECK message="mbstringrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="curl" level="required">
<FEEDBACK>
<ON_ERROR message="curlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="openssl" level="optional">
<FEEDBACK>
<ON_CHECK message="opensslrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="tokenizer" level="optional">
<FEEDBACK>
<ON_CHECK message="tokenizerrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="xmlrpc" level="optional">
<FEEDBACK>
<ON_CHECK message="xmlrpcrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="soap" level="optional">
<FEEDBACK>
<ON_CHECK message="soaprecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="ctype" level="required">
<FEEDBACK>
<ON_ERROR message="ctyperequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="zip" level="required">
<FEEDBACK>
<ON_ERROR message="ziprequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="zlib" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="gd" level="required">
<FEEDBACK>
<ON_ERROR message="gdrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="simplexml" level="required">
<FEEDBACK>
<ON_ERROR message="simplexmlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="spl" level="required">
<FEEDBACK>
<ON_ERROR message="splrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="pcre" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="dom" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="xml" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="xmlreader" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="intl" level="optional">
<FEEDBACK>
<ON_CHECK message="intlrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="json" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="hash" level="required"/>
</PHP_EXTENSIONS>
<PHP_SETTINGS>
<PHP_SETTING name="memory_limit" value="96M" level="required">
<FEEDBACK>
<ON_ERROR message="settingmemorylimit" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="file_uploads" value="1" level="optional">
<FEEDBACK>
<ON_CHECK message="settingfileuploads" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="opcache.enable" value="1" level="optional">
<FEEDBACK>
<ON_CHECK message="opcacherecommended" />
</FEEDBACK>
</PHP_SETTING>
</PHP_SETTINGS>
<CUSTOM_CHECKS>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_storage_engine" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbstorageengine" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="question/engine/upgrade/upgradelib.php" function="quiz_attempts_upgraded" level="required">
<FEEDBACK>
<ON_ERROR message="quizattemptsupgradedmessage" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_slasharguments" level="optional">
<FEEDBACK>
<ON_CHECK message="slashargumentswarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_tables_row_format" level="optional">
<FEEDBACK>
<ON_CHECK message="unsupporteddbtablerowformat" />
</FEEDBACK>
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
</COMPATIBILITY_MATRIX>
@@ -219,10 +219,12 @@ class rules extends \table_sql implements \renderable {
if (has_capability('tool/monitor:subscribe', \context_system::instance())) {
$options[0] = get_string('site');
}
if ($courses = get_user_capability_course('tool/monitor:subscribe', null, true, 'fullname', $orderby)) {
if ($courses = get_user_capability_course('tool/monitor:subscribe', null, true, 'fullname, visible', $orderby)) {
foreach ($courses as $course) {
$options[$course->id] = format_string($course->fullname, true,
array('context' => \context_course::instance($course->id)));
$coursecontext = \context_course::instance($course->id);
if ($course->visible || has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
$options[$course->id] = format_string($course->fullname, true, array('context' => $coursecontext));
}
}
}
$url = new \moodle_url('/admin/tool/monitor/index.php');
+28
View File
@@ -314,6 +314,7 @@ class auth_plugin_db extends auth_plugin_base {
$updateuser = new stdClass();
$updateuser->id = $user->id;
$updateuser->suspended = 1;
$updateuser = $this->clean_data($updateuser);
user_update_user($updateuser, false);
$trace->output(get_string('auth_dbsuspenduser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)), 1);
}
@@ -400,6 +401,7 @@ class auth_plugin_db extends auth_plugin_base {
$updateuser = new stdClass();
$updateuser->id = $olduser->id;
$updateuser->suspended = 0;
$updateuser = $this->clean_data($updateuser);
user_update_user($updateuser);
$trace->output(get_string('auth_dbreviveduser', 'auth_db', array('name' => $username,
'id' => $olduser->id)), 1);
@@ -422,6 +424,7 @@ class auth_plugin_db extends auth_plugin_base {
$trace->output(get_string('auth_dbinsertuserduplicate', 'auth_db', array('username'=>$user->username, 'auth'=>$collision->auth)), 1);
continue;
}
$user = $this->clean_data($user);
try {
$id = user_create_user($user, false); // It is truly a new user.
$trace->output(get_string('auth_dbinsertuser', 'auth_db', array('name'=>$user->username, 'id'=>$id)), 1);
@@ -563,6 +566,7 @@ class auth_plugin_db extends auth_plugin_base {
}
if ($needsupdate) {
require_once($CFG->dirroot . '/user/lib.php');
$updateuser = $this->clean_data($updateuser);
user_update_user($updateuser);
}
return $DB->get_record('user', array('id'=>$userid, 'deleted'=>0));
@@ -888,6 +892,30 @@ class auth_plugin_db extends auth_plugin_base {
error_reporting($CFG->debug);
ob_end_flush();
}
/**
* Clean the user data that comes from an external database.
*
* @param array $user the user data to be validated against properties definition.
* @return stdClass $user the cleaned user data.
*/
public function clean_data($user) {
if (empty($user)) {
return $user;
}
foreach ($user as $field => $value) {
// Get the property parameter type and do the cleaning.
try {
$property = core_user::get_property_definition($field);
$user->$field = clean_param($value, $property['type']);
} catch (coding_exception $e) {
debugging("The property '$field' could not be cleaned.", DEBUG_DEVELOPER);
}
}
return $user;
}
}
+73
View File
@@ -374,4 +374,77 @@ class auth_db_testcase extends advanced_testcase {
$this->cleanup_auth_database();
}
/**
* Testing the clean_data() method.
*/
public function test_clean_data() {
global $DB;
$this->resetAfterTest(false);
$this->preventResetByRollback();
$this->init_auth_database();
$auth = get_auth_plugin('db');
$auth->db_init();
// Create users on external table.
$extdbuser1 = (object)array('name'=>'u1', 'pass'=>'heslo', 'email'=>'u1@example.com');
$extdbuser1->id = $DB->insert_record('auth_db_users', $extdbuser1);
// User with malicious data on the name.
$extdbuser2 = (object)array('name'=>'user<script>alert(1);</script>xss', 'pass'=>'heslo', 'email'=>'xssuser@example.com');
$extdbuser2->id = $DB->insert_record('auth_db_users', $extdbuser2);
$trace = new null_progress_trace();
// Let's test user sync make sure still works as expected..
$auth->sync_users($trace, true);
// Get the user on moodle user table.
$user2 = $DB->get_record('user', array('email'=> $extdbuser2->email, 'auth'=>'db'));
// The malicious code should be sanitized.
$this->assertEquals($user2->username, 'userscriptalert1scriptxss');
$this->assertNotEquals($user2->username, $extdbuser2->name);
// User with correct data, should be equal to external db.
$user1 = $DB->get_record('user', array('email'=> $extdbuser1->email, 'auth'=>'db'));
$this->assertEquals($extdbuser1->name, $user1->username);
$this->assertEquals($extdbuser1->email, $user1->email);
// Now, let's update the name.
$extdbuser2->name = 'user no xss anymore';
$DB->update_record('auth_db_users', $extdbuser2);
// Run sync again to update the user data.
$auth->sync_users($trace, true);
// The user information should be updated.
$user2 = $DB->get_record('user', array('username' => 'usernoxssanymore', 'auth' => 'db'));
// The spaces should be removed, as it's the username.
$this->assertEquals($user2->username, 'usernoxssanymore');
// Now let's test just the clean_data() method isolated.
// Testing PARAM_USERNAME, PARAM_NOTAGS, PARAM_RAW_TRIMMED and others.
$user3 = new stdClass();
$user3->firstname = 'John <script>alert(1)</script> Doe';
$user3->username = 'john%#&~%*_doe';
$user3->email = ' john@testing.com ';
$user3->deleted = 'no';
$user3->description = '<b>A description about myself.</b>';
$user3cleaned = $auth->clean_data($user3);
// Expected results.
$this->assertEquals($user3cleaned->firstname, 'John alert(1) Doe');
$this->assertEquals($user3cleaned->email, 'john@testing.com');
$this->assertEquals($user3cleaned->deleted, 0);
$this->assertEquals($user3->description, '<b>A description about myself.</b>');
$this->assertEquals($user3->username, 'john_doe');
// Try to clean an invalid property (fullname).
$user3->fullname = 'John Doe';
$auth->clean_data($user3);
$this->assertDebuggingCalled("The property 'fullname' could not be cleaned.");
$this->cleanup_auth_database();
}
}
+35 -8
View File
@@ -1686,27 +1686,54 @@ class restore_course_structure_step extends restore_structure_step {
*/
public function process_course($data) {
global $CFG, $DB;
$context = context::instance_by_id($this->task->get_contextid());
$userid = $this->task->get_userid();
$target = $this->get_task()->get_target();
$isnewcourse = $target != backup::TARGET_CURRENT_ADDING && $target != backup::TARGET_EXISTING_ADDING;
// When restoring to a new course we can set all the things except for the ID number.
$canchangeidnumber = $isnewcourse || has_capability('moodle/course:changeidnumber', $context, $userid);
$canchangeshortname = $isnewcourse || has_capability('moodle/course:changeshortname', $context, $userid);
$canchangefullname = $isnewcourse || has_capability('moodle/course:changefullname', $context, $userid);
$canchangesummary = $isnewcourse || has_capability('moodle/course:changesummary', $context, $userid);
$data = (object)$data;
$data->id = $this->get_courseid();
$fullname = $this->get_setting_value('course_fullname');
$shortname = $this->get_setting_value('course_shortname');
$startdate = $this->get_setting_value('course_startdate');
// Calculate final course names, to avoid dupes
// Calculate final course names, to avoid dupes.
list($fullname, $shortname) = restore_dbops::calculate_course_names($this->get_courseid(), $fullname, $shortname);
// Need to change some fields before updating the course record
$data->id = $this->get_courseid();
$data->fullname = $fullname;
$data->shortname= $shortname;
if ($canchangefullname) {
$data->fullname = $fullname;
} else {
unset($data->fullname);
}
if ($canchangeshortname) {
$data->shortname = $shortname;
} else {
unset($data->shortname);
}
if (!$canchangesummary) {
unset($data->summary);
unset($data->summaryformat);
}
// Only allow the idnumber to be set if the user has permission and the idnumber is not already in use by
// another course on this site.
$context = context::instance_by_id($this->task->get_contextid());
if (!empty($data->idnumber) && has_capability('moodle/course:changeidnumber', $context, $this->task->get_userid()) &&
$this->task->is_samesite() && !$DB->record_exists('course', array('idnumber' => $data->idnumber))) {
if (!empty($data->idnumber) && $canchangeidnumber && $this->task->is_samesite()
&& !$DB->record_exists('course', array('idnumber' => $data->idnumber))) {
// Do not reset idnumber.
} else if (!$isnewcourse) {
// Prevent override when restoring as merge.
unset($data->idnumber);
} else {
$data->idnumber = '';
}
+10 -9
View File
@@ -173,6 +173,8 @@ class core_calendar_external extends external_api {
// Let us findout courses that we can return events from.
if (!$hassystemcap) {
$courses = enrol_get_my_courses('id');
$courses = array_keys($courses);
foreach ($params['events']['courseids'] as $id) {
try {
$context = context_course::instance($id);
@@ -185,7 +187,6 @@ class core_calendar_external extends external_api {
'warningcode' => 'nopermissions',
'message' => 'No access rights in course context '.$e->getMessage().$e->getTraceAsString()
);
continue;
}
}
} else {
@@ -221,21 +222,21 @@ class core_calendar_external extends external_api {
$funcparam['courses'][] = $SITE->id;
}
// Event list does not check visibility and permissions, we'll check that later.
$eventlist = calendar_get_events($params['options']['timestart'], $params['options']['timeend'], $funcparam['users'], $funcparam['groups'],
$funcparam['courses'], true, $params['options']['ignorehidden']);
// WS expects arrays.
$events = array();
foreach ($eventlist as $id => $event) {
$events[$id] = (array) $event;
}
// We need to get events asked for eventids.
$eventsbyid = calendar_get_events_by_id($params['events']['eventids']);
foreach ($eventsbyid as $eventid => $eventobj) {
if ($eventsbyid = calendar_get_events_by_id($params['events']['eventids'])) {
$eventlist += $eventsbyid;
}
foreach ($eventlist as $eventid => $eventobj) {
$event = (array) $eventobj;
if (isset($events[$eventid])) {
continue;
}
if ($hassystemcap) {
// User can see everything, no further check is needed.
$events[$eventid] = $event;
+31
View File
@@ -363,6 +363,37 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
$this->assertEquals(1, count($events['events'])); // site.
$this->assertEquals(0, count($events['warnings']));
// Try getting a course event by its id.
$paramevents = array ('eventids' => array($courseevent->id));
$events = core_calendar_external::get_calendar_events($paramevents, $options);
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
$this->assertEquals(1, count($events['events']));
$this->assertEquals(0, count($events['warnings']));
// Now, create an activity event.
$this->setAdminUser();
$nexttime = time() + DAYSECS;
$assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'duedate' => $nexttime));
$this->setUser($user);
$paramevents = array ('courseids' => array($course->id));
$options = array ('siteevents' => true, 'userevents' => true, 'timeend' => time() + WEEKSECS);
$events = core_calendar_external::get_calendar_events($paramevents, $options);
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
$this->assertCount(5, $events['events']);
// Hide the assignment.
set_coursemodule_visible($assign->cmid, 0);
// Empty all the caches that may be affected by this change.
accesslib_clear_all_caches_for_unit_testing();
course_modinfo::clear_instance_cache();
$events = core_calendar_external::get_calendar_events($paramevents, $options);
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
// Expect one less.
$this->assertCount(4, $events['events']);
}
/**
+2 -7
View File
@@ -78,13 +78,8 @@ class core_calendar_lib_testcase extends advanced_testcase {
global $CFG;
require_once($CFG->dirroot . '/lib/cronlib.php');
// Moodle ICal URL (moodle.org events).
$presetwhat = 'all';
$presettime = 'recentupcoming';
$userid = 1;
$authtoken = 'a8bcfee2fb868a05357f650bd65dc0699b026524';
$subscriptionurl = 'https://moodle.org/calendar/export_execute.php'
. '?preset_what='.$presetwhat.'&preset_time='.$presettime.'&userid='.$userid.'&authtoken='.$authtoken;
// ICal URL from external test repo.
$subscriptionurl = $this->getExternalTestFileUrl('/ical.ics');
$subscription = new stdClass();
$subscription->eventtype = 'site';
+1 -1
View File
@@ -1130,7 +1130,7 @@ class core_course_management_renderer extends plugin_renderer_base {
$totalpages = ceil($totalcourses / $perpage);
if ($showtotals) {
if ($totalpages == 0) {
$str = get_string('nocoursesfound', 'moodle', $search);
$str = get_string('nocoursesfound', 'moodle', s($search));
} else if ($totalpages == 1) {
$str = get_string('showingacourses', 'moodle', $totalcourses);
} else {
+324
View File
@@ -0,0 +1,324 @@
<?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/>.
/**
* Course restore tests.
*
* @package core_course
* @copyright 2016 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
/**
* Course restore testcase.
*
* @package core_course
* @copyright 2016 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class core_restore_backup_testcase extends advanced_testcase {
/**
* Backup a course and return its backup ID.
*
* @param int $courseid The course ID.
* @param int $userid The user doing the backup.
* @return string
*/
protected function backup_course($courseid, $userid = 2) {
globaL $CFG;
$packer = get_file_packer('application/vnd.moodle.backup');
$bc = new backup_controller(backup::TYPE_1COURSE, $courseid, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO,
backup::MODE_GENERAL, $userid);
$bc->execute_plan();
$results = $bc->get_results();
$results['backup_destination']->extract_to_pathname($packer, "$CFG->tempdir/backup/core_course_testcase");
$bc->destroy();
unset($bc);
return 'core_course_testcase';
}
/**
* Create a role with capabilities and permissions.
*
* @param string|array $caps Capability names.
* @param int $perm Constant CAP_* to apply to the capabilities.
* @return int The new role ID.
*/
protected function create_role_with_caps($caps, $perm) {
$caps = (array) $caps;
$dg = $this->getDataGenerator();
$roleid = $dg->create_role();
foreach ($caps as $cap) {
assign_capability($cap, $perm, $roleid, context_system::instance()->id, true);
}
accesslib_clear_all_caches_for_unit_testing();
return $roleid;
}
/**
* Restore a course.
*
* @param int $backupid The backup ID.
* @param int $courseid The course ID to restore in, or 0.
* @param int $userid The ID of the user performing the restore.
* @return stdClass The updated course object.
*/
protected function restore_course($backupid, $courseid, $userid) {
global $DB;
$target = backup::TARGET_CURRENT_ADDING;
if (!$courseid) {
$target = backup::TARGET_NEW_COURSE;
$categoryid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}");
$courseid = restore_dbops::create_new_course('Tmp', 'tmp', $categoryid);
}
$rc = new restore_controller($backupid, $courseid, backup::INTERACTIVE_NO, backup::MODE_GENERAL, $userid, $target);
$target == backup::TARGET_NEW_COURSE ?: $rc->get_plan()->get_setting('overwrite_conf')->set_value(true);
$rc->execute_precheck();
$rc->execute_plan();
$course = $DB->get_record('course', array('id' => $rc->get_courseid()));
$rc->destroy();
unset($rc);
return $course;
}
/**
* Restore a course to an existing course.
*
* @param int $backupid The backup ID.
* @param int $courseid The course ID to restore in.
* @param int $userid The ID of the user performing the restore.
* @return stdClass The updated course object.
*/
protected function restore_to_existing_course($backupid, $courseid, $userid = 2) {
return $this->restore_course($backupid, $courseid, $userid);
}
/**
* Restore a course to a new course.
*
* @param int $backupid The backup ID.
* @param int $userid The ID of the user performing the restore.
* @return stdClass The new course object.
*/
protected function restore_to_new_course($backupid, $userid = 2) {
return $this->restore_course($backupid, 0, $userid);
}
public function test_restore_existing_idnumber_in_new_course() {
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$c1 = $dg->create_course(['idnumber' => 'ABC']);
$backupid = $this->backup_course($c1->id);
$c2 = $this->restore_to_new_course($backupid);
// The ID number is set empty.
$this->assertEquals('', $c2->idnumber);
}
public function test_restore_non_existing_idnumber_in_new_course() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$c1 = $dg->create_course(['idnumber' => 'ABC']);
$backupid = $this->backup_course($c1->id);
$c1->idnumber = 'BCD';
$DB->update_record('course', $c1);
// The ID number changed.
$c2 = $this->restore_to_new_course($backupid);
$this->assertEquals('ABC', $c2->idnumber);
}
public function test_restore_existing_idnumber_in_existing_course() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$c1 = $dg->create_course(['idnumber' => 'ABC']);
$c2 = $dg->create_course(['idnumber' => 'DEF']);
$backupid = $this->backup_course($c1->id);
// The ID number does not change.
$c2 = $this->restore_to_existing_course($backupid, $c2->id);
$this->assertEquals('DEF', $c2->idnumber);
$c1 = $DB->get_record('course', array('id' => $c1->id));
$this->assertEquals('ABC', $c1->idnumber);
}
public function test_restore_non_existing_idnumber_in_existing_course() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$c1 = $dg->create_course(['idnumber' => 'ABC']);
$c2 = $dg->create_course(['idnumber' => 'DEF']);
$backupid = $this->backup_course($c1->id);
$c1->idnumber = 'XXX';
$DB->update_record('course', $c1);
// The ID number has changed.
$c2 = $this->restore_to_existing_course($backupid, $c2->id);
$this->assertEquals('ABC', $c2->idnumber);
}
public function test_restore_idnumber_in_existing_course_without_permissions() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$u1 = $dg->create_user();
$managers = get_archetype_roles('manager');
$manager = array_shift($managers);
$roleid = $this->create_role_with_caps('moodle/course:changeidnumber', CAP_PROHIBIT);
$dg->role_assign($manager->id, $u1->id);
$dg->role_assign($roleid, $u1->id);
$c1 = $dg->create_course(['idnumber' => 'ABC']);
$c2 = $dg->create_course(['idnumber' => 'DEF']);
$backupid = $this->backup_course($c1->id);
$c1->idnumber = 'XXX';
$DB->update_record('course', $c1);
// The ID number does not change.
$c2 = $this->restore_to_existing_course($backupid, $c2->id, $u1->id);
$this->assertEquals('DEF', $c2->idnumber);
}
public function test_restore_course_info_in_new_course() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$c1 = $dg->create_course(['shortname' => 'SN', 'fullname' => 'FN', 'summary' => 'DESC', 'summaryformat' => FORMAT_MOODLE]);
$backupid = $this->backup_course($c1->id);
// The information is restored but adapted because names are already taken.
$c2 = $this->restore_to_new_course($backupid);
$this->assertEquals('SN_1', $c2->shortname);
$this->assertEquals('FN copy 1', $c2->fullname);
$this->assertEquals('DESC', $c2->summary);
$this->assertEquals(FORMAT_MOODLE, $c2->summaryformat);
}
public function test_restore_course_info_in_existing_course() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$c1 = $dg->create_course(['shortname' => 'SN', 'fullname' => 'FN', 'summary' => 'DESC', 'summaryformat' => FORMAT_MOODLE]);
$c2 = $dg->create_course(['shortname' => 'A', 'fullname' => 'B', 'summary' => 'C', 'summaryformat' => FORMAT_PLAIN]);
$backupid = $this->backup_course($c1->id);
// The information is restored but adapted because names are already taken.
$c2 = $this->restore_to_existing_course($backupid, $c2->id);
$this->assertEquals('SN_1', $c2->shortname);
$this->assertEquals('FN copy 1', $c2->fullname);
$this->assertEquals('DESC', $c2->summary);
$this->assertEquals(FORMAT_MOODLE, $c2->summaryformat);
}
public function test_restore_course_shortname_in_existing_course_without_permissions() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$u1 = $dg->create_user();
$managers = get_archetype_roles('manager');
$manager = array_shift($managers);
$roleid = $this->create_role_with_caps('moodle/course:changeshortname', CAP_PROHIBIT);
$dg->role_assign($manager->id, $u1->id);
$dg->role_assign($roleid, $u1->id);
$c1 = $dg->create_course(['shortname' => 'SN', 'fullname' => 'FN', 'summary' => 'DESC', 'summaryformat' => FORMAT_MOODLE]);
$c2 = $dg->create_course(['shortname' => 'A1', 'fullname' => 'B1', 'summary' => 'C1', 'summaryformat' => FORMAT_PLAIN]);
// The shortname does not change.
$backupid = $this->backup_course($c1->id);
$restored = $this->restore_to_existing_course($backupid, $c2->id, $u1->id);
$this->assertEquals($c2->shortname, $restored->shortname);
$this->assertEquals('FN copy 1', $restored->fullname);
$this->assertEquals('DESC', $restored->summary);
$this->assertEquals(FORMAT_MOODLE, $restored->summaryformat);
}
public function test_restore_course_fullname_in_existing_course_without_permissions() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$u1 = $dg->create_user();
$managers = get_archetype_roles('manager');
$manager = array_shift($managers);
$roleid = $this->create_role_with_caps('moodle/course:changefullname', CAP_PROHIBIT);
$dg->role_assign($manager->id, $u1->id);
$dg->role_assign($roleid, $u1->id);
$c1 = $dg->create_course(['shortname' => 'SN', 'fullname' => 'FN', 'summary' => 'DESC', 'summaryformat' => FORMAT_MOODLE]);
$c2 = $dg->create_course(['shortname' => 'A1', 'fullname' => 'B1', 'summary' => 'C1', 'summaryformat' => FORMAT_PLAIN]);
// The fullname does not change.
$backupid = $this->backup_course($c1->id);
$restored = $this->restore_to_existing_course($backupid, $c2->id, $u1->id);
$this->assertEquals('SN_1', $restored->shortname);
$this->assertEquals($c2->fullname, $restored->fullname);
$this->assertEquals('DESC', $restored->summary);
$this->assertEquals(FORMAT_MOODLE, $restored->summaryformat);
}
public function test_restore_course_summary_in_existing_course_without_permissions() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$u1 = $dg->create_user();
$managers = get_archetype_roles('manager');
$manager = array_shift($managers);
$roleid = $this->create_role_with_caps('moodle/course:changesummary', CAP_PROHIBIT);
$dg->role_assign($manager->id, $u1->id);
$dg->role_assign($roleid, $u1->id);
$c1 = $dg->create_course(['shortname' => 'SN', 'fullname' => 'FN', 'summary' => 'DESC', 'summaryformat' => FORMAT_MOODLE]);
$c2 = $dg->create_course(['shortname' => 'A1', 'fullname' => 'B1', 'summary' => 'C1', 'summaryformat' => FORMAT_PLAIN]);
// The summary and format do not change.
$backupid = $this->backup_course($c1->id);
$restored = $this->restore_to_existing_course($backupid, $c2->id, $u1->id);
$this->assertEquals('SN_1', $restored->shortname);
$this->assertEquals('FN copy 1', $restored->fullname);
$this->assertEquals($c2->summary, $restored->summary);
$this->assertEquals($c2->summaryformat, $restored->summaryformat);
}
}
+10 -3
View File
@@ -603,14 +603,21 @@ class core_enrol_external extends external_api {
*
* @param int $courseid
* @return array of course enrolment methods
* @throws moodle_exception
*/
public static function get_course_enrolment_methods($courseid) {
global $DB;
$params = self::validate_parameters(self::get_course_enrolment_methods_parameters(), array('courseid' => $courseid));
$coursecontext = context_course::instance($params['courseid']);
$categorycontext = $coursecontext->get_parent_context();
self::validate_context($categorycontext);
// Note that we can't use validate_context because the user is not enrolled in the course.
require_login(null, false, null, false, true);
$course = $DB->get_record('course', array('id' => $params['courseid']), '*', MUST_EXIST);
$context = context_course::instance($course->id);
if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
throw new moodle_exception('coursehidden');
}
$result = array();
$enrolinstances = enrol_get_instances($params['courseid'], true);
+9 -3
View File
@@ -52,6 +52,7 @@ class enrol_self_external extends external_api {
*
* @param int $instanceid instance id of self enrolment plugin.
* @return array instance information.
* @throws moodle_exception
*/
public static function get_instance_info($instanceid) {
global $DB, $CFG;
@@ -66,10 +67,15 @@ class enrol_self_external extends external_api {
throw new moodle_exception('invaliddata', 'error');
}
// Note that we can't use validate_context because the user is not enrolled in the course.
require_login(null, false, null, false, true);
$enrolinstance = $DB->get_record('enrol', array('id' => $params['instanceid']), '*', MUST_EXIST);
$coursecontext = context_course::instance($enrolinstance->courseid);
$categorycontext = $coursecontext->get_parent_context();
self::validate_context($categorycontext);
$course = $DB->get_record('course', array('id' => $enrolinstance->courseid), '*', MUST_EXIST);
$context = context_course::instance($course->id);
if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
throw new moodle_exception('coursehidden');
}
$instanceinfo = (array) $enrolplugin->get_enrol_info($enrolinstance);
if (isset($instanceinfo['requiredparam']->enrolpassword)) {
+13 -1
View File
@@ -47,7 +47,9 @@ class enrol_self_external_testcase extends externallib_advanced_testcase {
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
$this->assertNotEmpty($studentrole);
$course = self::getDataGenerator()->create_course();
$coursedata = new stdClass();
$coursedata->visible = 0;
$course = self::getDataGenerator()->create_course($coursedata);
// Add enrolment methods for course.
$instanceid1 = $selfplugin->add_instance($course, array('status' => ENROL_INSTANCE_ENABLED,
@@ -68,6 +70,7 @@ class enrol_self_external_testcase extends externallib_advanced_testcase {
$enrolmentmethods = $DB->get_records('enrol', array('courseid' => $course->id, 'status' => ENROL_INSTANCE_ENABLED));
$this->assertCount(3, $enrolmentmethods);
$this->setAdminUser();
$instanceinfo1 = enrol_self_external::get_instance_info($instanceid1);
$instanceinfo1 = external_api::clean_returnvalue(enrol_self_external::get_instance_info_returns(), $instanceinfo1);
@@ -95,5 +98,14 @@ class enrol_self_external_testcase extends externallib_advanced_testcase {
$this->assertEquals('Test instance 3', $instanceinfo3['name']);
$this->assertTrue($instanceinfo3['status']);
$this->assertEquals(get_string('password', 'enrol_self'), $instanceinfo3['enrolpassword']);
// Try to retrieve information using a normal user for a hidden course.
$user = self::getDataGenerator()->create_user();
$this->setUser($user);
try {
enrol_self_external::get_instance_info($instanceid3);
} catch (moodle_exception $e) {
$this->assertEquals('coursehidden', $e->errorcode);
}
}
}
+14 -1
View File
@@ -405,7 +405,9 @@ class core_enrol_externallib_testcase extends externallib_advanced_testcase {
$this->assertNotEmpty($studentrole);
$course1 = self::getDataGenerator()->create_course();
$course2 = self::getDataGenerator()->create_course();
$coursedata = new stdClass();
$coursedata->visible = 0;
$course2 = self::getDataGenerator()->create_course($coursedata);
// Add enrolment methods for course.
$instanceid1 = $selfplugin->add_instance($course1, array('status' => ENROL_INSTANCE_ENABLED,
@@ -422,6 +424,8 @@ class core_enrol_externallib_testcase extends externallib_advanced_testcase {
$enrolmentmethods = $DB->get_records('enrol', array('courseid' => $course1->id, 'status' => ENROL_INSTANCE_ENABLED));
$this->assertCount(2, $enrolmentmethods);
$this->setAdminUser();
// Check if information is returned.
$enrolmentmethods = core_enrol_external::get_course_enrolment_methods($course1->id);
$enrolmentmethods = external_api::clean_returnvalue(core_enrol_external::get_course_enrolment_methods_returns(),
@@ -451,6 +455,15 @@ class core_enrol_externallib_testcase extends externallib_advanced_testcase {
$this->assertEquals('self', $enrolmentmethod['type']);
$this->assertTrue($enrolmentmethod['status']);
$this->assertEquals('enrol_self_get_instance_info', $enrolmentmethod['wsfunction']);
// Try to retrieve information using a normal user for a hidden course.
$user = self::getDataGenerator()->create_user();
$this->setUser($user);
try {
core_enrol_external::get_course_enrolment_methods($course2->id);
} catch (moodle_exception $e) {
$this->assertEquals('coursehidden', $e->errorcode);
}
}
public function get_enrolled_users_setup($capability) {
@@ -329,6 +329,13 @@ abstract class screen {
continue;
}
// If the user submits Exclude grade elements without the proper.
// permissions then we should refuse to update.
if ($matches[1] === 'exclude' && !has_capability('moodle/grade:manage', $this->context)){
$warnings[] = get_string('nopermissions', 'error', get_string('grade:manage', 'role'));
continue;
}
$msg = $element->set($posted);
// Optional type.
@@ -141,6 +141,12 @@ abstract class tablelike extends screen {
$html .= $this->structure->get_grade_analysis_icon($grade);
}
// Singleview users without proper permissions should be presented
// disabled checkboxes for the Exclude grade attribute.
if ($field == 'exclude' && !has_capability('moodle/grade:manage', $this->context)){
$html->disabled = true;
}
$line[] = $html;
}
return $line;
@@ -35,11 +35,14 @@ use grade_grade;
* @copyright 2014 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class exclude extends grade_attribute_format implements be_checked {
class exclude extends grade_attribute_format implements be_checked, be_disabled {
/** @var string $name The name of the input */
public $name = 'exclude';
/** @var bool $disabled Is the checkbox disabled? */
public $disabled = false;
/**
* Is it checked?
*
@@ -49,6 +52,15 @@ class exclude extends grade_attribute_format implements be_checked {
return $this->grade->is_excluded();
}
/**
* Is it disabled?
*
* @return bool
*/
public function is_disabled() {
return $this->disabled;
}
/**
* Generate the element used to render the UI
*
@@ -58,7 +70,8 @@ class exclude extends grade_attribute_format implements be_checked {
return new checkbox_attribute(
$this->get_name(),
$this->get_label(),
$this->is_checked()
$this->is_checked(),
$this->is_disabled()
);
}
@@ -11,6 +11,7 @@ Feature: We can use Single view
And the following "users" exist:
| username | firstname | lastname | email | idnumber | alternatename |
| teacher1 | Teacher | 1 | teacher1@example.com | t1 | fred |
| teacher2 | No edit | 1 | teacher2@example.com | t2 | nick |
| student1 | Student | 1 | student1@example.com | s1 | james |
| student2 | Student | 2 | student1@example.com | s2 | holly |
| student3 | Student | 3 | student1@example.com | s3 | anna |
@@ -27,6 +28,7 @@ Feature: We can use Single view
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher2 | C1 | teacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
@@ -44,6 +46,10 @@ Feature: We can use Single view
And the following "grade items" exist:
| itemname | course | gradetype |
| Test grade item | C1 | Scale |
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| moodle/grade:edit | Allow | teacher | Course | C1 |
| gradereport/singleview:view | Allow | teacher | Course | C1 |
And I log in as "teacher1"
And I follow "Course 1"
And I follow "Grades"
@@ -89,6 +95,14 @@ Feature: We can use Single view
And the following should exist in the "generaltable" table:
| First name (Alternate name) Surname | Grade |
| james (Student) 1 | Very good |
And I log out
And I log in as "teacher2"
And I follow "Course 1"
And I navigate to "Grades" node in "Course administration"
And I click on "Single view" "option"
And I click on "Student 4" "option"
And the "Exclude for Test assignment one" "checkbox" should be disabled
And the "Override for Test assignment one" "checkbox" should be enabled
Scenario: Single view links work on grade report.
Given I follow "Single view for Test assignment one"
+1
View File
@@ -35,6 +35,7 @@ $string['cliansweryes'] = 'Да';
$string['cliincorrectvalueerror'] = 'Грешка, некоректна стойност "{$a->value}" за "{$a->option}"';
$string['cliincorrectvalueretry'] = 'Неправилна стойност. Моля опитайте отново';
$string['clitypevalue'] = 'Тип стойност';
$string['clitypevaluedefault'] = 'въведете стойност, натиснете Enter за да се използва стойността по подразбиране ({$a})';
$string['cliyesnoprompt'] = 'Въведете y (означава да) или n (означава не)';
$string['environmentrequireinstall'] = 'Трябва да бъде инсталиран и разрешен';
$string['environmentrequireversion'] = 'Необходима е версия {$a->needed} а Вие имате {$a->current}';
+2 -2
View File
@@ -31,6 +31,6 @@
defined('MOODLE_INTERNAL') || die();
$string['language'] = 'Език';
$string['next'] = 'Следваща';
$string['previous'] = 'Предишна';
$string['next'] = 'Още';
$string['previous'] = 'Обратно';
$string['reload'] = 'Презареждане';
+34
View File
@@ -0,0 +1,34 @@
<?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/>.
/**
* Automatically generated strings for Moodle installer
*
* 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.
*
* @package installer
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$string['thisdirection'] = 'ltr';
$string['thislanguage'] = 'Breizh';
+1 -1
View File
@@ -35,7 +35,7 @@ $string['cliansweryes'] = 'Sí';
$string['cliincorrectvalueerror'] = 'Error, valor incorrecte "{$a->value}" per a "{$a->option}"';
$string['cliincorrectvalueretry'] = 'Valor incorrecte, si us plau, torneu-ho a provar.';
$string['clitypevalue'] = 'Valor de tipus';
$string['clitypevaluedefault'] = 'valor de tipus, premeu Intro per fer servir un valor per defecte ({$a})';
$string['clitypevaluedefault'] = 'valor de tipus, premeu la tecla de retorn (<em>Enter</em>) per fer servir un valor per defecte ({$a})';
$string['cliunknowoption'] = 'Opcions invàlides:
{$a}
L\'opció --help us orientarà.';
+1 -1
View File
@@ -35,7 +35,7 @@ $string['availablelangs'] = 'Llista d\'idiomes disponibles';
$string['chooselanguagehead'] = 'Trieu un idioma';
$string['chooselanguagesub'] = 'Trieu un idioma per a la instal·lació. S\'utilitzarà també com a idioma per defecte del lloc, tot i que després podeu canviar-lo.';
$string['clialreadyconfigured'] = 'El fitxer config.php ja existeix, feu servir dmin/cli/install_database.php si voleu instal·lar aquest lloc web.';
$string['clialreadyinstalled'] = 'El fitxer config.php ja existeix, feu servir admin/cli/upgrade.php si voleu actualitzar aquest lloc web.';
$string['clialreadyinstalled'] = 'El fitxer de configuració config.php ja existeix. Feu servir admin/cli/upgrade.php si voleu actualitzar Moodle per a aquest lloc web.';
$string['cliinstallheader'] = 'Programa d\'instal·lació de línia d\'ordres de Moodle {$a}';
$string['databasehost'] = 'Servidor de base de dades:';
$string['databasename'] = 'Nom de la base de dades:';
+7 -7
View File
@@ -34,8 +34,8 @@ $string['admindirname'] = 'Adresář se soubory pro správu serveru';
$string['availablelangs'] = 'Dostupné jazykové balíčky';
$string['chooselanguagehead'] = 'Vyberte jazyk';
$string['chooselanguagesub'] = 'Zvolte si jazyk tohoto průvodce instalací. Vybraný jazyk bude též nastaven jako výchozí jazyk stránek, ale to půjde případně později změnit.';
$string['clialreadyconfigured'] = 'Soubor config.php již existuje. Spusťte admin/cli/install_database.php, pokud chcete provést instalaci databáze.';
$string['clialreadyinstalled'] = 'Soubor config.php již existuje. Spusťte admin/cli/upgrade.php, pokud chcete provést upgrade vašich stránek.';
$string['clialreadyconfigured'] = 'Konfigurační soubor config.php již existuje. Spusťte admin/cli/install_database.php, pokud chcete provést instalaci databáze.';
$string['clialreadyinstalled'] = 'Konfigurační soubor config.php již existuje. Spusťte admin/cli/upgrade.php, pokud chcete provést upgrade vašich stránek.';
$string['cliinstallheader'] = 'Moodle {$a} - průvodce instalací z příkazové řádky';
$string['databasehost'] = 'Databázový server';
$string['databasename'] = 'Název databáze';
@@ -49,19 +49,19 @@ $string['environmentsub2'] = 'Každé vydání Moodle vyžaduje určitou minimá
$string['errorsinenvironment'] = 'Kontrola serverového prostředí selhala!';
$string['installation'] = 'Instalace';
$string['langdownloaderror'] = 'Bohužel, jazyk "{$a}" se nepodařilo nainstalovat. Instalace bude pokračovat v angličtine.';
$string['memorylimithelp'] = '<p>Limit paměti pro PHP skripty je na vašem serveru momentálně nastaven na hodnotu {$a}.</p>
$string['memorylimithelp'] = '<p>Limit paměti pro PHP skripty je na vašem serveru momentálně nastaven na {$a}.</p>
<p>To může později způsobovat Moodlu problémy, zvláště při větším množství modulů a/nebo uživatelů.</p>
<p>Je-li to možné, doporučujeme vám nastavit v PHP vyšší limit, např. 40M. Můžete to provést několika způsoby:
<p>Je-li to možné, doporučujeme vám nastavit v PHP vyšší limit, např. 40M. Můžete to provést několika způsoby:</p>
<ol>
<li>Můžete-li, překompilujte PHP s volbou <i>--enable-memory-limit</i>.
Moodle si tak bude sám moci nastavit potřebný limit.</li>
<li>Máte-li přístup k souboru php.ini, změňte nastavení <b>memory_limit</b>
na hodnotu blízkou 40M. Nemáte-li taková práva, požádejte správce vašeho webového serveru, aby toto nastavení provedl on.</li>
<li>Na některých serverech můžete v kořenovém adresáři Moodlu vytvořit soubor .htaccess s následujícím řádkem:
<p><blockquote>php_value memory_limit 40M</blockquote></p>
<p>Bohužel, v některých případech tím vyřadíte z provozu <b>všechny</b> PHP stránky (při jejich prohlížení uvidíte chybová hlášení), takže budete muset soubor .htaccess zase odstranit.</li>
<blockquote><div>php_value memory_limit 40M</div></blockquote>
<p>Bohužel, v některých případech tím vyřadíte z provozu <b>všechny</b> PHP stránky (při jejich prohlížení uvidíte chybová hlášení), takže budete muset soubor .htaccess zase odstranit.</p></li>
</ol>';
$string['paths'] = 'Cesty';
$string['pathserrcreatedataroot'] = 'Datový adresář ({$a->dataroot}) nemůže být tímto průvodcem instalací vytvořen.';
@@ -79,7 +79,7 @@ $string['phpversion'] = 'Verze PHP';
$string['phpversionhelp'] = '<p>Moodle vyžaduje PHP alespoň verze 4.3.0 nebo 5.1.0 (PHP 5.0.x obsahuje množství chyb).</p>
<p>Nyní používáte PHP verze {$a}.</p>
<p>Musíte PHP upgradovat, nebo přejít k hostiteli s vyšší verzí!<br />
(U PHP 5.0.x můžete také přejít na nižší verzi 4.4.x či 4.3.x.)</p>';
(U PHP 5.0.x můžete také přejít na nižší verzi 4.4.x )</p>';
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
$string['welcomep20'] = 'Podařilo se vám úspěšně nainstalovat a spustit balíček <strong>{$a->packname} {$a->packversion}</strong>. Gratulujeme!';
$string['welcomep30'] = '<strong>{$a->installername}</strong> obsahuje aplikace k vytvoření prostředí, ve kterém bude provozován váš <strong>Moodle</strong>. Jmenovitě se jedná o:';
+1
View File
@@ -34,6 +34,7 @@ $string['admindirname'] = 'Admin-mappe';
$string['availablelangs'] = 'Tilgængelige sprogpakker';
$string['chooselanguagehead'] = 'Vælg et sprog';
$string['chooselanguagesub'] = 'Vælg et sprog til brug under installationen. Dette sprog vil også blive brugt som standardsprog på webstedet, men det kan altid ændres til et andet sprog.';
$string['clialreadyconfigured'] = 'Konfigurationsfilen config.php eksisterer allerede. Benyt venigst admin/cli/install_database.php til at installere Moodle for dette site.';
$string['clialreadyinstalled'] = 'Filen config.php eksisterer allerede, brug venligst admin/cli/upgrade.php hvis du ønsker at opgradere dette websted.';
$string['cliinstallheader'] = 'Moodle {$a} kommandolinje-installationsprogram';
$string['databasehost'] = 'Databasevært';
+34
View File
@@ -0,0 +1,34 @@
<?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/>.
/**
* Automatically generated strings for Moodle installer
*
* 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.
*
* @package installer
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$string['parentlanguage'] = 'da';
$string['thislanguage'] = 'Dansk (kursus)';
+1 -1
View File
@@ -90,7 +90,7 @@ $string['phpversionhelp'] = '<p>Moodle requiere al menos una versión de PHP 4.3
<p>¡Debe actualizar PHP o trasladarse a otro servidor con una versión más reciente de PHP!<br />
(En caso de 5.0.x podría también revertir a la versión 4.4.x)</p>';
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
$string['welcomep20'] = 'Si está viendo esta página es porque ha podido ejecutar el paquete <strong>{$a->packname} {$a->packversion}</strong> en su computadora. !Enhorabuena!';
$string['welcomep20'] = 'Si está viendo esta página es porque ha podido instalar y ejecutar exitosamente el paquete <strong>{$a->packname} {$a->packversion}</strong> en su computadora. !Enhorabuena!';
$string['welcomep30'] = 'Esta versión de <strong>{$a->installername}</strong> incluye las aplicaciones necesarias para que <strong>Moodle</strong> funcione en su computadora, principalmente:';
$string['welcomep40'] = 'El paquete también incluye <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
$string['welcomep50'] = 'El uso de todas las aplicaciones del paquete está gobernado por sus respectivas
+1 -1
View File
@@ -31,5 +31,5 @@
defined('MOODLE_INTERNAL') || die();
$string['parentlanguage'] = '';
$string['thisdirection'] = 'izq-a-der';
$string['thisdirection'] = 'ltr';
$string['thislanguage'] = 'Español - México';
+2 -2
View File
@@ -40,5 +40,5 @@ $string['cliunknowoption'] = 'Options non reconnues :
{$a}.
Utilisez l\'option --help.';
$string['cliyesnoprompt'] = 'Tapez y (pour oui) ou n (pour non)';
$string['environmentrequireinstall'] = 'doit être installé et activé';
$string['environmentrequireversion'] = 'la version {$a->needed} est requise ; vous utilisez actuellement la version {$a->current}';
$string['environmentrequireinstall'] = 'L\'extension doit être installée et activée';
$string['environmentrequireversion'] = 'La version {$a->needed} est requise ; vous utilisez actuellement la version {$a->current}';
+1 -1
View File
@@ -36,7 +36,7 @@ $string['cliincorrectvalueerror'] = 'שגיאה: ערך לא תקין
"{$a->value}" עבור "{$a->option}"';
$string['cliincorrectvalueretry'] = 'ערך שגוי, נסה שנית';
$string['clitypevalue'] = 'סוג הערך';
$string['clitypevaluedefault'] = 'סוג הערך, הקש Enter לשימוש בערך ברירת מחדל ({$a})';
$string['clitypevaluedefault'] = 'יש להזין ערך, או להקיש על כפתור Enter לשימוש בערך בררת־המחדל ({$a})';
$string['cliunknowoption'] = 'אפשרויות לא מוכרות :
{$a}
אנא השתמש באפשרות העזרה.';
+2 -2
View File
@@ -35,8 +35,8 @@ $string['cannotcreatetempdir'] = 'לא ניתן ליצור סיפרייה זמנ
$string['cannotdownloadcomponents'] = 'לא ניתן להוריד רכיבים.';
$string['cannotdownloadzipfile'] = 'לא ניתן להוריד קובץ ZIP.';
$string['cannotfindcomponent'] = 'הרכיב לא נמצא.';
$string['cannotsavemd5file'] = 'לא ניתן לשמור קובץ md5.';
$string['cannotsavezipfile'] = 'לא ניתן לשמור קובץ ZIP.';
$string['cannotsavemd5file'] = 'לא ניתן לשמור קובץ md5';
$string['cannotsavezipfile'] = 'לא ניתן לשמור קובץ ZIP';
$string['cannotunzipfile'] = 'לא ניתן לפתוח את קובץ ה-ZIP.';
$string['componentisuptodate'] = 'הרכיב מעודכן.';
$string['downloadedfilecheckfailed'] = 'נכשלה בדיקת הקובץ המורד.';
+5 -5
View File
@@ -32,8 +32,8 @@ defined('MOODLE_INTERNAL') || die();
$string['admindirname'] = 'ספריית מנהל המערכת';
$string['availablelangs'] = 'חבילות שפה זמינות';
$string['chooselanguagehead'] = 'בחר שפה';
$string['chooselanguagesub'] = 'אנא בחר שפה עבור ההתקנה בלבד. תוכל לבחור בשפה שונה לאתר ולמשתמש באחד מהמסכים הבאים.';
$string['chooselanguagehead'] = 'בחירת שפה';
$string['chooselanguagesub'] = 'יש לבחור שפה עבור ההתקנה בלבד. תוכל לבחור בשפה שונה לאתר ולמשתמש באחד מהמסכים הבאים.';
$string['clialreadyconfigured'] = 'קובץ config.php כבר קיים, אנא השתמש ב
admin/cli/install_database.php
אם ברצונך להתקין את אתר זה.';
@@ -42,7 +42,7 @@ $string['clialreadyinstalled'] = 'קובץ ה-config.php קיים כבר, אנא
$string['cliinstallheader'] = 'תוכנית התקנת Moodle {$a} בשורת הפקודה';
$string['databasehost'] = 'מסד הנתונים המארח (host)';
$string['databasename'] = 'שם מסד הנתונים';
$string['databasetypehead'] = 'בחר התקן מסד הנתונים';
$string['databasetypehead'] = 'בחירת התקן מסד הנתונים';
$string['dataroot'] = 'ספריית הנתונים';
$string['datarootpermission'] = 'הרשאות תיקיות bתונים (data)';
$string['dbprefix'] = 'Tables prefix';
@@ -104,7 +104,7 @@ $string['welcomep50'] = 'השימוש בכל היישומים בחבילה זו
<a href="http://www.opensource.org/docs/definition_plain.html">קוד פתוח</a>
והיא מופצת תחת רשיון
<a href="http://www.gnu.org/copyleft/gpl.html">GPL</a>';
$string['welcomep60'] = 'העמודים הבאים יובילו אותך בצורה פשוטה דרך כמה צעדים לעיצוב הגדרות <strong>Moodle</strong> במחשבך.
תוכל לאשר את הגדרות ברירת המחדל או, באפשרותך, לשנותם לפי צרכיך.';
$string['welcomep60'] = 'העמודים הבאים יובילו אותך בצורה פשוטה דרך כמה צעדים לקביעת הגדרות <strong>Moodle</strong> בשרת.
ניתן לאשר הגדרות בררת־המחדל או לשנותם לפי צרכיך.';
$string['welcomep70'] = 'הקש על לחצן ה"המשך" למטה כדי להמשיך עם הגדרת ה-<strong>Moodle</strong>';
$string['wwwroot'] = 'כתובת האתר';
+1
View File
@@ -32,6 +32,7 @@ defined('MOODLE_INTERNAL') || die();
$string['clianswerno'] = 'एन';
$string['cliansweryes'] = 'वाई';
$string['cliincorrectvalueerror'] = 'त्रुटि, "{$a->option}" के लिए गलत मान जो की "{$a->value}" है';
$string['cliincorrectvalueretry'] = 'ग़लत मान, कृपया पुनः प्रयास करें';
$string['clitypevalue'] = 'टाइप मूल्य';
$string['cliyesnoprompt'] = 'टाइप Y (का मतलब है हाँ) या N (का मतलब है नहीं )';
+1 -1
View File
@@ -39,4 +39,4 @@ $string['clitypevaluedefault'] = 'unesite vrijednost ili pritisnite Enter za kor
$string['cliunknowoption'] = 'Nepoznate opcije: {$a} Molimo koristite --help opciju.';
$string['cliyesnoprompt'] = 'unesite y (znači da) ili n (znači ne)';
$string['environmentrequireinstall'] = 'je neophodno instalirati/omogućiti';
$string['environmentrequireversion'] = 'neophodna inačica je {$a->needed}, a vi trenutno koristite inačicu {$a->current}';
$string['environmentrequireversion'] = 'neophodna inačica je {$a->needed}, a vi trenutno koristite inačicu {$a->current}';
+1 -1
View File
@@ -41,7 +41,7 @@ $string['cannotunzipfile'] = 'Nije moguće otpakirati datoteku';
$string['componentisuptodate'] = 'Komponenta je dostupna u svojoj najnovijoj inačici.';
$string['downloadedfilecheckfailed'] = 'Došlo je do pogreške pri provjeri preuzete datoteke';
$string['invalidmd5'] = 'Neispravna md5 datoteka';
$string['missingrequiredfield'] = 'Nedostaje neko obvezno polje';
$string['missingrequiredfield'] = 'Nedostaje neko obvezatno polje';
$string['remotedownloaderror'] = 'Nije uspjelo preuzimanje komponente na poslužitelj, provjerite postavke proxyja. Preporuča se uporaba PHP cURL dodatka.<br /><br />Ručno preuzmite datoteku s <a href="{$a->url}">{$a->url}</a> iskopirajte ju u "{$a->dest}" na poslužitelju i raspakirajte.';
$string['wrongdestpath'] = 'Pogrešna odredišna putanja.';
$string['wrongsourcebase'] = 'Pogrešna baza izvornog URL-a';
+3 -3
View File
@@ -45,12 +45,12 @@ $string['datarootpermission'] = 'Ovlasti nad mapom s podacima';
$string['dbprefix'] = 'Prefiks tablice';
$string['dirroot'] = 'Moodle mapa';
$string['environmenthead'] = 'Provjera okruženja vašeg poslužitelja ...';
$string['environmentsub2'] = 'Svaka inačica Moodle-a ima minimalne zahtjeve po pitanju odgovarajuće PHP inačice i nekoliko obveznih PHP ekstenzija.
$string['environmentsub2'] = 'Svaka inačica Moodle-a ima minimalne zahtjeve po pitanju odgovarajuće PHP inačice i nekoliko obvezatnih PHP ekstenzija.
Puna provjera okruženja se obavlja prije svake instalacije ili nadogradnje postojeće inačice. Ako ne znate kako instalirati novu inačicu ili omogućiti PHP ekstenzije, kontaktirajte administratora vašeg poslužitelja.';
$string['errorsinenvironment'] = 'Pogreške u okruženju poslužitelja!';
$string['installation'] = 'Instalacija';
$string['langdownloaderror'] = 'Nažalost, jezik "{$a}" nije instaliran. Proces instalacije će biti nastavljen na engleskom jeziku.';
$string['memorylimithelp'] = '<p>PHP ograničenje memorije na poslužitelju je trenutno podešeno na {$a}.</p>
$string['memorylimithelp'] = '<p>PHP ograničenje memorije na poslužitelju je trenutno podešeno na {$a}.</p>
<p>Ova postavka može kasnije rezultirati memorijskim problemima na vašem Moodle sustavu, posebno ako imate veći broj omogućenih modula i/ili veći broj korisnika.</p>
@@ -78,7 +78,7 @@ $string['pathsunsecuredataroot'] = 'Podatkovna (dataroot) mapa nije sigurna';
$string['pathswrongadmindir'] = 'Admin mapa ne postoji';
$string['phpextension'] = 'PHP ekstenzija {$a}';
$string['phpversion'] = 'PHP inačica';
$string['phpversionhelp'] = '<p>Moodle zahtijeva najmanje PHP inačicu 4.3.0 ili 5.1.0 (5.0.x funkcionira uz brojne uočene probleme).</p> <p>Trenutno imate inačicu {$a}</p> <p>Morate nadograditi PHP ili premestiti Moodle instalaciju na web poslužitelj s novijom inačicom PHP-a!</br> (U slučaju inačice 5.0.x bilo bi najbolje da je vratite na inačicu 4.4.x)</p>';
$string['phpversionhelp'] = '<p>Moodle zahtijeva najmanje PHP inačicu 4.3.0 ili 5.1.0 (5.0.x funkcionira uz brojne uočene probleme).</p> <p>Trenutno imate inačicu {$a}</p> <p>Morate nadograditi PHP ili premestiti Moodle instalaciju na web poslužitelj s novijom inačicom PHP-a!</br> (U slučaju inačice 5.0.x bilo bi najbolje da je vratite na inačicu 4.4.x)</p>';
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
$string['welcomep20'] = 'Prikazana vam je ova stranica jer ste uspješno instalirali i pokrenuli <strong>{$a->packname} {$a->packversion}</strong> paket na svom poslužitelju. Čestitamo!';
$string['welcomep30'] = 'Ova inačica <strong>{$a->installername}</strong> uključuje aplikacije za stvaranje okruženja u kojem će sustav <strong>Moodle</strong> uspješno funkcionirati, konkretno:';
+1 -1
View File
@@ -31,7 +31,7 @@
defined('MOODLE_INTERNAL') || die();
$string['admindirname'] = 'Administratoriaus katalogas';
$string['availablelangs'] = 'Galimų kalbų sąrašas';
$string['availablelangs'] = 'Galimi kalbų paketai';
$string['chooselanguagehead'] = 'Pasirinkite kalbą';
$string['chooselanguagesub'] = 'Pasirinkite diegimo kalbą. Ši kalba bus naudojama ir kaip numatytoji svetainės kalba, nors vėliau ją bus galima pakeisti.';
$string['clialreadyconfigured'] = 'Failas config.php jau yra, prašau naudoti admin/cli/install_database.php jei norite įrašyti šią svetainę.';
+1
View File
@@ -33,3 +33,4 @@ defined('MOODLE_INTERNAL') || die();
$string['language'] = 'Јазик';
$string['next'] = 'Следно';
$string['previous'] = 'Претходно';
$string['reload'] = 'Вчитај повторно';
+1 -1
View File
@@ -42,7 +42,7 @@ $string['cannotsavemd5file'] = 'Enregistrament del fichièr md5 impossible';
$string['cannotsavezipfile'] = 'Enregistrament del fichièr ZIP impossible';
$string['cannotunzipfile'] = 'Descompression del fichièr ZIP impossibla';
$string['componentisuptodate'] = 'Lo component es a jorn';
$string['dmlexceptiononinstall'] = '<p>Una error de banca de donadas s\'es produsida [{$a->errorcode}].<br />{$a->debuginfo}</p>';
$string['dmlexceptiononinstall'] = '<p>Una error de banca de donadas s\'es producha [{$a->errorcode}].<br />{$a->debuginfo}</p>';
$string['downloadedfilecheckfailed'] = 'La verificacion del fichièr telecargat a fracassat';
$string['invalidmd5'] = 'Lo còde de contraròtle md5 es pas valid';
$string['missingrequiredfield'] = 'Un camp obligatòri es pas completat';
+34
View File
@@ -0,0 +1,34 @@
<?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/>.
/**
* Automatically generated strings for Moodle installer
*
* 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.
*
* @package installer
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$string['thisdirection'] = 'ltr';
$string['thislanguage'] = 'ଓଡ଼ିଆ';
+1 -1
View File
@@ -44,7 +44,7 @@ $string['dmlexceptiononinstall'] = '<p>Ocorreu um erro de base de dados [{$a->er
$string['downloadedfilecheckfailed'] = 'A verificação do ficheiro descarregado falhou.';
$string['invalidmd5'] = 'A variável de verificação está errada - tente novamente.';
$string['missingrequiredfield'] = 'Um dos campos obrigatórios está em falta';
$string['remotedownloaderror'] = 'O download do componente para o servidor falhou. Verifique as configurações do proxy. A instalação da extensão cURL do PHP é muito recomendada.<br /><br />Terá de fazer manualmente o download do ficheiro <a href="{$a->url}">{$a->url}</a>, copiá-lo para a pasta "{$a->dest}" no seu servidor e descompactá-lo';
$string['remotedownloaderror'] = 'Não foi possível descarregar o componente para o servidor. Verifique as configurações do proxy. A instalação da extensão cURL do PHP é muito recomendada.<br /><br />Terá de descarregar manualmente o ficheiro <a href="{$a->url}">{$a->url}</a>, copiá-lo para a pasta "{$a->dest}" no seu servidor e descompactá-lo';
$string['wrongdestpath'] = 'Caminho de destino errado';
$string['wrongsourcebase'] = 'Base do URL de origem errada';
$string['wrongzipfilename'] = 'Nome de ficheiro ZIP errado';
+2 -2
View File
@@ -48,14 +48,14 @@ $string['environmenthead'] = 'A verificar sistema...';
$string['environmentsub2'] = 'Cada nova versão do Moodle tem pré-requisitos mínimos relativamente à versão do PHP e extensões necessárias para o seu correto funcionamento. Estes pré-requisitos são verificados sempre que o Moodle é instalado ou atualizado. Contacte o administrador do servidor caso seja necessário atualizar a versão do PHP ou instalar novas extensões.';
$string['errorsinenvironment'] = 'A verificação do sistema falhou!';
$string['installation'] = 'Instalação';
$string['langdownloaderror'] = 'Não foi possível instalar o idioma <b>{$a}</b> por falha no download. O processo de instalação continuará em Inglês.';
$string['langdownloaderror'] = 'Não foi possível descarregar o idioma <b>{$a}</b> . O processo de instalação continuará em Inglês.';
$string['memorylimithelp'] = '<p>O limite de memória para o PHP definido atualmente no servidor é <b>{$a}</b>.</p><p>Um número elevado de módulos em utilização ou de utilizadores registados pode fazer com que o Moodle apresente problemas de falta de memória.</p><p>É recomendado que o PHP seja configurado com um limite de memória de pelo menos 40MB. Esta configuração pode ser definida de diversas formas:</p><ol><li>Compilação do PHP com o parâmetro <b>--enable-memory-limit</b>. Esta definição permitirá ao próprio Moodle definir o valor a utilizar.</li><li>Alteração do parâmetro <b>memory_limit</b> no ficheiro de configuração do PHP para um valor igual ou superior a 40MB.</li><li>Criação de um ficheiro <b>.htaccess</b> na raiz da pasta do Moodle com a linha <b>php_value memory_limit 40M</b><p>ATENÇÃO: Em alguns servidores esta configuração impedirá o funcionamento de <b>todas</b> as páginas PHP. Nestes casos, não poderá ser utilizado o ficheiro <b>.htaccess</b>.</p></li></ol>';
$string['paths'] = 'Caminhos';
$string['pathserrcreatedataroot'] = 'O programa de instalação não conseguiu criar a pasta de dados <b>{$a->dataroot}</b>.';
$string['pathshead'] = 'Confirmar caminhos';
$string['pathsrodataroot'] = 'A pasta de dados não tem permissões de escrita.';
$string['pathsroparentdataroot'] = 'A pasta pai <b>{$a->parent}</b> não tem permissões de escrita. O programa de instalação não conseguiu criar a pasta <b>{$a->dataroot}</b>.';
$string['pathssubadmindir'] = 'Alguns servidores Web utilizam a pasta <strong>admin</strong> em URLs especiais de acesso a funcionalidades especiais, como é o caso de painéis de controlo. Algumas situações podem criar conflitos com a localização normal das páginas de administração do Moodle. Estes problemas podem ser resolvidos renomeando a pasta <strong>admin</strong> na instalação do Moodle e indicando aqui o novo nome a utilizar. Por exemplo:<br /><br /><b>moodleadmin</b><br /><br />Esta ação resolverá os problemas de acesso dos links para as funcionalidades de administração do Moodle.';
$string['pathssubadmindir'] = 'Alguns servidores Web utilizam a pasta <strong>admin</strong> em URLs especiais de acesso a funcionalidades especiais, como é o caso de painéis de controlo. Algumas situações podem criar conflitos com a localização normal das páginas de administração do Moodle. Estes problemas podem ser resolvidos renomeando a pasta <strong>admin</strong> na instalação do Moodle e indicando aqui o novo nome a utilizar. Por exemplo:<br /><br /><b>moodleadmin</b><br /><br />Esta ação resolverá os problemas de acesso das hiperligações para as funcionalidades de administração do Moodle.';
$string['pathssubdataroot'] = '<p>Uma diretoria em que o Moodle irá armazenar todo o conteúdo de ficheiros enviados pelos utilizadores.</p>
<p>Esta diretoria deve ser legível e gravável pelo utilizador do servidor web (geralmente \'www-data\', \'nobody\', ou \'apache\').</p>
<p>Não deve ser diretamente acessível através da web.</p>
+4
View File
@@ -30,6 +30,9 @@
defined('MOODLE_INTERNAL') || die();
$string['cannotcreatedboninstall'] = '<p>Nu se poate crea baza de date.</p>
<p>Baza de date specificată nu există iar utilizatorul nu are permisiunea de a crea baza de date.</p>
<p>Admistratorul site-ului trebuie să verfice configurarea bazei de date.</p>';
$string['cannotcreatelangdir'] = 'Nu se poate crea un director lang';
$string['cannotcreatetempdir'] = 'Nu se poate crea director temporar';
$string['cannotdownloadcomponents'] = 'Nu se pot descărca componente';
@@ -39,6 +42,7 @@ $string['cannotsavemd5file'] = 'Fişierul md5 nu poate fi salvat';
$string['cannotsavezipfile'] = 'Arhiva ZIP nu poate fi salvată';
$string['cannotunzipfile'] = 'Arhiva nu poate fi deschisă';
$string['componentisuptodate'] = 'Componenta este actualizată';
$string['dmlexceptiononinstall'] = '<p>A apărut o problemă la baza de date [{$a->errorcode}].<br />{$a->debuginfo}</p>';
$string['downloadedfilecheckfailed'] = 'Verificarea fişierului descărcat a eşuat';
$string['invalidmd5'] = 'md5 incorect';
$string['missingrequiredfield'] = 'Lipseşte un câmp obligatoriu';
+17
View File
@@ -34,6 +34,9 @@ $string['admindirname'] = 'Director Admin';
$string['availablelangs'] = 'Pachete de limbă disponibile';
$string['chooselanguagehead'] = 'Selectare limbă';
$string['chooselanguagesub'] = 'Vă rugăm selectaţi limba pentru interfaţa de instalare, limba selectată va fi folosită EXCLUSIV în cadrul procedurii de instalare. Ulterior veţi putea selecta limba în care doriţi să fie afişată interfaţa.';
$string['clialreadyconfigured'] = 'Fișierul de configurare';
$string['clialreadyinstalled'] = 'Fișierul de configurare config.php există deja. Vă rugăm să folosiți dmin/cli/install_database.php to pentru a upgrada Moodle pentru acest site.';
$string['cliinstallheader'] = 'Program command line installation Moodle {$a}';
$string['databasehost'] = 'Gazdă baza de date';
$string['databasename'] = 'Nume baza de date';
$string['databasetypehead'] = 'Alegere driver baza de date';
@@ -42,10 +45,24 @@ $string['datarootpermission'] = 'Permisiuni directoare date';
$string['dbprefix'] = 'Prefix tabele';
$string['dirroot'] = 'Director Moodle';
$string['environmenthead'] = 'Se verifică mediul...';
$string['environmentsub2'] = 'Fiecare versiune Moodle are o anumită cerință minimă PHP și un număr de extensii PHP obligatorii.
Verificarea completă a mediului se face înainte de fiecare instalare și upgrade. Vă rugăm să contactați administratorul serverului, dacă nu știți cum se instalează noua versiune sau dacă activați extensiile PHP.';
$string['errorsinenvironment'] = 'Verificarea mediului eșuată!';
$string['installation'] = 'Instalare';
$string['langdownloaderror'] = 'Din păcate, limba "{$a}" nu a putut fi descărcată. Procesul de instalare va continua în limba engleză.';
$string['paths'] = 'Căi';
$string['pathserrcreatedataroot'] = 'Data directory ({$a->dataroot}) nu poate fi creat de către installer.';
$string['pathshead'] = 'Confirmare căi';
$string['pathsrodataroot'] = 'Directorul dataroot nu poate fi scris.';
$string['pathssubdirroot'] = '<p>Calea completă către directorul care conține codul Moodle .</p>';
$string['pathsunsecuredataroot'] = 'Locația dataroot nu este sigură';
$string['pathswrongadmindir'] = 'Directorul admin nu există';
$string['phpextension'] = 'extensie PHP {$a}';
$string['phpversion'] = 'Versiune PHP';
$string['phpversionhelp'] = '<p>Moodle necesită o versiune PHP de cel puțin 4.3.0 or 5.1.0 (5.0.x are un număr de probleme cunscute).</p>
<p>Momentan rulați versiunea {$a}</p>
<p>Trebuie să upgradați PHP sau să îl mutați pe o gazdă cu o nouă versiune de PHP!<br />
(În cazul 5.0.x puteți, de asemenea, să downgradați la versiunea 4.4.x)</p>';
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
$string['welcomep40'] = 'Pachetul include și <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
$string['wwwroot'] = 'Adresă Web';
+1
View File
@@ -40,6 +40,7 @@ $string['databasehost'] = 'Gostitelj podatkovne baze';
$string['databasename'] = 'Ime podatkovne baze';
$string['databasetypehead'] = 'Izberite gonilnik podatkovne baze';
$string['dataroot'] = 'Imenik za podatke';
$string['datarootpermission'] = 'Pravice za podatkovno mapo';
$string['dbprefix'] = 'Predpona tabel';
$string['dirroot'] = 'Imenik Moodle';
$string['environmenthead'] = 'Preverjanje vašega okolja ...';
+2 -2
View File
@@ -34,9 +34,9 @@ $string['clianswerno'] = 'n';
$string['cliansweryes'] = 'y';
$string['cliincorrectvalueerror'] = 'ผิดพลาด, ค่าต่อไปนี้ไม่ถูกต้อง "{$a->value}" สำหรับ "{$a->option}"';
$string['cliincorrectvalueretry'] = 'ค่าไม่ถูกต้องกรุณาลองใหม่อีกครั้ง';
$string['clitypevalue'] = 'ประเภทของค่า';
$string['clitypevalue'] = 'พิมพ์ค่า';
$string['clitypevaluedefault'] = 'ประเภทของค่า กด Enter หากต้องการใช้ค่าที่ตั้งไว้ ({$a})';
$string['cliunknowoption'] = 'ตัวเลือกที่ไม่สามารถระบุได้ : {$a}';
$string['cliunknowoption'] = 'ตัวเลือกที่ไม่สามารถระบุได้ : {$a} กรุณาเลือก การช่วยเหลือ';
$string['cliyesnoprompt'] = 'พิมพ์ y (สำหรับ ใช่) หรือ n (สำหรับ ไม่)';
$string['environmentrequireinstall'] = 'ต้องการเพื่อทำการติดตั้ง/เปิดใช้งาน';
$string['environmentrequireversion'] = 'ต้องการเวอร์ชัน {$a->needed} ขณะนี้ท่านกำลังใช้งานเวอร์ชัน {$a->current}';
+1
View File
@@ -33,3 +33,4 @@ defined('MOODLE_INTERNAL') || die();
$string['language'] = 'ภาษาที่ใช้ในเว็บ';
$string['next'] = 'ต่อไป';
$string['previous'] = 'หน้าก่อน';
$string['reload'] = 'โหลดใหม่';
+2 -1
View File
@@ -39,10 +39,11 @@ $string['cannotsavemd5file'] = '无法保存 md5 文件';
$string['cannotsavezipfile'] = '无法保存 ZIP 文件';
$string['cannotunzipfile'] = '无法解压文件';
$string['componentisuptodate'] = '组件已经是最新的了';
$string['dmlexceptiononinstall'] = '<p>发生了一个数据库错误[{$a->errorcode}].<br />{$a->debuginfo}</p>';
$string['downloadedfilecheckfailed'] = '下载文件检查失败';
$string['invalidmd5'] = '无效的 md5';
$string['missingrequiredfield'] = '缺少了必需的字段';
$string['remotedownloaderror'] = '下载组件至服务器失败,请校验代理设置,推荐安装 PHP cURL 扩展。<br /><br />您必须手动下载下载<a href="{$a->url}">{$a->url}</a> ,拷贝至服务器上的“{$a->dest}”并解压至此。';
$string['remotedownloaderror'] = '<p>下载组件至服务器失败,请校验代理设置,推荐安装 PHP cURL 扩展。</p> <p>您必须手动下载下载<a href="{$a->url}">{$a->url}</a> ,拷贝至服务器上的“{$a->dest}”并解压至此。</p>';
$string['wrongdestpath'] = '错误的目标路径';
$string['wrongsourcebase'] = '错误的源 URL 基地址。';
$string['wrongzipfilename'] = '错误的 ZIP 文件名。';
+4
View File
@@ -32,6 +32,10 @@ require_once(dirname(__FILE__) . '/../../config.php');
/** Include course lib for its functions */
require_once($CFG->dirroot.'/course/lib.php');
if (!empty($CFG->forcelogin)) {
require_login();
}
try {
// Start buffer capture so that we can `remove` any errors
ob_start();
+1 -6
View File
@@ -1141,12 +1141,7 @@ function profile_display_badges($userid, $courseid = 0) {
global $CFG, $PAGE, $USER, $SITE;
require_once($CFG->dirroot . '/badges/renderer.php');
// Determine context.
if (isloggedin()) {
$context = context_user::instance($USER->id);
} else {
$context = context_system::instance();
}
$context = context_user::instance($userid);
if ($USER->id == $userid || has_capability('moodle/badges:viewotherbadges', $context)) {
$records = badges_get_user_badges($userid, $courseid, null, null, null, true);
+103
View File
@@ -49,6 +49,9 @@ class core_user {
/** @var stdClass keep record of support user */
public static $supportuser = false;
/** @var array store user fields properties cache. */
protected static $propertiescache = null;
/**
* Return user object from db or create noreply or support user,
* if userid matches corse_user::NOREPLY_USER or corse_user::SUPPORT_USER
@@ -238,4 +241,104 @@ class core_user {
return true;
}
}
/**
* Definition of user profile fields and the expected parameter type for data validation.
*
* @return void
*/
protected static function fill_properties_cache() {
if (self::$propertiescache !== null) {
return;
}
// Array of user fields properties and expected parameters.
// Every new field on the user table should be added here otherwise it won't be validated.
$fields = array();
$fields['id'] = array('type' => PARAM_INT);
$fields['auth'] = array('type' => PARAM_AUTH);
$fields['confirmed'] = array('type' => PARAM_BOOL);
$fields['policyagreed'] = array('type' => PARAM_BOOL);
$fields['deleted'] = array('type' => PARAM_BOOL);
$fields['suspended'] = array('type' => PARAM_BOOL);
$fields['mnethostid'] = array('type' => PARAM_INT);
$fields['username'] = array('type' => PARAM_USERNAME);
$fields['password'] = array('type' => PARAM_RAW);
$fields['idnumber'] = array('type' => PARAM_RAW);
$fields['firstname'] = array('type' => PARAM_NOTAGS);
$fields['lastname'] = array('type' => PARAM_NOTAGS);
$fields['surname'] = array('type' => PARAM_NOTAGS);
$fields['email'] = array('type' => PARAM_RAW_TRIMMED);
$fields['emailstop'] = array('type' => PARAM_INT);
$fields['icq'] = array('type' => PARAM_NOTAGS);
$fields['skype'] = array('type' => PARAM_NOTAGS);
$fields['aim'] = array('type' => PARAM_NOTAGS);
$fields['yahoo'] = array('type' => PARAM_NOTAGS);
$fields['msn'] = array('type' => PARAM_NOTAGS);
$fields['phone1'] = array('type' => PARAM_NOTAGS);
$fields['phone2'] = array('type' => PARAM_NOTAGS);
$fields['institution'] = array('type' => PARAM_TEXT);
$fields['department'] = array('type' => PARAM_TEXT);
$fields['address'] = array('type' => PARAM_TEXT);
$fields['city'] = array('type' => PARAM_TEXT);
$fields['country'] = array('type' => PARAM_ALPHA);
$fields['lang'] = array('type' => PARAM_LANG);
$fields['calendartype'] = array('type' => PARAM_NOTAGS);
$fields['theme'] = array('type' => PARAM_THEME);
$fields['timezone'] = array('type' => PARAM_TIMEZONE);
$fields['firstaccess'] = array('type' => PARAM_INT);
$fields['lastaccess'] = array('type' => PARAM_INT);
$fields['lastlogin'] = array('type' => PARAM_INT);
$fields['currentlogin'] = array('type' => PARAM_INT);
$fields['lastip'] = array('type' => PARAM_NOTAGS);
$fields['secret'] = array('type' => PARAM_RAW);
$fields['picture'] = array('type' => PARAM_INT);
$fields['url'] = array('type' => PARAM_URL);
$fields['description'] = array('type' => PARAM_RAW);
$fields['descriptionformat'] = array('type' => PARAM_INT);
$fields['mailformat'] = array('type' => PARAM_INT);
$fields['maildigest'] = array('type' => PARAM_INT);
$fields['maildisplay'] = array('type' => PARAM_INT);
$fields['autosubscribe'] = array('type' => PARAM_INT);
$fields['trackforums'] = array('type' => PARAM_INT);
$fields['timecreated'] = array('type' => PARAM_INT);
$fields['timemodified'] = array('type' => PARAM_INT);
$fields['trustbitmask'] = array('type' => PARAM_INT);
$fields['imagealt'] = array('type' => PARAM_TEXT);
$fields['lastnamephonetic'] = array('type' => PARAM_NOTAGS);
$fields['firstnamephonetic'] = array('type' => PARAM_NOTAGS);
$fields['middlename'] = array('type' => PARAM_NOTAGS);
$fields['alternatename'] = array('type' => PARAM_NOTAGS);
self::$propertiescache = $fields;
}
/**
* Get properties of a user field.
*
* @param string $property property name to be retrieved.
* @throws coding_exception if the requested property name is invalid.
* @return array the property definition.
*/
public static function get_property_definition($property) {
self::fill_properties_cache();
if (!array_key_exists($property, self::$propertiescache)) {
throw new coding_exception('Invalid property requested.');
}
return self::$propertiescache[$property];
}
/**
* Clean the properties cache.
*
* During unit tests we need to be able to reset all caches so that each new test starts in a known state.
* Intended for use only for testing, phpunit calls this before every test.
*/
public static function reset_caches() {
self::$propertiescache = null;
}
}
+1 -1
View File
@@ -36,7 +36,7 @@ function flowplayer_send_flash_content($filename) {
// Note: Do not use any fancy APIs here, this must work in all supported versions.
// No url params.
if (!empty($_GET) or !empty($_POST) or !empty($_REQUEST)) {
if (!empty($_GET) or !empty($_POST)) {
header("HTTP/1.1 404 Not Found");
die;
}
+66
View File
@@ -119,3 +119,69 @@ class HTMLPurifier_URIScheme_teamspeak extends HTMLPurifier_URIScheme {
}
}
/**
* A custom HTMLPurifier transformation. Adds rel="noreferrer" to all links with target="_blank".
*
* @package core
* @copyright Cameron Ball
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class HTMLPurifier_AttrTransform_Noreferrer extends HTMLPurifier_AttrTransform {
/** @var HTMLPurifier_URIParser $parser */
private $parser;
/**
* Constructor.
*/
public function __construct() {
$this->parser = new HTMLPurifier_URIParser();
}
/**
* Transforms a tags such that when a target attribute is present, rel="noreferrer" is added.
*
* Note that this will not respect Attr.AllowedRel
*
* @param array $attr Assoc array of attributes, usually from
* HTMLPurifier_Token_Tag::$attr
* @param HTMLPurifier_Config $config Mandatory HTMLPurifier_Config object.
* @param HTMLPurifier_Context $context Mandatory HTMLPurifier_Context object
* @return array Processed attribute array.
*/
public function transform($attr, $config, $context) {
// Nothing to do If we already have noreferrer in the rel attribute
if (!empty($attr['rel']) && substr($attr['rel'], 'noreferrer') !== false) {
return $attr;
}
// If _blank target attribute exists, add rel=noreferrer
if (!empty($attr['target']) && $attr['target'] == '_blank') {
$attr['rel'] = !empty($attr['rel']) ? $attr['rel'] . ' noreferrer' : 'noreferrer';
}
return $attr;
}
}
/**
* A custom HTMLPurifier module to add rel="noreferrer" attributes a tags.
*
* @package core
* @copyright Cameron Ball
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class HTMLPurifier_HTMLModule_Noreferrer extends HTMLPurifier_HTMLModule {
/** @var string $name */
public $name = 'Noreferrer';
/**
* Module setup
*
* @param HTMLPurifier_Config $config
*/
public function setup($config) {
$a = $this->addBlankElement('a');
$a->attr_transform_post[] = new HTMLPurifier_AttrTransform_Noreferrer();
}
}
+1 -1
View File
@@ -85,7 +85,7 @@ abstract class advanced_testcase extends PHPUnit_Framework_TestCase {
$debugerror = phpunit_util::display_debugging_messages();
$this->resetDebugging();
if ($debugerror) {
trigger_error('Unenxpected debugging() call detected.', E_USER_NOTICE);
trigger_error('Unexpected debugging() call detected.', E_USER_NOTICE);
}
} catch (Exception $e) {
+1
View File
@@ -202,6 +202,7 @@ class phpunit_util extends testing_util {
core_text::reset_caches();
get_message_processors(false, true);
filter_manager::reset_caches();
core_user::reset_caches();
// Reset static unit test options.
if (class_exists('\availability_date\condition', false)) {
+5 -1
View File
@@ -40,9 +40,13 @@ class core_htmlpurifier_testcase extends basic_testcase {
* Verify _blank target is allowed.
*/
public function test_allow_blank_target() {
// See MDL-52651 for an explanation as to why the rel="noreferrer" attribute is expected here.
// Also note we do not need to test links with an existing rel attribute as the HTML Purifier is configured to remove
// the rel attribute.
$text = '<a href="http://moodle.org" target="_blank">Some link</a>';
$expected = '<a href="http://moodle.org" target="_blank" rel="noreferrer">Some link</a>';
$result = format_text($text, FORMAT_HTML);
$this->assertSame($text, $result);
$this->assertSame($expected, $result);
$result = format_text('<a href="http://moodle.org" target="some">Some link</a>', FORMAT_HTML);
$this->assertSame('<a href="http://moodle.org">Some link</a>', $result);
+6 -5
View File
@@ -132,8 +132,9 @@ class core_scheduled_task_testcase extends advanced_testcase {
// We are testing a difference between $CFG->timezone and the php.ini timezone.
// GMT+8.
date_default_timezone_set('Australia/Perth');
// GMT-04:30.
$CFG->timezone = 'America/Caracas';
// GMT+04:30.
$CFG->timezone = 'Asia/Kabul';
$testclass = new \core\task\scheduled_test_task();
@@ -149,9 +150,9 @@ class core_scheduled_task_testcase extends advanced_testcase {
$userdate = userdate($nexttime);
// Should be displayed in user timezone.
// I used http://www.timeanddate.com/worldclock/fixedtime.html?msg=Moodle+Test&iso=20140314T01&p1=58
// to verify this time.
$this->assertContains('11:15 AM', core_text::strtoupper($userdate));
// I used http://www.timeanddate.com/worldclock/fixedtime.html?msg=Moodle+Test&iso=20160502T01&p1=113
// setting my location to Kathmandu to verify this time.
$this->assertContains('2:15 AM', core_text::strtoupper($userdate));
$CFG->timezone = $currenttimezonecfg;
date_default_timezone_set($currenttimezonephp);
+25
View File
@@ -116,4 +116,29 @@ class core_user_testcase extends advanced_testcase {
// Assert that a user not in the db return false.
$this->assertFalse(core_user::get_user_by_username('janedoe'));
}
/**
* Test get_property_definition() method.
*/
public function test_get_property_definition() {
// Try to get a existing property.
$properties = core_user::get_property_definition('id');
$this->assertEquals($properties['type'], PARAM_INT);
$properties = core_user::get_property_definition('username');
$this->assertEquals($properties['type'], PARAM_USERNAME);
// Invalid property.
try {
core_user::get_property_definition('fullname');
} catch (coding_exception $e) {
$this->assertRegExp('/Invalid property requested./', $e->getMessage());
}
// Empty parameter.
try {
core_user::get_property_definition('');
} catch (coding_exception $e) {
$this->assertRegExp('/Invalid property requested./', $e->getMessage());
}
}
}
+2276 -2242
View File
File diff suppressed because it is too large Load Diff
+8
View File
@@ -1,6 +1,14 @@
This files describes API changes in core libraries and APIs,
information provided here is intended especially for developers.
=== 2.8.11 ===
* The core_user::fill_properties_cache() static method has been introduced to be a reference
and allow standard user fields data validation. Right now only type validation is supported
checking it against the parameter (PARAM_*) type of the target user field. MDL-52781 is
going to add support to null/not null and choices validation, replacing the existing code to
validate the user fields in different places in a common way.
=== 2.8.8 ===
* The actionmenu hideMenu() function now expects an EventFacade object to be passed to it,
+4 -1
View File
@@ -1733,7 +1733,7 @@ function purify_html($text, $options = array()) {
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.DefinitionID', 'moodlehtml');
$config->set('HTML.DefinitionRev', 3);
$config->set('HTML.DefinitionRev', 4);
$config->set('Cache.SerializerPath', $cachedir);
$config->set('Cache.SerializerPermissions', $CFG->directorypermissions);
$config->set('Core.NormalizeNewlines', false);
@@ -1775,6 +1775,9 @@ function purify_html($text, $options = array()) {
// Use the built-in Ruby module to add annotation support.
$def->manager->addModule(new HTMLPurifier_HTMLModule_Ruby());
// Use the custom Noreferrer module.
$def->manager->addModule(new HTMLPurifier_HTMLModule_Noreferrer());
}
$purifier = new HTMLPurifier($config);
+10 -3
View File
@@ -25,11 +25,18 @@
require_once(dirname(__FILE__) . '/../../config.php');
require_once($CFG->dirroot.'/mod/assign/adminlib.php');
$subtype = required_param('subtype', PARAM_PLUGIN);
$action = optional_param('action', null, PARAM_PLUGIN);
$plugin = optional_param('plugin', null, PARAM_PLUGIN);
if (!empty($plugin)) {
require_sesskey();
}
// Create the class for this controller.
$pluginmanager = new assign_plugin_manager(required_param('subtype', PARAM_PLUGIN));
$pluginmanager = new assign_plugin_manager($subtype);
$PAGE->set_context(context_system::instance());
// Execute the controller.
$pluginmanager->execute(optional_param('action', null, PARAM_PLUGIN),
optional_param('plugin', null, PARAM_PLUGIN));
$pluginmanager->execute($action, $plugin);
+6 -3
View File
@@ -1636,9 +1636,12 @@ class mod_assign_external extends external_api {
$notices = array();
$submissiondata = (object)$params['plugindata'];
$assignment->save_submission($submissiondata, $notices);
if (!$assignment->submissions_open($USER->id)) {
$notices[] = get_string('duedatereached', 'assign');
} else {
$submissiondata = (object)$params['plugindata'];
$assignment->save_submission($submissiondata, $notices);
}
$warnings = array();
foreach ($notices as $notice) {
@@ -212,6 +212,10 @@ class assign_feedback_comments extends assign_feedback_plugin {
*/
public function get_settings(MoodleQuickForm $mform) {
$default = $this->get_config('commentinline');
if ($default === false) {
// Apply the admin default if we don't have a value yet.
$default = get_config('assignfeedback_comments', 'inline');
}
$mform->addElement('selectyesno',
'assignfeedback_comments_commentinline',
get_string('commentinline', 'assignfeedback_comments'));
+10 -2
View File
@@ -406,8 +406,6 @@ class assign_grading_table extends table_sql implements renderable {
foreach ($extrauserfields as $extrafield) {
$this->column_class($extrafield, $extrafield);
}
// We require at least one unique column for the sort.
$this->sortable(true, 'userid');
$this->no_sorting('recordid');
$this->no_sorting('finalgrade');
$this->no_sorting('userid');
@@ -1364,6 +1362,16 @@ class assign_grading_table extends table_sql implements renderable {
has_capability('moodle/grade:viewall', $context);
}
/**
* Always return a valid sort - even if the userid column is missing.
* @return array column name => SORT_... constant.
*/
public function get_sort_columns() {
$result = parent::get_sort_columns();
$result = array_merge($result, array('userid' => SORT_ASC));
return $result;
}
/**
* Override the table show_hide_link to not show for select column.
*
+4 -1
View File
@@ -2590,6 +2590,9 @@ class assign {
// More efficient to load this here.
require_once($CFG->libdir.'/filelib.php');
// Increase the server timeout to handle the creation and sending of large zip files.
core_php_time_limit::raise();
$this->require_view_grades();
// Load all users with submit.
@@ -5537,7 +5540,7 @@ class assign {
require_once($CFG->dirroot . '/mod/assign/gradingoptionsform.php');
// Need submit permission to submit an assignment.
require_capability('mod/assign:grade', $this->context);
$this->require_view_grades();
require_sesskey();
// Is advanced grading enabled?
+10
View File
@@ -928,6 +928,16 @@ class mod_assign_external_testcase extends externallib_advanced_testcase {
$this->assertEquals(0, count($result));
// Set up a due and cutoff passed date.
$instance->duedate = time() - WEEKSECS;
$instance->cutoffdate = time() - WEEKSECS;
$DB->update_record('assign', $instance);
$result = mod_assign_external::save_submission($instance->id, $submissionpluginparams);
$result = external_api::clean_returnvalue(mod_assign_external::save_submission_returns(), $result);
$this->assertCount(1, $result);
$this->assertEquals(get_string('duedatereached', 'assign'), $result[0]['item']);
}
/**
+2 -2
View File
@@ -68,7 +68,7 @@ class data_field_file extends data_field_base {
$html .= '<fieldset><legend><span class="accesshide">'.$this->field->name.'</span></legend>';
// itemid element
$html .= '<input type="hidden" name="field_'.$this->field->id.'_file" value="'.$itemid.'" />';
$html .= '<input type="hidden" name="field_'.$this->field->id.'_file" value="'.s($itemid).'" />';
$options = new stdClass();
$options->maxbytes = $this->field->param3;
@@ -92,7 +92,7 @@ class data_field_file extends data_field_base {
function display_search_field($value = '') {
return '<label class="accesshide" for="f_' . $this->field->id . '">' . $this->field->name . '</label>' .
'<input type="text" size="16" id="f_'.$this->field->id.'" name="f_'.$this->field->id.'" value="'.$value.'" />';
'<input type="text" size="16" id="f_'.$this->field->id.'" name="f_'.$this->field->id.'" value="'.s($value).'" />';
}
function generate_sql($tablealias, $value) {
+1 -1
View File
@@ -71,7 +71,7 @@ class data_field_number extends data_field_base {
function display_search_field($value = '') {
return '<label class="accesshide" for="f_'.$this->field->id.'">' . get_string('fieldname', 'data') . '</label>' .
'<input type="text" size="16" id="f_'.$this->field->id.'" name="f_'.$this->field->id.'" value="'.$value.'" />';
'<input type="text" size="16" id="f_'.$this->field->id.'" name="f_'.$this->field->id.'" value="'.s($value).'" />';
}
function parse_search_field() {
+2 -2
View File
@@ -93,7 +93,7 @@ class data_field_picture extends data_field_base {
$str .= $output->render($fm);
$str .= '<div class="mdl-left">';
$str .= '<input type="hidden" name="field_'.$this->field->id.'_file" value="'.$itemid.'" />';
$str .= '<input type="hidden" name="field_'.$this->field->id.'_file" value="'.s($itemid).'" />';
$str .= '<label for="field_'.$this->field->id.'_alttext">'.get_string('alttext','data') .'</label>&nbsp;<input type="text" name="field_'
.$this->field->id.'_alttext" id="field_'.$this->field->id.'_alttext" value="'.s($alttext).'" />';
$str .= '</div>';
@@ -123,7 +123,7 @@ class data_field_picture extends data_field_base {
function display_search_field($value = '') {
return '<label class="accesshide" for="f_'.$this->field->id.'">' . get_string('fieldname', 'data') . '</label>' .
'<input type="text" size="16" id="f_'.$this->field->id.'" name="f_'.$this->field->id.'" value="'.$value.'" />';
'<input type="text" size="16" id="f_'.$this->field->id.'" name="f_'.$this->field->id.'" value="'.s($value).'" />';
}
function parse_search_field() {
+1 -1
View File
@@ -27,7 +27,7 @@ class data_field_text extends data_field_base {
var $type = 'text';
function display_search_field($value = '') {
return '<label class="accesshide" for="f_' . $this->field->id . '">'. $this->field->name.'</label>' . '<input type="text" size="16" id="f_'.$this->field->id.'" name="f_'.$this->field->id.'" value="'.$value.'" />';
return '<label class="accesshide" for="f_' . $this->field->id . '">'. $this->field->name.'</label>' . '<input type="text" size="16" id="f_'.$this->field->id.'" name="f_'.$this->field->id.'" value="'.s($value).'" />';
}
function parse_search_field() {
+2 -2
View File
@@ -121,7 +121,7 @@ class data_field_textarea extends data_field_base {
}
$editor->set_text($text);
$editor->use_editor($field, $options, $fpoptions);
$str .= '<input type="hidden" name="'.$field.'_itemid" value="'.$draftitemid.'" />';
$str .= '<input type="hidden" name="'.$field.'_itemid" value="'.s($draftitemid).'" />';
$str .= '<div><textarea id="'.$field.'" name="'.$field.'" rows="'.$this->field->param3.'" cols="'.$this->field->param2.'" spellcheck="true">'.s($text).'</textarea></div>';
$str .= '<div><label class="accesshide" for="' . $field . '_content1">' . get_string('format') . '</label>';
$str .= '<select id="' . $field . '_content1" name="'.$field.'_content1">';
@@ -139,7 +139,7 @@ class data_field_textarea extends data_field_base {
function display_search_field($value = '') {
return '<label class="accesshide" for="f_' . $this->field->id . '">' . $this->field->name . '</label>' .
'<input type="text" size="16" id="f_'.$this->field->id.'" name="f_'.$this->field->id.'" value="'.$value.'" />';
'<input type="text" size="16" id="f_'.$this->field->id.'" name="f_'.$this->field->id.'" value="'.s($value).'" />';
}
function parse_search_field() {
+3 -2
View File
@@ -54,7 +54,7 @@ class data_field_url extends data_field_base {
$str .= '<table><tr><td align="right">';
$str .= get_string('url','data').':</td><td>';
$str .= '<label class="accesshide" for="' . $fieldid . '">'. $this->field->name .'</label>';
$str .= '<input type="text" name="field_'.$this->field->id.'_0" id="'.$fieldid.'" value="'.$url.'" size="60" />';
$str .= '<input type="text" name="field_'.$this->field->id.'_0" id="'.$fieldid.'" value="'.s($url).'" size="60" />';
$str .= '<button id="filepicker-button-'.$options->client_id.'" style="display:none">'.$straddlink.'</button></td></tr>';
$str .= '<tr><td align="right">'.get_string('text','data').':</td><td><input type="text" name="field_'.$this->field->id.'_1" id="field_'.$this->field->id.'_1" value="'.s($text).'" size="60" /></td></tr>';
$str .= '</table>';
@@ -79,7 +79,7 @@ class data_field_url extends data_field_base {
function display_search_field($value = '') {
return '<label class="accesshide" for="f_'.$this->field->id.'">' . get_string('fieldname', 'data') . '</label>' .
'<input type="text" size="16" id="f_'.$this->field->id.'" name="f_'.$this->field->id.'" value="'.$value.'" />';
'<input type="text" size="16" id="f_'.$this->field->id.'" name="f_'.$this->field->id.'" value="'.s($value).'" />';
}
function parse_search_field() {
@@ -114,6 +114,7 @@ class data_field_url extends data_field_base {
if ($this->field->param3) {
// param3 defines whether this URL should open in a new window.
$attributes['target'] = '_blank';
$attributes['rel'] = 'noreferrer';
}
if (empty($text)) {
+2 -2
View File
@@ -1715,9 +1715,9 @@ function data_print_preference_form($data, $perpage, $search, $sort='', $order='
$fn = !empty($search_array[DATA_FIRSTNAME]->data) ? $search_array[DATA_FIRSTNAME]->data : '';
$ln = !empty($search_array[DATA_LASTNAME]->data) ? $search_array[DATA_LASTNAME]->data : '';
$patterns[] = '/##firstname##/';
$replacement[] = '<label class="accesshide" for="u_fn">'.get_string('authorfirstname', 'data').'</label><input type="text" size="16" id="u_fn" name="u_fn" value="'.$fn.'" />';
$replacement[] = '<label class="accesshide" for="u_fn">'.get_string('authorfirstname', 'data').'</label><input type="text" size="16" id="u_fn" name="u_fn" value="'.s($fn).'" />';
$patterns[] = '/##lastname##/';
$replacement[] = '<label class="accesshide" for="u_ln">'.get_string('authorlastname', 'data').'</label><input type="text" size="16" id="u_ln" name="u_ln" value="'.$ln.'" />';
$replacement[] = '<label class="accesshide" for="u_ln">'.get_string('authorlastname', 'data').'</label><input type="text" size="16" id="u_ln" name="u_ln" value="'.s($ln).'" />';
// actual replacement of the tags
$newtext = preg_replace($patterns, $replacement, $data->asearchtemplate);
+2 -2
View File
@@ -169,7 +169,7 @@ if ($move > 0 and confirm_sesskey()) {
forum_rss_delete_file($forum);
forum_rss_delete_file($forumto);
redirect($return.'&moved=-1&sesskey='.sesskey());
redirect($return.'&move=-1&sesskey='.sesskey());
}
$params = array(
@@ -355,7 +355,7 @@ if ($forum->type == 'qanda' && !has_capability('mod/forum:viewqandawithoutpostin
}
if ($move == -1 and confirm_sesskey()) {
echo $OUTPUT->notification(get_string('discussionmoved', 'forum', format_string($forum->name,true)));
echo $OUTPUT->notification(get_string('discussionmoved', 'forum', format_string($forum->name,true)), 'notifysuccess');
}
$canrate = has_capability('mod/forum:rate', $modcontext);
+2 -2
View File
@@ -230,7 +230,7 @@ if ($generalforums) {
} else if ($unread = forum_tp_count_forum_unread_posts($cm, $course)) {
$unreadlink = '<span class="unread"><a href="view.php?f='.$forum->id.'">'.$unread.'</a>';
$unreadlink .= '<a title="'.$strmarkallread.'" href="markposts.php?f='.
$forum->id.'&amp;mark=read"><img src="'.$OUTPUT->pix_url('t/markasread') . '" alt="'.$strmarkallread.'" class="iconsmall" /></a></span>';
$forum->id.'&amp;mark=read&amp;sesskey=' . sesskey() . '"><img src="'.$OUTPUT->pix_url('t/markasread') . '" alt="'.$strmarkallread.'" class="iconsmall" /></a></span>';
} else {
$unreadlink = '<span class="read">0</span>';
}
@@ -368,7 +368,7 @@ if ($course->id != SITEID) { // Only real courses have learning forums
} else if ($unread = forum_tp_count_forum_unread_posts($cm, $course)) {
$unreadlink = '<span class="unread"><a href="view.php?f='.$forum->id.'">'.$unread.'</a>';
$unreadlink .= '<a title="'.$strmarkallread.'" href="markposts.php?f='.
$forum->id.'&amp;mark=read"><img src="'.$OUTPUT->pix_url('t/markasread') . '" alt="'.$strmarkallread.'" class="iconsmall" /></a></span>';
$forum->id.'&amp;mark=read&sesskey=' . sesskey() . '"><img src="'.$OUTPUT->pix_url('t/markasread') . '" alt="'.$strmarkallread.'" class="iconsmall" /></a></span>';
} else {
$unreadlink = '<span class="read">0</span>';
}
+2 -2
View File
@@ -3805,7 +3805,7 @@ function forum_print_discussion_header(&$post, $forum, $group=-1, $datestring=""
echo $post->unread;
echo '</a>';
echo '<a title="'.$strmarkalldread.'" href="'.$CFG->wwwroot.'/mod/forum/markposts.php?f='.
$forum->id.'&amp;d='.$post->discussion.'&amp;mark=read&amp;returnpage=view.php">' .
$forum->id.'&amp;d='.$post->discussion.'&amp;mark=read&amp;returnpage=view.php&amp;sesskey=' . sesskey() . '">' .
'<img src="'.$OUTPUT->pix_url('t/markasread') . '" class="iconsmall" alt="'.$strmarkalldread.'" /></a>';
echo '</span>';
} else {
@@ -5486,7 +5486,7 @@ function forum_print_latest_discussions($course, $forum, $maxdiscussions = -1, $
if ($forumtracked) {
echo '<a title="'.get_string('markallread', 'forum').
'" href="'.$CFG->wwwroot.'/mod/forum/markposts.php?f='.
$forum->id.'&amp;mark=read&amp;returnpage=view.php">'.
$forum->id.'&amp;mark=read&amp;returnpage=view.php&amp;sesskey=' . sesskey() . '">'.
'<img src="'.$OUTPUT->pix_url('t/markasread') . '" class="iconsmall" alt="'.get_string('markallread', 'forum').'" /></a>';
}
echo '</th>';
+1
View File
@@ -55,6 +55,7 @@ if (!$cm = get_coursemodule_from_instance("forum", $forum->id, $course->id)) {
$user = $USER;
require_login($course, false, $cm);
require_sesskey();
if ($returnpage == 'index.php') {
$returnto = forum_go_back_to(new moodle_url("/mod/forum/$returnpage", array('id' => $course->id)));
+3 -1
View File
@@ -53,7 +53,9 @@ if (!is_null($sesskey)) {
}
if (!is_null($discussionid)) {
$url->param('d', $discussionid);
$discussion = $DB->get_record('forum_discussions', array('id' => $discussionid), '*', MUST_EXIST);
if (!$discussion = $DB->get_record('forum_discussions', array('id' => $discussionid, 'forum' => $id))) {
print_error('invaliddiscussionid', 'forum');
}
}
$PAGE->set_url($url);
+1 -1
View File
@@ -32,7 +32,7 @@ $includetext = optional_param('includetext', false, PARAM_BOOL);
$forum = $DB->get_record('forum', array('id' => $forumid), '*', MUST_EXIST);
$course = $DB->get_record('course', array('id' => $forum->course), '*', MUST_EXIST);
$discussion = $DB->get_record('forum_discussions', array('id' => $discussionid), '*', MUST_EXIST);
$discussion = $DB->get_record('forum_discussions', array('id' => $discussionid, 'forum' => $forumid), '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('forum', $forum->id, $course->id, false, MUST_EXIST);
$context = context_module::instance($cm->id);
@@ -0,0 +1,39 @@
@mod @mod_forum
Feature: A teacher can move discussions between forums
In order to move a discussion
As a teacher
I need to use the move discussion selector
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
Scenario: A teacher can move discussions
Given the following "activities" exist:
| activity | name | intro | course | idnumber | groupmode |
| forum | Test forum 1 | Test forum 2 | C1 | forum | 0 |
| forum | Test forum 2 | Test forum 1 | C1 | forum | 0 |
And I log in as "student1"
And I follow "Course 1"
And I follow "Test forum 1"
And I add a new discussion to "Test forum 1" forum with:
| Subject | Discussion 1 |
| Message | Test post message |
And I wait "1" seconds
And I log out
And I log in as "teacher1"
And I follow "Course 1"
And I follow "Test forum 1"
And I follow "Discussion 1"
When I set the field "jump" to "Test forum 2"
And I press "Move"
Then I should see "This discussion has been moved to 'Test forum 2'."
+1
View File
@@ -23,6 +23,7 @@ function scorm_openpopup(url,name,options,width,height) {
options += ",width=" + width + ",height=" + height;
windowobj = window.open(url,name,options);
windowobj.opener = null;
if (!windowobj) {
return;
}
+2
View File
@@ -83,6 +83,7 @@ M.mod_scormform.init = function(Y) {
winobj = window.open(launch_url,'Popup', poptions);
this.target = 'Popup';
scormredirect(winobj);
winobj.opener = null;
}
// Listen for view form submit and generate popup on user interaction.
if (scormform) {
@@ -91,6 +92,7 @@ M.mod_scormform.init = function(Y) {
winobj = window.open(launch_url, 'Popup', poptions);
this.target = 'Popup';
scormredirect(winobj);
winobj.opener = null;
e.preventDefault();
}, scormform);
}
+3 -3
View File
@@ -46,20 +46,20 @@ if (!empty($swid)) {
$subwiki = wiki_get_subwiki($swid);
if (!$wiki = wiki_get_wiki($subwiki->wikiid)) {
print_error('invalidwikiid', 'wiki');
print_error('incorrectwikiid', 'wiki');
}
} else {
$subwiki = wiki_get_subwiki_by_group($wid, $group, $uid);
if (!$wiki = wiki_get_wiki($wid)) {
print_error('invalidwikiid', 'wiki');
print_error('incorrectwikiid', 'wiki');
}
}
if (!$cm = get_coursemodule_from_instance('wiki', $wiki->id)) {
print_error('invalidcoursemoduleid', 'wiki');
print_error('invalidcoursemodule');
}
$groups = new stdClass();
+1 -1
View File
@@ -63,7 +63,7 @@ if (!$cm = get_coursemodule_from_instance('wiki', $wiki->id)) {
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
if ($compare >= $comparewith) {
print_error("A page version can only be compared with an older version.");
print_error('cannotcomparenewerversion', 'wiki');
}
require_login($course, true, $cm);
+4
View File
@@ -22,6 +22,7 @@ $string['backoldversion'] = 'Back to old version';
$string['backpage'] = 'Back to page';
$string['backtomapmenu'] = 'Back to map menu';
$string['changerate'] = 'Do you wish to change it?';
$string['cannotcomparenewerversion'] = 'A page version can only be compared with an older version.';
$string['cannoteditpage'] = 'You can not edit this page.';
$string['cannotmanagefiles'] = 'You don\'t have permission to manage the wiki files.';
$string['cannotviewfiles'] = 'You don\'t have permission to view the wiki files.';
@@ -102,6 +103,9 @@ $string['history'] = 'History';
$string['history_help'] = 'The history lists links to previous versions of the page.';
$string['html'] = 'HTML';
$string['incorrectdeleteversions'] = "Page versions provided for deletion are incorrect.";
$string['incorrectpageid'] = 'Page ID is incorrect.';
$string['incorrectsubwikiid'] = 'Subwiki ID is incorrect.';
$string['incorrectwikiid'] = 'Wiki ID is incorrect.';
$string['insertcomment'] = 'Insert comment';
$string['insertimage'] = 'Insert an image...';
$string['insertimage_help'] = 'This drop-down list will insert an image to the wiki editor. If you need to add more images to the wiki, please use "Files" tab.';
+1 -1
View File
@@ -268,7 +268,7 @@ if ($id) {
// * Error. No more options
// */
} else {
print_error('incorrectparameters');
print_error('invalidparameters', 'wiki');
}
if (!wiki_user_can_view($subwiki, $wiki)) {
+7 -2
View File
@@ -112,8 +112,13 @@ class report_log_table_log extends table_sql {
* @return string HTML for the time column
*/
public function col_time($event) {
$recenttimestr = get_string('strftimerecent', 'core_langconfig');
return userdate($event->timecreated, $recenttimestr);
if (empty($this->download)) {
$dateformat = get_string('strftimerecent', 'core_langconfig');
} else {
$dateformat = get_string('strftimedatetimeshort', 'core_langconfig');
}
return userdate($event->timecreated, $dateformat);
}
/**
+1 -1
View File
@@ -105,7 +105,7 @@ $params = $param->params;
$param->table = 'user_'.$param->table;
$sql = 'SELECT timeend,'.$param->fields.' FROM {stats_'.$param->table.'} WHERE '
$sql = 'SELECT id, timeend,'.$param->fields.' FROM {stats_'.$param->table.'} WHERE '
.(($course->id == SITEID) ? '' : ' courseid = '.$course->id.' AND ')
.' userid = '.$user->id.' AND timeend >= '.$param->timeafter .$param->extras
.' ORDER BY timeend DESC';
+10 -1
View File
@@ -133,6 +133,7 @@ class user_edit_form extends moodleform {
$fields = get_user_fieldnames();
$authplugin = get_auth_plugin($user->auth);
$customfields = $authplugin->get_custom_user_profile_fields();
$customfieldsdata = profile_user_record($userid, false);
$fields = array_merge($fields, $customfields);
foreach ($fields as $field) {
if ($field === 'description') {
@@ -144,7 +145,15 @@ class user_edit_form extends moodleform {
if (!$mform->elementExists($formfield)) {
continue;
}
$value = $mform->getElementValue($formfield);
// Get the original value for the field.
if (in_array($field, $customfields)) {
$key = str_replace('profile_field_', '', $field);
$value = isset($customfieldsdata->{$key}) ? $customfieldsdata->{$key} : '';
} else {
$value = $user->{$field};
}
$configvariable = 'field_lock_' . $field;
if (isset($authplugin->config->{$configvariable})) {
if ($authplugin->config->{$configvariable} === 'locked') {
+1 -1
View File
@@ -272,7 +272,7 @@ class user_editadvanced_form extends moodleform {
}
}
if (!$user or $user->email !== $usernew->email) {
if (!$user or (isset($usernew->email) && $user->email !== $usernew->email)) {
if (!validate_email($usernew->email)) {
$err['email'] = get_string('invalidemail');
} else if ($DB->record_exists('user', array('email' => $usernew->email, 'mnethostid' => $CFG->mnet_localhost_id))) {
+3 -2
View File
@@ -230,7 +230,9 @@ if ($mycourses = enrol_get_my_courses()) {
$controlstable->data[0]->cells[] = $OUTPUT->render($select);
}
$controlstable->data[0]->cells[] = groups_print_course_menu($course, $baseurl->out(), true);
if ($groupmenu = groups_print_course_menu($course, $baseurl->out(), true)) {
$controlstable->data[0]->cells[] = $groupmenu;
}
if (!isset($hiddenfields['lastaccess'])) {
// Get minimum lastaccess for this course and display a dropbox to filter by lastaccess going back this far.
@@ -650,7 +652,6 @@ if ($mode === MODE_USERDETAILS) { // Print simple listing.
$row->cells[1]->text .= get_string('role').get_string('labelsep', 'langconfig').$user->role.'<br />';
}
if ($user->maildisplay == 1 or ($user->maildisplay == 2 and ($course->id != SITEID) and !isguestuser()) or
has_capability('moodle/course:viewhiddenuserfields', $context) or
in_array('email', $extrafields) or ($user->id == $USER->id)) {
$row->cells[1]->text .= get_string('email').get_string('labelsep', 'langconfig').html_writer::link("mailto:$user->email", $user->email) . '<br />';
}
+3 -2
View File
@@ -551,9 +551,10 @@ function profile_signup_fields($mform) {
/**
* Returns an object with the custom profile fields set for the given user
* @param integer $userid
* @param bool $onlyinuserobject True if you only want the ones in $USER.
* @return stdClass
*/
function profile_user_record($userid) {
function profile_user_record($userid, $onlyinuserobject = true) {
global $CFG, $DB;
$usercustomfields = new stdClass();
@@ -563,7 +564,7 @@ function profile_user_record($userid) {
require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
$newfield = 'profile_field_'.$field->datatype;
$formfield = new $newfield($field->id, $userid);
if ($formfield->is_user_object_data()) {
if (!$onlyinuserobject || $formfield->is_user_object_data()) {
$usercustomfields->{$field->shortname} = $formfield->data;
}
}
+6
View File
@@ -62,6 +62,9 @@ class core_user_profilelib_testcase extends advanced_testcase {
// Check that profile_user_record returns same (no) fields.
$this->assertObjectNotHasAttribute('frogdesc', profile_user_record($user->id));
// Check that profile_user_record returns all the fields when requested.
$this->assertObjectHasAttribute('frogdesc', profile_user_record($user->id, false));
// Add another custom field, this time of normal text type.
$id2 = $DB->insert_record('user_info_field', array(
'shortname' => 'frogname', 'name' => 'Name of frog', 'categoryid' => 1,
@@ -77,6 +80,9 @@ class core_user_profilelib_testcase extends advanced_testcase {
// Check profile_user_record returns same field.
$this->assertObjectHasAttribute('frogname', profile_user_record($user->id));
// Check that profile_user_record returns all the fields when requested.
$this->assertObjectHasAttribute('frogname', profile_user_record($user->id, false));
}
/**
+2 -2
View File
@@ -29,11 +29,11 @@
defined('MOODLE_INTERNAL') || die();
$version = 2014111009.00; // 20141110 = branching date YYYYMMDD - do not modify!
$version = 2014111012.00; // 20141110 = branching date YYYYMMDD - do not modify!
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '2.8.9 (Build: 20151109)'; // Human-friendly version name
$release = '2.8.12 (Build: 20160509)'; // Human-friendly version name
$branch = '28'; // This version's branch.
$maturity = MATURITY_STABLE; // This version's maturity level.