Compare commits

..

261 Commits

Author SHA1 Message Date
Eloy Lafuente (stronk7) be3e6f6202 Moodle release 2.8.5 2015-03-10 00:42:44 +01:00
Eloy Lafuente (stronk7) 49f4e7c976 weekly release 2.8.4+ 2015-03-09 16:47:53 +01:00
Marina Glancy 2d73956d8e MDL-49418 core: partial revert of MDL-48804
this is a quick fix for the issue 'Course module with two or more availability restrictions is not accessible'
MDL-49434 is created to deal with the renderer access inside availability check
2015-03-09 11:26:18 +08:00
Eloy Lafuente (stronk7) f4dc567e79 Moodle release 2.8.4 2015-03-07 11:23:46 +01:00
Eloy Lafuente (stronk7) 67bbf0d422 weekly release 2.8.3+ 2015-03-05 11:26:48 +01:00
Eloy Lafuente (stronk7) 89784be6ff Merge branch 'MDL-49379_m28' of git://github.com/markn86/moodle into MOODLE_28_STABLE 2015-03-04 10:50:12 +01:00
Mark Nelson 8f938ff9a6 MDL-49379 core_webservice: fixed ability to edit services 2015-03-04 01:37:07 -08:00
David Monllao c35df119a5 MDL-49204 core_message: Checking current user 2015-03-04 10:05:44 +08:00
Andrew Nicols 98dfa7cae8 Merge branch 'MDL-49364_28' of git://github.com/timhunt/moodle into MOODLE_28_STABLE 2015-03-04 08:53:03 +08:00
Andrew Nicols 4d7ecf45a1 Merge branch 'mdl28_MDL-46390' of https://github.com/danmarsden/moodle into MOODLE_28_STABLE 2015-03-04 07:55:59 +08:00
Dan Marsden 2e12b4cffb MDL-46390 mod_scorm: Find correct sco to launch when org based sco is selected
Also tidies up some redundant code in scorm_format_toc_for_droplist()
2015-03-04 09:28:53 +13:00
Eloy Lafuente (stronk7) c2383703ea Merge branch 'MDL-49214_M28' of git://github.com/lazydaisy/moodle into MOODLE_28_STABLE 2015-03-03 19:36:19 +01:00
Dan Poltawski 9db4890064 Merge branch 'MDL-49335_28' of git://github.com/timhunt/moodle into MOODLE_28_STABLE 2015-03-03 14:46:34 +00:00
Dan Poltawski c6e925dbf0 Merge branch 'MDL-49334_28' of git://github.com/timhunt/moodle into MOODLE_28_STABLE 2015-03-03 13:25:33 +00:00
Dan Poltawski 35a615aa33 Merge branch 'MDL-47000-28' of git://github.com/merrill-oakland/moodle into MOODLE_28_STABLE 2015-03-03 13:21:30 +00:00
Tim Hunt f1fb96b698 MDL-49364 quiz statistics: escape output in the response analysis 2015-03-03 13:04:59 +00:00
Tim Hunt b6f112957e MDL-49335 quiz behat: new test of attempting a quiz
This separates out attempting the quiz into a separate .feature, away
from the monolithic add_quiz.feature. At some point we should clean that
up, but for now I am just adding this.

Really, the main reason for this test is to verify the two Behat
enhancememnts I just did.
2015-03-03 11:23:55 +00:00
Tim Hunt ccc1e11099 MDL-49335 quiz behat: improved step for adding questions to a quiz
Explicit headings make the script more readable, and pave the way for
new options that are due to be added.
2015-03-03 11:23:54 +00:00
Tim Hunt 44f6bc4ead MDL-49335 Behat: new question selector
So you can say things like
    And I click on "True" "radio" in the "First question" "question"
2015-03-03 11:23:54 +00:00
Tim Hunt 6e650b4c0a MDL-49334 behat: sort selector lists 2015-03-03 11:20:55 +00:00
Dan Poltawski 84fd0fd52c Merge branch 'MDL-34006_m28v7' of https://github.com/sbourget/moodle into MOODLE_28_STABLE 2015-03-03 11:03:12 +00:00
Stephen Bourget 2a433ad067 MDL-45621 Portfolio: Allow portfolios to be uninstalled 2015-03-03 10:59:48 +01:00
Dan Poltawski e527aff4d2 Merge branch 'MDL-49160-28' of git://github.com/merrill-oakland/moodle into MOODLE_28_STABLE 2015-03-03 08:34:50 +00:00
Andrew Nicols da9dfe70d4 Merge branch 'wip-mdl-49110-m28' of https://github.com/rajeshtaneja/moodle into MOODLE_28_STABLE 2015-03-03 16:27:03 +08:00
Andrew Nicols e2d00f5195 MDL-49285 mod_quiz: Remove unnecessary linebreak 2015-03-03 16:24:02 +08:00
Andrew Nicols 6afe470648 Merge branch 'MDL-49285-28' of git://github.com/merrill-oakland/moodle into MOODLE_28_STABLE 2015-03-03 16:23:24 +08:00
Andrew Nicols 76bd7cea87 Merge branch 'MDL-38485-28' of git://github.com/ankitagarwal/moodle into MOODLE_28_STABLE 2015-03-03 16:15:06 +08:00
Andrew Nicols 2b6bb87e59 Merge branch 'MDL-49075-28' of https://github.com/lucisgit/moodle into MOODLE_28_STABLE 2015-03-03 15:43:44 +08:00
pau.ferrer-ocana d259d014bb MDL-49234 oracle: Remove variables passed by reference error 2015-03-03 15:14:38 +08:00
Andrew Nicols fba097e3ce Merge branch 'MDL-49247_28' of git://github.com/timhunt/moodle into MOODLE_28_STABLE 2015-03-03 15:07:35 +08:00
Andrew Nicols 21b910b487 Merge branch 'MDL-49284_28' of git://github.com/timhunt/moodle into MOODLE_28_STABLE 2015-03-03 13:48:13 +08:00
Eloy Lafuente (stronk7) 83866c3c2a MDL-49087 mdeploy: now relying on config.php documented 2015-03-03 02:44:49 +01:00
Andrew Nicols 4475f1e478 MDL-49087 mnet: Ensure typeroot is in dirroot 2015-03-03 02:40:50 +01:00
Andrew Nicols c353a62026 MDL-49087 mnet: Use real dataroot instead of user-provided 2015-03-03 02:40:50 +01:00
Eloy Lafuente (stronk7) 1a67f29f38 Merge branch 'MDL-37470_28' of https://github.com/mike-grant/moodle into MOODLE_28_STABLE 2015-03-03 01:43:54 +01:00
Eloy Lafuente (stronk7) 50f2d4d645 Merge branch 'MDL-49240-28' of git://github.com/damyon/moodle into MOODLE_28_STABLE 2015-03-03 01:11:24 +01:00
Dan Poltawski f479a30931 Merge branch 'MOODLE_28_STABLE' of https://github.com/mitstek/moodle into MOODLE_28_STABLE 2015-03-02 17:27:15 +00:00
Dan Poltawski a62cc33c1f Merge branch '28_MDL-49303' of https://github.com/danmarsden/moodle into MOODLE_28_STABLE 2015-03-02 16:57:54 +00:00
Marina Glancy 4ab4ec652c MDL-48804 core: do not set current course until login validated 2015-03-02 16:49:44 +01:00
Juan Leyva 0899c0adc0 MDL-48691 webservices: Check if the user must be changing password 2015-03-02 14:40:01 +00:00
Simey Lameze 64e2179478 MDL-49084 core_tag: add capability check to flag as inappropriate action 2015-03-02 12:52:13 +00:00
Andrew Nicols 51094c6560 MDL-49144 blocks: Sanitise alt and title for block controls 2015-03-02 12:09:52 +00:00
Andrew Nicols 3f316035b4 MDL-49144 blocks: Add behat test to ensury sanity of block title 2015-03-02 12:09:52 +00:00
Dan Poltawski 0dedf765e0 Merge branch 'MDL-47911-28' of git://github.com/damyon/moodle into MOODLE_28_STABLE 2015-03-02 11:06:19 +00:00
Ankit Agarwal 5219605a81 MDL-38466 filters: Redos protection and unit tests 2015-03-02 11:30:45 +01:00
Zachary Durber 1b24951778 MDL-38466 filters: ReDoS protection for text to URL conversion. 2015-03-02 11:30:44 +01:00
Dan Poltawski 952bc6c5a6 Merge branch 'MDL-23273-28' of git://github.com/zbdd/moodle into MOODLE_28_STABLE 2015-03-02 09:34:57 +00:00
Mary Evans 3cf5c751ed MDL-49214 theme_bootstrapbase: OL list numbers cut off in Clean theme
Conflicts:

	theme/bootstrapbase/style/moodle.css
2015-03-01 19:40:58 +00:00
Eric Merrill fb50700b4e MDL-47911 gradebook: Improve the performance of set_usedinaggregation
This function is called many many times during grade calculation, so it
should be as efficient as possible.
2015-02-27 11:53:54 +08:00
Tony Butler 7c0e5b20b6 MDL-49075 mod_assign: Add assertions to marking workflow unit test
Make sure grades aren't pushed to gradebook for marking workflow
states other than 'released'.
2015-02-26 11:56:20 +00:00
Tony Butler bb790b84ca MDL-49075 mod_assign: Keep unreleased assign grades out of gradebook 2015-02-26 11:56:20 +00:00
Dan Marsden e1c81e5284 MDL-49303 mod_scorm: Initialise student preferences on re-entry. 2015-02-26 20:39:07 +13:00
Tim Hunt e89a286905 MDL-49284 formslib: fix strict validation of HTML. 2015-02-25 17:39:23 +00:00
Stephen Bourget c80f356bca MDL-34006 Lesson: Behat tests 2015-02-25 10:29:14 -05:00
Stephen Bourget cf49d1850e MDL-34006 Lesson: Resume lesson loads wrong page. 2015-02-25 10:29:01 -05:00
Dan Poltawski 2abfecbc8c weekly release 2.8.3+ 2015-02-25 14:57:39 +00:00
Dan Poltawski 6fe7343a94 Merge branch 'install_28_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_28_STABLE 2015-02-25 14:57:36 +00:00
Mitsuhiro Yoshida 9b1c53771a MDL-49259 lib: Fix for unzipped Japanese filename character corruption 2015-02-25 23:28:29 +09:00
Andrew Nicols f18a66f1ea MDL-49008 lang: Revert unnecessary rename warning
This was failing unit tests because it does not check for the presence of
the source directory first. If there is no source directory, it cannot be
moved.
2015-02-25 08:55:56 +08:00
Eric Merrill 3272e14576 MDL-47000 session: Update memcached version referecnes to 2.2.0 2015-02-24 15:19:30 -05:00
Eric Merrill 181269bf32 MDL-49285 quiz: Include lib.php for phpunit test 2015-02-24 14:54:37 -05:00
Eric Merrill fc63b8cf81 MDL-49160 quiz: Make sure to not select an outcome grade item
When we are computing completion, make sure we select only the true
grade_item, not outcome grade items.
2015-02-24 14:43:37 -05:00
Dan Poltawski 84be895b94 Merge branch 'MDL-49241-28-enfix' of git://github.com/mudrd8mz/moodle into MOODLE_28_STABLE 2015-02-24 16:50:15 +00:00
Dan Poltawski 8732862bb5 Merge branch 'wip_MDL-49184_m28_choice' of https://github.com/skodak/moodle into MOODLE_28_STABLE 2015-02-24 10:43:32 +00:00
Brian Barnes ede8ae0399 MDL-48519 accessibility: improved accessibility of user filters 2015-02-24 17:53:27 +08:00
Andrew Nicols 2d7c31b550 Merge branch 'MDL-49078_m28' of git://github.com/shashirepo/moodle into MOODLE_28_STABLE 2015-02-24 17:05:53 +08:00
Shashikant Vaishnav 9a055f40c2 MDL-49078 theme_bootstrapbase: 'Create new course' text too high
Thanks to  Gareth J Barnard  for the code suggestion
2015-02-24 14:21:09 +05:30
Dan Poltawski 40b53bda8c Merge branch 'MDL-49216-28' of git://github.com/andrewnicols/moodle into MOODLE_28_STABLE 2015-02-24 08:31:54 +00:00
Andrew Davis c49003263e MDL-29008 lang: reintroduced error silencing to prevent unit test failures 2015-02-24 16:16:20 +08:00
Zachary Durber c9e9862ed6 MDL-23273 mod_choice: error continue button redirects back to choice
Locks only occur when a choice is using limits.
2015-02-24 12:16:29 +08:00
Zachary Durber a455f2fa45 MDL-23273 mod_choice: Using locks to ensure choice limits 2015-02-24 12:16:29 +08:00
Andrew Nicols b34fc1800a Merge branch 'mdl28_MDL-46408' of https://github.com/danmarsden/moodle into MOODLE_28_STABLE 2015-02-24 11:35:53 +08:00
Ankit Agarwal 8a15bcf759 MDL-38485 calendar: Carry over line breaks on imports
Thanks to Matthias Schwabe for the patch suggestion
2015-02-24 08:55:40 +05:30
Andrew Nicols 4f2308d541 Merge branch 'MDL-49008_lang_vanish_28' of https://github.com/andyjdavis/moodle into MOODLE_28_STABLE 2015-02-24 11:08:28 +08:00
Andrew Nicols 41ab3ae676 MDL-49216 mod_forum: Move subquery to outer component
It is not possible to order sub-query results with some RDBMs, and the
subquery is not necessary anyway.
2015-02-24 08:30:24 +08:00
Andrew Nicols d2782c3d4b MDL-49216 mod_forum: Add tests for discussion reply count 2015-02-24 08:30:23 +08:00
Helen Foster b907bc26f6 MDL-49241 lang: Merge English strings from the en_fix language pack 2015-02-23 21:15:18 +01:00
Dan Poltawski 105e1af010 Merge branch 'MDL-49198_m28' of https://github.com/markn86/moodle into MOODLE_28_STABLE 2015-02-23 16:29:25 +00:00
Dan Poltawski 06b5e1f1e1 Merge branch 'MDL-49200_m28' of https://github.com/markn86/moodle into MOODLE_28_STABLE 2015-02-23 16:21:33 +00:00
Dan Poltawski 9c2e581e82 Merge branch 'MOODLE_28_STABLE' of https://github.com/eberhardt/moodle into MOODLE_28_STABLE 2015-02-23 15:55:37 +00:00
Andrew Nicols 0c8096792d MDL-48807 accesslib: Change create_level_instance to recordset 2015-02-23 16:03:17 +08:00
Andrew Nicols aa2b7c3b48 Merge branch 'MDL-48807-28' of git://github.com/lameze/moodle into MOODLE_28_STABLE 2015-02-23 15:08:09 +08:00
Simey Lameze 56145a4d6e MDL-48807 core_task: change create_contexts_task to daily frequency 2015-02-23 14:40:37 +08:00
Simey Lameze 34fcdf2da4 MDL-48807 accesslib: table locking fix on all create_level_instance 2015-02-23 14:36:52 +08:00
David Monllao 5e872af220 MDL-49145 report_log: Moving conditions
Now get_url() does not need to be resolved when
we are downloading.
2015-02-23 10:38:47 +08:00
Andrew Nicols 40155b1ca0 Merge branch 'MDL-49174-28' of git://github.com/jleyva/moodle into MOODLE_28_STABLE 2015-02-23 09:36:21 +08:00
Andrew Nicols 75b594848e Merge branch 'MDL-35392-28' of git://github.com/zbdd/moodle into MOODLE_28_STABLE 2015-02-23 09:21:55 +08:00
Zachary Durber ad4d28ff76 MDL-35392 mod_assign: Push feedback to gradebook when releasing grades
When bulk changing workflow status a mismatch in variable
names meant that feedback wasn't being sent to the gradebook.
2015-02-23 09:17:30 +08:00
Andrew Nicols a721901beb Merge branch 'MDL-49145_28' of git://github.com/dmonllao/moodle into MOODLE_28_STABLE 2015-02-23 09:05:58 +08:00
David Monllao e0c5923c07 MDL-49145 report_log: Fixing condition
Credit and thanks to Tyler Bannister and Renaat Debleu.
2015-02-23 08:46:56 +08:00
Andrew Davis bbc7df8d52 MDL-49008 lang: removed preemptive deleting of old language files 2015-02-22 21:08:31 +01:00
Andrew Davis 1ab376e86f MDL-49008 lang: made lang update error reporting work 2015-02-22 21:06:38 +01:00
Dan Marsden 4c30d78891 MDL-46408 mod_scorm: check param is set before using.
The default org is only set if it exists in the imsmanifest.xml
2015-02-20 13:42:23 +13:00
Tim Hunt 87e581f91a MDL-49247 question restore: avoid unique key errors from old bad data
Several tables have had unique keys added to enforce a constraint that
should always have been there. It is possible for old sites to have
data that violate the constraints, and sometimes people want to backup
data from those old sites, and restore them into a new Moodle.
Therefore, we need to guard agains the unique key violation errors.
2015-02-19 21:50:47 +00:00
AMOS bot 4571805430 Automatically generated installer lang files 2015-02-20 00:04:08 +08:00
Jan Eberhardt ec943fe107 MDL-31578 auth_shibboleth: Custom fields added to shibboleth settings
Since LDAP is able to sync custom user profile fields, this feature was
requested for Shibboleth.
2015-02-19 13:56:42 +00:00
Eloy Lafuente (stronk7) 8235b610bb weekly release 2.8.3+ 2015-02-19 10:44:47 +01:00
Eloy Lafuente (stronk7) aff125ae03 Merge branch 'install_28_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_28_STABLE 2015-02-19 10:44:41 +01:00
Damyon Wiese 41adb95781 MDL-49240 webservices: core_get_string and friends bad lang handling
The core_get_string webservice and friends have never passed lang values
properly, (so never worked) and when I fixed that I found they were passing
lang parameter into the lazyload parameter.
2015-02-19 17:42:50 +08:00
Andrew Nicols 7546d2e1c3 Revert "Merge branch 'MDL-49154_28' of git://github.com/timhunt/moodle into MOODLE_28_STABLE"
This reverts commit f5a176c125, reversing
changes made to cf015aa1f0.
2015-02-19 09:18:06 +08:00
Rajesh Taneja 282fdb22ca MDL-48841 admin: Behat table row should start with first row 2015-02-18 15:34:12 +08:00
Botond Hegedus dac942ff58 MDL-49198 core_webservice: Fix error when using existing service name 2015-02-17 23:14:22 -08:00
David Monllao 38a219301e Merge branch 'MDL-49034_m28' of git://github.com/mattporritt/moodle into MOODLE_28_STABLE 2015-02-18 09:36:38 +08:00
Eloy Lafuente (stronk7) 7001bf9a8c Merge branch 'MDL-49211_M28' of git://github.com/lazydaisy/moodle into MOODLE_28_STABLE 2015-02-18 00:03:59 +01:00
Eloy Lafuente (stronk7) 7f8ae8f54e Merge branch 'MDL-48973_28' of https://github.com/pauln/moodle into MOODLE_28_STABLE 2015-02-17 23:52:48 +01:00
Eloy Lafuente (stronk7) f5a176c125 Merge branch 'MDL-49154_28' of git://github.com/timhunt/moodle into MOODLE_28_STABLE 2015-02-17 23:46:47 +01:00
Eloy Lafuente (stronk7) cf015aa1f0 Merge branch 'MDL-49170_28' of https://github.com/totara/openbadges into MOODLE_28_STABLE 2015-02-17 23:43:38 +01:00
Eloy Lafuente (stronk7) d34122424c Merge branch 'MDL-49205_28' of git://github.com/timhunt/moodle into MOODLE_28_STABLE 2015-02-17 22:18:51 +01:00
Juan Leyva 6c1a52e67c MDL-49174 webservices: Return front page contents in get_contents ws 2015-02-17 21:33:42 +01:00
Eloy Lafuente (stronk7) 373252e7da Merge branch 'MDL-49041_28' of git://github.com/timhunt/moodle into MOODLE_28_STABLE 2015-02-17 21:09:26 +01:00
Eloy Lafuente (stronk7) 2f4dfae509 Merge branch 'MDL-49059-split_28' of https://github.com/pauln/moodle into MOODLE_28_STABLE 2015-02-17 20:58:39 +01:00
Eric Merrill 68adf314ec MDL-48993 gradebook: When importing new items, treat blank or - as empty 2015-02-17 17:21:49 +08:00
David Monllao 1c703690cd Merge branch 'MDL-49167-28' of git://github.com/damyon/moodle into MOODLE_28_STABLE 2015-02-17 17:01:26 +08:00
David Monllao 0289d8c766 MDL-48991 gradebook: Return value according to coding style 2015-02-17 16:48:44 +08:00
David Monllao a4e657878b Merge branch 'MDL-48991-28' of git://github.com/merrill-oakland/moodle into MOODLE_28_STABLE 2015-02-17 16:43:44 +08:00
David Monllao b7a6e68906 Merge branch 'MDL-48884_m28' of git://github.com/markn86/moodle into MOODLE_28_STABLE 2015-02-17 14:44:05 +08:00
David Monllao 65b48f6850 Merge branch 'MDL-48841-MOODLE_28_STABLE' of git://github.com/lucisgit/moodle into MOODLE_28_STABLE 2015-02-17 14:25:02 +08:00
Andrew Nicols 6e84137b30 Merge branch 'wip-mdl-48670-m28' of https://github.com/rajeshtaneja/moodle into MOODLE_28_STABLE 2015-02-17 14:07:15 +08:00
David Monllao e9a6191801 Merge branch 'MDL-49169_28' of git://github.com/grabs/moodle into MOODLE_28_STABLE 2015-02-17 14:01:14 +08:00
Mark Nelson 376d6d9bc0 MDL-49200 core_form: corrected string 2015-02-16 21:59:41 -08:00
David Monllao 94b3cc37aa Merge branch 'MDL-48215_m28' of git://github.com/markn86/moodle into MOODLE_28_STABLE 2015-02-17 13:24:36 +08:00
Petr Skoda 401465fe7c MDL-49184 choice: fix block actions
The problems was that blocks editing breaks if you redirect
after if (data_submitted()) - all form actions must make sure
it is really their form, otherwise they may hijack the post from
block actions.

Note that this is not a problem for mforms, only legacy forms
are affected.

