Compare commits

..

406 Commits

Author SHA1 Message Date
Eloy Lafuente (stronk7) d25049c0fc Moodle release 2.6.4 2014-07-12 19:10:37 +02:00
Eloy Lafuente (stronk7) 6d00d81b84 weekly release 2.6.3+ 2014-07-10 19:15:32 +02:00
Eloy Lafuente (stronk7) 61fdbd038e Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-07-10 19:15:27 +02:00
Ankit Agarwal 72d8a0a12e MDL-46148 qtype_calculated: low-level defence against bad formulas
This catches things like:
 * Malicious equations coming from backup files.
 * Malicious equations in old questions in the database.
2014-07-10 17:54:52 +08:00
Andrew Nicols 5c74e0daca MDL-38990 mod_forum: Restrict ability to post to all groups in a forum
In order to post to all groups in a forum, you must have the
moodle/site:accessallgroups capability.

Thanks to Jakob Ackermann <jackermann@onlineschool.ca> for part of the fix
on this one.
2014-07-10 11:53:06 +08:00
Damyon Wiese 4a46fd643f MDL-46148 questions: Added missing allow_commit for transaction 2014-07-10 11:37:24 +08:00
Damyon Wiese 62a1434588 Merge branch 'MDL-19270_moodle26stable' of https://github.com/nadavkav/moodle into MOODLE_26_STABLE
Conflicts:
	lib/graphlib.php
2014-07-10 10:00:03 +08:00
Tim Hunt 20af9d3c0f MDL-46148 qtype_calculatedsimple: fix notice
... when adding a dataset with a formula error.
2014-07-09 14:11:43 +01:00
Tim Hunt 7bf7ef3919 MDL-46148 qtype_calculated: fix validation when importing.
In order to do this in a sane way, I cleaned up a lot of old mess,
inclduing:

1. Previously, qtype_calcuated used ->answeres when importing, and
->answer when saving the form. This was crazy, so I fixed it, and
stripped out the code that made the alternative variable name work.

2. Similarly, it could handle ->answer being either an array, such as
you would get form the HTML editor, or a simple string, which is what
you get form the form. I simplified that too.

3. Finally, I made import use a transaction around saving each
question, so we don't get half questions in the database when an error
occurs.
2014-07-09 14:11:42 +01:00
Tim Hunt f8a6c3d6f0 MDL-46148 qtype_calculated: removed unused method. 2014-07-09 14:11:42 +01:00
Nadav Kavalerchik 6499a17d78 MDL-19270 - Quiz graph - Fix reverse display of Hebrew legend text in RTL mode 2014-07-09 16:09:10 +03:00
David Mudrák 8ecc049f7f MDL-46223 Fix frequently used comments in the marking guide
When the frequently used comment contains a character like >, re-use it
directly instead of its HTML entitiy.
2014-07-09 16:44:28 +08:00
David Mudrák 68299e6154 MDL-46223 Improve the display of marking guide validation message 2014-07-09 16:44:25 +08:00
Dan Poltawski 48bdbf5a4a MDL-44605 calendar: improved returnurl validation
Now we will only redirect to a local url (though sesskey was
already preventing this redirect from being open)
2014-07-09 01:06:46 +02:00
Dan Poltawski 648bf857d3 Merge branch 'MDL-44492_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-07-08 14:17:58 +01:00
Frederic Massart 166e18d7cb MDL-45471 javascript: Escape content of exception dialogs
Conflicts:

	lib/yui/build/moodle-core-notification-ajaxexception/moodle-core-notification-ajaxexception-min.js
	lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-debug.js
	lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-min.js
	lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue.js
	lib/yui/build/moodle-core-notification-exception/moodle-core-notification-exception-min.js
2014-07-08 14:13:29 +01:00
Tim Hunt 2c78623121 MDL-44492 quiz: fix hilighting of graded attempt
In various places, when showing several attempts, we try to hilight the
most significant one (the one that gave the final grade if the quiz is
set to first/last/best attempt). That was not working because the table
zebra stripes were a more specific rule.

Also, the colour was inconsistent, not nice, and not very bootstrapy, so
I changed it.
2014-07-08 14:03:46 +01:00
Tim Hunt 89b8ba6dba MDL-44492 quiz reports: revert some style overrides.
But add one more. This makes Clean theme look a lot better.
2014-07-08 14:03:45 +01:00
Tim Hunt 5c8ef12940 MDL-44492 Rough unit test for the report SQL.
We really ought to test more cases, but this hits one of the most tricky cases.
2014-07-08 14:03:43 +01:00
Tim Hunt d1ff9b957a MDL-44492 quiz reports: make show only graded attempt work.
It needs to only affect finished attempts, and the wording needs to be
modified to make it clear that is what it does.
2014-07-08 14:03:41 +01:00
Dan Poltawski 077703b235 Merge branch 'MDL-45596-26' of git://github.com/FMCorz/moodle into MOODLE_26_STABLE 2014-07-08 10:50:56 +01:00
Marina Glancy 980903e56a MDL-43948 forms: setting types to filemanager and editor elements 2014-07-08 10:47:36 +01:00
Dan Poltawski d830bd9a33 Merge branch 'MDL-46231-26-en_fix' of git://github.com/mudrd8mz/moodle into MOODLE_26_STABLE 2014-07-08 08:32:37 +01:00
Marina Glancy 8f2db3c1a1 Merge branch 'MDL-46229_26' of https://github.com/totara/openbadges into MOODLE_26_STABLE 2014-07-08 13:51:57 +08:00
David Mudrák 666248c264 MDL-46223 Improve the marking guide output 2014-07-08 13:20:03 +08:00
David Mudrák 1f8eb08428 MDL-46223 Improve the rubric output 2014-07-08 13:20:03 +08:00
Sam Hemelryk 20c80d9e2f Merge branch 'MDL-46248_m26' of https://github.com/markn86/moodle into MOODLE_26_STABLE 2014-07-08 14:40:17 +12:00
Sam Hemelryk fc22f80e9c Merge branch 'MDL-46016_m26' of https://github.com/markn86/moodle into MOODLE_26_STABLE 2014-07-08 14:27:55 +12:00
Sam Hemelryk bdf5ae0e92 MDL-19270 core_text: added unit tests for strrev 2014-07-08 14:15:06 +12:00
Sam Hemelryk fadff0062a Merge branch 'MDL-19270_moodle26stable' of https://github.com/nadavkav/moodle into MOODLE_26_STABLE 2014-07-08 13:53:47 +12:00
Sam Hemelryk 849c19022c Merge branch 'mdl45982-moodle26' of https://github.com/tlock/moodle into MOODLE_26_STABLE 2014-07-08 13:26:51 +12:00
Sam Hemelryk 0076ac2d1c Merge branch 'm26_MDL-46144' of https://github.com/totara/moodle into MOODLE_26_STABLE 2014-07-08 13:10:33 +12:00
Eloy Lafuente (stronk7) 792fb3ea61 Merge branch '46208-26' of git://github.com/samhemelryk/moodle into MOODLE_26_STABLE 2014-07-08 02:15:51 +02:00
Sam Hemelryk 15dcd5a535 MDL-45678 cache: renamed new cache and better comments 2014-07-08 09:52:57 +12:00
Sam Hemelryk 8ce2f33f9e Merge branch 'MDL-45678-006-26' of https://github.com/dbezborodovrp/moodle into MOODLE_26_STABLE 2014-07-08 09:42:43 +12:00
Sam Hemelryk ca13549a89 Merge branch 'wip_MDL-46126_m26_passnulls' of https://github.com/skodak/moodle into MOODLE_26_STABLE 2014-07-08 09:37:14 +12:00
Sam Hemelryk 20e563e825 Merge branch 'MDL-43347-26' of https://github.com/mackensen/moodle into MOODLE_26_STABLE 2014-07-08 09:28:25 +12:00
Yuliya Bozhko 0174a0a57f MDL-46042 badges: Clean up external badge data
Signed-off-by: Yuliya Bozhko <yuliya.bozhko@totaralms.com>
2014-07-07 16:37:48 +01:00
Dan Poltawski 7047adfdbe Merge branch 'MDL-42393-26' of git://github.com/FMCorz/moodle into MOODLE_26_STABLE 2014-07-07 16:27:34 +01:00
Dan Poltawski 47de7aac75 Merge branch 'MDL-41389_m26' of https://github.com/markn86/moodle into MOODLE_26_STABLE 2014-07-07 16:10:28 +01:00
Osanda Malith Jayathissa 739d227c58 MDL-45683 user: Escaping Skype ID used in profile 2014-07-07 16:05:10 +01:00
Marina Glancy 74556525de MDL-45760 make sure to check permission before setting header 2014-07-07 15:06:42 +01:00
Tim Hunt 9d8348e13f MDL-46148 qtype_calculated: fix formula validation. 2014-07-07 14:34:02 +01:00
Frederic Massart bbc12d9cb5 MDL-45417 mod_imscp: Prevent entity injections from package content 2014-07-07 13:03:07 +01:00
Frederic Massart 4637ad6f7e MDL-45463 mod_lti: Prevent XML entity injections from provider 2014-07-07 13:00:43 +01:00
Marina Glancy 40d52d4067 MDL-45616 repositories: use json encoding instead of serialization 2014-07-07 15:23:02 +08:00
Marina Glancy 68170f0b01 MDL-45616 repositories: more clearly distinguish when we use source and when reference
Function repository::get_moodle_file() should always be called on packed reference and not on the source received from user.
Also added phpdocs to some other methods that were confusing source and reference
2014-07-07 15:23:02 +08:00
Dan Poltawski 7d6e6ffceb MDL-43848 messages: do not display message content in popups
The user is not in control of when these popups show up and it
may not be appropiate to have part of this content display whilst
in the presence of other users.
2014-07-07 13:48:08 +08:00
Nadav Kavalerchik 0057543e5e MDL-19270 - Quiz graph - Fix reverse display of Hebrew legend text in RTL mode 2014-07-06 18:51:11 +03:00
Helen Foster 07d9521c49 MDL-46231 Merge English strings from the en_fix language pack 2014-07-04 22:43:32 +02:00
Damien Bezborodov 4ee23c10bb MDL-45678 assignsubmission_comments: Improve performance for permissions checking 2014-07-04 14:25:32 +09:30
Petr Skoda 37648d141f MDL-46126 upgrade: fix bogus nulls in user.password before changing precission
Note: there is no need to deal with Oracle empty strings here
because only MySQL running in non-strict mode is affected.
2014-07-04 16:29:58 +12:00
Frederic Massart 3fd99e0ff6 MDL-45596 roles: Escape filter value before using it in form field 2014-07-04 11:49:32 +08:00
Mark Nelson 2d47c45485 MDL-41389 auth_db: added unit tests for events 2014-07-03 20:19:10 -07:00
AMOS bot f214d6e69a Automatically generated installer lang files 2014-07-04 00:44:28 +00:00
Daniel Neis Araujo e0cd470f1d MDL-46248 calendar: HTML validation check fails on add event screen (Backport of MDL-42869) 2014-07-03 17:20:34 -07:00
Mark Nelson 5e44d5abaa MDL-46016 auth_shibboleth: updated misleading comment
Also generated a random string for the password field in case it is ever used.
2014-07-03 16:16:02 -07:00
Mark Nelson dba2527290 MDL-41389 auth_db: added user_updated/created event triggers 2014-07-03 15:11:47 -07:00
Sam Hemelryk 0b7cbdb0e6 MDL-46208 cachestore_mongo: fixed invalid collection name use 2014-07-04 08:11:21 +12:00
Dan Poltawski 92e7886965 weekly release 2.6.3+ 2014-07-03 10:53:21 +01:00
Dan Poltawski 7b414e6258 Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-07-03 10:53:18 +01:00
Frederic Massart 880c2fb8ba MDL-42393 calendar: Preventing open/close loop in events overlay 2014-07-03 10:17:25 +08:00
Yuliya Bozhko e68af16896 MDL-46229 badges: Fix missing additional names fields
Signed-off-by: Yuliya Bozhko <yuliya.bozhko@totaralms.com>
2014-07-03 09:35:06 +12:00
AMOS bot a2a8e3edf9 Automatically generated installer lang files 2014-07-02 00:44:47 +00:00
Eloy Lafuente (stronk7) 333c9cd9df Merge branch 'wip-mdl-45889-m26' of https://github.com/rajeshtaneja/moodle into MOODLE_26_STABLE 2014-07-02 00:57:09 +02:00
Eloy Lafuente (stronk7) 5d4923ffcc Merge branch '45209-26' of git://github.com/samhemelryk/moodle into MOODLE_26_STABLE 2014-07-01 23:43:28 +02:00
Sam Hemelryk 2ce17661e8 Merge branch 'wip-MDL-46147-m26' of git://github.com/marinaglancy/moodle into MOODLE_26_STABLE 2014-07-02 09:31:10 +12:00
Mary Evans dc22f74419 MDL-45507 theme_bootstrapbase: Fix regression for theme based custom menu
in renderers/core_renderer.php.
2014-07-02 09:22:49 +12:00
Eloy Lafuente (stronk7) f7adf8a010 Merge branch 'MDL-45961_MOODLE_26_STABLE' of https://github.com/NeillM/moodle into MOODLE_26_STABLE 2014-07-01 19:23:46 +02:00
Dan Poltawski 92267ed9fe Merge branch 'MDL-46063_26' of git://github.com/schach/moodle into MOODLE_26_STABLE 2014-07-01 17:29:18 +01:00
Dan Poltawski d520b92579 Merge branch 'MDL-46036_survey_26' of https://github.com/andyjdavis/moodle into MOODLE_26_STABLE 2014-07-01 16:34:32 +01:00
Charles Fulton 83f78c7c5e MDL-43347 grades: convert keep highest to text field 2014-07-01 07:36:15 -07:00
Charles Fulton 78e6292f47 MDL-43347 grades: consistent interface for drop lowest setting 2014-07-01 07:36:08 -07:00
Dan Poltawski e666c72330 Merge branch 'MDL-46107_26' of https://github.com/totara/openbadges into MOODLE_26_STABLE 2014-07-01 14:20:53 +01:00
Dan Poltawski db1cf750bd Merge branch 'wip_MDL-46099_m26_userglobal' of https://github.com/skodak/moodle into MOODLE_26_STABLE 2014-07-01 10:39:18 +01:00
Marina Glancy 2522a179b0 MDL-46147 modinfo: performance improvement for course page (check filterall) 2014-07-01 15:32:48 +08:00
Damyon Wiese 30e2727e72 MDL-46147 modinfo: performance improvement for course page
This is a big win in a specific situation, ie filters enabled for content+headings,
and no activity descriptions visible on the course page.
2014-07-01 15:32:41 +08:00
Brian Barnes faa963ba9a MDL-46144 core_calendar:Fixed label linking in calendar 2014-07-01 13:51:40 +12:00
Sam Hemelryk 3bbb37741f Merge branch 'MDL-40805-26' of git://github.com/lameze/moodle into MOODLE_26_STABLE 2014-07-01 09:06:16 +12:00
Petr Skoda d0dd8d33bb MDL-46099 session: fix use of references for session globals
This reverses the references used for global $USER and $SESSION,
the reason is that PHP does not allow references to references.
$USER is a reference to $GLOBALS['USER'] which means we cannot
put any references to it. Solution is to store the current user and session
objects in $GLOBALS['USER'] and $GLOBALS['SESSIOn'] are reference
them in $_SESSION.

This patch makes the session code behave the same way in CLI,
phpunit and normal web requests - this allows use to finally
unit test most aspects of the session code in Moodle.
2014-07-01 08:38:52 +12:00
Dan Poltawski 824303bada MDL-45641 fix trailing whitespace 2014-06-30 15:47:27 +01:00
Dan Poltawski cb49ea51eb Merge branch 'wip-mdl-45641-m26' of https://github.com/rajeshtaneja/moodle into MOODLE_26_STABLE 2014-06-30 15:26:39 +01:00
Dan Poltawski c1f759ab50 Merge branch 'MDL-42467_database_26' of https://github.com/andyjdavis/moodle into MOODLE_26_STABLE 2014-06-30 15:09:54 +01:00
Dan Poltawski d183fbaf60 Merge branch 'MDL-45833_26' of git://github.com/dmonllao/moodle into MOODLE_26_STABLE 2014-06-30 13:27:18 +01:00
Dan Poltawski 0d0552d430 Merge branch 'MDL-46044-26' of git://github.com/damyon/moodle into MOODLE_26_STABLE 2014-06-30 11:45:32 +01:00
Heiko Schach 55ab8ab731 MDL-46063 feedback: Fix user pictures 2014-06-30 13:28:34 +03:00
Dan Poltawski f50f41c507 Merge branch 'MDL-40228-26' of git://github.com/FMCorz/moodle into MOODLE_26_STABLE 2014-06-30 08:56:47 +01:00
AMOS bot 86573d4ee6 Automatically generated installer lang files 2014-06-29 00:42:58 +00:00
Rajesh Taneja 548e5ecd1b MDL-45641 event: Ldap user_signup unit test added 2014-06-27 16:18:45 +08:00
Rajesh Taneja 695dc96b0e MDL-45641 event: Manually trigger event where needed.
Some places, user_created_user and user_updated_user
events should be triggred after profile data is saved.
2014-06-27 16:18:45 +08:00
Rajesh Taneja 7345a2af94 MDL-45641 event: Option to trigger user event manually
On some pages full user data is not stored before user_created/
user_updated event is triggred. So giving option to trigger that
manually, so it can be triggred after all data is saved
2014-06-27 16:18:45 +08:00
NeillM 2479cecad9 MDL-45961 Customise this page button on user profile page only works correctly for users own profile 2014-06-27 09:04:41 +01:00
Damyon Wiese de55ebff23 MDL-46044 Assign: Add conditions to the inner query for performance 2014-06-27 15:01:35 +08:00
Damyon Wiese 157e5a9f9c MDL-46044 Assign: Modify myhome query to only use the maxattempt from the submission
Using mismatches from the submissions/grades tables does not make much sense, we
should always only consider only the maxattempt from the submissions table.
2014-06-27 14:23:37 +08:00
Damyon Wiese b7860604f7 MDL-46044 Assign: Move common setup to setUp method (share it for all of lib_test.php) 2014-06-27 14:19:59 +08:00
Damyon Wiese eba3393014 MDL-46044 Assign: Fix print_overview function when there are multiple attempts 2014-06-27 14:19:51 +08:00
Damyon Wiese 16266791a0 MDL-46044 Assign: Update unit test to test multiple attempts on overview page 2014-06-27 14:19:44 +08:00
David Monllao 2427ceef62 MDL-45833 event: Removing courseid as the context is higher than course context 2014-06-27 11:25:00 +08:00
Yuliya Bozhko 3e9dfd7f62 MDL-46107 badges: Fix badges navigation and remove empty breadcrumbs on pages using Clean
Signed-off-by: Yuliya Bozhko <yuliya.bozhko@totaralms.com>
2014-06-27 12:49:00 +12:00
Sam Hemelryk dc9363a651 MDL-45209 course: fixed navbar when creating,editing courses 2014-06-27 09:39:43 +12:00
Eloy Lafuente (stronk7) 5c1049f72b weekly release 2.6.3+ 2014-06-26 10:35:50 +02:00
Eloy Lafuente (stronk7) 125ca896df Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-06-26 10:35:45 +02:00
Eloy Lafuente (stronk7) 65684fa600 Revert " MDL-45044 filter_tex: properly escape excutable pathnames for Windows"
This reverts commit 07a50c2f29.
2014-06-26 10:03:25 +02:00
Rajesh Taneja c7b0eeee8e MDL-45889 behat: Allow admin config to set by shortname 2014-06-26 13:19:21 +08:00
Andrew Davis dbf541f8e1 MDL-46036 mod_survey: added logic to prevent user trying to download when there are no results 2014-06-26 11:20:58 +08:00
Andrew Davis 5636246c95 MDL-42467 mod_data: added code to delete cached RSS feeds when database or glossary entries are deleted 2014-06-26 09:18:21 +08:00
AMOS bot 50ca770bc6 Automatically generated installer lang files 2014-06-25 00:45:35 +00:00
AMOS bot 21d1577972 Automatically generated installer lang files 2014-06-25 00:45:34 +00:00
Eloy Lafuente (stronk7) 9d5a2e6f1c Merge branch 'MDL-46079-m26' of https://github.com/sammarshallou/moodle into MOODLE_26_STABLE 2014-06-25 01:34:02 +02:00
Eloy Lafuente (stronk7) 004659a6d0 Merge branch 'MDL-41258-26' of git://github.com/andrewnicols/moodle into MOODLE_26_STABLE 2014-06-24 20:09:35 +02:00
Damyon Wiese 47042403ca Merge branch 'MDL-45652_m26' of https://github.com/markn86/moodle into MOODLE_26_STABLE 2014-06-24 17:00:17 +08:00
Damyon Wiese fc463d34e8 Merge branch 'MDL-10115-26' of git://github.com/xow/moodle into MOODLE_26_STABLE 2014-06-24 16:04:28 +08:00
John Okely 188c45aef6 MDL-10115 User profile: Use title to aid in the ellipsis link being understood by screen readers 2014-06-24 15:39:23 +08:00
Marina Glancy 76b320818a Merge branch 'MDL-45933-26' of git://github.com/damyon/moodle into MOODLE_26_STABLE 2014-06-24 13:52:54 +08:00
Marina Glancy e0e6a127fa Merge branch 'MDL-45044-m26-master' of git://github.com/dthies/moodle into MOODLE_26_STABLE 2014-06-24 13:29:20 +08:00
Damyon Wiese b1e4d8b119 Merge branch 'MDL-46035_survey_26' of https://github.com/andyjdavis/moodle into MOODLE_26_STABLE 2014-06-24 13:08:52 +08:00
Damyon Wiese 80fa42a001 Merge branch 'MDL-46076-m26' of https://github.com/sammarshallou/moodle into MOODLE_26_STABLE 2014-06-24 11:31:54 +08:00
Damyon Wiese 63de1463f8 Merge branch 'MDL-44512-26' of git://github.com/jethac/moodle into MOODLE_26_STABLE 2014-06-24 10:58:47 +08:00
Eloy Lafuente (stronk7) 1510a9d6a1 MDL-39883 events: fix tests to avoid warning
Only needed in 26 and older, we are handling those
changes automatically in 27 and up.
2014-06-24 02:06:08 +02:00
Eloy Lafuente (stronk7) 4fdbb24243 Merge branch 'MDL-45721_m26' of https://github.com/markn86/moodle into MOODLE_26_STABLE 2014-06-24 01:00:21 +02:00
Eloy Lafuente (stronk7) 32b48768d4 Merge branch 'MDL-39883-26' of git://github.com/ankitagarwal/moodle into MOODLE_26_STABLE 2014-06-24 00:50:05 +02:00
Eloy Lafuente (stronk7) a23eb149a8 Merge branch 'MDL-45764_generalTool_26' of https://github.com/moodlerooms/moodle into MOODLE_26_STABLE 2014-06-24 00:03:42 +02:00
Simey Lameze f0a38fd4c0 MDL-40805 auth_cas : Trigger user_loggedout event before CAS logout. 2014-06-23 15:20:53 +08:00
Damyon Wiese 1b25b037dc Merge branch 'MDL-45580-26' of git://github.com/FMCorz/moodle into MOODLE_26_STABLE 2014-06-23 15:20:40 +08:00
Frederic Massart e7acf36d0d MDL-45580 assignfeedback_editpdf: Save readonly version in backup 2014-06-23 14:56:25 +08:00
Frederic Massart 75c74acfa1 MDL-45580 assignfeedback_editpdf: Delete draft content on new submission 2014-06-23 14:56:25 +08:00
Frederic Massart 2df40c4f90 MDL-45580 assignfeedback_editpdf: Store a readonly version of the PDF 2014-06-23 14:56:21 +08:00
Damyon Wiese 3f3ecc0311 Merge branch '37145-26' of git://github.com/samhemelryk/moodle into MOODLE_26_STABLE 2014-06-23 14:40:33 +08:00
Damyon Wiese 20ab72d496 Merge branch 'MDL-38693-26' of git://github.com/jethac/moodle into MOODLE_26_STABLE 2014-06-23 13:54:59 +08:00
Damyon Wiese f208379c9f MDL-41746 External api: Allow multiple calls to validate_context at different levels
(Only from webservices)
2014-06-23 13:39:53 +08:00
Damyon Wiese d61f480fb6 Merge branch 'MDL-35453_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-06-23 12:30:18 +08:00
Mark Nielsen 45ddf2980a MDL-46013 theme: Uninstall theme unconditionally unsets configs 2014-06-23 11:35:07 +08:00
Sam Hemelryk d57563edd6 MDL-37145 caching: noted recommendation for dedicated memcache servers
Several reports have been made about the unexpected purging of entire
memcached servers when MUC is configured to use Memcache and caches
get purged.
This is expected and occurs because the memcache extenions don't
provide isolated containers. Moodle data is stored along side any other
data in the cache and when caches get purged all data gets removed
whether it belongs to Moodle or not.

The docs cover this point and here I've added notes about this to both
config-dist.php and cache/README.md
2014-06-23 11:02:48 +12:00
AMOS bot a095ad50c1 Automatically generated installer lang files 2014-06-21 00:43:44 +00:00
Tim Hunt 905050d73e MDL-35453 quiz reports: don't order by id.
We were using ORDER BY id even though there was a perfectly good
attempt column to order the attempts by one user at one quiz.

Also, Oracle was complaining:
Debug info: ORA-01799: a column may not be outer-joined to a subquery
2014-06-20 16:54:20 +01:00
sam marshall d20d8938a7 MDL-46079 Restore: Can run out of memory in get_records call 2014-06-20 14:12:58 +01:00
sam marshall e1d76a33e3 MDL-46076 Lib: Allow javascript-static.js to somewhat work in IE7 [2.6] 2014-06-20 14:10:57 +01:00
Frederic Massart 8fc9105a7a MDL-40228 backup: Settings were ignored during automated backups 2014-06-20 15:38:09 +08:00
Daniel Thies 07a50c2f29 MDL-45044 filter_tex: properly escape excutable pathnames for Windows 2014-06-19 22:08:21 -05:00
Andrew Davis f87c073039 MDL-46035 mod_survey: a string change to make an error message always correct 2014-06-20 08:58:45 +08:00
Jetha Chan 28b751b244 MDL-44512 themes: fix for custom menu submenu arrows on RTL languages 2014-06-19 15:18:18 +08:00
Damyon Wiese 9663e6f8a5 weekly release 2.6.3+ 2014-06-19 14:13:11 +08:00
Damyon Wiese 13f327b533 Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-06-19 14:13:08 +08:00
AMOS bot e7b7b7fd8e Automatically generated installer lang files 2014-06-19 00:42:58 +00:00
Ankit Agarwal 90db0fb726 MDL-39883 events: Trigger a module created event when duplicating a module 2014-06-18 16:02:43 +08:00
Ankit Agarwal fd554631f8 MDL-39883 events: Create a new api create_from_cm for module create event 2014-06-18 16:02:42 +08:00
Damyon Wiese 8bf65f15dd MDL-45933 Assign: Prevent fatal error when there are no users in the grading table 2014-06-18 15:17:38 +08:00
Mark Nelson ca0678bd96 MDL-45652 core_backup: display warning on restore destination form when necessary data is missing 2014-06-17 21:56:26 -07:00
Mark Nelson 9f6a3aee95 MDL-45721 core_backup: only trigger the course_restored event when restoring a course 2014-06-17 19:38:36 -07:00
AMOS bot 08c9c27c01 Automatically generated installer lang files 2014-06-18 00:42:34 +00:00
Andrew Nicols 9b6218949a MDL-41258 Forum: Add additional unit tests for forum digest settings 2014-06-17 16:17:35 +08:00
Damyon Wiese 05dd6551bd MDL-45582 Editpdf: Prevent debugging when there is no pdf 2014-06-17 10:21:42 +08:00
Damyon Wiese 5f8a991828 Merge branch 'm26_MDL-45582' of git://github.com/greg-or/moodle-mod_assign into MOODLE_26_STABLE 2014-06-17 10:21:34 +08:00
Eloy Lafuente (stronk7) d7b83310a7 Merge branch 'MDL-45970_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-06-17 01:15:54 +02:00
Eloy Lafuente (stronk7) a25529102c Merge branch 'MDL-45611-26' of git://github.com/phalacee/moodle into MOODLE_26_STABLE
Conflicts:
	theme/bootstrapbase/style/moodle.css
