Compare commits

..

706 Commits

Author SHA1 Message Date
Eloy Lafuente (stronk7) ddadff9655 Moodle release 2.6.5 2014-09-06 13:01:43 +02:00
Eloy Lafuente (stronk7) 1e13288d77 weekly release 2.6.4+ 2014-09-04 19:55:01 +02:00
Eloy Lafuente (stronk7) 60ae7e9e3e Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-09-04 19:54:56 +02:00
Damyon Wiese 1541440ddc Merge branch 'wip-MDL-46464-MOODLE_26_STABLE' of https://github.com/kwiliarty/moodle into MOODLE_26_STABLE 2014-09-04 13:32:11 +08:00
Kevin Wiliarty 552f77e155 MDL-46464 supplies missing method (and PHPUnit test) for grading workflow 2014-09-04 00:22:51 -04:00
Eloy Lafuente (stronk7) 34bf5fa890 Merge branch 'MDL-47031-26-enfix' of git://github.com/mudrd8mz/moodle into MOODLE_26_STABLE 2014-09-03 19:26:04 +02:00
Helen Foster f3bdb845c4 MDL-47031 Merge English strings from the en_fix language pack 2014-09-03 13:00:25 +02:00
Marina Glancy 6e4c10f987 Merge branch 'm26_MDL-46639' of git://github.com/danmarsden/moodle into MOODLE_26_STABLE 2014-09-03 16:59:38 +08:00
Dan Marsden df5fd3cd97 MDL-46639 SCORM: incorrect setting of launch param, it is done in scorm_parse_aicc 2014-09-03 20:22:19 +12:00
Charles Fulton 0cc57751e4 MDL-30414 block_private_files: convert button to inline link 2014-09-03 01:09:56 +02:00
Michael de Raadt ebbff90562 MDL-46619 Forum: link to the discussion only if users cannot see posts. 2014-09-02 10:11:16 +08:00
Michael de Raadt 982c8524dd MDL-46619 Forum: only output last poster's name if user can view it. 2014-09-02 10:11:13 +08:00
Marina Glancy 390645bd44 Merge branch 'MDL-45952_26' of git://github.com/Syxton/moodle into MOODLE_26_STABLE 2014-09-02 09:59:20 +08:00
Eloy Lafuente (stronk7) 59be24cc60 Merge branch 'MDL-46633_m26' of https://github.com/shashirepo/moodle into MOODLE_26_STABLE 2014-09-02 02:12:30 +02:00
Eloy Lafuente (stronk7) 64e07a390e Merge branch 'wip_MDL-46679_m26_addonenv' of https://github.com/skodak/moodle into MOODLE_26_STABLE 2014-09-02 02:08:54 +02:00
Eloy Lafuente (stronk7) 19cd96e561 Merge branch 'MDL-46979_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-09-02 01:49:05 +02:00
Eloy Lafuente (stronk7) 0bd6dee49f Merge branch 'MDL-43639_updatePassEveryLogin_26' of https://github.com/moodlerooms/moodle into MOODLE_26_STABLE 2014-09-02 01:07:55 +02:00
Damyon Wiese d5cfda4734 Merge branch 'MDL-46852-26' of git://github.com/FMCorz/moodle into MOODLE_26_STABLE 2014-09-01 16:16:55 +08:00
Damyon Wiese b7c42f0d7e Merge branch 'MDL-46902_m26' of git://github.com/markn86/moodle into MOODLE_26_STABLE 2014-09-01 15:54:40 +08:00
Henning Bostelmann 333db4598d MDL-46911 Database activity: jump to correct place in list after (un)approve 2014-09-01 15:46:19 +08:00
Damyon Wiese a5580bc618 Merge branch 'm26_MDL-46985_7ZIP_RAR_MIME_types_missing' of https://github.com/scara/moodle into MOODLE_26_STABLE 2014-09-01 15:35:52 +08:00
Damyon Wiese dea12fe893 Merge branch 'm26_MDL-46961' of https://github.com/danmarsden/moodle into MOODLE_26_STABLE 2014-09-01 15:30:01 +08:00
Marina Glancy bb5b3ee263 Merge branch 'm26_MDL-46639' of git://github.com/danmarsden/moodle into MOODLE_26_STABLE 2014-09-01 14:35:39 +08:00
Marina Glancy 6e1fdb0951 Merge branch 'MDL-46539-fix-26' of https://github.com/jmarthaler/moodle into MOODLE_26_STABLE 2014-09-01 14:35:33 +08:00
Frederic Massart 69866e0377 MDL-46852 mod_lesson: More accurate comparison of shortanswer answers 2014-09-01 14:24:58 +08:00
Damyon Wiese 2b51c3212a Merge branch 'wip-MDL-39233-m26' of git://github.com/marinaglancy/moodle into MOODLE_26_STABLE 2014-09-01 13:42:06 +08:00
Damyon Wiese 99772c2ba1 MDL-46619 Forum: whitespace fixes 2014-09-01 11:35:31 +08:00
Damyon Wiese 861822dc1b Merge branch 'MDL-46619-2.6-visisble-authors-qanda' of https://github.com/amandadoughty/moodle into MOODLE_26_STABLE 2014-09-01 11:29:49 +08:00
Damyon Wiese e5d4b3d409 Merge branch 'm26_MDL-46737' of https://github.com/danmarsden/moodle into MOODLE_26_STABLE 2014-09-01 10:56:15 +08:00
Matteo Scaramuccia 34b17698c4 MDL-46985 Added 7-Zip and RAR MIME types. 2014-08-31 22:58:15 +02:00
Petr Skoda c8ec7b8a53 MDL-39840 environment: add support for environment.xml in plugins
New features:

* environment.xml files in all types of plugins
* support for plugin strings via new optional plugin attribute in FEEDBACK
* support for class_name::method_name custom callbacks and classloader
2014-09-01 08:39:53 +12:00
AMOS bot d63f2a10bc Automatically generated installer lang files 2014-09-01 00:05:45 +08:00
Mark Nelson 4e29893160 MDL-46902 core_course: display meaningful message when no courses found 2014-08-29 14:33:06 -07:00
AMOS bot a1cd496b31 Automatically generated installer lang files 2014-08-30 00:05:38 +08:00
zbdd a6d8e2b35e MDL-37312 backup: Keep course idnumber on same site course restore
When the course idnumber is set during a same site course restore,
retain the course idnumber if there are no duplicates.
2014-08-29 07:21:36 +00:00
Tim Hunt df27344e9a MDL-46979 backup: remove duplicate string.
Thanks to Matt Sammarco for spotting this.
2014-08-28 20:44:31 +01:00
Eloy Lafuente (stronk7) 0628d17bfa weekly release 2.6.4+ 2014-08-28 19:12:10 +02:00
Eloy Lafuente (stronk7) 44e3a9bdc6 Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-08-28 19:12:05 +02:00
shashirepo c34a0a0acb MDL-46633 chat: Chat send button gets stuck
Conflicts:
	mod/chat/gui_ajax/module.js