# Conflicts:
#	mod/choice/view.php
2015-02-17 16:56:45 +13:00
David Monllao 95337e5974 Merge branch 'MDL-48543-28' of git://github.com/damyon/moodle into MOODLE_28_STABLE 2015-02-17 11:15:12 +08:00
David Monllao a9e2dd494b Merge branch 'MDL-48709_28' of git://github.com/jmvedrine/moodle into MOODLE_28_STABLE 2015-02-17 09:17:25 +08:00
AMOS bot d153a4a39d Automatically generated installer lang files 2015-02-17 00:04:18 +08:00
Michael Hughes 5b7e7362a9 MDL-48215 gradingform_guide: Name length validation
Validating both criterion name and guide name to be 255 chars.
2015-02-15 21:52:56 -08:00
David Monllao 5eed950dd2 Merge branch 'MDL-47529-28' of git://github.com/FMCorz/moodle into MOODLE_28_STABLE 2015-02-16 11:55:39 +08:00
Damyon Wiese fe5ecacb2b MDL-49167 YUI: Fix for theme/yui_combo.php and $CFG->yuislashargs
It was too aggressively cleaning it's params (broken in MDL-48980).
2015-02-16 11:26:11 +08:00
Frederic Massart 84b1aeba07 MDL-47529 lock: Fix typo on lock factory in config-dist 2015-02-16 11:14:20 +08:00
Frederic Massart d940409a40 MDL-47529 task: Remove usage of lock when editing a task 2015-02-16 11:14:20 +08:00
Frederic Massart 58ebc0a42d MDL-47529 task: Do not use lock when updating task records 2015-02-16 11:14:20 +08:00
David Monllao 6eba5f4dfa Merge branch 'MDL-40776_28' of git://github.com/s-cenni/moodle into MOODLE_28_STABLE 2015-02-16 10:35:26 +08:00
Yuliya Bozhko a99654771f MDL-49170 badges: Backpack connection missing a port colon in URL
Signed-off-by: Yuliya Bozhko <yuliya.bozhko@totaralms.com>
2015-02-16 09:34:39 +13:00
Mary Evans 27a5f957ba MDL-49211 theme_bootstrapbase: Text alignment issue in CLOZE questions.
Conflicts:

	theme/bootstrapbase/style/moodle.css
2015-02-15 19:18:17 +00:00
Jean-Michel Vedrine 1a825a276e MDL-48709 mod_lesson: subclusters are not working 2015-02-14 18:21:40 +01:00
Tim Hunt dabbf48f50 MDL-49205 behat: fix I set the field with xpath fail message. 2015-02-13 16:16:18 +00:00
Paul Nicholls 10a382f1c8 MDL-48973 Atto: Atto does not listen to the drop event
The 'drop' event fires before the native ContentEditable drop handler, so
in order to update the underlying textarea we need to call updateOriginal
with a brief delay so that the dropped content has actually been added to
the editor.
2015-02-13 14:50:14 +13:00
Rajesh Taneja 21e8f813dc MDL-48670 behat: Set timezone to Australia/perth
Behat tests might rely on time related tests
Ensure we have default timezone set to Australia/Perth
2015-02-13 08:12:42 +08:00
Eric Merrill 49f1acf174 MDL-48991 gradebook: Fix style problems 2015-02-12 16:50:17 -05:00
Matt Switlik 4f9ccc21d8 MDL-48991 gradebook: Properly import multiple new grade items
Work done in MDL-46547 caused a problem where multiple new grade items
were not imported. Fix up the passing of new grade objects.
2015-02-12 16:50:17 -05:00
Paul Nicholls a92cd1e420 MDL-49059 medialib: Add test cases for invalid Youtube URL param values
Tests to ensure that we're not allowing injection via invalid values of
the Youtube start time and playlist parameters.
2015-02-13 09:46:02 +13:00
Paul Nicholls 40b72c27e8 MDL-49059 medialib: Support links to Youtube videos within playlists
As well as embedding playlists, you can embed specific videos from them -
resulting in the playlist UI displaying, but starting with the specified
video rather than the first in the playlist.  Previously, just the
specified video would embed - without the playlist UI.
2015-02-13 09:46:02 +13:00
Paul Nicholls f266c90917 MDL-49059 medialib: Support start time params in Youtube URLs
Medialib (and thus the Multimedia Plugins filter) was ignoring start time
parameters on YouTube video URLs, meaning that the video would always
start at the start, even when the appropriate parameter was present.
2015-02-13 09:46:02 +13:00
Paul Nicholls 71ce7d03ee MDL-49059 medialib: Add tests for Youtube videos within playlists
As well as embedding playlists, you can embed specific videos from them -
resulting in the playlist UI displaying, but starting with the specified
video rather than the first in the playlist.  These URLs should be covered
by the tests to ensure that we're handling them properly.
2015-02-13 09:46:01 +13:00
Paul Nicholls 7c339df7cb MDL-49059 medialib: Add test cases for Youtube start times
Add test cases to core_medialib_testcase to cover YouTube videos with
start times.
2015-02-13 09:46:01 +13:00
Tim Hunt 8f990cc5bf MDL-49154 behat: step to type with focus on a given element 2015-02-12 20:15:49 +00:00
Andreas Grabs 51112014d2 MDL-49169 user - After MDL-48978-Fix description is not saved anymore 2015-02-12 12:26:03 +01:00
Mike Grant 361370bae3 MDL-37470 blocklib: Respect block weight and offset 2015-02-12 09:43:13 +00:00
David Monllao 201f5085c6 weekly release 2.8.3+ 2015-02-12 15:30:23 +08:00
David Monllao ea836818a5 Merge branch 'install_28_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_28_STABLE 2015-02-12 15:30:21 +08:00
David Monllao 2fb32e8591 Revert "Merge branch 'MDL-36009-28' of git://github.com/jethac/moodle into MOODLE_28_STABLE"
This reverts commit e89bda0f80, reversing
changes made to bec8c20cab.
2015-02-12 13:46:31 +08:00
Ruslan Kabalin d7e275f123 MDL-48841 admin: Fix scheduled task reset to defaults finctionality.
It is safe to make fields as non-required, because form validation will not
pass through any empty field anyway.
2015-02-11 11:18:40 +00:00
Marina Glancy 0a976df90c MDL-49003 login: prevent signup when user is logged in 2015-02-11 00:04:25 +01:00
AMOS bot 924ef95068 Automatically generated installer lang files 2015-02-11 00:04:12 +08:00
Eloy Lafuente (stronk7) 67c51ec7ec Merge branch 'MDL-48910_block_my_28' of https://github.com/andyjdavis/moodle into MOODLE_28_STABLE 2015-02-10 13:22:51 +01:00
Sara Cenni 6473207888 MDL-40776 grade: fix query for report outcomes
Add a missing space to the query for report outcomes to avoid error with Oracle.
2015-02-10 11:52:02 +01:00
David Monllao da6815741e MDL-48679 gradebook: Fixing trailing whitespace 2015-02-10 17:54:40 +08:00
David Monllao 537fd32c02 Merge branch 'MDL-48679-28' of git://github.com/lameze/moodle into MOODLE_28_STABLE 2015-02-10 17:53:19 +08:00
Simey Lameze 9461ad93fd MDL-48679 gradebook: fix grade publishing feature 2015-02-10 17:40:29 +08:00
Simey Lameze 32a491a8d2 MDL-48679 gradebook: helper methods for grade publishing 2015-02-10 17:40:29 +08:00
Dan Poltawski f4241a5974 Merge branch 'wip-mdl-49081-m28' of https://github.com/rajeshtaneja/moodle into MOODLE_28_STABLE 2015-02-10 09:17:58 +00:00
David Monllao 1c65824b82 MDL-48805 theme: Fixing trailing whitespace 2015-02-10 15:46:31 +08:00
David Monllao f556dce6a5 Merge branch 'm28_MDL-48805' of git://github.com/totara/moodle into MOODLE_28_STABLE 2015-02-10 15:27:04 +08:00
Andrew Davis 0cce3ea50d MDL-48910 core_block: user_can_addto() respects applicable formats 2015-02-10 08:17:32 +01:00
Mark Nelson 52781ec82f MDL-48884 mod_assign: prevented setting gradebook feedback unnecessarily 2015-02-09 22:18:15 -08:00
David Monllao 2ee301e041 Merge branch 'm28_MDL-49064' of git://github.com/totara/moodle into MOODLE_28_STABLE 2015-02-10 11:57:47 +08:00
David Monllao fdc6ac362e Merge branch 'MDL-48960-28' of git://github.com/danpoltawski/moodle into MOODLE_28_STABLE 2015-02-10 11:12:33 +08:00
Matt Porritt ceee804962 MDL-49034 enrol_self: Enforce maxlength in self enrolment form fields.
Alter self enrolment creation form to enforce max field lengths.
Limit "Custom instance name" (name) form field to 255 characters via maxlength.
Limit "Enrolment key" (password) form field to 50 characters via maxlength.

Fix for when the form is submitted causing a database write error to be thrown
as corresponding field "name" in the table mdl_enrol is set to varchar(255) and
database field "password" is varying(50).
2015-02-10 13:21:02 +11:00
Eloy Lafuente (stronk7) f16383191b Merge branch 'MDL-48964_28' of git://github.com/jmvedrine/moodle into MOODLE_28_STABLE 2015-02-10 01:10:17 +01:00
Eloy Lafuente (stronk7) 1e968e2d27 Merge branch 'MDL-49073-28' of git://github.com/jethac/moodle into MOODLE_28_STABLE 2015-02-10 01:04:57 +01:00
Dan Poltawski fa75bb63e3 Merge branch 'MDL-48544-28' of git://github.com/andrewnicols/moodle into MOODLE_28_STABLE 2015-02-09 22:42:14 +00:00
Eloy Lafuente (stronk7) d71119dbc5 Merge branch 'wip_MDL-49125_m28_install' of https://github.com/skodak/moodle into MOODLE_28_STABLE 2015-02-09 20:02:05 +01:00
Eloy Lafuente (stronk7) b60a617d3d Merge branch 'MDL-48357-28' of git://github.com/jleyva/moodle into MOODLE_28_STABLE 2015-02-09 15:51:56 +01:00
Dan Poltawski a1504fd7bc Merge branch 'wip-MDL-47558-m28' of git://github.com/marinaglancy/moodle into MOODLE_28_STABLE 2015-02-09 14:50:37 +00:00
Andrew Nicols 531cc5c727 MDL-48544 blocks: Only add docked tags if all blocks are docked
Previously, if all blocks were hidden, then the region was reported as
being docked eroniously and it was not possible to unhide the blocks.

Docking should have no relation to the presence of block content.
2015-02-09 20:55:44 +08:00
Eloy Lafuente (stronk7) 17f0e2a4af Merge branch 'wip-MDL-48794-m28' of git://github.com/marinaglancy/moodle into MOODLE_28_STABLE 2015-02-09 13:05:16 +01:00
Dan Poltawski 6561015165 Merge branch 'MDL-44520-28' of git://github.com/xow/moodle into MOODLE_28_STABLE 2015-02-09 11:33:14 +00:00
Dan Poltawski 69d4a9b94f Merge branch 'MDL-48294-28' of git://github.com/jleyva/moodle into MOODLE_28_STABLE 2015-02-09 11:28:21 +00:00
Dan Poltawski de90103193 Merge branch 'MDL_47085_28' of https://github.com/totara/openbadges into MOODLE_28_STABLE 2015-02-09 10:29:19 +00:00
Dan Poltawski e470238304 Merge branch 'MDL-47953-28' of git://github.com/FMCorz/moodle into MOODLE_28_STABLE 2015-02-09 10:21:42 +00:00
David Monllao 4d31580f93 Merge branch 'MDL-42138-28' of git://github.com/xow/moodle into MOODLE_28_STABLE 2015-02-09 17:18:48 +08:00
David Monllao e89bda0f80 Merge branch 'MDL-36009-28' of git://github.com/jethac/moodle into MOODLE_28_STABLE 2015-02-09 16:59:28 +08:00
Damyon Wiese 68b7d5ce4a MDL-48543 Mathjax: Update default config for JAWS Math player
JAWS Maths player does not recognise the math content when manually specifying the config for MathJax.
If you use one of the default config files it works.
So - we switch our config to the Accessible.js config that it is based off anyway.
There are no features changes with this approach.
2015-02-09 16:32:32 +08:00
Jetha Chan 1f70c8582d MDL-36009 grader_gradereport: filler and extra user cells should not be headers 2015-02-09 13:53:21 +08:00
Yuliya Bozhko 6db8c22913 MDL-47085 badges: Fix badges file download issues
Signed-off-by: Yuliya Bozhko <yuliya.bozhko@totaralms.com>
2015-02-09 16:01:09 +13:00
Petr Skoda 8b198fec72 MDL-49125 install: fix installer notices 2015-02-07 13:13:27 +13:00
Adrian Greeve bec8c20cab MDL-48038 mod_tag: Unit tests for tag cron functions. 2015-02-06 14:50:11 +08:00
Adrian Greeve 3359719ce9 MDL-48038 mod_tag: Improvement of tag cron. 2015-02-06 14:50:11 +08:00
Marina Glancy 9c6dab862a MDL-47558 resource: allow to edit module without being redirected
Thanks to Nathan Lewis for the code suggestion
2015-02-06 13:14:18 +08:00
Rajesh Taneja 6da3248b9f MDL-49110 behat: No expand form required in non-js mode 2015-02-06 13:06:52 +08:00
Tony Levi bd8926f9f3 MDL-49110 behat: Do not poll within spin for non-javascript mode 2015-02-06 13:06:44 +08:00
John Okely 93aa18b8de MDL-44520 behat: Change behat features to use new section selectors 2015-02-06 10:34:59 +08:00
John Okely 4dd5623f18 MDL-44520 behat: Add behat selectors for section, activity 2015-02-06 10:34:59 +08:00
John Okely 722e179f30 MDL-42138 user: Require custom profile fields when registering as guest
Previously when someone registers after logging in as a guest, required
custom profile fields would not be required.

Thanks to Andreas Diendorfer for providing the patch.
2015-02-06 10:11:42 +08:00
Tim Hunt c3ab0b8bbf MDL-49041 qtype_multianswer: don't reveal marks on partial responses
This commit also fixes MDL-32049 about the lack or valdiation message
when an incomplete respnses is submitted.

AMOS BEGIN
 CPY [pleaseananswerallparts,qtype_match],[pleaseananswerallparts,qtype_multianswer]