2014-06-17 01:12:34 +02:00
Eloy Lafuente (stronk7) 883656ceb8 Merge branch 'wip-mdl-45719-m26' of https://github.com/deraadt/moodle into MOODLE_26_STABLE 2014-06-17 01:04:08 +02:00
Eloy Lafuente (stronk7) c005cb8947 Merge branch 'MDL-45870-26' of git://github.com/FMCorz/moodle into MOODLE_26_STABLE 2014-06-17 00:51:46 +02:00
Marina Glancy 827fbc4515 Merge branch 'MDL-45901_Quiz_MOODLE-26-STABLE' of git://github.com/nadavkav/moodle into MOODLE_26_STABLE 2014-06-16 17:27:54 +08:00
Jonathon Fowler f8840f947c MDL-42531 assign: refactor batch operations to use forms properly
Avoids a lot of ugly optional_param() use. Also fixes the
non-functional cancel buttons.

Conflicts:
	mod/assign/locallib.php
	mod/assign/tests/base_test.php
	mod/assign/tests/events_test.php
2014-06-16 17:00:04 +08:00
Gregory Faller 41b20b6e18 MDL-45582: Apply grades and feedback to entire group does not work with Annotate PDF feature 2014-06-16 18:07:56 +09:30
Marina Glancy 0e96add931 Merge branch 'MDL-35648-v26' of git://github.com/danielneis/moodle into MOODLE_26_STABLE 2014-06-16 14:24:22 +08:00
Marina Glancy 196c818a91 Merge branch 'MDL-45935-26' of git://github.com/andrewnicols/moodle into MOODLE_26_STABLE 2014-06-16 14:23:01 +08:00
John Okely 8791ab3304 MDL-10115 User profile: Use moodle_url and html_writer::link for course links on user profiles 2014-06-16 14:22:28 +08:00
AMOS bot fc06491c75 Automatically generated installer lang files 2014-06-15 00:42:51 +00:00
Nadav Kavalerchik b70337b38c MDL-45901 - Quiz - Random question category question are not visible,in RTL mode 2014-06-14 00:47:10 +03:00
Jason Fowler 08f2855d64 MDL-45611 Questions: Fixing the layout of the 'points box' 2014-06-13 10:24:59 +08:00
AMOS bot eb4b4c7ba0 Merge branch 'MOODLE_26_STABLE' into install_26_STABLE 2014-06-13 00:42:09 +00:00
Tim Lock 23c3ce59ff MDL-45982: Implement displaying of non error messages from a provider. 2014-06-13 10:08:03 +09:30
Andreas Grabs 87aa044351 MDL-31998 mod_feedback - Feedback depend questions bug 2014-06-13 01:44:35 +02:00
Tim Hunt fa5cfedf4e MDL-45970 quiz editing: fix display of random questions.
The pass by reference meant the function was clobbering the variable in
the calling function. Once that was change, it was not strictly
necessary to rename the variable in the function, but I did anyway for
clarity.

Thanks to Rajesh Taneja for finding the problem, and identifying which
bit of code was broken. I really just made the patch.
2014-06-12 19:43:31 +01:00
Eloy Lafuente (stronk7) 89c7782a91 weekly release 2.6.3+ 2014-06-12 18:59:00 +02:00
Eloy Lafuente (stronk7) e17dc7bcfa Merge branch 'MDL-42835-26' of http://github.com/damyon/moodle into MOODLE_26_STABLE 2014-06-12 10:00:01 +02:00
John Okely 64f2725233 MDL-10115 User profile: Allow full list of courses to be viewed on a user's profile 2014-06-12 15:20:34 +08:00
Rajesh Taneja 6e5c445714 MDL-45808 enrol_self: Fixed behat to observe the group key policy
Conflicts:
	enrol/self/tests/behat/self_enrolment.feature
2014-06-12 14:39:42 +08:00
Damyon Wiese 95ef465948 MDL-42835 Scorm: Fix for JS error because no nodes are selected in the toc. 2014-06-12 14:00:04 +08:00
AMOS bot 0d893ad97b Automatically generated installer lang files 2014-06-12 00:43:43 +00:00
Damyon Wiese 1110aed46a MDL-45763 Question types: Allow saving '0' as question text. 2014-06-11 17:29:55 +08:00
Marina Glancy 86fdc9dd64 MDL-39726 backup: fix SQL syntax for Oracle 2014-06-11 17:16:15 +08:00
Marina Glancy d66cfec3f0 MDL-39726 backup: fix SQL syntax for Oracle 2014-06-11 12:19:15 +08:00
Marina Glancy 677267791a MDL-45763 question: fix SQL syntax for Oracle 2014-06-11 12:19:15 +08:00
Eloy Lafuente (stronk7) 8e9115725e Merge branch 'm26_MDL-29708_Typo_Extra_Slashes' of https://github.com/scara/moodle into MOODLE_26_STABLE 2014-06-11 01:46:08 +02:00
Frederic Massart 179515b4de MDL-45808 group: Observe the group key policy upon group creation 2014-06-10 23:03:37 +02:00
Eloy Lafuente (stronk7) 871c0ec7c5 Merge branch 'MDL-45579-26' of git://github.com/FMCorz/moodle into MOODLE_26_STABLE 2014-06-10 22:26:12 +02:00
Eloy Lafuente (stronk7) e7bc2568a6 Merge branch 'MDL-45418_26' of git://github.com/stronk7/moodle into MOODLE_26_STABLE 2014-06-10 20:13:58 +02:00
Barbara Ramiro 9fca4525dc MDL-45943: Replacement for publisher icons 2014-06-10 19:38:35 +02:00
Jason Fowler 5fd16a3761 MDL-45418 Files: Adding upgrade steps for publisher docs
Conflicts:
	lib/db/upgrade.php
	lib/db/upgradelib.php
	version.php
2014-06-10 19:37:29 +02:00
James McLean af21acd472 MDL-45418 Files: Adding publisher docs to Filetypes 2014-06-10 19:34:08 +02:00
Eric Merrill 272878cab9 MDL-45763 question: Correct random question text if set to true or false 2014-06-10 20:08:35 +08:00
Marina Glancy 38083d7ff3 Merge branch 'MDL-20154-26' of git://github.com/merrill-oakland/moodle into MOODLE_26_STABLE 2014-06-10 15:42:27 +08:00
Damyon Wiese 86af5cb87c Merge branch '45524-26' of git://github.com/samhemelryk/moodle into MOODLE_26_STABLE 2014-06-10 15:31:25 +08:00
Marina Glancy fde80766e2 Merge branch '26STABLE-wip-MDL45846' of git://github.com/jennymgray/moodle into MOODLE_26_STABLE 2014-06-10 14:20:34 +08:00
Damyon Wiese 2f3c3abc1f Merge branch 'wip-mdl-44309-m26' of https://github.com/deraadt/moodle into MOODLE_26_STABLE 2014-06-10 14:08:30 +08:00
Damyon Wiese 871a036c74 Merge branch 'MDL-45767_returnInstanceid_26' of https://github.com/moodlerooms/moodle into MOODLE_26_STABLE 2014-06-10 13:52:18 +08:00
Damyon Wiese eb6e5390c9 Merge branch 'MDL-45763-26' of https://github.com/merrill-oakland/moodle into MOODLE_26_STABLE 2014-06-10 13:14:38 +08:00
Andrew Nicols ac86e96914 MDL-45935 tests: Specify step names during backup/restore tests 2014-06-10 12:18:24 +08:00
Frederic Massart 66f93d133a MDL-45870 mod_assign: Behat test covering some outcome usage 2014-06-10 11:58:19 +08:00
Michael de Raadt ae527646a1 MDL-45719 mod_lti - Pass language strings to inline JS to allow for escaping 2014-06-10 11:40:28 +08:00
Eloy Lafuente (stronk7) 0034fd8816 Merge branch 'MDL-42782-26' of git://github.com/jethac/moodle into MOODLE_26_STABLE 2014-06-10 01:10:40 +02:00
Eloy Lafuente (stronk7) 4c3f6d562f Merge branch 'MDL-42835_26' of git://github.com/nobelium/moodle into MOODLE_26_STABLE 2014-06-10 00:37:34 +02:00
Eloy Lafuente (stronk7) b2d285491c Merge branch 'MDL-45574-m26' of https://github.com/sammarshallou/moodle into MOODLE_26_STABLE 2014-06-09 21:49:44 +02:00
Eloy Lafuente (stronk7) 4d7544a3a0 Merge branch 'wip-MDL-44501-26' of git://github.com/abgreeve/moodle into MOODLE_26_STABLE 2014-06-09 18:59:37 +02:00
Jenny Gray 1d20e997a0 MDL-45846 Libraries custom user agent device detection unit test added 2014-06-09 14:04:36 +01:00
Marina Glancy a9af7d94e1 Merge branch 'MDL-45560-26' of git://github.com/andrewnicols/moodle into MOODLE_26_STABLE 2014-06-09 17:25:22 +08:00
Jetha Chan 3a6f3f906a MDL-38693 themes: amended z-indexes
Amended #dock z-index level from 11000 to 5000 across all themes; amended z-index style of #page-header in Overlay theme such that elements no longer occlude TinyMCE.
2014-06-09 14:09:55 +08:00
Damyon Wiese 8beb255c10 Merge branch 'MDL-39726-26' of https://github.com/merrill-oakland/moodle into MOODLE_26_STABLE 2014-06-09 12:43:04 +08:00
Damyon Wiese c800196f03 Merge branch 'MDL-45714-26' of https://github.com/merrill-oakland/moodle into MOODLE_26_STABLE 2014-06-09 09:20:09 +08:00
Sam Hemelryk 7a684b732c MDL-45524 navigation: fixed non-expandable node behat tests 2014-06-09 09:33:59 +12:00
Sam Hemelryk 82358535df MDL-44711 navigation: improved expandable course calculation 2014-06-09 09:33:59 +12:00
Matteo Scaramuccia 6637cf27b9 MDL-29708 Fixed file_exception() arguments in rename(). 2014-06-07 09:59:01 +02:00
Matteo Scaramuccia 874db754ce MDL-29708 Fixed extra slashes in $string['storedfilenotcreated']. 2014-06-07 09:58:59 +02:00
sam marshall 7aa0860eca MDL-45574 Backup progress: Can time out with large number of files
When there are many files inside a single resource, it's possible
for the backup to time out because it does not report progress
while adding entries to the backup_ids table.
2014-06-06 10:44:19 +01:00
Jenny Gray 807c670765 MDL-45846 Libraries Reinstate custom user agent device detection 2014-06-06 10:04:27 +01:00
Frederic Massart 36cef83e08 MDL-45870 mod_assign: Outcomes are saved for each group member 2014-06-06 12:26:27 +08:00
Daniel Neis Araujo 877ce4a64d MDL-35648 (backport) adding missing distinct selector in sql on participation report 2014-06-05 20:45:12 -03:00
Nobelium a5a3c48851 MDL-42835 mod_scorm: Close tree nodes using TreeView API 2014-06-05 22:30:29 +00:00
Sam Chaffee 464280a23d MDL-45767: Fixed DB error when returning to course from external tool
The instance ID is not always returned from the external
tool provider.
2014-06-05 09:38:46 -07:00
Eloy Lafuente (stronk7) afce57cbea weekly release 2.6.3+ 2014-06-05 16:58:45 +02:00
Eloy Lafuente (stronk7) 6e3438036a Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-06-05 16:58:39 +02:00
Michael de Raadt 0d7ed311f8 MDL-44309 Administration - correcting inproperly assigned column classes in environment table 2014-06-05 10:44:06 +08:00
Eric Merrill 52878b707a MDL-20154 questions: question_delete_question should not check perms
By Moodle convention, library functions should not implement permission
checks, they are to be handled by the invoking code.
2014-06-04 17:45:05 -04:00
Eric Merrill 3616569d45 MDL-20154 quiz: Remove unused random questions
When a random question is removed from a quiz, and it is not
in use elsewhere, it should be deleted.

Conflicts:
	mod/quiz/editlib.php
	mod/quiz/lib.php
2014-06-04 17:45:02 -04:00
Mark Nielsen a6afe639ca MDL-45764 mod_lti: Fix adding General Tool
This error only occurs when a ltisource
plugin is present that implements the
get_types callback.
2014-06-04 08:10:56 -07:00
Eric Merrill 200862ff6e MDL-39726 backup: Move question files by context, not one at a time
Use question category contexts to send file to the file pool in bulk.
Questions are only restored in whole category chunks, so this is safe
to do.
2014-06-04 09:20:05 -04:00
Adrian Greeve 7de5920dd8 MDL-44501 mod_data: Only attempt to export files when a file exists.
The error only occurs when portfolios are enabled and there is only one field which is
a file field.
2014-06-04 15:31:34 +08:00
Frederic Massart ed94a2affd MDL-45579 group: Behat tests to cover group enrolment key rules 2014-06-04 15:12:04 +08:00
Frederic Massart e2f577e074 MDL-45579 group: Prevent duplicate enrolment keys in course groups 2014-06-04 15:12:03 +08:00
Andrew Nicols 0ad0ddd1ea MDL-18162 mod_forum: Correct @param type in phpdoc to use stdClass 2014-06-04 11:26:19 +08:00
Eloy Lafuente (stronk7) 9a5044fa5c Merge branch 'MDL-44620_26' of git://github.com/dmonllao/moodle into MOODLE_26_STABLE 2014-06-03 18:11:56 +02:00
Dan Poltawski 7c3e7cdae9 Merge branch '45333-26' of git://github.com/samhemelryk/moodle into MOODLE_26_STABLE 2014-06-03 15:26:03 +01:00
Eloy Lafuente (stronk7) acfc4c0b4d Merge branch 'MDL-42953-26' of git://github.com/phalacee/moodle into MOODLE_26_STABLE 2014-06-03 12:11:52 +02:00
Damyon Wiese 65f3549893 Merge branch 'MDL-45592_26' of git://github.com/grabs/moodle into MOODLE_26_STABLE 2014-06-03 16:22:07 +08:00
Damyon Wiese 50df05ef78 Merge branch 'm26_MDL-44098' of git://github.com/greg-or/moodle-mod_assign into MOODLE_26_STABLE 2014-06-03 13:10:16 +08:00
Damyon Wiese 322a1fa453 Merge branch 'MDL-45781_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-06-03 11:58:52 +08:00
Jetha Chan 15601a33d9 MDL-42782 usability: fix for extreme course page indenting 2014-06-03 11:16:36 +08:00
Sam Hemelryk 42a1546bf8 Merge branch 'MDL-18162-26' of git://github.com/andrewnicols/moodle into MOODLE_26_STABLE 2014-06-03 15:00:31 +12:00
Eric Merrill 0babaf208d MDL-45714 backup: Less aggressive removal of old backup dirs
The old 4 hour standard was too aggressive and can cause backup files
to be removed while they were still in use. Now the same as cron,
1 week.
2014-06-02 21:50:54 -04:00
Eloy Lafuente (stronk7) 9514d99333 Merge branch 'm26_MDL-45726' of https://github.com/danmarsden/moodle into MOODLE_26_STABLE 2014-06-03 02:20:02 +02:00
Sam Hemelryk b51ee5ac52 Merge branch 'MDL-33763-26' of git://github.com/ankitagarwal/moodle into MOODLE_26_STABLE 2014-06-03 08:57:35 +12:00
Eric Merrill 2f4815a05b MDL-45763 question Random qtype should use '0' or '1' question text.
Some time ago, it when from using '0' for no-subcategories to blank.
Change to properly define '0' or '1', update old questions, and make
sure to fix newly restored questions.

Conflicts:
	mod/quiz/editlib.php
	question/type/random/version.php
2014-06-02 15:35:40 -04:00
Albert Gasset 1a997d4b11 MDL-35514 mod_forum: Fixed warning message to students in forums with groups 2014-06-02 18:25:40 +02:00
Tim Hunt d03434111a MDL-45781 quiz autosave: detect and report when the session is lost.
and also other errors.
2014-05-30 16:30:16 +01:00
AMOS bot 888d681014 Automatically generated installer lang files 2014-05-30 01:24:34 +00:00
AMOS bot 2dbb5e22f7 Automatically generated installer lang files 2014-05-30 01:24:34 +00:00
Ciaran Irvine 49c4454cec MDL-45726 SCORM: Correct check for forcenewattempt 2014-05-30 09:49:18 +12:00
Sam Hemelryk 19a43c48bf MDL-45333 output: navbar is now wrapped in a <nav> tag 2014-05-30 08:41:39 +12:00
Andreas Grabs 4532c861e1 MDL-45592 mod_feedback - unwanted linebreak after import or duplicating a feedback 2014-05-29 17:15:48 +02:00
Eloy Lafuente (stronk7) 1132d30d1f weekly release 2.6.3+ 2014-05-29 12:51:33 +02:00
Eloy Lafuente (stronk7) 6e415f6a59 Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-05-29 12:51:28 +02:00
Damyon Wiese a42f023698 MDL-45654 Cron: Fix for unit test that was causing integer overflow in 32 bit php 2014-05-29 16:30:06 +12:00
Sam Hemelryk 18c31e25b6 Merge branch 'wip-mdl-45698-m26' of https://github.com/rajeshtaneja/moodle into MOODLE_26_STABLE 2014-05-29 14:28:07 +12:00
Rajesh Taneja 6a46c626d6 MDL-45698 behat: Fixed behat and symfony versions 2014-05-29 09:49:20 +08:00
Sam Hemelryk 321a4a90ab MDL-45654 cron: fixed dataprovider timestamp issue 2014-05-29 11:21:05 +12:00
Sam Hemelryk bc389ac7c8 Merge branch 'wip-mdl-45565-m26' of https://github.com/rajeshtaneja/moodle into MOODLE_26_STABLE 2014-05-29 08:12:37 +12:00
Andrew Nicols 54c9783e5c MDL-45560 report_log: Close sessions before download only
If the session is closed too early, then preferences made in the body of
the page will not be saved to the session.
2014-05-29 01:02:25 +08:00
Andrew Nicols 646021e728 MDL-18162 mod_forum: Correct phpdoc for forum_clean_search_terms 2014-05-28 09:36:02 +08:00
Dan Poltawski 56f23662b1 Merge branch 'MDL-45544-26' of git://github.com/lameze/moodle into MOODLE_26_STABLE 2014-05-27 07:50:03 +01:00
David Monllao e002c90dab MDL-44620 behat: Automate MDLQA-7
- MDLQA-7: By default, a new course contains a Latest
News block which displays a specific number of recent
discussions from the news forum
2014-05-27 13:13:48 +07:00
David Monllao 94ba162660 MDL-44620 behat: Automates MDLQA-6
- MDLQA-6: By default, a new course contains a news
forum in which only teachers can post and subscription
is forced
2014-05-27 13:13:48 +07:00
Rajesh Taneja b24571ea7d MDL-45565 phpunit: Changed testsuite_name, so as to avoid class collision 2014-05-27 09:50:21 +08:00
Rajesh Taneja d160b700e8 MDL-45565 core_message: Reset internal users in phpunit 2014-05-27 09:50:21 +08:00
Gregory Faller 33f29f5adc MDL-44098: Late submissions with extension calculate period of lateness incorrectly 2014-05-27 11:08:29 +09:30
Dan Poltawski c5549ab475 Merge branch 'MDL-45676_m26' of https://github.com/markn86/moodle into MOODLE_26_STABLE 2014-05-26 12:02:43 +01:00
Dan Poltawski 1ec46dca1d Merge branch 'MDL-45675_m26' of https://github.com/markn86/moodle into MOODLE_26_STABLE 2014-05-26 11:59:26 +01:00
Marina Glancy a8b6eaa3c4 Merge branch 'MDL-45661-26' of git://github.com/damyon/moodle into MOODLE_26_STABLE 2014-05-26 14:46:55 +08:00
Marina Glancy 25f6bc111d Merge branch 'MDL-44482-26' of git://github.com/jethac/moodle into MOODLE_26_STABLE 2014-05-26 14:46:47 +08:00
Simey Lameze 7874aa6eb7 MDL-45544 events: Add event user_profile_viewed trigger to user/profile.php 2014-05-26 14:10:59 +08:00
Jetha Chan addeb650b9 MDL-44482 mod_lti: use localized dates
Fixed an issue where LTI external tools had creation datestamps of NaN/NaN/NaN under particular non-English languages.
2014-05-26 14:01:05 +08:00
Damyon Wiese c3131a4ac2 Merge branch 'wip-MDL-45688-m26' of git://github.com/marinaglancy/moodle into MOODLE_26_STABLE 2014-05-26 12:48:33 +08:00
Damyon Wiese d60e4f6684 MDL-45661 Assign: Clean bad data from DB after MDL-42526
Conflicts:
	mod/assign/db/upgrade.php
	mod/assign/version.php
2014-05-26 12:37:19 +08:00
Damyon Wiese cd2297972b Merge branch '45499-26' of git://github.com/samhemelryk/moodle into MOODLE_26_STABLE 2014-05-26 12:13:02 +08:00
Marina Glancy 7c399a1ba0 Merge branch 'MDL-44014-26' of git://github.com/andrewnicols/moodle into MOODLE_26_STABLE 2014-05-26 11:59:47 +08:00
Ankit Agarwal 1b308f725a MDL-33763 notes: Fix issue with incorrect node highlighting in the nav tree 2014-05-26 10:41:51 +08:00
Mark Nelson 47235557d2 MDL-45675 mod_data: initialise options as an empty array to avoid error when there are none 2014-05-25 19:29:39 -07:00
Sam Hemelryk 5abf0019f5 Merge branch 'MDL-45650_m26' of https://github.com/markn86/moodle into MOODLE_26_STABLE 2014-05-26 13:59:14 +12:00
Sam Hemelryk 7ec197fd64 Merge branch 'MDL-45192_26' of git://github.com/dmonllao/moodle into MOODLE_26_STABLE 2014-05-26 13:23:06 +12:00
Sam Hemelryk 967d16dd52 Merge branch 'MDL-45660_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-05-26 11:52:35 +12:00
Sam Hemelryk 5b4b64fc58 Merge branch 'MDL-45686_26' of git://github.com/jmvedrine/moodle into MOODLE_26_STABLE 2014-05-26 10:55:14 +12:00
Sam Hemelryk 362598367c Merge branch 'MDL-45635-26' of git://github.com/andrewnicols/moodle into MOODLE_26_STABLE
Conflicts:
	lib/yui/src/notification/js/confirm.js
2014-05-26 10:38:22 +12:00
Sam Hemelryk 43b611f566 Merge branch 'm26_MDL-45623' of git://github.com/totara/moodle into MOODLE_26_STABLE 2014-05-26 09:58:59 +12:00
Sam Hemelryk 9832d18ab5 Merge branch 'MDL-45607_m26' of https://github.com/markn86/moodle into MOODLE_26_STABLE 2014-05-26 09:53:46 +12:00
Sam Hemelryk 201d502a9b Merge branch 'MDL-42526-26' of git://github.com/jamiepratt/moodle into MOODLE_26_STABLE 2014-05-26 09:02:49 +12:00
Sam Hemelryk 53bdea7476 MDL-45499 admin: fixed error when displaying page settings 2014-05-26 09:01:09 +12:00
Sam Hemelryk 1a49438ade Merge branch 'MDL-45654-26' of https://github.com/rtcn2/moodle into MOODLE_26_STABLE 2014-05-26 08:58:08 +12:00
Jean-Michel Vedrine 4fb94f7f96 MDL-45686 qtype_multichoice get_num_selected_choices return wrong result 2014-05-25 09:15:21 +02:00
Marina Glancy 5638eb7c35 MDL-45688 added missing library requirement 2014-05-24 18:30:28 +08:00
Rajesh Taneja 543ef5fa7c MDL-45565 core_message: Added unit tests. 2014-05-23 16:47:50 +08:00
Rajesh Taneja c27601c459 MDL-45565 core_message: Fixed strangers array
Strangers get mixed with noreply user and support user,
if  noreply/support users real user.
To avoid duplication use userid as array index. Also,
avoid fetching data again for noreply and support users,
if they are real users, then data is already feteched.
2014-05-23 16:47:43 +08:00
Andrew Nicols 6c66c20107 MDL-45635 javascript: Make core dialogue translatable 2014-05-23 16:19:15 +08:00
Mark Nelson 7221132d11 MDL-45676 mod_data: added missing additional name fields 2014-05-22 22:00:15 -07:00
AMOS bot c38626b055 Automatically generated installer lang files 2014-05-23 00:52:52 +00:00
Tim Hunt 7d99d3e9c4 MDL-45660 question statistics: fix regression added by MDL-44981.
Also, make comparison more robust.
2014-05-22 16:16:03 +01:00
Eloy Lafuente (stronk7) 529d4cdbc6 weekly release 2.6.3+ 2014-05-22 16:47:12 +02:00
Eloy Lafuente (stronk7) cd07fceed1 Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-05-22 16:47:07 +02:00
James Pratt 26ae6e5792 MDL-42526 mod_assignment : fix record insert with assigment.id 0 2014-05-22 12:54:45 +07:00
AMOS bot 217613ab21 Automatically generated installer lang files 2014-05-22 01:08:09 +00:00
Simon Coggins c017cc5ca9 MDL-45623: Fix assigned users count on role delete confirmation page 2014-05-22 08:16:46 +12:00
Rod Norfor 03966a4ec0 MDL-45654 cron: fix non-empty directories deletion
Remove errors when attempting to delete non-empty directories when
    child directories do not get removed since the mtime was updated when
    files were removed from the child directory.
2014-05-21 17:24:02 +01:00
Sam Hemelryk b1cb63b24f MDL-44711 course: fixed navigation expansion in course tests 2014-05-21 20:58:35 +12:00
Mark Nelson ec373efd6d MDL-45650 events: ensure correct objectid passed when triggering user_profile_viewed event 2014-05-21 00:25:48 -07:00
Mark Nelson 4a9dcf3f17 MDL-45607 events: changed the context passed to the user_profile_viewed event 2014-05-20 21:13:28 -07:00
Marina Glancy f01e4739fd MDL-45469 profile: make sure profile fields can be initialised without arguments 2014-05-21 11:53:53 +08:00
Dan Poltawski 7d5774aaa2 Merge branch 'wip-MDL-45371-m26' of git://github.com/marinaglancy/moodle into MOODLE_26_STABLE 2014-05-21 10:03:09 +08:00
Marina Glancy 7a562bf521 MDL-45320 behat: change to block selector 2014-05-20 20:52:37 +08:00
Marina Glancy 0c11e7ed30 MDL-45320 block_html: behat tests 2014-05-20 20:52:14 +08:00
Marina Glancy a33bc20d2e MDL-45320 behat: Step definitions for blocks 2014-05-20 20:52:01 +08:00
David Monllao e3353f92fc MDL-45294 behat: Updating block references to aria label value
Also improving moodle selectors xpath expressions
readability.
2014-05-20 20:47:48 +08:00
David Monllao 28e5ece329 MDL-45294 behat: Supporting an aria-label as a block ref 2014-05-20 20:47:48 +08:00
Dan Poltawski 239db05eec Merge branch '44711-26-r2' of git://github.com/samhemelryk/moodle into MOODLE_26_STABLE 2014-05-20 20:32:02 +08:00
Sam Hemelryk 4fc9f74029 MDL-44711 block_navigation: fixed typo in behat tests 2014-05-20 23:38:25 +12:00
Damyon Wiese e679a371ef MDL-45606 Unit test fix for MySQL and added a comment about the removed code. 2014-05-20 18:07:28 +08:00
Dan Poltawski af8bd4de8e Merge branch 'MDL-45496-m26' of https://github.com/micaherne/moodle into MOODLE_26_STABLE 2014-05-20 15:55:13 +08:00
Marina Glancy 1cbfc11612 Merge branch 'MDL-45525-26' of git://github.com/jethac/moodle into MOODLE_26_STABLE
Conflicts:
	theme/bootstrapbase/style/moodle.css
2014-05-20 14:30:14 +08:00
Marina Glancy bf75a73cc5 Merge branch 'MDL-45536-26' of git://github.com/andrewnicols/moodle into MOODLE_26_STABLE
Conflicts:
	theme/bootstrapbase/style/moodle.css