2014-08-28 14:54:37 +05:30
Syxton 4c9103a485 MDL-45952 feedback: non-respondents in groupings
Fixes feedback non-respondents list to show only members in groups in
the selected grouping if "Available for group members only" is selected.
2014-08-27 15:17:02 -04:00
Mark Nielsen ae376d3b2f MDL-43639: Prevent user updated event on every login
If auth plugin prevents local passwords, then user
is updated and event is triggered on every login.
2014-08-27 11:30:04 -07:00
Jon Marthaler 14a2ef282b MDL-46539 assign calendar: Fix lastcron value for assign cron 2014-08-27 11:11:11 -05:00
AMOS bot ab39338705 Automatically generated installer lang files 2014-08-28 00:05:36 +08:00
Damyon Wiese 6c4e723d6b Merge branch 'wip-MDL-39888-26' of git://github.com/abgreeve/moodle into MOODLE_26_STABLE 2014-08-27 09:56:17 +08:00
Faisal Kaleem 892eb5d190 MDL-46961 SCORM: JavaScript Hoisting issue. 2014-08-27 13:09:31 +12:00
Eloy Lafuente (stronk7) f0640eb7d2 MDL-46875 tinymce: keep stable version YYYMMDD constant
Note this has been integrated together with previous commit
so nobody should get a "downgrade" ever (but Brian, I'm sorry :-)
2014-08-27 02:10:14 +02:00
Eloy Lafuente (stronk7) 60f1480cdc Merge branch 'm26_MDL-46875' of https://github.com/totara/moodle into MOODLE_26_STABLE 2014-08-27 02:08:26 +02:00
Adrian Greeve 53ed4016e6 MDL-39888 mnet: Added a warning message that no logging may be reveived from other clients.
Moodle client machines that are running 2.6 or above that are not using the legacy log store
will not generate any logs to be transfered to the parent site.
2014-08-26 15:02:56 +08:00
Marina Glancy 76d6b7a9b4 MDL-39233 mod_url: added unittest for get_course_content 2014-08-26 13:56:14 +08:00
Jason 97c36ae969 MDL-39233 mod_url: fix php notice 2014-08-26 13:56:14 +08:00
Damyon Wiese 8e2d62e5e2 MDL-46842 assign: Fix for unit tests - previous patch was completely ignoring manually reopening attempts. 2014-08-26 10:36:27 +08:00
Brian Barnes 8d42b3ceb5 MDL-46875 tinymce: Fixed issue with full screen and spelling 2014-08-26 13:26:49 +12:00
Eloy Lafuente (stronk7) b5570e07ca Merge branch 'MDL-46477_m26' of https://github.com/shashirepo/moodle into MOODLE_26_STABLE 2014-08-26 02:24:50 +02:00
Eloy Lafuente (stronk7) d5ee2634bd Merge branch 'MDL-46753-26' of git://github.com/lameze/moodle into MOODLE_26_STABLE 2014-08-26 02:08:35 +02:00
Eloy Lafuente (stronk7) cc2ef7a505 Merge branch 'm26_MDL-46842' of https://github.com/greg-or/moodle-mod_assign into MOODLE_26_STABLE 2014-08-26 01:59:40 +02:00
Eloy Lafuente (stronk7) 49f1a64cb0 Merge branch 'm26_MDL-46816' of https://github.com/danmarsden/moodle into MOODLE_26_STABLE 2014-08-26 00:11:04 +02:00
Eloy Lafuente (stronk7) bf7c584ffe Merge branch 'wip-MDL-46874-m26' of git://github.com/marinaglancy/moodle into MOODLE_26_STABLE 2014-08-25 22:11:43 +02:00
Eloy Lafuente (stronk7) fa74d00ca6 Merge branch 'm26_MDL-46900' of https://github.com/totara/moodle into MOODLE_26_STABLE 2014-08-25 20:55:44 +02:00
Marina Glancy 124aa2558a Merge branch 'MDL-46894_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-08-25 16:54:08 +08:00
Tim Hunt 8e321075bd MDL-46916 behat: improve question state test. 2014-08-25 16:50:30 +08:00
Damyon Wiese 9a72e79050 Merge branch 'MDL-46923_m26' of git://github.com/markn86/moodle into MOODLE_26_STABLE 2014-08-25 16:47:55 +08:00
Damyon Wiese ea254fc7dd Merge branch 'wip_MDL-43918_m26_cm' of https://github.com/skodak/moodle into MOODLE_26_STABLE 2014-08-25 16:46:29 +08:00
Marina Glancy 514a13e431 Merge branch 'M26_MDL46887_assignment_file_max_size' of git://github.com/Dave-B/moodle into MOODLE_26_STABLE 2014-08-25 16:30:01 +08:00
Colin Chambers a9568d3d7f MDL-46895 qtype_calculated_find_formula_errors not defined causes Calculated question type test to fail 2014-08-25 16:28:25 +08:00
Rex Lorenzo 269695f48b MDL-46776 gradereport_grader: Improve Grader report user interface
* Adding assignments to test course generator to more easily test the grader report with large number of students and graded activities.
2014-08-25 16:20:56 +08:00
Dan Marsden 9dc8c0f8b1 MDL-46639 mod_scorm: Fix load of simple AICC content
Thanks to Ian Wild for the report and suggested patch.
2014-08-25 20:03:01 +12:00
Damyon Wiese 4b4fb1ce8b Merge branch 'wip-MDL-46812_M26' of git://github.com/lazydaisy/moodle into MOODLE_26_STABLE 2014-08-25 14:03:36 +08:00
Damyon Wiese 4157b01343 Merge branch 'wip-MDL-46703-m26' of git://github.com/marinaglancy/moodle into MOODLE_26_STABLE 2014-08-25 13:54:12 +08:00
Petr Skoda 98af233a16 MDL-43918 add more validation to $modulename parameter when fetching cms 2014-08-25 12:19:43 +12:00
Eloy Lafuente (stronk7) 3312fc1ed5 MDL-46918 ddl: cover behavior with unit test 2014-08-21 18:33:55 +01:00
Tim Hunt f45e49f01b MDL-46918 ddl: fix error when renaming table already exists 2014-08-21 18:33:55 +01:00
AMOS bot b463508597 Automatically generated installer lang files 2014-08-22 00:05:35 +08:00
Tim Hunt 7464e1b39d MDL-46894 make Behat backup steps more robust. 2014-08-21 14:15:20 +01:00
Amanda Doughty 1c5d2aefd1 MDL-46619 Forum: author showing in Q and A forum 2014-08-21 13:10:55 +01:00
shashirepo 910043d965 MDL-46477 chat:hard coded string in mod/chat 2014-08-21 17:34:30 +05:30
Mary Evans f29d5f891a MDL-46812 grade/report/grader: Need to tie up loose ends in Gradebook after MDL-43824
commit 47f382e509ec41bed7b0e7c12e7d798d2b5ba2f7
Author: Mary Evans <lazydaisy@visible-expression.co.uk>
Date:   Fri Aug 15 01:47:49 2014 +0100

    MDL-46812 grade/report/grader: Fixes gradebook in 2.6.

    also removed two redundent CSS rules in base/style/grade.css.
2014-08-21 11:27:33 +01:00
Mark Nelson 1d9c8d95f2 MDL-46923 core_behat: fixed typos in function names 2014-08-20 22:11:39 -07:00
Brian Barnes d489ecd1eb MDL-46900 theme: allowed more than 1 nav collapse element 2014-08-21 15:05:37 +12:00
Marina Glancy fd72531964 weekly release 2.6.4+ 2014-08-21 10:18:47 +08:00
Marina Glancy ebb8098668 Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-08-21 10:18:46 +08:00
AMOS bot 911ab1a334 Automatically generated installer lang files 2014-08-21 00:05:34 +08:00
Gregory Faller fc86ba1b68 MDL-46842: Reopen assignment submissions when using offline grading worksheet 2014-08-20 19:12:15 +09:30
Damyon Wiese 24d7efcec3 Merge branch 'MDL-45029-26' of git://github.com/lameze/moodle into MOODLE_26_STABLE
Conflicts:
	course/modlib.php
2014-08-20 13:59:45 +08:00
Simey Lameze 66dbc14778 MDL-45029 core_course: set aggregationcoef while creating a new course module 2014-08-20 12:07:40 +08:00
Mark Nelson ec5fda6d6f MDL-46188 core_course: use correct hide/show icon 2014-08-20 12:05:25 +08:00
Damyon Wiese cb86d02348 Merge branch 'MDL-45029-26' of git://github.com/lameze/moodle into MOODLE_26_STABLE 2014-08-20 10:22:08 +08:00
Mark Nielsen 8faaca0ea2 MDL-46536: OAuth signature fails with inconsistent new lines
When the LTI intro contains a single \n or
\r newline character then the OAuth signature
fails.  All newlines should be \r\n

Conflicts:
	mod/lti/tests/locallib_test.php
2014-08-19 22:17:04 +02:00
AMOS bot b16e3e2217 Automatically generated installer lang files 2014-08-20 00:05:33 +08:00
Eloy Lafuente (stronk7) 881af32789 Merge branch 'MDL-46051_LTI_event26' of https://github.com/moodlerooms/moodle into MOODLE_26_STABLE 2014-08-19 17:24:37 +02:00
Michael Wheeler 2cb77a22ff Normalize request header names. 2014-08-19 15:39:27 +02:00
David Balch 68305e513b MDL-46887 mod_assign: Enforce module's maxbytes setting at submission. 2014-08-19 14:03:13 +01:00
Simey Lameze fe845dd3c2 MDL-45029 core_course: set aggregationcoef while creating a new course module 2014-08-19 17:08:18 +08:00
Marina Glancy 135efed7f1 MDL-46538 theme_base: recompiled moodle.css 2014-08-19 16:53:30 +08:00
Marina Glancy 2a8877376a Merge branch 'MDL-46538_M26' of git://github.com/lazydaisy/moodle into MOODLE_26_STABLE 2014-08-19 16:53:09 +08:00
Marina Glancy 26929ce1a7 Merge branch 'MDL-46281-MOODLE_26_STABLE' of git://github.com/lucisgit/moodle into MOODLE_26_STABLE 2014-08-19 16:23:00 +08:00
Marina Glancy 3e15af69de Merge branch 'MDL-46833-MOODLE_26_STABLE' of git://github.com/lucisgit/moodle into MOODLE_26_STABLE 2014-08-19 14:22:01 +08:00
Damyon Wiese a69107e549 Merge branch 'MDL-41513-Scrollbar_not_working-26' of https://github.com/MorrisR2/moodle into MOODLE_26_STABLE 2014-08-19 14:07:39 +08:00
Marina Glancy 0f9d61091b Merge branch 'wip-mdl-46817-m26' of git://github.com/rajeshtaneja/moodle into MOODLE_26_STABLE 2014-08-19 14:04:21 +08:00
Marina Glancy f09f95fefa Merge branch 'MDL-43197-26-2nd' of git://github.com/FMCorz/moodle into MOODLE_26_STABLE 2014-08-19 13:26:19 +08:00
Damyon Wiese 4e6eb5b8be Merge branch 'MDL-46188_m26' of https://github.com/shashirepo/moodle into MOODLE_26_STABLE 2014-08-19 13:15:13 +08:00
Marina Glancy 8b50f60a64 MDL-46874 gradereport: replace usage of class hidden with dimmed_text 2014-08-19 12:56:43 +08:00
Michael Wheeler 25da4fa204 MDL-46794 install: Fixed typo in config-dist.php 2014-08-19 11:27:46 +08:00
Marina Glancy c8c0aa21e4 Merge branch 'm26_MDL-46775' of git://github.com/totara/moodle into MOODLE_26_STABLE 2014-08-19 11:22:09 +08:00
Frederic Massart 0eef41f639 MDL-43197 gradereport_user: Parents/mentors can see all the relevant grades 2014-08-19 10:49:09 +08:00
Marina Glancy 0a88b33a6a MDL-46691 mod_choice: apply filters to user input 2014-08-19 03:05:55 +02:00
James Henestofel d79710afde MDL-42231 auth: custom profile fields to support numbers at the end.
For data mapping LDAP or CAS.  Change order of fieldname display checks to verify
custom profile fields first to allow custom field shortname to contain number at the end.
2014-08-19 02:44:14 +02:00
Eloy Lafuente (stronk7) 829eb491e0 Merge branch 'MDL-44894_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-08-19 02:35:04 +02:00
Petr Skoda f460295a58 MDL-46552 session: add support for multiple servers in memcached session driver 2014-08-19 02:30:30 +02:00
Eloy Lafuente (stronk7) de25146b0a Merge branch 'MDL-45874-26' of https://github.com/danielneis/moodle into MOODLE_26_STABLE 2014-08-19 02:12:32 +02:00
Eloy Lafuente (stronk7) 432785d430 Merge branch 'wip-MDL-46826-m26' of git://github.com/marinaglancy/moodle into MOODLE_26_STABLE 2014-08-18 20:08:52 +02:00
Eric Merrill ad94c5efb4 MDL-46766 auth_cas: Upgrading to phpCAS 1.3.3 2014-08-18 16:40:42 +08:00
Simey Lameze e3a51bcd28 MDL-46753 auth_cas: Replace hardcoded logout_return_url to user defined URL.
Credit goes to Mitsuru Udagawa, thanks!
2014-08-18 15:01:20 +08:00
Damyon Wiese e2aa68b154 Merge branch 'm26_MDL-46760' of https://github.com/danmarsden/moodle into MOODLE_26_STABLE 2014-08-18 12:41:29 +08:00
Rajesh Taneja 618704b6a5 MDL-46817 behat: Step to check if value exist/not in table column 2014-08-18 10:02:13 +08:00
AMOS bot f55eb23bde Automatically generated installer lang files 2014-08-18 00:07:54 +08:00
Marina Glancy 59829c0511 MDL-46703 mod_data: limit the width of select element when editing templates
Thanks to Hittesh for the provided solution
2014-08-16 13:26:34 +08:00
Mary Evans dcc5d2df3d MDL-46538 theme_base/theme_bootstrapbase: Removed incorrect RTL CSS. 2014-08-16 01:19:02 +01:00
Daniel Neis 3395def1fa MDL-45874 Fix access to users reports in navigation when using separate groups 2014-08-15 17:04:36 -03:00
Rajesh Taneja 60177550ee MDL-46817 behat: Table selector support css
Previously table selector supported id and caption only.
But in few cases we don't have proper id, so added support
for css
2014-08-15 13:20:47 +08:00
Marina Glancy 756d8f1171 MDL-46826 forum: make sql query indexed, regression from MDL-31089 2014-08-15 11:47:03 +08:00
Ray Morris edafa7ce90 MDL-41513 mod_quiz: Scrollbar not working in JS Security Popup 2014-08-14 15:46:37 -05:00
Ruslan Kabalin 61560c2b72 MDL-46833 mod_assign: Fix assignment view when available for group members only.
When assignment is "Available for group members only" and no users with
mod/assign:submit role permision is enrolled (students),
groups_filter_users_by_course_module_visible is causing error (as $users
array is empty). The patch resolves the issue.
2014-08-14 17:11:25 +01:00
shashirepo b8d5bd3da0 MDL-46188 course:show/hide button disappears after action 2014-08-14 20:36:03 +05:30
Tony Butler 3b7336fff2 MDL-46281 core_backup: Add class_exists check for backup_<mod>_activity_task
Signed-off-by: Tony Butler <tonyjbutler@gmail.com>
2014-08-14 12:57:56 +01:00
Tim Hunt 82e46ef9ea MDL-44894 question editing: fix validation with odd permissions
For users with edit permissions, but not add permissions, it was
impossible to save the editing form. The validation assuemd this value
was present, but it was not. Other code checks this field too, so I
added it rather than changing the validation and all the other uses.
2014-08-14 11:26:50 +01:00
Marina Glancy e95c5eed2c weekly release 2.6.4+ 2014-08-14 14:52:19 +08:00
Marina Glancy aec0fcdb6e Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-08-14 14:52:15 +08:00
Dan Marsden 4b3814f85e MDL-46816 mod_asssign plagiarism: Remove unnecessary code. 2014-08-14 13:10:59 +12:00
Dan Marsden 151b3a299b MDL-46760 mod_scorm: Fix js error when preview mode disabled 2014-08-14 10:11:28 +12:00
Mark Nielsen 9408170cb3 MDL-46051 mod_lti: Fixing errors in unknown_service_api_called class
Also adding unit tests.
2014-08-13 09:06:25 -07:00
AMOS bot e11cf87496 Automatically generated installer lang files 2014-08-14 00:05:49 +08:00
Marina Glancy 81c65c089a Revert "Merge branch 'm26_MDL-46643' of git://github.com/totara/moodle into MOODLE_26_STABLE"
This reverts commit c750f3de63, reversing
changes made to af8ef3b1da.
2014-08-13 16:32:47 +08:00
Eloy Lafuente (stronk7) 934a342fef Merge branch 'wip-MDL-46470-m26' of git://github.com/marinaglancy/moodle into MOODLE_26_STABLE 2014-08-13 00:26:27 +02:00
Tim Hunt b483b31dab MDL-45642 questions: add required index to question_attempts.
It is important to be able to tell which behaviours are in use, and
without this index, it requires a complete scan of this table, which can
be very big, to verify that a behaviour is unused.
2014-08-12 11:37:50 +01:00
Dan Poltawski 82b7d129d7 Merge branch 'MDL-43824-M26' of git://github.com/lazydaisy/moodle into MOODLE_26_STABLE
Conflicts:
	theme/bootstrapbase/style/moodle.css
2014-08-12 11:08:13 +01:00
Dan Poltawski a672c8337f Merge branch 'm26_MDL-46718' of https://github.com/greg-or/moodle-mod_assign into MOODLE_26_STABLE 2014-08-12 11:02:20 +01:00
Marina Glancy 63edba375c Merge branch 'MDL-46308_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-08-12 16:03:07 +08:00
Marina Glancy 530da41f30 Merge branch 'MDL-21042_m26' of git://github.com/markn86/moodle into MOODLE_26_STABLE 2014-08-12 16:02:29 +08:00
Marina Glancy 0a94ca9765 Merge branch 'm26_MDL-46315' of git://github.com/totara/moodle into MOODLE_26_STABLE 2014-08-12 15:03:00 +08:00
Marina Glancy a17f12e801 Merge branch 'MDL-46600_import_failed_26' of git://github.com/andyjdavis/moodle into MOODLE_26_STABLE 2014-08-12 15:02:51 +08:00
Marina Glancy 0faeeeea27 Merge branch 'wip_MDL-46480_m26_footernan' of git://github.com/skodak/moodle into MOODLE_26_STABLE 2014-08-12 15:02:36 +08:00
Marina Glancy c750f3de63 Merge branch 'm26_MDL-46643' of git://github.com/totara/moodle into MOODLE_26_STABLE 2014-08-12 13:32:03 +08:00
Marina Glancy af8ef3b1da Merge branch 'MDL-43740_manual_none_26' of git://github.com/andyjdavis/moodle into MOODLE_26_STABLE 2014-08-12 13:29:43 +08:00
Simon Coggins 1a68d6e7e1 MDL-46775: Fix call to unavailable function when loading an invalid JS file 2014-08-12 14:34:17 +12:00
Eloy Lafuente (stronk7) cb51189dce Merge branch 'MDL-46676_2.6' of https://github.com/ikawhero/moodle into MOODLE_26_STABLE 2014-08-12 01:48:26 +02:00
Eloy Lafuente (stronk7) f9a93a6aab Merge branch 'MDL-46681_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-08-12 01:44:29 +02:00
Mary Evans 2b6526e717 MDL-43824 core/grade/report/grader: Fix for misalignment of static rows with scale grades. 2014-08-12 00:06:08 +01:00
Dan Poltawski 86a42029e3 Merge branch 'MDL-46496-26' of git://github.com/andrewnicols/moodle into MOODLE_26_STABLE 2014-08-11 14:38:47 +01:00
Dan Poltawski 278c04a414 Merge branch 'm26_MDL-44015' of https://github.com/greg-or/moodle-mod_assign into MOODLE_26_STABLE 2014-08-11 14:31:06 +01:00
Dan Poltawski db6c4fc975 Merge branch 'MDL-46688_26' of git://github.com/timhunt/moodle into MOODLE_26_STABLE 2014-08-11 14:13:17 +01:00
Andrew Davis 23f1bddc01 MDL-43740 core_grade: Thanks to Robert Russo for the patch. Removed the ability to set manual grade items to grade type "None" 2014-08-11 20:20:36 +08:00
Dan Poltawski 7051114f00 Merge branch 'wip-MDL-30668-m26' of git://github.com/marinaglancy/moodle into MOODLE_26_STABLE 2014-08-11 10:41:44 +01:00
Damyon Wiese ceea52abf6 MDL-35984 Grades: Fix deprecation of grade_category::aggregate_values 2014-08-11 14:24:37 +08:00
Damyon Wiese 1285dadea3 MDL-35984 grade: Recalculate min/max for sum of grades when hidden grades are involved. 2014-08-11 14:24:22 +08:00
Damyon Wiese e26695f647 MDL-35984 grade: Add behat tests for grade aggregations 2014-08-11 14:23:59 +08:00
Tim Hunt 25c302c393 MDL-46308 qformat_xml: fix import of broken calculated questions.
Questions like this should not exist, of course. But they do, so we
should avoid generating errors in this case.
2014-08-08 17:59:21 +01:00
Tim Hunt b7dda99c5e MDL-46688 weblib: improve the highlight function.
Thanks to Joseph Baxter for suggesting some of the test cases.
2014-08-08 17:53:08 +01:00
Marina Glancy 8238f53d71 MDL-30668 gradereport_grader: split user preferences into individual courses
This solves the DB exception when users were trying to insert very large string in DB
2014-08-08 15:17:50 +08:00
Andrew Nicols b6c2f9333c MDL-46496 JS: Replace jQuery UI 1.10.3 minified CSS
The original version contained some invalid paths for images. I'm unsure
where these came from as the version from the offical jQuery UI does not
contain these, and these were the only differences in the files.
2014-08-08 14:05:03 +08:00
Gregory Faller f707b67259 MDL-46718: Return user to last accessed page when quick grading 2014-08-08 14:48:13 +09:30
Dan Marsden c15f312ff0 MDL-46737 SCORM: correct dml syntax. 2014-08-08 15:10:58 +12:00
Petr Skoda 8f73f2a160 MDL-46480 fix get_htmlelement_size() to deal with hidden or non-block elements 2014-08-08 10:29:17 +12:00
Tim Hunt 822ba7d3d8 MDL-46681 qtype_multichoice: disabled unused options
For questions set to 'One answer only', the 'Clear incorrect responses'
and 'Show the number of correct responses' hint options make not sense,
and are not used. Hence we disableIf them.
2014-08-07 14:23:13 +01:00
Marina Glancy c1b4e91098 weekly release 2.6.4+ 2014-08-07 13:15:01 +08:00
Marina Glancy 8e349b6d67 Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-08-07 13:15:00 +08:00
Paul Holden 9d4a316732 MDL-21042 report_security: don't display warning for riskbackup unnecessarily 2014-08-06 19:54:28 -07:00
Andrew Davis b6e158c52f MDL-46600 core_grades: made it explicit in the error message that a failed grade import means nothing was imported. 2014-08-07 09:16:58 +08:00
Shane Elliott 8dd43942d3 MDL-46676 profilefield_datetime: Use moodle time API 2014-08-06 16:36:43 +08:00
Gregory Faller 0eddbe018e MDL-44015: EditPDF scrolls instead of drawing on iOS 2014-08-06 15:28:41 +09:30
Brian Barnes bdfa413c98 MDL-46643 calendar: improved tab order of calendar detail pages 2014-08-06 15:56:07 +12:00
Marina Glancy faf858b6d4 MDL-46470 bootstrapbase: support linkedwhenselected attribute for tabs 2014-08-06 11:48:12 +08:00
Brian Barnes ee483e0520 MDL-46625 theme: Added a way to target the current page 2014-08-05 13:05:29 +02:00
Brian Barnes 73ae7da37b MDL-46315 themes: Fixed display inconsistancy with help modals 2014-08-05 13:04:09 +12:00
Eloy Lafuente (stronk7) 4bdc10db61 Merge branch 'MDL-44149-26' of git://github.com/damyon/moodle into MOODLE_26_STABLE 2014-08-04 17:11:55 +02:00
Damyon Wiese 5d839b02c2 MDL-44149 Assign: Reopen attempts from quick grading (reopenuntilpass)
Conflicts:
	mod/assign/locallib.php
2014-08-04 15:56:18 +08:00
Marina Glancy 3000cb1ee2 Merge branch 'MDL-44794-26' of git://github.com/lameze/moodle into MOODLE_26_STABLE 2014-08-04 14:25:16 +08:00
Simey Lameze 8be9386bdc MDL-44794 group: unit test for get_groups method. 2014-08-04 12:07:24 +08:00
Simey Lameze 4325b460cc MDL-44794 group: unit test for groups_get_user_groups method. 2014-08-04 12:07:01 +08:00
Marina Glancy 216da8ebb0 Merge branch 'MDL-46457_26' of git://github.com/aolley/moodle into MOODLE_26_STABLE 2014-08-04 11:25:10 +08:00
Eloy Lafuente (stronk7) 71591d7822 Merge branch 'MDL-46620-26' of https://github.com/merrill-oakland/moodle into MOODLE_26_STABLE 2014-08-03 20:01:51 +02:00
AMOS bot a7f445318d Automatically generated installer lang files 2014-08-01 00:05:41 +08:00
Dan Poltawski 753493ae11 weekly release 2.6.4+ 2014-07-31 09:37:18 +01:00
Dan Poltawski f73bb3a21a Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-07-31 09:37:14 +01:00
Eric Merrill e89b812518 MDL-46620 messages Make sure full message is used for read marking
message_mark_message_read needs to have the full message object,
otherwise data will be lost.
2014-07-30 15:58:08 -04:00
Dan Poltawski 4fe1c7647c Merge branch 'MDL-46236_26' of git://github.com/nobelium/moodle into MOODLE_26_STABLE 2014-07-29 12:04:34 +01:00
AMOS bot 3c1814cac7 Automatically generated installer lang files 2014-07-29 16:02:25 +08:00
Dan Poltawski 765ba4ce1e Merge branch 'wip-MDL-46338-m26' of git://github.com/marinaglancy/moodle into MOODLE_26_STABLE 2014-07-29 08:50:40 +01:00
Marina Glancy 2d1ac616e8 Merge branch 'm26_MDL-46325' of git://github.com/totara/moodle into MOODLE_26_STABLE 2014-07-29 11:59:29 +08:00
Sam Hemelryk 23bf420120 Merge branch 'MDL-43908-MOODLE_26_STABLE' of https://github.com/lucisgit/moodle into MOODLE_26_STABLE 2014-07-29 15:51:03 +12:00
Sam Hemelryk 5175bb487e Merge branch 'MDL-45041_26_STABLE' of git://github.com/jleyva/moodle into MOODLE_26_STABLE 2014-07-29 15:47:18 +12:00
Marina Glancy 198c28cda2 MDL-46338 enrol_self: Icon should indicate enrolment availability 2014-07-29 09:52:34 +08:00
Adam Olley 2b413491e3 MDL-46457 mod_lti: Render lti description through standard format_module_intro 2014-07-29 10:40:52 +09:30
Sam Hemelryk 98311522ed Merge branch 'MDL-45044-m26-master' of https://github.com/dthies/moodle into MOODLE_26_STABLE 2014-07-29 08:46:55 +12:00
Dan Poltawski 0a346972f3 Merge branch 'MDL-45594_m26' of git://github.com/markn86/moodle into MOODLE_26_STABLE 2014-07-28 12:54:19 +01:00
Dan Poltawski 54021dcedb Merge branch 'wip-MDL-46503-m26' of git://github.com/marinaglancy/moodle into MOODLE_26_STABLE 2014-07-28 12:49:17 +01:00
Dan Poltawski abeb9d6544 Merge branch 'm26_MDL-45715' of https://github.com/danmarsden/moodle into MOODLE_26_STABLE 2014-07-28 12:47:35 +01:00
Dan Poltawski 2c28f42bae Merge branch 'MDL-46433-26' of git://github.com/lameze/moodle into MOODLE_26_STABLE 2014-07-28 11:49:40 +01:00
Dan Poltawski f5b49d8004 Merge branch 'MDL-46504_26' of git://github.com/dmonllao/moodle into MOODLE_26_STABLE 2014-07-28 10:56:50 +01:00
Nobelium c02b2fc931 MDL-46236 mod_scorm : Setting lauch options for scorm in popup 2014-07-28 06:35:33 +00:00
Sam Hemelryk 3390644156 Merge branch 'MDL-43390_26' of git://github.com/dmonllao/moodle into MOODLE_26_STABLE 2014-07-28 12:22:45 +12:00
Sam Hemelryk fcb1e8a9c2 Merge branch 'wip-MDL-46525-m26' of git://github.com/marinaglancy/moodle into MOODLE_26_STABLE 2014-07-28 12:13:48 +12:00
Sam Hemelryk cedd791b19 Merge branch 'MDL-46506-26' of git://github.com/damyon/moodle into MOODLE_26_STABLE 2014-07-28 08:46:07 +12:00
Tony Butler 072e93e26e MDL-43908 mod_assign: Order submissions by course id then cm id
Signed-off-by: Tony Butler <tonyjbutler@gmail.com>
2014-07-25 10:28:47 +01:00
Tony Butler f249f9f41a MDL-43908 mod_assign: Remove redundant code and improve SQL query
Signed-off-by: Tony Butler <tonyjbutler@gmail.com>
2014-07-25 10:28:47 +01:00
Tony Butler d53cc3da71 MDL-43908 mod_assign: Prevent notifications for unavailable assignments
Signed-off-by: Tony Butler <tonyjbutler@gmail.com>

Conflicts:
	mod/assign/locallib.php
2014-07-25 09:54:49 +01:00
Tony Butler 1d3c72cafd MDL-43908 mod_assign: Defer notifications for unavailable assignments
Signed-off-by: Tony Butler <tonyjbutler@gmail.com>
2014-07-25 09:54:49 +01:00
Juan Leyva 4f3ed071d4 MDL-45041 Web Service: add_user_device doesn't store entries for different users using the same push key 2014-07-25 10:42:27 +02:00
Marina Glancy 9de849779c MDL-46525 enrol_cohort: fix JS error 2014-07-25 14:45:53 +08:00
Brian Barnes 67c5420a1f MDL-46325 behat: Fixed issue where 'teacher1' didn't exist 2014-07-25 14:37:27 +12:00
AMOS bot 7dfed7234c Automatically generated installer lang files 2014-07-24 22:42:05 +00:00
Daniel Thies 3b80e3f77a MDL-45044 filter_tex: properly escape excutable pathnames for Windows 2014-07-24 14:06:02 -05:00
Dan Poltawski 2d43ffd1a9 weekly release 2.6.4+ 2014-07-24 09:50:58 +01:00
Dan Poltawski 899c251521 Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-07-24 09:50:55 +01:00
Damyon Wiese 1bbe91bf16 MDL-46506 Assign: fix php warning on grant extension page
This code was missed when the extensionduedate was moved to the userflags table.
2014-07-24 11:26:28 +08:00
David Monllao 924cc85e08 MDL-46504 libraries: Fixing typo 2014-07-24 11:17:02 +08:00
Damyon Wiese 0ea2c043bc MDL-46017 Assign: Restore can't rely allocated marker fields existing in backup 2014-07-24 10:58:33 +08:00
Marina Glancy a164b026c7 MDL-46503 behat: cohort generator allows to create cohort in category 2014-07-24 10:05:06 +08:00
Mark Nelson 475cf8be48 MDL-45594 core_message: added unit tests 2014-07-23 16:40:32 -07:00
Mark Nelson aea298fc35 MDL-45594 core_message: ordered recent notifications by timecreated 2014-07-23 16:40:31 -07:00
Tim Hunt ca0074bf89 MDL-45594 simplify message_get_recent_conversations SQL
I am pretty sure that this new SQL is logically equivalent to
the original, and it passes Mark's unit tests. However, it is
hard to be 100% sure.
2014-07-23 16:40:31 -07:00
AMOS bot c4dd3d8dbf Automatically generated installer lang files 2014-07-23 22:46:24 +00:00
Simey Lameze f754b93fb0 MDL-46433 blog: fix error message when creating an external blog 2014-07-23 16:12:09 +08:00
Dan Poltawski 5414931209 Revert "Merge branch 'MDL-45594_m26' of git://github.com/markn86/moodle into MOODLE_26_STABLE"
This reverts commit 9e32e3befc, reversing
changes made to 695553b1a5.
2014-07-23 09:02:28 +01:00
Dan Marsden f320b2b391 MDL-45715 assign: disable marking allocation if markingworkflow is not set. 2014-07-23 19:22:00 +12:00
Damyon Wiese 170007b939 MDL-37509 Assign: Do not put description in calendar before it should be shown to students 2014-07-23 13:14:51 +08:00
Sam Hemelryk cd60515114 MDL-45724 cache: fixed warning structure bug 2014-07-23 15:24:16 +12:00
AMOS bot e9f88e7793 Automatically generated installer lang files 2014-07-22 22:49:19 +00:00
Dan Poltawski 5199fcd7cb Merge branch 'MDL-37509-26' of git://github.com/damyon/moodle into MOODLE_26_STABLE 2014-07-22 15:56:59 +01:00
Dan Poltawski 00d4919e69 Merge branch 'MDL-34248_m26' of https://github.com/markn86/moodle into MOODLE_26_STABLE 2014-07-22 12:01:06 +01:00
Dan Poltawski e14bbecd57 Merge branch '45724-26' of git://github.com/samhemelryk/moodle into MOODLE_26_STABLE 2014-07-22 09:07:27 +01:00
Sam Hemelryk 9e32e3befc Merge branch 'MDL-45594_m26' of git://github.com/markn86/moodle into MOODLE_26_STABLE 2014-07-22 11:12:13 +12:00
Sam Hemelryk 695553b1a5 Merge branch 'MDL-43063-26' of git://github.com/lameze/moodle into MOODLE_26_STABLE 2014-07-22 09:49:07 +12:00
Dan Poltawski c081554c0c Merge branch '46335-26' of git://github.com/samhemelryk/moodle into MOODLE_26_STABLE 2014-07-21 09:59:08 +01:00
Dan Poltawski b73aaa678c Merge branch 'MDL-46370_26' of https://github.com/moodlerooms/moodle into MOODLE_26_STABLE 2014-07-21 09:54:59 +01:00
Damyon Wiese 47c938a31b MDL-46017 Assign: Fix restore of marking workflow data 2014-07-21 16:39:01 +08:00
Simey Lameze bad139d09d MDL-43063 core: fix phpdoc comment codechecker issue. 2014-07-21 10:17:29 +08:00
Sam Hemelryk 3a8a3bc3f9 MDL-42909 course: fixed whitespace 2014-07-21 11:43:08 +12:00
Sam Hemelryk e8b0dadd6b Merge branch 'MDL-42909-26' of git://github.com/phalacee/moodle into MOODLE_26_STABLE 2014-07-21 11:35:50 +12:00
David Balch 4b2a23e36f MDL-40479 mod_assign: Fix the colour of grading success messages. 2014-07-21 11:33:25 +12:00
Brian Barnes 294629be5f MDL-46406 core_auth: Placed remember username before submit login form 2014-07-21 11:24:24 +12:00
Sam Hemelryk 2e8d176e27 Merge branch 'mdl-46427-m26' of git://github.com/deraadt/moodle into MOODLE_26_STABLE 2014-07-21 11:12:08 +12:00
Willy Lee d8d64eef11 MDL-46159 course: Add search box to course management pages 2014-07-21 10:56:27 +12:00
Sam Hemelryk 997be8cd2d Merge branch 'MDL-45339-26' of git://github.com/xow/moodle into MOODLE_26_STABLE 2014-07-21 10:49:29 +12:00
Sam Hemelryk 6958e7ebb0 Merge branch 'm26_MDL-46363' of https://github.com/danmarsden/moodle into MOODLE_26_STABLE 2014-07-21 10:45:38 +12:00
Sam Hemelryk a3f41f5840 Merge branch 'wip-mdl-46372-m26' of https://github.com/rajeshtaneja/moodle into MOODLE_26_STABLE 2014-07-21 10:42:35 +12:00
Sam Hemelryk f7a54f619a MDL-45724 cache: added cache API warnings to the admin notifications page 2014-07-21 09:49:45 +12:00
Sam Hemelryk 7bc4ca8b88 MDL-45724 cache: admin screen now shows store warnings
Implemented a means by which cache store instance can communicate
warnings due to things such as conflicting configurations etc.
2014-07-21 09:39:41 +12:00
AMOS bot 1980338f38 Automatically generated installer lang files 2014-07-20 00:44:31 +00:00
AMOS bot d7bd06bfde Automatically generated installer lang files 2014-07-19 00:41:57 +00:00
Michael de Raadt a74dd5b58c MDL-46427 Course: Correcting dimmed course link class on profile pages. 2014-07-18 15:54:16 +08:00
Jason Fowler 8ed407023d MDL-42909 Course: Fix title for move-targets 2014-07-18 14:43:11 +08:00
Mark Nelson fef6a23626 MDL-34248 core_backup: used API instead of inserting into the log table directly 2014-07-17 18:34:29 -07:00
Mark Nelson 46ca4a9099 MDL-34248 core_backup: added missing end quotation 2014-07-17 18:13:29 -07:00
Jim Thorpe 9df4af3757 enrol_imsenterprise: MDL-46363 including course lib when create_course is
used
2014-07-18 11:26:14 +12:00
Sam Hemelryk 4a77758f38 MDL-46335 backup: fixed casting issue with setting labels
The issue was that clean_param took an int and returned a string
and the result was used in an exact comparison.
The type change mean the comparison failed.
The solution was to ensure the param was cast as a string.
2014-07-18 08:29:48 +12:00
John Okely 803d739f4a MDL-45339 Libraries: Add a note to docblock of get_config, set_config, and unset_config to note they are used in lib/db/upgrade.php 2014-07-17 17:48:15 +08:00
Dan Poltawski 22ffc39685 weekly release 2.6.4+ 2014-07-17 09:22:49 +01:00
Dan Poltawski daf2f76125 Merge branch 'install_26_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_26_STABLE 2014-07-17 09:22:46 +01:00
AMOS bot 760bce86ea Automatically generated installer lang files 2014-07-17 00:53:00 +00:00
AMOS bot 8fec45ebf0 Automatically generated installer lang files 2014-07-17 00:53:00 +00:00
Mark Nelson 23aab8e694 MDL-45594 core_message: added unit tests 2014-07-16 17:06:48 -07:00
Mark Nelson e87c4986dd MDL-45594 core_message: ordered recent notifications by timecreated 2014-07-16 17:06:48 -07:00
Tim Hunt a62cfc3245 MDL-45594 simplify message_get_recent_conversations SQL
I am pretty sure that this new SQL is logically equivalent to
the original, and it passes Mark's unit tests. However, it is
hard to be 100% sure.
2014-07-16 17:06:47 -07:00
Sam Chaffee 01865c55bd MDL-46370 Ajax and Javascript - Fixes docked blocks not expanding when using dock on right 2014-07-16 12:01:31 -06:00
Dan Poltawski e9b7ea41c4 Revert "MDL-46226 core: pix_icon no longer sets title to the alt text"
This reverts commit b440662be2.
2014-07-16 13:45:46 +01:00
Dan Poltawski c82fa0c8ad Revert "MDL-46226 fix unit tests"
This reverts commit 42f05b95c6.
2014-07-16 13:45:45 +01:00
Rajesh Taneja bab46e77d7 MDL-30431 behat: Fixed wiki behat 2014-07-16 09:19:05 +02:00
Eloy Lafuente (stronk7) 6aff5581f6 MDL-30431 mod_wiki: whitespace fix 2014-07-16 01:19:13 +02:00
Eloy Lafuente (stronk7) 5cefb82acb Merge branch 'MDL-30431_wiki_comments_26' of https://github.com/andyjdavis/moodle into MOODLE_26_STABLE 2014-07-16 01:16:33 +02:00
Rajesh Taneja 9a24fe056e Backport event trigger from MDL-45641
While backporting MDL-45641, event trigger was missed
on editadavnced page.
2014-07-15 11:46:17 +08:00
Eloy Lafuente (stronk7) e60ca92e1d Merge branch 'MDL-46080_26' of https://github.com/jonof/moodle into MOODLE_26_STABLE 2014-07-14 23:30:34 +02:00
Sam Hemelryk 522cbb467c Merge branch 'MDL-42179-003-26' of https://github.com/dbezborodovrp/moodle into MOODLE_26_STABLE 2014-07-15 08:41:46 +12:00
Eloy Lafuente (stronk7) d7a9bd9da7 Merge branch 'm26_MDL-31366' of git://github.com/danmarsden/moodle into MOODLE_26_STABLE 2014-07-14 18:17:59 +02:00
Dan Poltawski 1aefe49544 Merge branch 'MDL-42752-26' of git://github.com/phalacee/moodle into MOODLE_26_STABLE 2014-07-14 16:09:28 +01:00
Dan Poltawski 42f05b95c6 MDL-46226 fix unit tests 2014-07-14 15:47:25 +01:00
Dan Poltawski 90e35c8929 Merge branch 'MDL-46218_disabled2_26' of https://github.com/andyjdavis/moodle into MOODLE_26_STABLE 2014-07-14 15:33:24 +01:00
Eloy Lafuente (stronk7) 674ce27e1b Merge branch 'm26_MDL-46197' of https://github.com/totara/moodle into MOODLE_26_STABLE 2014-07-14 16:25:18 +02:00
Dan Poltawski 8bbc71406d Merge branch 'm26_MDL-46226' of https://github.com/totara/moodle into MOODLE_26_STABLE 2014-07-14 15:15:07 +01:00
David Monllao e946e06322 MDL-43390 files: Only lock when locking is not prevented 2014-07-14 13:04:59 +08:00
Damien Bezborodov c50968f185 MDL-42179 mod_assign: Time remaining issue for group assignment 2014-07-14 13:53:29 +09:30
Sam Hemelryk 85cd13b837 Merge branch 'MDL-42214_popup_blocked_26' of https://github.com/andyjdavis/moodle into MOODLE_26_STABLE 2014-07-14 15:28:01 +12:00
Sam Hemelryk ff12f87c62 Merge branch 'MDL-46073_26' of https://github.com/totara/openbadges into MOODLE_26_STABLE 2014-07-14 15:16:11 +12:00
Andrew Davis 0257a401f7 MDL-42214 core_message:prevented popup notifications of messages from blocked users 2014-07-14 10:22:30 +08:00
Andrew Davis 9d9aef2fb0 MDL-30431 mod_wiki: clarified the logic around editing and deleting wiki comments and added behat tests 2014-07-14 08:16:47 +08:00
Sam Hemelryk 4a8103d97b Merge branch 'MDL-45765-moodle26' of https://github.com/StudiUM/moodle into MOODLE_26_STABLE 2014-07-14 12:10:03 +12:00
Sam Hemelryk 571516003b Merge branch 'wip-MDL-46280-m26' of git://github.com/marinaglancy/moodle into MOODLE_26_STABLE 2014-07-14 10:32:53 +12:00
Gilles-Philippe Leblanc 82d84457a0 MDL-22469 auth_cas: CAS module : parameter authCAS=NOCAS not properly handled 2014-07-14 10:22:01 +12:00
Sam Hemelryk cfaf9dc5a7 Merge branch 'MDL-31089_26' of git://github.com/dmonllao/moodle into MOODLE_26_STABLE 2014-07-14 09:51:27 +12:00
Sam Hemelryk 23dab427de Merge branch 'MDL-45562-26' of git://github.com/lameze/moodle into MOODLE_26_STABLE 2014-07-14 08:41:53 +12:00
Eloy Lafuente (stronk7) d25049c0fc Moodle release 2.6.4 2014-07-12 19:10:37 +02:00
David Monllao 00e1213a81 MDL-31089 mod_forum: Filtering non-visible groups 2014-07-11 16:50:38 +08:00
Simey Lameze 021ee71b69 MDL-45562 blog: fixed issues when creating/editing an external blog. 2014-07-11 15:22:28 +08:00
Dan Marsden 64ced100cc MDL-31366 Feedback: decode htmlchars on output to excel 2014-07-11 13:29:43 +12:00
Brian Barnes 4c2f38ace1 MDL-46197 core_calendar: Added label text to duration in minutes field 2014-07-11 09:01:03 +12:00
Brian Barnes b440662be2 MDL-46226 core: pix_icon no longer sets title to the alt text 2014-07-11 08:37:54 +12:00
Jean-Philippe Gaudreau 2d8c7cccd9 MDL-45765 Calendar import: Fix undefined variable in cron when updating calendar subscriptions 2014-07-10 16:08:32 -04: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
Andrew Davis 60770bb0a7 MDL-46218 reshuffled access checks in blog and notes 2014-07-10 11:25:23 +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
Marina Glancy ada0205360 MDL-46280 filter_activitynames: sort activities by length in reverse order 2014-07-08 11:48:59 +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
Yuliya Bozhko dcf8e1f5d8 MDL-46073 badges: Make sure html tags are not used in badge description
Signed-off-by: Yuliya Bozhko <yuliya.bozhko@totaralms.com>
2014-07-08 09:37:27 +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
Jason Fowler a5ac47089e MDL-42752 File-picker: Fix tabbing to disabled icons 2014-07-07 14:33:51 +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
Jonathon Fowler 15e7db4e1d MDL-46080 assign: fix offline grading worksheet marker column 2014-06-25 12:23:12 +10: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
514 changed files with 12278 additions and 3199 deletions
+4 -4
View File
@@ -142,14 +142,14 @@ function print_auth_lock_options($auth, $user_fields, $helptext, $retrieveopts,
$fieldname = $field;
if ($fieldname === 'lang') {
$fieldname = get_string('language');
} elseif (preg_match('/^(.+?)(\d+)$/', $fieldname, $matches)) {
$fieldname = get_string($matches[1]) . ' ' . $matches[2];
} elseif ($fieldname == 'url') {
$fieldname = get_string('webpage');
} elseif (!empty($customfields) && in_array($field, $customfields)) {
// If custom field then pick name from database.
$fieldshortname = str_replace('profile_field_', '', $fieldname);
$fieldname = $customfieldname[$fieldshortname]->name;
} elseif (preg_match('/^(.+?)(\d+)$/', $fieldname, $matches)) {
$fieldname = get_string($matches[1]) . ' ' . $matches[2];
} elseif ($fieldname == 'url') {
$fieldname = get_string('webpage');
} else {
$fieldname = get_string($fieldname);
}
+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();
+1 -1
View File
@@ -102,7 +102,7 @@ if ($contents = load_environment_xml()) {
}
// Get the results of the environment check.
list($envstatus, $environment_results) = check_moodle_environment($version);
list($envstatus, $environment_results) = check_moodle_environment($version, ENV_SELECT_NEWER);
// Display the page.
$output = $PAGE->get_renderer('core', 'admin');
+12 -6
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();
@@ -591,10 +593,14 @@ $availableupdatesfetch = $updateschecker->get_last_timefetched();
$buggyiconvnomb = (!function_exists('mb_convert_encoding') and @iconv('UTF-8', 'UTF-8//IGNORE', '100'.chr(130).'€') !== '100€');
//check if the site is registered on Moodle.org
$registered = $DB->count_records('registration_hubs', array('huburl' => HUB_MOODLEORGHUBURL, 'confirmed' => 1));
// Check if there are any cache warnings.
$cachewarnings = cache_helper::warnings();
admin_externalpage_setup('adminnotifications');
/* @var core_admin_renderer $output */
$output = $PAGE->get_renderer('core', 'admin');
echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed,
$cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb,
$registered);
echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed, $cronoverdue, $dbproblems,
$maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb,
$registered, $cachewarnings);
+26 -7
View File
@@ -303,12 +303,13 @@ class core_admin_renderer extends plugin_renderer_base {
* @param bool $buggyiconvnomb warn iconv problems
* @param array|null $availableupdates array of \core\update\info objects or null
* @param int|null $availableupdatesfetch timestamp of the most recent updates fetch or null (unknown)
* @param string[] $cachewarnings An array containing warnings from the Cache API.
*
* @return string HTML to output.
*/
public function admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed,
$cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch,
$buggyiconvnomb, $registered) {
$buggyiconvnomb, $registered, array $cachewarnings = array()) {
global $CFG;
$output = '';
@@ -321,6 +322,7 @@ class core_admin_renderer extends plugin_renderer_base {
$output .= $this->cron_overdue_warning($cronoverdue);
$output .= $this->db_problems($dbproblems);
$output .= $this->maintenance_mode_warning($maintenancemode);
$output .= $this->cache_warnings($cachewarnings);
$output .= $this->registration_warning($registered);
//////////////////////////////////////////////////////////////////////////////////////////////////
@@ -583,6 +585,19 @@ class core_admin_renderer extends plugin_renderer_base {
return $this->warning($dbproblems);
}
/**
* Renders cache warnings if there are any.
*
* @param string[] $cachewarnings
* @return string
*/
public function cache_warnings(array $cachewarnings) {
if (!count($cachewarnings)) {
return '';
}
return join("\n", array_map(array($this, 'warning'), $cachewarnings));
}
/**
* Render an appropriate message if the site in in maintenance mode.
* @param bool $maintenancemode
@@ -1355,7 +1370,7 @@ class core_admin_renderer extends plugin_renderer_base {
* configuration and how it suits Moodle needs.
*
* @param boolean $result final result of the check (true/false)
* @param array $environment_results array of results gathered
* @param environment_results[] $environment_results array of results gathered
* @return string HTML to output.
*/
public function environment_check_table($result, $environment_results) {
@@ -1367,9 +1382,10 @@ class core_admin_renderer extends plugin_renderer_base {
get_string('name'),
get_string('info'),
get_string('report'),
get_string('plugin'),
get_string('status'),
);
$servertable->colclasses = array('centeralign name', 'centeralign status', 'leftalign report', 'centeralign info');
$servertable->colclasses = array('centeralign name', 'centeralign info', 'leftalign report', 'leftalign plugin', 'centeralign status');
$servertable->attributes['class'] = 'admintable environmenttable generaltable';
$servertable->id = 'serverstatus';
@@ -1379,9 +1395,10 @@ class core_admin_renderer extends plugin_renderer_base {
$othertable->head = array(
get_string('info'),
get_string('report'),
get_string('plugin'),
get_string('status'),
);
$othertable->colclasses = array('aligncenter info', 'alignleft report', 'aligncenter status');
$othertable->colclasses = array('aligncenter info', 'alignleft report', 'alignleft plugin', 'aligncenter status');
$othertable->attributes['class'] = 'admintable environmenttable generaltable';
$othertable->id = 'otherserverstatus';
@@ -1397,6 +1414,7 @@ class core_admin_renderer extends plugin_renderer_base {
$type = $environment_result->getPart();
$info = $environment_result->getInfo();
$status = $environment_result->getStatus();
$plugin = $environment_result->getPluginName();
$error_code = $environment_result->getErrorCode();
// Process Report field
$rec = new stdClass();
@@ -1473,7 +1491,8 @@ class core_admin_renderer extends plugin_renderer_base {
if (!empty($info)){
$linkparts[] = $info;
}
if (empty($CFG->docroot)) {
// Plugin environments do not have docs pages yet.
if (empty($CFG->docroot) or $environment_result->plugin) {
$report = get_string($stringtouse, 'admin', $rec);
} else {
$report = $this->doc_link(join($linkparts, '/'), get_string($stringtouse, 'admin', $rec));
@@ -1499,9 +1518,9 @@ class core_admin_renderer extends plugin_renderer_base {
// Add the row to the table
if ($environment_result->getPart() == 'custom_check'){
$otherdata[$messagetype][] = array ($info, $report, $status);
$otherdata[$messagetype][] = array ($info, $report, $plugin, $status);
} else {
$serverdata[$messagetype][] = array ($type, $info, $report, $status);
$serverdata[$messagetype][] = array ($type, $info, $report, $plugin, $status);
}
}
}
+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);
@@ -233,3 +233,25 @@ Feature: Set up contextual data for tests
And the "members" select box should contain "Student 1"
And I select "Group 2 (1)" from "groups"
And the "members" select box should contain "Student 2"
Scenario: Add cohorts with data generator
Given the following "categories" exist:
| name | category | idnumber |
| Cat 1 | 0 | CAT1 |
And the following "cohorts" exist:
| name | idnumber |
| System cohort 1 | CH01 |
And the following "cohorts" exist:
| name | idnumber | contextlevel | reference |
| System cohort 2 | CH02 | System | |
| Cohort in category 1 | CH1 | Category | CAT1 |
When I log in as "admin"
And I navigate to "Cohorts" node in "Site administration > Users > Accounts"
Then I should see "System cohort 1"
And I should see "System cohort 2"
And I should not see "Cohort in category"
And I follow "Courses"
And I follow "Cat 1"
And I follow "Cohorts"
And I should see "Cohort in category 1"
And I should not see "System cohort"
@@ -36,6 +36,10 @@ class tool_generator_course_backend extends tool_generator_backend {
* @var array Number of sections in course
*/
private static $paramsections = array(1, 10, 100, 500, 1000, 2000);
/**
* @var array Number of assignments in course
*/
private static $paramassignments = array(1, 10, 100, 500, 1000, 2000);
/**
* @var array Number of Page activities in course
*/
@@ -179,6 +183,7 @@ class tool_generator_course_backend extends tool_generator_backend {
// Make course.
$this->course = $this->create_course();
$this->create_users();
$this->create_assignments();
$this->create_pages();
$this->create_small_files();
$this->create_big_files();
@@ -318,6 +323,26 @@ class tool_generator_course_backend extends tool_generator_backend {
$this->end_log();
}
/**
* Creates a number of Assignment activities.
*/
private function create_assignments() {
// Set up generator.
$assigngenerator = $this->generator->get_plugin_generator('mod_assign');
// Create assignments.
$number = self::$paramassignments[$this->size];
$this->log('createassignments', $number, true);
for ($i = 0; $i < $number; $i++) {
$record = array('course' => $this->course);
$options = array('section' => $this->get_target_section());
$assigngenerator->create_instance($record, $options);
$this->dot($i, $number);
}
$this->end_log();
}
/**
* Creates a number of Page activities.
*/
@@ -71,6 +71,7 @@ $string['pluginname'] = 'Development data generator';
$string['progress_checkaccounts'] = 'Checking user accounts ({$a})';
$string['progress_coursecompleted'] = 'Course completed ({$a}s)';
$string['progress_createaccounts'] = 'Creating user accounts ({$a->from} - {$a->to})';
$string['progress_createassignments'] = 'Creating assignments ({$a})';
$string['progress_createbigfiles'] = 'Creating big files ({$a})';
$string['progress_createcourse'] = 'Creating course {$a}';
$string['progress_createforum'] = 'Creating forum ({$a} posts)';
+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++;
+260 -348
View File
@@ -63,7 +63,7 @@ if (!defined('E_USER_DEPRECATED')) {
/**
* phpCAS version. accessible for the user by phpCAS::getVersion().
*/
define('PHPCAS_VERSION', '1.3.2');
define('PHPCAS_VERSION', '1.3.3');
/**
* @addtogroup public
@@ -78,6 +78,10 @@ define("CAS_VERSION_1_0", '1.0');
* CAS version 2.0
*/
define("CAS_VERSION_2_0", '2.0');
/**
* CAS version 3.0
*/
define("CAS_VERSION_3_0", '3.0');
// ------------------------------------------------------------------------
// SAML defines
@@ -318,18 +322,6 @@ class phpCAS
if (is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error(self::$_PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . self::$_PHPCAS_INIT_CALL['file'] . ':' . self::$_PHPCAS_INIT_CALL['line'] . ')');
}
if (gettype($server_version) != 'string') {
phpCAS :: error('type mismatched for parameter $server_version (should be `string\')');
}
if (gettype($server_hostname) != 'string') {
phpCAS :: error('type mismatched for parameter $server_hostname (should be `string\')');
}
if (gettype($server_port) != 'integer') {
phpCAS :: error('type mismatched for parameter $server_port (should be `integer\')');
}
if (gettype($server_uri) != 'string') {
phpCAS :: error('type mismatched for parameter $server_uri (should be `string\')');
}
// store where the initializer is called from
$dbg = debug_backtrace();
@@ -341,10 +333,14 @@ class phpCAS
);
// initialize the object $_PHPCAS_CLIENT
self::$_PHPCAS_CLIENT = new CAS_Client(
$server_version, false, $server_hostname, $server_port, $server_uri,
$changeSessionID
);
try {
self::$_PHPCAS_CLIENT = new CAS_Client(
$server_version, false, $server_hostname, $server_port, $server_uri,
$changeSessionID
);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
phpCAS :: traceEnd();
}
@@ -370,18 +366,6 @@ class phpCAS
if (is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error(self::$_PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . self::$_PHPCAS_INIT_CALL['file'] . ':' . self::$_PHPCAS_INIT_CALL['line'] . ')');
}
if (gettype($server_version) != 'string') {
phpCAS :: error('type mismatched for parameter $server_version (should be `string\')');
}
if (gettype($server_hostname) != 'string') {
phpCAS :: error('type mismatched for parameter $server_hostname (should be `string\')');
}
if (gettype($server_port) != 'integer') {
phpCAS :: error('type mismatched for parameter $server_port (should be `integer\')');
}
if (gettype($server_uri) != 'string') {
phpCAS :: error('type mismatched for parameter $server_uri (should be `string\')');
}
// store where the initialzer is called from
$dbg = debug_backtrace();
@@ -393,10 +377,14 @@ class phpCAS
);
// initialize the object $_PHPCAS_CLIENT
self::$_PHPCAS_CLIENT = new CAS_Client(
$server_version, true, $server_hostname, $server_port, $server_uri,
$changeSessionID
);
try {
self::$_PHPCAS_CLIENT = new CAS_Client(
$server_version, true, $server_hostname, $server_port, $server_uri,
$changeSessionID
);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
phpCAS :: traceEnd();
}
@@ -636,13 +624,13 @@ class phpCAS
*/
public static function setLang($lang)
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
phpCAS::_validateClientExists();
try {
self::$_PHPCAS_CLIENT->setLang($lang);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (gettype($lang) != 'string') {
phpCAS :: error('type mismatched for parameter $lang (should be `string\')');
}
self::$_PHPCAS_CLIENT->setLang($lang);
}
/** @} */
@@ -682,13 +670,13 @@ class phpCAS
*/
public static function setHTMLHeader($header)
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
phpCAS::_validateClientExists();
try {
self::$_PHPCAS_CLIENT->setHTMLHeader($header);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (gettype($header) != 'string') {
phpCAS :: error('type mismatched for parameter $header (should be `string\')');
}
self::$_PHPCAS_CLIENT->setHTMLHeader($header);
}
/**
@@ -700,13 +688,13 @@ class phpCAS
*/
public static function setHTMLFooter($footer)
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
phpCAS::_validateClientExists();
try {
self::$_PHPCAS_CLIENT->setHTMLFooter($footer);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (gettype($footer) != 'string') {
phpCAS :: error('type mismatched for parameter $footer (should be `string\')');
}
self::$_PHPCAS_CLIENT->setHTMLFooter($footer);
}
/** @} */
@@ -729,19 +717,13 @@ class phpCAS
public static function setPGTStorage($storage)
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
phpCAS::_validateProxyExists();
try {
self::$_PHPCAS_CLIENT->setPGTStorage($storage);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (!self::$_PHPCAS_CLIENT->isProxy()) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
}
if (self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
phpCAS :: error('this method should only be called before ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() (called at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ')');
}
if ( !($storage instanceof CAS_PGTStorage) ) {
phpCAS :: error('type mismatched for parameter $storage (should be a CAS_PGTStorage `object\')');
}
self::$_PHPCAS_CLIENT->setPGTStorage($storage);
phpCAS :: traceEnd();
}
@@ -766,25 +748,13 @@ class phpCAS
$password='', $table='', $driver_options=null
) {
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
phpCAS::_validateProxyExists();
try {
self::$_PHPCAS_CLIENT->setPGTStorageDb($dsn_or_pdo, $username, $password, $table, $driver_options);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (!self::$_PHPCAS_CLIENT->isProxy()) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
}
if (self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
phpCAS :: error('this method should only be called before ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() (called at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ')');
}
if (gettype($username) != 'string') {
phpCAS :: error('type mismatched for parameter $username (should be `string\')');
}
if (gettype($password) != 'string') {
phpCAS :: error('type mismatched for parameter $password (should be `string\')');
}
if (gettype($table) != 'string') {
phpCAS :: error('type mismatched for parameter $table (should be `string\')');
}
self::$_PHPCAS_CLIENT->setPGTStorageDb($dsn_or_pdo, $username, $password, $table, $driver_options);
phpCAS :: traceEnd();
}
@@ -799,19 +769,13 @@ class phpCAS
public static function setPGTStorageFile($path = '')
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
phpCAS::_validateProxyExists();
try {
self::$_PHPCAS_CLIENT->setPGTStorageFile($path);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (!self::$_PHPCAS_CLIENT->isProxy()) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
}
if (self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
phpCAS :: error('this method should only be called before ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() (called at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ')');
}
if (gettype($path) != 'string') {
phpCAS :: error('type mismatched for parameter $path (should be `string\')');
}
self::$_PHPCAS_CLIENT->setPGTStorageFile($path);
phpCAS :: traceEnd();
}
/** @} */
@@ -836,23 +800,13 @@ class phpCAS
public static function getProxiedService ($type)
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
}
if (!self::$_PHPCAS_CLIENT->isProxy()) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()');
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
}
if (gettype($type) != 'string') {
phpCAS :: error('type mismatched for parameter $type (should be `string\')');
}
phpCAS::_validateProxyExists();
$res = self::$_PHPCAS_CLIENT->getProxiedService($type);
try {
$res = self::$_PHPCAS_CLIENT->getProxiedService($type);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
phpCAS :: traceEnd();
return $res;
@@ -872,20 +826,13 @@ class phpCAS
*/
public static function initializeProxiedService (CAS_ProxiedService $proxiedService)
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
}
if (!self::$_PHPCAS_CLIENT->isProxy()) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()');
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
}
phpCAS::_validateProxyExists();
self::$_PHPCAS_CLIENT->initializeProxiedService($proxiedService);
try {
self::$_PHPCAS_CLIENT->initializeProxiedService($proxiedService);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
}
/**
@@ -906,23 +853,13 @@ class phpCAS
public static function serviceWeb($url, & $err_code, & $output)
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
}
if (!self::$_PHPCAS_CLIENT->isProxy()) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()');
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
}
if (gettype($url) != 'string') {
phpCAS :: error('type mismatched for parameter $url (should be `string\')');
}
phpCAS::_validateProxyExists();
$res = self::$_PHPCAS_CLIENT->serviceWeb($url, $err_code, $output);
try {
$res = self::$_PHPCAS_CLIENT->serviceWeb($url, $err_code, $output);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
phpCAS :: traceEnd($res);
return $res;
@@ -950,28 +887,14 @@ class phpCAS
public static function serviceMail($url, $service, $flags, & $err_code, & $err_msg, & $pt)
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
}
if (!self::$_PHPCAS_CLIENT->isProxy()) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()');
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
}
if (gettype($url) != 'string') {
phpCAS :: error('type mismatched for parameter $url (should be `string\')');
}
phpCAS::_validateProxyExists();
if (gettype($flags) != 'integer') {
phpCAS :: error('type mismatched for parameter $flags (should be `integer\')');
try {
$res = self::$_PHPCAS_CLIENT->serviceMail($url, $service, $flags, $err_code, $err_msg, $pt);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
$res = self::$_PHPCAS_CLIENT->serviceMail($url, $service, $flags, $err_code, $err_msg, $pt);
phpCAS :: traceEnd($res);
return $res;
}
@@ -998,13 +921,13 @@ class phpCAS
*/
public static function setCacheTimesForAuthRecheck($n)
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
phpCAS::_validateClientExists();
try {
self::$_PHPCAS_CLIENT->setCacheTimesForAuthRecheck($n);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (gettype($n) != 'integer') {
phpCAS :: error('type mismatched for parameter $n (should be `integer\')');
}
self::$_PHPCAS_CLIENT->setCacheTimesForAuthRecheck($n);
}
/**
@@ -1028,9 +951,7 @@ class phpCAS
*/
public static function setPostAuthenticateCallback ($function, array $additionalArgs = array())
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
self::$_PHPCAS_CLIENT->setPostAuthenticateCallback($function, $additionalArgs);
}
@@ -1051,9 +972,7 @@ class phpCAS
*/
public static function setSingleSignoutCallback ($function, array $additionalArgs = array())
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
self::$_PHPCAS_CLIENT->setSingleSignoutCallback($function, $additionalArgs);
}
@@ -1071,9 +990,7 @@ class phpCAS
public static function checkAuthentication()
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
$auth = self::$_PHPCAS_CLIENT->checkAuthentication();
@@ -1094,16 +1011,13 @@ class phpCAS
public static function forceAuthentication()
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
$auth = self::$_PHPCAS_CLIENT->forceAuthentication();
// store where the authentication has been checked and the result
self::$_PHPCAS_CLIENT->markAuthenticationCall($auth);
/* if (!$auth) {
/* if (!$auth) {
phpCAS :: trace('user is not authenticated, redirecting to the CAS server');
self::$_PHPCAS_CLIENT->forceAuthentication();
} else {
@@ -1122,9 +1036,8 @@ class phpCAS
public static function renewAuthentication()
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
$auth = self::$_PHPCAS_CLIENT->renewAuthentication();
// store where the authentication has been checked and the result
@@ -1143,9 +1056,7 @@ class phpCAS
public static function isAuthenticated()
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
// call the isAuthenticated method of the $_PHPCAS_CLIENT object
$auth = self::$_PHPCAS_CLIENT->isAuthenticated();
@@ -1166,9 +1077,8 @@ class phpCAS
*/
public static function isSessionAuthenticated()
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
return (self::$_PHPCAS_CLIENT->isSessionAuthenticated());
}
@@ -1176,65 +1086,56 @@ class phpCAS
* This method returns the CAS user's login name.
*
* @return string the login name of the authenticated user
* @warning should not be called only after phpCAS::forceAuthentication()
* @warning should only be called after phpCAS::forceAuthentication()
* or phpCAS::checkAuthentication().
* */
public static function getUser()
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
phpCAS::_validateClientExists();
try {
return self::$_PHPCAS_CLIENT->getUser();
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
}
return self::$_PHPCAS_CLIENT->getUser();
}
/**
* Answer attributes about the authenticated user.
*
* @warning should not be called only after phpCAS::forceAuthentication()
* @warning should only be called after phpCAS::forceAuthentication()
* or phpCAS::checkAuthentication().
*
* @return array
*/
public static function getAttributes()
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
phpCAS::_validateClientExists();
try {
return self::$_PHPCAS_CLIENT->getAttributes();
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
}
return self::$_PHPCAS_CLIENT->getAttributes();
}
/**
* Answer true if there are attributes for the authenticated user.
*
* @warning should not be called only after phpCAS::forceAuthentication()
* @warning should only be called after phpCAS::forceAuthentication()
* or phpCAS::checkAuthentication().
*
* @return bool
*/
public static function hasAttributes()
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
phpCAS::_validateClientExists();
try {
return self::$_PHPCAS_CLIENT->hasAttributes();
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
}
return self::$_PHPCAS_CLIENT->hasAttributes();
}
/**
@@ -1243,21 +1144,18 @@ class phpCAS
* @param string $key attribute name
*
* @return bool
* @warning should not be called only after phpCAS::forceAuthentication()
* @warning should only be called after phpCAS::forceAuthentication()
* or phpCAS::checkAuthentication().
*/
public static function hasAttribute($key)
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
phpCAS::_validateClientExists();
try {
return self::$_PHPCAS_CLIENT->hasAttribute($key);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
}
return self::$_PHPCAS_CLIENT->hasAttribute($key);
}
/**
@@ -1266,21 +1164,18 @@ class phpCAS
* @param string $key attribute name
*
* @return mixed string for a single value or an array if multiple values exist.
* @warning should not be called only after phpCAS::forceAuthentication()
* @warning should only be called after phpCAS::forceAuthentication()
* or phpCAS::checkAuthentication().
*/
public static function getAttribute($key)
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
phpCAS::_validateClientExists();
try {
return self::$_PHPCAS_CLIENT->getAttribute($key);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');
}
if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
}
return self::$_PHPCAS_CLIENT->getAttribute($key);
}
/**
@@ -1293,9 +1188,8 @@ class phpCAS
*/
public static function handleLogoutRequests($check_client = true, $allowed_clients = false)
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
return (self::$_PHPCAS_CLIENT->handleLogoutRequests($check_client, $allowed_clients));
}
@@ -1307,9 +1201,8 @@ class phpCAS
*/
public static function getServerLoginURL()
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
return self::$_PHPCAS_CLIENT->getServerLoginURL();
}
@@ -1324,13 +1217,14 @@ class phpCAS
public static function setServerLoginURL($url = '')
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after' . __CLASS__ . '::client()');
phpCAS::_validateClientExists();
try {
self::$_PHPCAS_CLIENT->setServerLoginURL($url);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (gettype($url) != 'string') {
phpCAS :: error('type mismatched for parameter $url (should be `string`)');
}
self::$_PHPCAS_CLIENT->setServerLoginURL($url);
phpCAS :: traceEnd();
}
@@ -1345,13 +1239,14 @@ class phpCAS
public static function setServerServiceValidateURL($url = '')
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after' . __CLASS__ . '::client()');
phpCAS::_validateClientExists();
try {
self::$_PHPCAS_CLIENT->setServerServiceValidateURL($url);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (gettype($url) != 'string') {
phpCAS :: error('type mismatched for parameter $url (should be `string`)');
}
self::$_PHPCAS_CLIENT->setServerServiceValidateURL($url);
phpCAS :: traceEnd();
}
@@ -1366,13 +1261,14 @@ class phpCAS
public static function setServerProxyValidateURL($url = '')
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after' . __CLASS__ . '::client()');
phpCAS::_validateClientExists();
try {
self::$_PHPCAS_CLIENT->setServerProxyValidateURL($url);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (gettype($url) != 'string') {
phpCAS :: error('type mismatched for parameter $url (should be `string`)');
}
self::$_PHPCAS_CLIENT->setServerProxyValidateURL($url);
phpCAS :: traceEnd();
}
@@ -1386,13 +1282,14 @@ class phpCAS
public static function setServerSamlValidateURL($url = '')
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after' . __CLASS__ . '::client()');
phpCAS::_validateClientExists();
try {
self::$_PHPCAS_CLIENT->setServerSamlValidateURL($url);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (gettype($url) != 'string') {
phpCAS :: error('type mismatched for parameter $url (should be`string\')');
}
self::$_PHPCAS_CLIENT->setServerSamlValidateURL($url);
phpCAS :: traceEnd();
}
@@ -1404,9 +1301,8 @@ class phpCAS
*/
public static function getServerLogoutURL()
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
return self::$_PHPCAS_CLIENT->getServerLogoutURL();
}
@@ -1421,17 +1317,14 @@ class phpCAS
public static function setServerLogoutURL($url = '')
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error(
'this method should only be called after' . __CLASS__ . '::client()'
);
phpCAS::_validateClientExists();
try {
self::$_PHPCAS_CLIENT->setServerLogoutURL($url);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (gettype($url) != 'string') {
phpCAS :: error(
'type mismatched for parameter $url (should be `string`)'
);
}
self::$_PHPCAS_CLIENT->setServerLogoutURL($url);
phpCAS :: traceEnd();
}
@@ -1446,9 +1339,8 @@ class phpCAS
public static function logout($params = "")
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
$parsedParams = array ();
if ($params != "") {
if (is_string($params)) {
@@ -1480,9 +1372,8 @@ class phpCAS
public static function logoutWithRedirectService($service)
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
if (!is_string($service)) {
phpCAS :: error('type mismatched for parameter $service (should be `string\')');
}
@@ -1532,9 +1423,8 @@ class phpCAS
{
trigger_error('Function deprecated for cas servers >= 3.3.5.1', E_USER_DEPRECATED);
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
if (!is_string($service)) {
phpCAS :: error('type mismatched for parameter $service (should be `string\')');
}
@@ -1563,16 +1453,14 @@ class phpCAS
public static function setFixedCallbackURL($url = '')
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
phpCAS::_validateProxyExists();
try {
self::$_PHPCAS_CLIENT->setCallbackURL($url);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (!self::$_PHPCAS_CLIENT->isProxy()) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
}
if (gettype($url) != 'string') {
phpCAS :: error('type mismatched for parameter $url (should be `string\')');
}
self::$_PHPCAS_CLIENT->setCallbackURL($url);
phpCAS :: traceEnd();
}
@@ -1587,13 +1475,14 @@ class phpCAS
public static function setFixedServiceURL($url)
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
phpCAS::_validateProxyExists();
try {
self::$_PHPCAS_CLIENT->setURL($url);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (gettype($url) != 'string') {
phpCAS :: error('type mismatched for parameter $url (should be `string\')');
}
self::$_PHPCAS_CLIENT->setURL($url);
phpCAS :: traceEnd();
}
@@ -1604,9 +1493,7 @@ class phpCAS
*/
public static function getServiceURL()
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
}
phpCAS::_validateProxyExists();
return (self::$_PHPCAS_CLIENT->getURL());
}
@@ -1621,13 +1508,13 @@ class phpCAS
*/
public static function retrievePT($target_service, & $err_code, & $err_msg)
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
phpCAS::_validateProxyExists();
try {
return (self::$_PHPCAS_CLIENT->retrievePT($target_service, $err_code, $err_msg));
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (gettype($target_service) != 'string') {
phpCAS :: error('type mismatched for parameter $target_service(should be `string\')');
}
return (self::$_PHPCAS_CLIENT->retrievePT($target_service, $err_code, $err_msg));
}
/**
@@ -1642,16 +1529,14 @@ class phpCAS
public static function setCasServerCACert($cert, $validate_cn = true)
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
phpCAS::_validateClientExists();
try {
self::$_PHPCAS_CLIENT->setCasServerCACert($cert, $validate_cn);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if (gettype($cert) != 'string') {
phpCAS :: error('type mismatched for parameter $cert (should be `string\')');
}
if (gettype($validate_cn) != 'boolean') {
phpCAS :: error('type mismatched for parameter $validate_cn (should be `boolean\')');
}
self::$_PHPCAS_CLIENT->setCasServerCACert($cert, $validate_cn);
phpCAS :: traceEnd();
}
@@ -1663,9 +1548,8 @@ class phpCAS
public static function setNoCasServerValidation()
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
phpCAS :: trace('You have configured no validation of the legitimacy of the cas server. This is not recommended for production use.');
self::$_PHPCAS_CLIENT->setNoCasServerValidation();
phpCAS :: traceEnd();
@@ -1684,9 +1568,8 @@ class phpCAS
public static function setNoClearTicketsFromUrl()
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
self::$_PHPCAS_CLIENT->setNoClearTicketsFromUrl();
phpCAS :: traceEnd();
}
@@ -1705,9 +1588,8 @@ class phpCAS
public static function setExtraCurlOption($key, $value)
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
}
phpCAS::_validateClientExists();
self::$_PHPCAS_CLIENT->setExtraCurlOption($key, $value);
phpCAS :: traceEnd();
}
@@ -1751,11 +1633,11 @@ class phpCAS
public static function allowProxyChain(CAS_ProxyChain_Interface $proxy_chain)
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
}
if (self::$_PHPCAS_CLIENT->getServerVersion() !== CAS_VERSION_2_0) {
phpCAS :: error('this method can only be used with the cas 2.0 protool');
phpCAS::_validateClientExists();
if (self::$_PHPCAS_CLIENT->getServerVersion() !== CAS_VERSION_2_0
&& self::$_PHPCAS_CLIENT->getServerVersion() !== CAS_VERSION_3_0) {
phpCAS :: error('this method can only be used with the cas 2.0/3.0 protocols');
}
self::$_PHPCAS_CLIENT->getAllowedProxyChains()->allowProxyChain($proxy_chain);
phpCAS :: traceEnd();
@@ -1772,9 +1654,7 @@ class phpCAS
*/
public static function getProxies ()
{
if ( !is_object(self::$_PHPCAS_CLIENT) ) {
phpCAS::error('this method should only be called after '.__CLASS__.'::client()');
}
phpCAS::_validateProxyExists();
return(self::$_PHPCAS_CLIENT->getProxies());
}
@@ -1795,13 +1675,14 @@ class phpCAS
{
phpCAS::traceBegin();
phpCAS::log('rebroadcastNodeUrl:'.$rebroadcastNodeUrl);
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
phpCAS::_validateClientExists();
try {
self::$_PHPCAS_CLIENT->addRebroadcastNode($rebroadcastNodeUrl);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
if ( !(bool)preg_match("/^(http|https):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i", $rebroadcastNodeUrl)) {
phpCAS::error('type mismatched for parameter $rebroadcastNodeUrl (should be `url\')');
}
self::$_PHPCAS_CLIENT->addRebroadcastNode($rebroadcastNodeUrl);
phpCAS::traceEnd();
}
@@ -1816,14 +1697,45 @@ class phpCAS
public static function addRebroadcastHeader($header)
{
phpCAS :: traceBegin();
if (!is_object(self::$_PHPCAS_CLIENT)) {
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
phpCAS::_validateClientExists();
try {
self::$_PHPCAS_CLIENT->addRebroadcastHeader($header);
} catch (Exception $e) {
phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
}
self::$_PHPCAS_CLIENT->addRebroadcastHeader($header);
phpCAS :: traceEnd();
}
}
/**
* Checks if a client already exists
*
* @throws CAS_OutOfSequenceBeforeClientException
*
* @return void
*/
private static function _validateClientExists()
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
throw new CAS_OutOfSequenceBeforeClientException();
}
}
/**
* Checks of a proxy client aready exists
*
* @throws CAS_OutOfSequenceBeforeProxyException
*
* @return void
*/
private static function _validateProxyExists()
{
if (!is_object(self::$_PHPCAS_CLIENT)) {
throw new CAS_OutOfSequenceBeforeProxyException();
}
}
}
// ########################################################################
// DOCUMENTATION
// ########################################################################
+2 -1
View File
@@ -74,7 +74,7 @@ implements CAS_Exception
printf(
$lang->getYouWereNotAuthenticated(),
htmlentities($client->getURL()),
$_SERVER['SERVER_ADMIN']
isset($_SERVER['SERVER_ADMIN']) ? $_SERVER['SERVER_ADMIN']:''
);
phpCAS::trace('CAS URL: '.$cas_url);
phpCAS::trace('Authentication failure: '.$failure);
@@ -89,6 +89,7 @@ implements CAS_Exception
phpCAS::trace('Reason: CAS error');
break;
case CAS_VERSION_2_0:
case CAS_VERSION_3_0:
if ( empty($err_code) ) {
phpCAS::trace('Reason: no CAS error');
} else {
+30 -22
View File
@@ -25,35 +25,39 @@ function CAS_autoload($class)
{
// Static to hold the Include Path to CAS
static $include_path;
// Setup the include path if it's not already set from a previous call
if (!$include_path) {
$include_path = dirname(dirname(__FILE__));
}
// Check only for CAS classes
if (substr($class, 0, 4) !== 'CAS_') {
return false;
}
// Declare local variable to store the expected full path to the file
$file_path = $include_path . '/' . str_replace('_', '/', $class) . '.php';
// Setup the include path if it's not already set from a previous call
if (empty($include_path)) {
$include_path = array(dirname(dirname(__FILE__)), dirname(dirname(__FILE__)) . '/../test/' );
}
$fp = @fopen($file_path, 'r', true);
if ($fp) {
fclose($fp);
include $file_path;
if (!class_exists($class, false) && !interface_exists($class, false)) {
die(
new Exception(
'Class ' . $class . ' was not present in ' .
$file_path .
' [CAS_autoload]'
)
);
// Declare local variable to store the expected full path to the file
foreach ($include_path as $path) {
$file_path = $path . '/' . str_replace('_', '/', $class) . '.php';
$fp = @fopen($file_path, 'r', true);
if ($fp) {
fclose($fp);
include $file_path;
if (!class_exists($class, false) && !interface_exists($class, false)) {
die(
new Exception(
'Class ' . $class . ' was not present in ' .
$file_path .
' [CAS_autoload]'
)
);
}
return true;
}
return true;
}
$e = new Exception(
'Class ' . $class . ' could not be loaded from ' .
$file_path . ', file does not exist (Path="'
. $include_path .'") [CAS_autoload]'
. implode(':', $include_path) .'") [CAS_autoload]'
);
$trace = $e->getTrace();
if (isset($trace[2]) && isset($trace[2]['function'])
@@ -71,9 +75,13 @@ function CAS_autoload($class)
// set up __autoload
if (function_exists('spl_autoload_register')) {
if (!(spl_autoload_functions()) || !in_array('CAS_autoload', spl_autoload_functions())) {
if (!(spl_autoload_functions())
|| !in_array('CAS_autoload', spl_autoload_functions())
) {
spl_autoload_register('CAS_autoload');
if (function_exists('__autoload') && !in_array('__autoload', spl_autoload_functions())) {
if (function_exists('__autoload')
&& !in_array('__autoload', spl_autoload_functions())
) {
// __autoload() was being used, but now would be ignored, add
// it to the autoload stack
spl_autoload_register('__autoload');
File diff suppressed because it is too large Load Diff
+14 -6
View File
@@ -161,7 +161,9 @@ class CAS_CookieJar
protected function parseCookieHeader ($line, $defaultDomain)
{
if (!$defaultDomain) {
throw new CAS_InvalidArgumentException('$defaultDomain was not provided.');
throw new CAS_InvalidArgumentException(
'$defaultDomain was not provided.'
);
}
// Set our default values
@@ -315,10 +317,14 @@ class CAS_CookieJar
protected function cookieMatchesTarget ($cookie, $target)
{
if (!is_array($target)) {
throw new CAS_InvalidArgumentException('$target must be an array of URL attributes as generated by parse_url().');
throw new CAS_InvalidArgumentException(
'$target must be an array of URL attributes as generated by parse_url().'
);
}
if (!isset($target['host'])) {
throw new CAS_InvalidArgumentException('$target must be an array of URL attributes as generated by parse_url().');
throw new CAS_InvalidArgumentException(
'$target must be an array of URL attributes as generated by parse_url().'
);
}
// Verify that the scheme matches
@@ -352,15 +358,17 @@ class CAS_CookieJar
}
}
} else {
// If the cookie host doesn't begin with '.', the host must case-insensitive
// match exactly
// If the cookie host doesn't begin with '.',
// the host must case-insensitive match exactly
if (strcasecmp($target['host'], $cookie['domain']) !== 0) {
return false;
}
}
// Verify that the port matches
if (isset($cookie['ports']) && !in_array($target['port'], $cookie['ports'])) {
if (isset($cookie['ports'])
&& !in_array($target['port'], $cookie['ports'])
) {
return false;
}
+2 -2
View File
@@ -99,7 +99,7 @@ class CAS_Languages_German implements CAS_Languages_LanguageInterface
*/
public function getYouWereNotAuthenticated()
{
return '<p>Sie wurden nicht angemeldet.</p><p>Um es erneut zu versuchen klicken Sie <a href="%s">hier</a>.</p><p>Wenn das Problem bestehen bleibt, kontkatieren Sie den <a href="mailto:%s">Administrator</a> dieser Seite.</p>';
return '<p>Sie wurden nicht angemeldet.</p><p>Um es erneut zu versuchen klicken Sie <a href="%s">hier</a>.</p><p>Wenn das Problem bestehen bleibt, kontaktieren Sie den <a href="mailto:%s">Administrator</a> dieser Seite.</p>';
}
/**
@@ -113,4 +113,4 @@ class CAS_Languages_German implements CAS_Languages_LanguageInterface
}
}
?>
?>
@@ -0,0 +1,56 @@
<?php
/**
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*
* Jasig licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* PHP Version 5
*
* @file CAS/OutOfSequenceBeforeAuthenticationCallException.php
* @category Authentication
* @package PhpCAS
* @author Joachim Fritschi <jfritschi@freenet.de>
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://wiki.jasig.org/display/CASC/phpCAS
*/
/**
* This class defines Exceptions that should be thrown when the sequence of
* operations is invalid. In this case it should be thrown when an
* authentication call has not yet happened.
*
* @class CAS_OutOfSequenceBeforeAuthenticationCallException
* @category Authentication
* @package PhpCAS
* @author Joachim Fritschi <jfritschi@freenet.de>
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://wiki.jasig.org/display/CASC/phpCAS
*/
class CAS_OutOfSequenceBeforeAuthenticationCallException
extends CAS_OutOfSequenceException
implements CAS_Exception
{
/**
* Return standard error meessage
*
* @return void
*/
public function __construct ()
{
parent::__construct('An authentication call hasn\'t happened yet.');
}
}
@@ -0,0 +1,58 @@
<?php
/**
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*
* Jasig licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* PHP Version 5
*
* @file CAS/OutOfSequenceBeforeClientException.php
* @category Authentication
* @package PhpCAS
* @author Joachim Fritschi <jfritschi@freenet.de>
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://wiki.jasig.org/display/CASC/phpCAS
*/
/**
* This class defines Exceptions that should be thrown when the sequence of
* operations is invalid. In this case it should be thrown when the client() or
* proxy() call has not yet happened and no client or proxy object exists.
*
* @class CAS_OutOfSequenceBeforeClientException
* @category Authentication
* @package PhpCAS
* @author Joachim Fritschi <jfritschi@freenet.de>
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://wiki.jasig.org/display/CASC/phpCAS
*/
class CAS_OutOfSequenceBeforeClientException
extends CAS_OutOfSequenceException
implements CAS_Exception
{
/**
* Return standard error message
*
* @return void
*/
public function __construct ()
{
parent::__construct(
'this method cannot be called before phpCAS::client() or phpCAS::proxy()'
);
}
}
@@ -0,0 +1,59 @@
<?php
/**
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*
* Jasig licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* PHP Version 5
*
* @file CAS/OutOfSequenceBeforeProxyException.php
* @category Authentication
* @package PhpCAS
* @author Joachim Fritschi <jfritschi@freenet.de>
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://wiki.jasig.org/display/CASC/phpCAS
*/
/**
* This class defines Exceptions that should be thrown when the sequence of
* operations is invalid. In this case it should be thrown when the proxy() call
* has not yet happened and no proxy object exists.
*
* @class CAS_OutOfSequenceBeforeProxyException
* @category Authentication
* @package PhpCAS
* @author Joachim Fritschi <jfritschi@freenet.de>
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://wiki.jasig.org/display/CASC/phpCAS
*/
class CAS_OutOfSequenceBeforeProxyException
extends CAS_OutOfSequenceException
implements CAS_Exception
{
/**
* Return standard error message
*
* @return void
*/
public function __construct ()
{
parent::__construct(
'this method cannot be called before phpCAS::proxy()'
);
}
}
@@ -68,7 +68,9 @@ abstract class CAS_PGTStorage_AbstractStorage
{
phpCAS::traceBegin();
if ( !$cas_parent->isProxy() ) {
phpCAS::error('defining PGT storage makes no sense when not using a CAS proxy');
phpCAS::error(
'defining PGT storage makes no sense when not using a CAS proxy'
);
}
phpCAS::traceEnd();
}
+20 -9
View File
@@ -135,8 +135,10 @@ class CAS_PGTStorage_Db extends CAS_PGTStorage_AbstractStorage
* @param string $driver_options any driver options to use when
* connecting to the database
*/
public function __construct($cas_parent, $dsn_or_pdo, $username='', $password='', $table='', $driver_options=null)
{
public function __construct(
$cas_parent, $dsn_or_pdo, $username='', $password='', $table='',
$driver_options=null
) {
phpCAS::traceBegin();
// call the ancestor's constructor
parent::__construct($cas_parent);
@@ -188,7 +190,10 @@ class CAS_PGTStorage_Db extends CAS_PGTStorage_AbstractStorage
// create the PDO object if it doesn't exist already
if (!($this->_pdo instanceof PDO)) {
try {
$this->_pdo = new PDO($this->_dsn, $this->_username, $this->_password, $this->_driver_options);
$this->_pdo = new PDO(
$this->_dsn, $this->_username, $this->_password,
$this->_driver_options
);
}
catch(PDOException $e) {
phpCAS::error('Database connection error: ' . $e->getMessage());
@@ -247,23 +252,28 @@ class CAS_PGTStorage_Db extends CAS_PGTStorage_AbstractStorage
*/
protected function createTableSql()
{
return 'CREATE TABLE ' . $this->_getTable() . ' (pgt_iou VARCHAR(255) NOT NULL PRIMARY KEY, pgt VARCHAR(255) NOT NULL)';
return 'CREATE TABLE ' . $this->_getTable()
. ' (pgt_iou VARCHAR(255) NOT NULL PRIMARY KEY, pgt VARCHAR(255) NOT NULL)';
}
/**
* This method returns the query used to store a pgt
*
* @return the store PGT SQL, :pgt and :pgt_iou are the bind params contained in the query
* @return the store PGT SQL, :pgt and :pgt_iou are the bind params contained
* in the query
*/
protected function storePgtSql()
{
return 'INSERT INTO ' . $this->_getTable() . ' (pgt_iou, pgt) VALUES (:pgt_iou, :pgt)';
return 'INSERT INTO ' . $this->_getTable()
. ' (pgt_iou, pgt) VALUES (:pgt_iou, :pgt)';
}
/**
* This method returns the query used to retrieve a pgt. the first column of the first row should contain the pgt
* This method returns the query used to retrieve a pgt. the first column
* of the first row should contain the pgt
*
* @return the retrieve PGT SQL, :pgt_iou is the only bind param contained in the query
* @return the retrieve PGT SQL, :pgt_iou is the only bind param contained
* in the query
*/
protected function retrievePgtSql()
{
@@ -273,7 +283,8 @@ class CAS_PGTStorage_Db extends CAS_PGTStorage_AbstractStorage
/**
* This method returns the query used to delete a pgt.
*
* @return the delete PGT SQL, :pgt_iou is the only bind param contained in the query
* @return the delete PGT SQL, :pgt_iou is the only bind param contained in
* the query
*/
protected function deletePgtSql()
{
+17 -6
View File
@@ -55,15 +55,20 @@ implements CAS_ProxiedService, CAS_ProxiedService_Testable
*
* @return void
* @throws InvalidArgumentException If the $proxyTicket is invalid.
* @throws CAS_OutOfSequenceException If called after a proxy ticket has already been initialized/set.
* @throws CAS_OutOfSequenceException If called after a proxy ticket has
* already been initialized/set.
*/
public function setProxyTicket ($proxyTicket)
{
if (empty($proxyTicket)) {
throw new CAS_InvalidArgumentException("Trying to initialize with an empty proxy ticket.");
throw new CAS_InvalidArgumentException(
'Trying to initialize with an empty proxy ticket.'
);
}
if (!empty($this->_proxyTicket)) {
throw new CAS_OutOfSequenceException('Already initialized, cannot change the proxy ticket.');
throw new CAS_OutOfSequenceException(
'Already initialized, cannot change the proxy ticket.'
);
}
$this->_proxyTicket = $proxyTicket;
}
@@ -78,7 +83,9 @@ implements CAS_ProxiedService, CAS_ProxiedService_Testable
protected function getProxyTicket ()
{
if (empty($this->_proxyTicket)) {
throw new CAS_OutOfSequenceException('No proxy ticket yet. Call $this->initializeProxyTicket() to aquire the proxy ticket.');
throw new CAS_OutOfSequenceException(
'No proxy ticket yet. Call $this->initializeProxyTicket() to aquire the proxy ticket.'
);
}
return $this->_proxyTicket;
@@ -105,7 +112,9 @@ implements CAS_ProxiedService, CAS_ProxiedService_Testable
public function setCasClient (CAS_Client $casClient)
{
if (!empty($this->_proxyTicket)) {
throw new CAS_OutOfSequenceException('Already initialized, cannot change the CAS_Client.');
throw new CAS_OutOfSequenceException(
'Already initialized, cannot change the CAS_Client.'
);
}
$this->_casClient = $casClient;
@@ -124,7 +133,9 @@ implements CAS_ProxiedService, CAS_ProxiedService_Testable
protected function initializeProxyTicket()
{
if (!empty($this->_proxyTicket)) {
throw new CAS_OutOfSequenceException('Already initialized, cannot initialize again.');
throw new CAS_OutOfSequenceException(
'Already initialized, cannot initialize again.'
);
}
// Allow usage of a particular CAS_Client for unit testing.
if (empty($this->_casClient)) {
@@ -38,9 +38,8 @@
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://wiki.jasig.org/display/CASC/phpCAS
*/
abstract class CAS_ProxiedService_Http_Abstract
extends CAS_ProxiedService_Abstract
implements CAS_ProxiedService_Http
abstract class CAS_ProxiedService_Http_Abstract extends
CAS_ProxiedService_Abstract implements CAS_ProxiedService_Http
{
/**
* The HTTP request mechanism talking to the target service.
@@ -64,8 +63,9 @@ implements CAS_ProxiedService_Http
*
* @return void
*/
public function __construct (CAS_Request_RequestInterface $requestHandler, CAS_CookieJar $cookieJar)
{
public function __construct(CAS_Request_RequestInterface $requestHandler,
CAS_CookieJar $cookieJar
) {
$this->requestHandler = $requestHandler;
$this->_cookieJar = $cookieJar;
}
@@ -82,10 +82,12 @@ implements CAS_ProxiedService_Http
* @return string
* @throws Exception If no service url is available.
*/
public function getServiceUrl ()
public function getServiceUrl()
{
if (empty($this->_url)) {
throw new CAS_ProxiedService_Exception('No URL set via '.get_class($this).'->setUrl($url).');
throw new CAS_ProxiedService_Exception(
'No URL set via ' . get_class($this) . '->setUrl($url).'
);
}
return $this->_url;
@@ -93,7 +95,7 @@ implements CAS_ProxiedService_Http
/*********************************************************
* Configure the Request
*********************************************************/
*********************************************************/
/**
* Set the URL of the Request
@@ -103,10 +105,12 @@ implements CAS_ProxiedService_Http
* @return void
* @throws CAS_OutOfSequenceException If called after the Request has been sent.
*/
public function setUrl ($url)
public function setUrl($url)
{
if ($this->hasBeenSent()) {
throw new CAS_OutOfSequenceException('Cannot set the URL, request already sent.');
throw new CAS_OutOfSequenceException(
'Cannot set the URL, request already sent.'
);
}
if (!is_string($url)) {
throw new CAS_InvalidArgumentException('$url must be a string.');
@@ -117,7 +121,7 @@ implements CAS_ProxiedService_Http
/*********************************************************
* 2. Send the Request
*********************************************************/
*********************************************************/
/**
* Perform the request.
@@ -132,10 +136,12 @@ implements CAS_ProxiedService_Http
* @throws CAS_ProxiedService_Exception If there is a failure sending the
* request to the target service.
*/
public function send ()
public function send()
{
if ($this->hasBeenSent()) {
throw new CAS_OutOfSequenceException('Cannot send, request already sent.');
throw new CAS_OutOfSequenceException(
'Cannot send, request already sent.'
);
}
phpCAS::traceBegin();
@@ -144,9 +150,9 @@ implements CAS_ProxiedService_Http
$this->initializeProxyTicket();
$url = $this->getServiceUrl();
if (strstr($url, '?') === false) {
$url = $url.'?ticket='.$this->getProxyTicket();
$url = $url . '?ticket=' . $this->getProxyTicket();
} else {
$url = $url.'&ticket='.$this->getProxyTicket();
$url = $url . '&ticket=' . $this->getProxyTicket();
}
try {
@@ -199,7 +205,7 @@ implements CAS_ProxiedService_Http
* @throws CAS_ProxiedService_Exception If there is a failure sending the
* request to the target service.
*/
protected function makeRequest ($url)
protected function makeRequest($url)
{
// Verify that we are not in a redirect loop
$this->_numRequests++;
@@ -220,9 +226,10 @@ implements CAS_ProxiedService_Http
$this->populateRequest($request);
// Perform the request.
phpCAS::trace('Performing proxied service request to \''.$url.'\'');
phpCAS::trace('Performing proxied service request to \'' . $url . '\'');
if (!$request->send()) {
$message = 'Could not perform proxied service request to URL`'.$url.'\'. '.$request->getErrorMessage();
$message = 'Could not perform proxied service request to URL`'
. $url . '\'. ' . $request->getErrorMessage();
phpCAS::trace($message);
throw new CAS_ProxiedService_Exception($message);
}
@@ -231,8 +238,9 @@ implements CAS_ProxiedService_Http
$this->_cookieJar->storeCookies($url, $request->getResponseHeaders());
// Follow any redirects
if ($redirectUrl = $this->getRedirectUrl($request->getResponseHeaders())) {
phpCAS :: trace('Found redirect:'.$redirectUrl);
if ($redirectUrl = $this->getRedirectUrl($request->getResponseHeaders())
) {
phpCAS::trace('Found redirect:' . $redirectUrl);
$this->makeRequest($redirectUrl);
} else {
@@ -249,7 +257,9 @@ implements CAS_ProxiedService_Http
*
* @return void
*/
abstract protected function populateRequest (CAS_Request_RequestInterface $request);
abstract protected function populateRequest(
CAS_Request_RequestInterface $request
);
/**
* Answer a redirect URL if a redirect header is found, otherwise null.
@@ -258,11 +268,12 @@ implements CAS_ProxiedService_Http
*
* @return string or null
*/
protected function getRedirectUrl (array $responseHeaders)
protected function getRedirectUrl(array $responseHeaders)
{
// Check for the redirect after authentication
foreach ($responseHeaders as $header) {
if (preg_match('/^(Location:|URI:)\s*([^\s]+.*)$/', $header, $matches)) {
if ( preg_match('/^(Location:|URI:)\s*([^\s]+.*)$/', $header, $matches)
) {
return trim(array_pop($matches));
}
}
@@ -271,14 +282,14 @@ implements CAS_ProxiedService_Http
/*********************************************************
* 3. Access the response
*********************************************************/
*********************************************************/
/**
* Answer true if our request has been sent yet.
*
* @return bool
*/
protected function hasBeenSent ()
protected function hasBeenSent()
{
return ($this->_numRequests > 0);
}
@@ -289,10 +300,12 @@ implements CAS_ProxiedService_Http
* @return array An array of header strings.
* @throws CAS_OutOfSequenceException If called before the Request has been sent.
*/
public function getResponseHeaders ()
public function getResponseHeaders()
{
if (!$this->hasBeenSent()) {
throw new CAS_OutOfSequenceException('Cannot access response, request not sent yet.');
throw new CAS_OutOfSequenceException(
'Cannot access response, request not sent yet.'
);
}
return $this->_responseHeaders;
@@ -304,10 +317,12 @@ implements CAS_ProxiedService_Http
* @return int
* @throws CAS_OutOfSequenceException If called before the Request has been sent.
*/
public function getResponseStatusCode ()
public function getResponseStatusCode()
{
if (!$this->hasBeenSent()) {
throw new CAS_OutOfSequenceException('Cannot access response, request not sent yet.');
throw new CAS_OutOfSequenceException(
'Cannot access response, request not sent yet.'
);
}
return $this->_responseStatusCode;
@@ -319,10 +334,12 @@ implements CAS_ProxiedService_Http
* @return string
* @throws CAS_OutOfSequenceException If called before the Request has been sent.
*/
public function getResponseBody ()
public function getResponseBody()
{
if (!$this->hasBeenSent()) {
throw new CAS_OutOfSequenceException('Cannot access response, request not sent yet.');
throw new CAS_OutOfSequenceException(
'Cannot access response, request not sent yet.'
);
}
return $this->_responseBody;
@@ -334,7 +351,7 @@ implements CAS_ProxiedService_Http
*
* @return array An array containing cookies. E.g. array('name' => 'val');
*/
public function getCookies ()
public function getCookies()
{
return $this->_cookieJar->getCookies($this->getServiceUrl());
}
+24 -23
View File
@@ -32,30 +32,31 @@
*
* Usage Example:
*
* try {
* $service = phpCAS::getProxiedService(PHPCAS_PROXIED_SERVICE_HTTP_GET);
* $service->setUrl('http://www.example.com/path/');
* $service->send();
* if ($service->getResponseStatusCode() == 200)
* return $service->getResponseBody();
* else
* // The service responded with an error code 404, 500, etc.
* throw new Exception('The service responded with an error.');
* try {
* $service = phpCAS::getProxiedService(PHPCAS_PROXIED_SERVICE_HTTP_GET);
* $service->setUrl('http://www.example.com/path/');
* $service->send();
* if ($service->getResponseStatusCode() == 200)
* return $service->getResponseBody();
* else
* // The service responded with an error code 404, 500, etc.
* throw new Exception('The service responded with an error.');
*
* } catch (CAS_ProxyTicketException $e) {
* if ($e->getCode() == PHPCAS_SERVICE_PT_FAILURE)
* return "Your login has timed out. You need to log in again.";
* else
* // Other proxy ticket errors are from bad request format (shouldn't happen)
* // or CAS server failure (unlikely) so lets just stop if we hit those.
* throw $e;
* } catch (CAS_ProxiedService_Exception $e) {
* // Something prevented the service request from being sent or received.
* // We didn't even get a valid error response (404, 500, etc), so this
* // might be caused by a network error or a DNS resolution failure.
* // We could handle it in some way, but for now we will just stop.
* throw $e;
* }
* } catch (CAS_ProxyTicketException $e) {
* if ($e->getCode() == PHPCAS_SERVICE_PT_FAILURE)
* return "Your login has timed out. You need to log in again.";
* else
* // Other proxy ticket errors are from bad request format
* // (shouldn't happen) or CAS server failure (unlikely)
* // so lets just stop if we hit those.
* throw $e;
* } catch (CAS_ProxiedService_Exception $e) {
* // Something prevented the service request from being sent or received.
* // We didn't even get a valid error response (404, 500, etc), so this
* // might be caused by a network error or a DNS resolution failure.
* // We could handle it in some way, but for now we will just stop.
* throw $e;
* }
*
* @class CAS_ProxiedService_Http_Get
* @category Authentication
+36 -28
View File
@@ -32,32 +32,33 @@
*
* Usage Example:
*
* try {
* $service = phpCAS::getProxiedService(PHPCAS_PROXIED_SERVICE_HTTP_POST);
* $service->setUrl('http://www.example.com/path/');
* $service->setContentType('text/xml');
* $service->setBody(''<?xml version="1.0"?'.'><methodCall><methodName>example.search</methodName></methodCall>');
* $service->send();
* if ($service->getResponseStatusCode() == 200)
* return $service->getResponseBody();
* else
* // The service responded with an error code 404, 500, etc.
* throw new Exception('The service responded with an error.');
* try {
* $service = phpCAS::getProxiedService(PHPCAS_PROXIED_SERVICE_HTTP_POST);
* $service->setUrl('http://www.example.com/path/');
* $service->setContentType('text/xml');
* $service->setBody('<?xml version="1.0"?'.'><methodCall><methodName>example.search</methodName></methodCall>');
* $service->send();
* if ($service->getResponseStatusCode() == 200)
* return $service->getResponseBody();
* else
* // The service responded with an error code 404, 500, etc.
* throw new Exception('The service responded with an error.');
*
* } catch (CAS_ProxyTicketException $e) {
* if ($e->getCode() == PHPCAS_SERVICE_PT_FAILURE)
* return "Your login has timed out. You need to log in again.";
* else
* // Other proxy ticket errors are from bad request format (shouldn't happen)
* // or CAS server failure (unlikely) so lets just stop if we hit those.
* throw $e;
* } catch (CAS_ProxiedService_Exception $e) {
* // Something prevented the service request from being sent or received.
* // We didn't even get a valid error response (404, 500, etc), so this
* // might be caused by a network error or a DNS resolution failure.
* // We could handle it in some way, but for now we will just stop.
* throw $e;
* }
* } catch (CAS_ProxyTicketException $e) {
* if ($e->getCode() == PHPCAS_SERVICE_PT_FAILURE)
* return "Your login has timed out. You need to log in again.";
* else
* // Other proxy ticket errors are from bad request format
* // (shouldn't happen) or CAS server failure (unlikely) so lets just
* // stop if we hit those.
* throw $e;
* } catch (CAS_ProxiedService_Exception $e) {
* // Something prevented the service request from being sent or received.
* // We didn't even get a valid error response (404, 500, etc), so this
* // might be caused by a network error or a DNS resolution failure.
* // We could handle it in some way, but for now we will just stop.
* throw $e;
* }
*
* @class CAS_ProxiedService_Http_Post
* @category Authentication
@@ -95,7 +96,9 @@ extends CAS_ProxiedService_Http_Abstract
public function setContentType ($contentType)
{
if ($this->hasBeenSent()) {
throw new CAS_OutOfSequenceException('Cannot set the content type, request already sent.');
throw new CAS_OutOfSequenceException(
'Cannot set the content type, request already sent.'
);
}
$this->_contentType = $contentType;
@@ -112,7 +115,9 @@ extends CAS_ProxiedService_Http_Abstract
public function setBody ($body)
{
if ($this->hasBeenSent()) {
throw new CAS_OutOfSequenceException('Cannot set the body, request already sent.');
throw new CAS_OutOfSequenceException(
'Cannot set the body, request already sent.'
);
}
$this->_body = $body;
@@ -128,7 +133,10 @@ extends CAS_ProxiedService_Http_Abstract
protected function populateRequest (CAS_Request_RequestInterface $request)
{
if (empty($this->_contentType) && !empty($this->_body)) {
throw new CAS_ProxiedService_Exception("If you pass a POST body, you must specify a content type via ".get_class($this).'->setContentType($contentType).');
throw new CAS_ProxiedService_Exception(
"If you pass a POST body, you must specify a content type via "
.get_class($this).'->setContentType($contentType).'
);
}
$request->makePost();
+30 -10
View File
@@ -79,7 +79,9 @@ extends CAS_ProxiedService_Abstract
public function getServiceUrl ()
{
if (empty($this->_url)) {
throw new CAS_ProxiedService_Exception('No URL set via '.get_class($this).'->getServiceUrl($url).');
throw new CAS_ProxiedService_Exception(
'No URL set via '.get_class($this).'->getServiceUrl($url).'
);
}
return $this->_url;
@@ -100,7 +102,9 @@ extends CAS_ProxiedService_Abstract
public function setServiceUrl ($url)
{
if ($this->hasBeenOpened()) {
throw new CAS_OutOfSequenceException('Cannot set the URL, stream already opened.');
throw new CAS_OutOfSequenceException(
'Cannot set the URL, stream already opened.'
);
}
if (!is_string($url) || !strlen($url)) {
throw new CAS_InvalidArgumentException('Invalid url.');
@@ -127,7 +131,9 @@ extends CAS_ProxiedService_Abstract
public function setMailbox ($mailbox)
{
if ($this->hasBeenOpened()) {
throw new CAS_OutOfSequenceException('Cannot set the mailbox, stream already opened.');
throw new CAS_OutOfSequenceException(
'Cannot set the mailbox, stream already opened.'
);
}
if (!is_string($mailbox) || !strlen($mailbox)) {
throw new CAS_InvalidArgumentException('Invalid mailbox.');
@@ -155,7 +161,9 @@ extends CAS_ProxiedService_Abstract
public function setOptions ($options)
{
if ($this->hasBeenOpened()) {
throw new CAS_OutOfSequenceException('Cannot set options, stream already opened.');
throw new CAS_OutOfSequenceException(
'Cannot set options, stream already opened.'
);
}
if (!is_int($options)) {
throw new CAS_InvalidArgumentException('Invalid options.');
@@ -178,14 +186,19 @@ extends CAS_ProxiedService_Abstract
* PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE
* PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE
* PHPCAS_SERVICE_PT_FAILURE
* @throws CAS_ProxiedService_Exception If there is a failure sending the request to the target service. */
* @throws CAS_ProxiedService_Exception If there is a failure sending the
* request to the target service.
*/
public function open ()
{
if ($this->hasBeenOpened()) {
throw new CAS_OutOfSequenceException('Stream already opened.');
}
if (empty($this->_mailbox)) {
throw new CAS_ProxiedService_Exception('You must specify a mailbox via '.get_class($this).'->setMailbox($mailbox)');
throw new CAS_ProxiedService_Exception(
'You must specify a mailbox via '.get_class($this)
.'->setMailbox($mailbox)'
);
}
phpCAS::traceBegin();
@@ -193,13 +206,16 @@ extends CAS_ProxiedService_Abstract
// Get our proxy ticket and append it to our URL.
$this->initializeProxyTicket();
phpCAS::trace('opening IMAP mailbox `'.$this->_mailbox.'\'...');
$this->_stream = @imap_open($this->_mailbox, $this->_username, $this->getProxyTicket(), $this->_options);
$this->_stream = @imap_open(
$this->_mailbox, $this->_username, $this->getProxyTicket(),
$this->_options
);
if ($this->_stream) {
phpCAS::trace('ok');
} else {
phpCAS::trace('could not open mailbox');
// @todo add localization integration.
$message = 'IMAP Error: '.$url.' '. var_export(imap_errors(), true);
$message = 'IMAP Error: '.$this->_url.' '. var_export(imap_errors(), true);
phpCAS::trace($message);
throw new CAS_ProxiedService_Exception($message);
}
@@ -236,7 +252,9 @@ extends CAS_ProxiedService_Abstract
public function getStream ()
{
if (!$this->hasBeenOpened()) {
throw new CAS_OutOfSequenceException('Cannot access stream, not opened yet.');
throw new CAS_OutOfSequenceException(
'Cannot access stream, not opened yet.'
);
}
return $this->_stream;
}
@@ -252,7 +270,9 @@ extends CAS_ProxiedService_Abstract
public function getImapProxyTicket ()
{
if (!$this->hasBeenOpened()) {
throw new CAS_OutOfSequenceException('Cannot access errors, stream not opened yet.');
throw new CAS_OutOfSequenceException(
'Cannot access errors, stream not opened yet.'
);
}
return $this->getProxyTicket();
}
+5 -3
View File
@@ -31,8 +31,9 @@
* This interface defines methods that allow proxy-authenticated service handlers
* to be tested in unit tests.
*
* Classes implementing this interface SHOULD store the CAS_Client passed and initialize
* themselves with that client rather than via the static phpCAS method. For example:
* Classes implementing this interface SHOULD store the CAS_Client passed and
* initialize themselves with that client rather than via the static phpCAS
* method. For example:
*
* / **
* * Fetch our proxy ticket.
@@ -65,7 +66,8 @@ interface CAS_ProxiedService_Testable
* @param CAS_Client $casClient Cas client object
*
* @return void
* @throws CAS_OutOfSequenceException If called after a proxy ticket has already been initialized/set.
* @throws CAS_OutOfSequenceException If called after a proxy ticket has
* already been initialized/set.
*/
public function setCasClient (CAS_Client $casClient);
+14 -5
View File
@@ -59,7 +59,8 @@ implements CAS_ProxyChain_Interface
*/
public function __construct(array $chain)
{
$this->chain = array_values($chain); // Ensure that we have an indexed array
// Ensure that we have an indexed array
$this->chain = array_values($chain);
}
/**
@@ -78,17 +79,25 @@ implements CAS_ProxyChain_Interface
$proxy_url = $list[$i];
if (preg_match('/^\/.*\/[ixASUXu]*$/s', $search)) {
if (preg_match($search, $proxy_url)) {
phpCAS::trace("Found regexp " . $search . " matching " . $proxy_url);
phpCAS::trace(
"Found regexp " . $search . " matching " . $proxy_url
);
} else {
phpCAS::trace("No regexp match " . $search . " != " . $proxy_url);
phpCAS::trace(
"No regexp match " . $search . " != " . $proxy_url
);
$mismatch = true;
break;
}
} else {
if (strncasecmp($search, $proxy_url, strlen($search)) == 0) {
phpCAS::trace("Found string " . $search . " matching " . $proxy_url);
phpCAS::trace(
"Found string " . $search . " matching " . $proxy_url
);
} else {
phpCAS::trace("No match " . $search . " != " . $proxy_url);
phpCAS::trace(
"No match " . $search . " != " . $proxy_url
);
$mismatch = true;
break;
}
+4 -1
View File
@@ -60,7 +60,10 @@ implements CAS_Exception
PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE,
);
if (!in_array($code, $ptCodes)) {
trigger_error('Invalid code '.$code.' passed. Must be one of PHPCAS_SERVICE_PT_FAILURE, PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, or PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE.');
trigger_error(
'Invalid code '.$code
.' passed. Must be one of PHPCAS_SERVICE_PT_FAILURE, PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, or PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE.'
);
}
parent::__construct($message, $code);
+53 -17
View File
@@ -68,7 +68,9 @@ implements CAS_Request_RequestInterface
public function setUrl ($url)
{
if ($this->_sent) {
throw new CAS_OutOfSequenceException('Request has already been sent cannot '.__METHOD__);
throw new CAS_OutOfSequenceException(
'Request has already been sent cannot '.__METHOD__
);
}
$this->url = $url;
@@ -86,7 +88,9 @@ implements CAS_Request_RequestInterface
public function addCookie ($name, $value)
{
if ($this->_sent) {
throw new CAS_OutOfSequenceException('Request has already been sent cannot '.__METHOD__);
throw new CAS_OutOfSequenceException(
'Request has already been sent cannot '.__METHOD__
);
}
$this->cookies[$name] = $value;
@@ -105,7 +109,9 @@ implements CAS_Request_RequestInterface
public function addCookies (array $cookies)
{
if ($this->_sent) {
throw new CAS_OutOfSequenceException('Request has already been sent cannot '.__METHOD__);
throw new CAS_OutOfSequenceException(
'Request has already been sent cannot '.__METHOD__
);
}
$this->cookies = array_merge($this->cookies, $cookies);
@@ -122,7 +128,9 @@ implements CAS_Request_RequestInterface
public function addHeader ($header)
{
if ($this->_sent) {
throw new CAS_OutOfSequenceException('Request has already been sent cannot '.__METHOD__);
throw new CAS_OutOfSequenceException(
'Request has already been sent cannot '.__METHOD__
);
}
$this->headers[] = $header;
@@ -139,7 +147,9 @@ implements CAS_Request_RequestInterface
public function addHeaders (array $headers)
{
if ($this->_sent) {
throw new CAS_OutOfSequenceException('Request has already been sent cannot '.__METHOD__);
throw new CAS_OutOfSequenceException(
'Request has already been sent cannot '.__METHOD__
);
}
$this->headers = array_merge($this->headers, $headers);
@@ -154,7 +164,9 @@ implements CAS_Request_RequestInterface
public function makePost ()
{
if ($this->_sent) {
throw new CAS_OutOfSequenceException('Request has already been sent cannot '.__METHOD__);
throw new CAS_OutOfSequenceException(
'Request has already been sent cannot '.__METHOD__
);
}
$this->isPost = true;
@@ -171,10 +183,14 @@ implements CAS_Request_RequestInterface
public function setPostBody ($body)
{
if ($this->_sent) {
throw new CAS_OutOfSequenceException('Request has already been sent cannot '.__METHOD__);
throw new CAS_OutOfSequenceException(
'Request has already been sent cannot '.__METHOD__
);
}
if (!$this->isPost) {
throw new CAS_OutOfSequenceException('Cannot add a POST body to a GET request, use makePost() first.');
throw new CAS_OutOfSequenceException(
'Cannot add a POST body to a GET request, use makePost() first.'
);
}
$this->postBody = $body;
@@ -192,7 +208,9 @@ implements CAS_Request_RequestInterface
public function setSslCaCert ($caCertPath,$validate_cn=true)
{
if ($this->_sent) {
throw new CAS_OutOfSequenceException('Request has already been sent cannot '.__METHOD__);
throw new CAS_OutOfSequenceException(
'Request has already been sent cannot '.__METHOD__
);
}
$this->caCertPath = $caCertPath;
$this->validateCN = $validate_cn;
@@ -211,10 +229,14 @@ implements CAS_Request_RequestInterface
public function send ()
{
if ($this->_sent) {
throw new CAS_OutOfSequenceException('Request has already been sent cannot send again.');
throw new CAS_OutOfSequenceException(
'Request has already been sent cannot send again.'
);
}
if (is_null($this->url) || !$this->url) {
throw new CAS_OutOfSequenceException('A url must be specified via setUrl() before the request can be sent.');
throw new CAS_OutOfSequenceException(
'A url must be specified via setUrl() before the request can be sent.'
);
}
$this->_sent = true;
return $this->sendRequest();
@@ -288,7 +310,9 @@ implements CAS_Request_RequestInterface
public function getResponseHeaders ()
{
if (!$this->_sent) {
throw new CAS_OutOfSequenceException('Request has not been sent yet. Cannot '.__METHOD__);
throw new CAS_OutOfSequenceException(
'Request has not been sent yet. Cannot '.__METHOD__
);
}
return $this->_responseHeaders;
}
@@ -302,11 +326,19 @@ implements CAS_Request_RequestInterface
public function getResponseStatusCode ()
{
if (!$this->_sent) {
throw new CAS_OutOfSequenceException('Request has not been sent yet. Cannot '.__METHOD__);
throw new CAS_OutOfSequenceException(
'Request has not been sent yet. Cannot '.__METHOD__
);
}
if (!preg_match('/HTTP\/[0-9.]+\s+([0-9]+)\s*(.*)/', $this->_responseHeaders[0], $matches)) {
throw new CAS_Request_Exception("Bad response, no status code was found in the first line.");
if (!preg_match(
'/HTTP\/[0-9.]+\s+([0-9]+)\s*(.*)/',
$this->_responseHeaders[0], $matches
)
) {
throw new CAS_Request_Exception(
'Bad response, no status code was found in the first line.'
);
}
return intval($matches[1]);
@@ -321,7 +353,9 @@ implements CAS_Request_RequestInterface
public function getResponseBody ()
{
if (!$this->_sent) {
throw new CAS_OutOfSequenceException('Request has not been sent yet. Cannot '.__METHOD__);
throw new CAS_OutOfSequenceException(
'Request has not been sent yet. Cannot '.__METHOD__
);
}
return $this->_responseBody;
@@ -336,7 +370,9 @@ implements CAS_Request_RequestInterface
public function getErrorMessage ()
{
if (!$this->_sent) {
throw new CAS_OutOfSequenceException('Request has not been sent yet. Cannot '.__METHOD__);
throw new CAS_OutOfSequenceException(
'Request has not been sent yet. Cannot '.__METHOD__
);
}
return $this->_errorMessage;
}
+15 -5
View File
@@ -64,10 +64,14 @@ implements CAS_Request_MultiRequestInterface
public function addRequest (CAS_Request_RequestInterface $request)
{
if ($this->_sent) {
throw new CAS_OutOfSequenceException('Request has already been sent cannot '.__METHOD__);
throw new CAS_OutOfSequenceException(
'Request has already been sent cannot '.__METHOD__
);
}
if (!$request instanceof CAS_Request_CurlRequest) {
throw new CAS_InvalidArgumentException('As a CAS_Request_CurlMultiRequest, I can only work with CAS_Request_CurlRequest objects.');
throw new CAS_InvalidArgumentException(
'As a CAS_Request_CurlMultiRequest, I can only work with CAS_Request_CurlRequest objects.'
);
}
$this->_requests[] = $request;
@@ -81,7 +85,9 @@ implements CAS_Request_MultiRequestInterface
public function getNumRequests()
{
if ($this->_sent) {
throw new CAS_OutOfSequenceException('Request has already been sent cannot '.__METHOD__);
throw new CAS_OutOfSequenceException(
'Request has already been sent cannot '.__METHOD__
);
}
return count($this->_requests);
}
@@ -100,10 +106,14 @@ implements CAS_Request_MultiRequestInterface
public function send ()
{
if ($this->_sent) {
throw new CAS_OutOfSequenceException('Request has already been sent cannot send again.');
throw new CAS_OutOfSequenceException(
'Request has already been sent cannot send again.'
);
}
if (!count($this->_requests)) {
throw new CAS_OutOfSequenceException('At least one request must be added via addRequest() before the multi-request can be sent.');
throw new CAS_OutOfSequenceException(
'At least one request must be added via addRequest() before the multi-request can be sent.'
);
}
$this->_sent = true;
+4 -2
View File
@@ -75,7 +75,9 @@ implements CAS_Request_RequestInterface
$buf = curl_exec($ch);
if ( $buf === false ) {
phpCAS::trace('curl_exec() failed');
$this->storeErrorMessage('CURL error #'.curl_errno($ch).': '.curl_error($ch));
$this->storeErrorMessage(
'CURL error #'.curl_errno($ch).': '.curl_error($ch)
);
$res = false;
} else {
$this->storeResponseBody($buf);
@@ -120,7 +122,7 @@ implements CAS_Request_RequestInterface
if ($this->validateCN) {
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
} else {
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
}
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_CAINFO, $this->caCertPath);
@@ -0,0 +1,70 @@
<?php
/**
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*
* Jasig licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* PHP Version 5
*
* @file CAS/InvalidArgumentException.php
* @category Authentication
* @package PhpCAS
* @author Adam Franco <afranco@middlebury.edu>
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://wiki.jasig.org/display/CASC/phpCAS
*/
/**
* Exception that denotes invalid arguments were passed.
*
* @class CAS_InvalidArgumentException
* @category Authentication
* @package PhpCAS
* @author Adam Franco <afranco@middlebury.edu>
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://wiki.jasig.org/display/CASC/phpCAS
*/
class CAS_TypeMismatchException
extends CAS_InvalidArgumentException
{
/**
* Constructor, provides a nice message.
*
* @param mixed $argument Argument
* @param string $argumentName Argument Name
* @param string $type Type
* @param string $message Error Message
* @param integer $code Code
*
* @return void
*/
public function __construct (
$argument, $argumentName, $type, $message = '', $code = 0
) {
if (is_object($argument)) {
$foundType = get_class($argument).' object';
} else {
$foundType = gettype($argument);
}
parent::__construct(
'type mismatched for parameter '
. $argumentName . ' (should be \'' . $type .' \'), '
. $foundType . ' given. ' . $message, $code
);
}
}
?>
+2 -2
View File
@@ -1,5 +1,5 @@
Description of phpCAS 1.3.2 library import
Description of phpCAS 1.3.3 library import
* downloaded from http://downloads.jasig.org/cas-clients/php/current/
iarenaza
merrill
+39 -25
View File
@@ -111,6 +111,26 @@ class auth_plugin_cas extends auth_plugin_ldap {
return;
}
// If the multi-authentication setting is used, check for the param before connecting to CAS.
if ($this->config->multiauth) {
$authCAS = optional_param('authCAS', '', PARAM_RAW);
if ($authCAS == 'NOCAS') {
return;
}
// Show authentication form for multi-authentication.
// Test pgtIou parameter for proxy mode (https connection in background from CAS server to the php server).
if ($authCAS != 'CAS' && !isset($_GET['pgtIou'])) {
$PAGE->set_url('/login/index.php');
$PAGE->navbar->add($CASform);
$PAGE->set_title("$site->fullname: $CASform");
$PAGE->set_heading($site->fullname);
echo $OUTPUT->header();
include($CFG->dirroot.'/auth/cas/cas_form.html');
echo $OUTPUT->footer();
exit();
}
}
// Connection to CAS server
$this->connectCAS();
@@ -134,27 +154,6 @@ class auth_plugin_cas extends auth_plugin_ldap {
return;
}
if ($this->config->multiauth) {
$authCAS = optional_param('authCAS', '', PARAM_RAW);
if ($authCAS == 'NOCAS') {
return;
}
// Show authentication form for multi-authentication
// test pgtIou parameter for proxy mode (https connection
// in background from CAS server to the php server)
if ($authCAS != 'CAS' && !isset($_GET['pgtIou'])) {
$PAGE->set_url('/login/index.php');
$PAGE->navbar->add($CASform);
$PAGE->set_title("$site->fullname: $CASform");
$PAGE->set_heading($site->fullname);
echo $OUTPUT->header();
include($CFG->dirroot.'/auth/cas/cas_form.html');
echo $OUTPUT->footer();
exit();
}
}
// Force CAS authentication (if needed).
if (!phpCAS::isAuthenticated()) {
phpCAS::setLang($this->config->language);
@@ -167,12 +166,27 @@ class auth_plugin_cas extends auth_plugin_ldap {
*
*/
function prelogout_hook() {
global $CFG;
global $CFG, $USER, $DB;
if (!empty($this->config->logoutcas)) {
$backurl = $CFG->wwwroot;
if (!empty($this->config->logoutcas) && $USER->auth == $this->authtype) {
$backurl = !empty($this->config->logout_return_url) ? $this->config->logout_return_url : $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);
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
<location>CAS</location>
<name>CAS</name>
<license>BSD</license>
<version>1.3.2</version>
<version>1.3.3</version>
<licenseversion></licenseversion>
</library>
</libraries>
+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;
+1 -1
View File
@@ -125,7 +125,7 @@ $string['notcalledfromserver'] = 'Should not be called from the web server!';
$string['noupdatestobedone'] = "No updates to be done\n";
$string['nouserentriestoremove'] = "No user entries to be removed\n";
$string['nouserentriestorevive'] = "No user entries to be revived\n";
$string['nouserstobeadded'] = "No users to be added\n";
$string['nouserstobeadded'] = 'No user entries to be added';
$string['ntlmsso_attempting'] = 'Attempting Single Sign On via NTLM...';
$string['ntlmsso_failed'] = 'Auto-login failed, try the normal login page...';
$string['ntlmsso_isdisabled'] = 'NTLM SSO is disabled.';
+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
@@ -159,7 +159,7 @@ class backup_xml_transformer extends xml_contenttransformer {
// Add the module ones. Each module supporting moodle2 backups MUST have it
$mods = core_component::get_plugin_list('mod');
foreach ($mods as $mod => $moddir) {
if (plugin_supports('mod', $mod, FEATURE_BACKUP_MOODLE2)) {
if (plugin_supports('mod', $mod, FEATURE_BACKUP_MOODLE2) && class_exists('backup_' . $mod . '_activity_task')) {
$encoders['backup_' . $mod . '_activity_task'] = 'encode_content_links';
}
}
+105 -52
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
}
@@ -1401,11 +1401,14 @@ class restore_course_structure_step extends restore_structure_step {
$data->fullname = $fullname;
$data->shortname= $shortname;
// Only allow the idnumber to be set if the user has permission and the idnumber is not already in use by
// another course on this site.
$context = context::instance_by_id($this->task->get_contextid());
if (has_capability('moodle/course:changeidnumber', $context, $this->task->get_userid())) {
$data->idnumber = '';
if (!empty($data->idnumber) && has_capability('moodle/course:changeidnumber', $context, $this->task->get_userid()) &&
$this->task->is_samesite() && !$DB->record_exists('course', array('idnumber' => $data->idnumber))) {
// Do not reset idnumber.
} else {
unset($data->idnumber);
$data->idnumber = '';
}
// Any empty value for course->hiddensections will lead to 0 (default, show collapsed).
@@ -2537,7 +2540,14 @@ class restore_course_logs_structure_step extends restore_structure_step {
// If we have data, insert it, else something went wrong in the restore_logs_processor
if ($data) {
$DB->insert_record('log', $data);
if (empty($data->url)) {
$data->url = '';
}
if (empty($data->info)) {
$data->info = '';
}
add_to_log($data->course, $data->module, $data->action, $data->url, $data->info,
$data->cmid, $data->userid);
}
}
}
@@ -2575,7 +2585,14 @@ class restore_activity_logs_structure_step extends restore_course_logs_structure
// If we have data, insert it, else something went wrong in the restore_logs_processor
if ($data) {
$DB->insert_record('log', $data);
if (empty($data->url)) {
$data->url = '';
}
if (empty($data->info)) {
$data->info = '';
}
add_to_log($data->course, $data->module, $data->action, $data->url, $data->info,
$data->cmid, $data->userid);
}
}
}
@@ -3558,13 +3575,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 +3592,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();
@@ -89,11 +89,11 @@ class restore_logs_processor {
}
// Arrived here log is empty, no rule was able to perform the conversion, log the problem
if (empty($newlog)) {
self::$task->log('Log module-action "' . $keyname . ' process problem. Not restored', backup::LOG_DEBUG);
self::$task->log('Log module-action "' . $keyname . '" process problem. Not restored', backup::LOG_DEBUG);
}
} else { // Action not found log the problem
self::$task->log('Log module-action "' . $keyname . ' unknown. Not restored', backup::LOG_DEBUG);
self::$task->log('Log module-action "' . $keyname . '" unknown. Not restored', backup::LOG_DEBUG);
$newlog = false;
}
+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);
}
}
}
+2 -1
View File
@@ -139,7 +139,8 @@ class base_setting_ui {
* @param string $label
*/
public function set_label($label) {
if ((string)$label === '' || $label !== clean_param($label, PARAM_TEXT)) {
$label = (string)$label;
if ($label === '' || $label !== clean_param($label, PARAM_TEXT)) {
throw new base_setting_ui_exception('setting_invalid_ui_label');
}
$this->label = $label;
+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"
+55 -17
View File
@@ -27,6 +27,7 @@
require_once(__DIR__ . '/../../../../../lib/behat/behat_base.php');
require_once(__DIR__ . '/../../../../../lib/behat/behat_field_manager.php');
require_once(__DIR__ . '/../../../../../lib/tests/behat/behat_navigation.php');
use Behat\Gherkin\Node\TableNode as TableNode,
Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException,
@@ -42,6 +43,19 @@ use Behat\Gherkin\Node\TableNode as TableNode,
*/
class behat_backup extends behat_base {
/**
* Follow a link like 'Backup' or 'Import', where the link name comes from
* a language string, in the settings nav block of a course.
* @param string $langstring the lang string to look for. E.g. 'backup' or 'import'.
* @param string $component (optional) second argument to {@link get_string}.
*/
protected function navigate_to_course_settings_link($langstring, $component = '') {
$behatnavigation = new behat_navigation();
$behatnavigation->setMink($this->getMink());
$behatnavigation->i_navigate_to_node_in(get_string($langstring, $component),
get_string('courseadministration'));
}
/**
* Backups the specified course using the provided options. If you are interested in restoring this backup would be useful to provide a 'Filename' option.
*
@@ -50,34 +64,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->navigate_to_course_settings_link('backup');
$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.
@@ -113,7 +124,7 @@ class behat_backup extends behat_base {
$this->wait();
// Click the import link.
$this->find_link(get_string('import'))->click();
$this->navigate_to_course_settings_link('import');
$this->wait();
// Select the course.
@@ -132,12 +143,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 +314,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 +352,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);
}
+1 -1
View File
@@ -54,7 +54,7 @@ class edit_details_form extends moodleform {
$mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
$mform->addElement('textarea', 'description', get_string('description', 'badges'), 'wrap="virtual" rows="8" cols="70"');
$mform->setType('description', PARAM_CLEANHTML);
$mform->setType('description', PARAM_NOTAGS);
$mform->addRule('description', null, 'required');
$str = $action == 'new' ? get_string('badgeimage', 'badges') : get_string('newimage', 'badges');
+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"
When I log in as "admin"
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
+3 -2
View File
@@ -62,9 +62,10 @@ class block_private_files extends block_base {
$renderer = $this->page->get_renderer('block_private_files');
$this->content->text = $renderer->private_files_tree();
if (has_capability('moodle/user:manageownfiles', $this->context)) {
$this->content->text .= $OUTPUT->single_button(new moodle_url('/user/files.php', array('returnurl'=>$PAGE->url->out())), get_string('myfilesmanage'), 'get');
$this->content->footer = html_writer::link(
new moodle_url('/user/files.php', array('returnurl' => $PAGE->url->out())),
get_string('myfilesmanage') . '...');
}
$this->content->footer = '';
}
return $this->content;
+6 -1
View File
@@ -2,4 +2,9 @@
.block_private_files .content table {
table-layout: fixed;
width: 100%;
}
}
.block_private_files .content .footer {
padding: 10px 0 0;
margin-top: .5em;
}
+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"
+20 -21
View File
@@ -31,8 +31,12 @@ include_once('locallib.php');
$action = required_param('action', PARAM_ALPHA);
$id = optional_param('entryid', 0, PARAM_INT);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$modid = optional_param('modid', 0, PARAM_INT); // To associate the entry with a module instance
$courseid = optional_param('courseid', 0, PARAM_INT); // To associate the entry with a course
$modid = optional_param('modid', 0, PARAM_INT); // To associate the entry with a module instance.
$courseid = optional_param('courseid', 0, PARAM_INT); // To associate the entry with a course.
if ($action == 'edit') {
$id = required_param('entryid', PARAM_INT);
}
$PAGE->set_url('/blog/edit.php', array('action' => $action, 'entryid' => $id, 'confirm' => $confirm, 'modid' => $modid, 'courseid' => $courseid));
@@ -41,6 +45,20 @@ if (!empty($id) && $action == 'add') {
$id = null;
}
// Blogs are always in system context.
$sitecontext = context_system::instance();
$PAGE->set_context($sitecontext);
require_login($courseid);
if (empty($CFG->enableblogs)) {
print_error('blogdisable', 'blog');
}
if (isguestuser()) {
print_error('noguestentry', 'blog');
}
$returnurl = new moodle_url('/blog/index.php');
if (!empty($courseid) && empty($modid)) {
@@ -54,27 +72,8 @@ if (!empty($modid)) {
$returnurl->param('courseid', $courseid);
}
// Blogs are always in system context.
$sitecontext = context_system::instance();
$PAGE->set_context($sitecontext);
$blogheaders = blog_get_headers();
require_login($courseid);
if ($action == 'edit') {
$id = required_param('entryid', PARAM_INT);
}
if (empty($CFG->enableblogs)) {
print_error('blogdisable', 'blog');
}
if (isguestuser()) {
print_error('noguestentry', 'blog');
}
if (!has_capability('moodle/blog:create', $sitecontext) && !has_capability('moodle/blog:manageentries', $sitecontext)) {
print_error('cannoteditentryorblog');
}
+10 -5
View File
@@ -79,12 +79,15 @@ if ($externalblogform->is_cancelled()){
$newexternal->description = (empty($data->description)) ? $rss->get_description() : $data->description;
$newexternal->userid = $USER->id;
$newexternal->url = $data->url;
$newexternal->filtertags = $data->filtertags;
$newexternal->filtertags = (!empty($data->filtertags)) ? $data->filtertags : null;
$newexternal->timemodified = time();
$newexternal->id = $DB->insert_record('blog_external', $newexternal);
blog_sync_external_entries($newexternal);
tag_set('blog_external', $newexternal->id, explode(',', $data->autotags));
if ($CFG->usetags) {
$autotags = (!empty($data->autotags)) ? $data->autotags : null;
tag_set('blog_external', $newexternal->id, explode(',', $autotags));
}
break;
@@ -98,12 +101,14 @@ if ($externalblogform->is_cancelled()){
$external->description = (empty($data->description)) ? $rss->get_description() : $data->description;
$external->userid = $USER->id;
$external->url = $data->url;
$external->filtertags = $data->filtertags;
$external->filtertags = (!empty($data->filtertags)) ? $data->filtertags : null;
$external->timemodified = time();
$DB->update_record('blog_external', $external);
tag_set('blog_external', $external->id, explode(',', $data->autotags));
if ($CFG->usetags) {
$autotags = (!empty($data->autotags)) ? $data->autotags : null;
tag_set('blog_external', $external->id, explode(',', $autotags));
}
} else {
print_error('wrongexternalid', 'blog');
}
+3 -1
View File
@@ -118,7 +118,9 @@ class blog_edit_external_form extends moodleform {
if ($id = $mform->getElementValue('id')) {
$mform->setDefault('autotags', implode(',', tag_get_tags_array('blog_external', $id)));
$mform->freeze('url');
$mform->freeze('filtertags');
if ($mform->elementExists('filtertags')) {
$mform->freeze('filtertags');
}
// TODO change the filtertags element to a multiple select, using the tags of the external blog
// Use $rss->get_channel_tags()
}
+13 -13
View File
@@ -34,10 +34,6 @@ foreach ($url_params as $var => $val) {
}
$PAGE->set_url('/blog/index.php', $url_params);
if (empty($CFG->enableblogs)) {
print_error('blogdisable', 'blog');
}
//correct tagid if a text tag is provided as a param
if (!empty($tag)) {
if ($tagrec = $DB->get_record('tag', array('name' => $tag))) {
@@ -47,15 +43,6 @@ if (!empty($tag)) {
}
}
// add courseid if modid or groupid is specified: This is used for navigation and title
if (!empty($modid) && empty($courseid)) {
$courseid = $DB->get_field('course_modules', 'course', array('id'=>$modid));
}
if (!empty($groupid) && empty($courseid)) {
$courseid = $DB->get_field('groups', 'courseid', array('id'=>$groupid));
}
$sitecontext = context_system::instance();
// Blogs are always in system context.
$PAGE->set_context($sitecontext);
@@ -84,6 +71,19 @@ if ($CFG->bloglevel == BLOG_GLOBAL_LEVEL) {
print_error('blogdisable', 'blog');
}
if (empty($CFG->enableblogs)) {
print_error('blogdisable', 'blog');
}
// Add courseid if modid or groupid is specified: This is used for navigation and title.
if (!empty($modid) && empty($courseid)) {
$courseid = $DB->get_field('course_modules', 'course', array('id' => $modid));
}
if (!empty($groupid) && empty($courseid)) {
$courseid = $DB->get_field('groups', 'courseid', array('id' => $groupid));
}
if (!$userid && has_capability('moodle/blog:view', $sitecontext) && $CFG->bloglevel > BLOG_USER_LEVEL) {
if ($entryid) {
+5 -3
View File
@@ -181,9 +181,11 @@ function blog_sync_external_entries($externalblog) {
$filtertags = array_map('trim', $filtertags);
$filtertags = array_map('strtolower', $filtertags);
foreach ($categories as $category) {
if (in_array(trim(strtolower($category->term)), $filtertags)) {
$containsfiltertag = true;
if (!empty($categories)) {
foreach ($categories as $category) {
if (in_array(trim(strtolower($category->term)), $filtertags)) {
$containsfiltertag = true;
}
}
}
+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.
+12 -9
View File
@@ -52,7 +52,7 @@ $locks = cache_administration_helper::get_lock_summaries();
$title = new lang_string('cacheadmin', 'cache');
$mform = null;
$notification = null;
$notifications = array();
$notifysuccess = true;
if (!empty($action) && confirm_sesskey()) {
@@ -110,10 +110,10 @@ if (!empty($action) && confirm_sesskey()) {
if (!array_key_exists($store, $stores)) {
$notifysuccess = false;
$notification = get_string('invalidstore', 'cache');
$notifications[] = array(get_string('invalidstore', 'cache'), false);
} else if ($stores[$store]['mappings'] > 0) {
$notifysuccess = false;
$notification = get_string('deletestorehasmappings', 'cache');
$notifications[] = array(get_string('deletestorehasmappings', 'cache'), false);
}
if ($notifysuccess) {
@@ -250,10 +250,10 @@ if (!empty($action) && confirm_sesskey()) {
$confirm = optional_param('confirm', false, PARAM_BOOL);
if (!array_key_exists($lock, $locks)) {
$notifysuccess = false;
$notification = get_string('invalidlock', 'cache');
$notifications[] = array(get_string('invalidlock', 'cache'), false);
} else if ($locks[$lock]['uses'] > 0) {
$notifysuccess = false;
$notification = get_string('deletelockhasuses', 'cache');
$notifications[] = array(get_string('deletelockhasuses', 'cache'), false);
}
if ($notifysuccess) {
if (!$confirm) {
@@ -280,6 +280,12 @@ if (!empty($action) && confirm_sesskey()) {
}
}
// Add cache store warnings to the list of notifications.
// Obviously as these are warnings they are show as failures.
foreach (cache_helper::warnings($stores) as $warning) {
$notifications[] = array($warning, false);
}
$PAGE->set_title($title);
$PAGE->set_heading($SITE->fullname);
/* @var core_cache_renderer $renderer */
@@ -287,10 +293,7 @@ $renderer = $PAGE->get_renderer('core_cache');
echo $renderer->header();
echo $renderer->heading($title);
if (!is_null($notification)) {
echo $renderer->notification($notification, ($notifysuccess)?'notifysuccess' : 'notifyproblem');
}
echo $renderer->notifications($notifications);
if ($mform instanceof moodleform) {
$mform->display();
+26 -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.
@@ -734,4 +735,28 @@ class cache_helper {
}
return $stores;
}
/**
* Returns an array of warnings from the cache API.
*
* The warning returned here are for things like conflicting store instance configurations etc.
* These get shown on the admin notifications page for example.
*
* @param array|null $stores An array of stores to get warnings for, or null for all.
* @return string[]
*/
public static function warnings(array $stores = null) {
global $CFG;
if ($stores === null) {
require_once($CFG->dirroot.'/cache/locallib.php');
$stores = cache_administration_helper::get_store_instance_summaries();
}
$warnings = array();
foreach ($stores as $store) {
if (!empty($store['warnings'])) {
$warnings = array_merge($warnings, $store['warnings']);
}
}
return $warnings;
}
}
+12
View File
@@ -338,4 +338,16 @@ abstract class cache_store implements cache_store_interface {
// Any stores that have an issue with this will need to override the create_clone method.
return clone($this);
}
/**
* Can be overridden to return any warnings this store instance should make to the admin.
*
* This should be used to notify things like configuration conflicts etc.
* The warnings returned here will be displayed on the cache configuration screen.
*
* @return string[] An array of warning strings from the store instance.
*/
public function get_warnings() {
return array();
}
}
+2 -1
View File
@@ -709,7 +709,8 @@ abstract class cache_administration_helper extends cache_helper {
'nativelocking' => ($store instanceof cache_is_lockable),
'keyawareness' => ($store instanceof cache_is_key_aware),
'searchable' => ($store instanceof cache_is_searchable)
)
),
'warnings' => $store->get_warnings()
);
if (empty($details['default'])) {
$return[$name] = $record;

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