AMOS END
2015-02-05 20:00:53 +00:00
Jean-Michel Vedrine cc8ac87f01 MDL-48964 mod_lesson: Errors when updating matching questions 2015-02-05 13:23:51 +01:00
Dan Poltawski 96dc38c46a weekly release 2.8.3+ 2015-02-05 10:07:22 +00:00
Dan Poltawski 354e304f29 Merge branch 'install_28_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_28_STABLE 2015-02-05 10:07:20 +00:00
Dan Poltawski 89b92ecbb9 MDL-48960 output: use nofollow attribute to stop crawling invalid links
Both the calendar set url and switch theme links are displayed to
non-logged in users which mean they get crawled by search bots. This
prevents the search bots following these links.
2015-02-05 08:14:02 +00:00
Frederic Massart 37dd88e750 MDL-47953 gradereport_grader: Accurate pagination with suspended users
Thanks to Zvonko Martinovic for pointing out the source of the bug.
2015-02-05 15:08:21 +08:00
AMOS bot 1e826d374e Automatically generated installer lang files 2015-02-05 00:04:10 +08:00
Juan Leyva 14a59f1eee MDL-48294 settings: enablemobilewebservice appears twice 2015-02-04 10:27:00 +01:00
Jetha Chan f4966d09b2 MDL-49073 timezones: update to 2015a (2323 rules) 2015-02-04 13:19:31 +08:00
Rajesh Taneja d603a9c792 MDL-49081 tests: Removed dev option from composer
dev option is enabled by default in composer, so not required.
https://github.com/composer/composer/blob/master/CHANGELOG.md
2015-02-04 10:21:01 +08:00
Dan Poltawski 7606f81a88 Merge branch 'MDL-48942_survey_28' of https://github.com/andyjdavis/moodle into MOODLE_28_STABLE 2015-02-03 15:55:24 +00:00
Dan Poltawski abb61b1a65 Merge branch 'MDL-48955-28' of https://github.com/vadimonus/moodle into MOODLE_28_STABLE 2015-02-03 14:04:37 +00:00
Dan Poltawski 14caa61bd4 Merge branch 'wip-mdl-49002-m28' of https://github.com/rajeshtaneja/moodle into MOODLE_28_STABLE 2015-02-03 13:16:53 +00:00
Dan Poltawski 45acb77a3f Merge branch 'm28_MDL-48799_Incorrect_Legacy_Dir_Fallback' of https://github.com/scara/moodle into MOODLE_28_STABLE 2015-02-03 13:13:25 +00:00
Dan Poltawski 9e98e66cb2 Merge branch 'm28_MDL-48907' of https://github.com/totara/moodle into MOODLE_28_STABLE 2015-02-03 12:56:44 +00:00
Eloy Lafuente (stronk7) b7f6f1c601 MDL-48920 tool_generator: fix unit tests 2015-02-03 12:39:30 +00:00
Dan Poltawski 8bde103118 Merge branch 'MDL-44071-28' of git://github.com/zbdd/moodle into MOODLE_28_STABLE 2015-02-03 12:17:20 +00:00
Dan Poltawski ed67b6fb06 Merge branch 'MDL-48533_m28' of https://github.com/markn86/moodle into MOODLE_28_STABLE 2015-02-03 11:13:50 +00:00
Dan Poltawski 4151d0aa1f MDL-48624 behat: fix trailing whitespace 2015-02-03 11:02:20 +00:00
Dan Poltawski 8bca20b7ec Merge branch 'wip-mdl-48624-m28' of https://github.com/rajeshtaneja/moodle into MOODLE_28_STABLE 2015-02-03 11:01:57 +00:00
Eloy Lafuente (stronk7) a6de116442 Merge branch 'wip-mdl-48403-m28' of https://github.com/rajeshtaneja/moodle into MOODLE_28_STABLE 2015-02-03 11:57:53 +01:00
Eloy Lafuente (stronk7) 314c64ef2f Merge branch 'wip-mdl-49015-m28' of https://github.com/rajeshtaneja/moodle into MOODLE_28_STABLE 2015-02-03 11:52:22 +01:00
Andrew Nicols a43f2c6338 Merge branch 'MDL-48865-28' of git://github.com/xow/moodle into MOODLE_28_STABLE 2015-02-03 16:41:30 +08:00
Neill Magill 401697c397 MDL-48865 core_block: Show regions with only hidden blocks when editing
Before this patch if all the blocks in a block region are set to hidden the region will be docked even when editing is enabled.
This meant that as a user I would need to add a new block to the page and move it to that region via the configuration
menu before I could manipulate the hidden blocks again.
2015-02-03 16:14:36 +08:00
Andrew Nicols 8060291174 Merge branch 'MDL-48920-28' of git://github.com/FMCorz/moodle into MOODLE_28_STABLE 2015-02-03 16:11:44 +08:00
Andrew Nicols 45c07b94fd Merge branch 'tgz_fixing28' of https://github.com/tlevi/moodle into MOODLE_28_STABLE 2015-02-03 16:03:48 +08:00
Andrew Nicols 5b8a93a867 Merge branch '48968-28' of git://github.com/samhemelryk/moodle into MOODLE_28_STABLE 2015-02-03 14:24:42 +08:00
Andrew Nicols 93e95c2579 Merge branch 'MDL-48929-28' of git://github.com/FMCorz/moodle into MOODLE_28_STABLE 2015-02-03 14:09:53 +08:00
Andrew Nicols 8298719c51 MDL-48484 admin: Improve coding style 2015-02-03 13:43:29 +08:00
Andrew Nicols 76ec958619 Merge branch 'm28_MDL-48484' of https://github.com/totara/moodle into MOODLE_28_STABLE 2015-02-03 13:16:36 +08:00
Andrew Nicols fa224641d8 Merge branch 'm28_MDL-46467' of https://github.com/totara/moodle into MOODLE_28_STABLE 2015-02-03 12:59:12 +08:00
Andrew Nicols d9324ce9ee Merge branch 'MDL-48608_m28' of git://github.com/markn86/moodle into MOODLE_28_STABLE 2015-02-03 12:31:06 +08:00
Mark Nelson 7728a2cae3 MDL-48608 mod_assign: correctly display grades for group assignments 2015-02-02 20:16:18 -08:00
Eloy Lafuente (stronk7) 36125f82fa Merge branch 'MDL-48525-28' of git://github.com/jleyva/moodle into MOODLE_28_STABLE 2015-02-03 00:57:46 +01:00
Eloy Lafuente (stronk7) 9555ae2d10 Merge branch 'MDL-48578-28' of git://github.com/jleyva/moodle into MOODLE_28_STABLE 2015-02-03 00:47:40 +01:00
Brian Barnes 8ead44805a MDL-49064 bootstrapbase: fixed rtl alignment of leftalign CSS class 2015-02-03 09:19:29 +13:00
David Monllao e2d914b204 Merge branch 'MDL-31036-28' of git://github.com/zbdd/moodle into MOODLE_28_STABLE 2015-02-02 14:55:01 +08:00
David Monllao 47c6fb2bd3 Merge branch 'MDL-48772-28' of git://github.com/xow/moodle into MOODLE_28_STABLE 2015-02-02 12:29:42 +08:00
David Monllao 8bb969d6cc Merge branch 'wip-mdl-46626-m28' of git://github.com/rajeshtaneja/moodle into MOODLE_28_STABLE 2015-02-02 12:08:37 +08:00
Brian Barnes dcde7ca176 MDL-48484 admin: Added labels to configtime settings 2015-02-02 16:34:36 +13:00
AMOS bot 798790c4e8 Automatically generated installer lang files 2015-02-02 00:04:06 +08:00
Matteo Scaramuccia 48a515c37b MDL-48799 Files API: fixed legacy directory fallback. 2015-02-01 09:16:41 +01:00
Zachary Durber 07f99ca6d6 MDL-31036 mod_assign: Don't strip quickgrading feedback of special chars 2015-01-30 14:37:55 +08:00
John Okely b4ac530cf2 MDL-48772 enrol_cohort: Replace hardcoded language with language strings 2015-01-30 11:36:06 +08:00
Rajesh Taneja b3486b0192 MDL-48403 behat: Select text in atto editor before inserting image 2015-01-30 10:10:46 +08:00
Tyler Bannister ab4a3e8cb1 MDL-46626 report_log: Removed HTML from log report export
This is a partial backport of MDL-34867
2015-01-30 09:09:37 +08:00
Rajesh Taneja c9d53c1e17 MDL-49002 mod_lesson: Added @_file_upload tag to avoid random fails 2015-01-30 09:01:13 +08:00
Rajesh Taneja 66293e8414 MDL-49015 mod_lesson: Removed unused image insert step in behat 2015-01-30 08:58:52 +08:00
Rajesh Taneja f8fe046fb5 MDL-49015 mod_lesson: Don't rely on external links in behat 2015-01-30 08:58:52 +08:00
Rajesh Taneja a686d8374a MDL-48624 behat: Added page load check in workshop step
i_allocate_submissions_in_workshop_as step sometimes
fails because of server speed. Added page load check
with extended timout.
2015-01-30 08:55:30 +08:00
Rajesh Taneja c441c21e7a MDL-48624 behat: Added extended timeout to ensure step pass
following_should_download_between_and_bytes step sometimes
fails because of server speed. Added extended timout
ensuring they wait enough before failing.
Also, not calling force download while running behat site
2015-01-30 08:55:29 +08:00
Vadim Dvorovenko d3f49a8c84 MDL-48955 filter_mathjax: Regexp fix for texfiltercompatibility mode
Fixing incorrect regexp for replacing text like
"$$a$$ and $$b$$" to "\(a\) and \(b\)". This is needed for
texfiltercompatibility to work as expected.
2015-01-29 23:16:51 +07:00
Juan Leyva 060c2d3c9c MDL-48357 webservices: Missing instance property in course contents ws 2015-01-29 14:15:16 +01:00
Tony Levi 846711d69f MDL-48924 backup: Fix some get_file_packer() calls for enabletgzbackups 2015-01-29 22:53:14 +10:30
Juan Leyva 6dbf42a600 MDL-48525 webservices: Fixed profile user image is not always returned 2015-01-28 17:20:37 +01:00
Juan Leyva 4a97b8476b MDL-48578 webservices: Fixed missing required library 2015-01-28 14:44:48 +01:00
James Henestofel 9f5571d405 MDL-44071 webservices: Sorting courses post deletion.
Signed-off-by: Zachary Durber <zdurber@gmail.com>
2015-01-27 11:40:58 +08:00
Frederic Massart fa5aa434bd MDL-48920 tool_generator: Use 'real' names during course generation 2015-01-27 11:27:55 +08:00
Brian Barnes 1ff8d56a2e MDL-46467 forms: Labels have "for" attribute even when frozen 2015-01-27 14:55:26 +13:00
Andrew Davis 2e77d5ec7b MDL-48942 mod_survey: synced security checks in view.php and graph.php 2015-01-26 15:06:28 +01:00
Brian Barnes e5a35eb25f MDL-48805 theme: Collapse now collapses all data-target 2015-01-26 11:32:10 +13:00
Valerii Kuznetsov d5da6e42c2 MDL-48968 blocks: fixed bug with pagetype handling 2015-01-26 09:28:41 +13:00
Nelson Moller 116dd8a02f MDL-48929 repository_filesystem: Valide relative path against realpath
On Windows systems, there could have been a mix of back and forward
slashes, causing the validation of the relative path to fail. Now
we will always get the realpath before comparing.
2015-01-23 17:28:19 +08:00
Brian Barnes 044b689308 MDL-48907 grades: fixed display of grade tabs 2015-01-21 10:37:54 +13:00
Marina Glancy 054609f8b0 MDL-48794 report_log: make sure y-axis gridlines in graphs are integers 2015-01-12 16:21:37 +08:00
Mark Nelson 7bc0151a4c MDL-48533 report_backups: added ability to view backup logs 2015-01-07 22:25:04 -08:00
Mark Nelson 85f5d4ac95 MDL-48533 core_backup: use default log level when none specified 2015-01-07 22:25:03 -08:00
207 changed files with 5641 additions and 3091 deletions
-3
View File
@@ -278,9 +278,6 @@ if ($hassiteconfig) {
$ADMIN->add('webservicesettings', new admin_externalpage('webservicedocumentation', new lang_string('wsdocapi', 'webservice'), "$CFG->wwwroot/$CFG->admin/webservice/documentation.php", 'moodle/site:config', false));
/// manage service
$temp = new admin_settingpage('externalservices', new lang_string('externalservices', 'webservice'));
$temp->add(new admin_setting_enablemobileservice('enablemobilewebservice',
new lang_string('enablemobilewebservice', 'admin'),
new lang_string('configenablemobilewebservice', 'admin', $enablemobiledoclink), 0));
$temp->add(new admin_setting_heading('manageserviceshelpexplaination', new lang_string('information', 'webservice'), new lang_string('servicehelpexplanation', 'webservice')));
$temp->add(new admin_setting_manageexternalservices());
$ADMIN->add('webservicesettings', $temp);
@@ -308,8 +308,7 @@ class tool_generator_course_backend extends tool_generator_backend {
$username = 'tool_generator_' . $textnumber;
// Create user account.
$record = array('firstname' => get_string('firstname', 'tool_generator'),
'lastname' => $number, 'username' => $username);
$record = array('username' => $username, 'idnumber' => $number);
// We add a user password if it has been specified.
if (!empty($CFG->tool_generator_users_password)) {
@@ -62,7 +62,6 @@ $string['error_nonexistingcourse'] = 'The specified course does not exist';
$string['error_nopageinstances'] = 'The selected course does not contain page module instances';
$string['error_notdebugging'] = 'Not available on this server because debugging is not set to DEVELOPER';
$string['error_nouserspassword'] = 'You need to set $CFG->tool_generator_users_password in config.php to generate the test plan';
$string['firstname'] = 'Test course user';
$string['fullname'] = 'Test course: {$a->size}';
$string['maketestcourse'] = 'Make test course';
$string['maketestplan'] = 'Make JMeter test plan';
@@ -136,7 +136,7 @@ class tool_generator_maketestcourse_testcase extends advanced_testcase {
$lastusernumber = 0;
$discussionstarters = array();
foreach ($discussions as $discussion) {
$usernumber = intval($discussion->lastname);
$usernumber = core_user::get_user($discussion->userid, 'id, idnumber')->idnumber;
// Checks that the users are odd numbers.
$this->assertEquals(1, $usernumber % 2);
+2 -28
View File
@@ -156,7 +156,7 @@ class controller {
$updateablelangs = array();
foreach ($currentlangs as $clang) {
if (!array_key_exists($clang, $md5array)) {
$noticeok[] = get_string('langpackupdateskipped', 'tool_langimport', $clang);
$this->info[] = get_string('langpackupdateskipped', 'tool_langimport', $clang);
continue;
}
$dest1 = $CFG->dataroot.'/lang/'.$clang;
@@ -175,36 +175,10 @@ class controller {
}
}
// Clean-up currently installed versions of the packs.
foreach ($neededlangs as $packindex => $pack) {
if ($pack == 'en') {
continue;
}
// Delete old directories.
$dest1 = $CFG->dataroot.'/lang/'.$pack;
$dest2 = $CFG->dirroot.'/lang/'.$pack;
if (file_exists($dest1)) {
if (!remove_dir($dest1)) {
$noticeerror[] = 'Could not delete old directory '.$dest1.', update of '.$pack
.' failed, please check permissions.';
unset($neededlangs[$packindex]);
continue;
}
}
if (file_exists($dest2)) {
if (!remove_dir($dest2)) {
$noticeerror[] = 'Could not delete old directory '.$dest2.', update of '.$pack
.' failed, please check permissions.';
unset($neededlangs[$packindex]);
continue;
}
}
}
try {
$updated = $this->install_languagepacks($neededlangs, true);
} catch (\moodle_exception $e) {
$this->errors[] = 'An exception occurred while installing language packs: ' . $e->getMessage();
return false;
}
@@ -58,27 +58,22 @@ class tool_task_edit_scheduled_task_form extends moodleform {
$mform->addElement('text', 'minute', get_string('taskscheduleminute', 'tool_task'));
$mform->setType('minute', PARAM_RAW);
$mform->addHelpButton('minute', 'taskscheduleminute', 'tool_task');
$mform->addRule('minute', get_string('required'), 'required');
$mform->addElement('text', 'hour', get_string('taskschedulehour', 'tool_task'));
$mform->setType('hour', PARAM_RAW);
$mform->addHelpButton('hour', 'taskschedulehour', 'tool_task');
$mform->addRule('hour', get_string('required'), 'required');
$mform->addElement('text', 'day', get_string('taskscheduleday', 'tool_task'));
$mform->setType('day', PARAM_RAW);
$mform->addHelpButton('day', 'taskscheduleday', 'tool_task');
$mform->addRule('day', get_string('required'), 'required');
$mform->addElement('text', 'month', get_string('taskschedulemonth', 'tool_task'));
$mform->setType('month', PARAM_RAW);
$mform->addHelpButton('month', 'taskschedulemonth', 'tool_task');
$mform->addRule('month', get_string('required'), 'required');
$mform->addElement('text', 'dayofweek', get_string('taskscheduledayofweek', 'tool_task'));
$mform->setType('dayofweek', PARAM_RAW);
$mform->addHelpButton('dayofweek', 'taskscheduledayofweek', 'tool_task');
$mform->addRule('dayofweek', get_string('required'), 'required');
$mform->addElement('advcheckbox', 'disabled', get_string('disabled', 'tool_task'));
$mform->addHelpButton('disabled', 'disabled', 'tool_task');
@@ -0,0 +1,53 @@
@tool @tool_task @javascript
Feature: Manage scheduled tasks
In order to configure scheduled tasks
As an admin
I need to be able to disable, enable, edit and reset to default scheduled tasks
Background:
Given I log in as "admin"
And I navigate to "Scheduled tasks" node in "Site administration > Server"
Scenario: Disable scheduled task
When I click on "Edit task schedule: Log table cleanup" "link" in the "Log table cleanup" "table_row"
Then I should see "Edit task schedule: Log table cleanup"
And I set the following fields to these values:
| disabled | 1 |
And I press "Save changes"
Then I should see "Changes saved"
And I should see "Task disabled" in the "Log table cleanup" "table_row"
Scenario: Enable scheduled task
When I click on "Edit task schedule: Log table cleanup" "link" in the "Log table cleanup" "table_row"
Then I should see "Edit task schedule: Log table cleanup"
And I set the following fields to these values:
| disabled | 0 |
And I press "Save changes"
Then I should see "Changes saved"
And I should not see "Task disabled" in the "Log table cleanup" "table_row"
Scenario: Edit scheduled task
When I click on "Edit task schedule: Log table cleanup" "link" in the "Log table cleanup" "table_row"
Then I should see "Edit task schedule: Log table cleanup"
And I set the following fields to these values:
| minute | */5 |
| hour | 1 |
| day | 2 |
| month | 3 |
| dayofweek | 4 |
And I press "Save changes"
Then I should see "Changes saved"
And the following should exist in the "admintable" table:
| Component | Minute | Hour | Day | Day of week | Month |
| Standard log | */5 | 1 | 2 | 4 | 3 |
Scenario: Reset scheduled task to default
When I click on "Edit task schedule: Log table cleanup" "link" in the "Log table cleanup" "table_row"
Then I should see "Edit task schedule: Log table cleanup"
And I set the following fields to these values:
| resettodefaults | 1 |
And I press "Save changes"
Then I should see "Changes saved"
And the following should not exist in the "admintable" table:
| Name | Component | Minute | Hour | Day | Day of week | Month |
| Log table cleanup | Standard log | */5 | 1 | 2 | 4 | 3 |
+7
View File
@@ -157,6 +157,13 @@ class external_service_form extends moodleform {
$errors = parent::validation($data, $files);
// Add field validation check for duplicate name.
if ($webservice = $DB->get_record('external_services', array('name' => $data['name']))) {
if (empty($data['id']) || $webservice->id != $data['id']) {
$errors['name'] = get_string('nameexists', 'webservice');
}
}
// Add field validation check for duplicate shortname.
// Allow duplicated "empty" shortnames.
if (!empty($data['shortname'])) {
+2 -1
View File
@@ -143,7 +143,8 @@ class auth_plugin_shibboleth extends auth_plugin_base {
$configarray = (array) $this->config;
$moodleattributes = array();
foreach ($this->userfields as $field) {
$userfields = array_merge($this->userfields, $this->get_custom_user_profile_fields());
foreach ($userfields as $field) {
if (isset($configarray["field_map_$field"])) {
$moodleattributes[$field] = $configarray["field_map_$field"];
}
+1 -1
View File
@@ -138,7 +138,7 @@ urn:mace:organization2:providerID, Example Organization 2, /Shibboleth.sso/WAYF/
<?php
print_auth_lock_options($this->authtype, $user_fields, '<!-- empty help -->', true, false);
print_auth_lock_options($this->authtype, $user_fields, '<!-- empty help -->', true, false, $this->get_custom_user_profile_fields());
?>
</table>
@@ -109,17 +109,17 @@ Feature: display_availability
# Page 1 display still there but should be dimmed and not a link.
Then I should see "Page 1" in the "#section-1 .dimmed_text" "css_element"
And ".activityinstance a" "css_element" should not exist in the "#section-1" "css_element"
And ".activityinstance a" "css_element" should not exist in the "Topic 1" "section"
# Date display should be present.
And I should see "Available until" in the "#section-1" "css_element"
And I should see "Available until" in the "Topic 1" "section"
# Page 2 display not there at all
And I should not see "Page 2" in the "region-main" "region"
# Page 3 display and link
And I should see "Page 3" in the "region-main" "region"
And ".activityinstance a" "css_element" should exist in the "#section-3" "css_element"
And ".activityinstance a" "css_element" should exist in the "Topic 3" "section"
@javascript
Scenario: Section availability display
@@ -66,7 +66,7 @@ abstract class backup_factory {
// Create database_logger, observing $CFG->backup_database_logger_level and defaulting to LOG_WARNING
// and pointing to the backup_logs table
$dllevel = isset($CFG->backup_database_logger_level) ? $CFG->backup_database_logger_level : backup::LOG_WARNING;
$dllevel = isset($CFG->backup_database_logger_level) ? $CFG->backup_database_logger_level : $dfltloglevel;
$columns = array('backupid' => $backupid);
$enabledloggers[] = new database_logger($dllevel, 'timecreated', 'loglevel', 'message', 'backup_logs', $columns);
@@ -34,6 +34,6 @@ Feature: Duplicate activities
| Name | Duplicated database name |
| Description | Duplicated database description |
And I press "Save and return to course"
Then I should see "Original database name" in the "#section-1" "css_element"
And I should see "Duplicated database name" in the "#section-1" "css_element"
Then I should see "Original database name" in the "Topic 1" "section"
And I should see "Duplicated database name" in the "Topic 1" "section"
And "Original database name" "link" should appear before "Duplicated database name" "link"
@@ -126,5 +126,5 @@ Feature: Restore Moodle 2 course backups
And section "3" should be hidden
And section "7" should be hidden
And section "15" should be visible
And I should see "Test URL name" in the "#section-3" "css_element"
And I should see "Test forum name" in the "#section-1" "css_element"
And I should see "Test URL name" in the "Topic 3" "section"
And I should see "Test forum name" in the "Topic 1" "section"
+1 -1
View File
@@ -49,7 +49,7 @@ $assertion = filter_input(
// Audience is the site url scheme + host + port only.
$wwwparts = parse_url($CFG->wwwroot);
$audience = $wwwparts['scheme'] . '://' . $wwwparts['host'];
$audience .= isset($wwwparts['port']) ? $wwwparts['port'] : '';
$audience .= isset($wwwparts['port']) ? ':' . $wwwparts['port'] : '';
$params = 'assertion=' . urlencode($assertion) . '&audience=' .
urlencode($audience);
+5 -6
View File
@@ -26,6 +26,7 @@
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
require_once($CFG->libdir . '/filelib.php');
$id = required_param('hash', PARAM_ALPHANUM);
$bake = optional_param('bake', 0, PARAM_BOOL);
@@ -37,12 +38,10 @@ $badge = new issued_badge($id);
if ($bake && ($badge->recipient->id == $USER->id)) {
$name = str_replace(' ', '_', $badge->badgeclass['name']) . '.png';
ob_start();
$file = badges_bake($id, $badge->badgeid);
header('Content-Type: image/png');
header('Content-Disposition: attachment; filename="'. $name .'"');
readfile($file);
ob_flush();
$filehash = badges_bake($id, $badge->badgeid, $USER->id, true);
$fs = get_file_storage();
$file = $fs->get_file_by_hash($filehash);
send_stored_file($file, 0, 0, true, array('filename' => $name));
}
$PAGE->set_url('/badges/badge.php', array('hash' => $id));
+5 -8
View File
@@ -26,6 +26,7 @@
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
require_once($CFG->libdir . '/filelib.php');
$page = optional_param('page', 0, PARAM_INT);
$search = optional_param('search', '', PARAM_CLEAN);
@@ -71,17 +72,13 @@ if ($hide) {
require_sesskey();
$badge = new badge($download);
$name = str_replace(' ', '_', $badge->name) . '.png';
ob_start();
$file = badges_bake($hash, $download);
header('Content-Type: image/png');
header('Content-Disposition: attachment; filename="'. $name .'"');
readfile($file);
ob_flush();
$filehash = badges_bake($hash, $download, $USER->id, true);
$fs = get_file_storage();
$file = $fs->get_file_by_hash($filehash);
send_stored_file($file, 0, 0, true, array('filename' => $name));
} else if ($downloadall) {
require_sesskey();
ob_start();
badges_download($USER->id);
ob_flush();
}
$context = context_user::instance($USER->id);
@@ -25,7 +25,7 @@
$string['activityoverview'] = 'You have {$a}s that need attention';
$string['alwaysshowall'] = 'Always show all';
$string['collapseall'] = 'Collapse all course lists';
$string['configotherexpanded'] = 'If enabled, other courses will be expanded by default unless overriden by user preferences.';
$string['configotherexpanded'] = 'If enabled, other courses will be expanded by default unless overridden by user preferences.';
$string['configpreservestates'] = 'If enabled, the collapsed/expanded states set by the user are stored and used on each load.';
$string['course_overview:addinstance'] = 'Add a new course overview block';
$string['course_overview:myaddinstance'] = 'Add a new course overview block to My home';
+15 -3
View File
@@ -552,9 +552,21 @@ class block_base {
&& $page->context->contextlevel == CONTEXT_USER // Page belongs to a user
&& $page->context->instanceid == $USER->id // Page belongs to this user
&& $page->pagetype == 'my-index') { // Ensure we are on the My Moodle page
$capability = 'block/' . $this->name() . ':myaddinstance';
return $this->has_add_block_capability($page, $capability)
&& has_capability('moodle/my:manageblocks', $page->context);
// If the block cannot be displayed on /my it is ok if the myaddinstance capability is not defined.
$formats = $this->applicable_formats();
// Is 'my' explicitly forbidden?
// If 'all' has not been allowed, has 'my' been explicitly allowed?
if ((isset($formats['my']) && $formats['my'] == false)
|| (empty($formats['all']) && empty($formats['my']))) {
// Block cannot be added to /my regardless of capabilities.
return false;
} else {
$capability = 'block/' . $this->name() . ':myaddinstance';
return $this->has_add_block_capability($page, $capability)
&& has_capability('moodle/my:manageblocks', $page->context);
}
}
$capability = 'block/' . $this->name() . ':addinstance';
@@ -56,3 +56,16 @@ Feature: Add and configure blocks throughout the site
And I follow "Course 1"
And I follow "Turn editing on"
Then I should see "Assign roles in Search forums block"
@javascript
Scenario: Blocks can safely be customised
Given I log in as "admin"
And I click on "My home" "link" in the "Navigation" "block"
And I press "Customise this page"
And I add the "HTML" block
And I configure the "(new HTML block)" block
And I set the following fields to these values:
| Block title | Foo " onload="document.getElementsByTagName('body')[0].remove()" alt="
| Content | Example
When I press "Save changes"
Then I should see "Course overview"
@@ -0,0 +1,49 @@
@core @core_block
Feature: Show hidden blocks in a docked block region when editing
In order to edit blocks in a hidden region
As a teacher
I need to be able to see the blocks when editing is on
Background:
Given the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "course enrolments" exist:
| user | course | role |
| admin | C1 | editingteacher |
And I log in as "admin"
And I follow "Course 1"
And I turn editing mode on
# Hide all the blocks in the non-default region
And I configure the "Search forums" block
And I set the following fields to these values:
| Visible | No |
And I click on "Save changes" "button"
And I configure the "Latest news" block
And I set the following fields to these values:
| Visible | No |
And I click on "Save changes" "button"
And I configure the "Upcoming events" block
And I set the following fields to these values:
| Visible | No |
And I click on "Save changes" "button"
And I configure the "Recent activity" block
And I set the following fields to these values:
| Visible | No |
When I click on "Save changes" "button"
# Editing is on so they should be visible
Then I should see "Search forums"
And I should see "Latest news"
And I should see "Upcoming events"
And I should see "Recent activity"
And I turn editing mode off
# Editing is off, so they should no longer be visible
And I should not see "Search forums"
And I should not see "Latest news"
And I should not see "Upcoming events"
And I should not see "Recent activity"
@javascript
Scenario: Check that a region with only hidden blocks is not docked in editing mode (javascript enabled)
Scenario: Check that a region with only hidden blocks is not docked in editing mode (javascript disabled)
+28
View File
@@ -0,0 +1,28 @@
@core @core_block
Feature: Block visibility
In order to configure blocks visibility
As a teacher
I need to show and hide blocks on a page
Background:
Given the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And I log in as "admin"
And I am on homepage
And I follow "Course 1"
And I follow "Turn editing on"
@javascript
Scenario: Hiding all blocks on the page should remove the column they're in
Given I open the "Search forums" blocks action menu
And I click on "Hide Search forums block" "link" in the "Search forums" "block"
And I open the "Latest news" blocks action menu
And I click on "Hide Latest news block" "link" in the "Latest news" "block"
And I open the "Upcoming events" blocks action menu
And I click on "Hide Upcoming events block" "link" in the "Upcoming events" "block"
And I open the "Recent activity" blocks action menu
When I click on "Hide Recent activity block" "link" in the "Recent activity" "block"
Then ".empty-region-side-post" "css_element" should not exist in the "body" "css_element"
And I follow "Turn editing off"
And ".empty-region-side-post" "css_element" should exist in the "body" "css_element"
+3 -2
View File
@@ -991,7 +991,7 @@ function calendar_filter_controls_element(moodle_url $url, $type) {
$str = get_string('show'.$typeforhumans.'events', 'calendar');
}
$content = html_writer::start_tag('li', array('class' => 'calendar_event'));
$content .= html_writer::start_tag('a', array('href' => $url));
$content .= html_writer::start_tag('a', array('href' => $url, 'rel' => 'nofollow'));
$content .= html_writer::tag('span', $icon, array('class' => $class));
$content .= html_writer::tag('span', $str, array('class' => 'eventname'));
$content .= html_writer::end_tag('a');
@@ -2953,11 +2953,12 @@ function calendar_add_icalendar_event($event, $courseid, $subscriptionid, $timez
$description = '';
} else {
$description = $event->properties['DESCRIPTION'][0]->value;
$description = clean_param($description, PARAM_NOTAGS);
$description = str_replace('\n', '<br />', $description);
$description = str_replace('\\', '', $description);
$description = preg_replace('/\s+/', ' ', $description);
}
$eventrecord->description = clean_param($description, PARAM_NOTAGS);
$eventrecord->description = $description;
// Probably a repeating event with RRULE etc. TODO: skip for now.
if (empty($event->properties['DTSTART'][0]->value)) {
+2 -2
View File
@@ -242,7 +242,7 @@ $CFG->admin = 'admin';
// $CFG->session_memcached_save_path = '127.0.0.1:11211';
// $CFG->session_memcached_prefix = 'memc.sess.key.';
// $CFG->session_memcached_acquire_lock_timeout = 120;
// $CFG->session_memcached_lock_expire = 7200; // Ignored if memcached extension <= 2.1.0
// $CFG->session_memcached_lock_expire = 7200; // Ignored if PECL memcached is below version 2.2.0
//
// Memcache session handler (requires memcached server and memcache extension):
// $CFG->session_handler_class = '\core\session\memcache';
@@ -507,7 +507,7 @@ $CFG->admin = 'admin';
// Uses lock files stored by default in the dataroot. Whether this
// works on clusters depends on the file system used for the dataroot.
//
// "\\core\\lock\\db_row_lock_factory" - DB locking based on table rows.
// "\\core\\lock\\db_record_lock_factory" - DB locking based on table rows.
//
// "\\core\\lock\\postgres_lock_factory" - DB locking based on postgres advisory locks.
//
+12 -6
View File
@@ -77,11 +77,14 @@ class core_course_external extends external_api {
//retrieve the course
$course = $DB->get_record('course', array('id' => $params['courseid']), '*', MUST_EXIST);
//check course format exist
if (!file_exists($CFG->dirroot . '/course/format/' . $course->format . '/lib.php')) {
throw new moodle_exception('cannotgetcoursecontents', 'webservice', '', null, get_string('courseformatnotfound', 'error', '', $course->format));
} else {
require_once($CFG->dirroot . '/course/format/' . $course->format . '/lib.php');
if ($course->id != SITEID) {
// Check course format exist.
if (!file_exists($CFG->dirroot . '/course/format/' . $course->format . '/lib.php')) {
throw new moodle_exception('cannotgetcoursecontents', 'webservice', '', null,
get_string('courseformatnotfound', 'error', $course->format));
} else {
require_once($CFG->dirroot . '/course/format/' . $course->format . '/lib.php');
}
}
// now security checks
@@ -217,6 +220,7 @@ class core_course_external extends external_api {
'id' => new external_value(PARAM_INT, 'activity id'),
'url' => new external_value(PARAM_URL, 'activity url', VALUE_OPTIONAL),
'name' => new external_value(PARAM_RAW, 'activity module name'),
'instance' => new external_value(PARAM_INT, 'instance id', VALUE_OPTIONAL),
'description' => new external_value(PARAM_RAW, 'activity description', VALUE_OPTIONAL),
'visible' => new external_value(PARAM_INT, 'is the module visible', VALUE_OPTIONAL),
'modicon' => new external_value(PARAM_URL, 'activity icon url'),
@@ -849,6 +853,7 @@ class core_course_external extends external_api {
// Check if the current user has enought permissions.
if (!can_delete_course($courseid)) {
fix_course_sortorder();
throw new moodle_exception('cannotdeletecategorycourse', 'error',
'', format_string($course->fullname)." (id: $courseid)");
}
@@ -857,6 +862,7 @@ class core_course_external extends external_api {
}
$transaction->allow_commit();
fix_course_sortorder();
return null;
}
@@ -1028,7 +1034,7 @@ class core_course_external extends external_api {
// Check if we need to unzip the file because the backup temp dir does not contains backup files.
if (!file_exists($backupbasepath . "/moodle_backup.xml")) {
$file->extract_to_pathname(get_file_packer(), $backupbasepath);
$file->extract_to_pathname(get_file_packer('application/vnd.moodle.backup'), $backupbasepath);
}
// Create new course.
+35 -35
View File
@@ -42,18 +42,18 @@ Feature: Course activity controls works as expected
And I click on "Actions" "link" in the "Recent activity" "block"
And I click on "Delete Recent activity block" "link"
And I press "Yes"
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I add a "Forum" to section "1" and I fill the form with:
| Forum name | Test forum name 1 |
| Description | Test forum description 1 |
And I add a "Forum" to section "1" and I fill the form with:
| Forum name | Test forum name 2 |
| Description | Test forum description 2 |
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I indent right "Test forum name 1" activity
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I indent left "Test forum name 1" activity
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I open "Test forum name 1" actions menu
And I click on "Edit settings" "link" in the "Test forum name 1" activity
And I should see "Updating Forum"
@@ -63,38 +63,38 @@ Feature: Course activity controls works as expected
| Description | Just to check that I can edit the description |
| Display description on course page | 1 |
And I click on "Cancel" "button"
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I open "Test forum name 1" actions menu
And I click on "Hide" "link" in the "Test forum name 1" activity
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I delete "Test forum name 1" activity
And I should not see "Test forum name 1" in the "#region-main" "css_element"
And I duplicate "Test forum name 2" activity editing the new copy with:
| Forum name | Edited test forum name 2 |
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I should see "Test forum name 2"
And I should see "Edited test forum name 2"
And I hide section "1"
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And section "1" should be hidden
And all activities in section "1" should be hidden
And I show section "1"
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And section "1" should be visible
And I add the "Section links" block
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I should see "1 2 3 4 5" in the "Section links" "block"
And I click on "2" "link" in the "Section links" "block"
And I <should_see_other_sections_following_block_sections_links> see "Test forum name 2"
Examples:
| courseformat | coursedisplay | targetpage | should_see_other_sections | should_see_other_sections_following_block_sections_links |
| topics | 0 | "Course 1" | should | should |
| topics | 1 | "Topic 1" | should not | should not |
| topics | 1 | "Course 1" | should | should not |
| weeks | 0 | "Course 1" | should | should |
| weeks | 1 | "1 January - 7 January" | should not | should not |
| weeks | 1 | "Course 1" | should | should not |
| courseformat | coursedisplay | targetpage | should_see_other_sections | should_see_other_sections_following_block_sections_links | belowpage |
| topics | 0 | "Course 1" | should | should | "Topic 2" |
| topics | 1 | "Topic 1" | should not | should not | "Topic 2" |
| topics | 1 | "Course 1" | should | should not | "Topic 2" |
| weeks | 0 | "Course 1" | should | should | "8 January - 14 January" |
| weeks | 1 | "1 January - 7 January" | should not | should not | "8 January - 14 January" |
| weeks | 1 | "Course 1" | should | should not | "8 January - 14 January" |
Scenario Outline: General activities course controls using topics and weeks formats, and paged mode and not paged mode works as expected
Given the following "users" exist:
@@ -122,51 +122,51 @@ Feature: Course activity controls works as expected
And I click on "Actions" "link" in the "Recent activity" "block"
And I click on "Delete Recent activity block" "link"
And I press "Yes"
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I add a "Forum" to section "1" and I fill the form with:
| Forum name | Test forum name 1 |
| Description | Test forum description 1 |
And I add a "Forum" to section "1" and I fill the form with:
| Forum name | Test forum name 2 |
| Description | Test forum description 2 |
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I indent right "Test forum name 1" activity
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I indent left "Test forum name 1" activity
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I click on "Edit settings" "link" in the "Test forum name 1" activity
And I should see "Updating Forum"
And I should see "Display description on course page"
And I press "Save and return to course"
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I click on "Hide" "link" in the "Test forum name 1" activity
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I delete "Test forum name 1" activity
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I should not see "Test forum name 1" in the "#region-main" "css_element"
And I duplicate "Test forum name 2" activity editing the new copy with:
| Forum name | Edited test forum name 2 |
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I should see "Test forum name 2"
And I should see "Edited test forum name 2"
And I hide section "1"
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And section "1" should be hidden
And all activities in section "1" should be hidden
And I show section "1"
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And section "1" should be visible
And I add the "Section links" block
And "#section-2" "css_element" <should_see_other_sections> exist
And <belowpage> "section" <should_see_other_sections> exist
And I should see "1 2 3 4 5" in the "Section links" "block"
And I click on "2" "link" in the "Section links" "block"
And I <should_see_other_sections_following_block_sections_links> see "Test forum name 2"
Examples:
| courseformat | coursedisplay | targetpage | should_see_other_sections | should_see_other_sections_following_block_sections_links |
| topics | 0 | "Course 1" | should | should |
| topics | 1 | "Topic 1" | should not | should not |
| topics | 1 | "Course 1" | should | should not |
| weeks | 0 | "Course 1" | should | should |
| weeks | 1 | "1 January - 7 January" | should not | should not |
| weeks | 1 | "Course 1" | should | should not |
| courseformat | coursedisplay | targetpage | should_see_other_sections | should_see_other_sections_following_block_sections_links | belowpage |
| topics | 0 | "Course 1" | should | should | "Topic 2" |
| topics | 1 | "Topic 1" | should not | should not | "Topic 2" |
| topics | 1 | "Course 1" | should | should not | "Topic 2" |
| weeks | 0 | "Course 1" | should | should | "8 January - 14 January" |
| weeks | 1 | "1 January - 7 January" | should not | should not | "8 January - 14 January" |
| weeks | 1 | "Course 1" | should | should not | "8 January - 14 January" |
+4 -4
View File
@@ -29,8 +29,8 @@ Feature: Activities can be moved between sections
Scenario: Move activities in a single page course with Javascript disabled
When I move "Test forum name" activity to section "2"
Then I should see "Test forum name" in the "#section-2" "css_element"
And I should not see "Test forum name" in the "#section-1" "css_element"
Then I should see "Test forum name" in the "Topic 2" "section"
And I should not see "Test forum name" in the "Topic 1" "section"
Scenario: Move activities in the course home with Javascript disabled using paged mode
Given I click on "Edit settings" "link" in the "Administration" "block"
@@ -38,8 +38,8 @@ Feature: Activities can be moved between sections
| Course layout | Show one section per page |
And I press "Save changes"
When I move "Test forum name" activity to section "2"
Then I should see "Test forum name" in the "#section-2" "css_element"
And I should not see "Test forum name" in the "#section-1" "css_element"
Then I should see "Test forum name" in the "Topic 2" "section"
And I should not see "Test forum name" in the "Topic 1" "section"
Scenario: Move activities in a course section with Javascript disabled using paged mode
Given I click on "Edit settings" "link" in the "Administration" "block"
+6 -6
View File
@@ -23,9 +23,9 @@ Feature: Sections can be moved
| Forum name | Test forum name |
| Description | Test forum description |
When I move down section "1"
Then I should see "Test forum name" in the "#section-2" "css_element"
Then I should see "Test forum name" in the "Topic 2" "section"
And I move up section "2"
And I should see "Test forum name" in the "#section-1" "css_element"
And I should see "Test forum name" in the "Topic 1" "section"
Scenario: Move up and down a section with Javascript disabled in the course home of a course using paged mode
Given I click on "Edit settings" "link" in the "Administration" "block"
@@ -36,9 +36,9 @@ Feature: Sections can be moved
| Forum name | Test forum name |
| Description | Test forum description |
When I move down section "1"
Then I should see "Test forum name" in the "#section-2" "css_element"
Then I should see "Test forum name" in the "Topic 2" "section"
And I move up section "2"
And I should see "Test forum name" in the "#section-1" "css_element"
And I should see "Test forum name" in the "Topic 1" "section"
Scenario: Sections can not be moved with Javascript disabled in a section page of a course using paged mode
Given I click on "Edit settings" "link" in the "Administration" "block"
@@ -49,7 +49,7 @@ Feature: Sections can be moved
| Forum name | Test forum name |
| Description | Test forum description |
When I follow "Topic 2"
Then "#section-1" "css_element" should not exist
And "#section-3" "css_element" should not exist
Then "Topic 1" "section" should not exist
And "Topic 3" "section" should not exist
And "Move down" "link" should not exist
And "Move up" "link" should not exist
@@ -11,11 +11,11 @@ Feature: Course paged mode
| Course 1 | C1 | 0 | <courseformat> | 1 | 3 |
And I log in as "admin"
And I follow "Course 1"
Then I click on <section2> "link" in the "#section-2" "css_element"
Then I click on <section2> "link" in the <section2> "section"
And I follow "C1"
And I click on <section3> "link" in the "#section-3" "css_element"
And I click on <section3> "link" in the <section3> "section"
And I follow "C1"
And I click on <section1> "link" in the "#section-1" "css_element"
And I click on <section1> "link" in the <section1> "section"
And I should see <section1> in the "div.single-section" "css_element"
And I should see <section2> in the ".single-section span.mdl-right" "css_element"
And I should not see <prevunexistingsection> in the ".single-section" "css_element"
@@ -44,11 +44,11 @@ Feature: Course paged mode
| Course 1 | C1 | 0 | <courseformat> | 1 | 3 |
And I log in as "admin"
And I follow "Course 1"
Then I click on <section2> "link" in the "#section-2" "css_element"
Then I click on <section2> "link" in the <section2> "section"
And I follow "C1"
And I click on <section3> "link" in the "#section-3" "css_element"
And I click on <section3> "link" in the <section3> "section"
And I follow "C1"
And I click on <section1> "link" in the "#section-1" "css_element"
And I click on <section1> "link" in the <section1> "section"
And I should see <section1> in the "div.single-section" "css_element"
And I should see <section2> in the ".single-section span.mdl-right" "css_element"
And I should not see <prevunexistingsection> in the ".single-section" "css_element"
+1 -1
View File
@@ -1726,7 +1726,7 @@ class core_course_courselib_testcase extends advanced_testcase {
$bc->execute_plan();
$results = $bc->get_results();
$file = $results['backup_destination'];
$fp = get_file_packer();
$fp = get_file_packer('application/vnd.moodle.backup');
$filepath = $CFG->dataroot . '/temp/backup/test-restore-course-event';
$file->extract_to_pathname($fp, $filepath);
$bc->destroy();
+2
View File
@@ -611,12 +611,14 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
$formattedtext = format_text($cm->content, FORMAT_HTML,
array('noclean' => true, 'para' => false, 'filter' => false));
$this->assertEquals($formattedtext, $module['description']);
$this->assertEquals($forumcm->instance, $module['instance']);
$testexecuted = $testexecuted + 1;
} else if ($module['id'] == $labelcm->id and $module['modname'] == 'label') {
$cm = $modinfo->cms[$labelcm->id];
$formattedtext = format_text($cm->content, FORMAT_HTML,
array('noclean' => true, 'para' => false, 'filter' => false));
$this->assertEquals($formattedtext, $module['description']);
$this->assertEquals($labelcm->instance, $module['instance']);
$testexecuted = $testexecuted + 1;
}
}
+2
View File
@@ -263,8 +263,10 @@ class enrol_manual_plugin extends enrol_plugin {
'enrol',
'enrolmentoptions',
'enrolusers',
'enrolxusers',
'errajaxfailedenrol',
'errajaxsearch',
'foundxcohorts',
'none',
'usersearch',
'unlimitedduration',
+2 -2
View File
@@ -451,13 +451,13 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
.append(create('<div class="'+CSS.DETAILS+'"></div>')
.append(create('<div class="'+CSS.COHORTNAME+'">'+cohort.name+'</div>')))
.append(create('<div class="'+CSS.OPTIONS+'"></div>')
.append(create('<input type="button" class="'+CSS.ENROL+'" value="'+'Enrol '+cohort.cnt+' users'+'" />'))) // TODO string
.append(create('<input type="button" class="' + CSS.ENROL + '" value="' + M.util.get_string('enrolxusers', 'enrol', cohort.cnt) + '" />')))
);
}
this.set(UEP.COHORTCOUNT, count);
if (!args.append) {
//var usersstr = (result.response.totalusers == '1')?M.str.enrol.ajaxoneuserfound:M.util.get_string('ajaxxusersfound','enrol', result.response.totalusers);
var cohortsstr = 'Found '+result.response.totalcohorts+' cohorts'; // TODO
var cohortsstr = M.util.get_string('foundxcohorts', 'enrol', result.response.totalcohorts);
var content = create('<div class="'+CSS.SEARCHRESULTS+'"></div>')
.append(create('<div class="'+CSS.TOTALCOHORTS+'">'+cohortsstr+'</div>'))
.append(cohorts);
+2
View File
@@ -759,8 +759,10 @@ class course_enrolment_other_users_table extends course_enrolment_table {
'enrol',
'enrolmentoptions',
'enrolusers',
'enrolxusers',
'errajaxfailedenrol',
'errajaxsearch',
'foundxcohorts',
'none',
'usersearch',
'unlimitedduration',
+6 -2
View File
@@ -39,8 +39,10 @@ class enrol_self_edit_form extends moodleform {
$mform->addElement('header', 'header', get_string('pluginname', 'enrol_self'));
$mform->addElement('text', 'name', get_string('custominstancename', 'enrol'));
$nameattribs = array('size' => '20', 'maxlength' => '255');
$mform->addElement('text', 'name', get_string('custominstancename', 'enrol'), $nameattribs);
$mform->setType('name', PARAM_TEXT);
$mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'server');
$options = array(ENROL_INSTANCE_ENABLED => get_string('yes'),
ENROL_INSTANCE_DISABLED => get_string('no'));
@@ -52,11 +54,13 @@ class enrol_self_edit_form extends moodleform {
$mform->addHelpButton('customint6', 'newenrols', 'enrol_self');
$mform->disabledIf('customint6', 'status', 'eq', ENROL_INSTANCE_DISABLED);
$mform->addElement('passwordunmask', 'password', get_string('password', 'enrol_self'));
$passattribs = array('size' => '20', 'maxlength' => '50');
$mform->addElement('passwordunmask', 'password', get_string('password', 'enrol_self'), $passattribs);
$mform->addHelpButton('password', 'password', 'enrol_self');
if (empty($instance->id) and $plugin->get_config('requirepassword')) {
$mform->addRule('password', get_string('required'), 'required', null, 'client');
}
$mform->addRule('password', get_string('maximumchars', '', 50), 'maxlength', 50, 'server');
$options = array(1 => get_string('yes'),
0 => get_string('no'));
+2 -1
View File
@@ -87,7 +87,8 @@ if (!$file = $fs->get_file_by_hash(sha1($fullpath))) {
if (strrpos($fullpath, '/') !== strlen($fullpath) -1 ) {
$fullpath .= '/';
}
if (!$file = $fs->get_file_by_hash(sha1($fullpath.'/.'))) {
// Try to fallback to the directory named as the supposed file.
if (!$file = $fs->get_file_by_hash(sha1($fullpath.'.'))) {
send_file_not_found();
}
}
+41
View File
@@ -46,6 +46,47 @@ function xmldb_filter_mathjaxloader_upgrade($oldversion) {
// Moodle v2.8.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2014111001) {
$oldconfig = get_config('filter_mathjaxloader', 'mathjaxconfig');
$olddefault = 'MathJax.Hub.Config({
config: ["MMLorHTML.js", "Safe.js"],
jax: ["input/TeX","input/MathML","output/HTML-CSS","output/NativeMML"],
extensions: ["tex2jax.js","mml2jax.js","MathMenu.js","MathZoom.js"],
TeX: {
extensions: ["AMSmath.js","AMSsymbols.js","noErrors.js","noUndefined.js"]
},
menuSettings: {
zoom: "Double-Click",
mpContext: true,
mpMouse: true
},
errorSettings: { message: ["!"] },
skipStartupTypeset: true,
messageStyle: "none"
});
';
$newdefault = '
MathJax.Hub.Config({
config: ["Accessible.js", "Safe.js"],
errorSettings: { message: ["!"] },
skipStartupTypeset: true,
messageStyle: "none"
});
';
// Ignore white space changes.
$oldconfig = trim(preg_replace('/\s+/', ' ', $oldconfig));
$olddefault = trim(preg_replace('/\s+/', ' ', $olddefault));
// Update the default config for mathjax only if it has not been customised.
if ($oldconfig == $olddefault) {
set_config('mathjaxconfig', $newdefault, 'filter_mathjaxloader');
}
upgrade_plugin_savepoint(true, 2014111001, 'filter', 'mathjaxloader');
}
return true;
}
+1 -1
View File
@@ -143,7 +143,7 @@ class filter_mathjaxloader extends moodle_text_filter {
$text = str_replace('[tex]', '\\(', $text);
$text = str_replace('[/tex]', '\\)', $text);
// E.g. "$$ blah $$".
$text = preg_replace('|\$\$[\S\s]\$\$|u', '\\(\1\\)', $text);
$text = preg_replace('|\$\$([\S\s]*?)\$\$|u', '\\(\1\\)', $text);
// E.g. "\[ blah \]".
$text = str_replace('\\[', '\\(', $text);
$text = str_replace('\\]', '\\)', $text);
+1 -11
View File
@@ -52,17 +52,7 @@ if ($ADMIN->fulltree) {
$default = '
MathJax.Hub.Config({
config: ["MMLorHTML.js", "Safe.js"],
jax: ["input/TeX","input/MathML","output/HTML-CSS","output/NativeMML"],
extensions: ["tex2jax.js","mml2jax.js","MathMenu.js","MathZoom.js"],
TeX: {
extensions: ["AMSmath.js","AMSsymbols.js","noErrors.js","noUndefined.js"]
},
menuSettings: {
zoom: "Double-Click",
mpContext: true,
mpMouse: true
},
config: ["Accessible.js", "Safe.js"],
errorSettings: { message: ["!"] },
skipStartupTypeset: true,
messageStyle: "none"
+1 -1
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2014111000;
$plugin->version = 2014111001;
$plugin->requires = 2014110400; // Requires this Moodle version
$plugin->component= 'filter_mathjaxloader';
+33 -3
View File
@@ -134,10 +134,9 @@ class filter_urltolink extends moodle_text_filter {
// Lookbehind assertions.
// Is not HTML attribute or CSS URL property. Unfortunately legit text like "url(http://...)" will not be a link.
$lookbehindstart = "(?<!=[\"']|\burl\([\"' ]|\burl\()";
$lookbehindend = "(?<![]),.;])";
$regex = "$lookbehindstart$urlstart((?:$domainsegment\.)+$domainsegment|$numericip)" .
$regex = "$urlstart((?:$domainsegment\.)+$domainsegment|$numericip)" .
"($port?$path$querystring?$fragment?)$lookbehindend";
if ($unicoderegexp) {
$regex = '#' . $regex . '#ui';
@@ -145,7 +144,38 @@ class filter_urltolink extends moodle_text_filter {
$regex = '#' . preg_replace(array('\pLl', '\PL'), 'a-z', $regex) . '#i';
}
$text = preg_replace($regex, '<a href="http$1://$2$3$4" class="_blanktarget">$0</a>', $text);
// Locate any HTML tags.
$matches = preg_split('/(<[^<|>]*>)/i', $text, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
// Iterate through the tokenized text to handle chunks (html and content).
foreach ($matches as $idx => $chunk) {
// Nothing to do. We skip completely any html chunk.
if (strpos(trim($chunk), '<') === 0) {
continue;
}
// Nothing to do. We skip any content chunk having any of these attributes.
if (preg_match('#(background=")|(action=")|(style="background)|(href=")|(src=")|(url [(])#', $chunk)) {
continue;
}
// Arrived here, we want to process every word in this chunk.
$text = $chunk;
$words = explode(' ', $text);
foreach ($words as $idx2 => $word) {
// ReDoS protection. Stop processing if a word is too large.
if (strlen($word) < 4096) {
$words[$idx2] = preg_replace($regex, '<a href="http$1://$2$3$4" class="_blanktarget">$0</a>', $word);
}
}
$text = implode(' ', $words);
// Copy the result back to the array.
$matches[$idx] = $text;
}
$text = implode('', $matches);
if (!empty($ignoretags)) {
$ignoretags = array_reverse($ignoretags); /// Reversed so "progressive" str_replace() will solve some nesting problems.
+27 -1
View File
@@ -29,9 +29,13 @@ global $CFG;
require_once($CFG->dirroot . '/filter/urltolink/filter.php'); // Include the code to test
class filter_urltolink_testcase extends basic_testcase {
class filter_urltolink_filter_testcase extends basic_testcase {
function get_convert_urls_into_links_test_cases() {
// Create a 4095 and 4096 long URLs.
$superlong4095 = str_pad('http://www.superlong4095.com?this=something', 4095, 'a');
$superlong4096 = str_pad('http://www.superlong4096.com?this=something', 4096, 'a');
$texts = array (
//just a url
'http://moodle.org - URL' => '<a href="http://moodle.org" class="_blanktarget">http://moodle.org</a> - URL',
@@ -130,6 +134,7 @@ class filter_urltolink_testcase extends basic_testcase {
'<td background="http://moodle.org">&nbsp;</td>' => '<td background="http://moodle.org">&nbsp;</td>',
'<td background="www.moodle.org">&nbsp;</td>' => '<td background="www.moodle.org">&nbsp;</td>',
'<form name="input" action="http://moodle.org/submit.asp" method="get">'=>'<form name="input" action="http://moodle.org/submit.asp" method="get">',
'<input type="submit" value="Go to http://moodle.org">' => '<input type="submit" value="Go to http://moodle.org">',
'<td background="https://www.moodle.org">&nbsp;</td>' => '<td background="https://www.moodle.org">&nbsp;</td>',
// CSS URLs.
'<table style="background-image: url(\'http://moodle.org/pic.jpg\');">' => '<table style="background-image: url(\'http://moodle.org/pic.jpg\');">',
@@ -148,6 +153,27 @@ class filter_urltolink_testcase extends basic_testcase {
//Encoded URLs in the query
'URL: http://127.0.0.1/path/to?param=value_with%28parenthesis%29&param2=1' => 'URL: <a href="http://127.0.0.1/path/to?param=value_with%28parenthesis%29&param2=1" class="_blanktarget">http://127.0.0.1/path/to?param=value_with%28parenthesis%29&param2=1</a>',
'URL: www.localhost.com/path/to?param=value_with%28parenthesis%29&param2=1' => 'URL: <a href="http://www.localhost.com/path/to?param=value_with%28parenthesis%29&param2=1" class="_blanktarget">www.localhost.com/path/to?param=value_with%28parenthesis%29&param2=1</a>',
// Test URL less than 4096 characters in size is converted to link.
'URL: ' . $superlong4095 => 'URL: <a href="' . $superlong4095 . '" class="_blanktarget">' . $superlong4095 . '</a>',
// Test URL equal to or greater than 4096 characters in size is not converted to link.
'URL: ' . $superlong4096 => 'URL: ' . $superlong4096,
// Testing URL within a span tag.
'URL: <span style="kasd"> my link to http://google.com </span>' => 'URL: <span style="kasd"> my link to <a href="http://google.com" class="_blanktarget">http://google.com</a> </span>',
// Nested tags test.
'<b><i>www.google.com</i></b>' => '<b><i><a href="http://www.google.com" class="_blanktarget">www.google.com</a></i></b>',
'<input type="submit" value="Go to http://moodle.org">' => '<input type="submit" value="Go to http://moodle.org">',
// Test realistic content.
'<p><span style="color: rgb(37, 37, 37); font-family: sans-serif; line-height: 22.3999996185303px;">Lorem ipsum amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut http://google.com aliquip ex ea <a href="http://google.com">commodo consequat</a>. Duis aute irure in reprehenderit in excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia https://docs.google.com/document/d/BrokenLinkPleaseAyacDHc_Ov8aoskoSVQsfmLHP_jYAkRMk/edit?usp=sharing https://docs.google.com/document/d/BrokenLinkPleaseAyacDHc_Ov8aoskoSVQsfmLHP_jYAkRMk/edit?usp=sharing mollit anim id est laborum.</span><br></p>'
=>
'<p><span style="color: rgb(37, 37, 37); font-family: sans-serif; line-height: 22.3999996185303px;">Lorem ipsum amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut <a href="http://google.com" class="_blanktarget">http://google.com</a> aliquip ex ea <a href="http://google.com">commodo consequat</a>. Duis aute irure in reprehenderit in excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia <a href="https://docs.google.com/document/d/BrokenLinkPleaseAyacDHc_Ov8aoskoSVQsfmLHP_jYAkRMk/edit?usp=sharing" class="_blanktarget">https://docs.google.com/document/d/BrokenLinkPleaseAyacDHc_Ov8aoskoSVQsfmLHP_jYAkRMk/edit?usp=sharing</a> <a href="https://docs.google.com/document/d/BrokenLinkPleaseAyacDHc_Ov8aoskoSVQsfmLHP_jYAkRMk/edit?usp=sharing" class="_blanktarget">https://docs.google.com/document/d/BrokenLinkPleaseAyacDHc_Ov8aoskoSVQsfmLHP_jYAkRMk/edit?usp=sharing</a> mollit anim id est laborum.</span><br></p>',
// Test some broken html.
'5 < 10 www.google.com <a href="hi.com">im a link</a>' => '5 < 10 <a href="http://www.google.com" class="_blanktarget">www.google.com</a> <a href="hi.com">im a link</a>',
'h3 (www.styles.com/h3) < h1 (www.styles.com/h1)' => 'h3 (<a href="http://www.styles.com/h3" class="_blanktarget">www.styles.com/h3</a>) < h1 (<a href="http://www.styles.com/h1" class="_blanktarget">www.styles.com/h1</a>)',
'<p>text www.moodle.org&lt;/p> text' => '<p>text <a href="http://www.moodle.org" class="_blanktarget">www.moodle.org</a>&lt;/p> text',
// Some more urls.
'<link rel="search" type="application/opensearchdescription+xml" href="/osd.jsp" title="Peer review - Moodle Tracker"/>' => '<link rel="search" type="application/opensearchdescription+xml" href="/osd.jsp" title="Peer review - Moodle Tracker"/>',
'<a href="https://docs.moodle.org/dev/Main_Page"></a><span>www.google.com</span><span class="placeholder"></span>' => '<a href="https://docs.moodle.org/dev/Main_Page"></a><span><a href="http://www.google.com" class="_blanktarget">www.google.com</a></span><span class="placeholder"></span>',
'http://nolandforzombies.com <a href="zombiesFTW.com">Zombies FTW</a> http://aliens.org' => '<a href="http://nolandforzombies.com" class="_blanktarget">http://nolandforzombies.com</a> <a href="zombiesFTW.com">Zombies FTW</a> <a href="http://aliens.org" class="_blanktarget">http://aliens.org</a>',
//URLs in Javascript. Commented out as part of MDL-21183
//'var url="http://moodle.org";'=>'var url="http://moodle.org";',
//'var url = "http://moodle.org";'=>'var url = "http://moodle.org";',
+2
View File
@@ -196,6 +196,8 @@ class grade_export_form extends moodleform {
$submitstring = get_string('download');
if (empty($features['simpleui'])) {
$submitstring = get_string('submit');
} else if (!empty($CFG->gradepublishing)) {
$submitstring = get_string('export', 'grades');
}
$this->add_action_buttons(false, $submitstring);
+169 -10
View File
@@ -383,16 +383,30 @@ abstract class grade_export {
$itemidsparam = '-1';
}
$params = array('id' =>$this->course->id,
'groupid' =>$this->groupid,
'itemids' =>$itemidsparam,
'export_letters' =>$this->export_letters,
'export_feedback' =>$this->export_feedback,
'updatedgradesonly' =>$this->updatedgradesonly,
'displaytype' =>$this->displaytype,
'decimalpoints' =>$this->decimalpoints,
'export_onlyactive' =>$this->onlyactive,
'usercustomfields' =>$this->usercustomfields);
// We have a single grade display type constant.
if (!is_array($this->displaytype)) {
$displaytypes = $this->displaytype;
} else {
// Implode the grade display types array as moodle_url function doesn't accept arrays.
$displaytypes = implode(',', $this->displaytype);
}
if (!empty($this->updatedgradesonly)) {
$updatedgradesonly = $this->updatedgradesonly;
} else {
$updatedgradesonly = 0;
}
$params = array('id' => $this->course->id,
'groupid' => $this->groupid,
'itemids' => $itemidsparam,
'export_letters' => $this->export_letters,
'export_feedback' => $this->export_feedback,
'updatedgradesonly' => $updatedgradesonly,
'decimalpoints' => $this->decimalpoints,
'export_onlyactive' => $this->onlyactive,
'usercustomfields' => $this->usercustomfields,
'displaytype' => $displaytypes,
'key' => $this->userkey);
return $params;
}
@@ -436,6 +450,151 @@ abstract class grade_export {
return;
}
/**
* Generate the export url.
*
* Get submitted form data and create the url to be used on the grade publish feature.
*
* @return moodle_url the url of grade publishing export.
*/
public function get_export_url() {
return new moodle_url('/grade/export/'.$this->plugin.'/dump.php', $this->get_export_params());
}
/**
* Convert the grade display types parameter into the required array to grade exporting class.
*
* In order to export, the array key must be the display type name and the value must be the grade display type
* constant.
*
* Note: Added support for combined display types constants like the (GRADE_DISPLAY_TYPE_PERCENTAGE_REAL) as
* the $CFG->grade_export_displaytype config is still used on 2.7 in case of missing displaytype url param.
* In these cases, the file will be exported with a column for each display type.
*
* @param string $displaytypes can be a single or multiple display type constants comma separated.
* @return array $types
*/
public static function convert_flat_displaytypes_to_array($displaytypes) {
$types = array();
// We have a single grade display type constant.
if (is_int($displaytypes)) {
$displaytype = clean_param($displaytypes, PARAM_INT);
// Let's set a default value, will be replaced below by the grade display type constant.
$display[$displaytype] = 1;
} else {
// Multiple grade display types constants.
$display = array_flip(explode(',', $displaytypes));
}
// Now, create the array in the required format by grade exporting class.
foreach ($display as $type => $value) {
$type = clean_param($type, PARAM_INT);
if ($type == GRADE_DISPLAY_TYPE_LETTER) {
$types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
} else if ($type == GRADE_DISPLAY_TYPE_PERCENTAGE) {
$types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
} else if ($type == GRADE_DISPLAY_TYPE_REAL) {
$types['real'] = GRADE_DISPLAY_TYPE_REAL;
} else if ($type == GRADE_DISPLAY_TYPE_REAL_PERCENTAGE) {
$types['real'] = GRADE_DISPLAY_TYPE_REAL;
$types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
} else if ($type == GRADE_DISPLAY_TYPE_REAL_LETTER) {
$types['real'] = GRADE_DISPLAY_TYPE_REAL;
$types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
} else if ($type == GRADE_DISPLAY_TYPE_LETTER_REAL) {
$types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
$types['real'] = GRADE_DISPLAY_TYPE_REAL;
} else if ($type == GRADE_DISPLAY_TYPE_LETTER_PERCENTAGE) {
$types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
$types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
} else if ($type == GRADE_DISPLAY_TYPE_PERCENTAGE_LETTER) {
$types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
$types['letter'] = GRADE_DISPLAY_TYPE_LETTER;
} else if ($type == GRADE_DISPLAY_TYPE_PERCENTAGE_REAL) {
$types['percentage'] = GRADE_DISPLAY_TYPE_PERCENTAGE;
$types['real'] = GRADE_DISPLAY_TYPE_REAL;
}
}
return $types;
}
/**
* Convert the item ids parameter into the required array to grade exporting class.
*
* In order to export, the array key must be the grade item id and all values must be one.
*
* @param string $itemids can be a single item id or many item ids comma separated.
* @return array $items correctly formatted array.
*/
public static function convert_flat_itemids_to_array($itemids) {
$items = array();
// We just have one single item id.
if (is_int($itemids)) {
$itemid = clean_param($itemids, PARAM_INT);
$items[$itemid] = 1;
} else {
// Few grade items.
$items = array_flip(explode(',', $itemids));
foreach ($items as $itemid => $value) {
$itemid = clean_param($itemid, PARAM_INT);
$items[$itemid] = 1;
}
}
return $items;
}
/**
* Create the html code of the grade publishing feature.
*
* @return string $output html code of the grade publishing.
*/
public function get_grade_publishing_url() {
$url = $this->get_export_url();
$output = html_writer::start_div();
$output .= html_writer::tag('p', get_string('gradepublishinglink', 'grades', html_writer::link($url, $url)));
$output .= html_writer::end_div();
return $output;
}
/**
* Create a stdClass object from URL parameters to be used by grade_export class.
*
* @param int $id course id.
* @param string $itemids grade items comma separated.
* @param bool $exportfeedback export feedback option.
* @param bool $onlyactive only enrolled active students.
* @param string $displaytype grade display type constants comma separated.
* @param int $decimalpoints grade decimal points.
* @param null $updatedgradesonly recently updated grades only (Used by XML exporting only).
* @param null $separator separator character: tab, comma, colon and semicolon (Used by TXT exporting only).
*
* @return stdClass $formdata
*/
public static function export_bulk_export_data($id, $itemids, $exportfeedback, $onlyactive, $displaytype,
$decimalpoints, $updatedgradesonly = null, $separator = null) {
$formdata = new \stdClass();
$formdata->id = $id;
$formdata->itemids = self::convert_flat_itemids_to_array($itemids);
$formdata->exportfeedback = $exportfeedback;
$formdata->export_onlyactive = $onlyactive;
$formdata->display = self::convert_flat_displaytypes_to_array($displaytype);
$formdata->decimals = $decimalpoints;
if (!empty($updatedgradesonly)) {
$formdata->updatedgradesonly = $updatedgradesonly;
}
if (!empty($separator)) {
$formdata->separator = $separator;
}
return $formdata;
}
}
/**
+21 -3
View File
@@ -17,8 +17,16 @@
define('NO_MOODLE_COOKIES', true); // session not used here
require_once '../../../config.php';
require_once($CFG->dirroot.'/grade/export/ods/grade_export_ods.php');
$id = required_param('id', PARAM_INT);
$groupid = optional_param('groupid', 0, PARAM_INT);
$itemids = required_param('itemids', PARAM_RAW);
$exportfeedback = optional_param('export_feedback', 0, PARAM_BOOL);
$displaytype = optional_param('displaytype', $CFG->grade_export_displaytype, PARAM_RAW);
$decimalpoints = optional_param('decimalpoints', $CFG->grade_export_decimalpoints, PARAM_INT);
$onlyactive = optional_param('export_onlyactive', 0, PARAM_BOOL);
$id = required_param('id', PARAM_INT); // course id
if (!$course = $DB->get_record('course', array('id'=>$id))) {
print_error('nocourseid');
}
@@ -30,9 +38,19 @@ if (empty($CFG->gradepublishing)) {
}
$context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/ods:view', $context);
require_capability('gradeexport/ods:publish', $context);
// use the same page parameters as export.php and append &key=sdhakjsahdksahdkjsahksadjksahdkjsadhksa
require 'export.php';
if (!groups_group_visible($groupid, $COURSE)) {
print_error('cannotaccessgroup', 'grades');
}
// Get all url parameters and create an object to simulate a form submission.
$formdata = grade_export::export_bulk_export_data($id, $itemids, $exportfeedback, $onlyactive, $displaytype,
$decimalpoints);
$export = new grade_export_ods($course, $groupid, $formdata);
$export->print_grades();
+16 -4
View File
@@ -20,6 +20,7 @@ require_once $CFG->dirroot.'/grade/export/lib.php';
require_once 'grade_export_ods.php';
$id = required_param('id', PARAM_INT); // course id
$PAGE->set_url('/grade/export/ods/export.php', array('id'=>$id));
if (!$course = $DB->get_record('course', array('id'=>$id))) {
print_error('nocourseid');
@@ -32,6 +33,13 @@ $groupid = groups_get_course_group($course, true);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/ods:view', $context);
// We need to call this method here before any output otherwise the menu won't display.
// If you use this method without this check, will break the direct grade exporting (without publishing).
$key = optional_param('key', '', PARAM_RAW);
if (!empty($CFG->gradepublishing) && !empty($key)) {
print_grade_page_head($COURSE->id, 'export', 'ods', get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_ods'));
}
if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
if (!groups_is_member($groupid, $USER->id)) {
print_error('cannotaccessgroup', 'grades');
@@ -39,9 +47,13 @@ if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('
}
$mform = new grade_export_form(null, array('publishing' => true, 'simpleui' => true, 'multipledisplaytypes' => true));
$data = $mform->get_data();
// print all the exported data here
$export = new grade_export_ods($course, $groupid, $data);
$export->print_grades();
// If the gradepublishing is enabled and user key is selected print the grade publishing link.
if (!empty($CFG->gradepublishing) && !empty($key)) {
groups_print_course_menu($course, 'index.php?id='.$id);
echo $export->get_grade_publishing_url();
echo $OUTPUT->footer();
} else {
$export->print_grades();
}
+22 -3
View File
@@ -17,8 +17,17 @@
define('NO_MOODLE_COOKIES', true); // session not used here
require_once '../../../config.php';
require_once($CFG->dirroot.'/grade/export/txt/grade_export_txt.php');
$id = required_param('id', PARAM_INT);
$groupid = optional_param('groupid', 0, PARAM_INT);
$itemids = required_param('itemids', PARAM_RAW);
$exportfeedback = optional_param('export_feedback', 0, PARAM_BOOL);
$separator = optional_param('separator', 'comma', PARAM_ALPHA);
$displaytype = optional_param('displaytype', $CFG->grade_export_displaytype, PARAM_RAW);
$decimalpoints = optional_param('decimalpoints', $CFG->grade_export_decimalpoints, PARAM_INT);
$onlyactive = optional_param('export_onlyactive', 0, PARAM_BOOL);
$id = required_param('id', PARAM_INT); // course id
if (!$course = $DB->get_record('course', array('id'=>$id))) {
print_error('nocourseid');
}
@@ -30,9 +39,19 @@ if (empty($CFG->gradepublishing)) {
}
$context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/txt:publish', $context);
require_capability('gradeexport/txt:view', $context);
// use the same page parameters as export.php and append &key=sdhakjsahdksahdkjsahksadjksahdkjsadhksa
require 'export.php';
if (!groups_group_visible($groupid, $COURSE)) {
print_error('cannotaccessgroup', 'grades');
}
// Get all url parameters and create an object to simulate a form submission.
$formdata = grade_export::export_bulk_export_data($id, $itemids, $exportfeedback, $onlyactive, $displaytype,
$decimalpoints, null, $separator);
$export = new grade_export_txt($course, $groupid, $formdata);
$export->print_grades();
+16 -3
View File
@@ -20,6 +20,7 @@ require_once $CFG->dirroot.'/grade/export/lib.php';
require_once 'grade_export_txt.php';
$id = required_param('id', PARAM_INT); // course id
$PAGE->set_url('/grade/export/txt/export.php', array('id'=>$id));
if (!$course = $DB->get_record('course', array('id'=>$id))) {
print_error('nocourseid');
@@ -32,6 +33,13 @@ $groupid = groups_get_course_group($course, true);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/txt:view', $context);
// We need to call this method here before any print otherwise the menu won't display.
// If you use this method without this check, will break the direct grade exporting (without publishing).
$key = optional_param('key', '', PARAM_RAW);
if (!empty($CFG->gradepublishing) && !empty($key)) {
print_grade_page_head($COURSE->id, 'export', 'txt', get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_txt'));
}
if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
if (!groups_is_member($groupid, $USER->id)) {
print_error('cannotaccessgroup', 'grades');
@@ -46,8 +54,13 @@ $params = array(
);
$mform = new grade_export_form(null, $params);
$data = $mform->get_data();
// Print all the exported data here.
$export = new grade_export_txt($course, $groupid, $data);
$export->print_grades();
// If the gradepublishing is enabled and user key is selected print the grade publishing link.
if (!empty($CFG->gradepublishing) && !empty($key)) {
groups_print_course_menu($course, 'index.php?id='.$id);
echo $export->get_grade_publishing_url();
echo $OUTPUT->footer();
} else {
$export->print_grades();
}
+21 -3
View File
@@ -17,8 +17,16 @@
define('NO_MOODLE_COOKIES', true); // session not used here
require_once '../../../config.php';
require_once($CFG->dirroot.'/grade/export/xls/grade_export_xls.php');
$id = required_param('id', PARAM_INT);
$groupid = optional_param('groupid', 0, PARAM_INT);
$itemids = required_param('itemids', PARAM_RAW);
$exportfeedback = optional_param('export_feedback', 0, PARAM_BOOL);
$displaytype = optional_param('displaytype', $CFG->grade_export_displaytype, PARAM_RAW);
$decimalpoints = optional_param('decimalpoints', $CFG->grade_export_decimalpoints, PARAM_INT);
$onlyactive = optional_param('export_onlyactive', 0, PARAM_BOOL);
$id = required_param('id', PARAM_INT); // course id
if (!$course = $DB->get_record('course', array('id'=>$id))) {
print_error('nocourseid');
}
@@ -30,9 +38,19 @@ if (empty($CFG->gradepublishing)) {
}
$context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/xls:view', $context);
require_capability('gradeexport/xls:publish', $context);
// use the same page parameters as export.php and append &key=sdhakjsahdksahdkjsahksadjksahdkjsadhksa
require 'export.php';
if (!groups_group_visible($groupid, $COURSE)) {
print_error('cannotaccessgroup', 'grades');
}
// Get all url parameters and create an object to simulate a form submission.
$formdata = grade_export::export_bulk_export_data($id, $itemids, $exportfeedback, $onlyactive, $displaytype,
$decimalpoints);
$export = new grade_export_xls($course, $groupid, $formdata);
$export->print_grades();
+16 -3
View File
@@ -20,6 +20,7 @@ require_once $CFG->dirroot.'/grade/export/lib.php';
require_once 'grade_export_xls.php';
$id = required_param('id', PARAM_INT); // course id
$PAGE->set_url('/grade/export/xls/export.php', array('id'=>$id));
if (!$course = $DB->get_record('course', array('id'=>$id))) {
print_error('nocourseid');
@@ -32,6 +33,13 @@ $groupid = groups_get_course_group($course, true);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/xls:view', $context);
// We need to call this method here before any print otherwise the menu won't display.
// If you use this method without this check, will break the direct grade exporting (without publishing).
$key = optional_param('key', '', PARAM_RAW);
if (!empty($CFG->gradepublishing) && !empty($key)) {
print_grade_page_head($COURSE->id, 'export', 'xls', get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_xls'));
}
if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
if (!groups_is_member($groupid, $USER->id)) {
print_error('cannotaccessgroup', 'grades');
@@ -39,9 +47,14 @@ if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('
}
$mform = new grade_export_form(null, array('publishing' => true, 'simpleui' => true, 'multipledisplaytypes' => true));
$formdata = $mform->get_data();
// print all the exported data here
$export = new grade_export_xls($course, $groupid, $formdata);
$export->print_grades();
// If the gradepublishing is enabled and user key is selected print the grade publishing link.
if (!empty($CFG->gradepublishing) && !empty($key)) {
groups_print_course_menu($course, 'index.php?id='.$id);
echo $export->get_grade_publishing_url();
echo $OUTPUT->footer();
} else {
$export->print_grades();
}
+22 -3
View File
@@ -17,8 +17,17 @@
define('NO_MOODLE_COOKIES', true); // session not used here
require_once '../../../config.php';
require_once($CFG->dirroot.'/grade/export/xml/grade_export_xml.php');
$id = required_param('id', PARAM_INT);
$groupid = optional_param('groupid', 0, PARAM_INT);
$itemids = required_param('itemids', PARAM_RAW);
$exportfeedback = optional_param('export_feedback', 0, PARAM_BOOL);
$updatedgradesonly = optional_param('updatedgradesonly', false, PARAM_BOOL);
$displaytype = optional_param('displaytype', $CFG->grade_export_displaytype, PARAM_RAW);
$decimalpoints = optional_param('decimalpoints', $CFG->grade_export_decimalpoints, PARAM_INT);
$onlyactive = optional_param('export_onlyactive', 0, PARAM_BOOL);
$id = required_param('id', PARAM_INT); // course id
if (!$course = $DB->get_record('course', array('id'=>$id))) {
print_error('nocourseid');
}
@@ -30,9 +39,19 @@ if (empty($CFG->gradepublishing)) {
}
$context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/xml:publish', $context);
require_capability('gradeexport/xml:view', $context);
// use the same page parameters as export.php and append &key=sdhakjsahdksahdkjsahksadjksahdkjsadhksa
require 'export.php';
if (!groups_group_visible($groupid, $COURSE)) {
print_error('cannotaccessgroup', 'grades');
}
// Get all url parameters and create an object to simulate a form submission.
$formdata = grade_export::export_bulk_export_data($id, $itemids, $exportfeedback, $onlyactive, $displaytype,
$decimalpoints, $updatedgradesonly, null);
$export = new grade_export_xml($course, $groupid, $formdata);
$export->print_grades();
+18 -4
View File
@@ -20,6 +20,7 @@ require_once $CFG->dirroot.'/grade/export/lib.php';
require_once 'grade_export_xml.php';
$id = required_param('id', PARAM_INT); // course id
$PAGE->set_url('/grade/export/xml/export.php', array('id'=>$id));
if (!$course = $DB->get_record('course', array('id'=>$id))) {
print_error('nocourseid');
@@ -32,17 +33,30 @@ $groupid = groups_get_course_group($course, true);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/xml:view', $context);
// We need to call this method here before any print otherwise the menu won't display.
// If you use this method without this check, will break the direct grade exporting (without publishing).
$key = optional_param('key', '', PARAM_RAW);
if (!empty($CFG->gradepublishing) && !empty($key)) {
print_grade_page_head($COURSE->id, 'export', 'xml', get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_xml'));
}
if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
if (!groups_is_member($groupid, $USER->id)) {
print_error('cannotaccessgroup', 'grades');
}
}
$mform = new grade_export_form(null, array('publishing' => true, 'simpleui' => true, 'multipledisplaytypes' => false,
'idnumberrequired' => true));
'idnumberrequired' => true, 'updategradesonly' => true));
$formdata = $mform->get_data();
// print all the exported data here
$export = new grade_export_xml($course, $groupid, $formdata);
$export->print_grades();
// If the gradepublishing is enabled and user key is selected print the grade publishing link.
if (!empty($CFG->gradepublishing) && !empty($key)) {
groups_print_course_menu($course, 'index.php?id='.$id);
echo $export->get_grade_publishing_url();
echo $OUTPUT->footer();
} else {
$export->print_grades();
}
+3 -1
View File
@@ -51,9 +51,11 @@ class gradingform_guide_editguide extends moodleform {
$form->setType('returnurl', PARAM_LOCALURL);
// Name.
$form->addElement('text', 'name', get_string('name', 'gradingform_guide'), array('size'=>52));
$form->addElement('text', 'name', get_string('name', 'gradingform_guide'),
array('size' => 52, 'maxlength' => 255));
$form->addRule('name', get_string('required'), 'required');
$form->setType('name', PARAM_TEXT);
$form->addRule('name', null, 'maxlength', 255, 'client');
// Description.
$options = gradingform_guide_controller::description_form_field_options($this->_customdata['context']);
+4
View File
@@ -197,6 +197,10 @@ class moodlequickform_guideeditor extends HTML_QuickForm_input {
$errors['err_noshortname'] = 1;
$criterion['error_description'] = true;
}
if (strlen(trim($criterion['shortname'])) > 255) {
$errors['err_shortnametoolong'] = 1;
$criterion['error_description'] = true;
}
if (!strlen(trim($criterion['maxscore']))) {
$errors['err_nomaxscore'] = 1;
$criterion['error_description'] = true;
@@ -54,6 +54,7 @@ $string['err_nodescription'] = 'Student description can not be empty';
$string['err_nodescriptionmarkers'] = 'Marker description can not be empty';
$string['err_nomaxscore'] = 'Criterion max score can not be empty';
$string['err_noshortname'] = 'Criterion name can not be empty';
$string['err_shortnametoolong'] = 'Criterion name must be less than 256 characters';
$string['err_scoreinvalid'] = 'The score given to {$a->criterianame} is not valid, the max score is: {$a->maxscore}';
$string['gradingof'] = '{$a} grading';
$string['guidemappingexplained'] = 'WARNING: Your marking guide has a maximum grade of <b>{$a->maxscore} points</b> but the maximum grade set in your activity is {$a->modulegrade} The maximum score set in your marking guide will be scaled to the maximum grade in the module.<br />
+10 -8
View File
@@ -180,7 +180,7 @@ class gradeimport_csv_load_data {
* @param array $header The column headers from the CSV file.
* @param int $key Current row identifier.
* @param string $value The value for this row (final grade).
* @return array new grades that are ready for commiting to the gradebook.
* @return stdClass new grade that is ready for commiting to the gradebook.
*/
protected function import_new_grade_item($header, $key, $value) {
global $DB, $USER;
@@ -199,14 +199,16 @@ class gradeimport_csv_load_data {
$newgrade = new stdClass();
$newgrade->newgradeitem = $this->newgradeitems[$key];
// If the user has a grade for this grade item.
if (trim($value) != '-') {
// Instead of omitting the grade we could insert one with finalgrade set to 0.
// We do not have access to grade item min grade.
$trimmed = trim($value);
if ($trimmed === '' or $trimmed == '-') {
// Blank or dash grade means null, ie "no grade".
$newgrade->finalgrade = null;
} else {
// We have an actual grade.
$newgrade->finalgrade = $value;
$newgrades[] = $newgrade;
}
return $newgrades;
$this->newgrades[] = $newgrade;
return $newgrade;
}
/**
@@ -385,7 +387,7 @@ class gradeimport_csv_load_data {
}
break;
case 'new':
$this->newgrades = $this->import_new_grade_item($header, $key, $value);
$this->import_new_grade_item($header, $key, $value);
break;
case 'feedback':
if ($feedbackgradeid) {
+14 -3
View File
@@ -41,9 +41,9 @@ require_once($CFG->libdir . '/grade/tests/fixtures/lib.php');
class gradeimport_csv_load_data_testcase extends grade_base_testcase {
/** @var string $oktext Text to be imported. This data should have no issues being imported. */
protected $oktext = '"First name",Surname,"ID number",Institution,Department,"Email address","Assignment: Assignment for grape group", "Feedback: Assignment for grape group","Course total"
Anne,Able,,"Moodle HQ","Rock on!",student7@mail.com,56.00,"We welcome feedback",56.00
Bobby,Bunce,,"Moodle HQ","Rock on!",student5@mail.com,75.00,,75.00';
protected $oktext = '"First name",Surname,"ID number",Institution,Department,"Email address","Assignment: Assignment for grape group", "Feedback: Assignment for grape group","Assignment: Second new grade item","Course total"
Anne,Able,,"Moodle HQ","Rock on!",student7@mail.com,56.00,"We welcome feedback",,56.00
Bobby,Bunce,,"Moodle HQ","Rock on!",student5@mail.com,75.00,,45.0,75.00';
/** @var string $badtext Text to be imported. This data has an extra column and should not succeed in being imported. */
protected $badtext = '"First name",Surname,"ID number",Institution,Department,"Email address","Assignment: Assignment for grape group","Course total"
@@ -109,6 +109,7 @@ Bobby,Bunce,,"Moodle HQ","Rock on!",student5@mail.com,75.00,,75.00,{exportdate}'
'student7@mail.com',
56.00,
'We welcome feedback',
'',
56.00
),
array(
@@ -120,6 +121,7 @@ Bobby,Bunce,,"Moodle HQ","Rock on!",student5@mail.com,75.00,,75.00,{exportdate}'
'student5@mail.com',
75.00,
'',
45.0,
75.00
)
);
@@ -133,6 +135,7 @@ Bobby,Bunce,,"Moodle HQ","Rock on!",student5@mail.com,75.00,,75.00,{exportdate}'
'Email address',
'Assignment: Assignment for grape group',
'Feedback: Assignment for grape group',
'Assignment: Second new grade item',
'Course total'
);
// Check that general data is returned as expected.
@@ -371,6 +374,14 @@ Bobby,Bunce,,"Moodle HQ","Rock on!",student5@mail.com,75.00,,75.00,{exportdate}'
// Check that the final grade is the same as the one inserted.
$this->assertEquals($testarray[0][6], $newgrades[0]->finalgrade);
$newgrades = $testobject->test_map_user_data_with_value('new', $testarray[0][8], $this->columns, $map, $key,
$this->courseid, $map[$key], $verbosescales);
// Check that the final grade is the same as the one inserted.
// The testobject should now contain 2 new grade items.
$this->assertEquals(2, count($newgrades));
// Because this grade item is empty, the value for final grade should be null.
$this->assertNull($newgrades[1]->finalgrade);
$feedback = $testobject->test_map_user_data_with_value('feedback', $testarray[0][7], $this->columns, $map, $key,
$this->courseid, $map[$key], $verbosescales);
// Expected result.
+3 -3
View File
@@ -617,7 +617,7 @@ function grade_print_tabs($active_type, $active_plugin, $plugin_info, $return=fa
$top_row = array();
$bottom_row = array();
$inactive = array($active_plugin);
$activated = array();
$activated = array($active_type);
$count = 0;
$active = '';
@@ -661,9 +661,9 @@ function grade_print_tabs($active_type, $active_plugin, $plugin_info, $return=fa
$tabs[] = $bottom_row;
if ($return) {
return print_tabs($tabs, $active_type, $inactive, $activated, true);
return print_tabs($tabs, $active_plugin, $inactive, $activated, true);
} else {
print_tabs($tabs, $active_type, $inactive, $activated);
print_tabs($tabs, $active_plugin, $inactive, $activated);
}
}
+29 -24
View File
@@ -412,8 +412,14 @@ class grade_report_grader extends grade_report {
// Limit to users with a gradeable role.
list($gradebookrolessql, $gradebookrolesparams) = $DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0');
// Check the status of showing only active enrolments.
$coursecontext = $this->context->get_course_context(true);
$defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol);
$showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol);
$showonlyactiveenrol = $showonlyactiveenrol || !has_capability('moodle/course:viewsuspendedusers', $coursecontext);
// Limit to users with an active enrollment.
list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->context);
list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->context, '', 0, $showonlyactiveenrol);
// Fields we need from the user table.
$userfields = user_picture::fields('u', get_extra_user_fields($this->context));
@@ -476,30 +482,29 @@ class grade_report_grader extends grade_report {
$this->userselect = "AND g.userid $usql";
$this->userselect_params = $uparams;
// Add a flag to each user indicating whether their enrolment is active.
$sql = "SELECT ue.userid
FROM {user_enrolments} ue
JOIN {enrol} e ON e.id = ue.enrolid
WHERE ue.userid $usql
AND ue.status = :uestatus
AND e.status = :estatus
AND e.courseid = :courseid
AND ue.timestart < :now1 AND (ue.timeend = 0 OR ue.timeend > :now2)
GROUP BY ue.userid";
$coursecontext = $this->context->get_course_context(true);
$time = time();
$params = array_merge($uparams, array('estatus' => ENROL_INSTANCE_ENABLED, 'uestatus' => ENROL_USER_ACTIVE,
'courseid' => $coursecontext->instanceid, 'now1' => $time, 'now2' => $time));
$useractiveenrolments = $DB->get_records_sql($sql, $params);
$defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol);
$showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol);
$showonlyactiveenrol = $showonlyactiveenrol || !has_capability('moodle/course:viewsuspendedusers', $coursecontext);
// First flag everyone as not suspended.
foreach ($this->users as $user) {
// If we are showing only active enrolments, then remove suspended users from list.
if ($showonlyactiveenrol && !array_key_exists($user->id, $useractiveenrolments)) {
unset($this->users[$user->id]);
} else {
$this->users[$user->id]->suspendedenrolment = false;
}
// If we want to mix both suspended and not suspended users, let's find out who is suspended.
if (!$showonlyactiveenrol) {
$sql = "SELECT ue.userid
FROM {user_enrolments} ue
JOIN {enrol} e ON e.id = ue.enrolid
WHERE ue.userid $usql
AND ue.status = :uestatus
AND e.status = :estatus
AND e.courseid = :courseid
AND ue.timestart < :now1 AND (ue.timeend = 0 OR ue.timeend > :now2)
GROUP BY ue.userid";
$time = time();
$params = array_merge($uparams, array('estatus' => ENROL_INSTANCE_ENABLED, 'uestatus' => ENROL_USER_ACTIVE,
'courseid' => $coursecontext->instanceid, 'now1' => $time, 'now2' => $time));
$useractiveenrolments = $DB->get_records_sql($sql, $params);
foreach ($this->users as $user) {
$this->users[$user->id]->suspendedenrolment = !array_key_exists($user->id, $useractiveenrolments);
}
}
+1 -1
View File
@@ -74,7 +74,7 @@ foreach ($outcomes as $outcomeid => $outcome) {
FROM {grade_grades}
WHERE itemid = ?".
$hidesuspendedsql.
"GROUP BY itemid";
" GROUP BY itemid";
$info = $DB->get_records_sql($sql, $params);
if (!$info) {
+1
View File
@@ -48,6 +48,7 @@ define('AJAX_SCRIPT', false); // prevents some warnings later
define('CACHE_DISABLE_ALL', true); // Disables caching.. just in case.
define('PHPUNIT_TEST', false);
define('IGNORE_COMPONENT_CACHE', true);
define('MDL_PERF_TEST', false);
// Servers should define a default timezone in php.ini, but if they don't then make sure something is defined.
// This is a quick hack. Ideally we should ask the admin for a value. See MDL-22625 for more on this.
+1
View File
@@ -39,6 +39,7 @@ $string['cannotsavemd5file'] = 'Ezin da Md5 fitxategia gorde';
$string['cannotsavezipfile'] = 'Ezin da ZIP fitxategia gorde';
$string['cannotunzipfile'] = 'Ezin da fitxategia deskonprimatu';
$string['componentisuptodate'] = 'Osagaia eguneratu da';
$string['dmlexceptiononinstall'] = '<p>Datu-basearen errorea gertatu da [{$a->errorcode}].<br />{$a->debuginfo}</p>';
$string['downloadedfilecheckfailed'] = 'Jaitsitako fitxategiaren konprobazioak kale egin du.';
$string['invalidmd5'] = 'md5 ez da baliagarria';
$string['missingrequiredfield'] = 'Beharrezko eremuren bat falta da.';
+34
View File
@@ -0,0 +1,34 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Automatically generated strings for Moodle installer
*
* Do not edit this file manually! It contains just a subset of strings
* needed during the very first steps of installation. This file was
* generated automatically by export-installer.php (which is part of AMOS
* {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
* list of strings defined in /install/stringnames.txt.
*
* @package installer
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$string['parentlanguage'] = 'fi';
$string['thislanguage'] = 'Suomi yrityksille';
+1 -1
View File
@@ -39,4 +39,4 @@ $string['clitypevaluedefault'] = 'érték beírása, Enter esetén alapérték (
$string['cliunknowoption'] = 'Ismeretlen paraméter: {$a}. Használja a --help paramétert.';
$string['cliyesnoprompt'] = 'írjon be i-t (igen) vagy n-t (nem)';
$string['environmentrequireinstall'] = 'telepíteni kell és be kell kapcsolni';
$string['environmentrequireversion'] = 'a {$a->needed} változatot kell a mostani {$a->current} helyett használni';
$string['environmentrequireversion'] = 'minimum a {$a->needed} változat szükséges, jelenleg a {$a->current} verziót használja';
+1 -1
View File
@@ -32,4 +32,4 @@ defined('MOODLE_INTERNAL') || die();
$string['parentlanguage'] = '';
$string['thisdirection'] = 'ltr';
$string['thislanguage'] = 'Lithuanian';
$string['thislanguage'] = 'Lietuvių';
+1 -1
View File
@@ -39,4 +39,4 @@ $string['clitypevaluedefault'] = 'тип значення, натисніть En
$string['cliunknowoption'] = 'Невизначені опції: {$a}. Будь ласка, використайте опцію --help.';
$string['cliyesnoprompt'] = 'натисніть y (означає так) або n (означає ні)';
$string['environmentrequireinstall'] = 'повинен бути встановлений і включений';
$string['environmentrequireversion'] = 'рекомендується версія {$a->needed}, використовується версія {$a->current}';
$string['environmentrequireversion'] = 'потрібна версія {$a->needed}, ви запускаєте {$a->current}';
+2
View File
@@ -61,6 +61,7 @@ $string['enrolnotpermitted'] = 'You do not have permission or are not allowed to
$string['enrolperiod'] = 'Enrolment duration';
$string['enrolusage'] = 'Instances / enrolments';
$string['enrolusers'] = 'Enrol users';
$string['enrolxusers'] = 'Enrol {$a} users';
$string['enroltimecreated'] = 'Enrolment created';
$string['enroltimeend'] = 'Enrolment ends';
$string['enroltimestart'] = 'Enrolment starts';
@@ -82,6 +83,7 @@ $string['expirynotifyhour'] = 'Hour to send enrolment expiry notifications';
$string['expirythreshold'] = 'Notification threshold';
$string['expirythreshold_help'] = 'How long before enrolment expiry should users be notified?';
$string['finishenrollingusers'] = 'Finish enrolling users';
$string['foundxcohorts'] = 'Found {$a} cohorts';
$string['instanceeditselfwarning'] = 'Warning:';
$string['instanceeditselfwarningtext'] = 'You are enrolled into this course through this enrolment method, changes may affect your access to this course.';
$string['invalidenrolinstance'] = 'Invalid enrolment instance';
+1
View File
@@ -145,6 +145,7 @@ $string['cannotsetupblock'] = 'Blocks tables could NOT be set up successfully!';
$string['cannotsetupcapformod'] = 'Could not set up the capabilities for {$a}';
$string['cannotsetupcapforplugin'] = 'Could not set up the capabilities for {$a}';
$string['cannotshowhidecoursesincategory'] = 'Cannot show/hide the courses in category {$a}.';
$string['cannotsignup'] = 'You cannot create a new account because you are already logged in as {$a}.';
$string['cannotunassigncap'] = 'Could not unassign deprecated capability {$a->cap} from role {$a->role}';
$string['cannotunassignrolefrom'] = 'Cannot unassign this user from role id: {$a}';
$string['cannotunzipfile'] = 'Cannot unzip file';
+6
View File
@@ -35,9 +35,11 @@ $string['categoryrole'] = 'Category role';
$string['contains'] = 'contains';
$string['content'] = 'Content';
$string['contentandheadings'] = 'Content and headings';
$string['coursecategory'] = 'course category';
$string['courserole'] = 'Course role';
$string['courserolelabel'] = '{$a->label} is {$a->rolename} in {$a->coursename} from {$a->categoryname}';
$string['courserolelabelerror'] = '{$a->label} error: course {$a->coursename} does not exist';
$string['coursevalue'] = 'course value';
$string['datelabelisafter'] = '{$a->label} is after {$a->after}';
$string['datelabelisbefore'] = '{$a->label} is before {$a->before}';
$string['datelabelisbetween'] = '{$a->label} is between {$a->after} and {$a->before}';
@@ -63,6 +65,7 @@ $string['isempty'] = 'is empty';
$string['isequalto'] = 'is equal to';
$string['isnotdefined'] = 'isn\'t defined';
$string['isnotequalto'] = 'isn\'t equal to';
$string['limiterfor'] = '{$a} field limiter';
$string['neveraccessed'] = 'Never accessed';
$string['nevermodified'] = 'Never modified';
$string['newfilter'] = 'New filter';
@@ -70,6 +73,8 @@ $string['nofiltersenabled'] = 'No filter plugins have been enabled on this site.
$string['off'] = 'Off';
$string['offbutavailable'] = 'Off, but available';
$string['on'] = 'On';
$string['profilefilterfield'] = 'Profile field name';
$string['profilefilterlimiter'] = 'Profile field operator';
$string['profilelabel'] = '{$a->label}: {$a->profile} {$a->operator} {$a->value}';
$string['profilelabelnovalue'] = '{$a->label}: {$a->profile} {$a->operator}';
$string['removeall'] = 'Remove all filters';
@@ -79,3 +84,4 @@ $string['startswith'] = 'starts with';
$string['tablenosave'] = 'Changes in table above are saved automatically.';
$string['textlabel'] = '{$a->label} {$a->operator} {$a->value}';
$string['textlabelnovalue'] = '{$a->label} {$a->operator}';
$string['valuefor'] = '{$a} value';
+1 -1
View File
@@ -32,7 +32,7 @@ $string['err_alphanumeric'] = 'You must enter only letters or numbers here.';
$string['err_email'] = 'You must enter a valid email address here.';
$string['err_lettersonly'] = 'You must enter only letters here.';
$string['err_maxfiles'] = 'You must not attach more than {$a} files here.';
$string['err_maxlength'] = 'You must enter not more than {$a->format} characters here.';
$string['err_maxlength'] = 'You must enter no more than {$a->format} characters here.';
$string['err_minlength'] = 'You must enter at least {$a->format} characters here.';
$string['err_nonzero'] = 'You must enter a number not starting with a 0 here.';
$string['err_nopunctuation'] = 'You must enter no punctuation characters here.';
+1
View File
@@ -305,6 +305,7 @@ $string['gradepointmax_validateerror'] = 'This setting must be an integer betwee
$string['gradepreferences'] = 'Grade preferences';
$string['gradepreferenceshelp'] = 'Grade preferences Help';
$string['gradepublishing'] = 'Enable publishing';
$string['gradepublishinglink'] = 'Download: {$a}';
$string['gradepublishing_help'] = 'Enable publishing in exports and imports: Exported grades can be accessed by accessing a URL, without having to log on to a Moodle site. Grades can be imported by accessing such a URL (which means that a Moodle site can import grades published by another site). By default only administrators may use this feature, please educate users before adding required capabilities to other roles (dangers of bookmark sharing and download accelerators, IP restrictions, etc.).';
$string['gradereport'] = 'Grade report';
$string['graderreport'] = 'Grader report';
+1 -1
View File
@@ -1561,7 +1561,7 @@ $string['rssarticles'] = 'Number of RSS recent articles';
$string['rsserror'] = 'Error reading RSS data';
$string['rsserrorauth'] = 'Your RSS link does not contain a valid authentication token.';
$string['rsserrorguest'] = 'This feed uses guest access to access the data, but guest does not have permission to read the data. Visit the original location that this feed comes from (URL) as a valid user and get a new RSS link from there.';
$string['rsskeyshelp'] = 'To ensure security and privacy, RSS feed URLs contain a special token that identifies the user they are for. This prevents other users from accessing areas of Moodle they shouldn\'t have access to via RSS feeds.</p><p>This token is automatically created the first time you access an area of Moodle that produces an RSS feed. If you feel that your RSS feed token has been compromised in some way you can request a new one by clicking the Reset link here. Please note that your current RSS feed URLs will then become invalid.';
$string['rsskeyshelp'] = '<p>To ensure security and privacy, RSS feed URLs contain a special token that identifies the user they are for. This prevents other users from accessing areas of the site where they are not allowed.</p><p>The token is automatically created the first time you access an area that produces an RSS feed. If you think that your RSS feed token has been compromised, you can request a new one by clicking the reset link. Please note that your current RSS feed URLs will then become invalid.</p>';
$string['rsstype'] = 'RSS feed for this activity';
$string['saveandnext'] = 'Save and show next';
$string['savedat'] = 'Saved at:';
+4 -4
View File
@@ -62,16 +62,16 @@ $string['close'] = 'Close';
$string['commonrepositorysettings'] = 'Common repository settings';
$string['configallowexternallinks'] = 'This option enables all users to choose whether or not external media is copied into Moodle or not. If this is off then media is always copied into Moodle (this is usually best for overall data integrity and security). If this is on then users can choose each time they add media to a text.';
$string['configcacheexpire'] = 'The amount of time that file listings are cached locally (in seconds) when browsing external repositories.';
$string['configgetfiletimeout'] = 'Timeout in seconds for downloading the external file into moodle.';
$string['configgetfiletimeout'] = 'Timeout in seconds for downloading an external file into Moodle.';
$string['configsaved'] = 'Configuration saved!';
$string['configsyncfiletimeout'] = 'Timeout in seconds for syncronising the external file size.';
$string['configsyncimagetimeout'] = 'Timeout in seconds for downloading an image file from external repository during syncronisation.';
$string['confirmdelete'] = 'Are you sure you want to delete this repository - {$a}? If you choose "Continue and download", file references to external contents will be downloaded to moodle, but it could take long time to process.';
$string['confirmdelete'] = 'Are you sure you want to delete the repository {$a}? If you choose "Continue and download", file references to external contents will be downloaded to Moodle. This could take a long time to process.';
$string['confirmdeletefile'] = 'Are you sure you want to delete this file?';
$string['confirmrenamefile'] = 'Are you sure you want to rename/move this file? There are {$a} alias/shortcut files that use this file as their source. If you proceed then those aliases will be converted to true copies.';
$string['confirmdeletefilewithhref'] = 'Are you sure you want to delete this file? There are {$a} alias/shortcut files that use this file as their source. If you proceed then those aliases will be converted to true copies.';
$string['confirmdeletefolder'] = 'Are you sure you want to delete this folder? All files and subfolders will be deleted.';
$string['confirmremove'] = 'Are you sure you want to remove this repository plugin, its options and <strong>all of its instances</strong> - {$a}? If you choose "Continue and download", file references to external contents will be downloaded to moodle, but it could take long time to process.';
$string['confirmremove'] = 'Are you sure you want to remove this repository plugin, its options and <strong>all of its instances</strong> - {$a}? If you choose "Continue and download", file references to external contents will be downloaded to Moodle. This could take a long time to process.';
$string['confirmrenamefolder'] = ' Are you sure you want to move/rename this folder? Any alias/shortcut files that reference files in this folder will be converted into true copies.';
$string['continueuninstall'] = 'Continue';
$string['continueuninstallanddownload'] = 'Continue and download';
@@ -241,7 +241,7 @@ $string['usenonjsfilemanager'] = 'Open file manager in new window';
$string['usenonjsfilepicker'] = 'Open file picker in new window';
$string['unzipped'] = 'Unzipped successfully';
$string['wrongcontext'] = 'You cannot access to this context';
$string['xhtmlerror'] = 'You are probably using XHTML strict header, some YUI Component doesn\'t work in this mode, please turn it off in moodle';
$string['xhtmlerror'] = 'You are probably using an XHTML strict header. Certain YUI components don\'t work in this mode; please turn it off.';
$string['ziped'] = 'Compress folder successfully';
// Deprecated since Moodle 2.8.
+2 -2
View File
@@ -171,10 +171,10 @@ $string['defaultx'] = 'Default: {$a}';
$string['defineroles'] = 'Define roles';
$string['deletecourseoverrides'] = 'Delete all overrides in course';
$string['deletelocalroles'] = 'Delete all local role assignments';
$string['deleterolesure'] = 'Are you sure that you want to delete role "{$a->name} ({$a->shortname})"?</p><p>Currently this role is assigned to {$a->count} users.';
$string['deleterolesure'] = '<p>Are you sure that you want to delete role "{$a->name} ({$a->shortname})"?</p><p>Currently this role is assigned to {$a->count} users.</p>';
$string['deletexrole'] = 'Delete {$a} role';
$string['duplicaterole'] = 'Duplicate role';
$string['duplicaterolesure'] = 'Are you sure that you want to duplicate role "{$a->name} ({$a->shortname})"?</p>';
$string['duplicaterolesure'] = '<p>Are you sure that you want to duplicate role "{$a->name} ({$a->shortname})"?</p>';
$string['editingrolex'] = 'Editing role \'{$a}\'';
$string['editrole'] = 'Edit role';
$string['editxrole'] = 'Edit {$a} role';
+1
View File
@@ -127,6 +127,7 @@ $string['missingusername'] = 'Missing username';
$string['missingversionfile'] = 'Coding error: version.php file is missing for the component {$a}';
$string['mobilewsdisabled'] = 'Disabled';
$string['mobilewsenabled'] = 'Enabled';
$string['nameexists'] = 'This name is already in use by another service';
$string['nocapabilitytouseparameter'] = 'The user does not have the required capability to use the parameter {$a}';
$string['nofunctions'] = 'This service has no functions.';
$string['norequiredcapability'] = 'No required capability';
+30 -15
View File
@@ -6447,14 +6447,17 @@ class context_user extends context {
protected static function create_level_instances() {
global $DB;
$sql = "INSERT INTO {context} (contextlevel, instanceid)
SELECT ".CONTEXT_USER.", u.id
$sql = "SELECT ".CONTEXT_USER.", u.id
FROM {user} u
WHERE u.deleted = 0
AND NOT EXISTS (SELECT 'x'
FROM {context} cx
WHERE u.id = cx.instanceid AND cx.contextlevel=".CONTEXT_USER.")";
$DB->execute($sql);
$contextdata = $DB->get_recordset_sql($sql);
foreach ($contextdata as $context) {
context::insert_context_record(CONTEXT_USER, $context->id, null);
}
$contextdata->close();
}
/**
@@ -6655,13 +6658,16 @@ class context_coursecat extends context {
protected static function create_level_instances() {
global $DB;
$sql = "INSERT INTO {context} (contextlevel, instanceid)
SELECT ".CONTEXT_COURSECAT.", cc.id
$sql = "SELECT ".CONTEXT_COURSECAT.", cc.id
FROM {course_categories} cc
WHERE NOT EXISTS (SELECT 'x'
FROM {context} cx
WHERE cc.id = cx.instanceid AND cx.contextlevel=".CONTEXT_COURSECAT.")";
$DB->execute($sql);
$contextdata = $DB->get_recordset_sql($sql);
foreach ($contextdata as $context) {
context::insert_context_record(CONTEXT_COURSECAT, $context->id, null);
}
$contextdata->close();
}
/**
@@ -6878,13 +6884,16 @@ class context_course extends context {
protected static function create_level_instances() {
global $DB;
$sql = "INSERT INTO {context} (contextlevel, instanceid)
SELECT ".CONTEXT_COURSE.", c.id
$sql = "SELECT ".CONTEXT_COURSE.", c.id
FROM {course} c
WHERE NOT EXISTS (SELECT 'x'
FROM {context} cx
WHERE c.id = cx.instanceid AND cx.contextlevel=".CONTEXT_COURSE.")";
$DB->execute($sql);
$contextdata = $DB->get_recordset_sql($sql);
foreach ($contextdata as $context) {
context::insert_context_record(CONTEXT_COURSE, $context->id, null);
}
$contextdata->close();
}
/**
@@ -7132,13 +7141,16 @@ class context_module extends context {
protected static function create_level_instances() {
global $DB;
$sql = "INSERT INTO {context} (contextlevel, instanceid)
SELECT ".CONTEXT_MODULE.", cm.id
$sql = "SELECT ".CONTEXT_MODULE.", cm.id
FROM {course_modules} cm
WHERE NOT EXISTS (SELECT 'x'
FROM {context} cx
WHERE cm.id = cx.instanceid AND cx.contextlevel=".CONTEXT_MODULE.")";
$DB->execute($sql);
$contextdata = $DB->get_recordset_sql($sql);
foreach ($contextdata as $context) {
context::insert_context_record(CONTEXT_MODULE, $context->id, null);
}
$contextdata->close();
}
/**
@@ -7349,13 +7361,16 @@ class context_block extends context {
protected static function create_level_instances() {
global $DB;
$sql = "INSERT INTO {context} (contextlevel, instanceid)
SELECT ".CONTEXT_BLOCK.", bi.id
$sql = "SELECT ".CONTEXT_BLOCK.", bi.id
FROM {block_instances} bi
WHERE NOT EXISTS (SELECT 'x'
FROM {context} cx
WHERE bi.id = cx.instanceid AND cx.contextlevel=".CONTEXT_BLOCK.")";
$DB->execute($sql);
$contextdata = $DB->get_recordset_sql($sql);
foreach ($contextdata as $context) {
context::insert_context_record(CONTEXT_BLOCK, $context->id, null);
}
$contextdata->close();
}
/**
+12 -8
View File
@@ -3231,16 +3231,20 @@ class admin_setting_configtime extends admin_setting {
$defaultinfo = NULL;
}
$return = '<div class="form-time defaultsnext">'.
'<select id="'.$this->get_id().'h" name="'.$this->get_full_name().'[h]">';
$return = '<div class="form-time defaultsnext">';
$return .= '<label class="accesshide" for="' . $this->get_id() . 'h">' . get_string('hours') . '</label>';
$return .= '<select id="' . $this->get_id() . 'h" name="' . $this->get_full_name() . '[h]">';
for ($i = 0; $i < 24; $i++) {
$return .= '<option value="'.$i.'"'.($i == $data['h'] ? ' selected="selected"' : '').'>'.$i.'</option>';
$return .= '<option value="' . $i . '"' . ($i == $data['h'] ? ' selected="selected"' : '') . '>' . $i . '</option>';
}
$return .= '</select>:<select id="'.$this->get_id().'m" name="'.$this->get_full_name().'[m]">';
$return .= '</select>:';
$return .= '<label class="accesshide" for="' . $this->get_id() . 'm">' . get_string('minutes') . '</label>';
$return .= '<select id="' . $this->get_id() . 'm" name="' . $this->get_full_name() . '[m]">';
for ($i = 0; $i < 60; $i += 5) {
$return .= '<option value="'.$i.'"'.($i == $data['m'] ? ' selected="selected"' : '').'>'.$i.'</option>';
$return .= '<option value="' . $i . '"' . ($i == $data['m'] ? ' selected="selected"' : '') . '>' . $i . '</option>';
}
$return .= '</select></div>';
$return .= '</select>';
$return .= '</div>';
return format_admin_setting($this, $this->visiblename, $return, $this->description, false, '', $defaultinfo, $query);
}
@@ -7771,11 +7775,11 @@ class admin_setting_webservicesoverview extends admin_setting {
get_string('enablemobilewebservice', 'admin'),
get_string('configenablemobilewebservice',
'admin', ''), 0); //we don't want to display it but to know the ws mobile status
$manageserviceurl = new moodle_url("/admin/settings.php?section=externalservices");
$manageserviceurl = new moodle_url("/admin/settings.php?section=mobile");
$wsmobileparam = new stdClass();
$wsmobileparam->enablemobileservice = get_string('enablemobilewebservice', 'admin');
$wsmobileparam->manageservicelink = html_writer::link($manageserviceurl,
get_string('externalservices', 'webservice'));
get_string('mobile', 'admin'));
$mobilestatus = $enablemobile->get_setting()?get_string('mobilewsenabled', 'webservice'):get_string('mobilewsdisabled', 'webservice');
$wsmobileparam->wsmobilestatus = html_writer::tag('strong', $mobilestatus);
$return .= $OUTPUT->heading(get_string('enablemobilewebservice', 'admin'), 3, 'main');
+1 -1
View File
@@ -28,7 +28,7 @@ require_once(dirname(__FILE__) . '/../../config.php');
// Initialise ALL common incoming parameters here, up front.
$courseid = required_param('courseid', PARAM_INT);
$pagelayout = required_param('pagelayout', PARAM_ALPHAEXT);
$pagetype = required_param('pagetype', PARAM_ALPHAEXT);
$pagetype = required_param('pagetype', PARAM_ALPHANUMEXT);
$contextid = required_param('contextid', PARAM_INT);
$subpage = optional_param('subpage', '', PARAM_ALPHANUMEXT);
$cmid = optional_param('cmid', null, PARAM_INT);
+2 -1
View File
@@ -1126,7 +1126,8 @@ function badges_download($userid) {
if ($zipper->archive_to_pathname($filelist, $tempzip)) {
send_temp_file($tempzip, 'badges.zip');
} else {
debugging("Problems with archiving the files.");
debugging("Problems with archiving the files.", DEBUG_DEVELOPER);
die;
}
}
+11 -4
View File
@@ -302,6 +302,11 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
$loops = $timeout;
}
// DOM will never change on non-javascript case; do not wait or try again.
if (!$this->running_javascript()) {
$loops = 1;
}
for ($i = 0; $i < $loops; $i++) {
// We catch the exception thrown by the step definition to execute it again.
try {
@@ -320,10 +325,12 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
continue;
}
if ($microsleep) {
usleep(100000);
} else {
sleep(1);
if ($this->running_javascript()) {
if ($microsleep) {
usleep(100000);
} else {
sleep(1);
}
}
}
+58 -38
View File
@@ -39,41 +39,47 @@ class behat_selectors {
* @var Allowed types when using text selectors arguments.
*/
protected static $allowedtextselectors = array(
'dialogue' => 'dialogue',
'activity' => 'activity',
'block' => 'block',
'region' => 'region',
'table_row' => 'table_row',
'list_item' => 'list_item',
'table' => 'table',
'fieldset' => 'fieldset',
'css_element' => 'css_element',
'xpath_element' => 'xpath_element'
'dialogue' => 'dialogue',
'fieldset' => 'fieldset',
'list_item' => 'list_item',
'question' => 'question',
'region' => 'region',
'section' => 'section',
'table' => 'table',
'table_row' => 'table_row',
'xpath_element' => 'xpath_element',
);
/**
* @var Allowed types when using selector arguments.
*/
protected static $allowedselectors = array(
'dialogue' => 'dialogue',
'activity' => 'activity',
'block' => 'block',
'region' => 'region',
'table_row' => 'table_row',
'list_item' => 'list_item',
'link' => 'link',
'button' => 'button',
'link_or_button' => 'link_or_button',
'select' => 'select',
'checkbox' => 'checkbox',
'radio' => 'radio',
'file' => 'file',
'filemanager' => 'filemanager',
'optgroup' => 'optgroup',
'option' => 'option',
'table' => 'table',
'css_element' => 'css_element',
'dialogue' => 'dialogue',
'field' => 'field',
'fieldset' => 'fieldset',
'file' => 'file',
'filemanager' => 'filemanager',
'link' => 'link',
'link_or_button' => 'link_or_button',
'list_item' => 'list_item',
'optgroup' => 'optgroup',
'option' => 'option',
'question' => 'question',
'radio' => 'radio',
'region' => 'region',
'section' => 'section',
'select' => 'select',
'table' => 'table',
'table_row' => 'table_row',
'text' => 'text',
'css_element' => 'css_element',
'xpath_element' => 'xpath_element'
);
@@ -86,8 +92,14 @@ class behat_selectors {
* @var XPaths for moodle elements.
*/
protected static $moodleselectors = array(
'text' => <<<XPATH
//*[contains(., %locator%)][count(./descendant::*[contains(., %locator%)]) = 0]
'activity' => <<<XPATH
//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')][normalize-space(.) = %locator% ]
XPATH
, 'block' => <<<XPATH
//div[contains(concat(' ', normalize-space(@class), ' '), ' block ') and
(contains(concat(' ', normalize-space(@class), ' '), concat(' ', %locator%, ' ')) or
descendant::h2[normalize-space(.) = %locator%] or
@aria-label = %locator%)]
XPATH
, 'dialogue' => <<<XPATH
//div[contains(concat(' ', normalize-space(@class), ' '), ' moodle-dialogue ') and
@@ -96,28 +108,36 @@ XPATH
]) = %locator%] |
//div[contains(concat(' ', normalize-space(@class), ' '), ' yui-dialog ') and
normalize-space(descendant::div[@class='hd']) = %locator%]
XPATH
, 'block' => <<<XPATH
//div[contains(concat(' ', normalize-space(@class), ' '), ' block ') and
(contains(concat(' ', normalize-space(@class), ' '), concat(' ', %locator%, ' ')) or
descendant::h2[normalize-space(.) = %locator%] or
@aria-label = %locator%)]
XPATH
, 'region' => <<<XPATH
//*[self::div | self::section | self::aside | self::header | self::footer][./@id = %locator%]
XPATH
, 'table_row' => <<<XPATH
.//tr[contains(normalize-space(.), %locator%)]
XPATH
, 'list_item' => <<<XPATH
.//li[contains(normalize-space(.), %locator%)]
XPATH
, 'filemanager' => <<<XPATH
//div[contains(concat(' ', normalize-space(@class), ' '), ' ffilemanager ')]
/descendant::input[@id = //label[contains(normalize-space(string(.)), %locator%)]/@for]
XPATH
, 'list_item' => <<<XPATH
.//li[contains(normalize-space(.), %locator%)]
XPATH
, 'question' => <<<XPATH
//div[contains(concat(' ', normalize-space(@class), ' '), ' que ')]
[contains(div[@class='content']/div[@class='formulation'], %locator%)]
XPATH
, 'region' => <<<XPATH
//*[self::div | self::section | self::aside | self::header | self::footer][./@id = %locator%]
XPATH
, 'section' => <<<XPATH
//li[contains(concat(' ', normalize-space(@class), ' '), ' section ')][./descendant::*[self::h3]
[normalize-space(.) = %locator%][contains(concat(' ', normalize-space(@class), ' '), ' sectionname ') or
contains(concat(' ', normalize-space(@class), ' '), ' section-title ')]] |
//div[contains(concat(' ', normalize-space(@class), ' '), ' sitetopic ')]
[./descendant::*[self::h2][normalize-space(.) = %locator%] or %locator% = 'frontpage']
XPATH
, 'table' => <<<XPATH
.//table[(./@id = %locator% or contains(.//caption, %locator%) or contains(concat(' ', normalize-space(@class), ' '), %locator% ))]
XPATH
, 'table_row' => <<<XPATH
.//tr[contains(normalize-space(.), %locator%)]
XPATH
, 'text' => <<<XPATH
//*[contains(., %locator%)][count(./descendant::*[contains(., %locator%)]) = 0]
XPATH
);
+23 -14
View File
@@ -486,6 +486,11 @@ class block_manager {
return false;
}
// Block regions should not be docked during editing when all the blocks are hidden.
if ($this->page->user_is_editing() && $this->page->user_can_edit_blocks()) {
return false;
}
$this->check_is_loaded();
$this->ensure_content_created($region, $output);
if (!$this->region_has_content($region, $output)) {
@@ -493,7 +498,7 @@ class block_manager {
return false;
}
foreach ($this->visibleblockcontent[$region] as $instance) {
if (!empty($instance->content) && !get_user_preferences('docked_block_instance_'.$instance->blockinstanceid, 0)) {
if (!get_user_preferences('docked_block_instance_'.$instance->blockinstanceid, 0)) {
return false;
}
}
@@ -745,19 +750,23 @@ class block_manager {
}
/**
* Convenience method, calls add_block repeatedly for all the blocks in $blocks.
* Convenience method, calls add_block repeatedly for all the blocks in $blocks. Optionally, a starting weight
* can be used to decide the starting point that blocks are added in the region, the weight is passed to {@link add_block}
* and incremented by the position of the block in the $blocks array
*
* @param array $blocks array with array keys the region names, and values an array of block names.
* @param string $pagetypepattern optional. Passed to @see add_block()
* @param string $subpagepattern optional. Passed to @see add_block()
* @param string $pagetypepattern optional. Passed to {@link add_block()}
* @param string $subpagepattern optional. Passed to {@link add_block()}
* @param boolean $showinsubcontexts optional. Passed to {@link add_block()}
* @param integer $weight optional. Determines the starting point that the blocks are added in the region.
*/
public function add_blocks($blocks, $pagetypepattern = NULL, $subpagepattern = NULL, $showinsubcontexts=false, $weight=0) {
$initialweight = $weight;
$this->add_regions(array_keys($blocks), false);
foreach ($blocks as $region => $regionblocks) {
$weight = 0;
foreach ($regionblocks as $blockname) {
foreach ($regionblocks as $offset => $blockname) {
$weight = $initialweight + $offset;
$this->add_block($blockname, $region, $weight, $showinsubcontexts, $pagetypepattern, $subpagepattern);
$weight += 1;
}
}
}
@@ -2118,12 +2127,12 @@ function blocks_find_block($blockid, $blocksarray) {
// Functions for programatically adding default blocks to pages ================
/**
* Parse a list of default blocks. See config-dist for a description of the format.
*
* @param string $blocksstr
* @return array
*/
/**
* Parse a list of default blocks. See config-dist for a description of the format.
*
* @param string $blocksstr Determines the starting point that the blocks are added in the region.
* @return array the parsed list of default blocks
*/
function blocks_parse_default_blocks_list($blocksstr) {
$blocks = array();
$bits = explode(':', $blocksstr);
@@ -2134,7 +2143,7 @@ function blocks_parse_default_blocks_list($blocksstr) {
}
}
if (!empty($bits)) {
$rightbits =trim(array_shift($bits));
$rightbits = trim(array_shift($bits));
if ($rightbits != '') {
$blocks[BLOCK_POS_RIGHT] = explode(',', $rightbits);
}
+38 -1
View File
@@ -54,4 +54,41 @@ class portfolio extends base {
public static function get_manage_url() {
return new moodle_url('/admin/portfolio.php');
}
}
/**
* Defines if there should be a way to uninstall the plugin via the administration UI.
* @return boolean
*/
public function is_uninstall_allowed() {
return true;
}
/**
* Pre-uninstall hook.
* This is intended for disabling of plugin, some DB table purging, etc.
*/
public function uninstall_cleanup() {
global $DB;
// Get all instances of this portfolio.
$count = $DB->count_records('portfolio_instance', array('plugin' => $this->name));
if ($count > 0) {
// This portfolio is in use, get the it's ID.
$rec = $DB->get_record('portfolio_instance', array('plugin' => $this->name));
// Remove all records from portfolio_instance_config.
$DB->delete_records('portfolio_instance_config', array('instance' => $rec->id));
// Remove all records from portfolio_instance_user.
$DB->delete_records('portfolio_instance_user', array('instance' => $rec->id));
// Remove all records from portfolio_log.
$DB->delete_records('portfolio_log', array('portfolio' => $rec->id));
// Remove all records from portfolio_tempdata.
$DB->delete_records('portfolio_tempdata', array('instance' => $rec->id));
// Remove the record from the portfolio_instance table.
$DB->delete_records('portfolio_instance', array('id' => $rec->id));
}
parent::uninstall_cleanup();
}
}
+3 -3
View File
@@ -44,7 +44,7 @@ class memcached extends handler {
protected $acquiretimeout = 120;
/**
* @var int $lockexpire how long to wait before expiring the lock so that other requests
* may continue execution, ignored if memcached <= 2.1.0.
* may continue execution, ignored if PECL memcached is below version 2.2.0.
*/
protected $lockexpire = 7200;
@@ -86,7 +86,7 @@ class memcached extends handler {
* @return bool success
*/
public function start() {
// NOTE: memcached <= 2.1.0 expires session locks automatically after max_execution_time,
// NOTE: memcached before 2.2.0 expires session locks automatically after max_execution_time,
// this leads to major difference compared to other session drivers that timeout
// and stop the second request execution instead.
@@ -119,7 +119,7 @@ class memcached extends handler {
ini_set('memcached.sess_prefix', $this->prefix);
ini_set('memcached.sess_locking', '1'); // Locking is required!
// Try to configure lock and expire timeouts - ignored if memcached <=2.1.0.
// Try to configure lock and expire timeouts - ignored if memcached is before version 2.2.0.
ini_set('memcached.sess_lock_max_wait', $this->acquiretimeout);
ini_set('memcached.sess_lock_expire', $this->lockexpire);
}
+14 -47
View File
@@ -85,53 +85,31 @@ class manager {
*/
public static function reset_scheduled_tasks_for_component($componentname) {
global $DB;
$cronlockfactory = \core\lock\lock_config::get_lock_factory('cron');
if (!$cronlock = $cronlockfactory->get_lock('core_cron', 10, 60)) {
throw new \moodle_exception('locktimeout');
}
$tasks = self::load_default_scheduled_tasks_for_component($componentname);
$tasklocks = array();
foreach ($tasks as $taskid => $task) {
$classname = get_class($task);
if (strpos($classname, '\\') !== 0) {
$classname = '\\' . $classname;
}
// For tasks, the first run should also follow the schedule.
$task->set_next_run_time($task->get_next_scheduled_time());
// If there is an existing task with a custom schedule, do not override it.
$currenttask = self::get_scheduled_task($classname);
if ($currenttask && $currenttask->is_customised()) {
$tasks[$taskid] = $currenttask;
}
if (!$lock = $cronlockfactory->get_lock($classname, 10, 60)) {
// Could not get all the locks required - release all locks and fail.
foreach ($tasklocks as $tasklock) {
$tasklock->release();
if ($currenttask = self::get_scheduled_task($classname)) {
if ($currenttask->is_customised()) {
// If there is an existing task with a custom schedule, do not override it.
continue;
}
$cronlock->release();
throw new \moodle_exception('locktimeout');
// Update the record from the default task data.
self::configure_scheduled_task($task);
} else {
// Ensure that the first run follows the schedule.
$task->set_next_run_time($task->get_next_scheduled_time());
// Insert the new task in the database.
$record = self::record_from_scheduled_task($task);
$DB->insert_record('task_scheduled', $record);
}
$tasklocks[] = $lock;
}
// Got a lock on cron and all the tasks for this component, time to reset the config.
$DB->delete_records('task_scheduled', array('component' => $componentname));
foreach ($tasks as $task) {
$record = self::record_from_scheduled_task($task);
$DB->insert_record('task_scheduled', $record);
}
// Release the locks.
foreach ($tasklocks as $tasklock) {
$tasklock->release();
}
$cronlock->release();
}
/**
@@ -160,20 +138,11 @@ class manager {
*/
public static function configure_scheduled_task(scheduled_task $task) {
global $DB;
$cronlockfactory = \core\lock\lock_config::get_lock_factory('cron');
if (!$cronlock = $cronlockfactory->get_lock('core_cron', 10, 60)) {
throw new \moodle_exception('locktimeout');
}
$classname = get_class($task);
if (strpos($classname, '\\') !== 0) {
$classname = '\\' . $classname;
}
if (!$lock = $cronlockfactory->get_lock($classname, 10, 60)) {
$cronlock->release();
throw new \moodle_exception('locktimeout');
}
$original = $DB->get_record('task_scheduled', array('classname'=>$classname), 'id', MUST_EXIST);
@@ -182,8 +151,6 @@ class manager {
$record->nextruntime = $task->get_next_scheduled_time();
$result = $DB->update_record('task_scheduled', $record);
$lock->release();
$cronlock->release();
return $result;
}
+5 -2
View File
@@ -323,8 +323,11 @@ class component_installer {
/// Move current revision to a safe place
$destinationdir = $CFG->dataroot.'/'.$this->destpath;
$destinationcomponent = $destinationdir.'/'.$this->componentname;
@remove_dir($destinationcomponent.'_old'); //Deleting possible old components before
@rename ($destinationcomponent, $destinationcomponent.'_old'); //Moving to a safe place
@remove_dir($destinationcomponent.'_old'); // Deleting a possible old version.
// Moving to a safe place.
@rename($destinationcomponent, $destinationcomponent.'_old');
/// Unzip new version
if (!unzip_file($zipfile, $destinationdir, false)) {
/// Error so, go back to the older
+13 -3
View File
@@ -168,9 +168,11 @@ function min_enable_zlib_compression() {
* Note: ".php" is NOT allowed in slasharguments,
* it is intended for ASCII characters only.
*
* @param boolean $clean - Should we do cleaning on this path argument. If you set this
* to false you MUST be very careful and do the cleaning manually.
* @return string
*/
function min_get_slash_argument() {
function min_get_slash_argument($clean = true) {
// Note: This code has to work in the same cases as normal get_file_argument(),
// but at the same time it may be simpler because we do not have to deal
// with encodings and other tricky stuff.
@@ -180,7 +182,12 @@ function min_get_slash_argument() {
if (!empty($_GET['file']) and strpos($_GET['file'], '/') === 0) {
// Server is using url rewriting, most probably IIS.
// Always clean the result of this function as it may be used in unsafe calls to send_file.
return min_clean_param($_GET['file'], 'SAFEPATH');
$relativepath = $_GET['file'];
if ($clean) {
$relativepath = min_clean_param($relativepath, 'SAFEPATH');
}
return $relativepath;
} else if (stripos($_SERVER['SERVER_SOFTWARE'], 'iis') !== false) {
if (isset($_SERVER['PATH_INFO']) and $_SERVER['PATH_INFO'] !== '') {
@@ -199,5 +206,8 @@ function min_get_slash_argument() {
}
// Always clean the result of this function as it may be used in unsafe calls to send_file.
return min_clean_param($relativepath, 'SAFEPATH');
if ($clean) {
$relativepath = min_clean_param($relativepath, 'SAFEPATH');
}
return $relativepath;
}
+2 -2
View File
@@ -125,8 +125,8 @@ $tasks = array(
array(
'classname' => 'core\task\create_contexts_task',
'blocking' => 1,
'minute' => '*',
'hour' => '*',
'minute' => '0',
'hour' => '0',
'day' => '*',
'dayofweek' => '*',
'month' => '*'
+2 -1
View File
@@ -978,7 +978,8 @@ class oci_native_moodle_database extends moodle_database {
default: // Bind as CHAR (applying dirty hack)
// TODO: Optimise
oci_bind_by_name($stmt, $key, $this->oracle_dirty_hack($tablename, $columnname, $params[$key]));
$params[$key] = $this->oracle_dirty_hack($tablename, $columnname, $params[$key]);
oci_bind_by_name($stmt, $key, $params[$key]);
}
}
}
@@ -299,6 +299,21 @@ Y.extend(Editor, Y.Base, {
setupAutomaticPolling: function() {
this._registerEventHandle(this.editor.on(['keyup', 'paste', 'cut'], this.updateOriginal, this));
// Call this.updateOriginal after dropped content has been processed.
this._registerEventHandle(this.editor.on('drop', this.updateOriginalDelayed, this));
return this;
},
/**
* Calls updateOriginal on a short timer to allow native event handlers to run first.
*
* @method updateOriginalDelayed
* @chainable
*/
updateOriginalDelayed: function() {
Y.soon(Y.bind(this.updateOriginal, this));
return this;
},
File diff suppressed because one or more lines are too long
@@ -297,6 +297,21 @@ Y.extend(Editor, Y.Base, {
setupAutomaticPolling: function() {
this._registerEventHandle(this.editor.on(['keyup', 'paste', 'cut'], this.updateOriginal, this));
// Call this.updateOriginal after dropped content has been processed.
this._registerEventHandle(this.editor.on('drop', this.updateOriginalDelayed, this));
return this;
},
/**
* Calls updateOriginal on a short timer to allow native event handlers to run first.
*
* @method updateOriginalDelayed
* @chainable
*/
updateOriginalDelayed: function() {
Y.soon(Y.bind(this.updateOriginal, this));
return this;
},
+15
View File
@@ -297,6 +297,21 @@ Y.extend(Editor, Y.Base, {
setupAutomaticPolling: function() {
this._registerEventHandle(this.editor.on(['keyup', 'paste', 'cut'], this.updateOriginal, this));
// Call this.updateOriginal after dropped content has been processed.
this._registerEventHandle(this.editor.on('drop', this.updateOriginalDelayed, this));
return this;
},
/**
* Calls updateOriginal on a short timer to allow native event handlers to run first.
*
* @method updateOriginalDelayed
* @chainable
*/
updateOriginalDelayed: function() {
Y.soon(Y.bind(this.updateOriginal, this));
return this;
},
+7 -5
View File
@@ -108,11 +108,12 @@ class core_external extends external_api {
* @return string
* @since Moodle 2.4
*/
public static function get_string($stringid, $component = 'moodle', $stringparams = array()) {
public static function get_string($stringid, $component = 'moodle', $lang = null, $stringparams = array()) {
$params = self::validate_parameters(self::get_string_parameters(),
array('stringid'=>$stringid, 'component' => $component, 'stringparams' => $stringparams));
array('stringid'=>$stringid, 'component' => $component, 'lang' => $lang, 'stringparams' => $stringparams));
return get_string($params['stringid'], $params['component'],
$stringmanager = get_string_manager();
return $stringmanager->get_string($params['stringid'], $params['component'],
core_external::format_string_parameters($params['stringparams']), $params['lang']);
}
@@ -163,11 +164,12 @@ class core_external extends external_api {
public static function get_strings($strings) {
$params = self::validate_parameters(self::get_strings_parameters(),
array('strings'=>$strings));
$stringmanager = get_string_manager();
$translatedstrings = array();
foreach($params['strings'] as $string) {
if (empty($string['lang'])) {
if (!empty($string['lang'])) {
$lang = $string['lang'];
} else {
$lang = current_language();
@@ -177,7 +179,7 @@ class core_external extends external_api {
'stringid' => $string['stringid'],
'component' => $string['component'],
'lang' => $lang,
'string' => get_string($string['stringid'], $string['component'],
'string' => $stringmanager->get_string($string['stringid'], $string['component'],
core_external::format_string_parameters($string['stringparams']), $lang));
}
+12 -6
View File
@@ -41,7 +41,7 @@ class core_external_testcase extends externallib_advanced_testcase {
$service->id = 12;
// String with two parameters.
$returnedstring = core_external::get_string('addservice', 'webservice',
$returnedstring = core_external::get_string('addservice', 'webservice', null,
array(array('name' => 'name', 'value' => $service->name),
array('name' => 'id', 'value' => $service->id)));
@@ -53,7 +53,7 @@ class core_external_testcase extends externallib_advanced_testcase {
// String with one parameter.
$acapname = 'A capability name';
$returnedstring = core_external::get_string('missingrequiredcapability', 'webservice',
$returnedstring = core_external::get_string('missingrequiredcapability', 'webservice', null,
array(array('value' => $acapname)));
// We need to execute the return values cleaning process to simulate the web service server.
@@ -73,7 +73,7 @@ class core_external_testcase extends externallib_advanced_testcase {
// String with two parameter but one is invalid (not named).
$this->setExpectedException('moodle_exception');
$returnedstring = core_external::get_string('addservice', 'webservice',
$returnedstring = core_external::get_string('addservice', 'webservice', null,
array(array('value' => $service->name),
array('name' => 'id', 'value' => $service->id)));
}
@@ -84,6 +84,8 @@ class core_external_testcase extends externallib_advanced_testcase {
public function test_get_strings() {
$this->resetAfterTest(true);
$stringmanager = get_string_manager();
$service = new stdClass();
$service->name = 'Dummy Service';
$service->id = 12;
@@ -94,16 +96,20 @@ class core_external_testcase extends externallib_advanced_testcase {
'stringid' => 'addservice', 'component' => 'webservice',
'stringparams' => array(array('name' => 'name', 'value' => $service->name),
array('name' => 'id', 'value' => $service->id)
)
),
'lang' => 'en'
),
array('stringid' => 'addaservice', 'component' => 'webservice')
array('stringid' => 'addaservice', 'component' => 'webservice', 'lang' => 'en')
));
// We need to execute the return values cleaning process to simulate the web service server.
$returnedstrings = external_api::clean_returnvalue(core_external::get_strings_returns(), $returnedstrings);
foreach($returnedstrings as $returnedstring) {
$corestring = get_string($returnedstring['stringid'], $returnedstring['component'], $service);
$corestring = $stringmanager->get_string($returnedstring['stringid'],
$returnedstring['component'],
$service,
'en');
$this->assertSame($corestring, $returnedstring['string']);
}
}
+1
View File
@@ -656,6 +656,7 @@ class zip_archive extends file_archive {
case 'ISO-8859-6': $encoding = 'CP720'; break;
case 'ISO-8859-7': $encoding = 'CP737'; break;
case 'ISO-8859-8': $encoding = 'CP862'; break;
case 'EUC-JP':
case 'UTF-8':
if ($winchar = get_string('localewincharset', 'langconfig')) {
// Most probably works only for zh_cn,
+1 -1
View File
@@ -2905,7 +2905,7 @@ class MoodleQuickForm_Rule_Required extends HTML_QuickForm_Rule {
global $CFG;
if (!empty($CFG->strictformsrequired)) {
if (!empty($format) && $format == FORMAT_HTML) {
return array('', "{jsVar}.replace(/(<[^img|hr|canvas]+>)|&nbsp;|\s+/ig, '') == ''");
return array('', "{jsVar}.replace(/(<(?!img|hr|canvas)[^>]*>)|&nbsp;|\s+/ig, '') == ''");
} else {
return array('', "{jsVar}.replace(/^\s+$/g, '') == ''");
}
+22 -31
View File
@@ -767,6 +767,8 @@ class grade_category extends grade_object {
* Set the flags on the grade_grade items to indicate how individual grades are used
* in the aggregation.
*
* WARNING: This function is called a lot during gradebook recalculation, be very performance considerate.
*
* @param int $userid The user we have aggregated the grades for.
* @param array $usedweights An array with keys for each of the grade_item columns included in the aggregation. The value are the relative weight.
* @param array $novalue An array with keys for each of the grade_item columns skipped because
@@ -779,44 +781,32 @@ class grade_category extends grade_object {
private function set_usedinaggregation($userid, $usedweights, $novalue, $dropped, $extracredit) {
global $DB;
// First set them all to weight null and status = 'unknown'.
if ($allitems = grade_item::fetch_all(array('categoryid'=>$this->id))) {
list($itemsql, $itemlist) = $DB->get_in_or_equal(array_keys($allitems), SQL_PARAMS_NAMED, 'g');
// Reset aggregation to unknown and 0 for all grade items for this user and category.
$params = array('categoryid' => $this->id, 'userid' => $userid);
$itemssql = "SELECT id
FROM {grade_items}
WHERE categoryid = :categoryid";
$itemlist['userid'] = $userid;
$sql = "UPDATE {grade_grades}
SET aggregationstatus = 'unknown',
aggregationweight = 0
WHERE userid = :userid
AND itemid IN ($itemssql)";
$DB->set_field_select('grade_grades',
'aggregationstatus',
'unknown',
"itemid $itemsql AND userid = :userid",
$itemlist);
$DB->set_field_select('grade_grades',
'aggregationweight',
0,
"itemid $itemsql AND userid = :userid",
$itemlist);
}
$DB->execute($sql, $params);
// Included.
// Included with weights.
if (!empty($usedweights)) {
// The usedweights items are updated individually to record the weights.
foreach ($usedweights as $gradeitemid => $contribution) {
$DB->set_field_select('grade_grades',
'aggregationweight',
$contribution,
"itemid = :itemid AND userid = :userid",
array('itemid'=>$gradeitemid, 'userid'=>$userid));
$sql = "UPDATE {grade_grades}
SET aggregationstatus = 'used',
aggregationweight = :contribution
WHERE itemid = :itemid AND userid = :userid";
$params = array('contribution' => $contribution, 'itemid' => $gradeitemid, 'userid' => $userid);
$DB->execute($sql, $params);
}
// Now set the status flag for all these weights.
list($itemsql, $itemlist) = $DB->get_in_or_equal(array_keys($usedweights), SQL_PARAMS_NAMED, 'g');
$itemlist['userid'] = $userid;
$DB->set_field_select('grade_grades',
'aggregationstatus',
'used',
"itemid $itemsql AND userid = :userid",
$itemlist);
}
// No value.
@@ -844,6 +834,7 @@ class grade_category extends grade_object {
"itemid $itemsql AND userid = :userid",
$itemlist);
}
// Extra credit.
if (!empty($extracredit)) {
list($itemsql, $itemlist) = $DB->get_in_or_equal(array_keys($extracredit), SQL_PARAMS_NAMED, 'g');
+23 -5
View File
@@ -597,14 +597,32 @@ M.util.init_block_hider = function(Y, config) {
this.set('block', '#'+this.get('id'));
var b = this.get('block'),
t = b.one('.title'),
a = null;
a = null,
hide,
show;
if (t && (a = t.one('.block_action'))) {
var hide = Y.Node.create('<img class="block-hider-hide" tabindex="0" alt="'+config.tooltipVisible+'" title="'+config.tooltipVisible+'" />');
hide.setAttribute('src', this.get('iconVisible')).on('click', this.updateState, this, true);
hide = Y.Node.create('<img />')
.addClass('block-hider-hide')
.setAttrs({
alt: config.tooltipVisible,
src: this.get('iconVisible'),
tabindex: 0,
'title': config.tooltipVisible
});
hide.on('keypress', this.updateStateKey, this, true);
var show = Y.Node.create('<img class="block-hider-show" tabindex="0" alt="'+config.tooltipHidden+'" title="'+config.tooltipHidden+'" />');
show.setAttribute('src', this.get('iconHidden')).on('click', this.updateState, this, false);
hide.on('click', this.updateState, this, true);
show = Y.Node.create('<img />')
.addClass('block-hider-show')
.setAttrs({
alt: config.tooltipHidden,
src: this.get('iconHidden'),
tabindex: 0,
'title': config.tooltipHidden
});
show.on('keypress', this.updateStateKey, this, false);
show.on('click', this.updateState, this, false);
a.insert(show, 0).insert(hide, 0);
}
},
+55 -1
View File
@@ -536,15 +536,69 @@ class core_media_player_youtube extends core_media_player_external {
self::pick_video_size($width, $height);
$params = '';
$start = self::get_start_time($url);
if ($start > 0) {
$params .= "start=$start&";
}
$listid = $url->param('list');
// Check for non-empty but valid playlist ID.
if (!empty($listid) && !preg_match('/[^a-zA-Z0-9\-_]/', $listid)) {
// This video is part of a playlist, and we want to embed it as such.
$params .= "list=$listid&";
}
return <<<OET
<span class="mediaplugin mediaplugin_youtube">
<iframe title="$info" width="$width" height="$height"
src="https://www.youtube.com/embed/$videoid?rel=0&wmode=transparent" frameborder="0" allowfullscreen="1"></iframe>
src="https://www.youtube.com/embed/$videoid?{$params}rel=0&wmode=transparent" frameborder="0" allowfullscreen="1"></iframe>
</span>
OET;
}
/**
* Check for start time parameter. Note that it's in hours/mins/secs in the URL,
* but the embedded player takes only a number of seconds as the "start" parameter.
* @param moodle_url $url URL of video to be embedded.
* @return int Number of seconds video should start at.
*/
protected static function get_start_time($url) {
$matches = array();
$seconds = 0;
$rawtime = $url->param('t');
if (empty($rawtime)) {
$rawtime = $url->param('start');
}
if (is_numeric($rawtime)) {
// Start time already specified as a number of seconds; ensure it's an integer.
$seconds = $rawtime;
} else if (preg_match('/(\d+?h)?(\d+?m)?(\d+?s)?/i', $rawtime, $matches)) {
// Convert into a raw number of seconds, as that's all embedded players accept.
for ($i = 1; $i < count($matches); $i++) {
if (empty($matches[$i])) {
continue;
}
$part = str_split($matches[$i], strlen($matches[$i]) - 1);
switch ($part[1]) {
case 'h':
$seconds += 3600 * $part[0];
break;
case 'm':
$seconds += 60 * $part[0];
break;
default:
$seconds += $part[0];
}
}
}
return intval($seconds);
}
protected function get_regex() {
// Regex for standard youtube link
$link = '(youtube(-nocookie)?\.com/(?:watch\?v=|v/))';

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