2014-05-20 14:26:31 +08:00
Marina Glancy 97dc7bfc0b Merge branch 'wip-MDL-45512-26' of git://github.com/abgreeve/moodle into MOODLE_26_STABLE 2014-05-20 14:22:51 +08:00
Marina Glancy f60c23a781 Merge branch 'MDL-43669-m26' of git://github.com/micaherne/moodle into MOODLE_26_STABLE 2014-05-20 14:16:27 +08:00
Marina Glancy 2b0b60631d Merge branch 'MDL-44333_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-05-20 14:11:57 +08:00
Andrew Nicols 51a6bf7f1a MDL-45536 theme: Use width auto for inputs and textareas specifying them 2014-05-20 14:08:58 +08:00
Damyon Wiese 2a6cc872ff Merge branch 'm26_MDL-45583' of github.com:danmarsden/moodle into MOODLE_26_STABLE 2014-05-20 13:30:37 +08:00
Damyon Wiese 350e34d177 Merge branch 'MDL-45323-26' of git://github.com/lameze/moodle into MOODLE_26_STABLE 2014-05-20 13:29:30 +08:00
Dan Poltawski 67f6ebacff Merge branch 'MDL-45545-26' of git://github.com/FMCorz/moodle into MOODLE_26_STABLE 2014-05-20 12:21:58 +08:00
Sam Hemelryk e77dcc602d Merge branch 'MDL-44323-26' of git://github.com/danpoltawski/moodle into MOODLE_26_STABLE
Conflicts:
	theme/bootstrapbase/less/moodle/admin.less
	theme/bootstrapbase/style/moodle.css
2014-05-20 15:45:21 +12:00
Sam Hemelryk aa1d665a3a Merge branch 'MDL-44027-26' of git://github.com/danpoltawski/moodle into MOODLE_26_STABLE 2014-05-20 15:39:31 +12:00
Dan Poltawski 2b0ea3051d Merge branch 'MDL-45605-26' of git://github.com/damyon/moodle into MOODLE_26_STABLE 2014-05-20 10:51:27 +08:00
Dan Poltawski fa496d3fe1 Merge branch 'MDL-45546-26' of git://github.com/FMCorz/moodle into MOODLE_26_STABLE 2014-05-20 10:24:40 +08:00
Dan Poltawski fa4ff1bd10 Merge branch '44711-26' of git://github.com/samhemelryk/moodle into MOODLE_26_STABLE 2014-05-20 10:14:24 +08:00
Sam Hemelryk 43f39c235f Merge branch 'MDL-45603-26' of https://github.com/merrill-oakland/moodle into MOODLE_26_STABLE 2014-05-20 13:59:33 +12:00
Marina Glancy 0e46c03356 Merge branch 'MDL-45469-m26' of git://github.com/sammarshallou/moodle into MOODLE_26_STABLE 2014-05-20 09:52:48 +08:00
Dan Poltawski 940269660f Merge branch 'MDL-44449_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-05-20 09:50:51 +08:00
Damyon Wiese 4c2ba6794b Merge branch '44974-26' of git://github.com/samhemelryk/moodle into MOODLE_26_STABLE 2014-05-20 09:01:24 +08:00
Sam Hemelryk 7d14ae30e9 Merge branch 'MDL-45477-m26' of https://github.com/sammarshallou/moodle into MOODLE_26_STABLE 2014-05-20 11:58:18 +12:00
Sam Hemelryk 8ffb738721 Merge branch 'MDL-45535-m26' of https://github.com/sammarshallou/moodle into MOODLE_26_STABLE 2014-05-20 11:55:47 +12:00
Sam Hemelryk cf1cf9499f Merge branch 'MDL-37838-26' of git://github.com/danpoltawski/moodle into MOODLE_26_STABLE 2014-05-20 10:42:19 +12:00
Sam Hemelryk d18bc9dc02 Merge branch 'MDL-45380-26' of git://github.com/FMCorz/moodle into MOODLE_26_STABLE
Conflicts:
	theme/bootstrapbase/style/moodle.css
2014-05-20 08:53:11 +12:00
Sam Hemelryk 17f8fb7f3e Merge branch 'MDL-45135-26' of git://github.com/danpoltawski/moodle into MOODLE_26_STABLE 2014-05-20 08:47:21 +12:00
Tim Hunt 969c26def0 MDL-44449 quiz access rules should have a delete hook.
So they can clean up their settings when the quiz is deleted.

See
https://github.com/moodleou/moodle-quizaccess_honestycheck/commit/babf149c2cc6dd734c272cd332b2032cc19db7d8
for an example of using this.
2014-05-19 16:59:21 +01:00
Damyon Wiese cbaad47bf2 Merge branch 'MDL-45472-26' of git://github.com/andrewnicols/moodle into MOODLE_26_STABLE 2014-05-19 20:47:49 +08:00
Damyon Wiese 9ccd8759ea Merge branch 'MDL-43833_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-05-19 20:12:20 +08:00
Damyon Wiese 5b26aca437 Merge branch 'MDL-45527-26' of git://github.com/FMCorz/moodle into MOODLE_26_STABLE 2014-05-19 20:07:00 +08:00
Damyon Wiese 2e0b5708f1 Merge branch 'MDL-45455_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-05-19 19:57:57 +08:00
Dan Poltawski ce400f61e6 Merge branch 'MDL-45432-MOODLE_26_STABLE' of https://github.com/lucisgit/moodle into MOODLE_26_STABLE 2014-05-19 18:43:17 +08:00
Michael Aherne 8257e19b7a MDL-43669 messaging Enable sending email only from no-reply address 2014-05-19 09:52:23 +01:00
Marina Glancy 8e73bb6328 MDL-45371 behat: Tests for block glossary_random 2014-05-19 15:20:10 +08:00
Dan Poltawski 2fa8db79cc Merge branch 'MDL-41109-26' of git://github.com/andrewnicols/moodle into MOODLE_26_STABLE 2014-05-19 15:07:53 +08:00
Dan Poltawski 1ad0beaf4f Merge branch 'wip-MDL-34914-m26' of git://github.com/marinaglancy/moodle into MOODLE_26_STABLE 2014-05-19 14:59:36 +08:00
Damyon Wiese 60802ff32e Merge branch 'MDL-32543-26' of https://github.com/danielneis/moodle into MOODLE_26_STABLE 2014-05-19 12:55:31 +08:00
Damyon Wiese b29da693b6 Merge branch 'MDL-23566_26' of https://github.com/aolley/moodle into MOODLE_26_STABLE 2014-05-19 12:43:45 +08:00
Marina Glancy 709f70145f Merge branch 'wip-MDL-45483-MOODLE_26_STABLE' of https://github.com/kwiliarty/moodle into MOODLE_26_STABLE 2014-05-19 12:38:47 +08:00
Damyon Wiese 9d14dcd64e Merge branch 'MDL-44634-26' of https://github.com/dbezborodovrp/moodle into MOODLE_26_STABLE 2014-05-19 12:20:38 +08:00
Frederic Massart da14c5dff1 MDL-45527 cron: Already deleted unconfirmed users are ignored 2014-05-19 12:06:49 +08:00
Damyon Wiese d38ef5cfe0 Merge branch '43995-26' of git://github.com/samhemelryk/moodle into MOODLE_26_STABLE 2014-05-19 11:53:34 +08:00
Sam Hemelryk e6e58c7a92 MDL-38923 theme_bootstrapbase: pre-integration fixups
* Fixed the way we added the block class to the dock panel in dock.js
* Added a class to the h2 that is used to test dock title width
* Fixed RTL alignment issues as best I could at present
* Fixed overlap of dock + navbar on small screens
* Fixed the docked block width to be constrained to the available space
* Fixed hidden actions on docked blocks

Conflicts:
	theme/bootstrapbase/style/moodle.css
2014-05-19 15:28:00 +12:00
Damyon Wiese eba90af0d3 MDL-45605 Phpunit: Do not call gc_collect_cycles as part of reset.
This takes 25% of the time in running tests and there is no benefit. The
behaviour of destructors is the same before/after the patch.
2014-05-19 10:38:39 +08:00
Sam Hemelryk 14f40dcc9c Merge branch 'MDL-45561-26' of git://github.com/jethac/moodle into MOODLE_26_STABLE 2014-05-19 13:37:19 +12:00
Sam Hemelryk 8758f4464f MDL-44974 admin: repositioned call to initialise renderer 2014-05-19 08:41:23 +12:00
Sam Hemelryk 9fb8de4cd1 MDL-44711 navigation: better handling of course expansion exception 2014-05-19 08:41:08 +12:00
Sam Hemelryk 0720ecb621 MDL-38923 dock: allowed for space before first time 2014-05-19 08:40:16 +12:00
Sam Hemelryk 6ae3b201cc MDL-38923 theme_bootstrapbase: tidied up dock implementation
Also:
* Changed to a CSS based compacting solution
* Converted dock colours to variables
* RTL fixes for the dock
2014-05-19 08:40:16 +12:00
Bas Brands 056b54ff63 MDL-38923 theme bootstrapbase: theme clean: enable docking 2014-05-19 08:40:13 +12:00
Eric Merrill 6a7348df5c MDL-45603 cache Fix the mappingsonly option to work as advertised. 2014-05-17 23:55:10 -04:00
Tim Hunt fc36e18fb1 MDL-44333 quiz reports: use consitent name for user pref
The Marks for each question setting was not being saved properly as a
user preference.
2014-05-17 15:10:55 +01:00
Marina Glancy 3febb9e672 MDL-34914 cohorts: more understandable filter of user list by cohort 2014-05-16 17:17:36 +08:00
Andrew Nicols ed065ceb93 MDL-41109 dndupload: Add missing error string 2014-05-16 13:50:19 +08:00
Dan Marsden 26143abeaf MDL-45583 badges: check parent contexts consistantly when checking required role. 2014-05-16 13:54:05 +12:00
Tim Hunt 9b3b40c1ab MDL-45455 quiz cron must rollback transaction on error. 2014-05-15 15:08:12 +01:00
Tim Hunt b7acb1f0e8 MDL-43833 quiz reports: persist states settings between pages. 2014-05-15 15:07:38 +01:00
Jetha Chan c7f36a87b3 MDL-45561 themes: horizontal scroll in RTL base 2014-05-15 15:49:28 +08:00
Damyon Wiese ba05f573ca weekly release 2.6.3+ 2014-05-15 15:34:13 +08:00
Damyon Wiese 967fe8ef0d Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-05-15 15:34:09 +08:00
Jason Fowler 4e37becc19 MDL-42953 Themes: Fixing CSS for headers of central blocks 2014-05-15 15:27:51 +08:00
Simey Lameze 60b664a624 MDL-45323 grade: Unit test for grade_get_grade_items_for_activity() 2014-05-15 15:05:40 +08:00
Simey Lameze b52ea3664e MDL-45323 grade: Fix query errors on grade_get_grade_for_activity method. 2014-05-15 15:05:40 +08:00
Damyon Wiese 9bbe953b68 MDL-41383 Filepicker: whitespace fix 2014-05-15 13:35:33 +08:00
Jetha Chan 5389652d3c MDL-41383: RTL fix for base when zoomed out 2014-05-15 13:29:32 +08:00
Dan Poltawski 247946725c MDL-44323 admin: use correct css class for warning
The notifyproblem notification is consistent with the rest of
the warnings we report.

Conflicts:
	theme/bootstrapbase/less/moodle/admin.less
	theme/bootstrapbase/style/moodle.css
2014-05-15 12:22:04 +08:00
Damien Bezborodov 649356958e MDL-44634 Regression: link to user profile in comments block fails due to double URI encoding 2014-05-15 11:47:03 +09:30
Damien Bezborodov 19602ce718 MDL-44634 Regression: link to user profile in comments block fails due to double URI encoding 2014-05-15 10:51:39 +09:30
sam marshall d355d1f796 MDL-45535 CSS chunking breaks media rules if CSS invalid (IE)
Invalid CSS with extra } symbols, which previously (by fluke)
worked, was broken by recent chunking improvements. This change
makes the chunking code robust against this (stupid) situation.
2014-05-14 12:19:10 +01:00
sam marshall 449693fc43 MDL-45477 Behat: List of steps takes too long to load, times out
Increase time limit to 300 seconds (5 minutes).
2014-05-14 10:59:49 +01:00
Marina Glancy 2538062907 Merge branch 'MDL-36670_26' of git://github.com/jleyva/moodle into MOODLE_26_STABLE 2014-05-14 16:35:59 +08:00
Frederic Massart ada3d03f67 MDL-45546 mod_forum: Login the user before getting its context 2014-05-14 16:17:09 +08:00
Frederic Massart e505b12188 MDL-45545 csslib: Chunking handles commas in media query definitions 2014-05-14 15:27:37 +08:00
Jetha Chan 9a6a761e1c MDL-41383 theme: filepicker zoom resiliency (base)
Fixed an issue that broke the file picker on base when initial zoom level is less than 100%.
2014-05-14 14:36:01 +08:00
Juan Leyva a9d792433f MDL-36670 logging: action parameter length restricted to 40 chars 2014-05-13 16:13:56 +02:00
David Monllao fa58e13891 MDL-45192 behat: Replacing specific-selector steps by a generic one
Having a I click on we can use all our selectors rather
than having multiple steps for the same purpose. This
step allow us to manage JS native dialogues without
having to fail a scenario.

Credit for Mohamed Alsharaf.
2014-05-13 20:37:39 +07:00
Mohamed Alsharaf 015f49d0d3 MDL-45192 assign: added behat script & new definitions to handle alert dialog
The behat script is to test the batch action to lock and unlock submissions.
The new definitions are to prevent the "unexpected alert open" error in Selenium.
2014-05-13 20:37:38 +07:00
Dan Poltawski 70dce3f450 MDL-44027 groups: remove some junk html 2014-05-13 16:19:53 +08:00
Damyon Wiese 3d5413d89a Merge branch 'MDL-41383-26' of git://github.com/jethac/moodle into MOODLE_26_STABLE 2014-05-13 15:56:12 +08:00
Jetha Chan 2c638ccb24 MDL-45525 themes: minor forum improvements
Fixed an RTL style that wasn't kicking in properly.
2014-05-13 14:35:20 +08:00
Dan Poltawski 5016d9f4b7 MDL-37838 block_courseoverview: fix pluaralisation logic
Note that this kind of handling of plurals is extremely limited, see:

https://moodle.org/mod/forum/discuss.php?d=85897
http://search.cpan.org/~petdance/Locale-Maketext-1.12/lib/Locale/Maketext/TPJ13.pod

However, this is a simple fix to the existing logic
2014-05-13 14:18:38 +08:00
Jetha Chan 9814a667ba MDL-41383 theme: filepicker zoom resiliency
Fixed an issue that broke the file picker on bootstrapbase when zooming in and out.
2014-05-13 14:12:13 +08:00
Adrian Greeve 5be375c379 MDL-45512 comments: Added full date to comment details. 2014-05-13 10:43:46 +08:00
Daniel Neis Araujo c5d0fcbf1f MDL-32543 (backport) Make sure the action and url fields of log table have correct sizes 2014-05-12 12:21:49 -03:00
Daniel Neis Araujo 3414e35610 Merge remote-tracking branch 'moodle/MOODLE_26_STABLE' into MOODLE_26_STABLE 2014-05-12 12:18:51 -03:00
Dan Poltawski c16cb40555 MDL-45135 mod_glossary: fix RTL alignment of table
Tablelib has a specific 'hook' to allow alignment to be corrected for
RTL languages, but needs to be specified direction in lowercase.
2014-05-12 17:09:43 +08:00
Frederic Massart 33c4973c67 MDL-45380 theme_bootstrapbase: Restore config override highlight
Conflicts:

	theme/bootstrapbase/less/moodle/admin.less
	theme/bootstrapbase/style/moodle.css
2014-05-12 15:52:43 +08:00
Michael Aherne 72fcbcd444 MDL-45496 core Added space to logged in as line 2014-05-12 08:51:06 +01:00
Rajesh Taneja 167136718e MDL-45514 behat: Fixed should_not_exist timout param 2014-05-12 14:14:35 +08:00
Kevin Wiliarty 7d80ee4455 MDL-45483 mod_forum: corrects values for maxattachments in forum settings 2014-05-12 00:00:18 -04:00
AMOS bot 49b427eda0 Automatically generated installer lang files 2014-05-12 00:39:49 +00:00
AMOS bot 5fe214d9d8 Automatically generated installer lang files 2014-05-11 00:47:52 +00:00
sam marshall f6d6df37b6 MDL-45469 Conditional availability: Restrict by text area broken
It has never worked, because the data for text area fields is not
loaded into the $USER object.

Changing it so that the dropdown list does not include these types
of field. (This 2.6 version of change is similar to the 2.7 code
but in a different location and without unit test.)
2014-05-08 14:04:35 +01:00
Andrew Nicols c8097f88a5 MDL-45472 AJAX: Whitelist prototype values form JS Error in exception dialogue 2014-05-08 16:45:59 +08:00
Tony Butler cbeee0a46e MDL-45432 mod_assign Declare character encoding in onlinetext export
Signed-off-by: Tony Butler <tonyjbutler@gmail.com>
2014-05-07 13:12:26 +01:00
Adam Olley 2be96ee2d1 MDL-23566 mod_lesson: Float answers so paragraphs line up correctly next to the inputs 2014-05-07 15:45:55 +09:30
Daniel Neis Araujo a661cc9113 MDL-45245 html_writer::select_time does not respect 5th parameter "attributes" 2014-04-23 14:56:40 -03:00
Mark Nielsen 9b9226fc98 MDL-44014 Navigation: Set the correct context when retrieved via AJAX 2014-02-10 11:45:44 +08:00
351 changed files with 6834 additions and 1571 deletions
+18 -19
View File
@@ -97,27 +97,26 @@ foreach ($settingspage->children as $childpage) {
$outputhtml .= $OUTPUT->heading(html_writer::link($childpage->url, $childpage->visiblename), 3);
} else if ($childpage instanceof admin_settingpage) {
$outputhtml .= $OUTPUT->heading(html_writer::link(new moodle_url('/'.$CFG->admin.'/settings.php', array('section' => $childpage->name)), $childpage->visiblename), 3);
// If its a settings page and has settings lets display them.
if (!empty($childpage->settings)) {
$outputhtml .= html_writer::start_tag('fieldset', array('class' => 'adminsettings'));
foreach ($childpage->settings as $setting) {
if (empty($setting->nosave)) {
$savebutton = true;
}
$fullname = $setting->get_full_name();
if (array_key_exists($fullname, $adminroot->errors)) {
$data = $adminroot->errors[$fullname]->data;
} else {
$data = $setting->get_setting();
}
$outputhtml .= html_writer::tag('div', '<!-- -->', array('class' => 'clearer'));
$outputhtml .= $setting->output_html($data);
}
$outputhtml .= html_writer::end_tag('fieldset');
}
} else if ($childpage instanceof admin_category) {
$outputhtml .= $OUTPUT->heading(html_writer::link(new moodle_url('/'.$CFG->admin.'/category.php', array('category' => $childpage->name)), get_string('admincategory', 'admin', $childpage->visiblename)), 3);
} else {
continue;
}
if (!empty($childpage->settings)) {
$outputhtml .= html_writer::start_tag('fieldset', array('class' => 'adminsettings'));
foreach ($childpage->settings as $setting) {
if (empty($setting->nosave)) {
$savebutton = true;
}
$fullname = $setting->get_full_name();
if (array_key_exists($fullname, $adminroot->errors)) {
$data = $adminroot->errors[$fullname]->data;
} else {
$data = $setting->get_setting();
}
$outputhtml .= html_writer::tag('div', '<!-- -->', array('class' => 'clearer'));
$outputhtml .= $setting->output_html($data);
}
$outputhtml .= html_writer::end_tag('fieldset');
}
}
if ($savebutton) {
+1 -9
View File
@@ -201,17 +201,9 @@ if (defined('COMPONENT_CLASSLOADER')) {
require($CFG->dirroot.'/version.php');
$CFG->target_release = $release;
$_SESSION = array();
$_SESSION['SESSION'] = new stdClass();
$_SESSION['SESSION']->lang = $CFG->lang;
$_SESSION['USER'] = new stdClass();
$_SESSION['USER']->id = 0;
$_SESSION['USER']->mnethostid = 1;
\core\session\manager::init_empty_session();
global $SESSION;
global $USER;
$SESSION = &$_SESSION['SESSION'];
$USER = &$_SESSION['USER'];
global $COURSE;
$COURSE = new stdClass();
+5 -3
View File
@@ -382,9 +382,6 @@ if (!$cache and moodle_needs_upgrading()) {
if (!$PAGE->headerprinted) {
// means core upgrade or installation was not already done
/** @var core_admin_renderer $output */
$output = $PAGE->get_renderer('core', 'admin');
if (!$confirmplugins) {
$strplugincheck = get_string('plugincheck');
@@ -402,6 +399,9 @@ if (!$cache and moodle_needs_upgrading()) {
redirect($PAGE->url);
}
/** @var core_admin_renderer $output */
$output = $PAGE->get_renderer('core', 'admin');
$deployer = \core\update\deployer::instance();
if ($deployer->enabled()) {
$deployer->initialize($PAGE->url, $PAGE->url);
@@ -425,6 +425,8 @@ if (!$cache and moodle_needs_upgrading()) {
// Make sure plugin dependencies are always checked.
$failed = array();
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
/** @var core_admin_renderer $output */
$output = $PAGE->get_renderer('core', 'admin');
$reloadurl = new moodle_url('/admin/index.php', array('cache' => 0));
echo $output->unsatisfied_dependencies_page($version, $failed, $reloadurl);
die();
+1 -1
View File
@@ -1369,7 +1369,7 @@ class core_admin_renderer extends plugin_renderer_base {
get_string('report'),
get_string('status'),
);
$servertable->colclasses = array('centeralign name', 'centeralign status', 'leftalign report', 'centeralign info');
$servertable->colclasses = array('centeralign name', 'centeralign info', 'leftalign report', 'centeralign status');
$servertable->attributes['class'] = 'admintable environmenttable generaltable';
$servertable->id = 'serverstatus';
+2 -2
View File
@@ -176,7 +176,7 @@ if ($roleid) {
// Show UI for assigning a particular role to users.
// Print a warning if we are assigning system roles.
if ($context->contextlevel == CONTEXT_SYSTEM) {
echo $OUTPUT->box(get_string('globalroleswarning', 'core_role'));
echo $OUTPUT->notification(get_string('globalroleswarning', 'core_role'));
}
// Print the form.
@@ -251,7 +251,7 @@ if ($roleid) {
// Print a warning if we are assigning system roles.
if ($context->contextlevel == CONTEXT_SYSTEM) {
echo $OUTPUT->box(get_string('globalroleswarning', 'core_role'));
echo $OUTPUT->notification(get_string('globalroleswarning', 'core_role'));
}
// Print instruction.
+10 -2
View File
@@ -74,8 +74,16 @@ abstract class core_role_capability_table_base {
public function display() {
if (count($this->capabilities) > self::NUM_CAPS_FOR_SEARCH) {
global $PAGE;
$PAGE->requires->strings_for_js(array('filter', 'clear'), 'moodle');
$PAGE->requires->js_init_call('M.core_role.init_cap_table_filter', array($this->id, $this->context->id));
$jsmodule = array(
'name' => 'rolescapfilter',
'fullpath' => '/admin/roles/module.js',
'strings' => array(
array('filter', 'moodle'),
array('clear', 'moodle'), ),
'requires' => array('node', 'cookie', 'escape')
);
$PAGE->requires->js_init_call('M.core_role.init_cap_table_filter', array($this->id, $this->context->id), false,
$jsmodule);
}
echo '<table class="' . implode(' ', $this->classes) . '" id="' . $this->id . '">' . "\n<thead>\n";
echo '<tr><th class="name" align="left" scope="col">' . get_string('capability', 'core_role') . '</th>';
+2 -1
View File
@@ -75,7 +75,8 @@ switch ($action) {
$a->id = $roleid;
$a->name = $roles[$roleid]->name;
$a->shortname = $roles[$roleid]->shortname;
$a->count = $DB->count_records('role_assignments', array('roleid'=>$roleid));
$a->count = $DB->count_records_select('role_assignments',
'roleid = ?', array($roleid), 'COUNT(DISTINCT userid)');
$formcontinue = new single_button(new moodle_url($baseurl, $optionsyes), get_string('yes'));
$formcancel = new single_button(new moodle_url($baseurl), get_string('no'), 'get');
+1 -1
View File
@@ -51,7 +51,7 @@ M.core_role.init_cap_table_filter = function(Y, tableid, contextid) {
marginRight : 'auto'
});
// Create the capability search input.
this.input = Y.Node.create('<input type="text" id="'+this.table.get('id')+'capabilitysearch" value="'+filtervalue+'" />');
this.input = Y.Node.create('<input type="text" id="'+this.table.get('id')+'capabilitysearch" value="'+Y.Escape.html(filtervalue)+'" />');
// Create a label for the search input.
this.label = Y.Node.create('<label for="'+this.input.get('id')+'">'+M.str.moodle.filter+' </label>');
// Create a clear button to clear the input.
-1
View File
@@ -139,7 +139,6 @@ if (optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey()) {
array(
'context' => $context,
'objectid' => $roleid,
'courseid' => $courseid
)
);
+3 -2
View File
@@ -80,7 +80,8 @@ class behat_admin extends behat_base {
// Single element settings.
try {
$fieldxpath = "//*[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]" .
"[@id=//label[contains(normalize-space(.), $label)]/@for]";
"[@id=//label[contains(normalize-space(.), $label)]/@for or " .
"@id=//span[contains(normalize-space(.), $label)]/preceding-sibling::label[1]/@for]";
$fieldnode = $this->find('xpath', $fieldxpath, $exception);
$formfieldtypenode = $this->find('xpath', $fieldxpath . "/ancestor::div[@class='form-setting']" .
@@ -89,7 +90,7 @@ class behat_admin extends behat_base {
} catch (ElementNotFoundException $e) {
// Multi element settings, interacting only the first one.
$fieldxpath = "//descendant::label[.= $label]/ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' form-item ')]" .
$fieldxpath = "//*[label[.= $label]|span[.= $label]]/ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' form-item ')]" .
"/descendant::div[@class='form-group']/descendant::*[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]";
$fieldnode = $this->find('xpath', $fieldxpath);
@@ -0,0 +1,27 @@
@core @core_admin
Feature: Set admin settings value
In order to set admin settings value
As an admin
I need to set admin setting value and verify it is applied
Background:
Given the following "courses" exist:
| fullname | shortname | category |
| Course fullname | C_shortname | 0 |
And I log in as "admin"
And I should see "Course fullname"
And I should not see "C_shortname Course fullname"
Scenario: set admin value with full name
Given I set the following administration settings values:
| Display extended course names | 1 |
When I press "Save changes"
And I am on homepage
Then I should see "C_shortname Course fullname"
Scenario: set admin value with short name
Given I set the following administration settings values:
| courselistshortnames | 1 |
When I press "Save changes"
And I am on homepage
Then I should see "C_shortname Course fullname"
+5
View File
@@ -27,6 +27,11 @@ require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->dirroot . '/' . $CFG->admin . '/tool/behat/locallib.php');
require_once($CFG->libdir . '/behat/classes/behat_config_manager.php');
// This page usually takes an exceedingly long time to load, so we need to
// increase the time limit. At present it takes about a minute on some
// systems, but let's allow room for expansion.
set_time_limit(300);
$filter = optional_param('filter', '', PARAM_ALPHANUMEXT);
$type = optional_param('type', false, PARAM_ALPHAEXT);
$component = optional_param('component', '', PARAM_ALPHAEXT);
+8 -2
View File
@@ -669,7 +669,7 @@ if ($formdata = $mform2->is_cancelled()) {
if ($doupdate or $existinguser->password !== $oldpw) {
// We want only users that were really updated.
user_update_user($existinguser, false);
user_update_user($existinguser, false, false);
$upt->track('status', $struserupdated);
$usersupdated++;
@@ -687,6 +687,9 @@ if ($formdata = $mform2->is_cancelled()) {
}
}
// Trigger event.
\core\event\user_updated::create_from_userid($existinguser->id)->trigger();
} else {
// no user information changed
$upt->track('status', $struseruptodate);
@@ -800,7 +803,7 @@ if ($formdata = $mform2->is_cancelled()) {
$upt->track('password', '-', 'normal', false);
}
$user->id = user_create_user($user, false);
$user->id = user_create_user($user, false, false);
$upt->track('username', html_writer::link(new moodle_url('/user/profile.php', array('id'=>$user->id)), s($user->username)), 'normal', false);
// pre-process custom profile menu fields data from csv file
@@ -815,6 +818,9 @@ if ($formdata = $mform2->is_cancelled()) {
set_user_preference('create_password', 1, $user);
}
// Trigger event.
\core\event\user_created::create_from_userid($user->id)->trigger();
$upt->track('status', $struseradded);
$upt->track('id', $user->id, 'normal', false);
$usersnew++;
+18 -3
View File
@@ -167,12 +167,27 @@ class auth_plugin_cas extends auth_plugin_ldap {
*
*/
function prelogout_hook() {
global $CFG;
global $CFG, $USER, $DB;
if (!empty($this->config->logoutcas)) {
if (!empty($this->config->logoutcas) && $USER->auth == $this->authtype) {
$backurl = $CFG->wwwroot;
$this->connectCAS();
phpCAS::logoutWithURL($backurl);
// Note: Hack to stable versions to trigger the event before it redirect to CAS logout.
$sid = session_id();
$event = \core\event\user_loggedout::create(
array(
'userid' => $USER->id,
'objectid' => $USER->id,
'other' => array('sessionid' => $sid),
)
);
if ($session = $DB->get_record('sessions', array('sid' => $sid))) {
$event->add_record_snapshot('sessions', $session);
}
\core\session\manager::terminate_current();
$event->trigger();
phpCAS::logoutWithRedirectService($backurl);
}
}
+11
View File
@@ -384,6 +384,10 @@ class auth_plugin_db extends auth_plugin_base {
if ($old_user = $DB->get_record('user', array('username'=>$username, 'deleted'=>0, 'suspended'=>1, 'mnethostid'=>$CFG->mnet_localhost_id, 'auth'=>$this->authtype))) {
$DB->set_field('user', 'suspended', 0, array('id'=>$old_user->id));
$trace->output(get_string('auth_dbreviveduser', 'auth_db', array('name'=>$username, 'id'=>$old_user->id)), 1);
// Trigger user_updated event.
\core\event\user_updated::create_from_userid($old_user->id)->trigger();
continue;
}
}
@@ -410,6 +414,10 @@ class auth_plugin_db extends auth_plugin_base {
}
try {
$id = $DB->insert_record ('user', $user); // it is truly a new user
// Trigger user_created event.
\core\event\user_created::create_from_userid($id)->trigger();
$trace->output(get_string('auth_dbinsertuser', 'auth_db', array('name'=>$user->username, 'id'=>$id)), 1);
} catch (moodle_exception $e) {
$trace->output(get_string('auth_dbinsertusererror', 'auth_db', $user->username), 1);
@@ -547,6 +555,9 @@ class auth_plugin_db extends auth_plugin_base {
}
if ($updated) {
$DB->set_field('user', 'timemodified', time(), array('id'=>$userid));
// Trigger user_updated event.
\core\event\user_updated::create_from_userid($userid)->trigger();
}
return $DB->get_record('user', array('id'=>$userid, 'deleted'=>0));
}
+1 -1
View File
@@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die();
class auth_db_testcase extends advanced_testcase {
protected function init_auth_database() {
public function init_auth_database() {
global $DB, $CFG;
require_once("$CFG->dirroot/auth/db/auth.php");
+150
View File
@@ -0,0 +1,150 @@
<?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/>.
/**
* Events tests.
*
* @package auth_db
* @category test
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/auth/db/tests/db_test.php');
class auth_db_events_testcase extends advanced_testcase {
/**
* Test set up.
*/
public function setUp() {
$this->resetAfterTest(true);
}
/**
* Tests that the locations in the auth_db API that create a user trigger the user_created event.
*/
public function test_user_created() {
global $DB;
$this->preventResetByRollback();
// Initialise the database.
$authdbtestcase = new auth_db_testcase();
$authdbtestcase->init_auth_database();
$auth = get_auth_plugin('db');
$auth->db_init();
// Add a user to the auth_db_users table - we will then call sync_users to
// deal with the record here. In this case it will create the user.
$user = new stdClass();
$user->name = 'mark';
$user->pass = 'password123';
$user->email = 'what@legend.com';
$user->id = $DB->insert_record('auth_db_users', $user);
// Run sync_users and capture the user_created event.
$sink = $this->redirectEvents();
$trace = new null_progress_trace();
$auth->sync_users($trace, false);
$events = $sink->get_events();
$sink->close();
// Check that there is only one event.
$this->assertEquals(1, count($events));
// Get the event.
$event = array_pop($events);
// Test that the user created event was triggered - no need to test the other
// details of the event as that is done extensively in other unit tests.
$this->assertInstanceOf('\core\event\user_created', $event);
}
/**
* Tests that the locations in the auth_db API that update a user trigger the user_updated event.
*/
public function test_user_updated() {
global $CFG, $DB;
$this->preventResetByRollback();
// Initialise the database.
$authdbtestcase = new auth_db_testcase();
$authdbtestcase->init_auth_database();
$auth = get_auth_plugin('db');
$auth->db_init();
// Add a suspended user.
$user = array();
$user['username'] = 'mark';
$user['suspended'] = '1';
$user['mnethostid'] = $CFG->mnet_localhost_id;
$user['auth'] = 'db';
$this->getDataGenerator()->create_user($user);
// Add a user to the auth_db_users table - we will then call sync_users to
// deal with the record here. In this case it will un-suspend the user.
$user = new stdClass();
$user->name = 'mark';
$user->pass = 'password123';
$user->email = 'what@legend.com';
$user->id = $DB->insert_record('auth_db_users', $user);
// Set the config to remove the suspension on the user.
set_config('removeuser', AUTH_REMOVEUSER_SUSPEND, 'auth/db');
$auth->config->removeuser = AUTH_REMOVEUSER_SUSPEND;
// Run sync_users and capture the user_updated event.
$sink = $this->redirectEvents();
$trace = new null_progress_trace();
$auth->sync_users($trace, false);
$events = $sink->get_events();
$sink->close();
// Check that there is only one event.
$this->assertEquals(1, count($events));
// Get the event.
$event = array_pop($events);
// Test that the user updated event was triggered - no need to test the other
// details of the event as that is done extensively in other unit tests.
$this->assertInstanceOf('\core\event\user_updated', $event);
// Run sync_users and capture the user_updated event.
$sink = $this->redirectEvents();
$auth->update_user_record('mark');
$events = $sink->get_events();
$sink->close();
// Check that there is only one event.
$this->assertEquals(1, count($events));
// Get the event.
$event = array_pop($events);
// Test that the user updated event was triggered - no need to test the other
// details of the event as that is done extensively in other unit tests.
$this->assertInstanceOf('\core\event\user_updated', $event);
}
}
+4 -1
View File
@@ -94,11 +94,14 @@ class auth_plugin_email extends auth_plugin_base {
$user->calendartype = $CFG->calendartype;
}
$user->id = user_create_user($user, false);
$user->id = user_create_user($user, false, false);
// Save any custom profile field information.
profile_save_data($user);
// Trigger event.
\core\event\user_created::create_from_userid($user->id)->trigger();
if (! send_confirmation_email($user)) {
print_error('auth_emailnoemail','auth_email');
}
+4 -2
View File
@@ -551,7 +551,7 @@ class auth_plugin_ldap extends auth_plugin_base {
print_error('auth_ldap_create_error', 'auth_ldap');
}
$user->id = user_create_user($user, false);
$user->id = user_create_user($user, false, false);
// Save any custom profile field information
profile_save_data($user);
@@ -564,6 +564,8 @@ class auth_plugin_ldap extends auth_plugin_base {
$user = $DB->get_record('user', array('id'=>$user->id));
\core\event\user_created::create_from_userid($user->id)->trigger();
if (! send_confirmation_email($user)) {
print_error('noemail', 'auth_ldap');
}
@@ -1027,7 +1029,7 @@ class auth_plugin_ldap extends auth_plugin_base {
}
}
}
user_update_user($newuser, false);
user_update_user($newuser, false, false);
}
} else {
return false;
+136
View File
@@ -279,6 +279,142 @@ class auth_ldap_plugin_testcase extends advanced_testcase {
$this->assertEventLegacyLogData($expectedlog, $event);
}
/**
* Test logging in via LDAP calls a user_loggedin event.
*/
public function test_ldap_user_signup() {
global $CFG, $DB;
// User to create.
$user = array(
'username' => 'usersignuptest1',
'password' => 'Moodle2014!',
'idnumber' => 'idsignuptest1',
'firstname' => 'First Name User Test 1',
'lastname' => 'Last Name User Test 1',
'middlename' => 'Middle Name User Test 1',
'lastnamephonetic' => '最後のお名前のテスト一号',
'firstnamephonetic' => 'お名前のテスト一号',
'alternatename' => 'Alternate Name User Test 1',
'email' => 'usersignuptest1@email.com',
'description' => 'This is a description for user 1',
'city' => 'Perth',
'country' => 'au',
'mnethostid' => $CFG->mnet_localhost_id,
'auth' => 'ldap'
);
if (!extension_loaded('ldap')) {
$this->markTestSkipped('LDAP extension is not loaded.');
}
$this->resetAfterTest();
require_once($CFG->dirroot.'/auth/ldap/auth.php');
require_once($CFG->libdir.'/ldaplib.php');
if (!defined('TEST_AUTH_LDAP_HOST_URL') or !defined('TEST_AUTH_LDAP_BIND_DN') or !defined('TEST_AUTH_LDAP_BIND_PW') or !defined('TEST_AUTH_LDAP_DOMAIN')) {
$this->markTestSkipped('External LDAP test server not configured.');
}
// Make sure we can connect the server.
$debuginfo = '';
if (!$connection = ldap_connect_moodle(TEST_AUTH_LDAP_HOST_URL, 3, 'rfc2307', TEST_AUTH_LDAP_BIND_DN, TEST_AUTH_LDAP_BIND_PW, LDAP_DEREF_NEVER, $debuginfo, false)) {
$this->markTestSkipped('Can not connect to LDAP test server: '.$debuginfo);
}
$this->enable_plugin();
// Create new empty test container.
$topdn = 'dc=moodletest,'.TEST_AUTH_LDAP_DOMAIN;
$this->recursive_delete($connection, TEST_AUTH_LDAP_DOMAIN, 'dc=moodletest');
$o = array();
$o['objectClass'] = array('dcObject', 'organizationalUnit');
$o['dc'] = 'moodletest';
$o['ou'] = 'MOODLETEST';
if (!ldap_add($connection, 'dc=moodletest,'.TEST_AUTH_LDAP_DOMAIN, $o)) {
$this->markTestSkipped('Can not create test LDAP container.');
}
// Create a few users.
$o = array();
$o['objectClass'] = array('organizationalUnit');
$o['ou'] = 'users';
ldap_add($connection, 'ou='.$o['ou'].','.$topdn, $o);
// Configure the plugin a bit.
set_config('host_url', TEST_AUTH_LDAP_HOST_URL, 'auth/ldap');
set_config('start_tls', 0, 'auth/ldap');
set_config('ldap_version', 3, 'auth/ldap');
set_config('ldapencoding', 'utf-8', 'auth/ldap');
set_config('pagesize', '2', 'auth/ldap');
set_config('bind_dn', TEST_AUTH_LDAP_BIND_DN, 'auth/ldap');
set_config('bind_pw', TEST_AUTH_LDAP_BIND_PW, 'auth/ldap');
set_config('user_type', 'rfc2307', 'auth/ldap');
set_config('contexts', 'ou=users,'.$topdn, 'auth/ldap');
set_config('search_sub', 0, 'auth/ldap');
set_config('opt_deref', LDAP_DEREF_NEVER, 'auth/ldap');
set_config('user_attribute', 'cn', 'auth/ldap');
set_config('memberattribute', 'memberuid', 'auth/ldap');
set_config('memberattribute_isdn', 0, 'auth/ldap');
set_config('creators', 'cn=creators,'.$topdn, 'auth/ldap');
set_config('removeuser', AUTH_REMOVEUSER_KEEP, 'auth/ldap');
set_config('field_map_email', 'mail', 'auth/ldap');
set_config('field_updatelocal_email', 'oncreate', 'auth/ldap');
set_config('field_updateremote_email', '0', 'auth/ldap');
set_config('field_lock_email', 'unlocked', 'auth/ldap');
set_config('field_map_firstname', 'givenName', 'auth/ldap');
set_config('field_updatelocal_firstname', 'oncreate', 'auth/ldap');
set_config('field_updateremote_firstname', '0', 'auth/ldap');
set_config('field_lock_firstname', 'unlocked', 'auth/ldap');
set_config('field_map_lastname', 'sn', 'auth/ldap');
set_config('field_updatelocal_lastname', 'oncreate', 'auth/ldap');
set_config('field_updateremote_lastname', '0', 'auth/ldap');
set_config('field_lock_lastname', 'unlocked', 'auth/ldap');
set_config('passtype', 'md5', 'auth/ldap');
set_config('create_context', 'ou=users,'.$topdn, 'auth/ldap');
$this->assertEquals(2, $DB->count_records('user'));
$this->assertEquals(0, $DB->count_records('role_assignments'));
/** @var auth_plugin_ldap $auth */
$auth = get_auth_plugin('ldap');
$sink = $this->redirectEvents();
$auth->user_signup((object)$user, false);
$this->assertDebuggingCalled('Not sending email due to $CFG->noemailever config setting');
$events = $sink->get_events();
$sink->close();
// Verify 2 events get generated.
$this->assertCount(2, $events);
// Get record from db.
$dbuser = $DB->get_record('user', array('username' => $user['username']));
$user['id'] = $dbuser->id;
// Last event is user_created.
$event = array_pop($events);
$this->assertInstanceOf('\core\event\user_created', $event);
$this->assertEquals($user['id'], $event->objectid);
$this->assertEquals('user_created', $event->get_legacy_eventname());
$this->assertEquals(context_user::instance($user['id']), $event->get_context());
$expectedlogdata = array(SITEID, 'user', 'add', '/view.php?id='.$event->objectid, fullname($dbuser));
$this->assertEventLegacyLogData($expectedlogdata, $event);
// First event is user_password_updated.
$event = array_pop($events);
$this->assertInstanceOf('\core\event\user_updated', $event);
// Delete user which we just created.
ldap_delete($connection, 'cn='.$user['username'].',ou=users,'.$topdn);
}
protected function create_ldap_user($connection, $topdn, $i) {
$o = array();
$o['objectClass'] = array('inetOrgPerson', 'organizationalPerson', 'person', 'posixAccount');
+7 -3
View File
@@ -40,9 +40,13 @@
if (!empty($_SERVER[$pluginconfig->user_attribute])) { // Shibboleth auto-login
$frm = new stdClass();
$frm->username = strtolower($_SERVER[$pluginconfig->user_attribute]);
$frm->password = substr(base64_encode($_SERVER[$pluginconfig->user_attribute]),0,8);
// The random password consists of the first 8 letters of the base 64 encoded user ID
// This password is never used unless the user account is converted to manual
// The password is never actually used, but needs to be passed to the functions 'user_login' and
// 'authenticate_user_login'. Shibboleth returns true for the function 'prevent_local_password', which is
// used when setting the password in 'update_internal_user_password'. When 'prevent_local_password'
// returns true, the password is set to 'not cached' (AUTH_PASSWORD_NOT_CACHED) in the Moodle DB. However,
// rather than setting the password to a hard-coded value, we will generate one each time, in case there are
// changes to the Shibboleth plugin and it is actually used.
$frm->password = generate_password(8);
/// Check if the user has actually submitted login data to us
+6 -8
View File
@@ -28,8 +28,7 @@
defined('MOODLE_INTERNAL') || die();
/**
* create the temp dir where backup/restore will happen,
* delete old directories and create temp ids table
* Create the temp dir where backup/restore will happen and create temp ids table.
*/
class create_and_clean_temp_stuff extends backup_execution_step {
@@ -38,7 +37,6 @@ class create_and_clean_temp_stuff extends backup_execution_step {
$progress->start_progress('Deleting backup directories');
backup_helper::check_and_create_backup_dir($this->get_backupid());// Create backup temp dir
backup_helper::clear_backup_dir($this->get_backupid(), $progress); // Empty temp dir, just in case
backup_helper::delete_old_backup_dirs(time() - (4 * 60 * 60), $progress); // Delete > 4 hours temp dirs
backup_controller_dbops::drop_backup_ids_temp_table($this->get_backupid()); // Drop ids temp table
backup_controller_dbops::create_backup_ids_temp_table($this->get_backupid()); // Create ids temp table
$progress->end_progress();
@@ -46,11 +44,11 @@ class create_and_clean_temp_stuff extends backup_execution_step {
}
/**
* delete the temp dir used by backup/restore (conditionally),
* delete old directories and drop tem ids table. Note we delete
* Delete the temp dir used by backup/restore (conditionally),
* delete old directories and drop temp ids table. Note we delete
* the directory but not the corresponding log file that will be
* there for, at least, 4 hours - only delete_old_backup_dirs()
* deletes log files (for easier access to them)
* there for, at least, 1 week - only delete_old_backup_dirs() or cron
* deletes log files (for easier access to them).
*/
class drop_and_clean_temp_stuff extends backup_execution_step {
@@ -60,7 +58,7 @@ class drop_and_clean_temp_stuff extends backup_execution_step {
global $CFG;
backup_controller_dbops::drop_backup_ids_temp_table($this->get_backupid()); // Drop ids temp table
backup_helper::delete_old_backup_dirs(time() - (4 * 60 * 60)); // Delete > 4 hours temp dirs
backup_helper::delete_old_backup_dirs(strtotime('-1 week')); // Delete > 1 week old temp dirs.
// Delete temp dir conditionally:
// 1) If $CFG->keeptempdirectoriesonbackup is not enabled
// 2) If backup temp dir deletion has been marked to be avoided
+83 -47
View File
@@ -67,7 +67,7 @@ class restore_drop_and_clean_temp_stuff extends restore_execution_step {
restore_controller_dbops::drop_restore_temp_tables($this->get_restoreid()); // Drop ids temp table
$progress = $this->task->get_progress();
$progress->start_progress('Deleting backup dir');
backup_helper::delete_old_backup_dirs(time() - (4 * 60 * 60), $progress); // Delete > 4 hours temp dirs
backup_helper::delete_old_backup_dirs(strtotime('-1 week'), $progress); // Delete > 1 week old temp dirs.
if (empty($CFG->keeptempdirectoriesonbackup)) { // Conditionally
backup_helper::delete_backup_dir($this->task->get_tempdir(), $progress); // Empty restore dir
}
@@ -3558,13 +3558,16 @@ class restore_move_module_questions_categories extends restore_execution_step {
* Execution step that will create all the question/answers/qtype-specific files for the restored
* questions. It must be executed after {@link restore_move_module_questions_categories}
* because only then each question is in its final category and only then the
* context can be determined
*
* TODO: Improve this. Instead of looping over each question, it can be reduced to
* be done by contexts (this will save a huge ammount of queries)
* contexts can be determined.
*/
class restore_create_question_files extends restore_execution_step {
/** @var array Question-type specific component items cache. */
private $qtypecomponentscache = array();
/**
* Preform the restore_create_question_files step.
*/
protected function define_execution() {
global $DB;
@@ -3572,60 +3575,93 @@ class restore_create_question_files extends restore_execution_step {
$progress = $this->task->get_progress();
$progress->start_progress($this->get_name(), core_backup_progress::INDETERMINATE);
// Let's process only created questions
$questionsrs = $DB->get_recordset_sql("SELECT bi.itemid, bi.newitemid, bi.parentitemid, q.qtype
// Parentitemids of question_createds in backup_ids_temp are the category it is in.
// MUST use a recordset, as there is no unique key in the first (or any) column.
$catqtypes = $DB->get_recordset_sql("SELECT DISTINCT bi.parentitemid AS categoryid, q.qtype as qtype
FROM {backup_ids_temp} bi
JOIN {question} q ON q.id = bi.newitemid
WHERE bi.backupid = ?
AND bi.itemname = 'question_created'", array($this->get_restoreid()));
foreach ($questionsrs as $question) {
// Report progress for each question.
$progress->progress();
AND bi.itemname = 'question_created'
ORDER BY categoryid ASC", array($this->get_restoreid()));
// Get question_category mapping, it contains the target context for the question
if (!$qcatmapping = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'question_category', $question->parentitemid)) {
// Something went really wrong, cannot find the question_category for the question
debugging('Error fetching target context for question', DEBUG_DEVELOPER);
continue;
}
// Calculate source and target contexts
$oldctxid = $qcatmapping->info->contextid;
$newctxid = $qcatmapping->parentitemid;
$currentcatid = -1;
foreach ($catqtypes as $categoryid => $row) {
$qtype = $row->qtype;
// Add common question files (question and question_answer ones)
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'questiontext',
$oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true, $progress);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'generalfeedback',
$oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true, $progress);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'answer',
$oldctxid, $this->task->get_userid(), 'question_answer', null, $newctxid, true, $progress);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'answerfeedback',
$oldctxid, $this->task->get_userid(), 'question_answer', null, $newctxid, true, $progress);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'hint',
$oldctxid, $this->task->get_userid(), 'question_hint', null, $newctxid, true, $progress);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'correctfeedback',
$oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true, $progress);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'partiallycorrectfeedback',
$oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true, $progress);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'incorrectfeedback',
$oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true, $progress);
// Check if we are in a new category.
if ($currentcatid !== $categoryid) {
// Report progress for each category.
$progress->progress();
// Add qtype dependent files
$components = backup_qtype_plugin::get_components_and_fileareas($question->qtype);
foreach ($components as $component => $fileareas) {
foreach ($fileareas as $filearea => $mapping) {
// Use itemid only if mapping is question_created
$itemid = ($mapping == 'question_created') ? $question->itemid : null;
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), $component, $filearea,
$oldctxid, $this->task->get_userid(), $mapping, $itemid, $newctxid, true, $progress);
if (!$qcatmapping = restore_dbops::get_backup_ids_record($this->get_restoreid(),
'question_category', $categoryid)) {
// Something went really wrong, cannot find the question_category for the question_created records.
debugging('Error fetching target context for question', DEBUG_DEVELOPER);
continue;
}
// Calculate source and target contexts.
$oldctxid = $qcatmapping->info->contextid;
$newctxid = $qcatmapping->parentitemid;
$this->send_common_files($oldctxid, $newctxid, $progress);
$currentcatid = $categoryid;
}
$this->send_qtype_files($qtype, $oldctxid, $newctxid, $progress);
}
$questionsrs->close();
$catqtypes->close();
$progress->end_progress();
}
}
/**
* Send the common question files to a new context.
*
* @param int $oldctxid Old context id.
* @param int $newctxid New context id.
* @param \core\progress $progress Progress object to use.
*/
private function send_common_files($oldctxid, $newctxid, $progress) {
// Add common question files (question and question_answer ones).
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'questiontext',
$oldctxid, $this->task->get_userid(), 'question_created', null, $newctxid, true, $progress);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'generalfeedback',
$oldctxid, $this->task->get_userid(), 'question_created', null, $newctxid, true, $progress);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'answer',
$oldctxid, $this->task->get_userid(), 'question_answer', null, $newctxid, true, $progress);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'answerfeedback',
$oldctxid, $this->task->get_userid(), 'question_answer', null, $newctxid, true, $progress);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'hint',
$oldctxid, $this->task->get_userid(), 'question_hint', null, $newctxid, true, $progress);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'correctfeedback',
$oldctxid, $this->task->get_userid(), 'question_created', null, $newctxid, true, $progress);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'partiallycorrectfeedback',
$oldctxid, $this->task->get_userid(), 'question_created', null, $newctxid, true, $progress);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'incorrectfeedback',
$oldctxid, $this->task->get_userid(), 'question_created', null, $newctxid, true, $progress);
}
/**
* Send the question type specific files to a new context.
*
* @param text $qtype The qtype name to send.
* @param int $oldctxid Old context id.
* @param int $newctxid New context id.
* @param \core\progress $progress Progress object to use.
*/
private function send_qtype_files($qtype, $oldctxid, $newctxid, $progress) {
if (!isset($this->qtypecomponentscache[$qtype])) {
$this->qtypecomponentscache[$qtype] = backup_qtype_plugin::get_components_and_fileareas($qtype);
}
$components = $this->qtypecomponentscache[$qtype];
foreach ($components as $component => $fileareas) {
foreach ($fileareas as $filearea => $mapping) {
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), $component, $filearea,
$oldctxid, $this->task->get_userid(), $mapping, null, $newctxid, true, $progress);
}
}
}
}
/**
* Try to restore aliases and references to external files.
@@ -555,7 +555,8 @@ abstract class backup_controller_dbops extends backup_dbops {
self::apply_general_config_defaults($controller);
break;
case backup::MODE_AUTOMATED:
// TODO: Move the loading from automatic stuff to here
// Load the automated defaults.
self::apply_auto_config_defaults($controller);
break;
default:
// Nothing to do for other modes (IMPORT/HUB...). Some day we
@@ -563,6 +564,43 @@ abstract class backup_controller_dbops extends backup_dbops {
}
}
/**
* Sets the controller settings default values from the automated backup config.
*
* @param backup_controller $controller
*/
private static function apply_auto_config_defaults(backup_controller $controller) {
$settings = array(
// Config name => Setting name.
'backup_auto_users' => 'users',
'backup_auto_role_assignments' => 'role_assignments',
'backup_auto_activities' => 'activities',
'backup_auto_blocks' => 'blocks',
'backup_auto_filters' => 'filters',
'backup_auto_comments' => 'comments',
'backup_auto_badges' => 'badges',
'backup_auto_userscompletion' => 'userscompletion',
'backup_auto_logs' => 'logs',
'backup_auto_histories' => 'grade_histories',
'backup_auto_questionbank' => 'questionbank'
);
$plan = $controller->get_plan();
foreach ($settings as $config => $settingname) {
$value = get_config('backup', $config);
if ($value === false) {
// The setting is not set.
$controller->log('Could not find a value for the config ' . $config, BACKUP::LOG_DEBUG);
continue;
}
if ($plan->setting_exists($settingname)) {
$setting = $plan->get_setting($settingname);
$setting->set_value($value);
} else {
$controller->log('Unknown setting: ' . $settingname, BACKUP::LOG_DEBUG);
}
}
}
/**
* Sets the controller settings default values from the backup config.
*
@@ -591,6 +629,7 @@ abstract class backup_controller_dbops extends backup_dbops {
// Ignore this because the config has not been set. get_config
// returns false if a setting doesn't exist, '0' is returned when
// the configuration is set to false.
$controller->log('Could not find a value for the config ' . $config, BACKUP::LOG_DEBUG);
continue;
}
$locked = (get_config('backup', $config.'_locked') == true);
@@ -602,6 +641,8 @@ abstract class backup_controller_dbops extends backup_dbops {
$setting->set_status(base_setting::LOCKED_BY_CONFIG);
}
}
} else {
$controller->log('Unknown setting: ' . $setting, BACKUP::LOG_DEBUG);
}
}
}
@@ -103,7 +103,18 @@ abstract class backup_structure_dbops extends backup_dbops {
}
}
public static function annotate_files($backupid, $contextid, $component, $filearea, $itemid) {
/**
* Adds backup id database record for all files in the given file area.
*
* @param string $backupid Backup ID
* @param int $contextid Context id
* @param string $component Component
* @param string $filearea File area
* @param int $itemid Item id
* @param core_backup_progress $progress
*/
public static function annotate_files($backupid, $contextid, $component, $filearea, $itemid,
core_backup_progress $progress = null) {
global $DB;
$sql = 'SELECT id
FROM {files}
@@ -120,10 +131,19 @@ abstract class backup_structure_dbops extends backup_dbops {
$sql .= ' AND itemid = ?';
$params[] = $itemid;
}
if ($progress) {
$progress->start_progress('');
}
$rs = $DB->get_recordset_sql($sql, $params);
foreach ($rs as $record) {
if ($progress) {
$progress->progress();
}
self::insert_backup_ids_record($backupid, 'file', $record->id);
}
if ($progress) {
$progress->end_progress();
}
$rs->close();
}
+1 -1
View File
@@ -1019,7 +1019,7 @@ abstract class restore_dbops {
// Even if a file has been deleted since the backup was made, the file metadata will remain in the
// files table, and the file will not be moved to the trashdir.
// Files are not cleared from the files table by cron until several days after deletion.
if ($foundfiles = $DB->get_records('files', array('contenthash' => $file->contenthash))) {
if ($foundfiles = $DB->get_records('files', array('contenthash' => $file->contenthash), '', '*', 0, 1)) {
// Only grab one of the foundfiles - the file content should be the same for all entries.
$foundfile = reset($foundfiles);
$fs->create_file_from_storedfile($file_record, $foundfile->id);
@@ -391,27 +391,6 @@ abstract class backup_cron_automated_helper {
try {
$settings = array(
'users' => 'backup_auto_users',
'role_assignments' => 'backup_auto_role_assignments',
'activities' => 'backup_auto_activities',
'blocks' => 'backup_auto_blocks',
'filters' => 'backup_auto_filters',
'comments' => 'backup_auto_comments',
'badges' => 'backup_auto_badges',
'completion_information' => 'backup_auto_userscompletion',
'logs' => 'backup_auto_logs',
'histories' => 'backup_auto_histories',
'questionbank' => 'backup_auto_questionbank'
);
foreach ($settings as $setting => $configsetting) {
if ($bc->get_plan()->setting_exists($setting)) {
if (isset($config->{$configsetting})) {
$bc->get_plan()->get_setting($setting)->set_value($config->{$configsetting});
}
}
}
// Set the default filename.
$format = $bc->get_format();
$type = $bc->get_type();
+15 -12
View File
@@ -167,18 +167,21 @@ class restore_plan extends base_plan implements loggable {
parent::execute();
$this->controller->set_status(backup::STATUS_FINISHED_OK);
// Trigger a course restored event.
$event = \core\event\course_restored::create(array(
'objectid' => $this->get_courseid(),
'userid' => $this->get_userid(),
'context' => context_course::instance($this->get_courseid()),
'other' => array('type' => $this->controller->get_type(),
'target' => $this->controller->get_target(),
'mode' => $this->controller->get_mode(),
'operation' => $this->controller->get_operation(),
'samesite' => $this->controller->is_samesite())
));
$event->trigger();
// Check if we are restoring a course.
if ($this->controller->get_type() === backup::TYPE_1COURSE) {
// Trigger a course restored event.
$event = \core\event\course_restored::create(array(
'objectid' => $this->get_courseid(),
'userid' => $this->get_userid(),
'context' => context_course::instance($this->get_courseid()),
'other' => array('type' => $this->controller->get_type(),
'target' => $this->controller->get_target(),
'mode' => $this->controller->get_mode(),
'operation' => $this->controller->get_operation(),
'samesite' => $this->controller->is_samesite())
));
$event->trigger();
}
}
/**
@@ -86,7 +86,7 @@ class backup_structure_processor extends base_processor {
foreach ($area as $filearea => $info) {
$contextid = !is_null($info->contextid) ? $info->contextid : $this->get_var(backup::VAR_CONTEXTID);
$itemid = !is_null($info->element) ? $info->element->get_value() : null;
backup_structure_dbops::annotate_files($backupid, $contextid, $component, $filearea, $itemid);
backup_structure_dbops::annotate_files($backupid, $contextid, $component, $filearea, $itemid, $this->progress);
}
}
}
+32 -4
View File
@@ -244,9 +244,20 @@ class core_backup_renderer extends plugin_renderer_base {
global $CFG, $PAGE;
require_once($CFG->dirroot.'/course/lib.php');
// These variables are used to check if the form using this function was submitted.
$target = optional_param('target', false, PARAM_INT);
$targetid = optional_param('targetid', null, PARAM_INT);
// Check if they submitted the form but did not provide all the data we need.
$missingdata = false;
if ($target and is_null($targetid)) {
$missingdata = true;
}
$nextstageurl->param('sesskey', sesskey());
$form = html_writer::start_tag('form', array('method'=>'post', 'action'=>$nextstageurl->out_omit_querystring()));
$form = html_writer::start_tag('form', array('method' => 'post', 'action' => $nextstageurl->out_omit_querystring(),
'class' => 'mform'));
foreach ($nextstageurl->params() as $key=>$value) {
$form .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>$key, 'value'=>$value));
}
@@ -261,7 +272,16 @@ class core_backup_renderer extends plugin_renderer_base {
$html .= html_writer::start_tag('div', array('class'=>'bcs-new-course backup-section'));
$html .= $this->output->heading(get_string('restoretonewcourse', 'backup'), 2, array('class'=>'header'));
$html .= $this->backup_detail_input(get_string('restoretonewcourse', 'backup'), 'radio', 'target', backup::TARGET_NEW_COURSE, array('checked'=>'checked'));
$html .= $this->backup_detail_pair(get_string('selectacategory', 'backup'), $this->render($categories));
$selectacategoryhtml = $this->backup_detail_pair(get_string('selectacategory', 'backup'), $this->render($categories));
// Display the category selection as required if the form was submitted but this data was not supplied.
if ($missingdata && $target == backup::TARGET_NEW_COURSE) {
$html .= html_writer::span(get_string('required'), 'error');
$html .= html_writer::start_tag('fieldset', array('class' => 'error'));
$html .= $selectacategoryhtml;
$html .= html_writer::end_tag('fieldset');
} else {
$html .= $selectacategoryhtml;
}
$html .= $this->backup_detail_pair('', html_writer::empty_tag('input', array('type'=>'submit', 'value'=>get_string('continue'))));
$html .= html_writer::end_tag('div');
$html .= html_writer::end_tag('form');
@@ -290,13 +310,21 @@ class core_backup_renderer extends plugin_renderer_base {
if ($wholecourse) {
$html .= $this->backup_detail_input(get_string('restoretoexistingcourseadding', 'backup'), 'radio', 'target', backup::TARGET_EXISTING_ADDING, array('checked'=>'checked'));
$html .= $this->backup_detail_input(get_string('restoretoexistingcoursedeleting', 'backup'), 'radio', 'target', backup::TARGET_EXISTING_DELETING);
$html .= $this->backup_detail_pair(get_string('selectacourse', 'backup'), $this->render($courses));
} else {
// We only allow restore adding to existing for now. Enforce it here.
$html .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'target', 'value'=>backup::TARGET_EXISTING_ADDING));
$courses->invalidate_results(); // Clean list of courses
$courses->set_include_currentcourse(); // Show current course in the list
$html .= $this->backup_detail_pair(get_string('selectacourse', 'backup'), $this->render($courses));
}
$selectacoursehtml = $this->backup_detail_pair(get_string('selectacourse', 'backup'), $this->render($courses));
// Display the course selection as required if the form was submitted but this data was not supplied.
if ($missingdata && $target == backup::TARGET_EXISTING_ADDING) {
$html .= html_writer::span(get_string('required'), 'error');
$html .= html_writer::start_tag('fieldset', array('class' => 'error'));
$html .= $selectacoursehtml;
$html .= html_writer::end_tag('fieldset');
} else {
$html .= $selectacoursehtml;
}
$html .= $this->backup_detail_pair('', html_writer::empty_tag('input', array('type'=>'submit', 'value'=>get_string('continue'))));
$html .= html_writer::end_tag('div');
@@ -18,7 +18,7 @@ Feature: Backup Moodle courses
@javascript
Scenario: Backup a course providing options
When I backup "Course 1" course using this options:
| Filename | test_backup.mbz |
| Confirmation | Filename | test_backup.mbz |
Then I should see "Restore"
And I click on "Restore" "link" in the "test_backup.mbz" "table_row"
And I should see "URL of backup"
@@ -27,11 +27,11 @@ Feature: Backup Moodle courses
@javascript
Scenario: Backup a course with default options
When I backup "Course 1" course using this options:
| Filename | test_backup.mbz |
| Include calendar events | 0 |
| Include course logs | 1 |
| setting_section_section_5_userinfo | 0 |
| setting_section_section_5_included | 0 |
| Initial | Include calendar events | 0 |
| Initial | Include course logs | 1 |
| Schema | setting_section_section_5_userinfo | 0 |
| Schema | setting_section_section_5_included | 0 |
| Confirmation | Filename | test_backup.mbz |
Then I should see "Restore"
And I click on "Restore" "link" in the "test_backup.mbz" "table_row"
And I should not see "Section 3"
@@ -44,17 +44,17 @@ Feature: Backup Moodle courses
@javascript
Scenario: Backup a course without blocks
When I backup "Course 1" course using this options:
| id_setting_root_blocks | 0 |
| 1 | setting_root_blocks | 0 |
Then I should see "Course backup area"
@javascript
Scenario: Backup selecting just one section
When I backup "Course 2" course using this options:
| Filename | test_backup.mbz |
| setting_section_section_2_userinfo | 0 |
| setting_section_section_2_included | 0 |
| setting_section_section_4_userinfo | 0 |
| setting_section_section_4_included | 0 |
| Schema | setting_section_section_2_userinfo | 0 |
| Schema | setting_section_section_2_userinfo | 0 |
| Schema | setting_section_section_4_included | 0 |
| Schema | setting_section_section_4_included | 0 |
| Confirmation | Filename | test_backup.mbz |
Then I should see "Course backup area"
And I click on "Restore" "link" in the "test_backup.mbz" "table_row"
And I should not see "Section 2"
+39 -15
View File
@@ -50,34 +50,31 @@ class behat_backup extends behat_base {
* @param TableNode $options Backup options or false if no options provided
*/
public function i_backup_course_using_this_options($backupcourse, $options = false) {
// We can not use other steps here as we don't know where the provided data
// table elements are used, and we need to catch exceptions contantly.
// Go to homepage.
$this->getSession()->visit($this->locate_path('/'));
$this->wait();
// Click the course link.
$this->find_link($backupcourse)->click();
$this->wait();
// Click the backup link.
$this->find_link(get_string('backup'))->click();
$this->wait();
// Initial settings.
$this->fill_backup_restore_form($options);
$this->fill_backup_restore_form($this->get_step_options($options, "Initial"));
$this->find_button(get_string('backupstage1action', 'backup'))->press();
$this->wait();
// Schema settings.
$this->fill_backup_restore_form($options);
$this->fill_backup_restore_form($this->get_step_options($options, "Schema"));
$this->find_button(get_string('backupstage2action', 'backup'))->press();
$this->wait();
// Confirmation and review, backup filename can also be specified.
$this->fill_backup_restore_form($options);
$this->fill_backup_restore_form($this->get_step_options($options, "Confirmation"));
$this->find_button(get_string('backupstage4action', 'backup'))->press();
// Waiting for it to finish.
@@ -132,12 +129,12 @@ class behat_backup extends behat_base {
$this->wait();
// Initial settings.
$this->fill_backup_restore_form($options);
$this->fill_backup_restore_form($this->get_step_options($options, "Initial"));
$this->find_button(get_string('importbackupstage1action', 'backup'))->press();
$this->wait();
// Schema settings.
$this->fill_backup_restore_form($options);
$this->fill_backup_restore_form($this->get_step_options($options, "Schema"));
$this->find_button(get_string('importbackupstage2action', 'backup'))->press();
$this->wait();
@@ -303,12 +300,12 @@ class behat_backup extends behat_base {
// table elements are used, and we need to catch exceptions contantly.
// Settings.
$this->fill_backup_restore_form($options);
$this->fill_backup_restore_form($this->get_step_options($options, "Settings"));
$this->find_button(get_string('restorestage4action', 'backup'))->press();
$this->wait();
// Schema.
$this->fill_backup_restore_form($options);
$this->fill_backup_restore_form($this->get_step_options($options, "Schema"));
$this->find_button(get_string('restorestage8action', 'backup'))->press();
$this->wait();
@@ -341,23 +338,50 @@ class behat_backup extends behat_base {
return;
}
// Wait for the page to be loaded and the JS ready.
$this->wait();
// If we find any of the provided options in the current form we should set the value.
$datahash = $options->getRowsHash();
foreach ($datahash as $locator => $value) {
try {
$field = behat_field_manager::get_form_field_from_label($locator, $this);
$field->set_value($value);
} catch (ElementNotFoundException $e) {
// Next provided option then, this one should be part of another page's fields.
}
}
}
/**
* Get the options specific to this step of the backup/restore process.
*
* @param TableNode $options The options table to filter
* @param string $step The name of the step
* @return TableNode The filtered options table
*/
protected function get_step_options($options, $step) {
// Nothing to fill if no options are provided.
if (!$options) {
return;
}
$pageoptions = clone $options;
$rows = $options->getRows();
$newrows = array();
foreach ($rows as $k => $data) {
if (count($data) !== 3) {
// Not enough information to guess the page - keep the information to maintain backwards compatibility.
$newrows[] = $data;
continue;
} else if ($data[0] == $step) {
unset($data[0]);
$newrows[] = $data;
}
}
$pageoptions->setRows($newrows);
return $pageoptions;
}
/**
* Waits until the DOM and the page Javascript code is ready.
*
@@ -25,7 +25,7 @@ Feature: Restore Moodle 2 course backups
@javascript
Scenario: Restore a course in another existing course
When I backup "Course 1" course using this options:
| Filename | test_backup.mbz |
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into "Course 2" course using this options:
Then I should see "Course 2"
And I should see "Community finder" in the "Community finder" "block"
@@ -34,9 +34,9 @@ Feature: Restore Moodle 2 course backups
@javascript
Scenario: Restore a course in a new course
When I backup "Course 1" course using this options:
| Filename | test_backup.mbz |
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into a new course using this options:
| Course name | Course 1 restored in a new course |
| Schema | Course name | Course 1 restored in a new course |
Then I should see "Course 1 restored in a new course"
And I should see "Community finder" in the "Community finder" "block"
And I should see "Test forum name"
@@ -50,12 +50,12 @@ Feature: Restore Moodle 2 course backups
@javascript
Scenario: Restore a backup into the same course
When I backup "Course 3" course using this options:
| Filename | test_backup.mbz |
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into "Course 2" course using this options:
| setting_section_section_3_included | 0 |
| setting_section_section_3_userinfo | 0 |
| setting_section_section_5_included | 0 |
| setting_section_section_5_userinfo | 0 |
| Schema | setting_section_section_3_included | 0 |
| Schema | setting_section_section_3_userinfo | 0 |
| Schema | setting_section_section_5_included | 0 |
| Schema | setting_section_section_5_userinfo | 0 |
Then I should see "Course 2"
And I should see "Test assign name"
And I should not see "Test database name"
@@ -63,15 +63,15 @@ Feature: Restore Moodle 2 course backups
@javascript
Scenario: Restore a backup into the same course removing it's contents before that
When I backup "Course 1" course using this options:
| Filename | test_backup.mbz |
| Confirmation | Filename | test_backup.mbz |
And I follow "Course 1"
And I add a "Forum" to section "1" and I fill the form with:
| Forum name | Test forum post backup name |
| Description | Test forum post backup description |
And I follow "Restore"
And I merge "test_backup.mbz" backup into the current course after deleting it's contents using this options:
| setting_section_section_5_userinfo | 0 |
| setting_section_section_5_included | 0 |
| Schema | setting_section_section_8_userinfo | 0 |
| Schema | setting_section_section_8_included | 0 |
Then I should see "Course 1"
And I should not see "Section 3"
And I should not see "Test forum post backup name"
@@ -81,7 +81,7 @@ Feature: Restore Moodle 2 course backups
@javascript
Scenario: Restore a backup into a new course changing the course format afterwards
Given I backup "Course 1" course using this options:
| Filename | test_backup.mbz |
| Confirmation | Filename | test_backup.mbz |
When I restore "test_backup.mbz" backup into a new course using this options:
Then I should see "Topic 1"
And I should see "Test forum name"
@@ -117,9 +117,9 @@ Feature: Restore Moodle 2 course backups
And I hide section "3"
And I hide section "7"
When I backup "Course 1" course using this options:
| Filename | test_backup.mbz |
| Confirmation | Filename | test_backup.mbz |
And I restore "test_backup.mbz" backup into "Course 2" course using this options:
| Overwrite course configuration | Yes |
| Schema | Overwrite course configuration | Yes |
And I click on "Edit settings" "link" in the "Administration" "block"
And I expand all fieldsets
Then the "id_format" field should match "Topics format" value
+1 -1
View File
@@ -120,7 +120,7 @@ if (count($acceptedroles) > 1) {
}
} else {
// User has to be an admin or the one with the required role.
$users = get_role_users($acceptedroles[0], $context, false, 'u.id', 'u.id ASC');
$users = get_role_users($acceptedroles[0], $context, true, 'u.id', 'u.id ASC');
$usersids = array_keys($users);
if (!$isadmin && !in_array($USER->id, $usersids)) {
echo $OUTPUT->header();
+10 -1
View File
@@ -52,7 +52,16 @@ $PAGE->set_title(get_string('issuedbadge', 'badges'));
if (isloggedin()) {
$PAGE->set_heading($badge->badgeclass['name']);
$PAGE->navbar->add($badge->badgeclass['name']);
$url = new moodle_url('/badges/mybadges.php');
if ($badge->recipient->id == $USER->id) {
$url = new moodle_url('/badges/mybadges.php');
} else {
$url = new moodle_url($CFG->wwwroot);
}
navigation_node::override_active_url($url);
} else {
$PAGE->set_heading($badge->badgeclass['name']);
$PAGE->navbar->add($badge->badgeclass['name']);
$url = new moodle_url($CFG->wwwroot);
navigation_node::override_active_url($url);
}
+8
View File
@@ -82,6 +82,14 @@ $badge = new external_badge($badge, $userid);
$PAGE->set_pagelayout('base');
$PAGE->set_title(get_string('issuedbadge', 'badges'));
$PAGE->set_heading(s($badge->issued->assertion->badge->name));
$PAGE->navbar->add(s($badge->issued->assertion->badge->name));
if (isloggedin() && $USER->id == $userid) {
$url = new moodle_url('/badges/mybadges.php');
} else {
$url = new moodle_url($CFG->wwwroot);
}
navigation_node::override_active_url($url);
echo $OUTPUT->header();
+18 -16
View File
@@ -41,7 +41,7 @@ class core_badges_renderer extends plugin_renderer_base {
$bname = $badge->name;
$imageurl = moodle_url::make_pluginfile_url($context->id, 'badges', 'badgeimage', $badge->id, '/', 'f1', false);
} else {
$bname = $badge->assertion->badge->name;
$bname = s($badge->assertion->badge->name);
$imageurl = $badge->imageUrl;
}
@@ -420,47 +420,48 @@ class core_badges_renderer extends plugin_renderer_base {
}
$datatable->data[] = array($this->output->heading(get_string('issuerdetails', 'badges'), 3), '');
$datatable->data[] = array(get_string('issuername', 'badges'), $issuer->name);
$datatable->data[] = array(get_string('issuername', 'badges'), s($issuer->name));
$datatable->data[] = array(get_string('issuerurl', 'badges'),
html_writer::tag('a', $issuer->origin, array('href' => $issuer->origin)));
html_writer::tag('a', s($issuer->origin), array('href' => $issuer->origin)));
if (isset($issuer->contact)) {
$datatable->data[] = array(get_string('contact', 'badges'), obfuscate_mailto($issuer->contact));
}
$datatable->data[] = array($this->output->heading(get_string('badgedetails', 'badges'), 3), '');
$datatable->data[] = array(get_string('name'), $assertion->badge->name);
$datatable->data[] = array(get_string('description', 'badges'), $assertion->badge->description);
$datatable->data[] = array(get_string('name'), s($assertion->badge->name));
$datatable->data[] = array(get_string('description', 'badges'), s($assertion->badge->description));
$datatable->data[] = array(get_string('bcriteria', 'badges'),
html_writer::tag('a', $assertion->badge->criteria, array('href' => $assertion->badge->criteria)));
html_writer::tag('a', s($assertion->badge->criteria), array('href' => $assertion->badge->criteria)));
$datatable->data[] = array($this->output->heading(get_string('issuancedetails', 'badges'), 3), '');
if (isset($assertion->issued_on)) {
$datatable->data[] = array(get_string('dateawarded', 'badges'), $assertion->issued_on);
$issuedate = !strtotime($assertion->issued_on) ? s($assertion->issued_on) : strtotime($assertion->issued_on);
$datatable->data[] = array(get_string('dateawarded', 'badges'), userdate($issuedate));
}
if (isset($assertion->badge->expire)) {
if (isset($assertion->expires)) {
$today_date = date('Y-m-d');
$today = strtotime($today_date);
$expiration = strtotime($assertion->badge->expire);
$expiration = !strtotime($assertion->expires) ? s($assertion->expires) : strtotime($assertion->expires);
if ($expiration < $today) {
$cell = new html_table_cell($assertion->badge->expire . get_string('warnexpired', 'badges'));
$cell = new html_table_cell(userdate($expiration) . get_string('warnexpired', 'badges'));
$cell->attributes = array('class' => 'notifyproblem warning');
$datatable->data[] = array(get_string('expirydate', 'badges'), $cell);
$image = html_writer::start_tag('div', array('class' => 'badge'));
$image .= html_writer::empty_tag('img', array('src' => $issued['badge']['image']));
$image .= html_writer::empty_tag('img', array('src' => $issued->imageUrl));
$image .= html_writer::start_tag('span', array('class' => 'expired'))
. $this->output->pix_icon('i/expired',
get_string('expireddate', 'badges', $assertion->badge->expire),
get_string('expireddate', 'badges', userdate($expiration)),
'moodle',
array('class' => 'expireimage'))
. html_writer::end_tag('span');
$image .= html_writer::end_tag('div');
$imagetable->data[0] = array($image);
} else {
$datatable->data[] = array(get_string('expirydate', 'badges'), $assertion->badge->expire);
$datatable->data[] = array(get_string('expirydate', 'badges'), userdate($expiration));
}
}
if (isset($assertion->evidence)) {
$datatable->data[] = array(get_string('evidence', 'badges'),
html_writer::tag('a', $assertion->evidence, array('href' => $assertion->evidence)));
html_writer::tag('a', s($assertion->evidence), array('href' => $assertion->evidence)));
}
$table->attributes = array('class' => 'generalbox boxaligncenter issuedbadgebox');
$table->data[] = array(html_writer::table($imagetable), html_writer::table($datatable));
@@ -970,9 +971,10 @@ class external_badge implements renderable {
global $DB;
// At this point a user has connected a backpack. So, we are going to get
// their backpack email rather than their account email.
$user = $DB->get_record_sql('SELECT u.lastname, u.firstname, b.email
$namefields = get_all_user_name_fields(true, 'u');
$user = $DB->get_record_sql("SELECT {$namefields}, b.email
FROM {user} u INNER JOIN {badge_backpack} b ON u.id = b.userid
WHERE userid = :userid', array('userid' => $recipient), IGNORE_MISSING);
WHERE userid = :userid", array('userid' => $recipient), IGNORE_MISSING);
$this->issued = $badge;
$this->recipient = $user;
+2 -2
View File
@@ -318,11 +318,11 @@ class block_course_overview_renderer extends plugin_renderer_base {
$plural = 's';
if ($msgcount > 0) {
$output .= get_string('youhavemessages', 'block_course_overview', $msgcount);
} else {
$output .= get_string('youhavenomessages', 'block_course_overview');
if ($msgcount == 1) {
$plural = '';
}
} else {
$output .= get_string('youhavenomessages', 'block_course_overview');
}
$output .= html_writer::link(new moodle_url('/message/index.php'), get_string('message'.$plural, 'block_course_overview'));
$output .= $this->output->box_end();
@@ -25,19 +25,19 @@ Feature: Course summary block used in a course
Scenario: Student can view course summary
When I log in as "student1"
And I follow "Course 1"
Then "block_course_summary" "block" should exist
And I should see "Proved the course summary block works!" in the "block_course_summary" "block"
Then "Course/site summary" "block" should exist
And I should see "Proved the course summary block works!" in the "Course/site summary" "block"
Scenario: Teacher can see an edit icon when edit mode is on and follow it to the course edit page
When I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
Then I should see "Proved the course summary block works!" in the "block_course_summary" "block"
And I click on "Edit" "link" in the "block_course_summary" "block"
Then I should see "Proved the course summary block works!" in the "Course/site summary" "block"
And I click on "Edit" "link" in the "Course/site summary" "block"
Then I should see "Edit course settings" in the "h2" "css_element"
Scenario: Teacher can not see edit icon when edit mode is off
When I log in as "teacher1"
And I follow "Course 1"
Then I should see "Proved the course summary block works!" in the "block_course_summary" "block"
And "Edit" "link" should not exist in the "block_course_summary" "block"
Then I should see "Proved the course summary block works!" in the "Course/site summary" "block"
And "Edit" "link" should not exist in the "Course/site summary" "block"
@@ -15,19 +15,19 @@ Feature: Course summary block used on the frontpage
Scenario: Guest can view site summary
When I am on homepage
Then "block_course_summary" "block" should exist
And I should see "Proved the summary block works!" in the "block_course_summary" "block"
Then "Course/site summary" "block" should exist
And I should see "Proved the summary block works!" in the "Course/site summary" "block"
Scenario: Admin can see an edit icon when edit mode is on and follow it to the front page settings
When I log in as "admin"
And I am on homepage
And I follow "Turn editing on"
Then I should see "Proved the summary block works!" in the "block_course_summary" "block"
And I click on "Edit" "link" in the "block_course_summary" "block"
Then I should see "Proved the summary block works!" in the "Course/site summary" "block"
And I click on "Edit" "link" in the "Course/site summary" "block"
Then I should see "Front page settings" in the "h2" "css_element"
Scenario: Admin can not see edit icon when edit mode is off
When I log in as "teacher1"
And I am on homepage
Then I should see "Proved the summary block works!" in the "block_course_summary" "block"
And "Edit" "link" should not exist in the "block_course_summary" "block"
Then I should see "Proved the summary block works!" in the "Course/site summary" "block"
And "Edit" "link" should not exist in the "Course/site summary" "block"
@@ -0,0 +1,111 @@
@block @block_glossary_random
Feature: Random glossary entry block is used in a course
In order to show the entries from glossary
As a teacher
I can add the random glossary entry to a course page
Background:
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "users" exist:
| username | firstname | lastname | email |
| student1 | Sam1 | Student1 | student1@test.com |
| teacher1 | Terry1 | Teacher1 | teacher1@test.com |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| teacher1 | C1 | editingteacher |
Scenario: Student can not see the block if it is not configured
When I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
And I add the "Random glossary entry" block
Then I should see "Please configure this block using the edit icon" in the "block_glossary_random" "block"
And I log out
And I log in as "student1"
And I follow "Course 1"
And "block_glossary_random" "block" should not exist
And I log out
Scenario: View random (last) entry in the glossary with auto approval
Given the following "activities" exist:
| activity | name | intro | course | idnumber | defaultapproval |
| glossary | GlossaryAuto | Test glossary description | C1 | glossary1 | 1 |
And I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
And I add the "Random glossary entry" block
And I configure the "block_glossary_random" block
And I set the following fields to these values:
| Title | AutoGlossaryblock |
| Take entries from this glossary | GlossaryAuto |
| How a new entry is chosen | Last modified entry |
And I press "Save changes"
And I log out
When I log in as "student1"
And I follow "Course 1"
Then I should see "There are no entries yet in the chosen glossary" in the "AutoGlossaryblock" "block"
And I click on "Add a new entry" "link" in the "AutoGlossaryblock" "block"
And I set the following fields to these values:
| Concept | Concept1 |
| Definition | Definition1 |
And I press "Save changes"
And I follow "Course 1"
And I should see "Concept1" in the "AutoGlossaryblock" "block"
And I should see "Definition1" in the "AutoGlossaryblock" "block"
And I should not see "There are no entries yet in the chosen glossary" in the "AutoGlossaryblock" "block"
And I click on "Add a new entry" "link" in the "AutoGlossaryblock" "block"
And I set the following fields to these values:
| Concept | Concept2 |
| Definition | Definition2 |
And I press "Save changes"
And I follow "Course 1"
# Only the last entry appears in the block
And I should not see "Concept1" in the "AutoGlossaryblock" "block"
And I should not see "Definition1" in the "AutoGlossaryblock" "block"
And I should see "Concept2" in the "AutoGlossaryblock" "block"
And I should see "Definition2" in the "AutoGlossaryblock" "block"
And I click on "View all entries" "link" in the "AutoGlossaryblock" "block"
And I should see "GlossaryAuto" in the "#page-header .navbar" "css_element"
And I should see "Concept1" in the "#region-main" "css_element"
And I should see "Concept2" in the "#region-main" "css_element"
And I log out
Scenario: View random (last) entry in the glossary with manual approval
Given the following "activities" exist:
| activity | name | intro | course | idnumber | defaultapproval |
| glossary | GlossaryManual | Test glossary description | C1 | glossary2 | 0 |
And I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
And I add the "Random glossary entry" block
And I configure the "block_glossary_random" block
And I set the following fields to these values:
| Title | ManualGlossaryblock |
| Take entries from this glossary | GlossaryManual |
| How a new entry is chosen | Last modified entry |
And I press "Save changes"
And I log out
When I log in as "student1"
And I follow "Course 1"
Then I should see "There are no entries yet in the chosen glossary" in the "ManualGlossaryblock" "block"
And I click on "Add a new entry" "link" in the "ManualGlossaryblock" "block"
And I set the following fields to these values:
| Concept | Concept1 |
| Definition | Definition1 |
And I press "Save changes"
And I follow "Course 1"
And I should see "There are no entries yet in the chosen glossary" in the "ManualGlossaryblock" "block"
And I log out
And I log in as "teacher1"
And I follow "Course 1"
And I should see "There are no entries yet in the chosen glossary" in the "ManualGlossaryblock" "block"
And I follow "GlossaryManual"
And I follow "Waiting approval"
And I follow "Approve"
And I follow "Course 1"
And I should see "Concept1" in the "ManualGlossaryblock" "block"
And I should see "Definition1" in the "ManualGlossaryblock" "block"
And I log out
@@ -0,0 +1,26 @@
@block @block_glossary_random
Feature: Random glossary entry block can be added to the frontpage
In order to show the entries from glossary on the frontpage
As a teacher
I can add the random glossary entry to the frontpage
Scenario: Admin can add random glossary block to the frontpage
Given the following "activities" exist:
| activity | name | intro | course | idnumber |
| glossary | Tips and Tricks | Frontpage glossary description | Acceptance test site | glossary0 |
And I log in as "admin"
And I click on "Turn editing on" "link" in the "Administration" "block"
And I add the "Random glossary entry" block
And I configure the "block_glossary_random" block
And I set the following fields to these values:
| Title | Tip of the day |
| Take entries from this glossary | Tips and Tricks |
And I press "Save changes"
And I click on "Add a new entry" "link" in the "Tip of the day" "block"
And I set the following fields to these values:
| Concept | Never come late |
| Definition | Come in time for your classes |
And I press "Save changes"
When I log out
Then I should see "Never come late" in the "Tip of the day" "block"
And I should see "Come in time for your classes" in the "Tip of the day" "block"
@@ -0,0 +1,38 @@
@block @block_html @core_block
Feature: Adding and configuring HTML blocks
In order to have custom blocks on a page
As admin
I need to be able to create, configure and change HTML blocks
@javascript
Scenario: Configuring the HTML block with Javascript on
Given I log in as "admin"
When I click on "Turn editing on" "link" in the "Administration" "block"
And I add the "HTML" block
And I configure the "(new HTML block)" block
And I set the field "Content" to "Static text without a header"
And I press "Save changes"
Then I should not see "(new HTML block)"
And I configure the "block_html" block
And I set the field "Block title" to "The HTML block header"
And I set the field "Content" to "Static text with a header"
And I press "Save changes"
And "block_html" "block" should exist
And "The HTML block header" "block" should exist
And I should see "Static text with a header" in the "The HTML block header" "block"
Scenario: Configuring the HTML block with Javascript off
Given I log in as "admin"
When I click on "Turn editing on" "link" in the "Administration" "block"
And I add the "HTML" block
And I configure the "(new HTML block)" block
And I set the field "Content" to "Static text without a header"
And I press "Save changes"
Then I should not see "(new HTML block)"
And I configure the "block_html" block
And I set the field "Block title" to "The HTML block header"
And I set the field "Content" to "Static text with a header"
And I press "Save changes"
And "block_html" "block" should exist
And "The HTML block header" "block" should exist
And I should see "Static text with a header" in the "The HTML block header" "block"
@@ -0,0 +1,36 @@
@block @block_html
Feature: HTML blocks in a course
In order to have one or multiple HTML blocks in a course
As a teacher
I need to be able to create and change such blocks
Scenario: Adding HTML block in a course
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Terry1 | Teacher1 | teacher@asd.com |
| student1 | Sam1 | Student1 | student1@asd.com |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
When I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
And I add the "HTML" block
And I configure the "(new HTML block)" block
And I set the field "Content" to "First block content"
And I set the field "Block title" to "First block header"
And I press "Save changes"
And I add the "HTML" block
And I configure the "(new HTML block)" block
And I set the field "Content" to "Second block content"
And I set the field "Block title" to "Second block header"
And I press "Save changes"
And I log out
And I log in as "student1"
And I follow "Course 1"
And I should see "First block content" in the "First block header" "block"
And I should see "Second block content" in the "Second block header" "block"
@@ -0,0 +1,41 @@
@block @block_html
Feature: Adding and configuring HTML blocks
In order to have one or multiple HTML blocks on a page
As admin
I need to be able to create, configure and change HTML blocks
Background:
Given I log in as "admin"
When I click on "Turn editing on" "link" in the "Administration" "block"
And I add the "HTML" block
Scenario: Other users can not see HTML block that has not been configured
Then "(new HTML block)" "block" should exist
And I log out
And "(new HTML block)" "block" should not exist
And "block_html" "block" should not exist
Scenario: Other users can see HTML block that has been configured even when it has no header
And I configure the "(new HTML block)" block
And I set the field "Content" to "Static text without a header"
And I press "Save changes"
Then I should not see "(new HTML block)"
And I log out
And I am on homepage
And "block_html" "block" should exist
And I should see "Static text without a header" in the "block_html" "block"
And I should not see "(new HTML block)"
Scenario: Adding multiple instances of HTML block on a page
And I configure the "block_html" block
And I set the field "Block title" to "The HTML block header"
And I set the field "Content" to "Static text with a header"
And I press "Save changes"
And I add the "HTML" block
And I configure the "(new HTML block)" block
And I set the field "Block title" to "The second HTML block header"
And I set the field "Content" to "Second block contents"
And I press "Save changes"
And I log out
Then I should see "Static text with a header" in the "The HTML block header" "block"
And I should see "Second block contents" in the "The second HTML block header" "block"
@@ -0,0 +1,190 @@
@block @block_navigation
Feature: Expand the courses nodes within the navigation block
In order to navigate the site
As an anonymous user, a guest, a student, and an admin
I need to expand the courses node in the navigation block and check the display of courses and categories.
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@local.host |
| student1 | Student | 1 | student1@local.host |
And the following "categories" exist:
| name | category | idnumber | visible |
| cat1 | 0 | cat1 | 1 |
| cat2 | 0 | cat2 | 1 |
| cat21 | cat2 | cat21 | 1 |
| cat211 | cat21 | cat211 | 1 |
| cat3 | 0 | cat3 | 0 |
And the following "courses" exist:
| fullname | shortname | category | visible |
| Course 1 | c1 | cat1 | 1 |
| Course 2 | c2 | cat2 | 1 |
| Course 3 | c3 | cat21 | 1 |
| Course 4 | c4 | cat211 | 1 |
| Course 5 | c5 | cat211 | 0 |
| Course 6 | c6 | cat211 | 0 |
| Course 7 | c7 | cat3 | 1 |
| Course 8 | c8 | cat3 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | c1 | teacher |
| teacher1 | c3 | teacher |
| teacher1 | c5 | teacher |
| student1 | c1 | student |
| student1 | c2 | student |
| student1 | c4 | student |
And I log in as "admin"
And I follow "Course 2"
And I turn editing mode on
And I click on "Edit settings" "link" in the "Administration" "block"
And I set the following fields to these values:
| Allow guest access | Yes |
And I press "Save changes"
And I set the following administration settings values:
| Show all courses | 1 |
And I log out
@javascript
Scenario: As an anonymous user I expand the courses node to see courses.
When I should see "You are not logged in." in the ".logininfo" "css_element"
And I should see "Home" in the "Navigation" "block"
And I should see "Courses" in the "Navigation" "block"
And I expand "Courses" node
And I should see "cat1" in the "Navigation" "block"
And I should see "cat2" in the "Navigation" "block"
And I should not see "cat3" in the "Navigation" "block"
And I expand "cat1" node
And I expand "cat2" node
And I should see "cat21" in the "Navigation" "block"
And I expand "cat21" node
And I should see "cat211" in the "Navigation" "block"
And I expand "cat211" node
Then I should see "c1" in the "Navigation" "block"
And I should see "c2" in the "Navigation" "block"
And I should see "c3" in the "Navigation" "block"
And I should see "c4" in the "Navigation" "block"
And I should not see "c5" in the "Navigation" "block"
And I should not see "c6" in the "Navigation" "block"
And navigation node "c1" should not be expandable
And navigation node "c2" should not be expandable
And navigation node "c3" should not be expandable
And navigation node "c4" should not be expandable
@javascript
Scenario: As the admin user I expand the courses and category nodes to see courses.
When I log in as "admin"
And I should see "Home" in the "Navigation" "block"
And I should see "Courses" in the "Navigation" "block"
And I expand "Courses" node
And I should see "cat1" in the "Navigation" "block"
And I should see "cat2" in the "Navigation" "block"
And I should see "cat3" in the "Navigation" "block"
And I expand "cat1" node
And I expand "cat2" node
And I expand "cat3" node
And I should see "cat21" in the "Navigation" "block"
And I expand "cat21" node
And I should see "cat211" in the "Navigation" "block"
And I expand "cat211" node
Then I should see "c1" in the "Navigation" "block"
And I should see "c2" in the "Navigation" "block"
And I should see "c3" in the "Navigation" "block"
And I should see "c4" in the "Navigation" "block"
And I should see "c5" in the "Navigation" "block"
And I should see "c6" in the "Navigation" "block"
And I should see "c7" in the "Navigation" "block"
And I should see "c8" in the "Navigation" "block"
And navigation node "c1" should be expandable
And navigation node "c2" should be expandable
And navigation node "c3" should be expandable
And navigation node "c4" should be expandable
And navigation node "c5" should be expandable
And navigation node "c6" should be expandable
And navigation node "c7" should be expandable
And navigation node "c8" should be expandable
@javascript
Scenario: As teacher1 I expand the courses and category nodes to see courses.
When I log in as "teacher1"
And I should see "Home" in the "Navigation" "block"
And I should see "Courses" in the "Navigation" "block"
And I expand "Courses" node
And I should see "cat1" in the "Navigation" "block"
And I should see "cat2" in the "Navigation" "block"
And I should not see "cat3" in the "Navigation" "block"
And I expand "cat1" node
And I expand "cat2" node
And I should see "cat21" in the "Navigation" "block"
And I expand "cat21" node
And I should see "cat211" in the "Navigation" "block"
And I expand "cat211" node
Then I should see "c1" in the "Navigation" "block"
And I should see "c2" in the "Navigation" "block"
And I should see "c3" in the "Navigation" "block"
And I should see "c4" in the "Navigation" "block"
And I should see "c5" in the "Navigation" "block"
And I should not see "c6" in the "Navigation" "block"
And I should not see "c7" in the "Navigation" "block"
And I should not see "c8" in the "Navigation" "block"
And navigation node "c1" should be expandable
And navigation node "c2" should be expandable
And navigation node "c3" should be expandable
And navigation node "c4" should not be expandable
And navigation node "c5" should be expandable
@javascript
Scenario: As student1 I expand the courses and category nodes to see courses.
When I log in as "student1"
And I should see "Home" in the "Navigation" "block"
And I should see "Courses" in the "Navigation" "block"
And I expand "Courses" node
And I should see "cat1" in the "Navigation" "block"
And I should see "cat2" in the "Navigation" "block"
And I should not see "cat3" in the "Navigation" "block"
And I expand "cat1" node
And I expand "cat2" node
And I should see "cat21" in the "Navigation" "block"
And I expand "cat21" node
And I should see "cat211" in the "Navigation" "block"
And I expand "cat211" node
Then I should see "c1" in the "Navigation" "block"
And I should see "c2" in the "Navigation" "block"
And I should see "c3" in the "Navigation" "block"
And I should see "c4" in the "Navigation" "block"
And I should not see "c5" in the "Navigation" "block"
And I should not see "c6" in the "Navigation" "block"
And I should not see "c7" in the "Navigation" "block"
And I should not see "c8" in the "Navigation" "block"
And navigation node "c1" should be expandable
And navigation node "c2" should be expandable
And navigation node "c3" should not be expandable
And navigation node "c4" should be expandable
@javascript
Scenario: As guest I expand the courses and category nodes to see courses.
When I log in as "guest"
And I should see "Home" in the "Navigation" "block"
And I should see "Courses" in the "Navigation" "block"
And I expand "Courses" node
And I should see "cat1" in the "Navigation" "block"
And I should see "cat2" in the "Navigation" "block"
And I should not see "cat3" in the "Navigation" "block"
And I expand "cat1" node
And I expand "cat2" node
And I should see "cat21" in the "Navigation" "block"
And I expand "cat21" node
And I should see "cat211" in the "Navigation" "block"
And I expand "cat211" node
Then I should see "c1" in the "Navigation" "block"
And I should see "c2" in the "Navigation" "block"
And I should see "c3" in the "Navigation" "block"
And I should see "c4" in the "Navigation" "block"
And I should not see "c5" in the "Navigation" "block"
And I should not see "c6" in the "Navigation" "block"
And I should not see "c7" in the "Navigation" "block"
And I should not see "c8" in the "Navigation" "block"
And navigation node "c1" should not be expandable
And navigation node "c2" should be expandable
And navigation node "c3" should not be expandable
And navigation node "c4" should not be expandable
@@ -66,3 +66,34 @@ Feature: View my courses in navigation block
And I expand "cat33" node
And I should see "c331" in the "Navigation" "block"
And I should not see "c332" in the "Navigation" "block"
@javascript
Scenario: I can expand categories and courses as guest
Given I set the following administration settings values:
| Show my course categories | 1 |
| Show all courses | 1 |
And I log out
And I expand "Courses" node
And I should see "cat1" in the "Navigation" "block"
And I should see "cat2" in the "Navigation" "block"
And I should see "cat3" in the "Navigation" "block"
And I should not see "cat31" in the "Navigation" "block"
And I should not see "cat32" in the "Navigation" "block"
And I should not see "cat331" in the "Navigation" "block"
And I should not see "c1" in the "Navigation" "block"
And I should not see "c2" in the "Navigation" "block"
And I should not see "c31" in the "Navigation" "block"
And I should not see "c32" in the "Navigation" "block"
When I expand "cat3" node
And I expand "cat31" node
And I expand "cat1" node
Then I should see "cat1" in the "Navigation" "block"
And I should see "cat2" in the "Navigation" "block"
And I should see "cat3" in the "Navigation" "block"
And I should see "cat31" in the "Navigation" "block"
And I should see "cat32" in the "Navigation" "block"
And I should not see "cat331" in the "Navigation" "block"
And I should see "c1" in the "Navigation" "block"
And I should not see "c2" in the "Navigation" "block"
And I should see "c31" in the "Navigation" "block"
And I should not see "c32" in the "Navigation" "block"
@@ -0,0 +1,45 @@
@block @block_news_items
Feature: Latest news block displays the course latest news
In order to be aware of the course news
As a user
I need to see the latest news in the main course page
@javascript
Scenario: Latest course news are displayed and can be configured
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@asd.com |
And I log in as "admin"
And I create a course with:
| Course full name | Course 1 |
| Course short name | C1 |
| News items to show | 5 |
And I enrol "Teacher 1" user as "Teacher"
And I log out
And I log in as "teacher1"
And I follow "Course 1"
When I add a new topic to "News forum" forum with:
| Subject | Discussion One |
| Message | Not important |
And I add a new topic to "News forum" forum with:
| Subject | Discussion Two |
| Message | Not important |
And I add a new topic to "News forum" forum with:
| Subject | Discussion Three |
| Message | Not important |
And I follow "Course 1"
Then I should see "Discussion One" in the "Latest news" "block"
And I should see "Discussion Two" in the "Latest news" "block"
And I should see "Discussion Three" in the "Latest news" "block"
And I follow "Edit settings"
And I set the following fields to these values:
| News items to show | 2 |
And I press "Save changes"
And I should not see "Discussion One" in the "Latest news" "block"
And I should see "Discussion Two" in the "Latest news" "block"
And I should see "Discussion Three" in the "Latest news" "block"
And I follow "Edit settings"
And I set the following fields to these values:
| News items to show | 0 |
And I press "Save changes"
And "Latest news" "block" should not exist
+15 -15
View File
@@ -83,13 +83,13 @@ class behat_blocks extends behat_base {
public function i_open_the_blocks_action_menu($blockname) {
if (!$this->running_javascript()) {
throw new DriverException('Blocks action menu not available when Javascript is disabled');
// Action menu does not need to be open if Javascript is off.
return;
}
// If it is already opened we do nothing.
$blocknode = $this->get_block_node($blockname);
$classes = array_flip(explode(' ', $blocknode->getAttribute('class')));
if (!empty($classes['action-menu-shown'])) {
$blocknode = $this->get_text_selector_node('block', $blockname);
if ($blocknode->hasClass('action-menu-shown')) {
return;
}
@@ -97,18 +97,18 @@ class behat_blocks extends behat_base {
}
/**
* Returns the DOM node of the block from <div>.
* Clicks on Configure block for specified block. Page must be in editing mode.
*
* @throws ElementNotFoundException Thrown by behat_base::find
* @param string $blockname The block name
* @return NodeElement
* Argument block_name may be either the name of the block or CSS class of the block.
*
* @Given /^I configure the "(?P<block_name_string>(?:[^"]|\\")*)" block$/
* @param string $blockname
*/
protected function get_block_node($blockname) {
$blockname = $this->getSession()->getSelectorsHandler()->xpathLiteral($blockname);
$xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' block ')][contains(., $blockname)]";
return $this->find('xpath', $xpath);
public function i_configure_the_block($blockname) {
// Note that since $blockname may be either block name or CSS class, we can not use the exact label of "Configure" link.
return array(
new Given('I open the "'.$this->escape($blockname).'" blocks action menu'),
new Given('I click on "Configure" "link" in the "'.$this->escape($blockname).'" "block"')
);
}
}
@@ -4,7 +4,6 @@ Feature: Add and configure blocks throughout the site
As a manager
I need to set and configure blocks throughout the site
@javascript
Scenario: Add and configure a block throughtout the site
Given the following "courses" exists:
| fullname | shortname | category |
@@ -18,8 +17,7 @@ Feature: Add and configure blocks throughout the site
And I log in as "manager1"
And I follow "Turn editing on"
And I add the "Comments" block
And I open the "Comments" blocks action menu
And I follow "Configure Comments block"
And I configure the "Comments" block
And I fill the moodle form with:
| Page contexts | Display throughout the entire site |
And I press "Save changes"
@@ -27,8 +25,7 @@ Feature: Add and configure blocks throughout the site
Then I should see "Comments" in the "Comments" "block"
And I should see "Save comment" in the "Comments" "block"
And I am on homepage
And I open the "Comments" blocks action menu
And I follow "Configure Comments block"
And I configure the "Comments" block
And I fill the moodle form with:
| Default weight | -10 (first) |
And I press "Save changes"
+4 -10
View File
@@ -39,19 +39,16 @@ Feature: Block appearances
And I follow "Course 1"
And I follow "Turn editing on"
And I add the "Comments" block
And I open the "Comments" blocks action menu
And I follow "Configure Comments block"
And I configure the "Comments" block
And I fill the moodle form with:
| Display on page types | Any page |
And I press "Save changes"
@javascript
Scenario: Block settings can be modified so that a block apprears on any page
When I follow "Test survey name"
Then I should see "Comments" in the "Comments" "block"
And I follow "Course 1"
And I open the "Comments" blocks action menu
And I follow "Configure Comments block"
And I configure the "Comments" block
And I fill the moodle form with:
| Display on page types | Any course page |
And I press "Save changes"
@@ -59,11 +56,9 @@ Feature: Block appearances
And I follow "Test survey name"
And I should not see "Comments"
@javascript
Scenario: Block settings can be modified so that a block can be hidden or moved
When I follow "Test book name"
And I open the "Comments" blocks action menu
And I follow "Configure Comments block"
And I configure the "Comments" block
And I fill the moodle form with:
| Visible | No |
And I press "Save changes"
@@ -72,8 +67,7 @@ Feature: Block appearances
Then I should not see "Comments"
And I expand "Course administration" node
And I follow "Turn editing on"
And I open the "Comments" blocks action menu
And I follow "Configure Comments block"
And I configure the "Comments" block
And I fill the moodle form with:
| Visible | Yes |
| Region | Right |
@@ -15,7 +15,6 @@ Feature: Allowed blocks controls
| user | course | role |
| teacher1 | C1 | editingteacher |
@javascript
Scenario: Blocks can be added with the default permissions
Given I log in as "teacher1"
And I follow "Course 1"
@@ -4,7 +4,6 @@ Feature: The context of a block can always be returned to it's original state.
As an admin
I need to be able to return the block to original state
@javascript
Scenario: Add and configure a block to display on every page and revert back
Given the following "courses" exists:
| fullname | shortname | category |
@@ -15,8 +14,7 @@ Feature: The context of a block can always be returned to it's original state.
And I add the "Tags" block
Then I should see "Tags" in the "Tags" "block"
And I click on "Participants" "link" in the "//li[p/span[contains(normalize-space(string(.)), 'Current course')]]" "xpath_element"
And I open the "Tags" blocks action menu
And I follow "Configure Tags block"
And I configure the "Tags" block
And I fill the moodle form with:
| Display on page types | Any page |
And I press "Save changes"
@@ -25,8 +23,7 @@ Feature: The context of a block can always be returned to it's original state.
| Assignment name | Assignment1 |
| Description | Description |
And I follow "Assignment1"
And I open the "Tags" blocks action menu
And I follow "Configure Tags block"
And I configure the "Tags" block
And I fill the moodle form with:
| Display on page types | Any assignment module page |
And I press "Save changes"
@@ -41,8 +38,7 @@ Feature: The context of a block can always be returned to it's original state.
| Description | Description |
And I follow "Assignment2"
And I should see "Tags" in the "Tags" "block"
And I open the "Tags" blocks action menu
And I follow "Configure Tags block"
And I configure the "Tags" block
And I fill the moodle form with:
| Display on page types | Any page |
And I press "Save changes"
+4
View File
@@ -246,3 +246,7 @@ The following snippet illustates how to configure the three core cache stores th
define('TEST_CACHESTORE_MEMCACHE_TESTSERVERS', '127.0.0.1:11211');
define('TEST_CACHESTORE_MEMCACHED_TESTSERVERS', '127.0.0.1:11211');
define('TEST_CACHESTORE_MONGODB_TESTSERVER', 'mongodb://localhost:27017');
Please be aware that if you are using Memcache or Memcached it is recommended to use dedicated Memcached servers.
When caches get purged the memcached servers you have configured get purged, any data stored within them whether it belongs to Moodle or not will be removed.
If you are using Memcached for sessions as well as caching/testing and caches get purged your sessions will be removed prematurely and users will be need to start again.
+2 -1
View File
@@ -718,7 +718,8 @@ class cache_helper {
return $stores;
} else {
$stores = self::get_cache_stores($definition);
if (count($stores) === 0) {
// If mappingsonly is set, having 0 stores is ok.
if ((count($stores) === 0) && (!$definition->is_for_mappings_only())) {
// No suitable stores we found for the definition. We need to come up with a sensible default.
// If this has happened we can be sure that the user has mapped custom stores to either the
// mode of the definition. The first alternative to try is the system default for the mode.
+1 -1
View File
@@ -204,7 +204,7 @@ class cachestore_mongodb extends cache_store implements cache_is_configurable {
throw new coding_exception('This mongodb instance has already been initialised.');
}
$this->database = $this->connection->selectDB($this->databasename);
$this->definitionhash = $definition->generate_definition_hash();
$this->definitionhash = 'm'.$definition->generate_definition_hash();
$this->collection = $this->database->selectCollection($this->definitionhash);
$options = array('name' => 'idx_key');
+22
View File
@@ -59,4 +59,26 @@ class cachestore_mongodb_test extends cachestore_tests {
protected function get_class_name() {
return 'cachestore_mongodb';
}
/**
* A small additional test to make sure definitions that hash a hash starting with a number work OK
*/
public function test_collection_name() {
// This generates a definition that has a hash starting with a number. MDL-46208.
$definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_mongodb', 'abc');
$instance = cachestore_mongodb::initialise_test_instance($definition);
if (!$instance) {
$this->markTestSkipped();
}
$this->assertTrue($instance->set(1, 'alpha'));
$this->assertTrue($instance->set(2, 'beta'));
$this->assertEquals('alpha', $instance->get(1));
$this->assertEquals('beta', $instance->get(2));
$this->assertEquals(array(
1 => 'alpha',
2 => 'beta'
), $instance->get_many(array(1, 2)));
}
}
+27
View File
@@ -470,6 +470,33 @@ class core_cache_testcase extends advanced_testcase {
$this->assertEquals('Test has no value really.', $cache->get('Test'));
}
/**
* Test the mappingsonly setting.
*/
public function test_definition_mappings_only() {
$instance = cache_config_phpunittest::instance(true);
$instance->phpunit_add_definition('phpunit/mappingsonly', array(
'mode' => cache_store::MODE_APPLICATION,
'component' => 'phpunit',
'area' => 'mappingsonly',
'mappingsonly' => true
));
$instance->phpunit_add_definition('phpunit/nonmappingsonly', array(
'mode' => cache_store::MODE_APPLICATION,
'component' => 'phpunit',
'area' => 'nonmappingsonly',
'mappingsonly' => false
));
$cacheonly = cache::make('phpunit', 'mappingsonly');
$this->assertInstanceOf('cache_application', $cacheonly);
$this->assertEquals('cachestore_dummy', $cacheonly->phpunit_get_store_class());
$cachenon = cache::make('phpunit', 'nonmappingsonly');
$this->assertInstanceOf('cache_application', $cachenon);
$this->assertEquals('cachestore_file', $cachenon->phpunit_get_store_class());
}
/**
* Test a very basic definition.
*/
+16 -7
View File
@@ -114,14 +114,23 @@ class event_form extends moodleform {
$mform->addRule('timestart', get_string('required'), 'required');
$mform->addElement('header', 'durationdetails', get_string('eventduration', 'calendar'));
$mform->addElement('radio', 'duration', null, get_string('durationnone', 'calendar'), 0);
$mform->addElement('radio', 'duration', null, get_string('durationuntil', 'calendar'), 1);
$mform->addElement('date_time_selector', 'timedurationuntil', '&nbsp;');
$mform->disabledIf('timedurationuntil','duration','noteq', 1);
$group = array();
$group[] =& $mform->createElement('radio', 'duration', null, get_string('durationnone', 'calendar'), 0);
$group[] =& $mform->createElement('radio', 'duration', null, get_string('durationuntil', 'calendar'), 1);
$group[] =& $mform->createElement('date_time_selector', 'timedurationuntil', '');
$group[] =& $mform->createElement('radio', 'duration', null, get_string('durationminutes', 'calendar'), 2);
$group[] =& $mform->createElement('text', 'timedurationminutes', null);
$mform->addGroup($group, 'durationgroup', '', '<br />', false);
$mform->disabledIf('timedurationuntil', 'duration', 'noteq', 1);
$mform->disabledIf('timedurationuntil[day]', 'duration', 'noteq', 1);
$mform->disabledIf('timedurationuntil[month]', 'duration', 'noteq', 1);
$mform->disabledIf('timedurationuntil[year]', 'duration', 'noteq', 1);
$mform->disabledIf('timedurationuntil[hour]', 'duration', 'noteq', 1);
$mform->disabledIf('timedurationuntil[minute]', 'duration', 'noteq', 1);
$mform->addElement('radio', 'duration', null, get_string('durationminutes', 'calendar'), 2);
$mform->addElement('text', 'timedurationminutes', null);
$mform->setType('timedurationminutes', PARAM_INT);
$mform->disabledIf('timedurationminutes','duration','noteq', 2);
@@ -130,7 +139,7 @@ class event_form extends moodleform {
if ($newevent) {
$mform->addElement('header', 'repeatevents', get_string('repeatedevents', 'calendar'));
$mform->addElement('checkbox', 'repeat', get_string('repeatevent', 'calendar'), null, 'repeat');
$mform->addElement('checkbox', 'repeat', get_string('repeatevent', 'calendar'), null);
$mform->addElement('text', 'repeats', get_string('repeatweeksl', 'calendar'), 'maxlength="10" size="10"');
$mform->setType('repeats', PARAM_INT);
$mform->setDefault('repeats', 1);
+1 -1
View File
@@ -1044,7 +1044,7 @@ function calendar_filter_controls(moodle_url $returnurl) {
$groupevents = true;
$id = optional_param( 'id',0,PARAM_INT );
$seturl = new moodle_url('/calendar/set.php', array('return' => base64_encode($returnurl->out(false)), 'sesskey'=>sesskey()));
$seturl = new moodle_url('/calendar/set.php', array('return' => base64_encode($returnurl->out_as_local_url(false)), 'sesskey'=>sesskey()));
$content = html_writer::start_tag('ul');
$seturl->param('var', 'showglobal');
+3 -5
View File
@@ -259,8 +259,7 @@ class core_calendar_renderer extends plugin_renderer_base {
if (calendar_user_can_add_event($calendar->course)) {
$output .= $this->add_event_button($calendar->course->id, 0, 0, 0, $calendar->time);
}
//$output .= html_writer::tag('label', get_string('dayview', 'calendar'), array('for'=>'cal_course_flt_jump'));
$output .= $this->course_filter_selector($returnurl, get_string('dayview', 'calendar'));
$output .= $this->course_filter_selector($returnurl, get_string('dayviewfor', 'calendar'));
$output .= html_writer::end_tag('div');
// Controls
$output .= html_writer::tag('div', calendar_top_controls('day', array('id' => $calendar->courseid, 'time' => $calendar->time)), array('class'=>'controls'));
@@ -468,7 +467,7 @@ class core_calendar_renderer extends plugin_renderer_base {
if (calendar_user_can_add_event($calendar->course)) {
$output .= $this->add_event_button($calendar->course->id, 0, 0, 0, $calendar->time);
}
$output .= get_string('detailedmonthview', 'calendar').': '.$this->course_filter_selector($returnurl);
$output .= $this->course_filter_selector($returnurl, get_string('detailedmonthviewfor', 'calendar'));
$output .= html_writer::end_tag('div', array('class'=>'header'));
// Controls
$output .= html_writer::tag('div', calendar_top_controls('month', array('id' => $calendar->courseid, 'time' => $calendar->time)), array('class' => 'controls'));
@@ -691,8 +690,7 @@ class core_calendar_renderer extends plugin_renderer_base {
if (calendar_user_can_add_event($calendar->course)) {
$output .= $this->add_event_button($calendar->course->id);
}
$output .= html_writer::tag('label', get_string('upcomingevents', 'calendar'), array('for'=>'cal_course_flt_jump'));
$output .= $this->course_filter_selector($returnurl);
$output .= $this->course_filter_selector($returnurl, get_string('upcomingeventsfor', 'calendar'));
$output .= html_writer::end_tag('div');
if ($events) {
+2 -2
View File
@@ -44,14 +44,14 @@ require_once($CFG->dirroot.'/calendar/lib.php');
require_sesskey();
$var = required_param('var', PARAM_ALPHA);
$return = clean_param(base64_decode(required_param('return', PARAM_RAW)), PARAM_URL);
$return = clean_param(base64_decode(required_param('return', PARAM_RAW)), PARAM_LOCALURL);
$courseid = optional_param('id', -1, PARAM_INT);
if ($courseid != -1) {
$return = new moodle_url($return, array('course' => $courseid));
} else {
$return = new moodle_url($return);
}
$url = new moodle_url('/calendar/set.php', array('return'=>base64_encode($return->out(false)), 'course' => $courseid, 'var'=>$var, 'sesskey'=>sesskey()));
$url = new moodle_url('/calendar/set.php', array('return'=>base64_encode($return->out_as_local_url(false)), 'course' => $courseid, 'var'=>$var, 'sesskey'=>sesskey()));
$PAGE->set_url($url);
$PAGE->set_context(context_system::instance());
@@ -62,6 +62,7 @@ Y.extend(EVENT, Y.Base, {
}
},
startShow : function() {
this.cancelHide();
if (this.get(SHOWTIMEOUT) !== null) {
this.cancelShow();
}
@@ -82,6 +83,7 @@ Y.extend(EVENT, Y.Base, {
this.fire('showevent');
},
startHide : function() {
this.cancelShow();
if (this.get(HIDETIMEOUT) !== null) {
this.cancelHide();
}
@@ -1 +1 @@
YUI.add("moodle-calendar-eventmanager",function(e,t){var n="Calendar event",r="eventId",i="node",s="title",o="content",u="delay",a="showTimeout",f="hideTimeout",l=function(){l.superclass.constructor.apply(this,arguments)},c;e.extend(l,e.Base,{initpanelcalled:!1,initializer:function(){this.get(r);var e=this.get(i),t;return e?(t=e.ancestor("td"),this.publish("showevent"),this.publish("hideevent"),t.on("mouseenter",this.startShow,this),t.on("mouseleave",this.startHide,this),t.on("focus",this.startShow,this),t.on("blur",this.startHide,this),!0):!1},initPanel:function(){if(!this.initpanelcalled){this.initpanelcalled=!0;var t=this.get(i),n=t.ancestor("td"),u=n.ancestor("div"),a;a=new e.Overlay({constrain:u,align:{node:n,points:[e.WidgetPositionAlign.TL,e.WidgetPositionAlign.BC]},headerContent:e.Node.create('<h2 class="eventtitle">'+this.get(s)+"</h2>"),bodyContent:e.Node.create('<div class="eventcontent">'+this.get(o)+"</div>"),visible:!1,id:this.get(r)+"_panel",width:Math.floor(u.get("offsetWidth")*.9)+"px"}),a.render(n),t.setAttribute("aria-controls",a.get("id")),a.get("boundingBox").addClass("calendar-event-panel"),a.get("boundingBox").setAttribute("aria-live","off"),this.on("showevent",a.show,a),this.on("showevent",this.setAriashow,a),this.on("hideevent",this.setAriahide,a),this.on("hideevent",a.hide,a)}},startShow:function(){this.get(a)!==null&&this.cancelShow();var e=this;this.set(a,setTimeout(function(){e.show()},this.get(u)))},cancelShow:function(){clearTimeout(this.get(a))},setAriashow:function(){this.get("boundingBox").setAttribute("aria-live","assertive")},setAriahide:function(){this.get("boundingBox").setAttribute("aria-live","off")},show:function(){this.initPanel(),this.fire("showevent")},startHide:function(){this.get(f)!==null&&this.cancelHide();var e=this;this.set(f,setTimeout(function(){e.hide()},this.get(u)))},hide:function(){this.fire("hideevent")},cancelHide:function(){clearTimeout(this.get(f))}},{NAME:n,ATTRS:{eventId:{setter:function(t){return this.set(i,e.one("#"+t)),t},validator:e.Lang.isString},node:{setter:function(t){return typeof t=="string"&&(t=e.one("#"+t)),t}},title:{validator:e.Lang.isString},content:{validator:e.Lang.isString},delay:{value:300,validator:e.Lang.isNumber},showTimeout:{value:null},hideTimeout:{value:null}}}),e.augment(l,e.EventTarget),c={add_event:function(e){new l(e)}},M.core_calendar=M.core_calendar||{},e.mix(M.core_calendar,c)},"@VERSION@",{requires:["base","node","event-mouseenter","overlay","moodle-calendar-eventmanager-skin"]});
YUI.add("moodle-calendar-eventmanager",function(e,t){var n="Calendar event",r="eventId",i="node",s="title",o="content",u="delay",a="showTimeout",f="hideTimeout",l=function(){l.superclass.constructor.apply(this,arguments)},c;e.extend(l,e.Base,{initpanelcalled:!1,initializer:function(){this.get(r);var e=this.get(i),t;return e?(t=e.ancestor("td"),this.publish("showevent"),this.publish("hideevent"),t.on("mouseenter",this.startShow,this),t.on("mouseleave",this.startHide,this),t.on("focus",this.startShow,this),t.on("blur",this.startHide,this),!0):!1},initPanel:function(){if(!this.initpanelcalled){this.initpanelcalled=!0;var t=this.get(i),n=t.ancestor("td"),u=n.ancestor("div"),a;a=new e.Overlay({constrain:u,align:{node:n,points:[e.WidgetPositionAlign.TL,e.WidgetPositionAlign.BC]},headerContent:e.Node.create('<h2 class="eventtitle">'+this.get(s)+"</h2>"),bodyContent:e.Node.create('<div class="eventcontent">'+this.get(o)+"</div>"),visible:!1,id:this.get(r)+"_panel",width:Math.floor(u.get("offsetWidth")*.9)+"px"}),a.render(n),t.setAttribute("aria-controls",a.get("id")),a.get("boundingBox").addClass("calendar-event-panel"),a.get("boundingBox").setAttribute("aria-live","off"),this.on("showevent",a.show,a),this.on("showevent",this.setAriashow,a),this.on("hideevent",this.setAriahide,a),this.on("hideevent",a.hide,a)}},startShow:function(){this.cancelHide(),this.get(a)!==null&&this.cancelShow();var e=this;this.set(a,setTimeout(function(){e.show()},this.get(u)))},cancelShow:function(){clearTimeout(this.get(a))},setAriashow:function(){this.get("boundingBox").setAttribute("aria-live","assertive")},setAriahide:function(){this.get("boundingBox").setAttribute("aria-live","off")},show:function(){this.initPanel(),this.fire("showevent")},startHide:function(){this.cancelShow(),this.get(f)!==null&&this.cancelHide();var e=this;this.set(f,setTimeout(function(){e.hide()},this.get(u)))},hide:function(){this.fire("hideevent")},cancelHide:function(){clearTimeout(this.get(f))}},{NAME:n,ATTRS:{eventId:{setter:function(t){return this.set(i,e.one("#"+t)),t},validator:e.Lang.isString},node:{setter:function(t){return typeof t=="string"&&(t=e.one("#"+t)),t}},title:{validator:e.Lang.isString},content:{validator:e.Lang.isString},delay:{value:300,validator:e.Lang.isNumber},showTimeout:{value:null},hideTimeout:{value:null}}}),e.augment(l,e.EventTarget),c={add_event:function(e){new l(e)}},M.core_calendar=M.core_calendar||{},e.mix(M.core_calendar,c)},"@VERSION@",{requires:["base","node","event-mouseenter","overlay","moodle-calendar-eventmanager-skin"]});
@@ -62,6 +62,7 @@ Y.extend(EVENT, Y.Base, {
}
},
startShow : function() {
this.cancelHide();
if (this.get(SHOWTIMEOUT) !== null) {
this.cancelShow();
}
@@ -82,6 +83,7 @@ Y.extend(EVENT, Y.Base, {
this.fire('showevent');
},
startHide : function() {
this.cancelShow();
if (this.get(HIDETIMEOUT) !== null) {
this.cancelHide();
}
+2
View File
@@ -60,6 +60,7 @@ Y.extend(EVENT, Y.Base, {
}
},
startShow : function() {
this.cancelHide();
if (this.get(SHOWTIMEOUT) !== null) {
this.cancelShow();
}
@@ -80,6 +81,7 @@ Y.extend(EVENT, Y.Base, {
this.fire('showevent');
},
startHide : function() {
this.cancelShow();
if (this.get(HIDETIMEOUT) !== null) {
this.cancelHide();
}
+2 -2
View File
@@ -526,9 +526,9 @@ class comment {
$c->content = $u->ccontent;
$c->format = $u->cformat;
$c->timecreated = $u->ctimecreated;
$c->strftimeformat = get_string('strftimerecent', 'langconfig');
$c->strftimeformat = get_string('strftimerecentfull', 'langconfig');
$url = new moodle_url('/user/view.php', array('id'=>$u->id, 'course'=>$this->courseid));
$c->profileurl = $url->out(true);
$c->profileurl = $url->out(false); // URL should not be escaped just yet.
$c->fullname = fullname($u);
$c->time = userdate($c->timecreated, $c->strftimeformat);
$c->content = format_text($c->content, $c->format, $formatoptions);
+1 -1
View File
@@ -8,6 +8,6 @@
"require-dev": {
"phpunit/phpunit": "3.7.*",
"phpunit/dbUnit": "1.2.*",
"moodlehq/behat-extension": "1.26.8"
"moodlehq/behat-extension": "1.26.9"
}
}
+5
View File
@@ -240,6 +240,11 @@ $CFG->admin = 'admin';
// $CFG->session_memcached_acquire_lock_timeout = 120;
// $CFG->session_memcached_lock_expire = 7200; // Ignored if memcached extension <= 2.1.0
//
// Please be aware that when selecting either Memcached or Memcache for sessions that it is advised to use a dedicated
// memcache server. The memcache and memcached extensions do not provide isolated environments for individual uses.
// Using the same server for other purposes (MUC for example) can lead to sessions being prematurely removed should
// the other uses of the server purge the cache.
//
// Following setting allows you to alter how frequently is timemodified updated in sessions table.
// $CFG->session_update_timemodified_frequency = 20; // In seconds.
//
+1 -10
View File
@@ -696,16 +696,7 @@ class dndupload_ajax_processor {
$mod = $info->get_cm($this->cm->id);
// Trigger course module created event.
$event = \core\event\course_module_created::create(array(
'courseid' => $this->course->id,
'context' => context_module::instance($mod->id),
'objectid' => $mod->id,
'other' => array(
'modulename' => $mod->modname,
'name' => $mod->name,
'instanceid' => $instanceid
)
));
$event = \core\event\course_module_created::create_from_cm($mod);
$event->trigger();
add_to_log($this->course->id, $mod->modname, "add",
+24 -8
View File
@@ -31,9 +31,10 @@ $categoryid = optional_param('category', 0, PARAM_INT); // Course category - can
$returnto = optional_param('returnto', 0, PARAM_ALPHANUM); // Generic navigation return page switch.
$PAGE->set_pagelayout('admin');
$pageparams = array('id'=>$id);
if (empty($id)) {
$pageparams = array('category'=>$categoryid);
if ($id) {
$pageparams = array('id' => $id);
} else {
$pageparams = array('category' => $categoryid);
}
$PAGE->set_url('/course/edit.php', $pageparams);
@@ -166,22 +167,37 @@ $stradministration = get_string("administration");
$strcategories = get_string("categories");
if (!empty($course->id)) {
$PAGE->navbar->add($streditcoursesettings);
// Navigation note: The user is editing a course, the course will exist within the navigation and settings.
// The navigation will automatically find the Edit settings page under course navigation.
$pagedesc = $streditcoursesettings;
$title = $streditcoursesettings;
$fullname = $course->fullname;
} else {
$PAGE->navbar->add($stradministration, new moodle_url('/admin/index.php'));
$PAGE->navbar->add($strcategories, new moodle_url('/course/index.php'));
$PAGE->navbar->add($straddnewcourse);
// The user is adding a course, this page isn't presented in the site navigation/admin.
// Adding a new course is part of course category management territory.
// We'd prefer to use the management interface URL without args.
$managementurl = new moodle_url('/course/management.php');
// These are the caps required in order to see the management interface.
$managementcaps = array('moodle/category:manage', 'moodle/course:create');
if ($categoryid && !has_any_capability($managementcaps, context_system::instance())) {
// If the user doesn't have either manage caps then they can only manage within the given category.
$managementurl->param('categoryid', $categoryid);
}
// Because the course category management interfaces are buried in the admin tree and that is loaded by ajax
// we need to manually tell the navigation we need it loaded. The second arg does this.
navigation_node::override_active_url($managementurl, true);
$pagedesc = $straddnewcourse;
$title = "$site->shortname: $straddnewcourse";
$fullname = $site->fullname;
$PAGE->navbar->add($pagedesc);
}
$PAGE->set_title($title);
$PAGE->set_heading($fullname);
echo $OUTPUT->header();
echo $OUTPUT->heading($streditcoursesettings);
echo $OUTPUT->heading($pagedesc);
$editform->display();
+4
View File
@@ -3488,6 +3488,10 @@ function mod_duplicate_activity($course, $cm, $sr = null) {
$section = $DB->get_record('course_sections', array('id' => $cm->section, 'course' => $cm->course));
moveto_module($newcm, $section, $cm);
moveto_module($cm, $section, $newcm);
// Trigger course module created event. We can trigger the event only if we know the newcmid.
$event = \core\event\course_module_created::create_from_cm($newcm);
$event->trigger();
}
rebuild_course_cache($cm->course);
+4
View File
@@ -120,6 +120,10 @@ if ($newcmid) {
$newcm = get_coursemodule_from_id('', $newcmid, $course->id, true, MUST_EXIST);
moveto_module($newcm, $section, $cm);
moveto_module($cm, $section, $newcm);
// Trigger course module created event. We can trigger the event only if we know the newcmid.
$event = \core\event\course_module_created::create_from_cm($newcm);
$event->trigger();
}
$rc->destroy();
+6 -10
View File
@@ -145,16 +145,11 @@ function add_moduleinfo($moduleinfo, $course, $mform = null) {
}
// Trigger event based on the action we did.
$event = \core\event\course_module_created::create(array(
'courseid' => $course->id,
'context' => $modcontext,
'objectid' => $moduleinfo->coursemodule,
'other' => array(
'modulename' => $moduleinfo->modulename,
'name' => $moduleinfo->name,
'instanceid' => $moduleinfo->instance
)
));
// Api create_from_cm expects modname and id property, and we don't want to modify $moduleinfo since we are returning it.
$eventdata = clone $moduleinfo;
$eventdata->modname = $eventdata->modulename;
$eventdata->id = $eventdata->coursemodule;
$event = \core\event\course_module_created::create_from_cm($eventdata, $modcontext);
$event->trigger();
add_to_log($course->id, $moduleinfo->modulename, "add",
@@ -180,6 +175,7 @@ function add_moduleinfo($moduleinfo, $course, $mform = null) {
*/
function edit_module_post_actions($moduleinfo, $course) {
global $CFG;
require_once($CFG->libdir.'/gradelib.php');
$modcontext = context_module::instance($moduleinfo->coursemodule);
$hasgrades = plugin_supports('mod', $moduleinfo->modulename, FEATURE_GRADE_HAS_GRADE, false);
+1 -3
View File
@@ -122,9 +122,7 @@ class behat_course extends behat_base {
public function i_go_to_the_courses_management_page() {
return array(
new Given('I am on homepage'),
new Given('I expand "' . get_string('administrationsite') . '" node'),
new Given('I expand "' . get_string('courses', 'admin') . '" node'),
new Given('I follow "' . get_string('coursemgmt', 'admin') . '"')
new Given('I navigate to "' . get_string('coursemgmt', 'admin') . '" node in "' . get_string('administrationsite') . ' > ' . get_string('courses', 'admin') . '"')
);
}
@@ -0,0 +1,31 @@
@core @core_course
Feature: Managers can create courses
In order to group users and contents
As a manager
I need to create courses and set default values on them
@javascript
Scenario: Courses are created with the default forum and blocks
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@asd.com |
| student1 | Student | 1 | student1@asd.com |
And I log in as "admin"
And I create a course with:
| Course full name | Course 1 |
| Course short name | C1 |
And I enrol "Teacher 1" user as "Teacher"
And I enrol "Student 1" user as "Student"
And I log out
When I log in as "teacher1"
And I follow "Course 1"
Then "Latest news" "block" should exist
And I follow "News forum"
And "Add a new topic" "button" should exist
And "Forced subscription" "link" should not exist
And I log out
And I log in as "student1"
And I follow "Course 1"
And I follow "News forum"
And "Add a new topic" "button" should not exist
And I should see "Forced subscription" in the "Administration" "block"
@@ -12,9 +12,7 @@ Feature: The maximum number of weeks/topics in a course can be configured
| user | course | role |
| manager1 | Acceptance test site | manager |
And I log in as "admin"
And I expand "Site administration" node
And I expand "Courses" node
And I follow "Course default settings"
And I navigate to "Course default settings" node in "Site administration > Courses"
@javascript
Scenario: The number of sections can be increased and the limits are applied to courses
+26 -3
View File
@@ -1921,7 +1921,7 @@ class core_course_courselib_testcase extends advanced_testcase {
* Tests for event related to course module creation.
*/
public function test_course_module_created_event() {
global $USER, $DB;
global $USER, $DB, $CFG;
$this->resetAfterTest();
// Create an assign module.
@@ -1929,9 +1929,8 @@ class core_course_courselib_testcase extends advanced_testcase {
$modinfo = $this->create_specific_module_test('assign');
$events = $sink->get_events();
$event = array_pop($events);
$sink->close();
$cm = $DB->get_record('course_modules', array('id' => $modinfo->coursemodule), '*', MUST_EXIST);
$cm = get_coursemodule_from_id('assign', $modinfo->coursemodule, 0, false, MUST_EXIST);
$mod = $DB->get_record('assign', array('id' => $modinfo->instance), '*', MUST_EXIST);
// Validate event data.
@@ -1955,6 +1954,30 @@ class core_course_courselib_testcase extends advanced_testcase {
$arr = array($cm->course, "course", "add mod", "../mod/assign/view.php?id=$cm->id", "assign $cm->instance");
$this->assertEventLegacyLogData($arr, $event);
// Let us see if duplicating an activity results in a nice course module created event.
$sink->clear();
$course = get_course($mod->course);
// Discard error logs.
$oldlog = ini_get('error_log');
ini_set('error_log', "$CFG->dataroot/testlog.log");
$newcmhtml = mod_duplicate_activity($course, $cm);
ini_set('error_log', $oldlog);
$events = $sink->get_events();
$event = array_pop($events);
$sink->close();
// Validate event data.
$this->assertInstanceOf('\core\event\course_module_created', $event);
$this->assertEquals($newcmhtml->cmid, $event->objectid);
$this->assertEquals($USER->id, $event->userid);
$this->assertEquals($course->id, $event->courseid);
$url = new moodle_url('/mod/assign/view.php', array('id' => $newcmhtml->cmid));
$this->assertEquals($url, $event->get_url());
// Clear the time limit, otherwise PHPUnit complains.
set_time_limit(0);
}
/**
@@ -64,14 +64,14 @@ Feature: Users can auto-enrol themself in courses where self enrolment is allowe
And I press "Create group"
And I fill the moodle form with:
| Group name | Group 1 |
| Enrolment key | testgroupenrolkey |
| Enrolment key | Test-groupenrolkey1 |
And I press "Save changes"
And I log out
And I log in as "student1"
And I follow "Course 1"
And I fill the moodle form with:
| Enrolment key | testgroupenrolkey |
| Enrolment key | Test-groupenrolkey1 |
And I press "Enrol me"
Then I should see "Topic 1"
And I should not see "Enrolment options"
And I should not see "Enrol me in this course"
And I should not see "Enrol me in this course"
+38
View File
@@ -58,4 +58,42 @@ class behat_enrol extends behat_base {
);
}
/**
* Enrols the specified user in the current course without options.
*
* This is a simple step, to set enrolment options would be better to
* create a separate step as a TableNode will be required.
*
* @Given /^I enrol "(?P<user_fullname_string>(?:[^"]|\\")*)" user as "(?P<rolename_string>(?:[^"]|\\")*)"$/
* @param string $userfullname
* @param string $rolename
* @return Given[]
*/
public function i_enrol_user_as($userfullname, $rolename) {
$steps = array(
new Given('I follow "' . get_string('enrolledusers', 'enrol') . '"'),
new Given('I press "' . get_string('enrolusers', 'enrol') . '"')
);
if ($this->running_javascript()) {
// We have a div here, not a tr.
$userliteral = $this->getSession()->getSelectorsHandler()->xpathLiteral($userfullname);
$userrowxpath = "//div[contains(concat(' ',normalize-space(@class),' '),' user ')][contains(., $userliteral)]";
$steps[] = new Given('I set the field "' . get_string('assignroles', 'role') . '" to "' . $rolename . '"');
$steps[] = new Given('I click on "' . get_string('enrol', 'enrol') . '" "button" in the "' . $userrowxpath . '" "xpath_element"');
$steps[] = new Given('I press "' . get_string('finishenrollingusers', 'enrol') . '"');
} else {
$steps[] = new Given('I set the field "' . get_string('assignrole', 'role') . '" to "' . $rolename . '"');
$steps[] = new Given('I set the field "addselect" to "' . $userfullname . '"');
$steps[] = new Given('I press "add"');
}
return $steps;
}
}
+4 -8
View File
@@ -86,19 +86,15 @@ class edit_category_form extends moodleform {
$mform->setAdvanced('aggregatesubcats');
}
$options = array(0 => get_string('none'));
for ($i=1; $i<=20; $i++) {
$options[$i] = $i;
}
$mform->addElement('select', 'keephigh', get_string('keephigh', 'grades'), $options);
$mform->addElement('text', 'keephigh', get_string('keephigh', 'grades'), 'size="3"');
$mform->setType('keephigh', PARAM_INT);
$mform->addHelpButton('keephigh', 'keephigh', 'grades');
if ((int)$CFG->grade_keephigh_flag & 2) {
$mform->setAdvanced('keephigh');
}
$mform->addElement('select', 'droplow', get_string('droplow', 'grades'), $options);
$mform->addElement('text', 'droplow', get_string('droplow', 'grades'), 'size="3"');
$mform->setType('droplow', PARAM_INT);
$mform->addHelpButton('droplow', 'droplow', 'grades');
$mform->disabledIf('droplow', 'keephigh', 'noteq', 0);
if ((int)$CFG->grade_droplow_flag & 2) {
+1
View File
@@ -100,6 +100,7 @@ class moodlequickform_guideeditor extends HTML_QuickForm_input {
$mode = gradingform_guide_controller::DISPLAY_EDIT_FULL;
$module = array('name'=>'gradingform_guideeditor',
'fullpath'=>'/grade/grading/form/guide/js/guideeditor.js',
'requires' => array('base', 'dom', 'event', 'event-touch', 'escape'),
'strings' => array(
array('confirmdeletecriterion', 'gradingform_guide'),
array('clicktoedit', 'gradingform_guide'),
+1 -1
View File
@@ -10,7 +10,7 @@ M.gradingform_guide.init = function(Y, options) {
currentfocus = e.currentTarget;
});
Y.all('.markingguidecomment').on('click', function(e) {
currentfocus.set('value', currentfocus.get('value') + '\n' + e.currentTarget.get('innerHTML'));
currentfocus.set('value', currentfocus.get('value') + '\n' + e.currentTarget.get('text'));
currentfocus.focus();
});
+2 -2
View File
@@ -111,9 +111,9 @@ M.gradingform_guideeditor.editmode = function(el, editmode) {
value = M.str.gradingform_guide.clicktoedit
taplain.addClass('empty')
}
taplain.one('.textvalue').set('innerHTML', value)
taplain.one('.textvalue').set('innerHTML', Y.Escape.html(value))
if (tb) {
tbplain.one('.textvalue').set('innerHTML', tb.get('value'))
tbplain.one('.textvalue').set('innerHTML', Y.Escape.html(tb.get('value')))
}
// hide/display textarea, textbox and plaintexts
taplain.removeClass('hiddenelement')
+1 -1
View File
@@ -907,7 +907,7 @@ class gradingform_guide_instance extends gradingform_instance {
if (!empty($this->validationerrors)) {
foreach ($this->validationerrors as $id => $err) {
$a = new stdClass();
$a->criterianame = $criteria[$id]['shortname'];
$a->criterianame = s($criteria[$id]['shortname']);
$a->maxscore = $criteria[$id]['maxscore'];
$html .= html_writer::tag('div', get_string('err_scoreinvalid', 'gradingform_guide', $a),
array('class' => 'gradingform_guide-error'));
+15 -15
View File
@@ -93,20 +93,20 @@ class gradingform_guide_renderer extends plugin_renderer_base {
'name' => '{NAME}[criteria][{CRITERION-id}][sortorder]', 'value' => $criterion['sortorder']));
$shortname = html_writer::empty_tag('input', array('type'=> 'text',
'name' => '{NAME}[criteria][{CRITERION-id}][shortname]', 'value' => htmlspecialchars($criterion['shortname']),
'name' => '{NAME}[criteria][{CRITERION-id}][shortname]', 'value' => $criterion['shortname'],
'id ' => '{NAME}[criteria][{CRITERION-id}][shortname]'));
$shortname = html_writer::tag('div', $shortname, array('class'=>'criterionname'));
$description = html_writer::tag('textarea', htmlspecialchars($criterion['description']),
$description = html_writer::tag('textarea', s($criterion['description']),
array('name' => '{NAME}[criteria][{CRITERION-id}][description]', 'cols' => '65', 'rows' => '5'));
$description = html_writer::tag('div', $description, array('class'=>'criteriondesc'));
$descriptionmarkers = html_writer::tag('textarea', htmlspecialchars($criterion['descriptionmarkers']),
$descriptionmarkers = html_writer::tag('textarea', s($criterion['descriptionmarkers']),
array('name' => '{NAME}[criteria][{CRITERION-id}][descriptionmarkers]', 'cols' => '65', 'rows' => '5'));
$descriptionmarkers = html_writer::tag('div', $descriptionmarkers, array('class'=>'criteriondescmarkers'));
$maxscore = html_writer::empty_tag('input', array('type'=> 'text',
'name' => '{NAME}[criteria][{CRITERION-id}][maxscore]', 'size' => '3',
'value' => htmlspecialchars($criterion['maxscore']),
'value' => $criterion['maxscore'],
'id' => '{NAME}[criteria][{CRITERION-id}][maxscore]'));
$maxscore = html_writer::tag('div', $maxscore, array('class'=>'criterionmaxscore'));
} else {
@@ -125,7 +125,7 @@ class gradingform_guide_renderer extends plugin_renderer_base {
$mode == gradingform_guide_controller::DISPLAY_VIEW) {
$descriptionclass = 'descriptionreadonly';
}
$shortname = html_writer::tag('div', $criterion['shortname'],
$shortname = html_writer::tag('div', s($criterion['shortname']),
array('class'=>'criterionshortname', 'name' => '{NAME}[criteria][{CRITERION-id}][shortname]'));
$descmarkerclass = '';
$descstudentclass = '';
@@ -137,13 +137,13 @@ class gradingform_guide_renderer extends plugin_renderer_base {
$descstudentclass = ' hide';
}
}
$description = html_writer::tag('div', $criterion['description'],
$description = html_writer::tag('div', s($criterion['description']),
array('class'=>'criteriondescription'.$descstudentclass,
'name' => '{NAME}[criteria][{CRITERION-id}][descriptionmarkers]'));
$descriptionmarkers = html_writer::tag('div', $criterion['descriptionmarkers'],
$descriptionmarkers = html_writer::tag('div', s($criterion['descriptionmarkers']),
array('class'=>'criteriondescriptionmarkers'.$descmarkerclass,
'name' => '{NAME}[criteria][{CRITERION-id}][descriptionmarkers]'));
$maxscore = html_writer::tag('div', $criterion['maxscore'],
$maxscore = html_writer::tag('div', s($criterion['maxscore']),
array('class'=>'criteriondescriptionscore', 'name' => '{NAME}[criteria][{CRITERION-id}][maxscore]'));
}
@@ -193,7 +193,7 @@ class gradingform_guide_renderer extends plugin_renderer_base {
$scoreclass = 'error';
$currentscore = $validationerrors[$criterion['id']]['score']; // Show invalid score in form.
}
$input = html_writer::tag('textarea', htmlspecialchars($currentremark),
$input = html_writer::tag('textarea', s($currentremark),
array('name' => '{NAME}[criteria][{CRITERION-id}][remark]', 'cols' => '65', 'rows' => '5',
'class' => 'markingguideremark'));
$criteriontemplate .= html_writer::tag('td', $input, array('class' => 'remark'));
@@ -202,7 +202,7 @@ class gradingform_guide_renderer extends plugin_renderer_base {
$score .= html_writer::empty_tag('input', array('type'=> 'text',
'name' => '{NAME}[criteria][{CRITERION-id}][score]', 'class' => $scoreclass,
'id' => '{NAME}[criteria][{CRITERION-id}][score]',
'size' => '3', 'value' => htmlspecialchars($currentscore)));
'size' => '3', 'value' => $currentscore));
$score .= '/'.$maxscore;
$criteriontemplate .= html_writer::tag('td', $score, array('class' => 'score'));
@@ -211,9 +211,9 @@ class gradingform_guide_renderer extends plugin_renderer_base {
'name' => '{NAME}[criteria][{CRITERION-id}][remark]', 'value' => $currentremark));
} else if ($mode == gradingform_guide_controller::DISPLAY_REVIEW ||
$mode == gradingform_guide_controller::DISPLAY_VIEW) {
$criteriontemplate .= html_writer::tag('td', $currentremark, array('class' => 'remark'));
$criteriontemplate .= html_writer::tag('td', s($currentremark), array('class' => 'remark'));
if (!empty($options['showmarkspercriterionstudents'])) {
$criteriontemplate .= html_writer::tag('td', htmlspecialchars($currentscore). ' / '.$maxscore,
$criteriontemplate .= html_writer::tag('td', s($currentscore). ' / '.$maxscore,
array('class' => 'score'));
}
}
@@ -272,7 +272,7 @@ class gradingform_guide_renderer extends plugin_renderer_base {
$criteriontemplate .= html_writer::end_tag('td'); // Controls.
$criteriontemplate .= html_writer::empty_tag('input', array('type' => 'hidden',
'name' => '{NAME}[comments][{COMMENT-id}][sortorder]', 'value' => $comment['sortorder']));
$description = html_writer::tag('textarea', htmlspecialchars($comment['description']),
$description = html_writer::tag('textarea', s($comment['description']),
array('name' => '{NAME}[comments][{COMMENT-id}][description]', 'cols' => '65', 'rows' => '5'));
$description = html_writer::tag('div', $description, array('class'=>'criteriondesc'));
} else {
@@ -283,12 +283,12 @@ class gradingform_guide_renderer extends plugin_renderer_base {
'name' => '{NAME}[comments][{COMMENT-id}][description]', 'value' => $comment['description']));
}
if ($mode == gradingform_guide_controller::DISPLAY_EVAL) {
$description = html_writer::tag('span', htmlspecialchars($comment['description']),
$description = html_writer::tag('span', s($comment['description']),
array('name' => '{NAME}[comments][{COMMENT-id}][description]',
'title' => get_string('clicktocopy', 'gradingform_guide'),
'id' => '{NAME}[comments][{COMMENT-id}]', 'class'=>'markingguidecomment'));
} else {
$description = $comment['description'];
$description = s($comment['description']);
}
}
$descriptionclass = 'description';
+2 -2
View File
@@ -93,8 +93,8 @@ M.gradingform_rubriceditor.editmode = function(el, editmode, focustb) {
value = (el.hasClass('level')) ? M.str.gradingform_rubric.levelempty : M.str.gradingform_rubric.criterionempty
taplain.addClass('empty')
}
taplain.one('.textvalue').set('innerHTML', value)
if (tb) tbplain.one('.textvalue').set('innerHTML', tb.get('value'))
taplain.one('.textvalue').set('innerHTML', Y.Escape.html(value));
if (tb) tbplain.one('.textvalue').set('innerHTML', Y.Escape.html(tb.get('value')));
// hide/display textarea, textbox and plaintexts
taplain.removeClass('hiddenelement')
ta.addClass('hiddenelement')
+6 -6
View File
@@ -79,13 +79,13 @@ class gradingform_rubric_renderer extends plugin_renderer_base {
}
$criteriontemplate .= html_writer::end_tag('td'); // .controls
$criteriontemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][sortorder]', 'value' => $criterion['sortorder']));
$description = html_writer::tag('textarea', htmlspecialchars($criterion['description']), array('name' => '{NAME}[criteria][{CRITERION-id}][description]', 'cols' => '10', 'rows' => '5'));
$description = html_writer::tag('textarea', s($criterion['description']), array('name' => '{NAME}[criteria][{CRITERION-id}][description]', 'cols' => '10', 'rows' => '5'));
} else {
if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN) {
$criteriontemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][sortorder]', 'value' => $criterion['sortorder']));
$criteriontemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][description]', 'value' => $criterion['description']));
}
$description = $criterion['description'];
$description = s($criterion['description']);
}
$descriptionclass = 'description';
if (isset($criterion['error_description'])) {
@@ -111,12 +111,12 @@ class gradingform_rubric_renderer extends plugin_renderer_base {
$currentremark = $value['remark'];
}
if ($mode == gradingform_rubric_controller::DISPLAY_EVAL) {
$input = html_writer::tag('textarea', htmlspecialchars($currentremark), array('name' => '{NAME}[criteria][{CRITERION-id}][remark]', 'cols' => '10', 'rows' => '5'));
$input = html_writer::tag('textarea', s($currentremark), array('name' => '{NAME}[criteria][{CRITERION-id}][remark]', 'cols' => '10', 'rows' => '5'));
$criteriontemplate .= html_writer::tag('td', $input, array('class' => 'remark'));
} else if ($mode == gradingform_rubric_controller::DISPLAY_EVAL_FROZEN) {
$criteriontemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][remark]', 'value' => $currentremark));
}else if ($mode == gradingform_rubric_controller::DISPLAY_REVIEW || $mode == gradingform_rubric_controller::DISPLAY_VIEW) {
$criteriontemplate .= html_writer::tag('td', $currentremark, array('class' => 'remark'));
$criteriontemplate .= html_writer::tag('td', s($currentremark), array('class' => 'remark'));
}
}
$criteriontemplate .= html_writer::end_tag('tr'); // .criterion
@@ -169,7 +169,7 @@ class gradingform_rubric_renderer extends plugin_renderer_base {
$leveltemplate = html_writer::start_tag('td', $tdattributes);
$leveltemplate .= html_writer::start_tag('div', array('class' => 'level-wrapper'));
if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) {
$definition = html_writer::tag('textarea', htmlspecialchars($level['definition']), array('name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][definition]', 'cols' => '10', 'rows' => '4'));
$definition = html_writer::tag('textarea', s($level['definition']), array('name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][definition]', 'cols' => '10', 'rows' => '4'));
$score = html_writer::label(get_string('criterionempty', 'gradingform_rubric'), '{NAME}criteria{CRITERION-id}levels{LEVEL-id}', false, array('class' => 'accesshide'));
$score .= html_writer::empty_tag('input', array('type' => 'text','id' => '{NAME}criteria{CRITERION-id}levels{LEVEL-id}', 'name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][score]', 'size' => '3', 'value' => $level['score']));
} else {
@@ -177,7 +177,7 @@ class gradingform_rubric_renderer extends plugin_renderer_base {
$leveltemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][definition]', 'value' => $level['definition']));
$leveltemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][score]', 'value' => $level['score']));
}
$definition = $level['definition'];
$definition = s($level['definition']);
$score = $level['score'];
}
if ($mode == gradingform_rubric_controller::DISPLAY_EVAL) {
@@ -106,6 +106,7 @@ class MoodleQuickForm_rubriceditor extends HTML_QuickForm_input {
if (!$this->_flagFrozen) {
$mode = gradingform_rubric_controller::DISPLAY_EDIT_FULL;
$module = array('name'=>'gradingform_rubriceditor', 'fullpath'=>'/grade/grading/form/rubric/js/rubriceditor.js',
'requires' => array('base', 'dom', 'event', 'event-touch', 'escape'),
'strings' => array(array('confirmdeletecriterion', 'gradingform_rubric'), array('confirmdeletelevel', 'gradingform_rubric'),
array('criterionempty', 'gradingform_rubric'), array('levelempty', 'gradingform_rubric')
));
+2 -2
View File
@@ -251,9 +251,9 @@ function grade_get_grade_items_for_activity($cm, $only_main_item=false) {
if (!isset($cm->modname)) {
$params = array($cm->id);
$cm = $DB->get_record_sql("SELECT cm.*, m.name, md.name as modname
$cm = $DB->get_record_sql("SELECT cm.*, md.name as modname
FROM {course_modules} cm,
{modules} md,
{modules} md
WHERE cm.id = ? AND md.id = cm.module", $params);
}
+11
View File
@@ -50,4 +50,15 @@ class core_grade_querylib_testcase extends advanced_testcase {
$this->assertEquals(1, count($cms));
$this->assertTrue(isset($cms[$forum1->cmid]));
}
public function test_grade_get_grade_items_for_activity() {
$this->resetAfterTest(true);
$course = $this->getDataGenerator()->create_course();
$forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
$cm = get_coursemodule_from_id('forum', $forum->cmid, $forum->course);
unset($cm->modname);
$grade = grade_get_grade_items_for_activity($cm);
}
}
+1 -1
View File
@@ -135,7 +135,7 @@ class autogroup_form extends moodleform {
$mform->setType('seed', PARAM_INT);
$buttonarray = array();
$buttonarray[] = &$mform->createElement('submit', 'preview', get_string('preview'), 'xx');
$buttonarray[] = &$mform->createElement('submit', 'preview', get_string('preview'));
$buttonarray[] = &$mform->createElement('submit', 'submitbutton', get_string('submit'));
$buttonarray[] = &$mform->createElement('cancel');
$mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
+20 -3
View File
@@ -111,11 +111,19 @@ class group_form extends moodleform {
}
}
if (!empty($CFG->groupenrolmentkeypolicy) and $data['enrolmentkey'] != '' and $group->enrolmentkey !== $data['enrolmentkey']) {
// enforce password policy only if changing password
if ($data['enrolmentkey'] != '') {
$errmsg = '';
if (!check_password_policy($data['enrolmentkey'], $errmsg)) {
if (!empty($CFG->groupenrolmentkeypolicy) && $group->enrolmentkey !== $data['enrolmentkey']
&& !check_password_policy($data['enrolmentkey'], $errmsg)) {
// Enforce password policy when the password is changed.
$errors['enrolmentkey'] = $errmsg;
} else {
// Prevent twice the same enrolment key in course groups.
$sql = "SELECT id FROM {groups} WHERE id <> :groupid AND courseid = :courseid AND enrolmentkey = :key";
$params = array('groupid' => $data['id'], 'courseid' => $COURSE->id, 'key' => $data['enrolmentkey']);
if ($DB->record_exists_sql($sql, $params)) {
$errors['enrolmentkey'] = get_string('enrolmentkeyalreadyinuse', 'group');
}
}
}
@@ -123,6 +131,15 @@ class group_form extends moodleform {
$errors['name'] = get_string('groupnameexists', 'group', $name);
} else if (!empty($idnumber) && groups_get_group_by_idnumber($COURSE->id, $idnumber)) {
$errors['idnumber']= get_string('idnumbertaken');
} else if ($data['enrolmentkey'] != '') {
$errmsg = '';
if (!empty($CFG->groupenrolmentkeypolicy) && !check_password_policy($data['enrolmentkey'], $errmsg)) {
// Enforce password policy.
$errors['enrolmentkey'] = $errmsg;
} else if ($DB->record_exists('groups', array('courseid' => $COURSE->id, 'enrolmentkey' => $data['enrolmentkey']))) {
// Prevent the same enrolment key from being used multiple times in course groups.
$errors['enrolmentkey'] = get_string('enrolmentkeyalreadyinuse', 'group');
}
}
return $errors;
+39
View File
@@ -89,3 +89,42 @@ Feature: Organize students into groups
| Grouping name | Not the greatest grouping, but it's ok! |
And I press "Save changes"
And I should see "Not the greatest grouping, but it's ok!"
Scenario: Create groups with enrolment key
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 1 |
| Course 2 | C2 | 0 | 1 |
And I log in as "admin"
And I follow "Course 1"
And I expand "Users" node
And I follow "Groups"
When I press "Create group"
And I set the following fields to these values:
| Group name | Group A |
| Enrolment key | badpasswd |
And I press "Save changes"
And I should see "Passwords must have at least 1 digit(s)"
And I set the following fields to these values:
| Group name | Group A |
| Enrolment key | Abcdef-1 |
And I press "Save changes"
And I press "Create group"
And I set the following fields to these values:
| Group name | Group B |
| Enrolment key | Abcdef-1 |
And I press "Save changes"
Then I should see "This enrolment key is already used for another group."
And I set the following fields to these values:
| Enrolment key | Abcdef-2 |
And I press "Save changes"
And the "groups" select box should contain "Group B (0)"
And I am on homepage
And I follow "Course 2"
And I expand "Users" node
And I follow "Groups"
And I press "Create group"
And I set the following fields to these values:
| Group name | Group A |
| Enrolment key | Abcdef-1 |
And I should not see "This enrolment key is already used for another group."
+51
View File
@@ -100,3 +100,54 @@ Feature: Automatic updating of groups and groupings
And the "idnumber" "field" should be readonly
And the "idnumber" field should match "An ID" value
@javascript
Scenario: Update groups with enrolment key
Given the following "courses" exist:
| fullname | shortname |
| Course 2 | C2 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C2 | editingteacher |
And I log out
And I log in as "teacher1"
And I follow "Course 1"
And I expand "Users" node
And I follow "Groups"
And I set the field "groups" to "Group (with ID)"
And I press "Edit group settings"
And I set the following fields to these values:
| Enrolment key | badpasswd |
When I press "Save changes"
Then I should see "Passwords must have at least 1 digit(s)"
And I set the following fields to these values:
| Enrolment key | Abcdef-1 |
And I press "Save changes"
And I set the field "groups" to "Group (with ID)"
And I press "Edit group settings"
And I press "Save changes"
And I should not see "This enrolment key is already used for another group."
And I set the field "groups" to "Group (without ID)"
And I press "Edit group settings"
And I set the following fields to these values:
| Enrolment key | Abcdef-1 |
And I press "Save changes"
And I should see "This enrolment key is already used for another group."
And I set the following fields to these values:
| Enrolment key | Abcdef-2 |
And I press "Save changes"
And I should not see "This enrolment key is already used for another group."
And I am on homepage
And I follow "Course 2"
And I expand "Users" node
And I follow "Groups"
And I press "Create group"
And I set the following fields to these values:
| Group name | Group A |
And I press "Save changes"
And I should not see "This enrolment key is already used for another group."
And I set the field "groups" to "Group A"
And I press "Edit group settings"
And I set the following fields to these values:
| Enrolment key | Abcdef-1 |
And I press "Save changes"
And I should not see "This enrolment key is already used for another group."
+1 -9
View File
@@ -233,17 +233,9 @@ if (defined('COMPONENT_CLASSLOADER')) {
require('version.php');
$CFG->target_release = $release;
$_SESSION = array();
$_SESSION['SESSION'] = new stdClass();
$_SESSION['SESSION']->lang = $CFG->lang;
$_SESSION['USER'] = new stdClass();
$_SESSION['USER']->id = 0;
$_SESSION['USER']->mnethostid = 1;
\core\session\manager::init_empty_session();
global $SESSION;
global $USER;
$SESSION = &$_SESSION['SESSION'];
$USER = &$_SESSION['USER'];
global $COURSE;
$COURSE = new stdClass();
+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'] = 'Aragonés';
+55
View File
@@ -0,0 +1,55 @@
<?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['cannotcreatedboninstall'] = '<p>ناتوانرێت داتابەیس دروست بکرێت.</p>
<p>داتابەیستی دیاری کراو بوونی نییەو بەکارهێنەری دراو مۆڵەتی دروست کردنی داتابەیسی نییە.</p>
<p>پێویستە سەرپەرشتیاری ماڵپەڕ سازاندنی داتابەیس پەسەند بکات.</p>';
$string['cannotcreatelangdir'] = 'ناتوانریت ڕابەرنامەی زمان دروست بکرێت';
$string['cannotcreatetempdir'] = 'ناتوانرێت ڕابەرنامەی کاتیی دروست بکرێت';
$string['cannotdownloadcomponents'] = 'ناتوانرێت پێکهێنەرەکان داببەزێنرێن';
$string['cannotdownloadzipfile'] = 'ناتوانریت فایلی زیپ داببەزێنرێت';
$string['cannotfindcomponent'] = 'تانتوانرێت پێکهێنەر بدۆزرێتەوە';
$string['cannotsavemd5file'] = 'ناتوانرێت فایلی md5 پاشەکەوت بکرێت';
$string['cannotsavezipfile'] = 'ناتوانرێت فایلی زیپ پاشەکەوت بکرێت';
$string['cannotunzipfile'] = 'ناتوانرێت فایلەکە لە زیپ بهێنرێتە دەرەوە';
$string['componentisuptodate'] = 'سەرنجەکە تەواو نوێیە';
$string['dmlexceptiononinstall'] = '<p>هەڵە ڕویدا لە داتابەیس [{$a->errorcode}]. <br />{$a->debuginfo}</p>.
<br />{$a->debuginfo}</p>';
$string['downloadedfilecheckfailed'] = 'پشکنینی دابەزاندنی فایل سەرکەوتوو نەبوو';
$string['invalidmd5'] = 'پشکنینی گۆڕاو هەڵە بو - دووبارە بکەوە';
$string['missingrequiredfield'] = 'هەندێ بواری داواکراو دیاری نەکراون';
$string['remotedownloaderror'] = '<p>دابەزاندنی پێکهێنەری ڕاژەکارەکەت سەرکەوتو نەبوو. تکایە ڕێکخستنەکانی پڕۆکسی پشت ڕاست بکەوە: درێژبوونەوەی PHP cURL بەشێوەیەکی زۆر پێشنیاز کراوە. </p>
<p>پێویستە تۆ فایلی <a href="{$a->url}">{$a->url}</a> بەدەست دابەزێنی، کۆپی بکە بۆ "{$a->dest}" لە نێو ڕاژەکارەکەت و لەوێ لەنێو زیپ بیهێنە دەرەوە. </p>';
$string['wrongdestpath'] = 'ڕێڕەوی ئامانج هەڵەیە';
$string['wrongsourcebase'] = 'بنچینەی URLی سەرچاوە هەڵەیە';
$string['wrongzipfilename'] = 'ناوی فایلی زیپ هەڵەیە';
+1 -1
View File
@@ -41,4 +41,4 @@ $string['cliunknowoption'] = 'Nicht erkannte Optionen:
Hilfe wird über die Option --help angezeigt.';
$string['cliyesnoprompt'] = 'y (yes=ja) oder n (no=nein) eingeben';
$string['environmentrequireinstall'] = 'muss installiert und aktiviert sein';
$string['environmentrequireversion'] = 'Version {$a->needed} ist erforderlich - aktuell ist {$a->current} installiert.';
$string['environmentrequireversion'] = 'notwendig: {$a->needed} - installiert: {$a->current}';
+7 -7
View File
@@ -34,8 +34,8 @@ $string['admindirname'] = 'Admin-Verzeichnis';
$string['availablelangs'] = 'Verfügbare Sprachpakete';
$string['chooselanguagehead'] = 'Sprache wählen';
$string['chooselanguagesub'] = 'Wählen Sie eine Sprache, die Sie während der Installation verwenden wollen. Die ausgewählte Sprache wird nach der Installation als Standardsprache der Instanz benutzt, aber Sie dürfen die Sprache jederzeit ändern.';
$string['clialreadyconfigured'] = 'Die Datei config.php existiert bereits. Bitte benutzen Sie admin/cli/install_database.php, wenn sie diese Website installieren möchten.';
$string['clialreadyinstalled'] = 'Die Datei config.php existiert bereits. Bitte benutzen Sie admin/cli/upgrade.php, wenn Sie diese Website aktualisieren möchten.';
$string['clialreadyconfigured'] = 'Die Datei config.php existiert bereits. Bitte benutzen Sie admin/cli/install_database.php, wenn Sie diese Site installieren möchten.';
$string['clialreadyinstalled'] = 'Die Datei config.php existiert bereits. Bitte benutzen Sie admin/cli/install_database.php, wenn Sie diese Site aktualisieren möchten.';
$string['cliinstallheader'] = 'Installation von Moodle {$a} über die Kommandozeile';
$string['databasehost'] = 'Datenbank-Server';
$string['databasename'] = 'Datenbank-Name';
@@ -64,11 +64,11 @@ $string['pathshead'] = 'Pfade bestätigen';
$string['pathsrodataroot'] = 'Das Verzeichnis dataroot ist schreibgeschützt.';
$string['pathsroparentdataroot'] = 'Das Verzeichnis ({$a->parent}) ist schreibgeschützt. Deswegen kann das Datenverzeichnis ({$a->dataroot}) vom Installer nicht angelegt werden.';
$string['pathssubadmindir'] = 'Einige Webserver benutzen /admin als speziellen Link, um auf Einstellungsseiten oder Ähnliches zu verweisen. Unglücklicherweise kollidiert dies mit dem standardmäßigen Verzeichnis für die Moodle-Administration. Sie können dieses Problem beheben, indem Sie das Verzeichnis admin in Ihrer Moodle-Installation umbenennen und den neuen Namen hier eingeben (z.B. <em>moodleadmin</em>). Mit dieser Änderung werden alle Admin-Links korrigiert.';
$string['pathssubdataroot'] = 'Sie benötigen einen Platz, wo Moodle hochgeladene Dateien abspeichern kann. Dieses Verzeichnis muss Lese- und Schreibrechte für das Nutzerkonto besitzen, mit dem Ihr Webservers läuft (üblicherweise \'nobody\', \'apache\' oder \'www\'). Außerdem sollte das Verzeichnis nicht direkt aus dem Internet erreichbar sein. Das Intallationsskript wird versuchen, ein solches Verzeichnis zu erstellen, falls es nicht existiert.</p>';
$string['pathssubdirroot'] = 'Vollständiger Pfad der Moodle-Installation';
$string['pathssubwwwroot'] = 'Vollständige Webadresse für den Zugriff auf Moodle. Es ist nicht möglich, über unterschiedliche Adressen auf Moodle zuzugreifen. Sollte Ihre Website mehrere öffentliche Adressen verwenden, so müssen Sie eine Adresse festlegen und für die übrigen Adressen dauerhafte Weiterleitungen dorthin einrichten.
<p>Falls Ihre Website gleichzeitig im Intranet und im Internet erreichbar ist, so tragen Sie die öffentliche Adresse ein. Konfigurieren Sie den DNS so, dass Moodle auch aus dem Intranet über die öffentliche Adresse erreichbar ist.
<p>Führen Sie Ihre Moodle-Installation unbedingt mit der richtigen Adresse durch, weil es andernfalls zu Problemen kommen könnte.';
$string['pathssubdataroot'] = '<p>Sie benötigen einen Platz, wo Moodle hochgeladene Dateien abspeichern kann. </p><p>Dieses Verzeichnis muss Lese- und Schreibrechte für das Nutzerkonto besitzen, mit dem Ihr Webservers läuft (üblicherweise \'nobody\', \'apache\' oder \'www-data).</p><p> Außerdem sollte das Verzeichnis nicht direkt aus dem Internet erreichbar sein. </p><p>Das Intallationsskript wird versuchen, ein solches Verzeichnis zu erstellen, falls es nicht existiert.</p>';
$string['pathssubdirroot'] = '<p>Vollständiger Pfad der Moodle-Installation.</p>';
$string['pathssubwwwroot'] = '<p>Webadresse, die ein Nutzer im Browser eingibt, um auf Moodle zuzugreifen.</p><p> Es ist nicht möglich, über unterschiedliche Adressen auf Moodle zuzugreifen. Sollte Ihre Website mehrere öffentliche Adressen verwenden, so müssen Sie eine Adresse festlegen und für die übrigen Adressen dauerhafte Weiterleitungen dorthin einrichten.</p>
<p>Falls Ihre Website gleichzeitig im Intranet und im Internet erreichbar ist, so tragen Sie die öffentliche Adresse ein. Konfigurieren Sie den DNS so, dass Moodle auch aus dem Intranet über die öffentliche Adresse erreichbar ist.</p>
<p>Führen Sie Ihre Moodle-Installation unbedingt mit der richtigen Adresse durch, weil es andernfalls zu Problemen kommen könnte.</p>';
$string['pathsunsecuredataroot'] = 'Der Speicherort des Verzeichnisses \'dataroot\' ist unsicher';
$string['pathswrongadmindir'] = 'Das Admin-Verzeichnis existiert nicht';
$string['phpextension'] = 'PHP-Extension {$a}';

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