Compare commits

..

971 Commits

Author SHA1 Message Date
Eloy Lafuente (stronk7) 3d765bc299 Moodle release 2.0.5 2011-10-09 00:52:59 +02:00
Eloy Lafuente (stronk7) 9e4b400c67 weekly release 2.0.4+ 2011-10-07 00:11:54 +02:00
Eloy Lafuente (stronk7) 9a31f96622 Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-10-07 00:05:23 +02:00
Aparup Banerjee 8e6e5adb5b Merge branch 'wip-MDL-28615-m20-squashed' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-10-05 14:54:31 +08:00
Eloy Lafuente (stronk7) 51acffb94a Merge branch 'MDL-28469_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-10-05 01:15:06 +02:00
Eloy Lafuente (stronk7) 74126d6d3e Merge branch 'wip-MDL-25697-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-10-05 01:10:40 +02:00
Sam Hemelryk c9cfe78950 MDL-28615 forum: Fixed up a couple of minor regressions 2011-10-05 11:09:38 +13:00
Eloy Lafuente (stronk7) d5ca7b11b7 Merge branch 'MDL-27857-assignment-portfolio_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-10-04 12:48:30 +02:00
Eloy Lafuente (stronk7) 33091e7e58 Merge branch 'MDL-19575-m20' of git://github.com/ankitagarwal/moodle into MOODLE_20_STABLE 2011-10-04 12:13:09 +02:00
Sam Hemelryk 019e897604 Merge branch 'MDL-29621_20_wip' of git://github.com/grabs/moodle into MOODLE_20_STABLE 2011-10-04 17:58:07 +13:00
Sam Hemelryk bdf95827b5 MDL-28615 forum: Fixed missing context regression 2011-10-04 16:36:52 +13:00
Sam Hemelryk c03a8543f0 Merge branch 'MDL-28725_wiki_section2_20' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-10-04 16:21:48 +13:00
Andreas Grabs fdd6b2fa57 MDL-29621 - XHTML not welformed when creating Feedback questions 2011-10-03 18:46:22 +02:00
Tim Hunt 2602c1ce44 MDL-28469 quiz settings pages should be pagelayout admin. 2011-10-03 16:39:34 +01:00
David Mudrak f5edf4eba4 MDL-27857 Export to portfolio support in the assignment module improved
Portfolio API code in the assignment module expected that the current
user is the author of the submission. Therefore the "Export to
portfolio" button did not work when the submission was viewed by a
teacher (eg at the page with the list of all submissions in the Advanced
upload assignment).

This patch introduces a new callback argument 'submissionid' that holds
explicit ID of the submission the export deals with. With it available,
we do not need to expect the current user is the author of the
submission.

The patch also cleans some strings used for portfolio callback
exceptions.

Backported from MOODLE_21_STABLE, resolved conflicts in:

	mod/assignment/lib.php
	mod/assignment/renderer.php
2011-10-03 11:15:17 +02:00
David Mudrak ee281f15a7 MDL-27857 Typo in the phpDocs fixed 2011-10-03 10:27:05 +02:00
David Mudrak 490057db33 MDL-27857 Assignment does not use form tag to render portfolio export control widget
When this code was used as a part of the grading screen, the default
PORTFOLIO_ADD_FULL_FORM widget led to nested form elements. This patch replaces
the form widget with a plain text link that can be embedded safely.

Backported from MOODLE_21_STABLE with a conflict resolved in mod/assignment/renderer.php
2011-10-03 10:26:01 +02:00
Aparup Banerjee 6dd8588504 MDL-26486 Lesson : fixed whitespace 2011-10-03 16:03:15 +08:00
Aparup Banerjee e2c3a02bb8 Merge branch 'MDL-26486_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-10-03 16:03:03 +08:00
Andrew Davis (andyjdavis) 5dd5818c9a MDL-27640 rating: altered the return url provided by mod_data to ratings 2011-10-03 15:27:58 +08:00
Aparup Banerjee 1f6a502674 Merge branch 'wip-MDL-27867-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-10-03 14:31:44 +08:00
Aparup Banerjee 067a949f46 MDL-29541 Administration : fixed whitespace 2011-10-03 14:05:05 +08:00
Aparup Banerjee 4824e2deff Merge branch 'wip-mdl-29244-m20' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-10-03 13:52:52 +08:00
Rajesh Taneja 95a14f5d55 MDL-29244 Users: Fixed filter for selecting users who never logged in and course roles dropdown show all revelent roles 2011-10-03 13:47:58 +08:00
Sam Hemelryk 77738c4562 Merge branch 'MDL-29296_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-10-03 17:09:35 +13:00
Sam Hemelryk e93dd0d650 Merge branch 'wip-mdl-29539-m20' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-10-03 15:10:05 +13:00
Sam Hemelryk 98b723b1ce MDL-28566 theme_base: removed MDL comment 2011-10-03 15:00:43 +13:00
Sam Hemelryk d6a7cac991 Merge branch 'MDL-28566-M20' of git://github.com/lazydaisy/moodle into MOODLE_20_STABLE 2011-10-03 14:38:14 +13:00
Sam Hemelryk ec9b8fb68d Merge branch 'MDL-29323-M20' of git://github.com/lazydaisy/moodle into MOODLE_20_STABLE 2011-10-03 14:30:26 +13:00
Sam Hemelryk 8bd76f9e65 Merge branch 'wip-MDL-25454-MOODLE_20_STABLE' of git://github.com/marinaglancy/moodle into MOODLE_20_STABLE 2011-10-03 14:23:59 +13:00
AMOS bot 4dbfb1becc Automatically generated installer lang files 2011-10-03 00:55:34 +00:00
Sam Hemelryk c06645a539 Merge branch 'MDL-29567_20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-10-03 13:23:37 +13:00
Sam Hemelryk 85906b4ae5 Merge branch 'MDL-29566_20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-10-03 12:50:10 +13:00
Sam Hemelryk 424cb3b0ef Merge branch 'MDL-29618_20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-10-03 12:28:27 +13:00
Eloy Lafuente (stronk7) ab37ff5952 MDL-29618 backup - back to handling enrolments properly. Regession of MDL-26841, my fault, grrr 2011-10-03 00:47:51 +02:00
Sam Hemelryk b38867187f MDL-28615 forum: Revised enrol_sharing_course to use the new enrol_get_shared_courses and fixed permission checking in forum_user_can_see_post 2011-10-03 11:31:17 +13:00
Kordan 1cef86131d MDL-29403 fix for M20 2011-09-30 11:14:00 +02:00
Mary Evans 14b0fea807 MDL-29323-FIX invalid border style 2011-09-30 03:08:51 +01:00
AMOS bot 9fb272baaa Automatically generated installer lang files 2011-09-30 00:55:25 +00:00
Marina Glancy 44e9ca744e MDL-25454: using the faster way to check if record exists in db 2011-09-29 17:07:39 +08:00
Andrew Davis (andyjdavis) a80c9b9816 MDL-28725 wiki: added urlencode around the section variable when it is being used to construct URLs 2011-09-29 16:53:16 +08:00
Andrew Davis (andyjdavis) 3f1ef9ec5a MDL-28725 wiki: added missing string
AMOS BEGIN
 CPY [invalidsection,core_admin],[invalidsection,mod_wiki]
AMOS END
2011-09-29 16:53:07 +08:00
Rossiani Wijaya d754f1b012 MDL-26486 lesson mod: fixed grade report error on matching and shortanswers questions. 2011-09-29 13:10:35 +08:00
Ankit Kumar Agarwal 4ca24885a5 MDL-19575 Global Search Adding capability checks to the search and stat pages 2011-09-29 09:18:23 +05:30
Marina Glancy d69c84b185 MDL-25454 before skipping course backup make sure that there are no change entries in it's log during the last month. Store the nextstarttime even for courses that were not backed up 2011-09-29 10:01:50 +08:00
Rajesh Taneja 87fccbc271 MDL-29539 HTML Editor: Fixed XHTML formatting for editor 2011-09-29 09:35:52 +08:00
Sam Hemelryk dbde930a58 MDL-28615 mod_forum: Fixed the users page that shows all of the users posts 2011-09-29 14:21:26 +13:00
Sam Hemelryk 63cca18b3a MDL-25697 theme_base: Improved the alignment of the activity editing icons on the course frontpage 2011-09-29 14:15:13 +13:00
AMOS bot 18c99c67fa Automatically generated installer lang files 2011-09-29 00:55:45 +00:00
Eloy Lafuente (stronk7) 00b4aadafe MDL-29567 postgresql - handle negative defaults in numerical cols properly 2011-09-29 01:22:54 +02:00
Eloy Lafuente (stronk7) 13e183dd84 MDL-29567 unit tests - add some tests to cover negative defaults in numerical cols 2011-09-29 01:22:51 +02:00
Eloy Lafuente (stronk7) b558672db4 MDL-29566 mysql - length / decimal specs in float columns are optional 2011-09-29 00:31:30 +02:00
Eloy Lafuente (stronk7) 627282714b MDL-29566 unit tests - add some tests to cover get_columns() with number/float columns 2011-09-29 00:31:21 +02:00
Sam Hemelryk 199e7e9f85 MDL-27867 course: Course and category theme selectors no longer show theme's that should be hidden from the selector 2011-09-29 10:48:16 +13:00
Mary Evans 20b76253fb MDL-28566 - Fix for participants user details 2011-09-28 15:36:12 +01:00
Eloy Lafuente (stronk7) 690ef509de weekly release 2.0.4+ 2011-09-28 11:08:56 +02:00
Eloy Lafuente (stronk7) 0442a23878 Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-09-28 11:04:44 +02:00
AMOS bot df50b954c6 Automatically generated installer lang files 2011-09-28 00:55:26 +00:00
Aparup Banerjee 38be5071c8 Merge branch 'MDL-29230_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-09-27 15:01:45 +08:00
Aparup Banerjee 041d4b3fab Merge branch 'MDL-25241_forum_search_ratings_20' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-09-27 11:27:26 +08:00
Sam Hemelryk a53366f7ab Merge branch 'm20_MDL-29519' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-09-27 14:17:36 +13:00
Sam Hemelryk bacfad505d Merge branch 'MDL-29411_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-09-27 11:17:59 +13:00
Eloy Lafuente (stronk7) fff222f460 Merge branch 'w38_MDL-29535_m20_filters' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-09-26 23:57:51 +02:00
Petr Skoda 60df5b0c05 MDL-29535 fix support for custom filter settings in contrib filters 2011-09-26 23:51:08 +02:00
Eloy Lafuente (stronk7) d2175fceaa Merge branch 'MDL-29462_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-09-26 22:42:43 +02:00
Eloy Lafuente (stronk7) aa114967bb Merge branch 'MDL-28202_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-09-26 22:37:51 +02:00
Eloy Lafuente (stronk7) e60ca6985b Merge branch 'MDL-29201_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-09-26 22:22:04 +02:00
Eloy Lafuente (stronk7) b506a6f08e Merge branch 'MDL-29528_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-09-26 21:45:15 +02:00
Tim Hunt 5751edbcb1 MDL-29411 questiontext images not displayed in randomsamatch generated questions. 2011-09-26 13:52:02 +01:00
Tim Hunt 7c144c47e5 MDL-29528 qtype multichoice and caclulated combined feedback format overwritten during upgrade.
Conflicts:

	question/type/multichoice/backup/moodle1/lib.php
2011-09-26 13:40:56 +01:00
Rossiani Wijaya 5f32139fde MDL-29296 lesson mod: fixed regression for continue button on last lesson page. 2011-09-26 16:30:43 +08:00
Aparup Banerjee 30a7869e49 Merge branch 'wip-MDL-29487-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-09-26 16:01:47 +08:00
Aparup Banerjee f2b7714f6b Merge branch 'MDL-29464_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-09-26 14:50:09 +08:00
Aparup Banerjee d0830107cb Merge branch 'MDL-29333_rating_ajax_20' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-09-26 14:08:30 +08:00
AMOS bot 953560c9c4 Merge branch 'MOODLE_20_STABLE' into install_20_STABLE 2011-09-26 00:55:37 +00:00
Dan Marsden b2f46deb0b MDL-29519 move plagiarism cron to after event queue 2011-09-26 13:17:11 +13:00
Sam Hemelryk 5ea58ff4e1 Merge branch 'MDL-29336-numerrors-mapping-20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-09-26 12:36:18 +13:00
Sam Hemelryk 3603e0856a Merge branch 'MDL-29139_m20' of git://github.com/nebgor/moodle into MOODLE_20_STABLE 2011-09-26 10:45:57 +13:00
Sam Hemelryk 91c578c06d Merge branch 'MDL-29190_20_wip' of git://github.com/grabs/moodle into MOODLE_20_STABLE 2011-09-26 10:39:41 +13:00
Eloy Lafuente (stronk7) 7608f458e3 weekly release 2.0.4+ (emergency) 2011-09-25 17:27:31 +02:00
Eloy Lafuente (stronk7) 78d1df7fd5 MDL-29512 Revert "MDL-25937 Froms Library: Added server side validation for filepicker and filemanager"
This reverts commit 59bc05c4a2.
2011-09-25 17:16:01 +02:00
Eloy Lafuente (stronk7) bdf1df7058 MDL-29512 Revert "MDL-25937 Forms Library: Added Javascript validation for filepicker and filemanager. Also fixed disbledif rule check for both"
This reverts commit 312a8e0436.
2011-09-25 17:15:47 +02:00
AMOS bot 6c6a05e561 Automatically generated installer lang files 2011-09-25 00:55:26 +00:00
Andreas Grabs 0972d40ad9 MDL-29190 - XHTML not well formed in show_nonrespondents.php 2011-09-23 18:51:50 +02:00
Sam Hemelryk 58d7e8cf60 MDL-29487 enrol: Fixed typo in enrol_sharing_course 2011-09-23 18:18:20 +12:00
Rossiani Wijaya ebc788d13e MDL-29230 lesson_module: fixed question's answer to have 0 value. 2011-09-23 14:17:51 +08:00
Kyle Temkin 9d19a2bcd8 MDL-28202 qtype_calculated fix edge case in the rounding code. 2011-09-22 12:14:59 +01:00
Tony Levi c538ea951f MDL-29201: questions: Fix regraded essay questions not being placed into correct state 2011-09-22 11:48:09 +01:00
Andrew Davis (andyjdavis) 1239f5a5c4 MDL-25241 forum: reimplemented the display of ratings on the forum search page 2011-09-22 15:27:54 +08:00
Aparup Banerjee 47147e2ff5 MDL-29139 Forms Library : fixed missing require_once 2011-09-22 14:55:46 +08:00
David Mudrak c418df9c94 MDL-29336 Saving grade mapping table in the Workshop
The Workshop module using the "Number of errors" grading strategy did
not save all items in the grade mapping table. If some assessment form
fields have weight > 1, the number of possible errors is greater that
the number of the assessment form fields. The previous code deleted all
mappings where the number of errors was greater than the number of
fields.

In this patch, the maximum number of possible errors is calculated as a
sum of weights of all fields. Only mappings over this maximum are
deleted now.
2011-09-22 05:31:03 +02:00
Andrew Davis (andyjdavis) 6ec18f437b MDL-29333 rating: refactored the ratings ajax 2011-09-22 11:03:05 +08:00
Tim Hunt 2d56b929c0 MDL-29464 quiz add random question popup does not update sumgrades. 2011-09-21 16:40:47 +01:00
Tim Hunt 8dce32bb7b MDL-29462 html_to_text('0') gives '', not '0'.
Conflicts:

	lib/simpletest/testweblib.php
2011-09-21 16:40:18 +01:00
Eloy Lafuente (stronk7) 51e1e3d536 weekly release 2.0.4+ 2011-09-21 17:12:24 +02:00
Eloy Lafuente (stronk7) 0ca9b41b50 Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-09-21 17:04:56 +02:00
AMOS bot 5e2f228709 Automatically generated installer lang files 2011-09-21 00:55:25 +00:00
Eloy Lafuente (stronk7) 387bde00c2 Merge branch 'MDL-26567_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-09-21 00:11:35 +02:00
Tim Hunt b9bed21722 MDL-26567 no grade category option on the quiz settings form.
Also, refine the standard_grading_coursemodule_elements method to add a
help string.

AMOS BEGIN
 CPY [gradecategory,grades],[gradecategoryonmodform,grades]
AMOS END
2011-09-20 12:21:36 +01:00
Eloy Lafuente (stronk7) eebe41c9d3 Merge branch 'wip-mdl-29079-m20' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-09-20 09:51:44 +02:00
Aparup Banerjee 5e90b425fb Merge branch 'MDL-26890-m20' of git://github.com/ankitagarwal/moodle into MOODLE_20_STABLE 2011-09-20 13:18:24 +08:00
Ankit Kumar Agarwal 1a17422d24 MDL-26890 Forums Check on filesize if the file is added to the forum from private area 2011-09-20 10:20:58 +05:30
Rajesh Taneja 722bbfc81f MDL-29079 Administration: Added space on both sides of locked checkbox and for rtl language space will be applied accordingly 2011-09-20 11:51:25 +08:00
Aparup Banerjee 3ee798f85f Merge branch 'wip-mdl-28726-m20' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-09-20 10:21:45 +08:00
Sam Hemelryk 5e51b68a18 Merge branch 'MDL-26841_20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-09-20 12:13:29 +12:00
Sam Hemelryk 0243159817 Merge branch 'MDL-29392_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-09-20 11:59:03 +12:00
Eloy Lafuente (stronk7) 2bc77f9cc9 Merge branch 'wip-mdl-29079-m20' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-09-20 00:18:03 +02:00
Eloy Lafuente (stronk7) 439de8cf42 Merge branch 'MDL-29126_export_separator_20' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-09-19 23:36:35 +02:00
Eloy Lafuente (stronk7) c1beb0fa2d Merge branch 'MDL-27298_forum_rating_participants' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-09-19 23:33:55 +02:00
M Kassaei 30721d4913 MDL-29392 grade/report/index.php should use $CFG->grade_profilereport 2011-09-19 11:33:18 +01:00
Eloy Lafuente (stronk7) aed1ff8d29 MDL-26841 backup - prevent any enrolments info to be handled in IMPORT/HUB operations 2011-09-19 11:25:02 +02:00
Rajesh Taneja facb211577 MDL-29079 Administration: Added space between checkboxes on general backup setting page 2011-09-19 13:37:48 +08:00
Sam Hemelryk f6b9535c4b Merge branch 'wip-mdl-25937-m20' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-09-19 17:00:23 +12:00
Aparup Banerjee 3a5dd161c2 Merge branch 's13_MDL-28509_youtube_20' of github.com:dongsheng/moodle into MOODLE_20_STABLE 2011-09-19 12:18:14 +08:00
Dongsheng Cai 54b3f85625 MDL-28509 repository : fixed youtube repository search keyword 2011-09-19 11:53:42 +08:00
Mark Johnson c865e54938 MDL-28509 repository_youtube Enable selection of sort order 2011-09-19 11:53:24 +08:00
Petr Skoda e157c695c9 MDL-29406 fix greedy config settings cleanup 2011-09-19 13:33:16 +12:00
Tim Hunt 1d469cae30 MDL-29360 quiz comment.php has broken JS for the Cancel button.
This swtichest it to more modern YUI3 approach.
2011-09-16 12:08:16 +01:00
Rajesh Taneja 7039fa8d96 MDL-28726 wiki-2.0: Fixed XSS in wiki comments 2011-09-16 11:11:32 +08:00
Rajesh Taneja 312a8e0436 MDL-25937 Forms Library: Added Javascript validation for filepicker and filemanager. Also fixed disbledif rule check for both 2011-09-16 09:18:57 +08:00
Rajesh Taneja 59bc05c4a2 MDL-25937 Froms Library: Added server side validation for filepicker and filemanager 2011-09-16 09:18:57 +08:00
Eloy Lafuente (stronk7) 3df2ab8d98 weekly release 2.0.4+ 2011-09-16 01:39:32 +02:00
Eloy Lafuente (stronk7) 77962f179e Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-09-16 01:34:52 +02:00
AMOS bot ce7582df1f Automatically generated installer lang files 2011-09-15 00:55:25 +00:00
Aparup Banerjee 29134ecc9e MDL-26257 Authentication : fixed typo 2011-09-14 16:12:03 +08:00
Petr Skoda 2d1e165183 MDL-29295 do not use strtok in dml and ddl layers
This prevents clobbering of internal pointer when code calling DML
uses strtok too. Unit test added to prevent future uses.
2011-09-14 00:21:50 +02:00
Aparup Banerjee f3f329d1be MDL-26257 Authentication : whitespace/style fixes 2011-09-13 19:19:28 +08:00
Aparup Banerjee e2ea315c5b Merge branch 'MDL-26257-20' of git://github.com/bostelm/moodle into MOODLE_20_STABLE 2011-09-13 19:17:03 +08:00
Aparup Banerjee 25c976527b Revert "MDL-29188 multilang Reviewed the uses of section name and ensured things were being formatted consistently"
This reverts commit 64e085e1d1.
2011-09-13 16:29:59 +08:00
Aparup Banerjee 06a8b8482d Merge branch 'wip-MDL-29188-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-09-13 13:35:15 +08:00
Sam Hemelryk 62920e80ba Merged branch 'MDL-22232_easier_turn_off_notifications_20' from git://github.com/andyjdavis/moodle.git with conflict resolution 2011-09-12 20:27:41 +12:00
Sam Hemelryk 5fbc1470b1 Merge branch 'MDL-29211_M20' of git://github.com/kordan/moodle into MOODLE_20_STABLE 2011-09-12 19:49:46 +12:00
kordan f196ac57ca MDL-29211 fox for MOODLE_20_STABLE 2011-09-12 09:36:40 +02:00
Sun Zhigang 479af9ed9f MDL-29112 trigger event mod_deleted after deleting mod through AJAX 2011-09-12 17:36:20 +12:00
Sam Hemelryk 52c00a59c6 Merge branch 'MDL-28724_m20' of git://github.com/nebgor/moodle into MOODLE_20_STABLE 2011-09-12 17:26:44 +12:00
Petr Skoda 42a349855f MDL-29131 fix multiple groups issues on the recent activity report 2011-09-12 17:09:06 +12:00
Aparup Banerjee 1fc6a6046a MDL-28724 wiki : Fixed bugs in wiki forms 2011-09-12 12:31:56 +08:00
Sam Hemelryk 13b7a5d4e5 Merge branch 'MDL-27635_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-09-12 14:39:42 +12:00
Sam Hemelryk f4aea09ea4 Merge branch 'w36_MDL-29312_m20_cookieless' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-09-12 14:31:03 +12:00
Rossiani Wijaya b086b19faa MDL-27635 hub component: fixed default value for 'secret' field in 'registration_hubs' table 2011-09-12 10:17:39 +08:00
Sam Hemelryk ef9d05cd99 Merge branch 'MDL-28488_20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-09-12 13:21:01 +12:00
kordan e60fc41fdb MDL-29056 theme-formal_white fix for the report pagelayout that was preventing horizontal scroll 2011-09-12 13:03:21 +12:00
Eloy Lafuente (stronk7) d561fa9527 MDL-28488 backup - conditionaly apply defaults based on mode
Some modes of backup cannot be preloaded with general backup
settings because they may conflict with the definitions required/set
by the mode (for example, import backups are, by definition, without
users always, so we cannot apply one default in the opposite direction).

So, after the patch, current general_backup setting will be only applied
to general backups, import/hub modes won't be using any default and
automated backup defaults should be loaded here (TODO)
2011-09-11 22:00:08 +02:00
Eloy Lafuente (stronk7) 53c074a81c MDL-28488 backup - '[backup|restore]:configure cap does not control import mode anymore 2011-09-11 21:59:58 +02:00
Eloy Lafuente (stronk7) a31173a6a6 MDL-28488 backup - fixup some strings and delete legacy ones 2011-09-11 21:59:48 +02:00
Eloy Lafuente (stronk7) f850a316f7 MDL-28488 backup - make backup and import capabilities independent
Before this change, in order to perform one course import it was
necessary to have both the backupcourse and the backuptargetimport
capabilities. After agreement now each one will control its own
backup mode. Same applies for restore.
2011-09-11 21:59:29 +02:00
Petr Skoda f0a75425cb MDL-29312 prevent cookieless mode for security reasons 2011-09-11 10:09:14 +02:00
AMOS bot 43426f3bf8 Automatically generated installer lang files 2011-09-11 00:55:45 +00:00
Henning Bostelmann 42d4cf091e MDL-26257 Shibboleth auth: run logout handler only if logged in via Shibboleth 2011-09-08 11:56:20 +01:00
Andrew Davis (andyjdavis) c841c104f0 MDL-27298 forum: corrected a query in forum_get_participants() 2011-09-08 12:05:35 +08:00
AMOS bot 57ee29839a Automatically generated installer lang files 2011-09-08 00:55:35 +00:00
Sam Hemelryk 64e085e1d1 MDL-29188 multilang Reviewed the uses of section name and ensured things were being formatted consistently 2011-09-08 09:28:05 +12:00
Eloy Lafuente (stronk7) 4f65f98942 weekly release 2.0.4+ 2011-09-07 17:53:24 +02:00
Eloy Lafuente (stronk7) f3266ff658 Merge branch 'wip-MDL-28043-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-09-06 13:56:25 +02:00
Eloy Lafuente (stronk7) bede2a2a34 Merge branch 'wip-mdl-28987-m20' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-09-06 02:00:12 +02:00
Sam Hemelryk c2731a79e2 MDL-28043 user Fixed context hack in pluginfile for user pics leading to init of page, theme and output for redirect 2011-09-06 11:29:56 +12:00
Eloy Lafuente (stronk7) 85ae284e59 Merge branch 'wip-mdl-23520-m20' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-09-06 01:28:28 +02:00
Eloy Lafuente (stronk7) 029a753b91 Merge branch 'wip-MDL-29006-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-09-06 00:38:55 +02:00
Eloy Lafuente (stronk7) cba00bdb69 MDL-29072 Import course - whitespace fixes 2011-09-05 10:43:32 +02:00
Rajesh Taneja 39f5ddeeb7 MDL-28987 Forms Library: Removed onBlur validation. Now the validation will occur on form submit only 2011-09-05 14:34:07 +08:00
Iñaki Arenaza 556c446f32 MDL-27689 Vague README-LDAP file in auth/ldap
README-LDAP referes to a file that was renamed (to auth.php) in Moodle
1.8 and no longer exists. Make clear what file we are referring to.
2011-09-05 13:32:16 +08:00
Aparup Banerjee 70e16becad Merge branch 'wip-MDL-26811-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-09-05 13:22:25 +08:00
Aparup Banerjee 146ada0aa6 Merge branch 'MDL-29198_20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-09-05 12:53:56 +08:00
Rajesh Taneja 11dd2fdb74 MDL-28987 Forms Library: Added tinyMCE onblur event callback for required tinymce fields 2011-09-05 12:23:29 +08:00
Rajesh Taneja 98b8818735 MDL-28987 Forms Library: Added tinyMCE save for tinymce editor validation 2011-09-05 12:23:23 +08:00
Adam Olley 52ed7bb7e3 MDL-28987: Affix [text] to editor element in JS validation and add blur event 2011-09-05 12:23:17 +08:00
Sam Hemelryk f364f5628f Merge branch 'MDL-29018_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-09-05 16:08:13 +12:00
Sam Hemelryk 2c90eef264 Merge branch 'MDL-28689_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-09-05 16:03:12 +12:00
Rossiani Wijaya 55b0567707 MDL-29018 lesson module statistics: fixed statistics diplay for whole the class 2011-09-05 11:14:21 +08:00
Rossiani Wijaya 08aaea9856 MDL-28689 chat module: add input.png file. This is a simple fix by copying the file from bubbles themes. Proper fix should be done in the future 2011-09-05 11:06:27 +08:00
Henning Bostelmann 1749c7aa31 MDL-29072 Import course: Use correct capability for course selection 2011-09-05 13:41:42 +12:00
Sam Hemelryk b1e71dac7d Merge branch 'MDL-27975_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-09-05 13:37:13 +12:00
Eloy Lafuente (stronk7) a2c3c37cb6 MDL-28080 DML unit tests - cover tweak_param_names() and the new 30 chars limit exception 2011-09-01 20:00:17 +02:00
Eloy Lafuente (stronk7) a4c5837ad7 MDL-28080 oracle - avoid tweak_param_names() tweaking too much :-P
Sometimes the (oracle only) tweak_param_names() method was causing
placeholders having > 28 chars length to exceed the 30 chars limit
imposed by Oracle. With this commit the tweak is performed by
replacement for such long placeholders and, at the same time, the
tweak has been commented out from insert/update because it is not
necessary there (placeholders are safe column name always)
2011-09-01 20:00:17 +02:00
Tim Hunt a167057d58 MDL-28080 coding_exception for over-long placeholder names. 2011-09-01 20:00:16 +02:00
Rossiani Wijaya 14d8d6b7bb MDL-27975 community block: fixed string typo 2011-09-01 17:11:39 +08:00
Eloy Lafuente (stronk7) 687e61cdea MDL-29198 DB - make delete_records transactional safe when needed 2011-09-01 11:08:58 +02:00
Andrew Davis (andyjdavis) e186fee5e3 MDL-22232 messaging: updated upgrade code to reduce server load during upgrade 2011-09-01 16:47:39 +08:00
Andrew Davis (andyjdavis) 1e7cd615c1 MDL-29126 gradebook: made text export with tabs as separator work 2011-09-01 15:42:53 +08:00
Rajesh Taneja 92a3823994 MDL-23520 mod-wiki-2.0: Added delete page and version feature as it was in 1.9 2011-08-31 13:54:24 +08:00
Sam Hemelryk 8068301cd7 MDL-29006 block_html Added formatted to title printed on editing form when a hard freeze is in effect 2011-08-31 11:47:03 +12:00
Eloy Lafuente (stronk7) 15141ad25f weekly release 2.0.4+ 2011-08-31 01:34:16 +02:00
Eloy Lafuente (stronk7) 724641e59a Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-08-31 01:29:52 +02:00
Aparup Banerjee 832ea65890 MDL-29005 blocks : clarified comment 2011-08-30 11:24:05 +08:00
Aparup Banerjee 311c3e9365 Merge branch 'MDL-29005_MOODLE_20_STABLE' of git://github.com/mouneyrac/moodle into MOODLE_20_STABLE 2011-08-30 11:23:57 +08:00
Eloy Lafuente (stronk7) 65ab1ffa5b MDL-28489 site news forum - support multilang filter 2011-08-30 11:07:08 +12:00
Eloy Lafuente (stronk7) b7424c7693 Merge branch 'MDL-29141_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-08-29 13:02:27 +02:00
Eloy Lafuente (stronk7) 081d16475b Merge branch 'wip-MDL-24202-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-08-29 10:31:34 +02:00
Andrew Davis (andyjdavis) b15713760e MDL-22232 messaging: added some Javascript to the messaging preferences screen to make it awesomer 2011-08-29 15:58:26 +08:00
Sam Hemelryk f24f704630 MDL-24202 navigation Fixed bug caused by navigation overriding a CFG setting 2011-08-29 13:45:56 +12:00
Eloy Lafuente (stronk7) 22a35ffaaf Merge branch 'MDL-26302_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-08-29 03:23:45 +02:00
Sam Hemelryk 96083d8068 Merge branch 'MDL-26819_20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-08-29 13:05:38 +12:00
Sam Hemelryk 31bb03f6e1 Merge branch 'dev_MDL-27289_boxnet_20' of git://github.com/dongsheng/moodle into MOODLE_20_STABLE 2011-08-29 12:55:00 +12:00
Eloy Lafuente (stronk7) 00f706d1f5 Merge branch 'MDL-29064_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-08-29 02:53:08 +02:00
Sam Hemelryk d3e5802d97 Merge branch 'MDL-29135-mnet-login_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-08-29 12:25:16 +12:00
David Mudrak 6b27edcc47 MDL-29148 MNet - improved handling of a verification function return code 2011-08-29 01:48:16 +02:00
Eloy Lafuente (stronk7) 28883e9b45 Merge branch 'MDL-25872-20' of git://github.com/bostelm/moodle into MOODLE_20_STABLE 2011-08-29 01:22:58 +02:00
Iñaki Arenaza e79edb11ee MDL-28402 LDAP configuration values being stored in lower case, causing misconfiguration
It looks like array_change_key_case() does not work recursively, so we
were not actually lowercasing the expiration attribute key. As the
configuration setting is always lowercase they didn't match.
2011-08-29 01:09:18 +02:00
Eloy Lafuente (stronk7) d5d16e1f9c MDL-26819 quiz statistics - use cross-db GROUP BY expression 2011-08-28 22:23:32 +02:00
David Mudrak a1e52c70e5 MDL-27107 auth_mnet - consider all incoming roaming users as confirmed
The 'confirmed' field can't be optional. If the identity provider did
not export it, the new remote user would be created with 'confirmed' set
to default zero and as such could be a subject of scheduled deletion.
2011-08-28 02:28:12 +02:00
David Mudrak b9720b8869 MDL-29135 Reworded login prompt with SSO over MNet enabled 2011-08-27 18:25:09 +02:00
AMOS bot 3f4a67b330 Automatically generated installer lang files 2011-08-27 00:55:45 +00:00
Henning Bostelmann 62da28c64d MDL-25872 View assignment submissions: show only students, not teachers
Fixing incorrect capability reference mod/assignment:view to ...:submit
2011-08-26 17:34:42 +01:00
Tim Hunt 1179c92d0b MDL-29141 question bank show question text checkbox does not match state. 2011-08-26 17:31:23 +01:00
M Kassaei 3388d2f9f9 MDL-27631 question bank Show question text in the question list when top level category is used 2011-08-26 17:30:20 +01:00
Eloy Lafuente (stronk7) 58609afebb weekly release 2.0.4+ 2011-08-26 15:07:04 +02:00
Eloy Lafuente (stronk7) 6a10905864 Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-08-26 14:57:03 +02:00
Andrew Davis (andyjdavis) 87a4bba39c MDL-22232 messaging: miscelaneous fixes after integration review 2011-08-26 15:59:31 +08:00
Sam Hemelryk 179b60aea6 MDL-26811 upgrade Fixed up default handling causing exception on upgrade of used site in MSSQL 2011-08-26 14:58:55 +12:00
Eloy Lafuente (stronk7) d52f9563d1 Merge branch 'MDL-27823_bulk_messaging_2_20' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-08-25 10:47:31 +02:00
Eloy Lafuente (stronk7) de8c58715a Merge branch 'MDL-28650-MOODLE_20_STABLE' of https://github.com/mouneyrac/moodle into MOODLE_20_STABLE 2011-08-25 01:16:38 +02:00
Jerome Mouneyrac 2771063982 MDL-29005 display enrollable courses total and downloadable courses total instead of courses/sites total 2011-08-24 14:53:51 +08:00
Aparup Banerjee acb05b5d4d Revert "MDL-28509 repository_youtube Enable selection of sort order"
This reverts commit 919304d4bf.
2011-08-24 14:43:36 +08:00
Eloy Lafuente (stronk7) d45e517538 Merge branch 'w33_MDL-29022_m20_idnumber' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-08-24 03:52:26 +02:00
Aaron Barnes df40fa5f66 MDL-28248 completion: Incorrect SQL for finding enrol start date 2011-08-24 12:06:12 +12:00
Sun Zhigang 02e5cdbeb8 MDL-29019 enrol - fix a typo 2011-08-24 01:31:47 +02:00
Petr Skoda 029e7f5eae MDL-29000 multiple password reset issues
* stop abusing get_complete_user_data()
* fix case-sensitiveness in password reset for PG
* do not allow reset of disabled accounts
* propose a solution for non-unique emails
2011-08-24 01:09:23 +02:00
Petr Skoda 9a529b0753 MDL-28981 fix forum_user_can_post() call params 2011-08-24 00:53:45 +02:00
Tony Levi 3c0b7e9468 MDL-27228: Fix label 'eye' does not match show/hide setting 2011-08-23 23:36:43 +02:00
Aparup Banerjee ce7519c27e Merge branch 'MDL-28723-plugin-tables_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-08-24 01:30:09 +08:00
Eloy Lafuente (stronk7) 0a2be338a8 MDL-28962 enrol imsenterprise - whitespace fix 2011-08-23 18:44:10 +02:00
Eloy Lafuente (stronk7) d3ff99e745 Merge branch 'm20_MDL-28962' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-08-23 18:43:56 +02:00
Eloy Lafuente (stronk7) 91d77b17bd Merge branch 'MDL-28397-20' of https://github.com/totara/moodle into MOODLE_20_STABLE 2011-08-23 17:31:45 +02:00
Sam Hemelryk 142af01f32 MDL-25636 block_html Fixed up missing format config if block restored from early 2.0 backup 2011-08-23 18:43:54 +08:00
Petr Skoda 6551049f07 MDL-28935 use weekdays as calendar table headings 2011-08-23 10:05:28 +02:00
Jason Ilicic ed246c21db MDL-28935 Add days of week to monthly calendar view 2011-08-23 10:05:22 +02:00
Tim Hunt e5073fe305 MDL-29064 qtype multianswer, question text should be a required field. 2011-08-23 08:41:18 +01:00
Aparup Banerjee 9ef338d744 Merge branch 'MDL-28509_20_STABLE' of git://github.com/marxjohnson/moodle into MOODLE_20_STABLE 2011-08-23 14:58:00 +08:00
Eloy Lafuente (stronk7) 68e22328b5 Merge branch 'm20_MDL-28999' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-08-23 02:50:21 +02:00
Petr Skoda 9986fe8d0d MDL-29016 allow distributions to set dataroot permissions 2011-08-23 02:43:17 +02:00
Eloy Lafuente (stronk7) 13c04d1701 Merge branch 'w33_MDL-29031_m20_oldblock' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-08-23 02:05:33 +02:00
Eloy Lafuente (stronk7) bf3e4e030f Merge branch 'MDL-28226_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-08-23 01:42:48 +02:00
Adam Olley f22a7de23f MDL-28481: Send headers before any possible output 2011-08-23 01:37:32 +02:00
Eloy Lafuente (stronk7) f9356f85ce Merge branch 'w33_MDL-28936_m20_msgstrlen' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-08-23 01:20:37 +02:00
Tom Cubanski 3c94cc716e MDL-26302 quiz editing: top move button on the order and paging tab does not work.
It is strange that processes the submission already handles the submitted data from this change to the HTML.
2011-08-22 23:58:12 +01:00
Aparup Banerjee 5a80cab06d Merge branch 'wip-mdl-28580-m20' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-08-23 01:54:22 +08:00
Andrew Davis (andyjdavis) b1f400ae6f MDL-27823 messaging: preventing html tags from being output to the UI 2011-08-22 15:33:30 +08:00
Aaron Barnes 551fa5f4dd MDL-28397 completion: Activity completion criteria not showing grading
requirement

Credit goes to Evan Irving-Pease for the patch
2011-08-22 14:56:35 +12:00
Andrew Davis (andyjdavis) bec1c29d84 MDL-22232 messaging: reimplementing support for "emailstop" in 2.0 stable 2011-08-22 09:51:17 +08:00
Petr Skoda 89f5428879 MDL-29031 remove blocks cleanup todo 2011-08-21 17:46:54 +02:00
Petr Skoda 84c656a557 MDL-27248 remove forgotten unique sortorder index from the course table 2011-08-21 17:34:26 +02:00
Petr Skoda 367f1a7300 MDL-29022 do not require idnumber in ext courses - backport from MDL-29020 2011-08-20 11:36:21 +02:00
Petr Skoda 725ef19f1f MDL-28936 fix invalid >200 comparison and utf-8 incompatibility
Credit for discovery goes to Jason Ilicic.
2011-08-19 18:46:38 +02:00
Rajesh Taneja 12acab953b MDL-28580 Administration: Added sanity check to grab wrong usage of upgrade_main_savepoint 2011-08-19 07:48:24 +00:00
Dan Marsden 1425c0b449 MDL-28999 SCORM add missing yui2 require 2011-08-19 10:22:41 +12:00
Tim Hunt 4f24a95cdd MDL-28226 wrong final quiz grade when regrading with first/last attempt graded.
This is an intermitted problem that depends on the order the DB returns
rows in the absence of an order-by. At any rate, adding an explicit
order-by fixes it.

Also inprove a PHP doc comment and some code to make the API clearer.
2011-08-18 13:47:46 +01:00
Jerome Mouneyrac f4a57f80ef MDL-28650 add a page in the administration to the full web service API (API documentation). 2011-08-18 13:31:50 +08:00
Dan Marsden feb6542872 MDL-28962 enrol imsenterprise - incorrect conversion of new dml syntax - thanks to Patrick Gagnon for report and fix. 2011-08-18 13:40:42 +12:00
AMOS bot 1c59b0ad97 Automatically generated installer lang files 2011-08-18 00:55:29 +00:00
Eloy Lafuente (stronk7) 9e47a85a24 weekly release 2.0.4+ 2011-08-18 02:43:23 +02:00
Eloy Lafuente (stronk7) a25ae4ff1b Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-08-18 02:38:59 +02:00
Eloy Lafuente (stronk7) 14f9c0cbcd Merge branch 'm20_MDL-28971' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-08-18 01:43:05 +02:00
Dan Marsden c9a0802794 MDL-28971 - SCORM_TOC_DISABLED is not available in 2.0 - only available in 2.1 and higher 2011-08-17 20:45:19 +12:00
Dongsheng Cai 078bd6815c MDL-27289, upgrade box.net repository plugin to use new box.net authentication process 2011-08-17 11:44:49 +08:00
Eloy Lafuente (stronk7) c7cce21d67 Merge branch 'wip-mdl-27219-m20' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-08-17 03:00:59 +02:00
Eloy Lafuente (stronk7) be3aba207e Merge branch 'MDL-28737_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-08-17 02:52:25 +02:00
Eloy Lafuente (stronk7) c2a64d94ff Revert "MDL-25757 SCORM fix issue with duplicate cmi values being saved"
This reverts commit 230a4ab6a2.
2011-08-17 02:29:28 +02:00
Eloy Lafuente (stronk7) 780cdcea5f Merge branch 'MDL-27752_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-08-17 01:02:39 +02:00
sam marshall 4cc5500d0e MDL-28643 Fix debugging message when deleting activity with grade completion 2011-08-17 00:46:06 +02:00
Eloy Lafuente (stronk7) c2fe54c236 Merge branch 'm20_MDL-28649' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-08-17 00:35:07 +02:00
Tim Hunt 104524f504 MDL-28654 fix path for TinyMCE in lib/thirdpartylibs.xml. 2011-08-17 00:10:51 +02:00
Eloy Lafuente (stronk7) 664a07f74e Merge branch 'm20_MDL-28721' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-08-16 23:44:32 +02:00
David Mudrak a0e1c31535 MDL-28723 Make sure that the arrays used by print_plugin_tables() are correctly initialized
This covers a very rare and unexpected case when no mods or no blocks
are installed. Credit goes to Aparup Banerjee for spotting this.
2011-08-16 13:59:56 +02:00
Eloy Lafuente (stronk7) bf479611db Merge branch 'wip-MDL-26754-MOODLE_20_STABLE' of github.com:marinaglancy/moodle into MOODLE_20_STABLE 2011-08-16 13:17:12 +02:00
Eloy Lafuente (stronk7) 1f52e72526 Merge branch 'MDL-23872_m20' of git://github.com/nebgor/moodle into MOODLE_20_STABLE 2011-08-16 11:52:12 +02:00
Rajesh Taneja 03af3e075d MDL-27219 chat: Beep will not display user fullname if user is not in chat 2011-08-16 16:36:34 +08:00
Eloy Lafuente (stronk7) 9a287f8a49 Merge branch 'MDL-28931_m20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-08-16 03:06:31 +02:00
Eloy Lafuente (stronk7) 76a07a1da5 Merge branch 'wip-mdl-27728-m20' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-08-16 02:15:18 +02:00
Eloy Lafuente (stronk7) 46894c5058 Merge branch 'MDL-27030_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-08-16 02:08:04 +02:00
Eloy Lafuente (stronk7) 52dd1d84a3 MDL-27896 filters/editor - fix whitespace 2011-08-16 02:02:12 +02:00
Eloy Lafuente (stronk7) 75e815fe72 Merge branch 'wip-mdl-27896-m20' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-08-16 02:01:48 +02:00
Eloy Lafuente (stronk7) 8634bb229e Merge branch 'm20_MDL-25757' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-08-16 00:39:41 +02:00
Petr Skoda 7431abde3c Merge branch 'MDL-28465_rating_aggregation_split' into MOODLE_20_STABLE 2011-08-15 20:26:19 +02:00
Eloy Lafuente (stronk7) eac56e02bc Merge branch 'm20_MDL-28603' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-08-15 20:02:56 +02:00
Dan Poltawski 5a52740940 MDL-28605 repsitory/local - Prevent server running out of memory
Removing useless code..
2011-08-15 19:58:34 +02:00
Eloy Lafuente (stronk7) 6e4ece5640 Merge branch 'MDL-28939_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-08-15 19:35:22 +02:00
Tim Hunt e84cef850a MDL-28939 Bad lang string reference in grade/import/csv. 2011-08-15 15:12:29 +01:00
Tim Hunt cf93bcd37d MDL-28639 question import should set timemodified and modified by.
Thanks to Jean-Michel Vedrine for the fix.
2011-08-15 14:57:57 +01:00
Eloy Lafuente (stronk7) b5e0ee6f4a MDL-28931 timezone - update to 2011h (2200 rules) 2011-08-14 18:06:34 +02:00
Dan Marsden 230a4ab6a2 MDL-25757 SCORM fix issue with duplicate cmi values being saved 2011-08-13 13:25:05 +12:00
Tim Hunt 41977bb4cc MDL-28737 advcheckboxes toggle state every submit if checkbox_controller present. 2011-08-12 19:15:18 +01:00
Rajesh Taneja 1d34dc5aa3 MDL-27896 course - Rectified wrong use of itemid for preparing draft file area 2011-08-12 16:52:25 +08:00
Rajesh Taneja 2c01ba7bb7 MDL-27896 editor - parent context will be respected by editor in case context is not created. 2011-08-12 16:52:12 +08:00
Rajesh Taneja 5b5bef12f0 MDL-27896 editor - added sanity check to pick wrong context passed to editor creation 2011-08-12 16:51:59 +08:00
Rajesh Taneja 88a7dcab1e MDL-27896 context - Fixed editor context to observe filter status 2011-08-12 16:51:21 +08:00
Dan Marsden aa1e13ed2e MDL-28603 SCORM fix regression with ADL scorm 1.2 tests 2011-08-12 17:25:59 +12:00
Rajesh Taneja 6a008b485e MDL-27728 Moodleforms: Added validation for element before checking element values 2011-08-12 10:56:14 +08:00
AMOS bot 659b8d8dc6 Automatically generated installer lang files 2011-08-12 00:55:35 +00:00
Dan Marsden 0dd1a7cb66 MDL-28649 SCORM start new attempt if set when skipview used. 2011-08-12 12:55:14 +12:00
Dan Marsden 07d9ba8e9b MDL-28721 SCORM - disable hidenav setting if hidetoc not set to display toc to the left 2011-08-12 11:07:49 +12:00
Eloy Lafuente (stronk7) 9d228de05a weekly release 2.0.4+ 2011-08-12 00:20:15 +02:00
Eloy Lafuente (stronk7) c8028c9371 Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-08-12 00:13:30 +02:00
Marina Glancy a2cfc3e460 MDL-26754: Removed unnecessary include 2011-08-11 13:41:30 +08:00
sam marshall 8b805ced71 MDL-27491 Add 'complete on view' support to wiki, survey 2011-08-10 23:07:16 +02:00
Eloy Lafuente (stronk7) 55ffbabe6d Merge branch 'm20_MDL-28295' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-08-10 22:59:47 +02:00
Daren Chandisingh e39ee61705 MDL-23872 Forms Library : Updated MoodleQuickForm to honour setConstant(), prevents injection. 2011-08-10 15:23:48 +08:00
Sam Hemelryk 3e7ff59eb4 Merge branch 'MDL-20501_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-08-10 14:10:41 +08:00
Dan Marsden cca2289111 MDL-28295 SCORM change mangement of pop-up windows, load full SCORM API in existing window - this fixes an issue with IE 7 and httpreq communication 2011-08-10 14:35:00 +12:00
Eloy Lafuente (stronk7) e8a165d2a3 Merge branch 'MDL-27550-workshop-feedback_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-08-10 02:49:28 +02:00
Eloy Lafuente (stronk7) fcda253026 Merge branch 'w31_MDL-27597_m20_catlike' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-08-10 02:37:32 +02:00
Dan Poltawski 3728b69f31 MDL-23967 admin/cron.php - warn about use on CLI
Admins now need to use the explicit CLI script
2011-08-10 02:06:31 +02:00
Dan Poltawski c8e7fdd9af MDL-28059 weblib - don't strip mailto: anchors 2011-08-10 01:59:35 +02:00
Eloy Lafuente (stronk7) 2bdfe77686 Merge branch 'wip-MDL-28407-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-08-10 01:12:11 +02:00
Eloy Lafuente (stronk7) 1b8b39cbde Merge branch 'MDL-28565_m20' of git://github.com/nebgor/moodle into MOODLE_20_STABLE 2011-08-09 10:16:14 +02:00
Eloy Lafuente (stronk7) c874785067 Merge branch 'MDL-28604_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-08-09 09:43:23 +02:00
AMOS bot cbf4d62ccd Automatically generated installer lang files 2011-08-09 00:55:27 +00:00
Tony Levi 6ad6368adc MDL-27030: Fix quiz overview report showing incorrect grades on regraded attempts 2011-08-08 23:47:42 +01:00
Aparup Banerjee 58cbfde495 MDL-28565 General - updated lang files License link to docs.moodle.org/dev/License 2011-08-08 17:10:32 +08:00
Aparup Banerjee a743d4a77c MDL-28565 General - updated License and Credits links
to docs.moodle.org/dev/License and docs.moodle.org/dev/Credits
2011-08-08 17:02:31 +08:00
Sagie Maoz f3a2907f15 MDL-26721 automated backups - Fix typo
Causing the 'role assignment' backup inclusion to be tied to the users

Signed-off-by: Dan Poltawski <dan.poltawski@luns.net.uk>
2011-08-08 15:38:36 +08:00
Dan Poltawski a873af4dfe MDL-28569 blocks/rss_client - RSS feed autodiscovery fails with ampersands
Simpliepie is quoting urls and we need the url to be unescaped
2011-08-08 14:10:44 +08:00
Sam Hemelryk 47a6e69179 Merged branch 'MDL-28575_MOODLE_20_STABLE' of git://github.com/kordan/moodle.git with conflict resolution 2011-08-08 14:00:08 +08:00
Sam Hemelryk 4ecd7134e5 Merge branch 'MDL-28587_MOODLE_20_STABLE' of git://github.com/kordan/moodle into MOODLE_20_STABLE 2011-08-08 13:45:05 +08:00
Rossiani Wijaya 269255473f MDL-27752_m20 Calendar export: fixed typo in url parameter 2011-08-08 12:06:46 +08:00
Sam Hemelryk 3bbbd26ee6 Merge branch 'MDL-28406_block_duplicate_20' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-08-08 11:19:18 +08:00
Sam Hemelryk 81c77993e3 Merge branch 'w31_MDL-27586_m20_browser' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-08-08 10:47:21 +08:00
Sam Hemelryk 6aec498812 Merge branch 'w31_MDL-27685_m20_pglike' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-08-08 10:25:55 +08:00
Sam Hemelryk 11909e87a0 Merge branch 'w31_MDL-28382_m20_iis' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-08-08 10:21:05 +08:00
Sam Hemelryk 48db633522 Merge branch 'w31_MDL-28450_m20_defgroup' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-08-08 10:09:56 +08:00
Petr Skoda 1a6bfd3c1e MDL-28382 work around or detect REQUEST_URI IIS bug 2011-08-07 14:48:44 +02:00
Petr Skoda e4ff5b5d74 MDL-27685 fix pg LIKE escape trouble 2011-08-07 13:23:36 +02:00
Petr Skoda 4e86cbabb0 MDL-28450 prefer member group for default 2011-08-07 13:09:00 +02:00
Petr Skoda 5bdd8b8e7a MDL-27586 fix file_browser access control 2011-08-06 16:41:18 +02:00
Petr Skoda fd526f38ce MDL-28473 fix $instanceids troubles in blocks upgrade
Credit goes to Mateusz Wójcik.
2011-08-05 22:10:44 +02:00
Petr Skoda 56eff94252 MDL-27597 fix invalid results of get_categories when shallow is false 2011-08-05 20:16:22 +02:00
Andrew Davis (andyjdavis) b6cbbb862c MDL-28465 rating: altered one of the get_ratings() queries to avoid possible future duplicate first column problems 2011-08-05 13:48:38 +08:00
Andrew Davis (andyjdavis) 0683e9c5be MDL-28406 blocks: added JS to prevent the addition of duplicate blocks 2011-08-05 11:36:58 +08:00
Sam Hemelryk 3b7127a9b7 MDL-28407 Fixed up calendar preferences form handling 2011-08-05 09:35:09 +08:00
Tim Hunt 6740639cef MDL-28604 Question bank display forgets sort order 2011-08-04 14:04:23 +01:00
Marina Glancy dcaa0b4e21 MDL-26754 Display blocks in 'manage blocks' alphabetically sorted 2011-08-04 14:14:39 +08:00
AMOS bot 190cae0e09 Automatically generated installer lang files 2011-08-04 00:55:44 +00:00
Petr Skoda 4b85dc13ac weekly release 2.0.4+ 2011-08-03 18:01:36 +02:00
kordan 761a9abd02 MDL-28587 fix for MOODLE_20_STABLE 2011-08-03 15:22:54 +02:00
Sam Hemelryk 763fc56f9a Revert "MDL-28284 don't load filepicker module for every page"
This reverts commit e336ad1b80.
2011-08-03 18:20:45 +08:00
kordan 43424771b6 MDL-28575 fix for MOODLE_20_STABLE 2011-08-02 23:44:13 +02:00
David Mudrak 4ac89c85d4 MDL-27550 workshop: fixed XHTML strictness of H3 and A combo
H3 is block level element while A is in-line element in XHTML.
Credit goes to Sam Hemelryk for spotting this during the peer-review.
2011-08-02 23:28:52 +02:00
David Mudrak d98c8aedb2 MDL-27550 workshop: rendering links to the submission and the assessment page
This usability improvement helps to provide feedback quickly during the
grading evaluation phase.
2011-08-02 23:14:45 +02:00
David Mudrak a6a58c3485 MDL-27550 workshop: students do not see peer-assessment that are not graded yet 2011-08-02 23:14:45 +02:00
David Mudrak 6e6b96d57b MDL-27550 workshop: display the feedback for the submission reviewer when the workshop is closed 2011-08-02 23:14:45 +02:00
David Mudrak c9f31ba3a3 MDL-27550 workshop: assessments are now displayed via proper rendering subsystem
AMOS BEGIN
 MOV [assessmentbyknown,mod_workshop],[assessmentbyfullname,mod_workshop]
AMOS END
2011-08-02 23:14:45 +02:00
David Mudrak 3675dbc32b MDL-27550 workshop: display the feedback for the submission author when the workshop is closed
The method user_picture::fields() was not available when these SQL
statements were originally written. Now instead of hard-coding the list
of returned fields, the user_picture is asked for the list.

Together with this change, methods workshop::get_submission_by_id()
and workshop::get_submission_by_author() now return the information
about the user who provided the feedback and overwrote the grade.
2011-08-02 23:14:44 +02:00
Petr Skoda b8a5c64e95 Merge branch 'wip-mdl-27658-m20' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-08-02 15:14:00 +02:00
Dan Marsden 984c6bd358 MDL-28410 Choice - allow single answer choice to be created 2011-08-02 15:06:15 +02:00
Dan Marsden 1389810600 MDL-28535 SCORM remove old IE 6 related warning about zlib 2011-08-02 14:42:24 +02:00
Sam Hemelryk 0f68bcbc52 Merge branch 'MDL-28508_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-08-02 17:47:13 +08:00
Andrew Robert Nicols 033be70faa MDL-28515 Add cli install options for fullname and shortname 2011-08-02 17:08:04 +08:00
Sam Hemelryk c440ddfb58 Merge branch 'MDL-28340_advanced_search_other_users_20' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-08-02 16:59:08 +08:00
Sam Hemelryk 6a60e3f282 Merge branch 'wip-mdl-28504-m20' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-08-02 16:52:22 +08:00
Sam Hemelryk f15c1b78ab Merge branch 'wip-MDL-19907-M00DLE_20_STABLE' of git://github.com/marinaglancy/moodle into MOODLE_20_STABLE 2011-08-02 16:44:33 +08:00
Sam Hemelryk 0b1bc0a771 MDL-27122 admin Improved block protection help string 2011-08-02 16:37:04 +08:00
Sam Hemelryk 43b2bb6cd9 Merge branch 'wip-MDL-27122-MOODLE_20_STABLE' of git://github.com/marinaglancy/moodle into MOODLE_20_STABLE 2011-08-02 16:36:16 +08:00
Sam Hemelryk 7d5f92870e Merge branch 'wip-MDL-27754-MOODLE_20_STABLE' of git://github.com/marinaglancy/moodle into MOODLE_20_STABLE 2011-08-02 14:09:57 +08:00
Sam Hemelryk e99d784ffe Merge branch 's11_MDL-28284_filepicker_module_20' of git://github.com/dongsheng/moodle into MOODLE_20_STABLE 2011-08-02 13:41:36 +08:00
Sam Hemelryk 25f8084ba0 Merge branch 'MDL-28510_20_STABLE' of git://github.com/marxjohnson/moodle into MOODLE_20_STABLE 2011-08-02 13:38:00 +08:00
unknown 187c395673 Merge branch 'm20_MDL-27876' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-08-02 13:27:00 +08:00
Piers Harding 902b6d7df4 MDL-27876 SCORM auto-adjust the stage height 2011-08-02 17:14:06 +12:00
Sam Hemelryk d5addee28f Merge branch 'MDL-28487-typo_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-08-02 12:22:57 +08:00
Sam Hemelryk a8562f6c01 Merged branch 'm20_MDL-28548' of git://github.com/danmarsden/moodle.git with comment changes 2011-08-02 11:49:21 +08:00
Marina Glancy e29521960d MDL-27754 fixed typo in language string 2011-08-02 08:51:24 +08:00
Marina Glancy 914cbfa714 MDL-27122 Allow admin to change CFG->undeletableblocktypes on 'Manage blocks' settings page. Instances of protected block types will be undeletable only from site context 2011-08-02 08:51:17 +08:00
Marina Glancy 54641661e1 MDL-19907 rewrote validation for required fields in forms, including support for editor field. Added parameter to use strict (no spaces) required fields validation 2011-08-02 08:50:51 +08:00
Rossiani Wijaya b7342c4c7b MDL-20501 survey module: fix text alignment for right to left language. Change undefined string to 2011-08-01 17:30:12 +08:00
Sam Hemelryk e8e1ad9100 Moodle 2.0.4 release 2011-08-01 16:55:04 +08:00
Andrew Davis (andyjdavis) 8c598be92d MDL-28465 rating: split the get_ratings() query into two 2011-08-01 15:35:40 +08:00
Rajesh Taneja dcb368720a MDL-27658 javascript: Typo fixed for toUpperCase 2011-08-01 12:55:01 +08:00
Rajesh Taneja 9d9e5bc707 MDL-28504 filter: Typo in css fixed 2011-08-01 10:24:15 +08:00
Dan Marsden e8ce08c331 MDL-28548 allow backup to contain info from multiple plagiarism plugins. 2011-08-01 10:29:23 +12:00
Sam Hemelryk f84058a263 weekly release 2.0.3+ (emergency) 2011-07-29 12:22:29 +08:00
Andrew Davis (andyjdavis) 3b81d3b0e2 MDL-28340 messaging: fixed a display issue when you search for and tried to view a conversation between two other users 2011-07-29 11:56:28 +08:00
Sam Hemelryk 03e29fff56 Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-07-29 10:13:30 +08:00
Sam Hemelryk 3765c3f098 MDL-28503 comment-caps Slight improvement to allow frontpage and guest users to view comments by default 2011-07-29 09:44:18 +08:00
Mark Johnson b3ebbd4fc8 MDL-28510 repository_youtube Use smaller thumbnails in search results 2011-07-28 13:44:53 +01:00
Mark Johnson 919304d4bf MDL-28509 repository_youtube Enable selection of sort order 2011-07-28 13:12:02 +01:00
Tim Hunt 01ae3d20da MDL-28508 bad string trunction in Aiken format. 2011-07-28 12:19:34 +01:00
Sam Hemelryk 15125314eb MDL-28503 Removed the ability for plugins to override comment capabilities and the defaults associated with it 2011-07-28 13:41:20 +08:00
AMOS bot 44e6b8ff57 Automatically generated installer lang files 2011-07-28 00:55:21 +00:00
David Mudrak 8684284e49 MDL-28487 Fixed typo in media filter help string 2011-07-27 14:42:05 +02:00
Petr Skoda c46c673568 weekly release 2.0.3+ 2011-07-26 11:08:28 +02:00
Petr Skoda aa79f99d53 Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-07-26 11:07:40 +02:00
AMOS bot ef65eefff8 Automatically generated installer lang files 2011-07-26 00:55:29 +00:00
Tim Hunt df390ba9f0 MDL-28218 allow testclient.php to find the necessary form for services defined in plugins. 2011-07-25 20:05:31 +02:00
Petr Skoda 2a41529f68 Merge branch 'MDL-28437_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-07-25 19:55:46 +02:00
Petr Skoda e9adc8f6eb Merge branch 'MDL-28453_MOODLE_20_STABLE' into MOODLE_20_STABLE 2011-07-25 16:30:52 +02:00
Aparup Banerjee 22edb9944a MDL-28453 backup - made temporary restoration courses hidden by default. 2011-07-25 16:46:22 +08:00
Tim Hunt ceedbe876d MDL-28437 Question bank pages should all use General type: admin. 2011-07-25 08:59:25 +01:00
Sam Hemelryk 213eaa94f6 Merge branch 'MDL-28107_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-07-25 15:14:39 +08:00
Dan Poltawski 2acfb396ec MDL-28232 - Course log text export is missing a new line 2011-07-25 12:57:39 +08:00
Michael Aherne 936f6706c2 MDL-27538 Added deprecation details to functions now in $DB 2011-07-25 11:31:40 +08:00
Sam Hemelryk 2e3a96e192 Merge branch 'w29_MDL-22584_m20_monsterpaths' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-25 11:18:45 +08:00
Sam Hemelryk 417fdfab6b Merge branch 'w29_MDL-27464_m20_continue' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-25 11:04:02 +08:00
Sam Hemelryk 77c9ae457d Merge branch 'w29_MDL-27653_m20_usercasting' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-25 10:59:30 +08:00
Sam Hemelryk a8fd6146e7 Merge branch 'w29_MDL-27796_m20_httphost' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-25 10:55:12 +08:00
Sam Hemelryk 538e680d39 Merge branch 'w29_MDL-27994_m20_creatorcaps' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-25 10:45:51 +08:00
Sam Hemelryk ec5f521a59 Merge branch 'w29_MDL-28145_m20_renderer' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-25 10:40:00 +08:00
Sam Hemelryk 100308ce24 Merge branch 'w29_MDL-28182_m20_userdel' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-25 10:37:05 +08:00
Sam Hemelryk f6fc3616de Merge branch 'w29_MDL-28384_m20_nullurl' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-25 10:15:05 +08:00
Sam Hemelryk 9a8343cdde Merge branch 'w29_MDL-28432_m20_cohortconfig' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-25 09:53:02 +08:00
Sam Hemelryk a4e3607a21 Merge branch 'w29_MDL-28440_m20_jssemicol' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-25 09:45:53 +08:00
Mary Evans 27a2c6bffd fix for MDL-27768 removed reference to gradient-sb image 2011-07-25 09:40:17 +08:00
Petr Skoda b6481ac993 MDL-27653 fix incorrect int | object detection 2011-07-24 15:06:07 +02:00
Petr Skoda 2abbe6e2a3 MDL-27994 course creator role is for creating courses only!
The course creator role is designed to be used to create courses, nothing else - that is create new course, create new course from backup + view hidden courses and categories.
2011-07-24 14:25:50 +02:00
Petr Skoda 3687ab70bc MDL-28384 convert empty log urls to ''
The problem is that the log table does not allow nulls, credit goes to Troy Williams.
2011-07-24 14:09:11 +02:00
Petr Skoda 201159335f MDL-27464 continuation link sometimes links off-site
This code was manually merged from MOODLE_19_STABLE, credit goes to Matt Meisberger.
2011-07-23 13:31:20 +02:00
Petr Skoda c3ceb8d218 MDL-28440 add missing semicolon causing JS issues
Credit goes to Mark Nielsen.
2011-07-23 11:50:22 +02:00
Petr Skoda 9df28ce5a3 MDL-22584 deal with oversized dir and file names during upgrade 2011-07-23 11:41:28 +02:00
Petr Skoda 784c24fde1 MDL-28145 fix renderer typo in comments 2011-07-22 23:44:49 +02:00
Petr Skoda cf264063c1 MDL-27796 ignore missing HTTP_HOST header 2011-07-22 23:34:34 +02:00
Petr Skoda 3f51ad2a70 MDL-28182 always use full user object when deleting users 2011-07-22 22:50:17 +02:00
Petr Skoda 6b0b96c581 MDL-28432 use enrol/cohort and enrol/manual capabilities correctly in cohort enrol UI and fix input validation in ajax 2011-07-22 10:11:08 +02:00
Rossiani Wijaya 8190a2911f MDL-28107 course enrolment icon: Fixed logged in user enrolment icons 2011-07-22 13:17:49 +08:00
Dongsheng Cai e336ad1b80 MDL-28284 don't load filepicker module for every page 2011-07-21 17:28:24 +08:00
Petr Skoda ac30618786 weekly release 2.0.3+ 2011-07-19 15:22:21 +02:00
Petr Skoda e9889abe38 Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-07-19 15:18:09 +02:00
Petr Skoda c0e1e425be MDL-27696 initialise arrays
Credit goes to David Mudrak.
2011-07-19 15:05:22 +02:00
Petr Skoda 517d606401 MDL-27696 do not use placeholders in GROUP BY because pg does no like that 2011-07-19 10:55:02 +02:00
Petr Skoda f3cbcc623d MDL-27889 use new recaptcha google urls in lang packs 2011-07-19 10:24:57 +02:00
Petr Skoda be36e2ad1d MDL-27889 use new recaptcha google urls in lang packs 2011-07-19 10:18:31 +02:00
AMOS bot aff1c65c3d Automatically generated installer lang files 2011-07-19 00:55:41 +00:00
Petr Skoda d96d964425 Merge branch 'wip-MDL-28040-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-07-18 15:34:42 +02:00
Petr Skoda 4f76e7ddf7 Merge branch 'wip-MDL-28184-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-07-18 15:29:19 +02:00
Petr Skoda 393d636e25 Merge branch 'wip-MDL-28205-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-07-18 15:25:56 +02:00
Petr Skoda 2b98c3d5e0 Merge branch 'wip-MDL-28137-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-07-18 15:23:21 +02:00
Petr Skoda 2bd3fc4d03 Merge branch 'wip-MDL-27771-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-07-18 15:20:26 +02:00
Petr Skoda 6b43f50c41 Merge branch 'wip-MDL-27696-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-07-18 15:18:24 +02:00
Petr Skoda 533a766447 Merge branch 'wip-MDL-27305-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-07-18 15:15:18 +02:00
Petr Skoda 59f3144e0a Merge branch 'wip-MDL-25870-m20' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-07-18 14:58:38 +02:00
Sam Hemelryk ef5a198d1c Merge branch 'wip-MDL-27756-MOODLE_20_STABLE' of github.com:marinaglancy/moodle into MOODLE_20_STABLE 2011-07-18 22:20:13 +10:00
Sam Hemelryk 60e7f2b113 Merge branch 'MDL-27555_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-07-18 21:51:39 +10:00
Sam Hemelryk 68bc5b7b68 Merge branch 'w28_MDL-27804_m20_csvauth' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-18 20:19:51 +10:00
Sam Hemelryk 45222fc50f Merge branch 'w28_MDL-28253_m20_managerupgrade' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-18 20:10:30 +10:00
Sam Hemelryk 78092d6742 Merge branch 'w28_MDL-28313_m20_enroldb' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-18 20:04:32 +10:00
Sam Hemelryk a3fe5348ab Merge branch 'w28_MDL-28348_m20_meta' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-18 19:39:56 +10:00
Sam Hemelryk e3f6f30896 Merge branch 'w28_MDL-28350_m20_wsra' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-18 19:29:01 +10:00
Petr Skoda 50296e134b Merge branch 'wip-MDL-25125-MOODLE_20_STABLE' of github.com:marinaglancy/moodle into MOODLE_20_STABLE 2011-07-18 09:36:20 +02:00
Sam Hemelryk a6c44179e5 Merge branch 'w28_MDL-28363_m20_dimmed' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-07-19 00:48:11 +10:00
Sam Hemelryk ab93b02919 Merge branch 'MDL-28298-workshop-constant_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-07-19 00:40:22 +10:00
Sam Hemelryk 07ea543a1c Merge branch 'MDL-28325-enrol-help_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-07-19 00:35:16 +10:00
Petr Skoda 768dd79e1f MDL-28348 fix spelling and some whitespace issues 2011-07-17 20:42:44 +02:00
Petr Skoda c7f51d2dfe MDL-28348 fix fatal error caused by unenrolling of incorrect enrol instance 2011-07-17 20:42:43 +02:00
Petr Skoda ebbc9e717f MDL-28348 prevent circular references in meta handler for enrolments 2011-07-17 20:42:43 +02:00
Petr Skoda 617027cf84 MDL-28348 fix meta sync when unassigning roles 2011-07-17 20:42:42 +02:00
Petr Skoda 21dc44b4df MDL-28363 make dimmed selectors more specific to prevent overriding from other themes 2011-07-16 21:05:48 +02:00
AMOS bot 922817560c Automatically generated installer lang files 2011-07-16 00:55:24 +00:00
Petr Skoda 4b9cb37191 MDL-28350 prevent bogus role assignment via externallib 2011-07-15 12:30:20 +02:00
Petr Skoda a4673317a7 MDL-27804 allow changing of only auth in csv user uploads 2011-07-15 11:10:38 +02:00
Petr Skoda deba736fbc MDL-28313 fix incorrect enrol database settings upgrade 2011-07-14 22:36:05 +02:00
Petr Skoda badddcab36 MDL-28253 use unique name for new manager role 2011-07-14 13:36:27 +02:00
Marina Glancy be1f4ab759 MDL-27756 Improving move_course() performance 2011-07-14 11:04:37 +08:00
Marina Glancy 01bb865997 MDL-25125 fix YUI bug with overriding styles 2011-07-14 10:02:43 +08:00
AMOS bot 79f544a45f Automatically generated installer lang files 2011-07-14 00:55:24 +00:00
Dan Marsden eadbd73918 MDL-28300 SCORM Fix check for SCORM 2004 thanks to Silvia Bastos for report/patch 2011-07-14 11:02:32 +12:00
David Mudrak bf9f318ead MDL-28325 Enrolment: added help to the duration, start date and end date setting
The patch also fixes one typo in enrol_manual detected while working on
this.
2011-07-13 22:36:00 +02:00
AMOS bot c015236f00 Removing oc_ES that was generated by an accident instead of proper oc_es 2011-07-13 15:36:08 +02:00
Sam Hemelryk 7a3156d001 weekly release 2.0.3+ 2011-07-13 20:24:18 +08:00
Sam Hemelryk b22eb6a987 Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-07-13 20:09:42 +08:00
David Mudrak c7c83663e1 MDL-28298 workshop: do not use a constant without explicit inclusion of the library
Instead of including whole formslib just to get the constant defined, I
decided to hard-code the value and put the reference to the comment so
that eventual grep would spot it. Of course that is is not nice at all
but it's lesser of two evils imho.
2011-07-13 10:23:10 +02:00
Sam Hemelryk 49d85b7cfa MDL-28184 navigation: Tidied up handling of coursenode when adding course essentials 2011-07-13 14:59:59 +08:00
Sam Hemelryk bc5d53c15c MDL-27771 filter-text: Fixed typo contninue 2011-07-13 14:53:18 +08:00
Chris Follin 95f780c200 MDL-27305 forum: Added missing item to forum_get_view_actions 2011-07-13 14:23:18 +08:00
Sam Hemelryk 3656becc4a MDL-25870 enrol-manual: Fixed pagination of AJAX search results for users when changing search 2011-07-13 14:03:08 +08:00
Sam Hemelryk 89ba1d6c2b MDL-28137 unit tests: Fixed up problem with block manager tests when running unit tests after turning editing on 2011-07-13 13:45:23 +08:00
Sam Hemelryk cca30c4795 MDL-28205 RSS: Fixed up notice and set better pagelayout type on manage feeds page 2011-07-13 10:31:50 +08:00
Sam Hemelryk c78b71efb6 MDL-27696 datalib Fixed up misused params in get_logs_usercourse 2011-07-13 10:29:36 +08:00
Sam Hemelryk 35a5d3b2fc MDL-28040 navigation: Fixed up error with navigation when dealing with categories that have a lower sort order than the parent. 2011-07-13 10:01:08 +08:00
AMOS bot 40638405ea Automatically generated installer lang files 2011-07-13 00:55:34 +00:00
Eloy Lafuente (stronk7) a53760ef5a Merge branch 'm20_MDL-28017' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-07-12 16:31:40 +02:00
Eloy Lafuente (stronk7) 1193e6b023 MDL-28210 messaging: all includes but config.php must use $CFG-based abosolute paths 2011-07-12 12:23:51 +02:00
Eloy Lafuente (stronk7) 8c5b86e044 Merge branch 'MDL-28210_messaging_constants_20_2' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-07-12 12:23:19 +02:00
Sam Hemelryk 6bc177e912 MDL-27809 navigation: Fixed up a couple of minor issues after peer-review 2011-07-12 16:04:12 +08:00
Sam Hemelryk 1f7907dac3 MDL-27809 navigation: Reworked the caching within navigation and improved the ordering of events in order to reduce the use of session without serious impact on serverload 2011-07-12 16:04:03 +08:00
Andrew Davis (andyjdavis) 25c53e2b9f MDL-28210 messaging: Fixed requires problems in /message/discussion.php 2011-07-12 10:56:33 +08:00
AMOS bot 83fcca9346 Automatically generated installer lang files 2011-07-12 00:55:27 +00:00
Dan Marsden ab837e6113 MDL-28017 SCORM add unset_config for old config var 2011-07-12 09:51:32 +12:00
Eloy Lafuente (stronk7) 96651cf9ed Merge branch 'MDL-28251_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-07-11 20:29:01 +02:00
Eloy Lafuente (stronk7) 583c465a3a Merge branch 'm20_MDL-26942' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-07-11 19:48:54 +02:00
Eloy Lafuente (stronk7) 24f90eedb9 Merge branch 'MDL-27755_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-07-11 19:44:41 +02:00
Eloy Lafuente (stronk7) 0d81404f9a Merge branch 'MDL-27741_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-07-11 19:36:16 +02:00
Dan Poltawski 7ba9375e84 MDL-23580 course overview - remove debugging junk 2011-07-11 16:47:43 +02:00
Eloy Lafuente (stronk7) 15ffa46a1a Merge branch 'MDL-27483_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-07-11 16:27:04 +02:00
Eloy Lafuente (stronk7) 38bc3c281a Merge branch 'MDL-27931_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-07-11 15:58:33 +02:00
Rossiani Wijaya 9bb6e09468 MDL-27741 forum subscribe link: Removed 'no' string in social course format to display a subscribe link if user is not enrolled 2011-07-11 17:00:33 +08:00
Sam Hemelryk 77de688b82 Merge branch 'wip-mdl-27954-MOODLE_20_STABLE' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-07-11 16:02:00 +08:00
Sam Hemelryk dd8e618917 Merge branch 'MDL-28227_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-07-11 14:54:48 +08:00
Dan Marsden ea819f2205 MDL-28017 SCORM - remove admin setting incorrectly added as it was never used. 2011-07-11 15:44:19 +12:00
Sam Hemelryk 05deeaacdb Merge branch 'm20_MDL-27947' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-07-11 11:32:04 +08:00
Sam Hemelryk 19dd687377 Merge branch 'mod_url_decode_m20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-07-11 11:04:35 +08:00
Sam Hemelryk f2c12522c3 Merge branch 'backup_groups_m20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-07-11 10:57:33 +08:00
Rajesh Taneja 79a80529f8 MDL-27954 mod_database - fixed search navigation link 2011-07-11 10:31:47 +08:00
AMOS bot 70a649e40c Automatically generated installer lang files 2011-07-11 00:55:22 +00:00
Eloy Lafuente (stronk7) 38a94e0d39 MDL-28156 restore - fix some notices restoring empty courses 2011-07-10 13:12:05 +02:00
Eloy Lafuente (stronk7) 327c88b76b MDL-28156 restore - support restoring files without grade items 2011-07-10 00:53:43 +02:00
Eloy Lafuente (stronk7) b229f563e5 MDL-27438 backup - on course backups add course gropus and groupings 2011-07-09 19:29:21 +02:00
Eloy Lafuente (stronk7) 7769615e76 MDL-27018 restore - decode links missing url->externalurl support 2011-07-09 13:36:14 +02:00
Dan Marsden 056d2682a1 MDL-27947 - fix TOC display on skipview - use correct org in TOC title 2011-07-09 11:50:15 +12:00
Dan Marsden a103d27e06 SCORM MDL-26942 - merge scorm_get_toc into a single global function 2011-07-09 11:15:13 +12:00
AMOS bot d9c90952bb Automatically generated installer lang files 2011-07-08 12:34:55 +02:00
Eloy Lafuente (stronk7) 89b2800f75 weekly release 2.0.3+ 2011-07-08 11:23:10 +02:00
Rossiani Wijaya e12559481f MDL-28251 DB activity module: fixed the argument type error for html_table_row from string to array 2011-07-08 16:54:38 +08:00
Eloy Lafuente (stronk7) 6761018805 Merge branch 'MDL-28015-workshop-sql_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-07-08 01:19:22 +02:00
Eloy Lafuente (stronk7) 9948122905 Merge branch 'MDL-28168-custommenu_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-07-08 00:58:24 +02:00
David Mudrak 308e53f572 MDL-28015 workshop - fixed unique list of columns in ORDER BY clause
MSSQL requires that the columns in the ORDER BY clause list must be
unique. The patch populates the list of fields by combining an array of
explicit sort definition with an array of implicit (default) sort
definition.
2011-07-07 15:02:34 +02:00
David Mudrak 3367e3ee1e MDL-28168 Revert "MDL-27073 Support multi-language content in custom menu"
This reverts commit 87e0230d0a.
2011-07-07 11:26:01 +02:00
Eloy Lafuente (stronk7) c1979ef02d Merge branch 'fix_import_search_course' of git://github.com/hit-moodle/moodle into MOODLE_20_STABLE 2011-07-07 10:38:44 +02:00
Tony Levi 25a5bd96f9 MDL-27483: Fix quiz repaginate enter in a endless loop 2011-07-07 16:19:56 +09:30
Rossiani Wijaya 536c7aa882 MDL-27755 course search: Add course id and shortname to search fields 2011-07-07 11:05:06 +08:00
Sun Zhigang 534eebdd35 MDL-27833 Backup - Fix can't search courses with non-latin characters during importing
PARAM_ALPHANUMEXT filter out all non-latin characters, including
Chinese, Japanese and etc. Use PARAM_NOTAGS instead.
2011-07-07 09:27:48 +08:00
Eloy Lafuente (stronk7) e317113746 Merge branch 'm20_MDL-28110' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-07-07 03:02:26 +02:00
Tony Levi ac473cb811 MDL-28227: Regrade sometimes grades user attempts for any quiz not selected quiz 2011-07-07 10:01:46 +09:30
Eloy Lafuente (stronk7) fea115dab3 Merge branch 'MDL-27989_MOODLE_20_STABLE' of git://github.com/kordan/moodle into MOODLE_20_STABLE 2011-07-07 02:23:33 +02:00
Dan Poltawski 46306d8a25 MDL-26285 block_rss_client - do not disable with enablerssfeeds
This setting was used in 1.9 and below to control feed generation only, not
for RSS consumption.
2011-07-07 02:12:09 +02:00
Petr Skoda 2c9b8852f0 MDL-27375 add missing lowercasing of external column names
Credit goes to Gail Preuninger.
2011-07-07 01:41:04 +02:00
Petr Skoda 413b73ffe3 MDL-28117 include repo lib when hacking file_picker renderer 2011-07-07 01:34:35 +02:00
Dan Poltawski 5bda351ef7 MDL-27329 course report - correct use of wrong fullname
We are refering to users in this column of the course report not
course full name.

Conflicts:

	course/lib.php
2011-07-07 00:26:26 +02:00
Dan Poltawski e5180a491c MDL-28100 - page resource was not using context for text filtering 2011-07-07 00:12:54 +02:00
Dan Poltawski 5d7b69cd80 MDL-27279 lang/en/xmldb - Fix Typo in confirmcheckforeignkeys 2011-07-07 00:02:04 +02:00
Eloy Lafuente (stronk7) 4bd293ee63 Merge branch 'MDL-27040_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-07-06 19:26:56 +02:00
Rossiani Wijaya 8252cd2848 MDL-27931 admin bulk user upload: convert city as required field. Credit goes to Charles Fulton for supplying the patch. 2011-07-06 16:17:01 +08:00
Dan Poltawski a35be2f5ef MDL-27855 navigation - only display participants link with permissions 2011-07-06 13:19:59 +08:00
Sam Hemelryk 668a9eb90b Merge branch 'MDL-27716_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-07-06 12:11:14 +08:00
Dan Poltawski 606e175133 MDL-27168 completionstatus block - Use localized strings 2011-07-06 12:03:59 +08:00
Dan Poltawski 2e214b26f3 MDL-26626 course competion block - fix hardcoded string 2011-07-06 11:30:33 +08:00
Dan Poltawski c24ad72ba0 MDL-26611 Roles Language - remove reference to 'legacy role type' 2011-07-06 11:10:47 +08:00
Sam Hemelryk ed26ad33ca Merge branch 'MDL-28135_MOODLE_20_STABLE' of git://github.com/nebgor/moodle into MOODLE_20_STABLE 2011-07-06 11:05:11 +08:00
Petr Skoda 9a380fbb53 MDL-28147 do not double cache theme css/js 2011-07-06 03:15:44 +02:00
Petr Skoda 6893e10840 MDL-28161 precreate htmlpurifier dir when resetting caches
Conflicts:

	lib/moodlelib.php
2011-07-06 02:59:16 +02:00
Eloy Lafuente (stronk7) c18a7f9d94 Merge branch 'MDL-28185_m20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-07-05 17:58:25 +02:00
Eloy Lafuente (stronk7) 07ca3c6816 Merge branch 'MDL-26618_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-07-05 17:48:30 +02:00
Eloy Lafuente (stronk7) 9315fd7200 MDL-28185 upgrade - fix oracle problem upgrading blocks 2011-07-05 15:38:37 +02:00
Kordan 10bc60a163 addition to previous fix for MDL-27989 in MOODLE_20_STABLE 2011-07-05 11:24:09 +02:00
Kordan 0f9a1467e2 MDL-27989 fix for MOODLE_20_STABLE 2011-07-05 10:13:35 +02:00
Aparup Banerjee 8b3405e8f2 MDL-28135 general Updated broken and typo docs links 2011-07-05 15:43:34 +08:00
Aparup Banerjee c5b7c1f627 MDL-28135 general Updated the Copyright notice to point to docs.moodle.org/dev/Releases instead of en/Release 2011-07-05 15:43:23 +08:00
Aparup Banerjee cc56539e51 MDL-28135 general Updated doc links related to Release notes to docs.moodle.org/dev/Releases now 2011-07-05 15:43:13 +08:00
Aparup Banerjee ae8da34929 MDL-28135 general Updating all hardcoded "docs.moodle.org/en/Development:" type doc links to "docs.moodle.org/dev/"
- cherry-picked and resolved conflicts
2011-07-05 15:39:56 +08:00
Rossiani Wijaya 0a6604e525 MDL-27555 assignment module: remove 'submitted' option from optional setting for offline assignment type. 2011-07-05 14:39:59 +08:00
Iñaki Arenaza 385e9d72ec MDL-24666 sync_users.php can throw db exception on sites upgraded from 1.x
From 2.0 on we lowercase all the settings related to LDAP attributes
to cope with differences in LDAP servers when returning attribute
names as array indices (some lowercase them, some leave them as
specified in the query, some normalize them, etc.).

But we only lowercase them when saving the settings page. So on sites
that have been migrated from 1.x, it may happen that we still have
mixed-case attribute names. And this is fatal for the user_attribute
setting, as we might not detect it in the returned array from LDAP and
it will be empty (and the db layer throws and exception).

So we just make sure the attribute name is lowercased (and trimmed,
in case it's got some white space around it).
2011-07-04 21:38:53 +02:00
Tim Hunt ae912070ea MDL-27040 get_users_by_capability generates u.id IN () when no uesrs have accessallgroups 2011-07-04 19:01:06 +01:00
Joseph Rezeau 988f1a05e7 MDL-27716 qtype_multianswer make the work 'Close' in the overlib popup translatable. 2011-07-04 15:53:09 +01:00
Tim Hunt b8369f5e9f MDL-26618 Moving sticky blocks on other pages does not work in Oracle.
This was due to some missing $DB->sql_empty() in a query affecting the
block_positions table.
2011-07-04 14:24:36 +01:00
Eloy Lafuente (stronk7) 020f0ffc5b weekly release 2.0.3+ 2011-07-02 00:01:29 +02:00
Eloy Lafuente (stronk7) 087a329eef Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-07-01 23:37:36 +02:00
Sam Hemelryk 39025fe177 Merge branch 's11_MDL-28121_split_20' of github.com:dongsheng/moodle into MOODLE_20_STABLE 2011-07-01 15:08:59 +08:00
Dan Marsden 473afcbfec SCORM MDL-28110 fix string name 2011-07-01 14:24:52 +12:00
Eloy Lafuente (stronk7) 1dcb107bd4 Merge branch 'MDL-28132_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-07-01 01:38:44 +02:00
Tim Hunt 7cf9937724 MDL-28132 truncate very long category names before using them in random question names. 2011-06-30 19:34:44 +01:00
Eloy Lafuente (stronk7) f6c6bb4d39 Merge branch 'MDL-28115_20stable' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-06-30 17:12:31 +02:00
Rossiani Wijaya 814bce6575 MDL-28115 lesson module: fixed undefined variable for multiple answer, disabled numberical input text during review and fixed bug for essay answer during review process. 2011-06-30 19:11:15 +08:00
Dongsheng Cai f12c714e6f MDL-28121, fixed deprecated split() function 2011-06-30 17:35:33 +08:00
Dan Marsden 74e78f3ad8 SCORM MDL-28110 set default for forcejavascript to yes - add string explaining what it does. 2011-06-30 19:40:01 +12:00
Sam Hemelryk 4a7e2298a3 Merge branch 'MDL-24684_20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-06-30 10:50:10 +08:00
Eloy Lafuente (stronk7) 910c941fa8 MDL-24684 backup - basic protection against time/memory limits 2011-06-30 03:43:50 +02:00
AMOS bot bfb0183f6d Automatically generated installer lang files 2011-06-30 00:55:15 +00:00
Eloy Lafuente (stronk7) add39c57dd Merge branch 'MDL-28044_MOODLE_20_STABLE' of git://github.com/nebgor/moodle into MOODLE_20_STABLE 2011-06-30 02:01:44 +02:00
Eloy Lafuente (stronk7) 1b024a0b51 Merge branch 'MDL-15587-stable' of git://github.com/grabs/moodle into MOODLE_20_STABLE 2011-06-30 01:54:44 +02:00
Eloy Lafuente (stronk7) 9d12edfcae Merge branch 'm20_MDL-28016' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-06-30 01:11:28 +02:00
Sam Hemelryk 746f1ac85c MDL-27988 backup grade: Calculated grade items calculation references now corrected and idnumber restore improved 2011-06-29 18:42:34 +02:00
Eloy Lafuente (stronk7) 8277c39c76 Merge branch 'MDL-27955_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-06-29 15:59:57 +02:00
Eloy Lafuente (stronk7) fb654f651f Merge branch 'wip-mdl-27964-MOODLE_20_STABLE' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-06-29 15:12:50 +02:00
Rossiani Wijaya 494f645bf4 MDL-27955 lesson module (m20): fixed error for reviewing lesson and update string to continue or finish reviewing 2011-06-29 18:34:54 +08:00
Dan Marsden a26a8c6a6f SCORM MDL-28016 - fix redirect call to use proper moodle_url 2011-06-29 20:32:36 +12:00
Rajesh Taneja 27beb68c4b MDL-27964 lesson - Quick fix added for importing question files in lesson module 2011-06-29 14:09:20 +08:00
Rajesh Taneja 8254083dc9 MDL-27964 lesson - Old file picker is replaced with new filepicker, currently all imported questions will be saved in /temp/questionimport/ where questionbank files are saved. 2011-06-29 14:08:30 +08:00
Aparup Banerjee 9b7ac1ea57 MDL-28044 general - updated print_error() link to point to new versioned docs link. 2011-06-29 10:57:14 +08:00
AMOS bot b214520d8b Automatically generated installer lang files 2011-06-29 00:55:20 +00:00
Sam Hemelryk abfe9dbe6e Merge branch 'MDL-28023_assignment_jabber_20' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-06-28 17:05:41 +08:00
Sam Hemelryk 8c75bb5976 Merge branch 's11_MDL-27866_pix_url_20' of git://github.com/dongsheng/moodle into MOODLE_20_STABLE 2011-06-28 10:17:48 +08:00
Sam Hemelryk e78632643c Merge branch 'MDL-28014_stable' of git://github.com/grabs/moodle into MOODLE_20_STABLE 2011-06-28 10:13:15 +08:00
sam marshall f114cff65f MDL-28021 Completion system can create inconsistent database rows
This change includes:

(1) update deletes older versions of inconsistent rows
(2) update drops one index and replaces it with a new unique index
(3) fixed to ensure that when it decides whether to insert or update
    it uses current database state and not cached info
(4) unit tests updated to test #3
2011-06-27 15:26:54 +02:00
Andrew Davis (andyjdavis) 3c18677ad1 MDL-28023_assignment_jabber assignment: added context url to improve the jabber notifications 2011-06-27 11:11:34 +08:00
Andrew Davis (andyjdavis) 1a199937f0 MDL-28023 assignment: assignment wasnt supplying all the data necessary to produce a meaningful jabber notification 2011-06-27 11:11:19 +08:00
AMOS bot b39029f718 Automatically generated installer lang files 2011-06-27 00:55:14 +00:00
Eloy Lafuente (stronk7) 7cb1a84978 Merge branch 'MDL-27922_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-06-27 00:55:29 +02:00
AMOS bot 8f7c097a09 Automatically generated installer lang files 2011-06-26 00:55:14 +00:00
Andreas Grabs 5dc47fbbc6 MDL-15587 - Course Participation report for a feedback activity 2011-06-24 23:11:10 +02:00
Rossiani Wijaya bac9a5e95e MDL-27922 lesson mod: fixed string for activity link 2011-06-24 16:48:46 +08:00
Eloy Lafuente (stronk7) 4a8d589d41 Merge branch 'MDL-27827_stable' of git://github.com/grabs/moodle into MOODLE_20_STABLE 2011-06-24 00:23:03 +02:00
Eloy Lafuente (stronk7) ffd06a7394 Merge branch 's11_MDL-27999_wiki_preview_20' of github.com:dongsheng/moodle into MOODLE_20_STABLE 2011-06-24 00:14:41 +02:00
Eloy Lafuente (stronk7) ba55e33828 Merge branch 'wip-MDL-27958-MOODLE_20_STABLE' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-06-23 23:58:21 +02:00
Andreas Grabs 3fcd1d05b9 MDL-28014 - unpropitious use of bcmod() 2011-06-23 21:20:49 +02:00
Andreas Grabs 29f02f10f0 MDL-27827 - Missing messageprovider:message language string 2011-06-23 20:31:17 +02:00
Eloy Lafuente (stronk7) ff555b58be emergency release 2.0.3+ 2011-06-23 18:23:51 +02:00
stabijoh 42d1a03acc MDL-27998 canvas theme - fix font sizes 2011-06-23 17:29:45 +02:00
Eloy Lafuente (stronk7) 80a90f8d71 weekly release 2.0.3+ 2011-06-23 11:27:12 +02:00
Eloy Lafuente (stronk7) 4a225b69bb Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-06-23 11:24:19 +02:00
Eloy Lafuente (stronk7) 727242750d Merge branch 's10_MDL-27341_flickr_plugin_20' of git://github.com/dongsheng/moodle into MOODLE_20_STABLE 2011-06-23 11:16:34 +02:00
Dongsheng Cai 454efc509f MDL-26677 flickr repo - fix undefined index usewatermarks 2011-06-23 17:14:30 +08:00
Eloy Lafuente (stronk7) 1bef145b49 Merge branch 'MDL-27920_grade_export_20' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-06-23 10:19:13 +02:00
Andrew Davis (andyjdavis) 1a20976561 MDL-27920 gradebook: fixes following integration review 2011-06-23 16:02:04 +08:00
Andrew Davis (andyjdavis) 2558ce3593 MDL-27920 gradebook: export was always excluding course totals and xml export was failing 2011-06-23 16:01:52 +08:00
Dongsheng Cai ab14ec06d2 MDL-27999 mod wiki, fixed broken image in preview 2011-06-23 13:53:12 +08:00
Sam Hemelryk d072124ba4 MDL-27958 Added missing set_context call which would cause errors for all contexts below course 2011-06-23 12:17:55 +08:00
Sam Hemelryk d9c19266c8 Merge branch 'MDL-27169_m20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-06-23 10:44:32 +08:00
Eloy Lafuente (stronk7) cf93662ffe MDL-26677 repositories - clean one debugging var_dump() 2011-06-23 02:06:16 +02:00
Eloy Lafuente (stronk7) 177f14d6f6 Merge branch 's10_MDL-27341_flickr_plugin_20' of git://github.com/dongsheng/moodle into MOODLE_20_STABLE 2011-06-23 02:05:45 +02:00
Eloy Lafuente (stronk7) bdcea1a221 Merge branch 'MDL-27196-hardcodedstrings_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-06-23 00:26:09 +02:00
Eloy Lafuente (stronk7) 25ebb1df63 MDL-27169 filepicker - add explicit enctype to the js upload form. Credit goes to J Ross Nicoll, thanks! 2011-06-22 19:32:01 +02:00
David Mudrak 39af096daf MDL-27196 workshop - hardcoded strings in the random allocator 2011-06-22 18:02:48 +02:00
David Mudrak 0ff186d7d7 MDL-27196 workshop - hardcoded string in the number of errors strategy form 2011-06-22 18:02:44 +02:00
Eloy Lafuente (stronk7) 26a92149cc Merge branch 'wip-mdl-26281-MOODLE_20_STABLE' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-06-22 14:28:36 +02:00
Eloy Lafuente (stronk7) 38961259de Merge branch 'MDL-27969-randomallocator-20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-06-22 14:16:41 +02:00
Eloy Lafuente (stronk7) 528cde2db2 Merge branch 'MDL-27073_multilang-custommenu_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-06-22 14:12:11 +02:00
David Mudrak 0ca33a3835 MDL-27969 workshop - prevent PHP notices in the random allocator
When generating the output of the allocation results, the names of
reviewers and authors are obtained based on the current state of assigned
roles and the 'musthavesubmission' setting. Therefore, when we want to
display information about a re-used allocation, the name of the author
or the name of the author may not be available.

In case of reviewers, we first try to reload the list including the
users without own submission. If it does not help, we just display the
id of the user instead of the name. In case of authors, we just display
the id the user. I can't see much point of eventual fetching the user
record from the database just to populate the list that almost no-one
reads anyway.
2011-06-22 12:15:47 +02:00
Rajesh Taneja 2a02a3f0de MDL-26281 Lesson - Fixed short answer with apostrophe and other html formats 2011-06-22 17:20:25 +08:00
Sam Hemelryk 8445c4724c Merge branch 'MDL-27966_m20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-06-22 17:16:00 +08:00
Sam Hemelryk 3e6c1d4d55 Merge branch 'MDL-25811_m20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-06-22 17:10:53 +08:00
Eloy Lafuente (stronk7) 2c85a824fc Merge branch 's10_MDL-27341_flickr_json_error_20' of git://github.com/dongsheng/moodle into MOODLE_20_STABLE 2011-06-22 03:07:26 +02:00
Eloy Lafuente (stronk7) 6ce26b03e7 Merge branch 'MDL-27860_2.0' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-06-22 03:00:41 +02:00
AMOS bot ae18165edd Automatically generated installer lang files 2011-06-22 00:55:18 +00:00
Eloy Lafuente (stronk7) 5def8d573d Merge branch 'MDL-26948_2.0' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-06-22 02:36:05 +02:00
Eloy Lafuente (stronk7) 41c5f54940 MDL-27966 timezones - updated to 2011g version + fix minor notice 2011-06-21 16:25:18 +02:00
AMOS bot 39b5360e69 Automatically generated installer lang files 2011-06-21 00:55:16 +00:00
Rossiani Wijaya 6409d38377 MDL-27906 calendar event: fixed retrieving coursemodule by replacing get_coursemodule_from_id() to get_coursemodule_from_instance() 2011-06-20 15:13:59 +08:00
Dongsheng Cai 945df69ff3 MDL-27866, set page context for $OUTPUT->pix_url 2011-06-20 13:53:06 +08:00
AMOS bot 16aae71dcd Automatically generated installer lang files 2011-06-20 00:55:14 +00:00
Eloy Lafuente (stronk7) 371e83db2d MDL-25811 automated backups - clean running status after 90 mins of inactivity 2011-06-18 22:12:57 +02:00
Tim Hunt f4bc50d2bb MDL-27860 count quiz attempts properly when checking if a new attempt is allowed. 2011-06-18 18:33:55 +01:00
AMOS bot b32484d582 Automatically generated installer lang files 2011-06-18 00:55:20 +00:00
Tim Hunt 6750bec6c9 MDL-26948 quiz navigation fake block should have an id to allow styling. 2011-06-17 17:26:34 +01:00
David Mudrak 6a8787828e MDL-27073 Support multi-language content in custom menu 2011-06-17 17:05:10 +02:00
Dongsheng Cai 466b23caf7 MDL-27341, fixed flickr public plugin should check
search text, tag and nsid before searching photos
2011-06-17 12:13:42 +08:00
Dongsheng Cai a4d6717aec MDL-26677 fixed undefined index usewatermarks in flickr plugin 2011-06-17 12:11:22 +08:00
Eloy Lafuente (stronk7) cc50a2fbc4 weekly release 2.0.3+ 2011-06-16 19:09:49 +02:00
Eloy Lafuente (stronk7) 3345c20e29 fix permissions 2011-06-16 19:06:33 +02:00
Eloy Lafuente (stronk7) c06e87a410 Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-06-16 19:04:49 +02:00
Eloy Lafuente (stronk7) db005da178 Merge branch 'MDL-24355-MOODLE_20_STABLE2' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-06-16 10:39:48 +02:00
Andrew Davis (andyjdavis) cfc9f55ca6 MDL-24355 tag: minor clean up of tags changes 2011-06-16 10:35:29 +08:00
Sam Hemelryk 15f0d2ed37 MDL-24355 Fixed up deletion of tag correlations when deleting tags 2011-06-16 10:07:58 +08:00
Sam Hemelryk a370e4e4fa MDL-24355 Added code to delete any tag correlations that wern't just identified 2011-06-16 10:07:41 +08:00
Eloy Lafuente (stronk7) a9e0bc82fb Merge branch 'wip-mdl-27863-MOODLE_20_STABLE' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-06-15 11:30:15 +02:00
Rajesh Taneja ec05915767 MDL-27863 moodlelib: - fixed testcase faliure in MDL-27577 2011-06-15 16:38:29 +08:00
Eloy Lafuente (stronk7) b5e8919b7c Merge branch 'm20_MDL-27858' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-06-15 01:18:33 +02:00
Eloy Lafuente (stronk7) 397262e292 Merge branch 'MDL-27848_for_MOODLE_20_STABLE' of git://github.com/kordan/moodle into MOODLE_20_STABLE 2011-06-15 00:55:08 +02:00
Dan Marsden ea1e93b265 SCORM MDL-27858 - fix typo 2011-06-15 10:33:15 +12:00
AMOS bot 29e42725a4 Automatically generated installer lang files 2011-06-14 18:25:59 +02:00
Eloy Lafuente (stronk7) 91c59dbd8e MDL-27759 backport some improvs from master + whitespace fix 2011-06-14 17:07:03 +02:00
Eloy Lafuente (stronk7) 87c8b752ca Merge branch 'wip-MDL-27759-MOODLE_20_STABLE' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-06-14 17:01:56 +02:00
Eloy Lafuente (stronk7) 4fcc689dfc Merge branch 'wip-MDL-27825-MOODLE_20_STABLE' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-06-14 12:30:55 +02:00
Eloy Lafuente (stronk7) 27f31cc626 Merge branch 'MDL-27525_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-06-14 12:12:57 +02:00
Kordan 9660303cc2 MDL-27835_for_MOODLE_20_STABLE fix 2011-06-14 11:45:31 +02:00
Sam Hemelryk 9abec7278b MDL-27825 Improved check of themedesignermode to prevent errors if it isn't set 2011-06-14 15:49:33 +08:00
Kordan ba7c14c1a7 MDL-27834 for MOODLE_20_STABLE fix 2011-06-14 09:54:53 +08:00
Sam Hemelryk 97161e5008 Merge branch 'MDL-27286_m20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-06-14 09:48:57 +08:00
AMOS bot 25041083d5 Automatically generated installer lang files 2011-06-14 00:55:09 +00:00
Eloy Lafuente (stronk7) a1c5868475 MDL-27822 rename new methods 2011-06-14 00:35:07 +02:00
Tim Hunt d4e94648cf MDL-27822 old module version should be available in restore_activity_structure_step::define_structure() 2011-06-14 00:34:50 +02:00
Eloy Lafuente (stronk7) b651e7bb74 MDL-27286 recent files repo - fix for oracle and cleanup 2011-06-13 18:55:19 +02:00
Eloy Lafuente (stronk7) d527599fcd whitespace fixes 2011-06-13 10:29:18 +02:00
Sam Hemelryk c1d93d47e9 Merged branch 'MDL-26960-for-20_STABLE' of git://git.luns.net.uk/moodle with changes 2011-06-13 15:09:16 +08:00
Sam Hemelryk 6160c1721c Merge branch 'm20_MDL-27404' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-06-13 14:54:06 +08:00
Sam Hemelryk 71472b0a82 Merge branch 'MDL-16168-CAS-crash-if-no-LDAP-20' of https://github.com/iarenaza/moodle into MOODLE_20_STABLE 2011-06-13 11:32:55 +08:00
Sam Hemelryk ba3721d463 Merge branch 'MDL-27757-20' of git://github.com/srynot4sale/moodle into MOODLE_20_STABLE 2011-06-13 11:18:48 +08:00
Sam Hemelryk 1a1f7b0eec Merge branch 'MDL-27783-20STABLE' of git://github.com/mouneyrac/moodle into MOODLE_20_STABLE 2011-06-13 11:14:02 +08:00
Rossiani Wijaya 0c60b1113e MDL-27525 mod_wiki: Fixed typing error for the variable and assign the value contextid to use mod context id 2011-06-13 11:08:32 +08:00
Sam Hemelryk 79121602c4 Merged branch 'MDL-27801_MOODLE_20_STABLE' of git://github.com/kordan/moodle.git with changes 2011-06-13 10:35:55 +08:00
Rajesh Taneja ba16180449 MDL-27759 user webservice - added new PARAM for timezone PARAM_TIMEZONE, to validate timezone input in webservice while deling with user information 2011-06-13 10:23:46 +08:00
Dan Marsden 01765239b0 MDL-27404 SCORM fix for IE 6 - thanks to Howard Miller 2011-06-13 11:31:48 +12:00
Marina Glancy d65a2b2262 MDL-26430 fixed appearance of one html form within another 2011-06-10 13:15:13 +08:00
Aaron Barnes 4754c0edd1 MDL-27757 lib/completionlib.php: Load "enablecompletion" property if required 2011-06-10 13:54:45 +12:00
kordan ec441b6dd0 MDL-27801 fix for MOODLE_20_STABLE 2011-06-09 22:05:32 +02:00
Dan Poltawski df01a82082 messaging: MDL-26960 Check correct users permissions
When on message profile page, the incorrect capability was checked
2011-06-09 16:01:15 +01:00
Jerome Mouneyrac 00338d8b94 MDL-27783 enabled status of a built-in service should never been updated on upgrade. It is only used during the installation. If a dev really needs to change the status, he can do it in lib/db/upgrade.php 2011-06-09 16:59:35 +08:00
Eloy Lafuente (stronk7) 57e034c094 weekly release 2.0.3+ 2011-06-09 03:42:48 +02:00
Eloy Lafuente (stronk7) c5b9fe0dda Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-06-09 03:38:54 +02:00
Eloy Lafuente (stronk7) 07511dbe6d Merge branch 'wip-MDL-27638-MOODLE_20_STABLE' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-06-09 01:23:30 +02:00
Eloy Lafuente (stronk7) df70dfe4ee Merge branch 'wip-mdl-27577-MOODLE_20_STABLE' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-06-09 01:10:27 +02:00
Eloy Lafuente (stronk7) f872b32778 Merge branch 'wip-MDL-27676-MOODLE_20_STABLE' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-06-09 00:36:33 +02:00
Iñaki Arenaza beb807e033 MDL-16168 auth/cas CAS crashes if no LDAP is set up
Pending fix for Moodle 2.x. Credit goes to Ivan Dackiewicz.
2011-06-08 19:45:14 +02:00
Sam Hemelryk 98d17b5bad MDL-27676 Requests for a users profile pic that doesnt exist now redirect to the requested f1/f2 rather than just f1 2011-06-08 18:06:22 +08:00
Sam Hemelryk bca840b4bc Merged branch 'MDL-27695_MOODLE_20_STABLE' of git://github.com/nebgor/moodle.git with changes 2011-06-08 16:32:18 +08:00
Sam Hemelryk 80406e9dd8 Merge branch 'MDL-27737_2.0' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-06-08 13:52:39 +08:00
Sam Hemelryk f4c5e50440 Merged branch 'MDL-25775_stable' of git://github.com/grabs/moodle.git 2011-06-08 13:51:10 +08:00
Sam Hemelryk 1382f8a549 Merged branch 'MDL-27118-MOODLE_20_STABLE' of git://github.com/epsd/moodle.git 2011-06-08 13:43:51 +08:00
Aparup Banerjee c372808e97 MDL-27695 Documentation : updated the moodle docs link at the footer of pages to point to new docs url 2011-06-08 13:43:44 +08:00
Sam Hemelryk f279137a86 Merge branch 'MDL-27294-MOODLE_20_STABLE' of git://github.com/epsd/moodle into MOODLE_20_STABLE 2011-06-08 13:39:29 +08:00
Sam Hemelryk 0ad12999d7 MDL-27704 Fixed typo in theme/fusion/style/core.css 2011-06-08 13:36:27 +08:00
Mary Evans a390156411 MDL-27704_master Fix for Overlapping problems in Fusion theme 2011-06-08 13:35:30 +08:00
kordan b84a272faf MDL-27588 Fixed up several bugs with the formal_white theme
-> MDL-26934 has been fixed
-> MDL-27474 has been fixed
-> one more option to have blocks column with different background colours
-> one more option to use custom font size
-> version.php, and b/install.php to handle upgrades
-> increased the font size in the table with plugin list shown at upgrade time
-> minor fixes in IE7 when images from remote web sites are shown in the header
-> conformed the dock background colour to the block background colour to avoid unpleasant color combinations
-> conformed a.link, a.visited and a.active colours in tabs
-> conformed a.link, a.visited and a.active colours in the navigation block
-> deleted an awful box border from enrolment page
-> right aligned commands for resources and activities in the course page
-> increased the width of field item title column in mform
-> increased the padding-top to the help popup box messages
-> user menu restyled to fix some minor tweaks in IE7
-> minor repair to tabs to improve its look
-> restyling of the docked item panel header to look like all the other blocks
-> reduced the distance between elements in headermenu to look better even when only headings are shown in the header
-> links wherever and always black
-> the "search courses" field in the navigation bar does not force extra height
-> some unpleasant generalbox border duplicating some other border have been removed
-> some unpleasant margin/padding in notices and mtables has been removed
2011-06-08 13:14:36 +08:00
Sam Hemelryk f2ba68efc1 Merged branch 'MDL-27692' of git://github.com/MaryE/moodle.git 2011-06-08 13:04:57 +08:00
Sam Hemelryk 629ea4957b Merge branch 'MDL-25477-MOODLE_20_STABLE' of git://github.com/epsd/moodle into MOODLE_20_STABLE 2011-06-08 11:31:14 +08:00
Sam Hemelryk 4c1db5b4ea Merged branch 's9_MDL-26392_wiki_files_20' from git://github.com/dongsheng/moodle.git with fixes 2011-06-07 16:31:38 +08:00
Sam Hemelryk 7ea0f8e519 Merge branch 'MDL-27734-workshop-example-weight_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-06-07 16:25:14 +08:00
Sam Hemelryk ece057943d Merge branch 'MDL-27733-workshop-deadlines_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-06-07 16:22:49 +08:00
Sam Hemelryk edb8d49d35 Merge branch 'MDL-27732-glossary-introformat_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-06-07 16:14:52 +08:00
Sam Hemelryk 8c23e3f5ff Merge branch 'admin_whitespace_cleanup_m20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-06-07 16:11:33 +08:00
AMOS bot 30a39ee2b7 Automatically generated installer lang files 2011-06-07 00:55:09 +00:00
Tim Hunt c3a68f4496 MDL-27737 numerical qtype upgrade bug 2.0dev -> 2.0. 2011-06-06 18:13:31 +01:00
Andreas Grabs d230fb7bcd MDL-25775 - Site policy page blank 2011-06-06 18:12:14 +02:00
David Mudrak 0f37e97dc6 MDL-27734 Fixed weights of the example submission assessments 2011-06-06 17:27:32 +02:00
David Mudrak c33e534dce MDL-27733 workshop: keep the phase deadlines during the 1.9 => 2.0 upgrade 2011-06-06 15:40:56 +02:00
David Mudrak 65814f90c1 MDL-27732 Include the introformat field in the glossary module backups 2011-06-06 15:16:46 +02:00
Eloy Lafuente (stronk7) 3a1380d81a MDL-27724 wiki - update commented upgrade step to avoid future problems 2011-06-05 19:46:46 +02:00
Eloy Lafuente (stronk7) 743010f779 MDL-27723 whitespace cleanup of admin directory 2011-06-05 19:34:12 +02:00
AMOS bot 5a1a6fc1f0 Automatically generated installer lang files 2011-06-05 00:55:09 +00:00
Dongsheng Cai b0022f8d91 MDL-26392 WIKI added file managment support to wiki editor 2011-06-03 11:24:50 +08:00
Mary Evans 838f1bcdf4 MDL-27692-fixes_bullets_not_numbers_in_ordered_list_in_topic_sectio_in_course_page_view 2011-06-03 03:03:38 +01:00
Rajesh Taneja 014fba4928 MDL-27577 moodlelib - fixed dst offset in userdate, usergetdate and make_timestamp functions 2011-06-03 09:59:52 +08:00
AMOS bot 32eadaf080 Automatically generated installer lang files 2011-06-03 00:55:27 +00:00
Eloy Lafuente (stronk7) dba24103ea weekly release 2.0.3+ 2011-06-02 23:37:12 +02:00
Eloy Lafuente (stronk7) 0a770d5c6c Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-06-02 23:28:02 +02:00
AMOS bot 29775a8e89 Automatically generated installer lang files 2011-06-02 00:55:11 +00:00
Sam Hemelryk f2855813c7 MDL-27638 Removed buggy status line from query as it is being calculated in php anyway 2011-05-31 17:03:17 +08:00
Eloy Lafuente (stronk7) b5e1c2e748 Merge branch 'MDL-25191-m20' of git://github.com/sammarshallou/moodle into MOODLE_20_STABLE 2011-05-31 01:01:24 +02:00
Sam Hemelryk 98c1207c46 Merge branch 'wip-mdl-27603-MOODLE_20_STABLE' of git://github.com/rajeshtaneja/moodle into MOODLE_20_STABLE 2011-05-30 17:22:41 +08:00
Sam Hemelryk 3466a42f31 Merge branch 'MDL-25512' of git://github.com/MaryE/moodle.git 2011-05-30 13:07:24 +08:00
Rajesh Taneja 3fc24f1238 MDL-27603 enrol_user - changed modifier to modifierid which is used in database 2011-05-30 10:20:24 +08:00
Sam Hemelryk 2e8ab7269c Merge branch 'MDL-27636_20stable' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-05-30 09:33:19 +08:00
Sam Hemelryk 72ca02b0b2 Merge branch 'MDL-27009' of git://github.com/aolley/moodle into MOODLE_20_STABLE 2011-05-30 09:04:34 +08:00
Mary Evans 22a7afd577 wip-MDL-25512 Correct CSS rules in Canvas theme to align with YUI3 CSS Fonts 2011-05-30 00:12:27 +01:00
Adam Olley c281550ce5 MDL-25191: Properly destroy all elements of the modinfo cache 2011-05-27 13:31:36 +01:00
AMOS bot 4a94bae470 Automatically generated installer lang files 2011-05-26 00:55:15 +00:00
Eloy Lafuente (stronk7) 92480bc82b MDL-27636 restore - add support for after_restore() to plugins. Credit goes to Mark Nielsen. Thanks! 2011-05-26 02:39:43 +02:00
Eloy Lafuente (stronk7) 2ff8943027 MDL-27541 course reports - allow teachers to view individual reports 2011-05-26 01:31:43 +02:00
Eloy Lafuente (stronk7) da63c93657 weekly release 2.0.3+ 2011-05-26 00:25:27 +02:00
Eloy Lafuente (stronk7) 4e184a9ce6 Merge branch 'install_20_STABLE' of git://github.com/amosbot/moodle into MOODLE_20_STABLE 2011-05-26 00:14:02 +02:00
Eloy Lafuente (stronk7) 36420f78c1 Merge branch 'MDL-27625_20stable' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-05-25 16:38:48 +02:00
Eloy Lafuente (stronk7) 93e980d52b MDL-27625 rating - consider RATING_UNSET_RATING a valid rating value 2011-05-25 16:14:07 +02:00
sam marshall 9e5855cb1a MDL-27532 Add backup support for course report per-course data 2011-05-23 12:16:13 +02:00
Sam Hemelryk f9ba5c5222 Merge branch 'm20_MDL-25177_choice_windowfix' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-05-23 11:34:29 +08:00
Sam Hemelryk f79dd3b57d Merge branch 'MDL-27530_stable' of git://github.com/grabs/moodle into MOODLE_20_STABLE 2011-05-23 11:25:25 +08:00
AMOS bot f5eec88fb6 Automatically generated installer lang files 2011-05-22 21:22:44 +02:00
AMOS bot f5a4f25375 Automatically generated installer lang files 2011-05-19 11:45:22 +02:00
Dan Marsden d714350a11 MDL-25177 Choice - fix typo for form creation causing pop-up window - thanks to Jason Hardin for fix 2011-05-19 13:03:04 +12:00
Sam Hemelryk a021f72a34 weekly release 2.0.3+ 2011-05-18 18:12:56 +08:00
Sam Hemelryk 32af9814f1 MDL-27161 Improved the 2 new strings in assignment 2011-05-18 17:30:06 +08:00
Sam Hemelryk bcb785fa9e MDL-26704 Fixed up variable typo 2011-05-18 15:33:41 +08:00
Eloy Lafuente (stronk7) 733bd07b8b MDL-27192 Global scope does not need global usage 2011-05-17 18:50:16 +02:00
Eloy Lafuente (stronk7) 19ab387d06 Merge branch 'wip-MDL-27192_MOODLE_20_STABLE' of git://github.com/jason-platts/moodle into MOODLE_20_STABLE 2011-05-17 18:49:49 +02:00
Jason Platts 02a03f4fe2 MDL-27192 Page context error on calendar export with custom user
profile fields
2011-05-17 15:24:39 +01:00
Eloy Lafuente (stronk7) 75c92b6306 MDL-27161: whitespace fix 2011-05-17 14:57:32 +02:00
Eloy Lafuente (stronk7) e56ac08a5c Merge branch 'MDL-27386_m20_b' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-05-17 14:28:55 +02:00
stabijoh 0cf31e061b MDL-27294 fix for fusion and overlay zoom text issue 2011-05-17 07:32:01 -04:00
Eloy Lafuente (stronk7) 65150b26cd MDL-26704 gradebook: adding TODO comment to avoid forgetting 2011-05-17 12:00:50 +02:00
Eloy Lafuente (stronk7) e1ad9ae4f5 Merge branch 'MDL-26704_user_outline_report' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-05-17 12:00:10 +02:00
Andreas Grabs ffa12b8397 MDL-27530 The webdav-repository loads empty files 2011-05-16 15:32:17 +02:00
Eloy Lafuente (stronk7) 890c7fae4e Merge branch 'MDL-26436_close_recordsets3' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-05-16 09:26:29 +02:00
Andrew Davis (andyjdavis) 9f2e9b535d MDL-26436 message: reviewed use of recordsets in messaging 2011-05-16 14:00:09 +08:00
Sam Hemelryk c7d4a92ccf Merge branch 'MDL-27161_m20' of git://github.com/rwijaya/moodle.git 2011-05-16 12:32:12 +08:00
Sam Hemelryk 5bd0e7af9f Merge branch 'MDL-27387_rating_scale_validation' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-05-16 12:16:26 +08:00
Sam Hemelryk 794fb0e565 Merge branch 'MDL-26075_stable' of git://github.com/grabs/moodle 2011-05-16 12:10:58 +08:00
Glenn Ansley 998b74a160 MDL-27494 choice - fixing incorrectly named column in backup 2011-05-16 03:25:46 +02:00
Eloy Lafuente (stronk7) 9ae0b69f59 Merge branch 'MDL-26436_close_recordsets2' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-05-16 02:46:52 +02:00
Rossiani Wijaya f4dc83e6e6 MDL-27161: fixed optional setting for 'require grading' to prevent page lock out 2011-05-13 14:10:45 +08:00
Sam Hemelryk ca2b2eb8af MDL-27456 Fixed typo in comment/lib.php after last refatoring 2011-05-13 11:18:48 +08:00
Andreas Grabs 5399e053d1 MDL-26075 Sending Message through Feedback Component throws an error 2011-05-12 17:10:06 +02:00
Rossiani Wijaya 6ef4ef1ee5 MDL-27161: fixed optional setting for 'require grading' to prevent page lock out 2011-05-12 16:53:55 +08:00
Andrew Davis (andyjdavis) f5a1b068cc MDL-27387 rating: prevent the submission of ratings outside of the range allowed by the current scale 2011-05-12 10:44:46 +08:00
Andrew Davis (andyjdavis) b9d64ab18f MDL-27460 roles: now closing a record set that wasnt being closed 2011-05-12 10:37:33 +08:00
Eloy Lafuente (stronk7) 39d106ee76 weekly release 2.0.3+ 2011-05-11 15:22:32 +02:00
Andrew Davis (andyjdavis) 07373d91a8 MDL-26704 gradebook: added some intelligence to the dates displayed on the user outline activity report 2011-05-10 11:02:22 +08:00
Sam Hemelryk 633fcef536 Merge branch 'MDL-27140_m20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-05-10 09:54:15 +08:00
Eloy Lafuente (stronk7) dde17843e0 MDL-27140 weeks course format - incorrect roll of dates on hidden sections
Credit goes to Nikhil Gupta, big thanks!
2011-05-09 18:17:35 +02:00
Eloy Lafuente (stronk7) 2430319b52 Merge branch 'MDL-27401-m20' of git://github.com/sammarshallou/moodle into MOODLE_20_STABLE 2011-05-09 17:47:47 +02:00
sam marshall adabef8bf6 MDL-27401 Unit test errors in lib/simpletest/testpagelib_moodlepage.php 2011-05-09 11:17:03 +01:00
Andreas Grabs 22ea14df25 MDL-27422 The excel export fails in some conditions. 2011-05-09 17:47:21 +08:00
Sam Hemelryk 6867fc94b7 Merge branch 'MDL-27325_20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-05-09 10:52:22 +08:00
Sam Hemelryk 8385249f5b Merge branch 'MDL-27367-20' of git://github.com/srynot4sale/moodle into MOODLE_20_STABLE 2011-05-09 10:22:20 +08:00
Eloy Lafuente (stronk7) 30dc7311ad Merge branch 'wip-MDL-27400-MOODLE_20_STABLE' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-05-09 02:13:26 +02:00
Eloy Lafuente (stronk7) 9784520acb Merge branch 'MDL-27372_MOODLE_20_STABLE' of git://github.com/nebgor/moodle into MOODLE_20_STABLE 2011-05-09 01:55:39 +02:00
Eloy Lafuente (stronk7) d015c2352f Merge branch 'MDL-27391-m20' of git://github.com/sammarshallou/moodle into MOODLE_20_STABLE 2011-05-09 01:01:44 +02:00
Eloy Lafuente (stronk7) 35fa620a2e MDL-27325 Adding some extreme, but 32bits safe, float tests 2011-05-06 16:07:02 +02:00
Eloy Lafuente (stronk7) 15516e6445 MDL-27325 Now also testing update_record and set_field 2011-05-06 16:07:02 +02:00
Eloy Lafuente (stronk7) 280a641232 MDL-27325 mysql: Avoid some implicit casting from float to varchar/text 2011-05-06 16:07:02 +02:00
Tim Hunt 14dac82376 MDL-27325 New DB unit tests to demonstrate the problem. 2011-05-06 16:07:01 +02:00
Eloy Lafuente (stronk7) 06ede85e1f Moodle 2.0.3 release 2011-05-06 15:09:21 +02:00
Sam Hemelryk 31a43cca97 MDL-27400 Fixed up typo in blocklib.php 2011-05-06 16:29:01 +08:00
Tim Hunt 8ad8b7dba8 MDL-27394 Moodle 2.0 backup and restore may randomise the order of multichoice/numerical/shortanswer answers 2011-05-06 00:18:50 +02:00
sam marshall a09897b4b1 MDL-26778 Completion unit tests broken by earlier change 2011-05-05 12:21:10 +01:00
Aparup Banerjee 5e00f29019 MDL-27372 moved blog comments to end of body of blog entry. we now see the entire blog entry without comments in the way. 2011-05-05 15:29:42 +08:00
Sam Hemelryk 36f0835e72 Merge branch 's9_MDL-27382_dropbox_get_file_fix_20' of github.com:dongsheng/moodle into MOODLE_20_STABLE 2011-05-05 13:26:46 +08:00
Sam Hemelryk 259b9d05f3 Merge branch 's9_MDL-27381_overwrite_dialog_safari_20' of github.com:dongsheng/moodle into MOODLE_20_STABLE 2011-05-05 13:23:22 +08:00
Sam Hemelryk da20cd7b43 Merge branch 's9_MDL-26854_spam_comments_20_2' of git://github.com/dongsheng/moodle into MOODLE_20_STABLE 2011-05-05 11:46:05 +08:00
Dongsheng Cai acb4688d29 MDL-26854 Added comments block lib.php, it contains comments callbacks 2011-05-05 11:25:19 +08:00
Jerome Mouneyrac 471952fe82 MDL-26250 Create a web service function that enrols users to a certain course 2011-05-05 11:00:00 +08:00
Dongsheng Cai 0d738689bd MDL-27381 fixed 'overwrite files' dialog zindex in safari 2011-05-05 10:43:17 +08:00
Sam Hemelryk 7390fdde63 Merge branch 's9_MDL-26854_spam_comments_20_2' of git://github.com/dongsheng/moodle into MOODLE_20_STABLE 2011-05-05 10:42:58 +08:00
Sam Hemelryk 1374c61bb4 Merge branch 'MDL-26838_ratings_bad_data3' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-05-05 10:19:54 +08:00
Dongsheng Cai 98d9209a34 MDL-27382 repository dropbox plugin, fixed bug of
file downloading path
2011-05-05 09:57:34 +08:00
Eloy Lafuente (stronk7) 8351ce1bd0 weekly release 2.0.2+ 2011-05-05 00:37:10 +02:00
Eloy Lafuente (stronk7) b911ab236c Merge branch 'MDL-25594-20' of git://github.com/srynot4sale/moodle into MOODLE_20_STABLE 2011-05-04 16:09:44 +02:00
Dongsheng Cai b4730465e6 MDL-26854 COMMENT
1. added pluginname_comment_validate callback to comments api
2. change permission callback defaults to false
3. Tidied up serveal areas of comments and implemented callback to
ignore system permissions for view (credits to Sam Hemelryk)

AMOS BEGIN
    MOV [modulerejectcomment,error],[callbackrejectcomment,error]
AMOS END
2011-05-04 17:59:19 +08:00
Eloy Lafuente (stronk7) 78cc7bee62 Merge branch 'MDL-26788_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-05-04 11:21:02 +02:00
Dongsheng Cai 5d6eafcf10 MDL-26388 Recent repository plugin should return draft url 2011-05-04 17:03:36 +08:00
Dongsheng Cai 090e19328e MDL-26388 Recent repository plugin should return draft url 2011-05-04 15:48:11 +08:00
Andrew Davis (andyjdavis) 34b5e856b0 MDL-26838 rating: multiple fixes after a review of rating validation code 2011-05-04 15:33:35 +08:00
Sam Hemelryk c44a5d5946 Merge branch 's10_MDL-27330_dropbox_authorization_url_20' of github.com:dongsheng/moodle into MOODLE_20_STABLE 2011-05-04 13:56:59 +08:00
Aaron Barnes b7d7679112 MDL-25594 completion: Remove unused column from query
Which is also a reserved word.
2011-05-04 13:01:27 +12:00
Aaron Barnes 90061a6d95 MDL-26190 completion blocks: Completion blocks shouldn't ever be blank 2011-05-04 12:53:02 +12:00
stabijoh c9c031fc90 MDL-25477 fix for Anomoly theme doesn't display bullets for unordered lists in descriptions or labels 2011-05-03 07:06:55 -04:00
Dongsheng Cai 64a17788aa MDL-27330 repository dropbox plugin
Dropbox changed authorization URL, and added a few error check code
2011-05-03 17:42:57 +08:00
Sam Hemelryk 0baa1eee59 Merged MDL-26388 Fixed whitespace 2011-05-03 16:28:38 +08:00
Sam Hemelryk 9f6eeb4abf Merged MDL-25805 Renamed property and function to be a little more descriptive 2011-05-03 15:43:20 +08:00
Sam Hemelryk 6a48b42ae8 Merge branch 'MDL-25805_MOODLE_20_STABLE' of git://github.com/nebgor/moodle into MOODLE_20_STABLE 2011-05-03 15:42:26 +08:00
Sam Hemelryk 2dd90f136c Merge branch 'MDL-26628' of git://github.com/srynot4sale/moodle into MOODLE_20_STABLE 2011-05-03 11:00:15 +08:00
Sam Hemelryk e6647397b9 Merged MDL-27251 Fixed up whitespace, Fixed broken string, reworded new strings 2011-05-03 10:54:44 +08:00
Aparup Banerjee 07fa10d725 MDL-25840 blog - fixed broken image file image attachment display 2011-05-03 01:14:16 +02:00
Eloy Lafuente (stronk7) 98032d512d Merge branch 'MDL-27293-customlang-timeout_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-05-02 16:19:40 +02:00
Aparup Banerjee 389235fb00 MDL-25805 Roles propagated ugly hack for parent seeing child activities into navigation lib to display nav node. 2011-05-02 20:21:51 +08:00
Eloy Lafuente (stronk7) 656237dd55 Merge branch 'MDL-26714_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-05-02 12:26:22 +02:00
Sam Hemelryk e3cc5b1a7f Merged changes and fixed whitespace issues for MDL-23188 2011-05-02 15:00:54 +08:00
Sam Hemelryk 0742ea86b2 Merge branch 'MDL-26955-themedir-plugindirectory_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-05-02 14:23:06 +08:00
Sam Hemelryk 41f79b5c07 Merge branch 'MDL-27116-themedir-config_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-05-02 14:12:45 +08:00
Sam Hemelryk ed85c0acd2 Merge branch 'MDL-27155_20' of git://github.com/timhunt/moodle into MOODLE_20_STABLE 2011-05-02 14:09:26 +08:00
Sam Hemelryk 9c39028179 Merge branch 'MDL-27246-cutomlang-version_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-05-02 12:14:05 +08:00
Dongsheng Cai 9fb4a6300b MDL-26388, pop up a dialog when attaching a file already being used in draft area. 2011-05-02 10:27:50 +08:00
Tim Hunt 44c9dc6e7b MDL-27340 tablelib.php fix a notice when is false. 2011-05-01 17:37:54 +01:00
Andrew Davis (andyjdavis) 4af7c9d188 MDL-26838 rating: remove logged in users ability to sidestep rating validity checks 2011-05-01 18:44:12 +08:00
Tim Hunt 847dee60ce MDL-27155 qtype_numerical problem with GIFT import. 2011-04-29 14:16:10 +01:00
stabijoh b7551bdf23 MDL-27118 Text in a highlighted topic box is white on white in the Leatherbound theme. 2011-04-29 07:44:56 -04:00
Rossiani Wijaya e0be8fd6a3 MDL-26788 - grading in lesson containing essays 2011-04-29 18:17:36 +08:00
Tim Hunt 55e03d1233 MDL-26714 qtype_multianswer regression from the previous commit for numerical subquestions. 2011-04-28 23:32:14 +01:00
stabijoh e391f907af MDL-23188 implement custom menu where possible in core themes, 20 stable version 2011-04-27 08:44:53 -04:00
David Mudrak bef867a96c MDL-26955 get_plugin_directory() respects $CFG->themedir
If $CFG->themedir is set (it is not usually) and the given theme is not
found in the standard location, then it is expected to be in the custom
$CFG->themedir directory.

Credit goes to Urs Hunkler for the idea of the patch.
2011-04-27 14:03:53 +02:00
David Mudrak 4207d47742 MDL-27116 theme_config::find_theme_location() respects $CFG->themedir
Credit goes to Jai Gupta for the idea of the patch.
2011-04-27 14:03:10 +02:00
David Mudrak bd7193c7ac MDL-27293 report customlang has extra execution time and displays a progress bar during the checkout
Initial checkout of strings into the translator table may take a long time. The
maximum execution time is increased to one hour and a progress bar is
displayed so the user is informed on what is going on.
2011-04-27 14:01:59 +02:00
David Mudrak 77e4a16c4f MDL-27246 customlang report stores the versions in a char field rather than integer 2011-04-27 14:01:38 +02:00
Petr Skoda 7daba2713e weekly release 2.0.2+ 2011-04-27 12:08:04 +02:00
Aaron Barnes 03b1be3005 MDL-26628 completion report: Fix hard coded strings in Completion report 2011-04-27 15:33:45 +12:00
Aparup Banerjee 5c8511ecf7 MDL-27251 Files API - added timeout re-calculation as an optional argument. added setting for minimum Kbps for large files fetched from internet where the passed in timeout maybe too low.
allowed turning off the http HEAD request timeout calculation with zero (or negative) bitrate

	This was added in to allow servers that have a problem with
	HEAD requests to carry on with the given timeout without re-calculations.
	See PULL-651 for the discussion.

	the optional argument to force recalculation of timeout has been forced within scorm/locallib.php

	timeout re-calculation only increments timeout.
2011-04-27 11:02:21 +08:00
Eloy Lafuente (stronk7) 52435228c5 Merge branch 'w17_MDL-27253_m20_swfsize' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-04-26 11:15:01 +02:00
Eloy Lafuente (stronk7) c9dc3e5564 Merge branch 'w17_MDL-27263_m20_loggedintypo' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-04-26 11:06:31 +02:00
Petr Skoda ffaf18a8c1 MDL-27253 add default swf size and allow #d=100x50 URL resizing in mod/url 2011-04-21 20:36:06 +02:00
Petr Skoda f5fddc6081 MDL-27263 fix already logged in error message typo 2011-04-21 20:35:33 +02:00
stabijoh 9d5a4e2b7c MDL-27252 themes, fix for nonzero current highlight 2011-04-20 13:19:12 -04:00
Eloy Lafuente (stronk7) ba9103b2c6 weekly release 2.0.2+ 2011-04-20 13:36:41 +02:00
Eloy Lafuente (stronk7) 79196c9ed5 Fix permissions 2011-04-20 11:09:11 +02:00
Aparup Banerjee a572cfe5bd MDL-26580 adding precautionary upgrade_set_timeout() calls to some loops which may timeout in very edge cases 2011-04-19 17:58:03 +08:00
Aparup Banerjee 92d7776478 MDL-26580 adding some upgrade_set_timeout() calls to 2010080901 upgrade block, upgrades on questions were timing out 2011-04-19 17:57:56 +08:00
Sam Hemelryk 2715f96932 Merged with small fix branch MDL-26516_m20_calevent_wip4 from git://github.com/rwijaya/moodle.git 2011-04-19 16:29:49 +08:00
John Stabinger 6919d9f790 Fixes for MDL-27138, add correct page headers and footer 2011-04-19 11:03:33 +08:00
Sam Hemelryk 8be0517692 MDL-26835 Fixed up styles being used for suspended users in the grader report. 2011-04-19 10:47:14 +08:00
Sam Hemelryk a4b65c11b9 Merged with conflict resolution branch MDL-26835_MASTER_grader_highlight_suspended_users from git://github.com/andyjdavis/moodle.git 2011-04-19 10:46:54 +08:00
Sam Hemelryk 64e711f04b MDL-25999 Fixed URL bug with admin bookmark changes 2011-04-19 10:26:46 +08:00
Sam Hemelryk e6cf40de78 Merge branch 'MDL-25999_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-04-19 10:26:30 +08:00
Rossiani Wijaya 174f5a0189 MDL-26516: fix calendar event type (user overides) 2011-04-18 18:12:25 +08:00
Eloy Lafuente (stronk7) dd56fd7c64 MDL-26167 lib/form: minor coding tweaks 2011-04-18 11:45:02 +02:00
Eloy Lafuente (stronk7) 436f83f8ff Merge branch 'MDL-26167-stable' of git://github.com/agwells/moodle into MOODLE_20_STABLE 2011-04-18 11:44:02 +02:00
Rossiani Wijaya d03f904759 MDL-25999: update Admin Bookmarks block to work properly in 2.0 2011-04-18 17:23:36 +08:00
Eloy Lafuente (stronk7) 15a6af91f5 Merge branch 'w16_MDL-17344_m20_uploadprof' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-04-18 11:07:42 +02:00
Andrew Davis (andyjdavis) 0a23dec07a MDL-26835 gradebook: grader report now marks suspended students 2011-04-18 14:25:16 +08:00
Sam Hemelryk 6f8081bef4 MDL-26958 PULL-675 Merged changes and removed border colour style 2011-04-18 10:57:27 +08:00
Andrew Davis (andyjdavis) c643d3ae06 MDL-27153 gradebook - fixed an SQL error in grade export 2011-04-18 02:17:09 +02:00
Eloy Lafuente (stronk7) 507ccf1c4b MDL-27148 whitespace fix 2011-04-18 01:47:11 +02:00
Eloy Lafuente (stronk7) 60bc533ee8 Merge branch 'w16_MDL-27148_m20_stringinc' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-04-18 01:44:10 +02:00
Eloy Lafuente (stronk7) 42f2b8d0dd Merge branch 'w16_MDL-27217_m20_tinyset' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-04-18 01:13:49 +02:00
Eloy Lafuente (stronk7) 84047d1fc9 Merge branch 'w16_MDL-27220_m20_tagprofile' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-04-18 01:08:10 +02:00
Petr Skoda b79ac7e0d6 Merge branch 'm20_MDL-26880_SCORM2004_tracking_fix' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-04-17 17:16:48 +02:00
Petr Skoda 241ceba38c Merge branch 'm20_MDL-24734_gradefix' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-04-17 17:09:59 +02:00
Petr Skoda 8e49e0833c Merge branch 'm20_MDL-18392_slash_cleanup' of git://github.com/danmarsden/moodle into MOODLE_20_STABLE 2011-04-17 17:04:09 +02:00
Petr Skoda f6bf9c932d Merge branch 'MDL-27198-m20' of git://github.com/sammarshallou/moodle into MOODLE_20_STABLE 2011-04-17 16:40:10 +02:00
Petr Skoda 1fb2369b09 Merge branch 'wip-MDL-26013-MOODLE_20_STABLE' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-04-17 16:22:34 +02:00
Petr Skoda 4de0925820 Merge branch 'wip-MDL-27145-MOODLE_20_STABLE' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-04-17 16:13:08 +02:00
Petr Skoda 81f2a1686a MDL-27217 use correct editor name in editor settings page
Credit goes to Franck Bellemain.
2011-04-17 11:18:00 +02:00
Petr Skoda 5f509554a5 MDL-27220 add missing tag lib include 2011-04-17 11:07:57 +02:00
Dan Marsden edd5d0693d SCORM MDL-24734 - fix display of grade information on view.php page - also fixes some XHTML in the same function. 2011-04-16 19:32:11 +12:00
Mary Evans d59a75a841 MDL-26958 Core Themes:adding css patch to base theme so hidden elements are dimmed
This patch also fixes MDL-27160 - the same bug which affects many CORE themes like Binarus and Nonzeo. This patch also a small element of a patch supplied by Thomas Lake in Tracker MDL-26958 (most of which already exists in Base theme).
2011-04-15 00:49:22 +01:00
Aaron Wells 9b482d1cbe MDL-26167 lib/form: Altering Javascript so that "disabledIf" will disable the "Choose" button for a filepicker 2011-04-15 10:02:34 +12:00
sam marshall ca090f3262 MDL-27198 Accessibility: For labels, completion/editing icons must appear after content 2011-04-14 17:28:53 +01:00
Petr Skoda 12db898084 MDL-27148 use new get_in_or_equal() param prefix instead of start 2011-04-14 15:13:28 +02:00
Petr Skoda c79345c0f0 MDL-27148 fix unit tests to accept arbitrary named params format from get_in_or_equal 2011-04-14 15:12:21 +02:00
Petr Skoda d691571218 MDL-27148 use static counter instead of incrementing parameter name 2011-04-14 14:44:50 +02:00
Petr Skoda 4e1bb6e10c MDL-17344 fix case and unicode related profile field issues in user upload
This fixes issue with uppercase and non-ascii profile fields and closes the iterator properly when field not found. Please note that profile fields with upper case letters must be specified exactly in CSV file headers. includes improved docs and parameter typo fix (credit for the parameter typo discovery goes to Aparup Banerjee)
2011-04-14 13:18:42 +02:00
Nadav Kavalerchik a7e920fbfb CSS MDL-26013 Fixed several display bugs when using right to left languages 2011-04-14 15:59:03 +08:00
Matteo Scaramuccia 7a725d6b59 PULL-498 - Fixed potential issues about UTF-8 and multilang filter by adopting pure ASCII chars, the SCO primary key 2011-04-14 10:26:41 +12:00
Matteo Scaramuccia 489c6ef357 MDL-26880 - Fixed missing of activity id
Moved errorCode as global, to allow GetLastError() to work
Applied MDL-17891 mechanism against AJAX failures, "true if true, false otherwise"
Limited what added to log when in debug, to be compliant with mdl_log.action as VARCHAR(40)
2011-04-14 10:26:18 +12:00
Dan Marsden dbb6157aa1 Merge remote branch 'moodle/MOODLE_20_STABLE' into m20_MDL-18392_slash_cleanup 2011-04-14 09:15:17 +12:00
Petr Skoda 50467e50c9 weekly release 2.0.2+ 2011-04-13 22:08:30 +02:00
Petr Skoda 85a91fb98e Merge branch 'MDL-24355_emergency_20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-04-13 16:49:29 +02:00
Eloy Lafuente (stronk7) 75454e2567 MDL-24355 tags - fix correlation sql to be cross-db 2011-04-13 16:37:37 +02:00
Petr Skoda 06c09f30e3 Revert "MDL-25840 fixed image files link not rendered correctly when attached as file (instead of inline)."
The reason is failed testing. This reverts commit 3d0e3ade75.
2011-04-13 15:07:22 +02:00
Dan Marsden 26daa23d9d SCORM MDL-18392 - remove old call to stripslashes 2011-04-13 20:00:59 +12:00
Matteo Scaramuccia 74a2ee73ed SCORM MDL-18392 MDL-26282 - Fixed calls to add/strip slashes 2011-04-13 19:58:44 +12:00
Petr Skoda fca41d2589 MDL-25718 fix incorrect 'no grade' test and improve coding style 2011-04-12 10:07:05 +02:00
Petr Skoda 6de6a45a10 Merge branch 'MDL-25718_enrol_grades_alternative2' of git://github.com/andyjdavis/moodle into MOODLE_20_STABLE 2011-04-12 09:55:28 +02:00
Sam Hemelryk 0f1fac1f1f form-dateselector MDL-27145 Fixed up error resulting from incorrectly required 'optional' argument on create event 2011-04-12 14:15:51 +08:00
andyjdavis 692134ecd4 enrol MDL-25718 added ability to recover grades when enrolling users 2011-04-12 11:05:02 +08:00
Eloy Lafuente (stronk7) d7706bac2c Merge branch 'MDL-26778-m20' of git://github.com/sammarshallou/moodle into MOODLE_20_STABLE 2011-04-11 17:54:21 +02:00
Eloy Lafuente (stronk7) 391e054c03 Merge branch 'w15_MDL-26577_m20_groupscleanup' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-04-11 16:02:10 +02:00
Eloy Lafuente (stronk7) 71f2316fe6 Merge branch 'w15_MDL-26805_m20_userpol' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-04-11 15:18:31 +02:00
Petr Skoda 16d610019a Merge branch 'wip-MDL-27024-MOODLE_20_STABLE' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-04-11 14:13:34 +02:00
Petr Skoda 4f5791da64 Merge branch 'wip-MDL-26599-MOODLE_20_STABLE' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-04-11 14:10:38 +02:00
sam marshall c5e3a242b1 MDL-26778 Change to completion should immediately affect nav block
Includes change so that updating completion resets the cache, and a debugging
warning if any module calls the completion viewed thing after it's already
printed navigation (which will mean navigation obviously doesn't update right
away). All existing modules that currently update after printing navigation
were updated.
2011-04-11 12:40:50 +01:00
Petr Skoda 13ad1eaf37 Merge branch 'MDL-25840_m20' of git://github.com/nebgor/moodle into MOODLE_20_STABLE 2011-04-11 13:30:44 +02:00
Petr Skoda 7ca448fa83 MDL-26805 cleanup default role selections
Frontpage role selection now allows only guest and frontpage roles. Default forntpage role is selected duuring install. Unused nodefaultuserrolelists option was removed completely. Coding style improvements.
2011-04-11 13:08:35 +02:00
Eloy Lafuente (stronk7) 37efb4f1ee Merge branch 's9_MDL-27098_filemanager_strings_20' of git://github.com/dongsheng/moodle into MOODLE_20_STABLE 2011-04-11 11:20:31 +02:00
Dongsheng Cai 81bd2292bc MDL-27098
1. Fixed add file language string
2. Fixed hard-coded 'moving' string
3. Fixed hard-coded 'Files' string
2011-04-11 17:10:30 +08:00
Eloy Lafuente (stronk7) 8fa13d155d Merge branch 'w15_MDL-25826_m20_htmlpurifier' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-04-11 11:08:23 +02:00
Sam Hemelryk 465846f082 Merge branch 'MDL-25746_m20' of git://github.com/nebgor/moodle into MOODLE_20_STABLE 2011-04-11 15:38:48 +08:00
Aparup Banerjee f68815ffcf MDL-25746 fixed db tempate page layout to prevent hidden content layers 2011-04-11 15:16:54 +08:00
Sam Hemelryk 67b5d74b2c Merge branch 'MDL-27034_xhprof_table_sql_20' of git://github.com/stronk7/moodle into MOODLE_20_STABLE 2011-04-11 14:34:57 +08:00
Aparup Banerjee 3d0e3ade75 MDL-25840 fixed image files link not rendered correctly when attached as file (instead of inline). 2011-04-11 14:24:22 +08:00
Sam Hemelryk 7d1fb2f6ec Merged branch 'MDL-26185_m20' of git://github.com/andyjdavis/moodle.git and fixed conflicts 2011-04-11 11:54:50 +08:00
Sam Hemelryk 227e54d65a Merge branch 'MDL-27063' of git://github.com/MaryE/moodle into MOODLE_20_STABLE 2011-04-11 11:38:21 +08:00
Sam Hemelryk ee6181b1e7 comment MDL-27024 Removed last check within comment.js for block_comment env 2011-04-11 10:43:25 +08:00
Sam Hemelryk 3962c89bbf comment MDL-27024 Fixed bug that arose when a comment section didnt require pagination but the JS still looked for pageination HTML in the page 2011-04-11 10:43:21 +08:00
Sam Hemelryk 59137c2c5b comment MDL-27024 Removed last reference to the comment block within the comment API and used the options properly 2011-04-11 10:43:17 +08:00
Sam Hemelryk b83e494d6f comment MDL-27024 Fixed up whitespace issues 2011-04-11 10:43:12 +08:00
Sam Hemelryk 3b2164bdca comment MDL-27024 made notoggle and autoload into proper options to remove comment block conditions from comment API 2011-04-11 10:43:06 +08:00
Sam Hemelryk aa54d70440 comment MDL-27024 Cleaned up HTML output in comment class 2011-04-11 10:43:01 +08:00
Sam Hemelryk d2d4bccec1 comment MDL-27024 Cleaned up use of undefined property $this->link 2011-04-11 10:42:56 +08:00
Sam Hemelryk f3a3c59f48 mod-lesson MDL-26599 Fixed echo causing incorrect nesting. 2011-04-11 10:27:58 +08:00
Eloy Lafuente (stronk7) 3d62a46b26 Merge branch 'w15_MDL-27094_m20_assval' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-04-11 01:32:15 +02:00
Eloy Lafuente (stronk7) 9aacfedb22 Merge branch 'w15_MDL-27007_m20_userupload' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-04-11 01:23:04 +02:00
Eloy Lafuente (stronk7) 12b734434b Merge branch 'w15_MDL-26910_m20_httpd' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-04-11 00:17:23 +02:00
Eloy Lafuente (stronk7) f9068e531c Merge branch 'w15_MDL-27121_m20_phpreq' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-04-10 23:55:11 +02:00
Eloy Lafuente (stronk7) 96506c474a Merge branch 'MDL-26319_MOODLE_20_STABLE' of git://github.com/nebgor/moodle into MOODLE_20_STABLE 2011-04-10 23:49:59 +02:00
Tony Levi 0d66e33da5 MDL-27084: mod/feedback fix bad syntax in database query 2011-04-10 23:43:56 +02:00
Petr Skoda 934fa3ed6c MDL-27094 fix incorrect assignment form validation method name
Credit goes to H. Hanna
2011-04-10 21:01:53 +02:00
Petr Skoda 6743d6c520 MDL-26910 add HTTPD server name whitelisting 2011-04-10 13:59:17 +02:00
Petr Skoda cf76e10e4a MDL-26577 fix several groups and groupings issues
The current group in verified on each page which prevents problems when group settings are changed. The default group for course level is now using correct grouping id which solves problems when activity and course are using different grouping. The grouping is now displayed in group selector if user has access to all groups.
2011-04-10 13:28:02 +02:00
Mary Evans c800e31213 MDL-27063 tt styled incorrectly in canvas theme 2011-04-10 00:48:35 +01:00
Petr Skoda 23580ddacb MDL-27121 fix incorrect check_moodle_environment() version parameter
This prevents Moodle 2.0 from using environment info for 2.1 in the installer and CLI upgrade.
2011-04-09 17:42:53 +02:00
Petr Skoda 827fcdb347 MDL-27007 fix incorrectly suspended user enrolment when uploading users
This bug surfaced after the recent change in enrol API, credit goes to Chaim Schendowich and Micky Fokken.
2011-04-09 12:09:53 +02:00
Petr Skoda 60aaf1dc77 MDL-25826 add more HTMLPurifier integration tests 2011-04-09 11:51:55 +02:00
Petr Skoda fd8fa6f9d0 MDL-25826 integrate HTMLPurifier 4.3.0 and improve performance
The new HTMLPurifier finally caches the schema properly eliminating both extra CPU cycles and disk writes. The repeated dir exists tests might cause problems on NFS shares.
2011-04-09 11:51:49 +02:00
Petr Skoda 8adf19eda8 MDL-25826 import HTMLPurifier 4.3.0 2011-04-09 11:51:35 +02:00
Andrew Davis (andyjdavis) a6e29ac6a3 message MDL-26185 fixed the logic around email addy in user profile Vs in messaging preferences 2011-04-07 15:39:03 +08:00
Aparup Banerjee 52e184904f MDL-26319 moved cancel_backup() from backup_ui to cancel_process() in base_ui and renamed callers. fix for method inheritance in restore_ui. 2011-04-07 10:40:45 +08:00
Eloy Lafuente (stronk7) b8d80c062e MDL-27034 profiling - xhprof_table_sql improvement 2011-04-07 00:46:33 +02:00
Petr Skoda eb9d692f8b weekly release 2.0.2+ 2011-04-06 14:55:57 +02:00
Petr Skoda a805d653d1 MDL-26804 fix undefined CFG langcache property during install
Sorry, I have committed fix for this in master incorrectly with MDL-26914.
2011-04-06 10:56:30 +02:00
Sam Hemelryk fe4a0cfe63 PULL-574 MDL-26185 Reverted changes due failed testing + review 2011-04-06 16:35:24 +08:00
Petr Skoda d0e3447e43 revert MDL-26577 added session cleaning to groups_get_activity_group() that fixes an issue with dirty session data. refactored session cleaning into one function, added caching to reduce queries.
(reverse-merged from commit 77335e76e9) This change was causing fatal errors on the course level, I am going to fix it myself.
2011-04-05 18:35:01 +02:00
Sam Hemelryk f046221272 messaging MDL-26185 Last minute fix of bug during integration, empty user preference causing error 2011-04-05 16:53:03 +08:00
Petr Skoda 42a50a0a45 Merge branch 'MDL-26577_groups_api_refactor_take2_m20' of git://github.com/nebgor/moodle into MOODLE_20_STABLE 2011-04-05 10:21:21 +02:00
Aparup Banerjee 77335e76e9 MDL-26577 added session cleaning to groups_get_activity_group() that fixes an issue with dirty session data. refactored session cleaning into one function, added caching to reduce queries. 2011-04-05 12:23:56 +08:00
Eloy Lafuente (stronk7) ddf3e875f3 Merge branch 'wip-MDL-26560-MOODLE_20_STABLE' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-04-04 23:16:53 +02:00
Eloy Lafuente (stronk7) 91fa7abf3d Merge branch 'wip-MDL-26858-MOODLE_20_STABLE' of git://github.com/samhemelryk/moodle into MOODLE_20_STABLE 2011-04-04 21:50:22 +02:00
Eloy Lafuente (stronk7) b060e5b0b8 Merge branch 'MDL-26931-blog-post-order_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-04-04 12:02:17 +02:00
Andrew Davis (andyjdavis) f9c8746704 gradebook MDL-20946 fixed average calculation where users have multiple gradeable roles 2011-04-04 11:27:09 +02:00
Petr Skoda c629aeabe3 MDL-25651 fix incorrect indentation 2011-04-04 10:01:30 +02:00
Petr Skoda 27614a5e5d Merge branch 'wip-MDL-25651_MOODLE_20_STABLE' of git://github.com/jennymgray/moodle into MOODLE_20_STABLE 2011-04-04 09:59:04 +02:00
Sam Hemelryk ba32fc0042 enrolments MDL-26560 Fixed panel.user bug with role assignments dialogue 2011-04-04 14:50:15 +08:00
Sam Hemelryk 87b05ba3e0 enrolments MDL-26858 Added finish user enrolments button to JS dialogue 2011-04-04 14:38:23 +08:00
Sam Hemelryk 728f3c9d08 Merge branch 'MDL-26185_m20' of git://github.com/rwijaya/moodle into MOODLE_20_STABLE 2011-04-04 13:21:24 +08:00
Mary Evans d7dd177eb4 Fix for MDL-27016 added min-width 2011-04-04 13:10:06 +08:00
Rossiani Wijaya 507de745e3 MDL-26185: simplify the logic of email message output and removing email cache 2011-04-01 11:12:54 +08:00
Jenny Gray bf8ff4889b MDL-25651 add capability check to my private files navigation link 2011-03-31 14:54:36 +01:00
Ankit Agarwal f9112bda35 MDL-26931 Order blog entries by the creation date 2011-03-31 11:56:53 +02:00
Tim Hunt ba63612bfa MDL-27035 table_sql forgets to set countparams. 2011-03-30 20:26:34 +01:00
Petr Skoda 408612d111 updating digits to match the .2 release 2011-03-30 18:01:09 +02:00
Petr Skoda 60e837038a weekly release 2011-03-30 14:29:56 +02:00
Petr Skoda 4cb05cea9d Merge branch 'MDL-26964-moodle_url-anchor_20_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_20_STABLE 2011-03-29 10:00:04 +02:00
Adam Olley 0960f2f417 MDL-27009: Fix role group by statement for statistics 2011-03-29 11:46:17 +10:30
Eloy Lafuente (stronk7) 09c1e72a56 Merge branch 'MDL-26744-metasyncstring_20_STABLE' of git://github.com/wildgirl/moodle into MOODLE_20_STABLE 2011-03-28 23:56:08 +02:00
Eloy Lafuente (stronk7) d2455301b7 Merge branch 'w13_MDL-22733_20_youtubeiframe' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-03-28 23:53:40 +02:00
Eloy Lafuente (stronk7) 1be2b904ab Merge branch 'w13_MDL-26909_20_mediatests' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-03-28 23:30:35 +02:00
Eloy Lafuente (stronk7) 337817e669 Merge branch 'w13_MDL-26987_20_sclean' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-03-28 21:59:21 +02:00
Eloy Lafuente (stronk7) b17a3a5591 Merge branch 'w13_MDL-26913_20_sitecreated' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-03-28 20:10:57 +02:00
Eloy Lafuente (stronk7) c44c552efa Merge branch 'w13_MDL-26951_20_archetypes' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-03-28 19:40:35 +02:00
Eloy Lafuente (stronk7) faa297ce6f Merge branch 'w13_MDL-26991_20_legacy' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-03-28 19:26:28 +02:00
Eloy Lafuente (stronk7) b6225c0f2f Merge branch 'w13_MDL-26966_20_urlparsing' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-03-28 19:07:00 +02:00
Eloy Lafuente (stronk7) 50496af78b Merge branch 'w13_MDL-26985_20_branching' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-03-28 18:41:22 +02:00
Tim Hunt 8fc52ccf46 MDL-26425 tablelib ability for table_sql to add a class to the row based on the data. 2011-03-28 17:12:26 +02:00
Tim Hunt 9f9324f408 MDL-26425 tablelib better validation of the sort code, also some cleanup.
You may think that the extra validation is unnecessary, since the sort fields are already validated when the URL parameters are parsed, however that overlooks an important point. There may be other options that affect which columns are in the SQL, for example the quiz show individual question grades setting. These other options can cause a column that was in the table, and being sorted on, to disappear. Therefore, it is necessary to re-validate the sort columns when they are used, to make sure they are still present, otherwise you can get ORDER BY sql that refers to non-existant columns, which then causes DB errors.
2011-03-28 17:10:53 +02:00
Helen Foster d4dc367a5b MDL-26744 enrol meta lang string improvement thanks to Ray Lawrence 2011-03-28 17:07:55 +02:00
Eloy Lafuente (stronk7) 3ede344b5c Merge branch 'w13_MDL-26990_20_missingrebuild' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-03-28 16:35:18 +02:00
Petr Skoda 5c686792c6 Merge branch 'MDL-26335' of github.com:mouneyrac/moodle into MOODLE_20_STABLE 2011-03-28 15:13:47 +02:00
David Mudrak 91a4b3bd3e MDL-26804 core_string_manager::get_list_of_translations() can use a cache again
This patch reimplements the internal cache that was used to store the
list of available translations in Moodle 1.x. By default, the method
get_list_of_translations() still uses the file
moodledata/cache/languages to store the list of available translations.
The location of that file can be redefined in config.php. The internal
format of the cache file is JSON now (used to be a plain text list).

The patch also fixes a usage of the global $CFG in translation_exists()
methods where the internal property should be used instead.
2011-03-28 14:49:17 +02:00
Dongsheng Cai 1a6a1487f4 MOD-WIKI MDL-26213
1. Rewrite the image urls in diff.php and viewdiff.php
2. Fxied image urls in search.php
3. Add modcontext variable to avoid using duplicated
get_context_instance calls
2011-03-28 11:50:37 +02:00
Jenny Gray a5286ae4cc MDL-26932 full url path for toggle completion form POST 2011-03-28 11:04:39 +02:00
Dan Marsden 5b97bff526 Plagiarism MDL-26939 - missing return 2011-03-28 10:53:13 +02:00
Dongsheng Cai 1c4873ba1b MDL-26916, MDL-26917
1. Fix filepicker paging issue MDL-26916
2. Highlight view as icon button by default MDL-26917
2011-03-28 16:13:27 +08:00
Dan Marsden 9a8f8cea49 Forum Overview MDL-26957 add classes to allow better control by theme 2011-03-28 16:11:30 +08:00
stabijoh c37f03543b Revised fix for MDL-26906, magazine and formal white secure browser quiz window 2011-03-28 16:04:21 +08:00
Andrew Davis (andyjdavis) cd4ca97611 message MDL-26077 fixed up a problem with html tags being stripped out 2011-03-28 16:00:36 +08:00
Myles Carrick 77bfc4ce0f MDL-26798 encode file path in dropbox repository plugin, credits to Myles Carrick 2011-03-28 15:57:38 +08:00
Sam Hemelryk 13c53a4a2e Merge branch 'w13_MDL-26992_20_uploadtemplates' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-03-28 14:33:27 +08:00
Sam Hemelryk d3796a2c61 Merge branch 'w13_MDL-26989_20_enrolroles' of git://github.com/skodak/moodle into MOODLE_20_STABLE 2011-03-28 14:17:08 +08:00
Petr Skoda 7bb8ae5911 MDL-26985 new Moodle 2.1 requirements
For now only extra PHP 5.3.2 requirement compared to 2.0.
2011-03-26 22:03:00 +01:00
David Mudrak dbe6d9f821 MDL-26964 URL anchor support for single_button and single_select
If the single_button or single_select use HTTP method 'get' then the
eventual anchor part of the URL is used.
2011-03-24 22:15:47 +01:00
David Mudrak 4927443761 MDL-26964 URL returned by moodle_url::out_omit_querystring() may contain the anchor part 2011-03-24 22:15:47 +01:00
1916 changed files with 68032 additions and 141638 deletions
+57 -4
View File
@@ -12,6 +12,8 @@
$hide = optional_param('hide', 0, PARAM_INT);
$show = optional_param('show', 0, PARAM_INT);
$delete = optional_param('delete', 0, PARAM_INT);
$unprotect = optional_param('unprotect', 0, PARAM_INT);
$protect = optional_param('protect', 0, PARAM_INT);
/// Print headings
@@ -24,6 +26,9 @@
$strcourses = get_string('blockinstances', 'admin');
$strname = get_string('name');
$strshowblockcourse = get_string('showblockcourse');
$strprotecthdr = get_string('blockprotect', 'admin'). $OUTPUT->help_icon('blockprotect','admin');
$strprotect = get_string('blockprotect', 'admin');
$strunprotect = get_string('blockunprotect', 'admin');
/// If data submitted, then process and store.
@@ -43,6 +48,36 @@
admin_get_root(true, false); // settings not required - only pages
}
if (!isset($CFG->undeletableblocktypes) || (!is_array($CFG->undeletableblocktypes) && !is_string($CFG->undeletableblocktypes))) {
$undeletableblocktypes = array('navigation', 'settings');
} else if (is_string($CFG->undeletableblocktypes)) {
$undeletableblocktypes = explode(',', $CFG->undeletableblocktypes);
} else {
$undeletableblocktypes = $CFG->undeletableblocktypes;
}
if (!empty($protect) && confirm_sesskey()) {
if (!$block = $DB->get_record('block', array('id'=>$protect))) {
print_error('blockdoesnotexist', 'error');
}
if (!in_array($block->name, $undeletableblocktypes)) {
$undeletableblocktypes[] = $block->name;
set_config('undeletableblocktypes', implode(',', $undeletableblocktypes));
}
admin_get_root(true, false); // settings not required - only pages
}
if (!empty($unprotect) && confirm_sesskey()) {
if (!$block = $DB->get_record('block', array('id'=>$unprotect))) {
print_error('blockdoesnotexist', 'error');
}
if (in_array($block->name, $undeletableblocktypes)) {
$undeletableblocktypes = array_diff($undeletableblocktypes, array($block->name));
set_config('undeletableblocktypes', implode(',', $undeletableblocktypes));
}
admin_get_root(true, false); // settings not required - only pages
}
if (!empty($delete) && confirm_sesskey()) {
echo $OUTPUT->header();
echo $OUTPUT->heading($strmanageblocks);
@@ -114,11 +149,12 @@
$table = new flexible_table('admin-blocks-compatible');
$table->define_columns(array('name', 'instances', 'version', 'hideshow', 'delete', 'settings'));
$table->define_headers(array($strname, $strcourses, $strversion, $strhide.'/'.$strshow, $strdelete, $strsettings));
$table->define_columns(array('name', 'instances', 'version', 'hideshow', 'undeletable', 'delete', 'settings'));
$table->define_headers(array($strname, $strcourses, $strversion, $strhide.'/'.$strshow, $strprotecthdr, $strdelete, $strsettings));
$table->define_baseurl($CFG->wwwroot.'/'.$CFG->admin.'/blocks.php');
$table->set_attribute('class', 'compatibleblockstable blockstable generaltable');
$table->setup();
$tablerows = array();
foreach ($blocks as $blockid=>$block) {
$blockname = $block->name;
@@ -191,15 +227,32 @@
$version = "$block->version ($plugin->version)";
}
if (!$blockobject) {
// ignore
$undeletable = '';
} else if (in_array($blockname, $undeletableblocktypes)) {
$undeletable = '<a href="blocks.php?unprotect='.$blockid.'&amp;sesskey='.sesskey().'" title="'.$strunprotect.'">'.
'<img src="'.$OUTPUT->pix_url('t/unlock') . '" class="icon" alt="'.$strunprotect.'" /></a>';
} else {
$undeletable = '<a href="blocks.php?protect='.$blockid.'&amp;sesskey='.sesskey().'" title="'.$strprotect.'">'.
'<img src="'.$OUTPUT->pix_url('t/unlock_gray') . '" class="icon" alt="'.$strprotect.'" /></a>';
}
$table->add_data(array(
$row = array(
'<span'.$class.'>'.$strblockname.'</span>',
$blocklist,
'<span'.$class.'>'.$version.'</span>',
$visible,
$undeletable,
$delete,
$settings
));
);
$tablerows[] = array(strip_tags($strblockname), $row); // first element will be used for sorting
}
textlib_get_instance()->asort($tablerows);
foreach ($tablerows as $row) {
$table->add_data($row[1]);
}
$table->print_html();
+19 -10
View File
@@ -376,16 +376,25 @@ if ($interactive) {
}
}
// download required lang packs
if ($CFG->lang !== 'en') {
$installer = new lang_installer($CFG->lang);
$results = $installer->run();
foreach ($results as $langcode => $langstatus) {
if ($langstatus === lang_installer::RESULT_DOWNLOADERROR) {
$a = new stdClass();
$a->url = $installer->lang_pack_url($langcode);
$a->dest = $CFG->dataroot.'/lang';
cli_problem(get_string('remotedownloaderror', 'error', $a));
//download lang pack with optional notification
if ($CFG->lang != 'en') {
if ($cd = new component_installer('http://download.moodle.org', 'langpack/2.0', $CFG->lang.'.zip', 'languages.md5', 'lang')) {
if ($cd->install() == COMPONENT_ERROR) {
if ($cd->get_error() == 'remotedownloaderror') {
$a = new stdClass();
$a->url = 'http://download.moodle.org/langpack/2.0/'.$CFG->lang.'.zip';
$a->dest = $CFG->dataroot.'/lang';
cli_problem(get_string($cd->get_error(), 'error', $a));
} else {
cli_problem(get_string($cd->get_error(), 'error'));
}
} else {
// install parent lang if defined
if ($parentlang = get_parent_language()) {
if ($cd = new component_installer('http://download.moodle.org', 'langpack/2.0', $parentlang.'.zip', 'languages.md5', 'lang')) {
$cd->install();
}
}
}
}
}
+23 -10
View File
@@ -46,6 +46,8 @@ Options:
--adminuser=USERNAME Username for the moodle admin account. Default is admin.
--adminpass=PASSWORD Password for the moodle admin account.
--agree-license Indicates agreement with software license.
--fullname Name of the site
--shortname Name of the site
-h, --help Print out this help
Example:
@@ -93,6 +95,8 @@ list($options, $unrecognized) = cli_get_params(
'lang' => 'en',
'adminuser' => 'admin',
'adminpass' => '',
'fullname' => '',
'shortname' => '',
'agree-license' => false,
'help' => false
),
@@ -121,17 +125,26 @@ if (!file_exists($CFG->dirroot.'/install/lang/'.$options['lang'])) {
}
$CFG->lang = $options['lang'];
// download required lang packs
if ($CFG->lang !== 'en') {
//download lang pack with optional notification
if ($CFG->lang != 'en') {
make_upload_directory('lang');
$installer = new lang_installer($CFG->lang);
$results = $installer->run();
foreach ($results as $langcode => $langstatus) {
if ($langstatus === lang_installer::RESULT_DOWNLOADERROR) {
$a = new stdClass();
$a->url = $installer->lang_pack_url($langcode);
$a->dest = $CFG->dataroot.'/lang';
cli_problem(get_string('remotedownloaderror', 'error', $a));
if ($cd = new component_installer('http://download.moodle.org', 'langpack/2.0', $CFG->lang.'.zip', 'languages.md5', 'lang')) {
if ($cd->install() == COMPONENT_ERROR) {
if ($cd->get_error() == 'remotedownloaderror') {
$a = new stdClass();
$a->url = 'http://download.moodle.org/langpack/2.0/'.$CFG->lang.'.zip';
$a->dest = $CFG->dataroot.'/lang';
cli_problem(get_string($cd->get_error(), 'error', $a));
} else {
cli_problem(get_string($cd->get_error(), 'error'));
}
} else {
// install parent lang if defined
if ($parentlang = get_parent_language()) {
if ($cd = new component_installer('http://download.moodle.org', 'langpack/2.0', $parentlang.'.zip', 'languages.md5', 'lang')) {
$cd->install();
}
}
}
}
}
+6
View File
@@ -36,6 +36,12 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (defined('STDIN')) {
fwrite(STDERR, "ERROR: This script no longer supports CLI, please use admin/cli/cron.php instead\n");
exit(1);
}
// This is a fake CLI script, it is a really ugly hack which emulates
// CLI via web interface, please do not use this hack elsewhere
define('CLI_SCRIPT', true);
+1 -1
View File
@@ -622,7 +622,7 @@ class generator {
require_once($CFG->libdir .'/questionlib.php');
require_once($CFG->dirroot .'/mod/quiz/editlib.php');
$questions = array();
$questionsmenu = question_bank::get_creatable_qtypes();
$questionsmenu = question_type_menu();
$questiontypes = array();
foreach ($questionsmenu as $qtype => $qname) {
$questiontypes[] = $qtype;
+20 -36
View File
@@ -48,7 +48,6 @@ $id = optional_param('id', '', PARAM_TEXT);
$confirmupgrade = optional_param('confirmupgrade', 0, PARAM_BOOL);
$confirmrelease = optional_param('confirmrelease', 0, PARAM_BOOL);
$confirmplugins = optional_param('confirmplugincheck', 0, PARAM_BOOL);
$showallplugins = optional_param('showallplugins', 0, PARAM_BOOL);
$agreelicense = optional_param('agreelicense', 0, PARAM_BOOL);
// Check some PHP server settings
@@ -124,7 +123,7 @@ if (!core_tables_exist()) {
echo $OUTPUT->box($copyrightnotice, 'copyrightnotice');
echo '<br />';
$continue = new single_button(new moodle_url('/admin/index.php', array('lang'=>$CFG->lang, 'agreelicense'=>1)), get_string('continue'), 'get');
echo $OUTPUT->confirm(get_string('doyouagree'), $continue, "http://docs.moodle.org/en/License");
echo $OUTPUT->confirm(get_string('doyouagree'), $continue, "http://docs.moodle.org/dev/License");
echo $OUTPUT->footer();
die;
}
@@ -194,7 +193,6 @@ if (empty($CFG->version)) {
}
if ($version > $CFG->version) { // upgrade
purge_all_caches();
$PAGE->set_pagelayout('maintenance');
$PAGE->set_popup_notification_allowed(false);
@@ -257,19 +255,17 @@ if ($version > $CFG->version) { // upgrade
$PAGE->set_title($strplugincheck);
$PAGE->set_heading($strplugincheck);
$PAGE->set_cacheable(false);
$output = $PAGE->get_renderer('core', 'admin');
$pluginman = plugin_manager::instance();
echo $output->header();
echo $output->box_start('generalbox');
echo $output->container(get_string('pluginchecknotice', 'core_plugin'), 'generalbox', 'notice');
echo $output->plugins_check($pluginman->get_plugins(), array('full' => $showallplugins));
echo $output->box_end();
echo $OUTPUT->header();
echo $OUTPUT->heading($strplugincheck);
echo $OUTPUT->box_start('generalbox', 'notice');
print_string('pluginchecknotice');
echo $OUTPUT->box_end();
print_plugin_tables();
print_upgrade_reload('index.php?confirmupgrade=1&amp;confirmrelease=1');
$button = new single_button(new moodle_url('index.php', array('confirmupgrade'=>1, 'confirmrelease'=>1, 'confirmplugincheck'=>1)), get_string('upgradestart', 'admin'), 'get');
$button->class = 'continuebutton';
echo $output->render($button);
echo $output->footer();
echo $OUTPUT->render($button);
echo $OUTPUT->footer();
die();
} else {
@@ -297,19 +293,17 @@ if (moodle_needs_upgrading()) {
$PAGE->set_title($strplugincheck);
$PAGE->set_heading($strplugincheck);
$PAGE->set_cacheable(false);
$output = $PAGE->get_renderer('core', 'admin');
$pluginman = plugin_manager::instance();
echo $output->header();
echo $output->box_start('generalbox');
echo $output->container(get_string('pluginchecknotice', 'core_plugin'), 'generalbox', 'notice');
echo $output->plugins_check($pluginman->get_plugins(), array('full' => $showallplugins));
echo $output->box_end();
echo $OUTPUT->header();
echo $OUTPUT->heading($strplugincheck);
echo $OUTPUT->box_start('generalbox', 'notice');
print_string('pluginchecknotice');
echo $OUTPUT->box_end();
print_plugin_tables();
print_upgrade_reload('index.php');
$button = new single_button(new moodle_url('index.php', array('confirmplugincheck'=>1)), get_string('upgradestart', 'admin'), 'get');
$button->class = 'continuebutton';
echo $output->render($button);
echo $output->footer();
echo $OUTPUT->render($button);
echo $OUTPUT->footer();
die();
}
}
@@ -355,6 +349,7 @@ if (during_initial_install()) {
}
// login user and let him set password and admin details
$adminuser->newadminuser = 1;
message_set_default_message_preferences($adminuser);
complete_user_login($adminuser, false);
redirect("$CFG->wwwroot/user/editadvanced.php?id=$adminuser->id"); // Edit thyself
@@ -407,17 +402,6 @@ if (any_new_admin_settings($adminroot)){
admin_externalpage_setup('adminnotifications');
echo $OUTPUT->header();
// Unstable code warning
if (isset($maturity)) {
if ($maturity < MATURITY_STABLE) {
$maturitylevel = get_string('maturity'.$maturity, 'admin');
echo $OUTPUT->box(
get_string('maturitycoreinfo', 'admin', $maturitylevel) . ' ' .
$OUTPUT->doc_link('admin/versions', get_string('morehelp')),
'generalbox adminwarning maturityinfo');
}
}
if ($insecuredataroot == INSECURE_DATAROOT_WARNING) {
echo $OUTPUT->box(get_string('datarootsecuritywarning', 'admin', $CFG->dataroot), 'generalbox adminwarning');
} else if ($insecuredataroot == INSECURE_DATAROOT_ERROR) {
@@ -458,8 +442,8 @@ if (!empty($CFG->maintenance_enabled)) {
$copyrighttext = '<a href="http://moodle.org/">Moodle</a> '.
'<a href="http://docs.moodle.org/dev/Releases" title="'.$CFG->version.'">'.$CFG->release.'</a><br />'.
'Copyright &copy; 1999 onwards, Martin Dougiamas<br />'.
'and <a href="http://docs.moodle.org/en/Credits">many other contributors</a>.<br />'.
'<a href="http://docs.moodle.org/en/License">GNU Public License</a>';
'and <a href="http://docs.moodle.org/dev/Credits">many other contributors</a>.<br />'.
'<a href="http://docs.moodle.org/dev/License">GNU Public License</a>';
echo $OUTPUT->box($copyrighttext, 'copyright');
//////////////////////////////////////////////////////////////////////////////////////////////////
+91 -50
View File
@@ -18,7 +18,7 @@
/**
* Fetches language packages from download.moodle.org server
*
* Language packages are available at http://download.moodle.org/langpack/
* Language packages are available at http://download.moodle.org/langpack/2.0/
* in ZIP format together with a file languages.md5 containing their hashes
* and meta info.
* Locally, language packs are saved into $CFG->dataroot/lang/
@@ -33,6 +33,8 @@ require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/filelib.php');
require_once($CFG->libdir.'/componentlib.class.php');
$thisversion = '2.0'; // TODO this information should be taken from version.php or similar source
admin_externalpage_setup('langimport');
if (!empty($CFG->skiplangupgrade)) {
@@ -61,22 +63,41 @@ if (($mode == INSTALLATION_OF_SELECTED_LANG) and confirm_sesskey() and !empty($p
make_upload_directory('temp');
make_upload_directory('lang');
$installer = new lang_installer($pack);
$results = $installer->run();
foreach ($results as $langcode => $langstatus) {
switch ($langstatus) {
case lang_installer::RESULT_DOWNLOADERROR:
$a = new stdClass();
$a->url = $installer->lang_pack_url($langcode);
$a->dest = $CFG->dataroot.'/lang';
print_error('remotedownloaderror', 'error', 'langimport.php', $a);
break;
case lang_installer::RESULT_INSTALLED:
$notice_ok[] = get_string('langpackinstalled', 'admin', $langcode);
break;
case lang_installer::RESULT_UPTODATE:
$notice_ok[] = get_string('langpackuptodate', 'admin', $langcode);
break;
if (is_array($pack)) {
$packs = $pack;
} else {
$packs = array($pack);
}
foreach ($packs as $pack) {
if ($cd = new component_installer('http://download.moodle.org', 'langpack/'.$thisversion, $pack.'.zip', 'languages.md5', 'lang')) {
$status = $cd->install();
switch ($status) {
case COMPONENT_ERROR:
if ($cd->get_error() == 'remotedownloaderror') {
$a = new stdClass();
$a->url = 'http://download.moodle.org/langpack/'.$thisversion.'/'.$pack.'.zip';
$a->dest = $CFG->dataroot.'/lang';
print_error($cd->get_error(), 'error', 'langimport.php', $a);
} else {
print_error($cd->get_error(), 'error', 'langimport.php');
}
break;
case COMPONENT_INSTALLED:
$notice_ok[] = get_string('langpackinstalled','admin',$pack);
if ($parentlang = get_parent_language($pack)) {
// install also parent pack if specified
if ($cd = new component_installer('http://download.moodle.org', 'langpack/'.$thisversion,
$parentlang.'.zip', 'languages.md5', 'lang')) {
$cd->install();
}
}
break;
case COMPONENT_UPTODATE:
break;
}
} else {
echo $OUTPUT->notification('Had an unspecified error with the component installer, sorry.');
}
}
}
@@ -115,9 +136,7 @@ if ($mode == DELETION_OF_SELECTED_LANG and !empty($uninstalllang)) {
if ($mode == UPDATE_ALL_LANG) {
set_time_limit(0);
$installer = new lang_installer();
if (!$availablelangs = $installer->get_remote_list_of_languages()) {
if (!$availablelangs = get_remote_list_of_languages()) {
print_error('cannotdownloadlanguageupdatelist', 'error');
}
$md5array = array(); // (string)langcode => (string)md5
@@ -152,8 +171,8 @@ if ($mode == UPDATE_ALL_LANG) {
make_upload_directory('temp');
make_upload_directory('lang');
// clean-up currently installed versions of the packs
foreach ($neededlangs as $packindex => $pack) {
$updated = false; // any packs updated?
foreach ($neededlangs as $pack) {
if ($pack == 'en') {
continue;
}
@@ -166,38 +185,41 @@ if ($mode == UPDATE_ALL_LANG) {
if (file_exists($dest1)) {
if (!remove_dir($dest1)) {
$notice_error[] = '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)) {
$notice_error[] = 'Could not delete old directory '.$dest2.', update of '.$pack.' failed, please check permissions.';
unset($neededlangs[$packindex]);
continue;
}
}
}
// install all needed language packs
$installer->set_queue($neededlangs);
$results = $installer->run();
$updated = false; // any packs updated?
foreach ($results as $langcode => $langstatus) {
switch ($langstatus) {
case lang_installer::RESULT_DOWNLOADERROR:
$a = new stdClass();
$a->url = $installer->lang_pack_url($langcode);
$a->dest = $CFG->dataroot.'/lang';
print_error('remotedownloaderror', 'error', 'langimport.php', $a);
break;
case lang_installer::RESULT_INSTALLED:
$updated = true;
$notice_ok[] = get_string('langpackinstalled', 'admin', $langcode);
break;
case lang_installer::RESULT_UPTODATE:
$notice_ok[] = get_string('langpackuptodate', 'admin', $langcode);
break;
// copy and unzip new version
if ($cd = new component_installer('http://download.moodle.org', 'langpack/'.$thisversion, $pack.'.zip', 'languages.md5', 'lang')) {
$status = $cd->install();
switch ($status) {
case COMPONENT_ERROR:
if ($cd->get_error() == 'remotedownloaderror') {
$a = new stdClass();
$a->url = 'http://download.moodle.org/langpack/'.$thisversion.'/'.$pack.'.zip';
$a->dest = $CFG->dataroot.'/lang';
print_error($cd->get_error(), 'error', 'langimport.php', $a);
} else {
print_error($cd->get_error(), 'error', 'langimport.php');
}
break;
case COMPONENT_UPTODATE:
// should not get here
break;
case COMPONENT_INSTALLED:
$notice_ok[] = get_string('langpackupdated', 'admin', $pack);
$updated = true;
break;
}
}
}
@@ -206,8 +228,6 @@ if ($mode == UPDATE_ALL_LANG) {
} else {
$notice_ok[] = get_string('nolangupdateneeded','admin');
}
unset($installer);
}
get_string_manager()->reset_caches();
@@ -219,7 +239,7 @@ $installedlangs = get_string_manager()->get_list_of_translations(true);
$missingparents = array();
foreach ($installedlangs as $installedlang => $unused) {
$parent = get_parent_language($installedlang);
if (empty($parent)) {
if (empty($parent) or ($parent === 'en')) {
continue;
}
if (!isset($installedlangs[$parent])) {
@@ -227,9 +247,7 @@ foreach ($installedlangs as $installedlang => $unused) {
}
}
$installer = new lang_installer();
if ($availablelangs = $installer->get_remote_list_of_languages()) {
if ($availablelangs = get_remote_list_of_languages()) {
$remote = true;
} else {
$remote = false;
@@ -339,3 +357,26 @@ function is_installed_lang($lang, $md5check) {
}
return false;
}
/**
* Returns the list of available language packs from download.moodle.org
*
* @return array|bool false if can not download
*/
function get_remote_list_of_languages() {
$source = 'http://download.moodle.org/langpack/2.0/languages.md5';
$availablelangs = array();
if ($content = download_file_content($source)) {
$alllines = explode("\n", $content);
foreach($alllines as $line) {
if (!empty($line)){
$availablelangs[] = explode(',', $line);
}
}
return $availablelangs;
} else {
return false;
}
}
-70
View File
@@ -1,70 +0,0 @@
<?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/>.
/**
* Message outputs configuration page
*
* @package message
* @copyright 2011 Lancaster University Network Services Limited
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->dirroot . '/message/lib.php');
require_once($CFG->libdir.'/adminlib.php');
// This is an admin page
admin_externalpage_setup('managemessageoutputs');
// Require site configuration capability
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
// Get the submitted params
$disable = optional_param('disable', 0, PARAM_INT);
$enable = optional_param('enable', 0, PARAM_INT);
if (!empty($disable) && confirm_sesskey()) {
if (!$processor = $DB->get_record('message_processors', array('id'=>$disable))) {
print_error('outputdoesnotexist', 'message');
}
$DB->set_field('message_processors', 'enabled', '0', array('id'=>$processor->id)); // Disable output
}
if (!empty($enable) && confirm_sesskey() ) {
if (!$processor = $DB->get_record('message_processors', array('id'=>$enable))) {
print_error('outputdoesnotexist', 'message');
}
$DB->set_field('message_processors', 'enabled', '1', array('id'=>$processor->id)); // Enable output
}
if ($disable || $enable) {
$url = new moodle_url('message.php');
redirect($url);
}
// Page settings
$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
// Grab the renderer
$renderer = $PAGE->get_renderer('core', 'message');
// Display the manage message outputs interface
$processors = get_message_processors();
$messageoutputs = $renderer->manage_messageoutputs($processors);
// Display the page
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('managemessageoutputs', 'message'));
echo $messageoutputs;
echo $OUTPUT->footer();
-41
View File
@@ -1,41 +0,0 @@
<?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/>.
/**
* UI for general plugins management
*
* @package core
* @subpackage admin
* @copyright 2011 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/pluginlib.php');
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
admin_externalpage_setup('pluginsoverview');
$output = $PAGE->get_renderer('core', 'admin');
$pluginman = plugin_manager::instance();
echo $output->header();
echo $output->heading(get_string('pluginsoverview', 'core_admin'));
echo $output->box_start('generalbox');
echo $output->plugins_control_panel($pluginman->get_plugins());
echo $output->box_end();
echo $output->footer();
-302
View File
@@ -1,302 +0,0 @@
<?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/>.
/**
* Allows the admin to manage question behaviours.
*
* @package moodlecore
* @subpackage questionengine
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->libdir . '/questionlib.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/tablelib.php');
// Check permissions.
require_login();
$systemcontext = get_context_instance(CONTEXT_SYSTEM);
require_capability('moodle/question:config', $systemcontext);
admin_externalpage_setup('manageqbehaviours');
$thispageurl = new moodle_url('/admin/qbehaviours.php');
$behaviours = get_plugin_list('qbehaviour');
// Get some data we will need - question counts and which types are needed.
$counts = $DB->get_records_sql_menu("
SELECT behaviour, COUNT(1)
FROM {question_attempts} GROUP BY behaviour");
$needed = array();
$archetypal = array();
foreach ($behaviours as $behaviour => $notused) {
if (!array_key_exists($behaviour, $counts)) {
$counts[$behaviour] = 0;
}
$needed[$behaviour] = $counts[$behaviour] > 0;
$archetypal[$behaviour] = question_engine::is_behaviour_archetypal($behaviour);
}
foreach ($behaviours as $behaviour => $notused) {
foreach (question_engine::get_behaviour_required_behaviours($behaviour) as $reqbehaviour) {
$needed[$reqbehaviour] = true;
}
}
foreach ($counts as $behaviour => $count) {
if (!array_key_exists($behaviour, $behaviours)) {
$counts['missingtype'] += $count;
}
}
// Work of the correct sort order.
$config = get_config('question');
$sortedbehaviours = array();
foreach ($behaviours as $behaviour => $notused) {
$sortedbehaviours[$behaviour] = question_engine::get_behaviour_name($behaviour);
}
if (!empty($config->behavioursortorder)) {
$sortedbehaviours = question_engine::sort_behaviours($sortedbehaviours,
$config->behavioursortorder, '');
}
if (!empty($config->disabledbehaviours)) {
$disabledbehaviours = explode(',', $config->disabledbehaviours);
} else {
$disabledbehaviours = array();
}
// Process actions ============================================================
// Disable.
if (($disable = optional_param('disable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($behaviours[$disable])) {
print_error('unknownbehaviour', 'question', $thispageurl, $disable);
}
if (array_search($disable, $disabledbehaviours) === false) {
$disabledbehaviours[] = $disable;
set_config('disabledbehaviours', implode(',', $disabledbehaviours), 'question');
}
redirect($thispageurl);
}
// Enable.
if (($enable = optional_param('enable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($behaviours[$enable])) {
print_error('unknownbehaviour', 'question', $thispageurl, $enable);
}
if (!$archetypal[$enable]) {
print_error('cannotenablebehaviour', 'question', $thispageurl, $enable);
}
if (($key = array_search($enable, $disabledbehaviours)) !== false) {
unset($disabledbehaviours[$key]);
set_config('disabledbehaviours', implode(',', $disabledbehaviours), 'question');
}
redirect($thispageurl);
}
// Move up in order.
if (($up = optional_param('up', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($behaviours[$up])) {
print_error('unknownbehaviour', 'question', $thispageurl, $up);
}
// This function works fine for behaviours, as well as qtypes.
$neworder = question_reorder_qtypes($sortedbehaviours, $up, -1);
set_config('behavioursortorder', implode(',', $neworder), 'question');
redirect($thispageurl);
}
// Move down in order.
if (($down = optional_param('down', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($behaviours[$down])) {
print_error('unknownbehaviour', 'question', $thispageurl, $down);
}
// This function works fine for behaviours, as well as qtypes.
$neworder = question_reorder_qtypes($sortedbehaviours, $down, +1);
set_config('behavioursortorder', implode(',', $neworder), 'question');
redirect($thispageurl);
}
// Delete.
if (($delete = optional_param('delete', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
// Check it is OK to delete this question type.
if ($delete == 'missing') {
print_error('cannotdeletemissingbehaviour', 'question', $thispageurl);
}
if (!isset($behaviours[$delete])) {
print_error('unknownbehaviour', 'question', $thispageurl, $delete);
}
$behaviourname = $sortedbehaviours[$delete];
if ($counts[$delete] > 0) {
print_error('cannotdeletebehaviourinuse', 'question', $thispageurl, $behaviourname);
}
if ($needed[$delete] > 0) {
print_error('cannotdeleteneededbehaviour', 'question', $thispageurl, $behaviourname);
}
// If not yet confirmed, display a confirmation message.
if (!optional_param('confirm', '', PARAM_BOOL)) {
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('deletebehaviourareyousure', 'question', $behaviourname));
echo $OUTPUT->confirm(
get_string('deletebehaviourareyousuremessage', 'question', $behaviourname),
new moodle_url($thispageurl, array('delete' => $delete, 'confirm' => 1)),
$thispageurl);
echo $OUTPUT->footer();
exit;
}
// Do the deletion.
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('deletingbehaviour', 'question', $behaviourname));
// Delete any configuration records.
if (!unset_all_config_for_plugin('qbehaviour_' . $delete)) {
echo $OUTPUT->notification(get_string('errordeletingconfig', 'admin', 'qbehaviour_' . $delete));
}
if (($key = array_search($delete, $disabledbehaviours)) !== false) {
unset($disabledbehaviours[$key]);
set_config('disabledbehaviours', implode(',', $disabledbehaviours), 'question');
}
$behaviourorder = explode(',', $config->behavioursortorder);
if (($key = array_search($delete, $behaviourorder)) !== false) {
unset($behaviourorder[$key]);
set_config('behavioursortorder', implode(',', $behaviourorder), 'question');
}
// Then the tables themselves
drop_plugin_tables($delete, get_plugin_directory('qbehaviour', $delete) . '/db/install.xml', false);
// Remove event handlers and dequeue pending events
events_uninstall('qbehaviour_' . $delete);
$a->behaviour = $behaviourname;
$a->directory = get_plugin_directory('qbehaviour', $delete);
echo $OUTPUT->box(get_string('qbehaviourdeletefiles', 'question', $a), 'generalbox', 'notice');
echo $OUTPUT->continue_button($thispageurl);
echo $OUTPUT->footer();
exit;
}
// End of process actions ==================================================
// Print the page heading.
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('manageqbehaviours', 'admin'));
// Set up the table.
$table = new flexible_table('qbehaviouradmintable');
$table->define_baseurl($thispageurl);
$table->define_columns(array('behaviour', 'numqas', 'version', 'requires',
'available', 'delete'));
$table->define_headers(array(get_string('behaviour', 'question'), get_string('numqas', 'question'),
get_string('version'), get_string('requires', 'admin'),
get_string('availableq', 'question'), get_string('delete')));
$table->set_attribute('id', 'qbehaviours');
$table->set_attribute('class', 'generaltable generalbox boxaligncenter boxwidthwide');
$table->setup();
// Add a row for each question type.
foreach ($sortedbehaviours as $behaviour => $behaviourname) {
$row = array();
// Question icon and name.
$row[] = $behaviourname;
// Count
$row[] = $counts[$behaviour];
// Question version number.
$version = get_config('qbehaviour_' . $behaviour, 'version');
if ($version) {
$row[] = $version;
} else {
$row[] = html_writer::tag('span', get_string('nodatabase', 'admin'), array('class' => 'disabled'));
}
// Other question types required by this one.
$requiredbehaviours = question_engine::get_behaviour_required_behaviours($behaviour);
if (!empty($requiredbehaviours)) {
$strrequiredbehaviours = array();
foreach ($requiredbehaviours as $required) {
$strrequiredbehaviours[] = $sortedbehaviours[$required];
}
$row[] = implode(', ', $strrequiredbehaviours);
} else {
$row[] = '';
}
// Are people allowed to create new questions of this type?
$rowclass = '';
if ($archetypal[$behaviour]) {
$enabled = array_search($behaviour, $disabledbehaviours) === false;
$icons = question_behaviour_enable_disable_icons($behaviour, $enabled);
if (!$enabled) {
$rowclass = 'dimmed_text';
}
} else {
$icons = $OUTPUT->spacer() . ' ';
}
// Move icons.
$icons .= question_behaviour_icon_html('up', $behaviour, 't/up', get_string('up'), null);
$icons .= question_behaviour_icon_html('down', $behaviour, 't/down', get_string('down'), null);
$row[] = $icons;
// Delete link, if available.
if ($needed[$behaviour]) {
$row[] = '';
} else {
$row[] = html_writer::link(new moodle_url($thispageurl,
array('delete' => $behaviour, 'sesskey' => sesskey())), get_string('delete'),
array('title' => get_string('uninstallbehaviour', 'question')));
}
$table->add_data($row, $rowclass);
}
$table->finish_output();
echo $OUTPUT->footer();
function question_behaviour_enable_disable_icons($behaviour, $enabled) {
if ($enabled) {
return question_behaviour_icon_html('disable', $behaviour, 'i/hide',
get_string('enabled', 'question'), get_string('disable'));
} else {
return question_behaviour_icon_html('enable', $behaviour, 'i/show',
get_string('disabled', 'question'), get_string('enable'));
}
}
function question_behaviour_icon_html($action, $behaviour, $icon, $alt, $tip) {
global $OUTPUT;
return $OUTPUT->action_icon(new moodle_url('/admin/qbehaviours.php',
array($action => $behaviour, 'sesskey' => sesskey())),
new pix_icon($icon, $alt, 'moodle', array('title' => '')),
null, array('title' => $tip)) . ' ';
}
+247 -266
View File
@@ -1,312 +1,293 @@
<?php
// Allows the admin to manage question types.
// 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/>.
require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->libdir . '/questionlib.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/tablelib.php');
/**
* Allows the admin to manage question types.
*
* @package moodlecore
* @subpackage questionbank
* @copyright 2008 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/// Check permissions.
require_login();
$systemcontext = get_context_instance(CONTEXT_SYSTEM);
require_capability('moodle/question:config', $systemcontext);
$canviewreports = has_capability('report/questioninstances:view', $systemcontext);
admin_externalpage_setup('manageqtypes');
require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->libdir . '/questionlib.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/tablelib.php');
// Check permissions.
require_login();
$systemcontext = get_context_instance(CONTEXT_SYSTEM);
require_capability('moodle/question:config', $systemcontext);
$canviewreports = has_capability('report/questioninstances:view', $systemcontext);
admin_externalpage_setup('manageqtypes');
$thispageurl = new moodle_url('/admin/qtypes.php');
$qtypes = question_bank::get_all_qtypes();
// Get some data we will need - question counts and which types are needed.
$counts = $DB->get_records_sql("
SELECT qtype, COUNT(1) as numquestions, SUM(hidden) as numhidden
FROM {question} GROUP BY qtype", array());
$needed = array();
foreach ($qtypes as $qtypename => $qtype) {
if (!isset($counts[$qtypename])) {
$counts[$qtypename] = new stdClass;
$counts[$qtypename]->numquestions = 0;
$counts[$qtypename]->numhidden = 0;
/// Get some data we will need - question counts and which types are needed.
$counts = $DB->get_records_sql("
SELECT qtype, COUNT(1) as numquestions, SUM(hidden) as numhidden
FROM {question} GROUP BY qtype", array());
$needed = array();
foreach ($QTYPES as $qtypename => $qtype) {
if (!isset($counts[$qtypename])) {
$counts[$qtypename] = new stdClass;
$counts[$qtypename]->numquestions = 0;
$counts[$qtypename]->numhidden = 0;
}
$needed[$qtypename] = $counts[$qtypename]->numquestions > 0;
$counts[$qtypename]->numquestions -= $counts[$qtypename]->numhidden;
}
$needed[$qtypename] = $counts[$qtypename]->numquestions > 0;
$counts[$qtypename]->numquestions -= $counts[$qtypename]->numhidden;
}
$needed['missingtype'] = true; // The system needs the missing question type.
foreach ($qtypes as $qtypename => $qtype) {
foreach ($qtype->requires_qtypes() as $reqtype) {
$needed[$reqtype] = true;
$needed['missingtype'] = true; // The system needs the missing question type.
foreach ($QTYPES as $qtypename => $qtype) {
foreach ($qtype->requires_qtypes() as $reqtype) {
$needed[$reqtype] = true;
}
}
}
foreach ($counts as $qtypename => $count) {
if (!isset($qtypes[$qtypename])) {
$counts['missingtype']->numquestions += $count->numquestions - $count->numhidden;
$counts['missingtype']->numhidden += $count->numhidden;
}
}
// Work of the correct sort order.
$config = get_config('question');
$sortedqtypes = array();
foreach ($qtypes as $qtypename => $qtype) {
$sortedqtypes[$qtypename] = $qtype->local_name();
}
$sortedqtypes = question_bank::sort_qtype_array($sortedqtypes, $config);
// Process actions ============================================================
// Disable.
if (($disable = optional_param('disable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($qtypes[$disable])) {
print_error('unknownquestiontype', 'question', $thispageurl, $disable);
foreach ($counts as $qtypename => $count) {
if (!isset($QTYPES[$qtypename])) {
$counts['missingtype']->numquestions += $count->numquestions - $count->numhidden;
$counts['missingtype']->numhidden += $count->numhidden;
}
}
set_config($disable . '_disabled', 1, 'question');
redirect($thispageurl);
}
/// Work of the correct sort order.
$config = get_config('question');
$sortedqtypes = array();
foreach ($QTYPES as $qtypename => $qtype) {
$sortedqtypes[$qtypename] = $qtype->local_name();
}
$sortedqtypes = question_sort_qtype_array($sortedqtypes, $config);
// Enable.
if (($enable = optional_param('enable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($qtypes[$enable])) {
print_error('unknownquestiontype', 'question', $thispageurl, $enable);
/// Process actions ============================================================
// Disable.
if (($disable = optional_param('disable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($QTYPES[$disable])) {
print_error('unknownquestiontype', 'question', admin_url('qtypes.php'), $disable);
}
set_config($disable . '_disabled', 1, 'question');
redirect(admin_url('qtypes.php'));
}
if (!$qtypes[$enable]->menu_name()) {
print_error('cannotenable', 'question', $thispageurl, $enable);
// Enable.
if (($enable = optional_param('enable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($QTYPES[$enable])) {
print_error('unknownquestiontype', 'question', admin_url('qtypes.php'), $enable);
}
if (!$QTYPES[$enable]->menu_name()) {
print_error('cannotenable', 'question', admin_url('qtypes.php'), $enable);
}
unset_config($enable . '_disabled', 'question');
redirect(admin_url('qtypes.php'));
}
unset_config($enable . '_disabled', 'question');
redirect($thispageurl);
}
// Move up in order.
if (($up = optional_param('up', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($QTYPES[$up])) {
print_error('unknownquestiontype', 'question', admin_url('qtypes.php'), $up);
}
// Move up in order.
if (($up = optional_param('up', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($qtypes[$up])) {
print_error('unknownquestiontype', 'question', $thispageurl, $up);
$neworder = question_reorder_qtypes($sortedqtypes, $up, -1);
question_save_qtype_order($neworder, $config);
redirect(admin_url('qtypes.php'));
}
$neworder = question_reorder_qtypes($sortedqtypes, $up, -1);
question_save_qtype_order($neworder, $config);
redirect($thispageurl);
}
// Move down in order.
if (($down = optional_param('down', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($QTYPES[$down])) {
print_error('unknownquestiontype', 'question', admin_url('qtypes.php'), $down);
}
// Move down in order.
if (($down = optional_param('down', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($qtypes[$down])) {
print_error('unknownquestiontype', 'question', $thispageurl, $down);
$neworder = question_reorder_qtypes($sortedqtypes, $down, +1);
question_save_qtype_order($neworder, $config);
redirect(admin_url('qtypes.php'));
}
$neworder = question_reorder_qtypes($sortedqtypes, $down, +1);
question_save_qtype_order($neworder, $config);
redirect($thispageurl);
}
// Delete.
if (($delete = optional_param('delete', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
// Check it is OK to delete this question type.
if ($delete == 'missingtype') {
print_error('cannotdeletemissingqtype', 'admin', admin_url('qtypes.php'));
}
// Delete.
if (($delete = optional_param('delete', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
// Check it is OK to delete this question type.
if ($delete == 'missingtype') {
print_error('cannotdeletemissingqtype', 'question', $thispageurl);
}
if (!isset($QTYPES[$delete])) {
print_error('unknownquestiontype', 'question', admin_url('qtypes.php'), $delete);
}
if (!isset($qtypes[$delete])) {
print_error('unknownquestiontype', 'question', $thispageurl, $delete);
}
$qtypename = $QTYPES[$delete]->local_name();
if ($counts[$delete]->numquestions + $counts[$delete]->numhidden > 0) {
print_error('cannotdeleteqtypeinuse', 'admin', admin_url('qtypes.php'), $qtypename);
}
$qtypename = $qtypes[$delete]->local_name();
if ($counts[$delete]->numquestions + $counts[$delete]->numhidden > 0) {
print_error('cannotdeleteqtypeinuse', 'question', $thispageurl, $qtypename);
}
if ($needed[$delete] > 0) {
print_error('cannotdeleteqtypeneeded', 'admin', admin_url('qtypes.php'), $qtypename);
}
if ($needed[$delete] > 0) {
print_error('cannotdeleteqtypeneeded', 'question', $thispageurl, $qtypename);
}
// If not yet confirmed, display a confirmation message.
if (!optional_param('confirm', '', PARAM_BOOL)) {
$qtypename = $QTYPES[$delete]->local_name();
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('deleteqtypeareyousure', 'admin', $qtypename));
echo $OUTPUT->confirm(get_string('deleteqtypeareyousuremessage', 'admin', $qtypename),
admin_url('qtypes.php?delete=' . $delete . '&confirm=1'),
admin_url('qtypes.php'));
echo $OUTPUT->footer();
exit;
}
// If not yet confirmed, display a confirmation message.
if (!optional_param('confirm', '', PARAM_BOOL)) {
$qtypename = $qtypes[$delete]->local_name();
// Do the deletion.
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('deleteqtypeareyousure', 'question', $qtypename));
echo $OUTPUT->confirm(get_string('deleteqtypeareyousuremessage', 'question', $qtypename),
new moodle_url($thispageurl, array('delete' => $delete, 'confirm' => 1)),
$thispageurl);
echo $OUTPUT->heading(get_string('deletingqtype', 'admin', $qtypename));
// Delete any configuration records.
if (!unset_all_config_for_plugin('qtype_' . $delete)) {
echo $OUTPUT->notification(get_string('errordeletingconfig', 'admin', 'qtype_' . $delete));
}
unset_config($delete . '_disabled', 'question');
unset_config($delete . '_sortorder', 'question');
// Then the tables themselves
drop_plugin_tables($delete, $QTYPES[$delete]->plugin_dir() . '/db/install.xml', false);
// Remove event handlers and dequeue pending events
events_uninstall('qtype/' . $delete);
$a->qtype = $qtypename;
$a->directory = $QTYPES[$delete]->plugin_dir();
echo $OUTPUT->box(get_string('qtypedeletefiles', 'admin', $a), 'generalbox', 'notice');
echo $OUTPUT->continue_button(admin_url('qtypes.php'));
echo $OUTPUT->footer();
exit;
}
// Do the deletion.
// End of process actions ==================================================
/// Print the page heading.
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('deletingqtype', 'question', $qtypename));
echo $OUTPUT->heading(get_string('manageqtypes', 'admin'));
// Delete any configuration records.
if (!unset_all_config_for_plugin('qtype_' . $delete)) {
echo $OUTPUT->notification(get_string('errordeletingconfig', 'admin', 'qtype_' . $delete));
/// Set up the table.
$table = new flexible_table('qtypeadmintable');
$table->define_columns(array('questiontype', 'numquestions', 'version', 'requires',
'availableto', 'delete', 'settings'));
$table->define_headers(array(get_string('questiontype', 'admin'), get_string('numquestions', 'admin'),
get_string('version'), get_string('requires', 'admin'), get_string('availableq', 'question'),
get_string('delete'), get_string('settings')));
$table->set_attribute('id', 'qtypes');
$table->set_attribute('class', 'generaltable generalbox boxaligncenter boxwidthwide');
$table->setup();
/// Add a row for each question type.
$createabletypes = question_type_menu();
foreach ($sortedqtypes as $qtypename => $localname) {
$qtype = $QTYPES[$qtypename];
$row = array();
// Question icon and name.
$fakequestion = new stdClass;
$fakequestion->qtype = $qtypename;
$icon = print_question_icon($fakequestion, true);
$row[] = $icon . ' ' . $localname;
// Number of questions of this type.
if ($counts[$qtypename]->numquestions + $counts[$qtypename]->numhidden > 0) {
if ($counts[$qtypename]->numhidden > 0) {
$strcount = get_string('numquestionsandhidden', 'admin', $counts[$qtypename]);
} else {
$strcount = $counts[$qtypename]->numquestions;
}
if ($canviewreports) {
$row[] = '<a href="' . admin_url('/report/questioninstances/index.php?qtype=' . $qtypename) .
'" title="' . get_string('showdetails', 'admin') . '">' . $strcount . '</a>';
} else {
$strcount;
}
} else {
$row[] = 0;
}
// Question version number.
$version = get_config('qtype_' . $qtypename, 'version');
if ($version) {
$row[] = $version;
} else {
$row[] = '<span class="disabled">' . get_string('nodatabase', 'admin') . '</span>';
}
// Other question types required by this one.
$requiredtypes = $qtype->requires_qtypes();
$strtypes = array();
if (!empty($requiredtypes)) {
foreach ($requiredtypes as $required) {
$strtypes[] = $QTYPES[$required]->local_name();
}
$row[] = implode(', ', $strtypes);
} else {
$row[] = '';
}
// Are people allowed to create new questions of this type?
$rowclass = '';
if ($qtype->menu_name()) {
$createable = isset($createabletypes[$qtypename]);
$icons = enable_disable_button($qtypename, $createable);
if (!$createable) {
$rowclass = 'dimmed_text';
}
} else {
$icons = '<img src="' . $OUTPUT->pix_url('spacer') . '" alt="" class="spacer" />';
}
// Move icons.
$icons .= icon_html('up', $qtypename, 't/up', get_string('up'), '');
$icons .= icon_html('down', $qtypename, 't/down', get_string('down'), '');
$row[] = $icons;
// Delete link, if available.
if ($needed[$qtypename]) {
$row[] = '';
} else {
$row[] = '<a href="' . admin_url('qtypes.php?delete=' . $qtypename .
'&amp;sesskey=' . sesskey()) . '" title="' .
get_string('uninstallqtype', 'admin') . '">' . get_string('delete') . '</a>';
}
// Settings link, if available.
$settings = admin_get_root()->locate('qtypesetting' . $qtypename);
if ($settings instanceof admin_externalpage) {
$row[] = '<a href="' . $settings->url .
'">' . get_string('settings') . '</a>';
} else if ($settings instanceof admin_settingpage) {
$row[] = '<a href="' . admin_url('settings.php?section=qtypesetting' . $qtypename) .
'">' . get_string('settings') . '</a>';
} else {
$row[] = '';
}
$table->add_data($row, $rowclass);
}
unset_config($delete . '_disabled', 'question');
unset_config($delete . '_sortorder', 'question');
// Then the tables themselves
drop_plugin_tables($delete, $qtypes[$delete]->plugin_dir() . '/db/install.xml', false);
$table->finish_output();
// Remove event handlers and dequeue pending events
events_uninstall('qtype_' . $delete);
$a->qtype = $qtypename;
$a->directory = $qtypes[$delete]->plugin_dir();
echo $OUTPUT->box(get_string('qtypedeletefiles', 'question', $a), 'generalbox', 'notice');
echo $OUTPUT->continue_button($thispageurl);
echo $OUTPUT->footer();
exit;
function admin_url($endbit) {
global $CFG;
return $CFG->wwwroot . '/' . $CFG->admin . '/' . $endbit;
}
// End of process actions ==================================================
// Print the page heading.
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('manageqtypes', 'admin'));
// Set up the table.
$table = new flexible_table('qtypeadmintable');
$table->define_baseurl($thispageurl);
$table->define_columns(array('questiontype', 'numquestions', 'version', 'requires',
'availableto', 'delete', 'settings'));
$table->define_headers(array(get_string('questiontype', 'question'), get_string('numquestions', 'question'),
get_string('version'), get_string('requires', 'admin'), get_string('availableq', 'question'),
get_string('delete'), get_string('settings')));
$table->set_attribute('id', 'qtypes');
$table->set_attribute('class', 'generaltable generalbox boxaligncenter boxwidthwide');
$table->setup();
// Add a row for each question type.
$createabletypes = question_bank::get_creatable_qtypes();
foreach ($sortedqtypes as $qtypename => $localname) {
$qtype = $qtypes[$qtypename];
$row = array();
// Question icon and name.
$fakequestion = new stdClass;
$fakequestion->qtype = $qtypename;
$icon = print_question_icon($fakequestion, true);
$row[] = $icon . ' ' . $localname;
// Number of questions of this type.
if ($counts[$qtypename]->numquestions + $counts[$qtypename]->numhidden > 0) {
if ($counts[$qtypename]->numhidden > 0) {
$strcount = get_string('numquestionsandhidden', 'question', $counts[$qtypename]);
} else {
$strcount = $counts[$qtypename]->numquestions;
}
if ($canviewreports) {
$row[] = html_writer::link(new moodle_url('/admin/report/questioninstances/index.php',
array('qtype' => $qtypename)), $strcount, array('title' => get_string('showdetails', 'admin')));
} else {
$strcount;
}
} else {
$row[] = 0;
}
// Question version number.
$version = get_config('qtype_' . $qtypename, 'version');
if ($version) {
$row[] = $version;
} else {
$row[] = html_writer::tag('span', get_string('nodatabase', 'admin'), array('class' => 'disabled'));
}
// Other question types required by this one.
$requiredtypes = $qtype->requires_qtypes();
$strtypes = array();
if (!empty($requiredtypes)) {
foreach ($requiredtypes as $required) {
$strtypes[] = $qtypes[$required]->local_name();
}
$row[] = implode(', ', $strtypes);
} else {
$row[] = '';
}
// Are people allowed to create new questions of this type?
$rowclass = '';
if ($qtype->menu_name()) {
$createable = isset($createabletypes[$qtypename]);
$icons = question_types_enable_disable_icons($qtypename, $createable);
if (!$createable) {
$rowclass = 'dimmed_text';
}
} else {
$icons = $OUTPUT->spacer() . ' ';
}
// Move icons.
$icons .= question_type_icon_html('up', $qtypename, 't/up', get_string('up'), '');
$icons .= question_type_icon_html('down', $qtypename, 't/down', get_string('down'), '');
$row[] = $icons;
// Delete link, if available.
if ($needed[$qtypename]) {
$row[] = '';
} else {
$row[] = html_writer::link(new moodle_url($thispageurl,
array('delete' => $qtypename, 'sesskey' => sesskey())), get_string('delete'),
array('title' => get_string('uninstallqtype', 'question')));
}
// Settings link, if available.
$settings = admin_get_root()->locate('qtypesetting' . $qtypename);
if ($settings instanceof admin_externalpage) {
$row[] = html_writer::link($settings->url, get_string('settings'));
} else if ($settings instanceof admin_settingpage) {
$row[] = html_writer::link(new moodle_url('/admin/settings.php',
array('section' => 'qtypesetting' . $qtypename)), get_string('settings'));
} else {
$row[] = '';
}
$table->add_data($row, $rowclass);
}
$table->finish_output();
echo $OUTPUT->footer();
function question_types_enable_disable_icons($qtypename, $createable) {
function enable_disable_button($qtypename, $createable) {
if ($createable) {
return question_type_icon_html('disable', $qtypename, 'i/hide',
get_string('enabled', 'question'), get_string('disable'));
return icon_html('disable', $qtypename, 'i/hide', get_string('enabled', 'question'), get_string('disable'));
} else {
return question_type_icon_html('enable', $qtypename, 'i/show',
get_string('disabled', 'question'), get_string('enable'));
return icon_html('enable', $qtypename, 'i/show', get_string('disabled', 'question'), get_string('enable'));
}
}
function question_type_icon_html($action, $qtypename, $icon, $alt, $tip) {
function icon_html($action, $qtypename, $icon, $alt, $tip) {
global $OUTPUT;
return $OUTPUT->action_icon(new moodle_url('/admin/qtypes.php',
array($action => $qtypename, 'sesskey' => sesskey())),
new pix_icon($icon, $alt, 'moodle', array('title' => '')),
null, array('title' => $tip)) . ' ';
if ($tip) {
$tip = 'title="' . $tip . '" ';
}
$html = ' <form action="' . admin_url('qtypes.php') . '" method="post"><div>';
$html .= '<input type="hidden" name="sesskey" value="' . sesskey() . '" />';
$html .= '<input type="image" name="' . $action . '" value="' . $qtypename .
'" src="' . $OUTPUT->pix_url($icon) . '" alt="' . $alt . '" ' . $tip . '/>';
$html .= '</div></form>';
return $html;
}
-296
View File
@@ -1,296 +0,0 @@
<?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/>.
/**
* Renderer for core_admin subsystem
*
* @package core
* @subpackage admin
* @copyright 2011 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/pluginlib.php');
/**
* Standard HTML output renderer for core_admin subsystem
*/
class core_admin_renderer extends plugin_renderer_base {
/**
* Displays all known plugins and information about their installation or upgrade
*
* This default implementation renders all plugins into one big table. The rendering
* options support:
* (bool)full = false: whether to display up-to-date plugins, too
*
* @param array $plugininfo as returned by {@see plugin_manager::get_plugins()}
* @param array $options rendering options
* @return string HTML code
*/
public function plugins_check(array $plugininfo, array $options = null) {
if (empty($plugininfo)) {
return '';
}
if (empty($options)) {
$options = array(
'full' => false,
);
}
$pluginman = plugin_manager::instance();
$table = new html_table();
$table->id = 'plugins-check';
$table->head = array(
get_string('displayname', 'core_plugin'),
get_string('rootdir', 'core_plugin'),
get_string('source', 'core_plugin'),
get_string('versiondb', 'core_plugin'),
get_string('versiondisk', 'core_plugin'),
get_string('status', 'core_plugin'),
);
$table->colclasses = array(
'displayname', 'rootdir', 'source', 'versiondb', 'versiondisk', 'status',
);
$table->data = array();
$numofhighlighted = array(); // number of highlighted rows per this subsection
foreach ($plugininfo as $type => $plugins) {
$header = new html_table_cell($pluginman->plugintype_name_plural($type));
$header->header = true;
$header->colspan = count($table->head);
$header = new html_table_row(array($header));
$header->attributes['class'] = 'plugintypeheader type-' . $type;
$numofhighlighted[$type] = 0;
if (empty($plugins) and $options['full']) {
$msg = new html_table_cell(get_string('noneinstalled', 'core_plugin'));
$msg->colspan = count($table->head);
$row = new html_table_row(array($msg));
$row->attributes['class'] .= 'msg msg-noneinstalled';
$table->data[] = $header;
$table->data[] = $row;
continue;
}
$plugintyperows = array();
foreach ($plugins as $name => $plugin) {
$row = new html_table_row();
$row->attributes['class'] = 'type-' . $plugin->type . ' name-' . $plugin->type . '_' . $plugin->name;
if ($this->page->theme->resolve_image_location('icon', $plugin->type . '_' . $plugin->name)) {
$icon = $this->output->pix_icon('icon', '', $plugin->type . '_' . $plugin->name, array('class' => 'smallicon pluginicon'));
} else {
$icon = $this->output->pix_icon('spacer', '', 'moodle', array('class' => 'smallicon pluginicon noicon'));
}
$displayname = $icon . ' ' . $plugin->displayname;
$displayname = new html_table_cell($displayname);
$rootdir = new html_table_cell($plugin->get_dir());
if ($isstandard = $plugin->is_standard()) {
$row->attributes['class'] .= ' standard';
$source = new html_table_cell(get_string('sourcestd', 'core_plugin'));
} else {
$row->attributes['class'] .= ' extension';
$source = new html_table_cell(get_string('sourceext', 'core_plugin'));
}
$versiondb = new html_table_cell($plugin->versiondb);
$versiondisk = new html_table_cell($plugin->versiondisk);
$statuscode = $plugin->get_status();
$row->attributes['class'] .= ' status-' . $statuscode;
$status = new html_table_cell(get_string('status_' . $statuscode, 'core_plugin'));
if ($isstandard and in_array($statuscode, array(plugin_manager::PLUGIN_STATUS_NODB, plugin_manager::PLUGIN_STATUS_UPTODATE))) {
if (empty($options['full'])) {
continue;
}
} else {
$numofhighlighted[$type]++;
}
$row->cells = array($displayname, $rootdir, $source, $versiondb, $versiondisk, $status);
$plugintyperows[] = $row;
}
if (empty($numofhighlighted[$type]) and empty($options['full'])) {
continue;
}
$table->data[] = $header;
$table->data = array_merge($table->data, $plugintyperows);
}
$sumofhighlighted = array_sum($numofhighlighted);
if ($sumofhighlighted == 0) {
$out = $this->output->container_start('nonehighlighted', 'plugins-check-info');
$out .= $this->output->heading(get_string('nonehighlighted', 'core_plugin'));
if (empty($options['full'])) {
$out .= html_writer::link(new moodle_url('/admin/index.php',
array('confirmupgrade' => 1, 'confirmrelease' => 1, 'showallplugins' => 1)),
get_string('nonehighlightedinfo', 'core_plugin'));
}
$out .= $this->output->container_end();
} else {
$out = $this->output->container_start('somehighlighted', 'plugins-check-info');
$out .= $this->output->heading(get_string('somehighlighted', 'core_plugin', $sumofhighlighted));
if (empty($options['full'])) {
$out .= html_writer::link(new moodle_url('/admin/index.php',
array('confirmupgrade' => 1, 'confirmrelease' => 1, 'showallplugins' => 1)),
get_string('somehighlightedinfo', 'core_plugin'));
}
$out .= $this->output->container_end();
}
if ($sumofhighlighted > 0 or $options['full']) {
$out .= html_writer::table($table);
}
return $out;
}
/**
* Displays all known plugins and links to manage them
*
* This default implementation renders all plugins into one big table.
*
* @param array $plugininfo as returned by {@see plugin_manager::get_plugins()}
* @return string HTML code
*/
public function plugins_control_panel(array $plugininfo) {
if (empty($plugininfo)) {
return '';
}
$pluginman = plugin_manager::instance();
$table = new html_table();
$table->id = 'plugins-control-panel';
$table->head = array(
get_string('displayname', 'core_plugin'),
get_string('systemname', 'core_plugin'),
get_string('source', 'core_plugin'),
get_string('version', 'core_plugin'),
get_string('availability', 'core_plugin'),
get_string('settings', 'core_plugin'),
get_string('uninstall','core_plugin'),
);
$table->colclasses = array(
'displayname', 'systemname', 'source', 'version', 'availability', 'settings', 'uninstall',
);
foreach ($plugininfo as $type => $plugins) {
$header = new html_table_cell($pluginman->plugintype_name_plural($type));
$header->header = true;
$header->colspan = count($table->head);
$header = new html_table_row(array($header));
$header->attributes['class'] = 'plugintypeheader type-' . $type;
$table->data[] = $header;
if (empty($plugins)) {
$msg = new html_table_cell(get_string('noneinstalled', 'core_plugin'));
$msg->colspan = count($table->head);
$row = new html_table_row(array($msg));
$row->attributes['class'] .= 'msg msg-noneinstalled';
$table->data[] = $row;
continue;
}
foreach ($plugins as $name => $plugin) {
$row = new html_table_row();
$row->attributes['class'] = 'type-' . $plugin->type . ' name-' . $plugin->type . '_' . $plugin->name;
if ($this->page->theme->resolve_image_location('icon', $plugin->type . '_' . $plugin->name)) {
$icon = $this->output->pix_icon('icon', '', $plugin->type . '_' . $plugin->name, array('class' => 'smallicon pluginicon'));
} else {
$icon = $this->output->pix_icon('spacer', '', 'moodle', array('class' => 'smallicon pluginicon noicon'));
}
if ($plugin->get_status() === plugin_manager::PLUGIN_STATUS_MISSING) {
$msg = html_writer::tag('span', get_string('status_missing', 'core_plugin'), array('class' => 'notifyproblem'));
$row->attributes['class'] .= ' missingfromdisk';
} else {
$msg = '';
}
$displayname = $icon . ' ' . $plugin->displayname . ' ' . $msg;
$displayname = new html_table_cell($displayname);
$systemname = new html_table_cell($plugin->type . '_' . $plugin->name);
if ($plugin->is_standard()) {
$row->attributes['class'] .= ' standard';
$source = new html_table_cell(get_string('sourcestd', 'core_plugin'));
} else {
$row->attributes['class'] .= ' extension';
$source = new html_table_cell(get_string('sourceext', 'core_plugin'));
}
$version = new html_table_cell($plugin->versiondb);
$isenabled = $plugin->is_enabled();
if (is_null($isenabled)) {
$availability = new html_table_cell('');
} else if ($isenabled) {
$row->attributes['class'] .= ' enabled';
$icon = $this->output->pix_icon('i/hide', get_string('pluginenabled', 'core_plugin'));
$availability = new html_table_cell($icon . ' ' . get_string('pluginenabled', 'core_plugin'));
} else {
$row->attributes['class'] .= ' disabled';
$icon = $this->output->pix_icon('i/show', get_string('plugindisabled', 'core_plugin'));
$availability = new html_table_cell($icon . ' ' . get_string('plugindisabled', 'core_plugin'));
}
$settingsurl = $plugin->get_settings_url();
if (is_null($settingsurl)) {
$settings = new html_table_cell('');
} else {
$settings = html_writer::link($settingsurl, get_string('settings', 'core_plugin'));
$settings = new html_table_cell($settings);
}
$uninstallurl = $plugin->get_uninstall_url();
if (is_null($uninstallurl)) {
$uninstall = new html_table_cell('');
} else {
$uninstall = html_writer::link($uninstallurl, get_string('uninstall', 'core_plugin'));
$uninstall = new html_table_cell($uninstall);
}
$row->cells = array(
$displayname, $systemname, $source, $version, $availability, $settings, $uninstall
);
$table->data[] = $row;
}
}
return html_writer::table($table);
}
}
+1 -1
View File
@@ -3,6 +3,6 @@
defined('MOODLE_INTERNAL') || die;
// profiling report, added to development
if (extension_loaded('xhprof') && function_exists('xhprof_enable') && (!empty($CFG->profilingenabled) || !empty($CFG->earlyprofilingenabled))) {
if (extension_loaded('xhprof') && function_exists('xhprof_enable') && !empty($CFG->profilingenabled)) {
$ADMIN->add('development', new admin_externalpage('reportprofiling', get_string('pluginname', 'report_profiling'), "$CFG->wwwroot/$CFG->admin/report/profiling/index.php", 'moodle/site:config'));
}
+3 -5
View File
@@ -22,9 +22,8 @@ echo $OUTPUT->header();
add_to_log(SITEID, "admin", "report questioninstances", "report/questioninstances/index.php?qtype=$requestedqtype", $requestedqtype);
// Prepare the list of capabilities to choose from
$qtypes = question_bank::get_all_qtypes();
$qtypechoices = array();
foreach ($qtypes as $qtype) {
foreach ($QTYPES as $qtype) {
$qtypechoices[$qtype->name()] = $qtype->local_name();
}
@@ -46,7 +45,7 @@ if ($requestedqtype) {
// Work out the bits needed for the SQL WHERE clauses.
if ($requestedqtype == 'missingtype') {
$othertypes = array_keys($qtypes);
$othertypes = array_keys($QTYPES);
$key = array_search('missingtype', $othertypes);
unset($othertypes[$key]);
list($sqlqtypetest, $params) = $DB->get_in_or_equal($othertypes, SQL_PARAMS_QM, '', false);
@@ -59,8 +58,7 @@ if ($requestedqtype) {
} else {
$sqlqtypetest = 'WHERE qtype = ?';
$params = array($requestedqtype);
$title = get_string('reportforqtype', 'report_questioninstances',
question_bank::get_qtype($requestedqtype)->local_name());
$title = get_string('reportforqtype', 'report_questioninstances', $QTYPES[$requestedqtype]->local_name());
}
// Get the question counts, and all the context information, for each
-2
View File
@@ -18,8 +18,6 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
$temp->add(new admin_setting_configcheckbox('allowuserblockhiding', get_string('allowuserblockhiding', 'admin'), get_string('configallowuserblockhiding', 'admin'), 1));
$temp->add(new admin_setting_configcheckbox('allowblockstodock', get_string('allowblockstodock', 'admin'), get_string('configallowblockstodock', 'admin'), 1));
$temp->add(new admin_setting_configtextarea('custommenuitems', get_string('custommenuitems', 'admin'), get_string('configcustommenuitems', 'admin'), '', PARAM_TEXT, '50', '10'));
$temp->add(new admin_setting_configcheckbox('enabledevicedetection', get_string('enabledevicedetection', 'admin'), get_string('configenabledevicedetection', 'admin'), 1));
$temp->add(new admin_setting_devicedetectregex('devicedetectregex', get_string('devicedetectregex', 'admin'), get_string('devicedetectregex_desc', 'admin'), ''));
$ADMIN->add('themes', $temp);
$ADMIN->add('themes', new admin_externalpage('themeselector', get_string('themeselector','admin'), $CFG->wwwroot . '/theme/index.php'));
+8 -8
View File
@@ -21,11 +21,10 @@ if ($hassiteconfig
$formcourseformats[$courseformat] = get_string('pluginname', "format_$courseformat");
}
$temp->add(new admin_setting_configselect('moodlecourse/format', get_string('format'), get_string('coursehelpformat'), 'weeks',$formcourseformats));
$temp->add(new admin_setting_configtext('moodlecourse/maxsections', get_string('maxnumberweeks'), get_string('maxnumberweeks_desc'), 52));
$temp->add(new admin_settings_num_course_sections('moodlecourse/numsections', get_string('numberweeks'), get_string('coursehelpnumberweeks'), 10));
for ($i=1; $i<=52; $i++) {
$sectionmenu[$i] = "$i";
}
$temp->add(new admin_setting_configselect('moodlecourse/numsections', get_string('numberweeks'), get_string('coursehelpnumberweeks'), 10,$sectionmenu));
$choices = array();
$choices['0'] = get_string('hiddensectionscollapsed');
$choices['1'] = get_string('hiddensectionsinvisible');
@@ -34,14 +33,15 @@ if ($hassiteconfig
$temp->add(new admin_setting_configselect('moodlecourse/newsitems', get_string('newsitemsnumber'), get_string('coursehelpnewsitemsnumber'), 5,$options));
$temp->add(new admin_setting_configselect('moodlecourse/showgrades', get_string('showgrades'), get_string('coursehelpshowgrades'), 1,array(0 => get_string('no'), 1 => get_string('yes'))));
$temp->add(new admin_setting_configselect('moodlecourse/showreports', get_string('showreports'), '', 0,array(0 => get_string('no'), 1 => get_string('yes'))));
if (isset($CFG->maxbytes)) {
$choices = get_max_upload_sizes($CFG->maxbytes);
} else {
$choices = get_max_upload_sizes();
}
$temp->add(new admin_setting_configselect('moodlecourse/maxbytes', get_string('maximumupload'), get_string('coursehelpmaximumupload'), key($choices), $choices));
if (!empty($CFG->legacyfilesinnewcourses)) {
$choices = array('0'=>get_string('no'), '2'=>get_string('yes'));
$temp->add(new admin_setting_configselect('moodlecourse/legacyfiles', get_string('courselegacyfiles'), get_string('courselegacyfiles_help'), key($choices), $choices));
@@ -142,7 +142,7 @@ if ($hassiteconfig
$temp->add(new admin_setting_heading('automatedsettings', get_string('automatedsettings','backup'), ''));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_users', get_string('users'), get_string('backupusershelp'), 1));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_users', get_string('generalusers', 'backup'), get_string('configgeneralusers', 'backup'), 1));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_role_assignments', get_string('generalroleassignments','backup'), get_string('configgeneralroleassignments','backup'), 1));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_user_files', get_string('generaluserfiles', 'backup'), get_string('configgeneraluserfiles','backup'), 1));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_activities', get_string('generalactivities','backup'), get_string('configgeneralactivities','backup'), 1));
@@ -150,7 +150,7 @@ if ($hassiteconfig
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_filters', get_string('generalfilters','backup'), get_string('configgeneralfilters','backup'), 1));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_comments', get_string('generalcomments','backup'), get_string('configgeneralcomments','backup'), 1));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_userscompletion', get_string('generaluserscompletion','backup'), get_string('configgeneraluserscompletion','backup'), 1));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_logs', get_string('logs'), get_string('backuplogshelp'), 0));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_logs', get_string('generallogs', 'backup'), get_string('configgenerallogs', 'backup'), 0));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_histories', get_string('generalhistories','backup'), get_string('configgeneralhistories','backup'), 0));
+2 -30
View File
@@ -5,7 +5,6 @@
*/
if ($hassiteconfig) {
$ADMIN->add('modules', new admin_page_pluginsoverview());
$ADMIN->add('modules', new admin_category('modsettings', get_string('activitymodules')));
$ADMIN->add('modsettings', new admin_page_managemods());
$modules = $DB->get_records('modules', array(), "name ASC");
@@ -46,27 +45,6 @@ if ($hassiteconfig) {
}
}
// message outputs
$ADMIN->add('modules', new admin_category('messageoutputs', get_string('messageoutputs', 'message')));
$ADMIN->add('messageoutputs', new admin_page_managemessageoutputs());
$ADMIN->add('messageoutputs', new admin_page_defaultmessageoutputs());
require_once($CFG->dirroot.'/message/lib.php');
$processors = get_message_processors();
foreach ($processors as $processor) {
$processorname = $processor->name;
if (!$processor->available) {
continue;
}
if ($processor->hassettings) {
$strprocessorname = get_string('pluginname', 'message_'.$processorname);
$settings = new admin_settingpage('messagesetting'.$processorname, $strprocessorname, 'moodle/site:config', !$processor->enabled);
include($CFG->dirroot.'/message/output/'.$processor->name.'/settings.php');
if ($settings) {
$ADMIN->add('messageoutputs', $settings);
}
}
}
// authentication plugins
$ADMIN->add('modules', new admin_category('authsettings', get_string('authentication', 'admin')));
@@ -74,7 +52,6 @@ if ($hassiteconfig) {
$temp->add(new admin_setting_manageauths());
$temp->add(new admin_setting_heading('manageauthscommonheading', get_string('commonsettings', 'admin'), ''));
$temp->add(new admin_setting_special_registerauth());
$temp->add(new admin_setting_configcheckbox('loginpageautofocus', get_string('loginpageautofocus', 'admin'), get_string('loginpageautofocus_help', 'admin'), 0));
$temp->add(new admin_setting_configselect('guestloginbutton', get_string('guestloginbutton', 'auth'),
get_string('showguestlogin', 'auth'), '1', array('0'=>get_string('hide'), '1'=>get_string('show'))));
$temp->add(new admin_setting_configtext('alternateloginurl', get_string('alternateloginurl', 'auth'),
@@ -344,11 +321,10 @@ if ($hassiteconfig) {
$temp = new admin_settingpage('webservicesoverview', get_string('webservicesoverview', 'webservice'));
$temp->add(new admin_setting_webservicesoverview());
$ADMIN->add('webservicesettings', $temp);
//API documentation
$ADMIN->add('webservicesettings', new admin_externalpage('webservicedocumentation', get_string('wsdocapi', 'webservice'), "$CFG->wwwroot/$CFG->admin/webservice/documentation.php", 'moodle/site:config', false));
/// manage service
$temp = new admin_settingpage('externalservices', get_string('externalservices', 'webservice'));
$enablemobiledocurl = new moodle_url(get_docs_url('Enable_mobile_web_services'));
$enablemobiledoclink = html_writer::link($enablemobiledocurl, get_string('documentation'));
$temp->add(new admin_setting_enablemobileservice('enablemobilewebservice', get_string('enablemobilewebservice', 'admin'), get_string('configenablemobilewebservice', 'admin', $enablemobiledoclink), 0));
$temp->add(new admin_setting_heading('manageserviceshelpexplaination', get_string('information', 'webservice'), get_string('servicehelpexplanation', 'webservice')));
$temp->add(new admin_setting_manageexternalservices());
$ADMIN->add('webservicesettings', $temp);
@@ -395,10 +371,6 @@ if ($hassiteconfig) {
// Question type settings
if ($hassiteconfig || has_capability('moodle/question:config', $systemcontext)) {
// Question behaviour settings.
$ADMIN->add('modules', new admin_category('qbehavioursettings', get_string('questionbehaviours', 'admin')));
$ADMIN->add('qbehavioursettings', new admin_page_manageqbehaviours());
// Question type settings.
$ADMIN->add('modules', new admin_category('qtypesettings', get_string('questiontypes', 'admin')));
$ADMIN->add('qtypesettings', new admin_page_manageqtypes());
+9 -3
View File
@@ -71,6 +71,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
$temp->add(new admin_setting_configcheckbox('groupenrolmentkeypolicy', get_string('groupenrolmentkeypolicy', 'admin'), get_string('groupenrolmentkeypolicy_desc', 'admin'), 1));
$temp->add(new admin_setting_configcheckbox('disableuserimages', get_string('disableuserimages', 'admin'), get_string('configdisableuserimages', 'admin'), 0));
$temp->add(new admin_setting_configcheckbox('emailchangeconfirmation', get_string('emailchangeconfirmation', 'admin'), get_string('configemailchangeconfirmation', 'admin'), 1));
$temp->add(new admin_setting_configcheckbox('strictformsrequired', get_string('strictformsrequired', 'admin'), get_string('configstrictformsrequired', 'admin'), 0));
$ADMIN->add('security', $temp);
@@ -91,9 +92,14 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
'all' => get_string('fulllistofcourses'),
'requested' => get_string('requestedcourses'))));
$temp->add(new admin_setting_configcheckbox('restrictbydefault', get_string('restrictbydefault', 'admin'), get_string('configrestrictbydefault', 'admin'), 0));
$temp->add(new admin_setting_configmultiselect_modules('defaultallowedmodules',
get_string('defaultallowedmodules', 'admin'),
get_string('configdefaultallowedmodules', 'admin')));
if (!$options = $DB->get_records('modules')) {
$options = array();
}
$options2 = array();
foreach ($options as $option) {
$options2[$option->id] = $option->name;
}
$temp->add(new admin_setting_configmultiselect('defaultallowedmodules', get_string('defaultallowedmodules', 'admin'), get_string('configdefaultallowedmodules', 'admin'), array(), $options2));
$ADMIN->add('security', $temp);
+51 -2
View File
@@ -17,8 +17,46 @@ $ADMIN->add('server', $temp);
// "supportcontact" settingpage
$temp = new admin_settingpage('supportcontact', get_string('supportcontact','admin'));
// "email" settingpage
$temp = new admin_settingpage('mail', get_string('mail','admin'));
$temp->add(new admin_setting_configtext('smtphosts', get_string('smtphosts', 'admin'), get_string('configsmtphosts', 'admin'), '', PARAM_RAW));
$temp->add(new admin_setting_configtext('smtpuser', get_string('smtpuser', 'admin'), get_string('configsmtpuser', 'admin'), '', PARAM_NOTAGS));
$temp->add(new admin_setting_configpasswordunmask('smtppass', get_string('smtppass', 'admin'), get_string('configsmtpuser', 'admin'), ''));
$temp->add(new admin_setting_configtext('smtpmaxbulk', get_string('smtpmaxbulk', 'admin'), get_string('configsmtpmaxbulk', 'admin'), 1, PARAM_INT));
$temp->add(new admin_setting_configtext('noreplyaddress', get_string('noreplyaddress', 'admin'), get_string('confignoreplyaddress', 'admin'), 'noreply@' . get_host_from_url($CFG->wwwroot), PARAM_NOTAGS));
$temp->add(new admin_setting_configselect('digestmailtime', get_string('digestmailtime', 'admin'), get_string('configdigestmailtime', 'admin'), 17, array('00' => '00',
'01' => '01',
'02' => '02',
'03' => '03',
'04' => '04',
'05' => '05',
'06' => '06',
'07' => '07',
'08' => '08',
'09' => '09',
'10' => '10',
'11' => '11',
'12' => '12',
'13' => '13',
'14' => '14',
'15' => '15',
'16' => '16',
'17' => '17',
'18' => '18',
'19' => '19',
'20' => '20',
'21' => '21',
'22' => '22',
'23' => '23')));
$charsets = get_list_of_charsets();
unset($charsets['UTF-8']); // not needed here
$options = array();
$options['0'] = 'UTF-8';
$options = array_merge($options, $charsets);
$temp->add(new admin_setting_configselect('sitemailcharset', get_string('sitemailcharset', 'admin'), get_string('configsitemailcharset','admin'), '0', $options));
$temp->add(new admin_setting_configcheckbox('allowusermailcharset', get_string('allowusermailcharset', 'admin'), get_string('configallowusermailcharset', 'admin'), 0));
$options = array('LF'=>'LF', 'CRLF'=>'CRLF');
$temp->add(new admin_setting_configselect('mailnewline', get_string('mailnewline', 'admin'), get_string('configmailnewline','admin'), 'LF', $options));
if (isloggedin()) {
global $USER;
$primaryadminemail = $USER->email;
@@ -35,6 +73,17 @@ $temp->add(new admin_setting_configtext('supportpage', get_string('supportpage',
$ADMIN->add('server', $temp);
// Jabber settingpage
$temp = new admin_settingpage('jabber', get_string('jabber', 'admin'));
$temp->add(new admin_setting_configtext('jabberhost', get_string('jabberhost', 'admin'), get_string('configjabberhost', 'admin'), '', PARAM_RAW));
$temp->add(new admin_setting_configtext('jabberserver', get_string('jabberserver', 'admin'), get_string('configjabberserver', 'admin'), '', PARAM_RAW));
$temp->add(new admin_setting_configtext('jabberusername', get_string('jabberusername', 'admin'), get_string('configjabberusername', 'admin'), '', PARAM_RAW));
$temp->add(new admin_setting_configpasswordunmask('jabberpassword', get_string('jabberpassword', 'admin'), get_string('configjabberpassword', 'admin'), ''));
$temp->add(new admin_setting_configtext('jabberport', get_string('jabberport', 'admin'), get_string('configjabberport', 'admin'), 5222, PARAM_INT));
$ADMIN->add('server', $temp);
// "sessionhandling" settingpage
$temp = new admin_settingpage('sessionhandling', get_string('sessionhandling', 'admin'));
$temp->add(new admin_setting_configcheckbox('dbsessions', get_string('dbsessions', 'admin'), get_string('configdbsessions', 'admin'), 1));
+61
View File
@@ -0,0 +1,61 @@
<?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/>.
/**
* Web services API documentation
*
* @package webservice
* @copyright 2011 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Jerome Mouneyrac
*/
require_once('../../config.php');
require_once($CFG->libdir . '/adminlib.php');
require($CFG->dirroot . '/webservice/lib.php');
admin_externalpage_setup('webservicedocumentation');
// get all the function descriptions
$functions = $DB->get_records('external_functions', array(), 'name');
$functiondescs = array();
foreach ($functions as $function) {
$functiondescs[$function->name] = external_function_info($function);
}
//display the documentation for all documented protocols,
//regardless if they are activated or not
$protocols = array();
$protocols['rest'] = true;
$protocols['xmlrpc'] = true;
/// Check if we are in printable mode
$printableformat = optional_param('print', false, PARAM_BOOL);
/// OUTPUT
echo $OUTPUT->header();
$renderer = $PAGE->get_renderer('core', 'webservice');
echo $renderer->documentation_html($functiondescs,
$printableformat, $protocols, array(), $PAGE->url);
/// trigger browser print operation
if (!empty($printableformat)) {
$PAGE->requires->js_function_call('window.print', array());
}
echo $OUTPUT->footer();
+36 -1
View File
@@ -360,7 +360,7 @@ class auth_plugin_cas extends auth_plugin_ldap {
* @return boolean result
*/
function iscreator($username) {
if ((empty($this->config->attrcreators) && empty($this->config->groupecreators)) or empty($this->config->memberattribute)) {
if (empty($this->config->host_url) or (empty($this->config->attrcreators) && empty($this->config->groupecreators)) or empty($this->config->memberattribute)) {
return false;
}
@@ -405,4 +405,39 @@ class auth_plugin_cas extends auth_plugin_ldap {
return false;
}
/**
* Reads user information from LDAP and returns it as array()
*
* If no LDAP servers are configured, user information has to be
* provided via other methods (CSV file, manually, etc.). Return
* an empty array so existing user info is not lost. Otherwise,
* calls parent class method to get user info.
*
* @param string $username username
* @return mixed array with no magic quotes or false on error
*/
function get_userinfo($username) {
if (empty($this->config->host_url)) {
return array();
}
return parent::get_userinfo($username);
}
/**
* Syncronizes users from LDAP server to moodle user table.
*
* If no LDAP servers are configured, simply return. Otherwise,
* call parent class method to do the work.
*
* @param bool $do_updates will do pull in data updates from LDAP if relevant
* @return nothing
*/
function sync_users($do_updates=true) {
if (empty($this->config->host_url)) {
error_log('[AUTH CAS] '.get_string('noldapserver', 'auth_cas'));
return;
}
parent::sync_users($do_updates);
}
}
+1
View File
@@ -61,4 +61,5 @@ $string['auth_cas_text'] = 'Secure connection';
$string['auth_cas_use_cas'] = 'Use CAS';
$string['auth_cas_version'] = 'Version of CAS';
$string['CASform'] = 'Authentication choice';
$string['noldapserver'] = 'No LDAP server configured for CAS! Syncing disabled.';
$string['pluginname'] = 'CAS server (SSO)';
+15
View File
@@ -24,8 +24,23 @@
*/
$string['auth_emaildescription'] = 'Email confirmation is the default authentication method. When the user signs up, choosing their own new username and password, a confirmation email is sent to the user\'s email address. This email contains a secure link to a page where the user can confirm their account. Future logins just check the username and password against the stored values in the Moodle database.';
$string['auth_emailchangecancel'] = 'Cancel email change';
$string['auth_emailchangepending'] = 'Change pending. Open the link sent to you at {$a->preference_newemail}.';
$string['auth_emailnoemail'] = 'Tried to send you an email but failed!';
$string['auth_emailnoinsert'] = 'Could not add your record to the database!';
$string['auth_emailnowexists'] = 'The email address you tried to assign to your profile has been assigned to someone else since your original request. Your request for change of email address is hereby cancelled, but you may try again with a different address.';
$string['auth_emailrecaptcha'] = 'Adds a visual/audio confirmation form element to the signup page for email self-registering users. This protects your site against spammers and contributes to a worthwhile cause. See http://www.google.com/recaptcha/learnmore for more details. <br /><em>PHP cURL extension is required.</em>';
$string['auth_emailrecaptcha_key'] = 'Enable reCAPTCHA element';
$string['auth_emailsettings'] = 'Settings';
$string['auth_emailupdate'] = 'Email address update';
$string['auth_emailupdatemessage'] = 'Dear {$a->fullname},
You have requested a change of your email address for your user account at {$a->site}. Please open the following URL in your browser in order to confirm this change.
{$a->url}';
$string['auth_emailupdatesuccess'] = 'Email address of user <em>{$a->fullname}</em> was successfully updated to <em>{$a->email}</em>.';
$string['auth_emailupdatetitle'] = 'Confirmation of email update at {$a->site}';
$string['auth_changingemailaddress'] = 'You have requested a change of email address, from {$a->oldemail} to {$a->newemail}. For security reasons, we are sending you an email message at the new address to confirm that it belongs to you. Your email address will be updated as soon as you open the URL sent to you in that message.';
$string['auth_invalidnewemailkey'] = 'Error: if you are trying to confirm a change of email address, you may have made a mistake in copying the URL we sent you by email. Please copy the address and try again.';
$string['auth_outofnewemailupdateattempts'] = 'You have run out of allowed attempts to update your email address. Your update request has been cancelled.';
$string['pluginname'] = 'Email-based self-registration';
+1 -1
View File
@@ -1,3 +1,3 @@
LDAP-module README
Please read comments from lib.php
Please read comments from auth.php in this directory.
+12 -11
View File
@@ -502,7 +502,7 @@ class auth_plugin_ldap extends auth_plugin_base {
events_trigger('user_created', $user);
if (! send_confirmation_email($user)) {
print_error('noemail', 'auth_ldap');
print_error('auth_emailnoemail', 'auth_email');
}
if ($notify) {
@@ -579,16 +579,17 @@ class auth_plugin_ldap extends auth_plugin_base {
$sr = ldap_read($ldapconnection, $user_dn, '(objectClass=*)', $search_attribs);
if ($sr) {
$info = ldap_get_entries_moodle($ldapconnection, $sr);
$info = array_change_key_case($info, CASE_LOWER);
if (!empty ($info) and !empty($info[0][$this->config->expireattr][0])) {
$expiretime = $this->ldap_expirationtime2unix($info[0][$this->config->expireattr][0], $ldapconnection, $user_dn);
if ($expiretime != 0) {
$now = time();
if ($expiretime > $now) {
$result = ceil(($expiretime - $now) / DAYSECS);
}
else {
$result = floor(($expiretime - $now) / DAYSECS);
if (!empty ($info)) {
$info = array_change_key_case($info[0], CASE_LOWER);
if (!empty($info[$this->config->expireattr][0])) {
$expiretime = $this->ldap_expirationtime2unix($info[$this->config->expireattr][0], $ldapconnection, $user_dn);
if ($expiretime != 0) {
$now = time();
if ($expiretime > $now) {
$result = ceil(($expiretime - $now) / DAYSECS);
} else {
$result = floor(($expiretime - $now) / DAYSECS);
}
}
}
}
-1
View File
@@ -114,7 +114,6 @@ $string['morethanoneuser'] = 'Strange! More than one user record found in ldap.
$string['needbcmath'] = 'You need the BCMath extension to use grace logins with Active Directory';
$string['needmbstring'] = 'You need the mbstring extension to change passwords in Active Directory';
$string['nodnforusername'] = 'Error in user_update_password(). No DN for: {$a->username}';
$string['noemail'] = 'Tried to send you an email but failed!';
$string['notcalledfromserver'] = 'Should not be called from the web server!';
$string['noupdatestobedone'] = "No updates to be done\n";
$string['nouserentriestoremove'] = "No user entries to be removed\n";
-3
View File
@@ -45,8 +45,5 @@ function xmldb_auth_manual_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2011022700, 'auth', 'manual');
}
// Moodle v2.1.0 release upgrade line
// Put any upgrade step following this
return true;
}
+1 -2
View File
@@ -276,6 +276,7 @@ class auth_plugin_mnet extends auth_plugin_base {
*/
$remoteuser->mnethostid = $remotehost->id;
$remoteuser->firstaccess = time(); // First time user in this server, grab it here
$remoteuser->confirmed = 1;
$remoteuser->id = $DB->insert_record('user', $remoteuser);
$firsttime = true;
@@ -889,8 +890,6 @@ class auth_plugin_mnet extends auth_plugin_base {
global $CFG, $DB;
$remoteclient = get_mnet_remote_client();
$CFG->usesid = true;
// We don't want to output anything to the client machine
$start = ob_start();
-3
View File
@@ -43,8 +43,5 @@ function xmldb_auth_mnet_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2010071300, 'auth', 'mnet');
}
// Moodle v2.1.0 release upgrade line
// Put any upgrade step following this
return true;
}
+5 -10
View File
@@ -193,18 +193,13 @@ class auth_plugin_shibboleth extends auth_plugin_base {
*
*/
function logoutpage_hook() {
global $redirect;
global $SESSION, $redirect;
// Only do this if logout handler is defined
if (
isset($this->config->logout_handler)
&& !empty($this->config->logout_handler)
){
// Only do this if logout handler is defined, and if the user is actually logged in via Shibboleth
$logouthandlervalid = isset($this->config->logout_handler) && !empty($this->config->logout_handler);
if ( isset($SESSION->shibboleth_session_id) && $logouthandlervalid) {
// Check if there is an alternative logout return url defined
if (
isset($this->config->logout_return_url)
&& !empty($this->config->logout_return_url)
){
if (isset($this->config->logout_return_url) && !empty($this->config->logout_return_url)) {
// Set temp_redirect to alternative return url
$temp_redirect = $this->config->logout_return_url;
} else {
+3 -4
View File
@@ -54,7 +54,6 @@ abstract class backup implements checksumable {
const MODE_HUB = 30;
const MODE_SAMESITE = 40;
const MODE_AUTOMATED = 50;
const MODE_CONVERTED = 60;
// Target (new/existing/current/adding/deleting)
const TARGET_CURRENT_DELETING = 0;
@@ -108,8 +107,8 @@ abstract class backup implements checksumable {
const OPERATION_RESTORE ='restore';// We are performing one restore
// Version (to keep CFG->backup_version (and release) updated automatically)
const VERSION = 2011063000;
const RELEASE = '2.1';
const VERSION = 2010111800;
const RELEASE = '2.0';
}
/*
@@ -118,6 +117,6 @@ abstract class backup implements checksumable {
abstract class backup_exception extends moodle_exception {
public function __construct($errorcode, $a=NULL, $debuginfo=null) {
parent::__construct($errorcode, 'error', '', $a, $debuginfo);
parent::__construct($errorcode, 'error', '', $a, null, $debuginfo);
}
}
+2
View File
@@ -92,3 +92,5 @@ define('MOODLE_QUIZ_MULTIPLE_RESPONSE', 'multichoice');
define('MOODLE_QUIZ_MACHT', 'match');
define('MOODLE_QUIZ_ESSAY', 'essay');
define('MOODLE_QUIZ_SHORTANSWER', 'shortanswer');
?>
@@ -339,7 +339,7 @@ class backup_controller extends backup implements loggable {
protected function apply_defaults() {
$this->log('applying plan defaults', backup::LOG_DEBUG);
backup_controller_dbops::apply_general_config_defaults($this);
backup_controller_dbops::apply_config_defaults($this);
$this->set_status(backup::STATUS_CONFIGURED);
}
}
+21 -27
View File
@@ -380,44 +380,38 @@ class restore_controller extends backup implements loggable {
}
/**
* Converts from current format to backup::MOODLE format
* convert from current format to backup::MOODLE format
*/
public function convert() {
global $CFG;
require_once($CFG->dirroot . '/backup/util/helper/convert_helper.class.php');
// Basic/initial prevention against time/memory limits
set_time_limit(1 * 60 * 60); // 1 hour for 1 course initially granted
raise_memory_limit(MEMORY_EXTRA);
if ($this->status != backup::STATUS_REQUIRE_CONV) {
throw new restore_controller_exception('cannot_convert_not_required_status');
}
$this->log('backup format conversion required', backup::LOG_INFO);
// Run conversion to the proper format
if (!convert_helper::to_moodle2_format($this->get_tempdir(), $this->format, $this->get_logger())) {
// todo - unable to find the conversion path, what to do now?
// throwing the exception as a temporary solution
throw new restore_controller_exception('unable_to_find_conversion_path');
if ($this->format == backup::FORMAT_UNKNOWN) {
throw new restore_controller_exception('cannot_convert_from_unknown_format');
}
if ($this->format == backup::FORMAT_MOODLE1) {
// TODO: Implement moodle1 => moodle2 conversion
throw new restore_controller_exception('cannot_convert_yet_from_moodle1_format');
}
$this->log('backup format conversion successful', backup::LOG_INFO);
// Once conversions have finished, we check again the format
$newformat = backup_general_helper::detect_backup_format($tempdir);
// If no exceptions were thrown, then we are in the proper format
$this->format = backup::FORMAT_MOODLE;
// If format is moodle2, load plan, apply security and set status based on interactivity
if ($newformat === backup::FORMAT_MOODLE) {
// Load plan
$this->load_plan();
// Load plan, apply security and set status based on interactivity
$this->load_plan();
// Perform all initial security checks and apply (2nd param) them to settings automatically
restore_check::check_security($this, true);
// Perform all initial security checks and apply (2nd param) them to settings automatically
restore_check::check_security($this, true);
if ($this->interactive == backup::INTERACTIVE_YES) {
$this->set_status(backup::STATUS_SETTING_UI);
if ($this->interactive == backup::INTERACTIVE_YES) {
$this->set_status(backup::STATUS_SETTING_UI);
} else {
$this->set_status(backup::STATUS_NEED_PRECHECK);
}
} else {
$this->set_status(backup::STATUS_NEED_PRECHECK);
throw new restore_controller_exception('conversion_ended_with_wrong_format', $newformat);
}
}
-286
View File
@@ -1,286 +0,0 @@
<?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/>.
/**
* Provides base converter classes
*
* @package core
* @subpackage backup-convert
* @copyright 2011 Mark Nielsen <mark@moodlerooms.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/backup/util/includes/convert_includes.php');
/**
* Base converter class
*
* All Moodle backup converters are supposed to extend this base class.
*
* @throws convert_exception
*/
abstract class base_converter implements loggable {
/** @var string unique identifier of this converter instance */
protected $id;
/** @var string the name of the directory containing the unpacked backup being converted */
protected $tempdir;
/** @var string the name of the directory where the backup is converted to */
protected $workdir;
/** @var null|base_logger logger to use during the conversion */
protected $logger = null;
/**
* Constructor
*
* @param string $tempdir the relative path to the directory containing the unpacked backup to convert
* @param null|base_logger logger to use during the conversion
*/
public function __construct($tempdir, $logger = null) {
$this->tempdir = $tempdir;
$this->id = convert_helper::generate_id($tempdir);
$this->workdir = $tempdir . '_' . $this->get_name() . '_' . $this->id;
$this->set_logger($logger);
$this->log('instantiating '.$this->get_name().' converter '.$this->get_id(), backup::LOG_DEBUG);
$this->log('conversion source directory', backup::LOG_DEBUG, $this->tempdir);
$this->log('conversion target directory', backup::LOG_DEBUG, $this->workdir);
$this->init();
}
/**
* Sets the logger to use during the conversion
*
* @param null|base_logger $logger
*/
public function set_logger($logger) {
if (is_null($logger) or ($logger instanceof base_logger)) {
$this->logger = $logger;
}
}
/**
* If the logger was set for the converter, log the message
*
* If the $display is enabled, the spaces in the $message text are removed
* and the text is used as a string identifier in the core_backup language file.
*
* @see backup_helper::log()
* @param string $message message text
* @param int $level message level {@example backup::LOG_WARNING}
* @param null|mixed $a additional information
* @param null|int $depth the message depth
* @param bool $display whether the message should be sent to the output, too
*/
public function log($message, $level, $a = null, $depth = null, $display = false) {
if ($this->logger instanceof base_logger) {
backup_helper::log($message, $level, $a, $depth, $display, $this->logger);
}
}
/**
* Get instance identifier
*
* @return string the unique identifier of this converter instance
*/
public function get_id() {
return $this->id;
}
/**
* Get converter name
*
* @return string the system name of the converter
*/
public function get_name() {
return array_shift(explode('_', get_class($this)));
}
/**
* Converts the backup directory
*/
public function convert() {
try {
$this->log('creating the target directory', backup::LOG_DEBUG);
$this->create_workdir();
$this->log('executing the conversion', backup::LOG_DEBUG);
$this->execute();
$this->log('replacing the source directory with the converted version', backup::LOG_DEBUG);
$this->replace_tempdir();
} catch (Exception $e) {
}
// clean-up stuff if needed
$this->destroy();
// eventually re-throw the execution exception
if (isset($e) and ($e instanceof Exception)) {
throw $e;
}
}
/**
* @return string the full path to the working directory
*/
public function get_workdir_path() {
global $CFG;
return "$CFG->dataroot/temp/backup/$this->workdir";
}
/**
* @return string the full path to the directory with the source backup
*/
public function get_tempdir_path() {
global $CFG;
return "$CFG->dataroot/temp/backup/$this->tempdir";
}
/// public static methods //////////////////////////////////////////////////
/**
* Makes sure that this converter is available at this site
*
* This is intended for eventual PHP extensions check, environment check etc.
* All checks that do not depend on actual backup data should be done here.
*
* @return boolean true if this converter should be considered as available
*/
public static function is_available() {
return true;
}
/**
* Detects the format of the backup directory
*
* Moodle 2.x format is being detected by the core itself. The converters are
* therefore supposed to detect the source format. Eventually, if the target
* format os not {@link backup::FORMAT_MOODLE} then they should be able to
* detect both source and target formats.
*
* @param string $tempdir the name of the backup directory
* @return null|string null if not recognized, backup::FORMAT_xxx otherwise
*/
public static function detect_format($tempdir) {
return null;
}
/**
* Returns the basic information about the converter
*
* The returned array must contain the following keys:
* 'from' - the supported source format, eg. backup::FORMAT_MOODLE1
* 'to' - the supported target format, eg. backup::FORMAT_MOODLE
* 'cost' - the cost of the conversion, non-negative non-zero integer
*/
public static function description() {
return array(
'from' => null,
'to' => null,
'cost' => null,
);
}
/// end of public API //////////////////////////////////////////////////////
/**
* Initialize the instance if needed, called by the constructor
*/
protected function init() {
}
/**
* Converts the contents of the tempdir into the target format in the workdir
*/
protected abstract function execute();
/**
* Prepares a new empty working directory
*/
protected function create_workdir() {
fulldelete($this->get_workdir_path());
if (!check_dir_exists($this->get_workdir_path())) {
throw new convert_exception('failed_create_workdir');
}
}
/**
* Replaces the source backup directory with the converted version
*
* If $CFG->keeptempdirectoriesonbackup is defined, the original source
* source backup directory is kept for debugging purposes.
*/
protected function replace_tempdir() {
global $CFG;
if (empty($CFG->keeptempdirectoriesonbackup)) {
fulldelete($this->get_tempdir_path());
} else {
if (!rename($this->get_tempdir_path(), $this->get_tempdir_path() . '_' . $this->get_name() . '_' . $this->id . '_source')) {
throw new convert_exception('failed_rename_source_tempdir');
}
}
if (!rename($this->get_workdir_path(), $this->get_tempdir_path())) {
throw new convert_exception('failed_move_converted_into_place');
}
}
/**
* Cleans up stuff after the execution
*
* Note that we do not know if the execution was successful or not.
* An exception might have been thrown.
*/
protected function destroy() {
global $CFG;
if (empty($CFG->keeptempdirectoriesonbackup)) {
fulldelete($this->get_workdir_path());
}
}
}
/**
* General convert-related exception
*
* @author David Mudrak <david@moodle.com>
*/
class convert_exception extends moodle_exception {
/**
* Constructor
*
* @param string $errorcode key for the corresponding error string
* @param object $a extra words and phrases that might be required in the error string
* @param string $debuginfo optional debugging information
*/
public function __construct($errorcode, $a = null, $debuginfo = null) {
parent::__construct($errorcode, '', '', $a, $debuginfo);
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

@@ -1,602 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<MOODLE_BACKUP>
<INFO>
<NAME>restore.zip</NAME>
<MOODLE_VERSION>2007101520</MOODLE_VERSION>
<MOODLE_RELEASE>1.9.2 (Build: 20080711)</MOODLE_RELEASE>
<BACKUP_VERSION>2008030300</BACKUP_VERSION>
<BACKUP_RELEASE>1.9</BACKUP_RELEASE>
<DATE>1299774017</DATE>
<ORIGINAL_WWWROOT>http://elearning-testadam.uss.lsu.edu/moodle</ORIGINAL_WWWROOT>
<ZIP_METHOD>internal</ZIP_METHOD>
<DETAILS>
<MOD>
<NAME>forum</NAME>
<INCLUDED>true</INCLUDED>
<USERINFO>false</USERINFO>
<INSTANCES>
<INSTANCE>
<ID>57</ID>
<NAME>News forum</NAME>
<INCLUDED>true</INCLUDED>
<USERINFO>false</USERINFO>
</INSTANCE>
</INSTANCES>
</MOD>
<METACOURSE>false</METACOURSE>
<USERS>course</USERS>
<LOGS>false</LOGS>
<USERFILES>true</USERFILES>
<COURSEFILES>true</COURSEFILES>
<SITEFILES>true</SITEFILES>
<GRADEBOOKHISTORIES>false</GRADEBOOKHISTORIES>
<MESSAGES>false</MESSAGES>
<BLOGS>false</BLOGS>
<BLOCKFORMAT>instances</BLOCKFORMAT>
</DETAILS>
</INFO>
<ROLES>
</ROLES>
<COURSE>
<HEADER>
<ID>33</ID>
<CATEGORY>
<ID>1</ID>
<NAME>Miscellaneous</NAME>
</CATEGORY>
<PASSWORD></PASSWORD>
<FULLNAME>Moodle 2.0 Test Restore</FULLNAME>
<SHORTNAME>M2TR</SHORTNAME>
<IDNUMBER></IDNUMBER>
<SUMMARY>Cazzin'</SUMMARY>
<FORMAT>weeks</FORMAT>
<SHOWGRADES>1</SHOWGRADES>
<NEWSITEMS>5</NEWSITEMS>
<TEACHER>Teacher</TEACHER>
<TEACHERS>Teachers</TEACHERS>
<STUDENT>Student</STUDENT>
<STUDENTS>Students</STUDENTS>
<GUEST>0</GUEST>
<STARTDATE>1299823200</STARTDATE>
<NUMSECTIONS>10</NUMSECTIONS>
<MAXBYTES>52428800</MAXBYTES>
<SHOWREPORTS>0</SHOWREPORTS>
<GROUPMODE>0</GROUPMODE>
<GROUPMODEFORCE>0</GROUPMODEFORCE>
<DEFAULTGROUPINGID>0</DEFAULTGROUPINGID>
<LANG></LANG>
<THEME></THEME>
<COST></COST>
<CURRENCY>USD</CURRENCY>
<MARKER>0</MARKER>
<VISIBLE>1</VISIBLE>
<HIDDENSECTIONS>0</HIDDENSECTIONS>
<TIMECREATED>1299773769</TIMECREATED>
<TIMEMODIFIED>1299773769</TIMEMODIFIED>
<METACOURSE>0</METACOURSE>
<EXPIRENOTIFY>0</EXPIRENOTIFY>
<NOTIFYSTUDENTS>0</NOTIFYSTUDENTS>
<EXPIRYTHRESHOLD>864000</EXPIRYTHRESHOLD>
<ENROLLABLE>1</ENROLLABLE>
<ENROLSTARTDATE>0</ENROLSTARTDATE>
<ENROLENDDATE>0</ENROLENDDATE>
<ENROLPERIOD>0</ENROLPERIOD>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
<ROLES_ASSIGNMENTS>
</ROLES_ASSIGNMENTS>
</HEADER>
<BLOCKS>
<BLOCK>
<ID>314</ID>
<NAME>participants</NAME>
<PAGEID>33</PAGEID>
<PAGETYPE>course-view</PAGETYPE>
<POSITION>l</POSITION>
<WEIGHT>0</WEIGHT>
<VISIBLE>1</VISIBLE>
<CONFIGDATA>Tjs=</CONFIGDATA>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
<ROLES_ASSIGNMENTS>
</ROLES_ASSIGNMENTS>
</BLOCK>
<BLOCK>
<ID>315</ID>
<NAME>activity_modules</NAME>
<PAGEID>33</PAGEID>
<PAGETYPE>course-view</PAGETYPE>
<POSITION>l</POSITION>
<WEIGHT>1</WEIGHT>
<VISIBLE>1</VISIBLE>
<CONFIGDATA>Tjs=</CONFIGDATA>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
<ROLES_ASSIGNMENTS>
</ROLES_ASSIGNMENTS>
</BLOCK>
<BLOCK>
<ID>316</ID>
<NAME>search_forums</NAME>
<PAGEID>33</PAGEID>
<PAGETYPE>course-view</PAGETYPE>
<POSITION>l</POSITION>
<WEIGHT>2</WEIGHT>
<VISIBLE>1</VISIBLE>
<CONFIGDATA>Tjs=</CONFIGDATA>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
<ROLES_ASSIGNMENTS>
</ROLES_ASSIGNMENTS>
</BLOCK>
<BLOCK>
<ID>317</ID>
<NAME>admin</NAME>
<PAGEID>33</PAGEID>
<PAGETYPE>course-view</PAGETYPE>
<POSITION>l</POSITION>
<WEIGHT>3</WEIGHT>
<VISIBLE>1</VISIBLE>
<CONFIGDATA>Tjs=</CONFIGDATA>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
<ROLES_ASSIGNMENTS>
</ROLES_ASSIGNMENTS>
</BLOCK>
<BLOCK>
<ID>318</ID>
<NAME>course_list</NAME>
<PAGEID>33</PAGEID>
<PAGETYPE>course-view</PAGETYPE>
<POSITION>l</POSITION>
<WEIGHT>4</WEIGHT>
<VISIBLE>1</VISIBLE>
<CONFIGDATA>Tjs=</CONFIGDATA>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
<ROLES_ASSIGNMENTS>
</ROLES_ASSIGNMENTS>
</BLOCK>
<BLOCK>
<ID>319</ID>
<NAME>news_items</NAME>
<PAGEID>33</PAGEID>
<PAGETYPE>course-view</PAGETYPE>
<POSITION>r</POSITION>
<WEIGHT>0</WEIGHT>
<VISIBLE>1</VISIBLE>
<CONFIGDATA>Tjs=</CONFIGDATA>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
<ROLES_ASSIGNMENTS>
</ROLES_ASSIGNMENTS>
</BLOCK>
<BLOCK>
<ID>320</ID>
<NAME>calendar_upcoming</NAME>
<PAGEID>33</PAGEID>
<PAGETYPE>course-view</PAGETYPE>
<POSITION>r</POSITION>
<WEIGHT>1</WEIGHT>
<VISIBLE>1</VISIBLE>
<CONFIGDATA>Tjs=</CONFIGDATA>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
<ROLES_ASSIGNMENTS>
</ROLES_ASSIGNMENTS>
</BLOCK>
<BLOCK>
<ID>321</ID>
<NAME>recent_activity</NAME>
<PAGEID>33</PAGEID>
<PAGETYPE>course-view</PAGETYPE>
<POSITION>r</POSITION>
<WEIGHT>2</WEIGHT>
<VISIBLE>1</VISIBLE>
<CONFIGDATA>Tjs=</CONFIGDATA>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
<ROLES_ASSIGNMENTS>
</ROLES_ASSIGNMENTS>
</BLOCK>
</BLOCKS>
<SECTIONS>
<SECTION>
<ID>436</ID>
<NUMBER>0</NUMBER>
<SUMMARY>$@NULL@$</SUMMARY>
<VISIBLE>1</VISIBLE>
<MODS>
<MOD>
<ID>250</ID>
<TYPE>forum</TYPE>
<INSTANCE>57</INSTANCE>
<ADDED>1299773780</ADDED>
<SCORE>0</SCORE>
<INDENT>0</INDENT>
<VISIBLE>1</VISIBLE>
<GROUPMODE>0</GROUPMODE>
<GROUPINGID>0</GROUPINGID>
<GROUPMEMBERSONLY>0</GROUPMEMBERSONLY>
<IDNUMBER>$@NULL@$</IDNUMBER>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
<ROLES_ASSIGNMENTS>
</ROLES_ASSIGNMENTS>
</MOD>
</MODS>
</SECTION>
<SECTION>
<ID>437</ID>
<NUMBER>1</NUMBER>
<SUMMARY></SUMMARY>
<VISIBLE>1</VISIBLE>
</SECTION>
<SECTION>
<ID>438</ID>
<NUMBER>2</NUMBER>
<SUMMARY></SUMMARY>
<VISIBLE>1</VISIBLE>
</SECTION>
<SECTION>
<ID>439</ID>
<NUMBER>3</NUMBER>
<SUMMARY></SUMMARY>
<VISIBLE>1</VISIBLE>
</SECTION>
<SECTION>
<ID>440</ID>
<NUMBER>4</NUMBER>
<SUMMARY></SUMMARY>
<VISIBLE>1</VISIBLE>
</SECTION>
<SECTION>
<ID>441</ID>
<NUMBER>5</NUMBER>
<SUMMARY></SUMMARY>
<VISIBLE>1</VISIBLE>
</SECTION>
<SECTION>
<ID>442</ID>
<NUMBER>6</NUMBER>
<SUMMARY></SUMMARY>
<VISIBLE>1</VISIBLE>
</SECTION>
<SECTION>
<ID>443</ID>
<NUMBER>7</NUMBER>
<SUMMARY></SUMMARY>
<VISIBLE>1</VISIBLE>
</SECTION>
<SECTION>
<ID>444</ID>
<NUMBER>8</NUMBER>
<SUMMARY></SUMMARY>
<VISIBLE>1</VISIBLE>
</SECTION>
<SECTION>
<ID>445</ID>
<NUMBER>9</NUMBER>
<SUMMARY></SUMMARY>
<VISIBLE>1</VISIBLE>
</SECTION>
<SECTION>
<ID>446</ID>
<NUMBER>10</NUMBER>
<SUMMARY></SUMMARY>
<VISIBLE>1</VISIBLE>
</SECTION>
</SECTIONS>
<USERS>
<USER>
<ID>2</ID>
<AUTH>manual</AUTH>
<CONFIRMED>1</CONFIRMED>
<POLICYAGREED>0</POLICYAGREED>
<DELETED>0</DELETED>
<USERNAME>admin</USERNAME>
<PASSWORD>ea557cf33bda866d97b07465f1ea3867</PASSWORD>
<IDNUMBER>891220979</IDNUMBER>
<FIRSTNAME>Admin</FIRSTNAME>
<LASTNAME>User</LASTNAME>
<EMAIL>adamzap@gmail.com</EMAIL>
<EMAILSTOP>0</EMAILSTOP>
<ICQ></ICQ>
<SKYPE></SKYPE>
<YAHOO></YAHOO>
<AIM></AIM>
<MSN></MSN>
<PHONE1></PHONE1>
<PHONE2></PHONE2>
<INSTITUTION></INSTITUTION>
<DEPARTMENT></DEPARTMENT>
<ADDRESS></ADDRESS>
<CITY>br</CITY>
<COUNTRY>US</COUNTRY>
<LANG>en_utf8</LANG>
<THEME></THEME>
<TIMEZONE>99</TIMEZONE>
<FIRSTACCESS>0</FIRSTACCESS>
<LASTACCESS>1265755409</LASTACCESS>
<LASTLOGIN>1265658108</LASTLOGIN>
<CURRENTLOGIN>1265741271</CURRENTLOGIN>
<LASTIP>130.39.194.172</LASTIP>
<SECRET>lknsJoSw0S6myJA</SECRET>
<PICTURE>1</PICTURE>
<URL></URL>
<DESCRIPTION></DESCRIPTION>
<MAILFORMAT>1</MAILFORMAT>
<MAILDIGEST>0</MAILDIGEST>
<MAILDISPLAY>1</MAILDISPLAY>
<HTMLEDITOR>1</HTMLEDITOR>
<AJAX>1</AJAX>
<AUTOSUBSCRIBE>1</AUTOSUBSCRIBE>
<TRACKFORUMS>0</TRACKFORUMS>
<TIMEMODIFIED>1265216036</TIMEMODIFIED>
<ROLES>
<ROLE>
<TYPE>needed</TYPE>
</ROLE>
</ROLES>
<USER_PREFERENCES>
<USER_PREFERENCE>
<NAME>email_bounce_count</NAME>
<VALUE>1</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>email_send_count</NAME>
<VALUE>1</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>user_editadvanced_form_showadvanced</NAME>
<VALUE>1</VALUE>
</USER_PREFERENCE>
</USER_PREFERENCES>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
<ROLES_ASSIGNMENTS>
</ROLES_ASSIGNMENTS>
</USER>
<USER>
<ID>3</ID>
<AUTH>cas</AUTH>
<CONFIRMED>1</CONFIRMED>
<POLICYAGREED>0</POLICYAGREED>
<DELETED>0</DELETED>
<USERNAME>azaple1</USERNAME>
<PASSWORD>fb005bdc5fb1b23ea95d238fb5ecb9e2</PASSWORD>
<IDNUMBER>891111111</IDNUMBER>
<FIRSTNAME>Adam</FIRSTNAME>
<LASTNAME>Zapletal</LASTNAME>
<EMAIL>azaple1@lsu.edu</EMAIL>
<EMAILSTOP>0</EMAILSTOP>
<ICQ></ICQ>
<SKYPE></SKYPE>
<YAHOO></YAHOO>
<AIM></AIM>
<MSN></MSN>
<PHONE1></PHONE1>
<PHONE2></PHONE2>
<INSTITUTION></INSTITUTION>
<DEPARTMENT></DEPARTMENT>
<ADDRESS></ADDRESS>
<CITY>asdf</CITY>
<COUNTRY>AL</COUNTRY>
<LANG>en_utf8</LANG>
<THEME></THEME>
<TIMEZONE>99</TIMEZONE>
<FIRSTACCESS>0</FIRSTACCESS>
<LASTACCESS>1299774054</LASTACCESS>
<LASTLOGIN>1297979000</LASTLOGIN>
<CURRENTLOGIN>1299773727</CURRENTLOGIN>
<LASTIP>173.253.129.223</LASTIP>
<SECRET></SECRET>
<PICTURE>1</PICTURE>
<URL></URL>
<DESCRIPTION></DESCRIPTION>
<MAILFORMAT>1</MAILFORMAT>
<MAILDIGEST>0</MAILDIGEST>
<MAILDISPLAY>2</MAILDISPLAY>
<HTMLEDITOR>1</HTMLEDITOR>
<AJAX>1</AJAX>
<AUTOSUBSCRIBE>1</AUTOSUBSCRIBE>
<TRACKFORUMS>0</TRACKFORUMS>
<TIMEMODIFIED>1288033285</TIMEMODIFIED>
<ROLES>
<ROLE>
<TYPE>needed</TYPE>
</ROLE>
</ROLES>
<USER_PREFERENCES>
<USER_PREFERENCE>
<NAME>assignment_mailinfo</NAME>
<VALUE>1</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>assignment_perpage</NAME>
<VALUE>10</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>assignment_quickgrade</NAME>
<VALUE>0</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>auth_forcepasswordchange</NAME>
<VALUE>0</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>forum_displaymode</NAME>
<VALUE>3</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>grader_report_preferences_form_showadvanced</NAME>
<VALUE>1</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>grade_report_simple_aggregationview51</NAME>
<VALUE>0</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>grade_report_simple_grader_collapsed_categories</NAME>
<VALUE>a:2:{s:14:&quot;aggregatesonly&quot;;a:4:{i:0;s:2:&quot;70&quot;;i:1;s:2:&quot;71&quot;;i:2;s:2:&quot;72&quot;;i:3;s:2:&quot;73&quot;;}s:10:&quot;gradesonly&quot;;a:0:{}}</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>grade_report_simple_meanselection</NAME>
<VALUE>2</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>grade_report_simple_showranges</NAME>
<VALUE>1</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>grade_report_simple_showstickytab</NAME>
<VALUE>0</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>lesson_view</NAME>
<VALUE>collapsed</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>mod_resource_mod_form_showadvanced</NAME>
<VALUE>1</VALUE>
</USER_PREFERENCE>
<USER_PREFERENCE>
<NAME>user_editadvanced_form_showadvanced</NAME>
<VALUE>1</VALUE>
</USER_PREFERENCE>
</USER_PREFERENCES>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
<ROLES_ASSIGNMENTS>
</ROLES_ASSIGNMENTS>
</USER>
<USER>
<ID>6</ID>
<AUTH>cas</AUTH>
<CONFIRMED>1</CONFIRMED>
<POLICYAGREED>0</POLICYAGREED>
<DELETED>0</DELETED>
<USERNAME>pcali1</USERNAME>
<PASSWORD>fb005bdc5fb1b23ea95d238fb5ecb9e2</PASSWORD>
<IDNUMBER></IDNUMBER>
<FIRSTNAME>Philip</FIRSTNAME>
<LASTNAME>Cali</LASTNAME>
<EMAIL>pcali1@lsu.edu</EMAIL>
<EMAILSTOP>0</EMAILSTOP>
<ICQ></ICQ>
<SKYPE></SKYPE>
<YAHOO></YAHOO>
<AIM></AIM>
<MSN></MSN>
<PHONE1></PHONE1>
<PHONE2></PHONE2>
<INSTITUTION></INSTITUTION>
<DEPARTMENT></DEPARTMENT>
<ADDRESS></ADDRESS>
<CITY></CITY>
<COUNTRY></COUNTRY>
<LANG>en_utf8</LANG>
<THEME></THEME>
<TIMEZONE>99</TIMEZONE>
<FIRSTACCESS>0</FIRSTACCESS>
<LASTACCESS>1268662392</LASTACCESS>
<LASTLOGIN>0</LASTLOGIN>
<CURRENTLOGIN>1268662284</CURRENTLOGIN>
<LASTIP>68.105.37.237</LASTIP>
<SECRET></SECRET>
<PICTURE>1</PICTURE>
<URL></URL>
<DESCRIPTION>$@NULL@$</DESCRIPTION>
<MAILFORMAT>1</MAILFORMAT>
<MAILDIGEST>0</MAILDIGEST>
<MAILDISPLAY>2</MAILDISPLAY>
<HTMLEDITOR>1</HTMLEDITOR>
<AJAX>1</AJAX>
<AUTOSUBSCRIBE>1</AUTOSUBSCRIBE>
<TRACKFORUMS>0</TRACKFORUMS>
<TIMEMODIFIED>1268662284</TIMEMODIFIED>
<ROLES>
<ROLE>
<TYPE>needed</TYPE>
</ROLE>
</ROLES>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
<ROLES_ASSIGNMENTS>
</ROLES_ASSIGNMENTS>
</USER>
</USERS>
<GRADEBOOK>
<GRADE_CATEGORIES>
<GRADE_CATEGORY>
<ID>90</ID>
<PARENT>$@NULL@$</PARENT>
<FULLNAME>?</FULLNAME>
<AGGREGATION>11</AGGREGATION>
<KEEPHIGH>0</KEEPHIGH>
<DROPLOW>0</DROPLOW>
<AGGREGATEONLYGRADED>1</AGGREGATEONLYGRADED>
<AGGREGATEOUTCOMES>0</AGGREGATEOUTCOMES>
<AGGREGATESUBCATS>0</AGGREGATESUBCATS>
<TIMECREATED>1299774068</TIMECREATED>
<TIMEMODIFIED>1299774068</TIMEMODIFIED>
</GRADE_CATEGORY>
</GRADE_CATEGORIES>
<GRADE_ITEMS>
<GRADE_ITEM>
<ID>410</ID>
<CATEGORYID>$@NULL@$</CATEGORYID>
<ITEMNAME>$@NULL@$</ITEMNAME>
<ITEMTYPE>course</ITEMTYPE>
<ITEMMODULE>$@NULL@$</ITEMMODULE>
<ITEMINSTANCE>90</ITEMINSTANCE>
<ITEMNUMBER>$@NULL@$</ITEMNUMBER>
<ITEMINFO>$@NULL@$</ITEMINFO>
<IDNUMBER>$@NULL@$</IDNUMBER>
<CALCULATION>$@NULL@$</CALCULATION>
<GRADETYPE>1</GRADETYPE>
<GRADEMAX>100.00000</GRADEMAX>
<GRADEMIN>0.00000</GRADEMIN>
<SCALEID>$@NULL@$</SCALEID>
<OUTCOMEID>$@NULL@$</OUTCOMEID>
<GRADEPASS>0.00000</GRADEPASS>
<MULTFACTOR>1.00000</MULTFACTOR>
<PLUSFACTOR>0.00000</PLUSFACTOR>
<AGGREGATIONCOEF>1.00000</AGGREGATIONCOEF>
<DISPLAY>0</DISPLAY>
<DECIMALS>$@NULL@$</DECIMALS>
<HIDDEN>0</HIDDEN>
<LOCKED>0</LOCKED>
<LOCKTIME>0</LOCKTIME>
<NEEDSUPDATE>0</NEEDSUPDATE>
<TIMECREATED>1299774068</TIMECREATED>
<TIMEMODIFIED>1299774068</TIMEMODIFIED>
</GRADE_ITEM>
</GRADE_ITEMS>
</GRADEBOOK>
<MODULES>
<MOD>
<ID>57</ID>
<MODTYPE>forum</MODTYPE>
<TYPE>news</TYPE>
<NAME>News forum</NAME>
<INTRO>General news and announcements</INTRO>
<ASSESSED>0</ASSESSED>
<ASSESSTIMESTART>0</ASSESSTIMESTART>
<ASSESSTIMEFINISH>0</ASSESSTIMEFINISH>
<MAXBYTES>0</MAXBYTES>
<SCALE>0</SCALE>
<FORCESUBSCRIBE>1</FORCESUBSCRIBE>
<TRACKINGTYPE>1</TRACKINGTYPE>
<RSSTYPE>0</RSSTYPE>
<RSSARTICLES>0</RSSARTICLES>
<TIMEMODIFIED>1299773780</TIMEMODIFIED>
<WARNAFTER>0</WARNAFTER>
<BLOCKAFTER>0</BLOCKAFTER>
<BLOCKPERIOD>0</BLOCKPERIOD>
</MOD>
</MODULES>
<FORMATDATA>
</FORMATDATA>
</COURSE>
</MOODLE_BACKUP>
File diff suppressed because it is too large Load Diff
@@ -1,463 +0,0 @@
<?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/>.
/**
* Unit tests for the moodle1 converter
*
* @package core
* @subpackage backup-convert
* @copyright 2011 Mark Nielsen <mark@moodlerooms.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/backup/converter/moodle1/lib.php');
class moodle1_converter_test extends UnitTestCase {
public static $includecoverage = array();
/** @var string the name of the directory containing the unpacked Moodle 1.9 backup */
protected $tempdir;
public function setUp() {
global $CFG;
$this->tempdir = convert_helper::generate_id('simpletest');
check_dir_exists("$CFG->dataroot/temp/backup/$this->tempdir/course_files/sub1");
check_dir_exists("$CFG->dataroot/temp/backup/$this->tempdir/moddata/unittest/4/7");
copy(
"$CFG->dirroot/backup/converter/moodle1/simpletest/files/moodle.xml",
"$CFG->dataroot/temp/backup/$this->tempdir/moodle.xml"
);
copy(
"$CFG->dirroot/backup/converter/moodle1/simpletest/files/icon.gif",
"$CFG->dataroot/temp/backup/$this->tempdir/course_files/file1.gif"
);
copy(
"$CFG->dirroot/backup/converter/moodle1/simpletest/files/icon.gif",
"$CFG->dataroot/temp/backup/$this->tempdir/course_files/sub1/file2.gif"
);
copy(
"$CFG->dirroot/backup/converter/moodle1/simpletest/files/icon.gif",
"$CFG->dataroot/temp/backup/$this->tempdir/moddata/unittest/4/file1.gif"
);
copy(
"$CFG->dirroot/backup/converter/moodle1/simpletest/files/icon.gif",
"$CFG->dataroot/temp/backup/$this->tempdir/moddata/unittest/4/icon.gif"
);
copy(
"$CFG->dirroot/backup/converter/moodle1/simpletest/files/icon.gif",
"$CFG->dataroot/temp/backup/$this->tempdir/moddata/unittest/4/7/icon.gif"
);
}
public function tearDown() {
global $CFG;
if (empty($CFG->keeptempdirectoriesonbackup)) {
fulldelete("$CFG->dataroot/temp/backup/$this->tempdir");
}
}
public function test_detect_format() {
$detected = moodle1_converter::detect_format($this->tempdir);
$this->assertEqual(backup::FORMAT_MOODLE1, $detected);
}
public function test_convert_factory() {
$converter = convert_factory::get_converter('moodle1', $this->tempdir);
$this->assertIsA($converter, 'moodle1_converter');
}
public function test_stash_storage_not_created() {
$converter = convert_factory::get_converter('moodle1', $this->tempdir);
$this->expectException('moodle1_convert_storage_exception');
$converter->set_stash('tempinfo', 12);
}
public function test_stash_requiring_empty_stash() {
$converter = convert_factory::get_converter('moodle1', $this->tempdir);
$converter->create_stash_storage();
$converter->set_stash('tempinfo', 12);
$this->expectException('moodle1_convert_empty_storage_exception');
try {
$converter->get_stash('anothertempinfo');
} catch (moodle1_convert_empty_storage_exception $e) {
// we must drop the storage here so we are able to re-create it in the next test
$converter->drop_stash_storage();
throw new moodle1_convert_empty_storage_exception('rethrowing');
}
}
public function test_stash_storage() {
$converter = convert_factory::get_converter('moodle1', $this->tempdir);
$converter->create_stash_storage();
// no implicit stashes
$stashes = $converter->get_stash_names();
$this->assertIsA($stashes, 'array');
$this->assertTrue(empty($stashes));
// test stashes without itemid
$converter->set_stash('tempinfo1', 12);
$converter->set_stash('tempinfo2', array('a' => 2, 'b' => 3));
$stashes = $converter->get_stash_names();
$this->assertIsA($stashes, 'array');
$this->assertEqual(2, count($stashes));
$this->assertTrue(in_array('tempinfo1', $stashes));
$this->assertTrue(in_array('tempinfo2', $stashes));
$this->assertIdentical(12, $converter->get_stash('tempinfo1'));
$this->assertIdentical(array('a' => 2, 'b' => 3), $converter->get_stash('tempinfo2'));
// overwriting a stashed value is allowed
$converter->set_stash('tempinfo1', '13');
$this->assertNotIdentical(13, $converter->get_stash('tempinfo1'));
$this->assertIdentical('13', $converter->get_stash('tempinfo1'));
// repeated reading is allowed
$this->assertIdentical('13', $converter->get_stash('tempinfo1'));
// storing empty array
$converter->set_stash('empty_array_stash', array());
$restored = $converter->get_stash('empty_array_stash');
//$this->assertIsA($restored, 'array'); // todo return null now, this needs MDL-27713 to be fixed, then uncomment
$this->assertTrue(empty($restored));
// test stashes with itemid
$converter->set_stash('tempinfo', 'Hello', 1);
$converter->set_stash('tempinfo', 'World', 2);
$this->assertIdentical('Hello', $converter->get_stash('tempinfo', 1));
$this->assertIdentical('World', $converter->get_stash('tempinfo', 2));
// test get_stash_itemids()
$ids = $converter->get_stash_itemids('course_fileref');
$this->assertIsA($ids, 'array');
$this->assertTrue(empty($ids));
$converter->set_stash('course_fileref', null, 34);
$converter->set_stash('course_fileref', null, 52);
$ids = $converter->get_stash_itemids('course_fileref');
$this->assertEqual(2, count($ids));
$this->assertTrue(in_array(34, $ids));
$this->assertTrue(in_array(52, $ids));
$converter->drop_stash_storage();
}
public function test_get_stash_or_default() {
$converter = convert_factory::get_converter('moodle1', $this->tempdir);
$converter->create_stash_storage();
$this->assertTrue(is_null($converter->get_stash_or_default('stashname')));
$this->assertTrue(is_null($converter->get_stash_or_default('stashname', 7)));
$this->assertTrue('default' === $converter->get_stash_or_default('stashname', 0, 'default'));
$this->assertTrue(array('foo', 'bar') === $converter->get_stash_or_default('stashname', 42, array('foo', 'bar')));
//$converter->set_stash('stashname', 0);
//$this->assertFalse(is_null($converter->get_stash_or_default('stashname'))); // todo returns true now, this needs MDL-27713 to be fixed
//$converter->set_stash('stashname', '');
//$this->assertFalse(is_null($converter->get_stash_or_default('stashname'))); // todo returns true now, this needs MDL-27713 to be fixed
//$converter->set_stash('stashname', array());
//$this->assertFalse(is_null($converter->get_stash_or_default('stashname'))); // todo returns true now, this needs MDL-27713 to be fixed
$converter->set_stash('stashname', 42);
$this->assertTrue(42 === $converter->get_stash_or_default('stashname'));
$this->assertTrue(is_null($converter->get_stash_or_default('stashname', 1)));
$this->assertTrue(42 === $converter->get_stash_or_default('stashname', 0, 61));
$converter->set_stash('stashname', array(42 => (object)array('id' => 42)), 18);
$stashed = $converter->get_stash_or_default('stashname', 18, 1984);
$this->assertIsA($stashed, 'array');
$this->assertTrue(is_object($stashed[42]));
$this->assertTrue($stashed[42]->id === 42);
$converter->drop_stash_storage();
}
public function test_get_contextid() {
$converter = convert_factory::get_converter('moodle1', $this->tempdir);
// stash storage must be created in advance
$converter->create_stash_storage();
// ids are generated on the first call
$id1 = $converter->get_contextid(CONTEXT_BLOCK, 10);
$id2 = $converter->get_contextid(CONTEXT_BLOCK, 11);
$id3 = $converter->get_contextid(CONTEXT_MODULE, 10);
$this->assertNotEqual($id1, $id2);
$this->assertNotEqual($id1, $id3);
$this->assertNotEqual($id2, $id3);
// and then re-used if called with the same params
$this->assertEqual($id1, $converter->get_contextid(CONTEXT_BLOCK, 10));
$this->assertEqual($id2, $converter->get_contextid(CONTEXT_BLOCK, 11));
$this->assertEqual($id3, $converter->get_contextid(CONTEXT_MODULE, 10));
// for system and course level, the instance is irrelevant
// as we need only one system and one course
$id1 = $converter->get_contextid(CONTEXT_COURSE);
$id2 = $converter->get_contextid(CONTEXT_COURSE, 10);
$id3 = $converter->get_contextid(CONTEXT_COURSE, 14);
$this->assertEqual($id1, $id2);
$this->assertEqual($id1, $id3);
$id1 = $converter->get_contextid(CONTEXT_SYSTEM);
$id2 = $converter->get_contextid(CONTEXT_SYSTEM, 11);
$id3 = $converter->get_contextid(CONTEXT_SYSTEM, 15);
$this->assertEqual($id1, $id2);
$this->assertEqual($id1, $id3);
$converter->drop_stash_storage();
}
public function test_get_nextid() {
$converter = convert_factory::get_converter('moodle1', $this->tempdir);
$id1 = $converter->get_nextid();
$id2 = $converter->get_nextid();
$id3 = $converter->get_nextid();
$this->assertTrue(0 < $id1);
$this->assertTrue($id1 < $id2);
$this->assertTrue($id2 < $id3);
}
public function test_migrate_file() {
// set-up the file manager
$converter = convert_factory::get_converter('moodle1', $this->tempdir);
$converter->create_stash_storage();
$contextid = $converter->get_contextid(CONTEXT_MODULE, 32);
$fileman = $converter->get_file_manager($contextid, 'mod_unittest', 'testarea');
// this fileman has not converted anything yet
$fileids = $fileman->get_fileids();
$this->assertIsA($fileids, 'array');
$this->assertEqual(0, count($fileids));
// try to migrate a non-existing directory
$returned = $fileman->migrate_directory('not/existing/directory');
$this->assertIsA($returned, 'array');
$this->assertEqual(0, count($returned));
$fileids = $fileman->get_fileids();
$this->assertIsA($fileids, 'array');
$this->assertEqual(0, count($fileids));
// migrate a single file
$fileman->itemid = 4;
$fileman->migrate_file('moddata/unittest/4/icon.gif');
$this->assertTrue(is_file($converter->get_workdir_path().'/files/4e/4ea114b0558f53e3af8dd9afc0e0810a95c2a724'));
// get the file id
$fileids = $fileman->get_fileids();
$this->assertIsA($fileids, 'array');
$this->assertEqual(1, count($fileids));
// migrate another single file into another file area
$fileman->filearea = 'anotherarea';
$fileman->itemid = 7;
$fileman->migrate_file('moddata/unittest/4/7/icon.gif', '/', 'renamed.gif');
// get the file records
$filerecordids = $converter->get_stash_itemids('files');
foreach ($filerecordids as $filerecordid) {
$filerecord = $converter->get_stash('files', $filerecordid);
$this->assertEqual('4ea114b0558f53e3af8dd9afc0e0810a95c2a724', $filerecord['contenthash']);
$this->assertEqual($contextid, $filerecord['contextid']);
$this->assertEqual('mod_unittest', $filerecord['component']);
if ($filerecord['filearea'] === 'testarea') {
$this->assertEqual(4, $filerecord['itemid']);
$this->assertEqual('icon.gif', $filerecord['filename']);
}
}
// explicitly clear the list of migrated files
$this->assertTrue(count($fileman->get_fileids()) > 0);
$fileman->reset_fileids();
$this->assertTrue(count($fileman->get_fileids()) == 0);
$converter->drop_stash_storage();
}
public function test_convert_path() {
$path = new convert_path('foo_bar', '/ROOT/THINGS/FOO/BAR');
$this->assertEqual('foo_bar', $path->get_name());
$this->assertEqual('/ROOT/THINGS/FOO/BAR', $path->get_path());
$this->assertEqual('process_foo_bar', $path->get_processing_method());
$this->assertEqual('on_foo_bar_start', $path->get_start_method());
$this->assertEqual('on_foo_bar_end', $path->get_end_method());
}
public function test_convert_path_implicit_recipes() {
$path = new convert_path('foo_bar', '/ROOT/THINGS/FOO/BAR');
$data = array(
'ID' => 76,
'ELOY' => 'stronk7',
'MARTIN' => 'moodler',
'EMPTY' => null,
);
// apply default recipes (converting keys to lowercase)
$data = $path->apply_recipes($data);
$this->assertEqual(4, count($data));
$this->assertEqual(76, $data['id']);
$this->assertEqual('stronk7', $data['eloy']);
$this->assertEqual('moodler', $data['martin']);
$this->assertIdentical(null, $data['empty']);
}
public function test_convert_path_explicit_recipes() {
$path = new convert_path(
'foo_bar', '/ROOT/THINGS/FOO/BAR',
array(
'newfields' => array(
'david' => 'mudrd8mz',
'petr' => 'skodak',
),
'renamefields' => array(
'empty' => 'nothing',
),
'dropfields' => array(
'id'
),
)
);
$data = array(
'ID' => 76,
'ELOY' => 'stronk7',
'MARTIN' => 'moodler',
'EMPTY' => null,
);
$data = $path->apply_recipes($data);
$this->assertEqual(5, count($data));
$this->assertFalse(array_key_exists('id', $data));
$this->assertEqual('stronk7', $data['eloy']);
$this->assertEqual('moodler', $data['martin']);
$this->assertEqual('mudrd8mz', $data['david']);
$this->assertEqual('skodak', $data['petr']);
$this->assertIdentical(null, $data['nothing']);
}
public function test_grouped_data_on_nongrouped_convert_path() {
// prepare some grouped data
$data = array(
'ID' => 77,
'NAME' => 'Pale lagers',
'BEERS' => array(
array(
'BEER' => array(
'ID' => 67,
'NAME' => 'Pilsner Urquell',
)
),
array(
'BEER' => array(
'ID' => 34,
'NAME' => 'Heineken',
)
),
)
);
// declare a non-grouped path
$path = new convert_path('beer_style', '/ROOT/BEER_STYLES/BEER_STYLE');
// an attempt to apply recipes throws exception because we do not expect grouped data
$this->expectException('convert_path_exception');
$data = $path->apply_recipes($data);
}
public function test_grouped_convert_path_with_recipes() {
// prepare some grouped data
$data = array(
'ID' => 77,
'NAME' => 'Pale lagers',
'BEERS' => array(
array(
'BEER' => array(
'ID' => 67,
'NAME' => 'Pilsner Urquell',
)
),
array(
'BEER' => array(
'ID' => 34,
'NAME' => 'Heineken',
)
),
)
);
// implict recipes work for grouped data if the path is declared as grouped
$path = new convert_path('beer_style', '/ROOT/BEER_STYLES/BEER_STYLE', array(), true);
$data = $path->apply_recipes($data);
$this->assertEqual('Heineken', $data['beers'][1]['beer']['name']);
// an attempt to provide explicit recipes on grouped elements throws exception
$this->expectException('convert_path_exception');
$path = new convert_path(
'beer_style', '/ROOT/BEER_STYLES/BEER_STYLE',
array(
'renamefields' => array(
'name' => 'beername', // note this is confusing recipe because the 'name' is used for both
// beer-style name ('Pale lagers') and beer name ('Pilsner Urquell')
)
), true);
}
public function test_referenced_course_files() {
$text = 'This is a text containing links to file.php
as it is parsed from the backup file. <br /><br /><img border="0" width="110" vspace="0" hspace="0" height="92" title="News" alt="News" src="$@FILEPHP@$$@SLASH@$pics$@SLASH@$news.gif" /><a href="$@FILEPHP@$$@SLASH@$pics$@SLASH@$news.gif$@FORCEDOWNLOAD@$">download image</a><br />
<br /><a href=\'$@FILEPHP@$$@SLASH@$MANUAL.DOC$@FORCEDOWNLOAD@$\'>download manual</a><br />';
$files = moodle1_converter::find_referenced_files($text);
$this->assertIsA($files, 'array');
$this->assertEqual(2, count($files));
$this->assertTrue(in_array('/pics/news.gif', $files));
$this->assertTrue(in_array('/MANUAL.DOC', $files));
$text = moodle1_converter::rewrite_filephp_usage($text, array('/pics/news.gif', '/another/file/notused.txt'), $files);
$this->assertEqual($text, 'This is a text containing links to file.php
as it is parsed from the backup file. <br /><br /><img border="0" width="110" vspace="0" hspace="0" height="92" title="News" alt="News" src="@@PLUGINFILE@@/pics/news.gif" /><a href="@@PLUGINFILE@@/pics/news.gif?forcedownload=1">download image</a><br />
<br /><a href=\'$@FILEPHP@$$@SLASH@$MANUAL.DOC$@FORCEDOWNLOAD@$\'>download manual</a><br />');
}
public function test_question_bank_conversion() {
global $CFG;
copy(
"$CFG->dirroot/backup/converter/moodle1/simpletest/files/questions.xml",
"$CFG->dataroot/temp/backup/$this->tempdir/moodle.xml"
);
$converter = convert_factory::get_converter('moodle1', $this->tempdir);
$converter->convert();
}
public function test_convert_run_convert() {
$converter = convert_factory::get_converter('moodle1', $this->tempdir);
$converter->convert();
}
public function test_inforef_manager() {
$converter = convert_factory::get_converter('moodle1', $this->tempdir);
$inforef = $converter->get_inforef_manager('unittest');
$inforef->add_ref('file', 45);
$inforef->add_refs('file', array(46, 47));
// todo test the write_refs() via some dummy xml_writer
$this->expectException('coding_exception');
$inforef->add_ref('unknown_referenced_item_name', 76);
}
}
+4 -2
View File
@@ -72,8 +72,10 @@ class backup_course_task extends backup_task {
// annotating some bits, tags and module restrictions
$this->add_step(new backup_course_structure_step('course_info', 'course.xml'));
// Generate the enrolment file
$this->add_step(new backup_enrolments_structure_step('course_enrolments', 'enrolments.xml'));
// Generate the enrolment file (conditionally, prevent it in any IMPORT/HUB operation)
if ($this->plan->get_mode() != backup::MODE_IMPORT && $this->plan->get_mode() != backup::MODE_HUB) {
$this->add_step(new backup_enrolments_structure_step('course_enrolments', 'enrolments.xml'));
}
// Annotate all the groups and groupings belonging to the course
$this->add_step(new backup_annotate_course_groups_and_groupings('annotate_course_groups'));
+2 -1
View File
@@ -111,7 +111,8 @@ abstract class backup_qtype_plugin extends backup_plugin {
// Define the elements
$options = new backup_nested_element('numerical_options');
$option = new backup_nested_element('numerical_option', array('id'), array(
'showunits', 'unitsleft', 'unitgradingtype', 'unitpenalty'));
'instructions', 'instructionsformat', 'showunits', 'unitsleft',
'unitgradingtype', 'unitpenalty'));
// Build the tree
$element->add_child($options);
+60 -69
View File
@@ -174,76 +174,78 @@ abstract class backup_questions_activity_structure_step extends backup_activity_
/**
* Attach to $element (usually attempts) the needed backup structures
* for question_usages and all the associated data.
* for question_states for a given question_attempt
*/
protected function add_question_usages($element, $usageidname) {
global $CFG;
require_once($CFG->dirroot . '/question/engine/lib.php');
protected function add_question_attempts_states($element, $questionattemptname) {
// Check $element is one nested_backup_element
if (! $element instanceof backup_nested_element) {
throw new backup_step_exception('question_states_bad_parent_element', $element);
}
if (! $element->get_final_element($usageidname)) {
throw new backup_step_exception('question_states_bad_question_attempt_element', $usageidname);
// Check that the $questionattemptname is final element in $element
if (! $element->get_final_element($questionattemptname)) {
throw new backup_step_exception('question_states_bad_question_attempt_element', $questionattemptname);
}
$quba = new backup_nested_element('question_usage', array('id'),
array('component', 'preferredbehaviour'));
// TODO: Some day we should stop these "encrypted" state->answers and
// TODO: delegate to qtypes plugin to proper XML writting the needed info on each question
$qas = new backup_nested_element('question_attempts');
$qa = new backup_nested_element('question_attempt', array('id'), array(
'slot', 'behaviour', 'questionid', 'maxmark', 'minfraction',
'flagged', 'questionsummary', 'rightanswer', 'responsesummary',
'timemodified'));
// TODO: Should be doing here some introspection in the "answer" element, based on qtype,
// TODO: to know which real questions are being used (for randoms and other qtypes...)
// TODO: Not needed if consistency is guaranteed, but it isn't right now :-(
$steps = new backup_nested_element('steps');
$step = new backup_nested_element('step', array('id'), array(
'sequencenumber', 'state', 'fraction', 'timecreated', 'userid'));
$response = new backup_nested_element('response');
$variable = new backup_nested_element('variable', null, array('name', 'value'));
// Define the elements
$states = new backup_nested_element('states');
$state = new backup_nested_element('state', array('id'), array(
'question', 'seq_number', 'answer', 'timestamp',
'event', 'grade', 'raw_grade', 'penalty'));
// Build the tree
$element->add_child($quba);
$quba->add_child($qas);
$qas->add_child($qa);
$qa->add_child($steps);
$steps->add_child($step);
$step->add_child($response);
$response->add_child($variable);
$element->add_child($states);
$states->add_child($state);
// Set the sources
$quba->set_source_table('question_usages',
array('id' => '../' . $usageidname));
$qa->set_source_sql('
SELECT *
FROM {question_attempts}
WHERE questionusageid = :questionusageid
ORDER BY slot',
array('questionusageid' => backup::VAR_PARENTID));
$step->set_source_sql('
SELECT *
FROM {question_attempt_steps}
WHERE questionattemptid = :questionattemptid
ORDER BY sequencenumber',
array('questionattemptid' => backup::VAR_PARENTID));
$variable->set_source_table('question_attempt_step_data',
array('attemptstepid' => backup::VAR_PARENTID));
$state->set_source_table('question_states', array('attempt' => '../../' . $questionattemptname));
// Annotate ids
$qa->annotate_ids('question', 'questionid');
$step->annotate_ids('user', 'userid');
$state->annotate_ids('question', 'question');
}
/**
* Attach to $element (usually attempts) the needed backup structures
* for question_sessions for a given question_attempt
*/
protected function add_question_attempts_sessions($element, $questionattemptname) {
// Check $element is one nested_backup_element
if (! $element instanceof backup_nested_element) {
throw new backup_step_exception('question_sessions_bad_parent_element', $element);
}
// Check that the $questionattemptname is final element in $element
if (! $element->get_final_element($questionattemptname)) {
throw new backup_step_exception('question_sessions_bad_question_attempt_element', $questionattemptname);
}
// Define the elements
$sessions = new backup_nested_element('sessions');
$session = new backup_nested_element('session', array('id'), array(
'questionid', 'newest', 'newgraded', 'sumpenalty',
'manualcomment', 'manualcommentformat', 'flagged'));
// Build the tree
$element->add_child($sessions);
$sessions->add_child($session);
// Set the sources
$session->set_source_table('question_sessions', array('attemptid' => '../../' . $questionattemptname));
// Annotate ids
$session->annotate_ids('question', 'questionid');
// Annotate files
$fileareas = question_engine::get_all_response_file_areas();
foreach ($fileareas as $filearea) {
$step->annotate_files('question', $filearea, 'id');
}
// Note: question_sessions haven't files associated. On purpose manualcomment is lacking
// support for them, so we don't need to annotated them here.
}
}
/**
* backup structure step in charge of calculating the categories to be
* included in backup, based in the context being backuped (module/course)
@@ -319,8 +321,9 @@ class backup_module_structure_step extends backup_structure_step {
// attach format plugin structure to $module element, only one allowed
$this->add_plugin_structure('format', $module, false);
// attach plagiarism plugin structure to $module element, only one allowed
$this->add_plugin_structure('plagiarism', $module, false);
// attach plagiarism plugin structure to $module element, there can be potentially
// many plagiarism plugins storing information about this course
$this->add_plugin_structure('plagiarism', $module, true);
// Define the tree
$module->add_child($availinfo);
@@ -421,8 +424,9 @@ class backup_course_structure_step extends backup_structure_step {
// course reports can save course data if required
$this->add_plugin_structure('coursereport', $course, true);
// attach plagiarism plugin structure to $course element, only one allowed
$this->add_plugin_structure('plagiarism', $course, false);
// attach plagiarism plugin structure to $course element, there can be potentially
// many plagiarism plugins storing information about this course
$this->add_plugin_structure('plagiarism', $course, true);
// Build the tree
@@ -1694,25 +1698,19 @@ class backup_questions_structure_step extends backup_structure_step {
$question = new backup_nested_element('question', array('id'), array(
'parent', 'name', 'questiontext', 'questiontextformat',
'generalfeedback', 'generalfeedbackformat', 'defaultmark', 'penalty',
'generalfeedback', 'generalfeedbackformat', 'defaultgrade', 'penalty',
'qtype', 'length', 'stamp', 'version',
'hidden', 'timecreated', 'timemodified', 'createdby', 'modifiedby'));
// attach qtype plugin structure to $question element, only one allowed
$this->add_plugin_structure('qtype', $question, false);
$qhints = new backup_nested_element('question_hints');
$qhint = new backup_nested_element('question_hint', array('id'), array(
'hint', 'hintformat', 'shownumcorrect', 'clearwrong', 'options'));
// Build the tree
$qcategories->add_child($qcategory);
$qcategory->add_child($questions);
$questions->add_child($question);
$question->add_child($qhints);
$qhints->add_child($qhint);
// Define the sources
@@ -1726,13 +1724,6 @@ class backup_questions_structure_step extends backup_structure_step {
$question->set_source_table('question', array('category' => backup::VAR_PARENTID));
$qhint->set_source_sql('
SELECT *
FROM {question_hints}
WHERE questionid = :questionid
ORDER BY id',
array('questionid' => backup::VAR_PARENTID));
// don't need to annotate ids nor files
// (already done by {@link backup_annotate_all_question_files}
+4 -2
View File
@@ -69,8 +69,10 @@ class restore_course_task extends restore_task {
// Restore course role assignments and overrides (internally will observe the role_assignments setting)
$this->add_step(new restore_ras_and_caps_structure_step('course_ras_and_caps', 'roles.xml'));
// Restore course enrolments (plugins and membership)
$this->add_step(new restore_enrolments_structure_step('course_enrolments', 'enrolments.xml'));
// Restore course enrolments (plugins and membership). Conditionally prevented for any IMPORT/HUB operation
if ($this->plan->get_mode() != backup::MODE_IMPORT && $this->plan->get_mode() != backup::MODE_HUB) {
$this->add_step(new restore_enrolments_structure_step('course_enrolments', 'enrolments.xml'));
}
// Restore course filters (conditionally)
if ($this->get_setting_value('filters')) {
+2 -31
View File
@@ -115,23 +115,6 @@ abstract class restore_qtype_plugin extends restore_plugin {
$newquestionid = $this->get_new_parentid('question');
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
// In the past, there were some sloppily rounded fractions around. Fix them up.
$changes = array(
'-0.66666' => '-0.6666667',
'-0.33333' => '-0.3333333',
'-0.16666' => '-0.1666667',
'-0.142857' => '-0.1428571',
'0.11111' => '0.1111111',
'0.142857' => '0.1428571',
'0.16666' => '0.1666667',
'0.33333' => '0.3333333',
'0.333333' => '0.3333333',
'0.66666' => '0.6666667',
);
if (array_key_exists($data->fraction, $changes)) {
$data->fraction = $changes[$data->fraction];
}
// If the question has been created by restore, we need to create its question_answers too
if ($questioncreated) {
// Adjust some columns
@@ -315,21 +298,9 @@ abstract class restore_qtype_plugin extends restore_plugin {
}
/**
* Do any re-coding necessary in the student response.
* @param int $questionid the new id of the question
* @param int $sequencenumber of the step within the qusetion attempt.
* @param array the response data from the backup.
* @return array the recoded response.
* Decode one question_states for this qtype (default impl)
*/
public function recode_response($questionid, $sequencenumber, array $response) {
return $response;
}
/**
* Decode legacy question_states.answer for this qtype. Used when restoring
* 2.0 attempt data.
*/
public function recode_legacy_state_answer($state) {
public function recode_state_answer($state) {
// By default, return answer unmodified, qtypes needing recode will override this
return $state->answer;
}
+93 -394
View File
@@ -146,18 +146,12 @@ class restore_gradebook_structure_step extends restore_structure_step {
$data->courseid = $this->get_courseid();
//manual grade items store category id in categoryid
if ($data->itemtype=='manual') {
// manual grade items store category id in categoryid
$data->categoryid = $this->get_mappingid('grade_category', $data->categoryid, NULL);
} else if ($data->itemtype=='course') {
// course grade item stores their category id in iteminstance
$coursecat = grade_category::fetch_course_category($this->get_courseid());
$data->iteminstance = $coursecat->id;
} else if ($data->itemtype=='category') {
// category grade items store their category id in iteminstance
} //course and category grade items store their category id in iteminstance
else if ($data->itemtype=='course' || $data->itemtype=='category') {
$data->iteminstance = $this->get_mappingid('grade_category', $data->iteminstance, NULL);
} else {
throw new restore_step_exception('unexpected_grade_item_type', $data->itemtype);
}
$data->scaleid = $this->get_mappingid('scale', $data->scaleid, NULL);
@@ -242,7 +236,6 @@ class restore_gradebook_structure_step extends restore_structure_step {
//get the already created course level grade category
$category = new stdclass();
$category->courseid = $this->get_courseid();
$category->parent = null;
$coursecategory = $DB->get_record('grade_categories', (array)$category);
if (!empty($coursecategory)) {
@@ -307,16 +300,12 @@ class restore_gradebook_structure_step extends restore_structure_step {
//if this is an activity grade item that needs to be put back in its correct category
if (!empty($grade_item_backup->parentitemid)) {
$oldcategoryid = $this->get_mappingid('grade_category', $grade_item_backup->parentitemid, null);
if (!is_null($oldcategoryid)) {
$updateobj->categoryid = $oldcategoryid;
$DB->update_record('grade_items', $updateobj);
}
$updateobj->categoryid = $this->get_mappingid('grade_category', $grade_item_backup->parentitemid);
} else {
//mark course and category items as needing to be recalculated
$updateobj->needsupdate=1;
$DB->update_record('grade_items', $updateobj);
}
$DB->update_record('grade_items', $updateobj);
}
}
$rs->close();
@@ -324,7 +313,8 @@ class restore_gradebook_structure_step extends restore_structure_step {
// We need to update the calculations for calculated grade items that may reference old
// grade item ids using ##gi\d+##.
// $mappings can be empty, use 0 if so (won't match ever)
list($sql, $params) = $DB->get_in_or_equal(array_values($mappings), SQL_PARAMS_NAMED, 'param', true, 0);
$mappings = !empty($mappings) ? $mappings : array(0);
list($sql, $params) = $DB->get_in_or_equal(array_values($mappings), SQL_PARAMS_NAMED);
$sql = "SELECT gi.id, gi.calculation
FROM {grade_items} gi
WHERE gi.id {$sql} AND
@@ -1291,6 +1281,28 @@ class restore_ras_and_caps_structure_step extends restore_structure_step {
*/
class restore_enrolments_structure_step extends restore_structure_step {
/**
* Conditionally decide if this step should be executed.
*
* This function checks the following parameter:
*
* 1. the course/enrolments.xml file exists
*
* @return bool true is safe to execute, false otherwise
*/
protected function execute_condition() {
// Check it is included in the backup
$fullpath = $this->task->get_taskbasepath();
$fullpath = rtrim($fullpath, '/') . '/' . $this->filename;
if (!file_exists($fullpath)) {
// Not found, can't restore enrolments info
return false;
}
return true;
}
protected function define_structure() {
$paths = array();
@@ -1749,7 +1761,7 @@ class restore_course_logs_structure_step extends restore_structure_step {
/**
* Conditionally decide if this step should be executed.
*
* This function checks the following four parameters:
* This function checks the following parameter:
*
* 1. the course/logs.xml file exists
*
@@ -2203,7 +2215,6 @@ class restore_module_structure_step extends restore_structure_step {
* - Activity includes completion info (file_exists)
*/
class restore_userscompletion_structure_step extends restore_structure_step {
private $done = array();
/**
* To conditionally decide if this step must be executed
@@ -2248,33 +2259,7 @@ class restore_userscompletion_structure_step extends restore_structure_step {
$data->userid = $this->get_mappingid('user', $data->userid);
$data->timemodified = $this->apply_date_offset($data->timemodified);
// Check we didn't already insert one for this cmid and userid
// (there aren't supposed to be duplicates in that field, but
// it was possible until MDL-28021 was fixed).
$key = $data->coursemoduleid . ',' . $data->userid;
if (array_key_exists($key, $this->done)) {
// Find the existing record
$existing = $DB->get_record('course_modules_completion', array(
'coursemoduleid' => $data->coursemoduleid,
'userid' => $data->userid), 'id, timemodified');
// Update it to these new values, but only if the time is newer
if ($existing->timemodified < $data->timemodified) {
$data->id = $existing->id;
$DB->update_record('course_modules_completion', $data);
}
} else {
// Normal entry where it doesn't exist already
$DB->insert_record('course_modules_completion', $data);
// Remember this entry
$this->done[$key] = true;
}
}
protected function after_execute() {
// This gets called once per activity (according to my testing).
// Clearing the array isn't strictly required, but avoids using
// unnecessary memory.
$this->done = array();
$DB->insert_record('course_modules_completion', $data);
}
}
@@ -2371,13 +2356,11 @@ class restore_create_categories_and_questions extends restore_structure_step {
$category = new restore_path_element('question_category', '/question_categories/question_category');
$question = new restore_path_element('question', '/question_categories/question_category/questions/question');
$hint = new restore_path_element('question_hint',
'/question_categories/question_category/questions/question/question_hints/question_hint');
// Apply for 'qtype' plugins optional paths at question level
$this->add_plugin_structure('qtype', $question);
return array($category, $question, $hint);
return array($category, $question);
}
protected function process_question_category($data) {
@@ -2430,17 +2413,6 @@ class restore_create_categories_and_questions extends restore_structure_step {
// we have loaded qcatids there for all parsed questions
$data->category = $this->get_mappingid('question_category', $questionmapping->parentitemid);
// In the past, there were some very sloppy values of penalty. Fix them.
if ($data->penalty >= 0.33 && $data->penalty <= 0.34) {
$data->penalty = 0.3333333;
}
if ($data->penalty >= 0.66 && $data->penalty <= 0.67) {
$data->penalty = 0.6666667;
}
if ($data->penalty >= 1) {
$data->penalty = 1;
}
$data->timecreated = $this->apply_date_offset($data->timecreated);
$data->timemodified = $this->apply_date_offset($data->timemodified);
@@ -2470,47 +2442,6 @@ class restore_create_categories_and_questions extends restore_structure_step {
// step will be in charge of restoring all the question files
}
protected function process_question_hint($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
// Detect if the question is created or mapped
$oldquestionid = $this->get_old_parentid('question');
$newquestionid = $this->get_new_parentid('question');
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
// If the question has been created by restore, we need to create its question_answers too
if ($questioncreated) {
// Adjust some columns
$data->questionid = $newquestionid;
// Insert record
$newitemid = $DB->insert_record('question_hints', $data);
// The question existed, we need to map the existing question_hints
} else {
// Look in question_hints by hint text matching
$sql = 'SELECT id
FROM {question_hints}
WHERE questionid = ?
AND ' . $DB->sql_compare_text('hint', 255) . ' = ' . $DB->sql_compare_text('?', 255);
$params = array($newquestionid, $data->hint);
$newitemid = $DB->get_field_sql($sql, $params);
// If we haven't found the newitemid, something has gone really wrong, question in DB
// is missing hints, exception
if (!$newitemid) {
$info = new stdClass();
$info->filequestionid = $oldquestionid;
$info->dbquestionid = $newquestionid;
$info->hint = $data->hint;
throw new restore_step_exception('error_question_hint_missing_in_db', $info);
}
}
// Create mapping (I'm not sure if this is really needed?)
$this->set_mapping('question_hint', $oldid, $newitemid);
}
protected function after_execute() {
global $DB;
@@ -2631,12 +2562,8 @@ class restore_create_question_files extends restore_execution_step {
$oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'generalfeedback',
$oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'answer',
$oldctxid, $this->task->get_userid(), 'question_answer', null, $newctxid, true);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'answerfeedback',
$oldctxid, $this->task->get_userid(), 'question_answer', null, $newctxid, true);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'hint',
$oldctxid, $this->task->get_userid(), 'question_hint', null, $newctxid, true);
// Add qtype dependent files
$components = backup_qtype_plugin::get_components_and_fileareas($question->qtype);
foreach ($components as $component => $fileareas) {
@@ -2657,16 +2584,12 @@ class restore_create_question_files extends restore_execution_step {
* (like the quiz module), to support qtype plugins, states and sessions
*/
abstract class restore_questions_activity_structure_step extends restore_activity_structure_step {
/** @var array question_attempt->id to qtype. */
protected $qtypes = array();
/** @var array question_attempt->id to questionid. */
protected $newquestionids = array();
/**
* Attach below $element (usually attempts) the needed restore_path_elements
* to restore question_usages and all they contain.
* to restore question_states
*/
protected function add_question_usages($element, &$paths) {
protected function add_question_attempts_states($element, &$paths) {
// Check $element is restore_path_element
if (! $element instanceof restore_path_element) {
throw new restore_step_exception('element_must_be_restore_path_element', $element);
@@ -2675,124 +2598,70 @@ abstract class restore_questions_activity_structure_step extends restore_activit
if (!is_array($paths)) {
throw new restore_step_exception('paths_must_be_array', $paths);
}
$paths[] = new restore_path_element('question_usage',
$element->get_path() . '/question_usage');
$paths[] = new restore_path_element('question_attempt',
$element->get_path() . '/question_usage/question_attempts/question_attempt');
$paths[] = new restore_path_element('question_attempt_step',
$element->get_path() . '/question_usage/question_attempts/question_attempt/steps/step',
true);
$paths[] = new restore_path_element('question_attempt_step_data',
$element->get_path() . '/question_usage/question_attempts/question_attempt/steps/step/response/variable');
$paths[] = new restore_path_element('question_state', $element->get_path() . '/states/state');
}
/**
* Process question_usages
* Attach below $element (usually attempts) the needed restore_path_elements
* to restore question_sessions
*/
protected function process_question_usage($data) {
global $DB;
// Clear our caches.
$this->qtypes = array();
$this->newquestionids = array();
$data = (object)$data;
$oldid = $data->id;
$oldcontextid = $this->get_task()->get_old_contextid();
$data->contextid = $this->get_mappingid('context', $this->task->get_old_contextid());
// Everything ready, insert (no mapping needed)
$newitemid = $DB->insert_record('question_usages', $data);
$this->inform_new_usage_id($newitemid);
$this->set_mapping('question_usage', $oldid, $newitemid, false);
}
/**
* When process_question_usage creates the new usage, it calls this method
* to let the activity link to the new usage. For example, the quiz uses
* this method to set quiz_attempts.uniqueid to the new usage id.
* @param integer $newusageid
*/
abstract protected function inform_new_usage_id($newusageid);
/**
* Process question_attempts
*/
protected function process_question_attempt($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
$question = $this->get_mapping('question', $data->questionid);
$data->questionusageid = $this->get_new_parentid('question_usage');
$data->questionid = $question->newitemid;
$data->timemodified = $this->apply_date_offset($data->timemodified);
$newitemid = $DB->insert_record('question_attempts', $data);
$this->set_mapping('question_attempt', $oldid, $newitemid);
$this->qtypes[$newitemid] = $question->info->qtype;
$this->newquestionids[$newitemid] = $data->questionid;
}
/**
* Process question_attempt_steps
*/
protected function process_question_attempt_step($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
// Pull out the response data.
$response = array();
if (!empty($data->response['variable'])) {
foreach ($data->response['variable'] as $variable) {
$response[$variable['name']] = $variable['value'];
}
protected function add_question_attempts_sessions($element, &$paths) {
// Check $element is restore_path_element
if (! $element instanceof restore_path_element) {
throw new restore_step_exception('element_must_be_restore_path_element', $element);
}
unset($data->response);
// Check $paths is one array
if (!is_array($paths)) {
throw new restore_step_exception('paths_must_be_array', $paths);
}
$paths[] = new restore_path_element('question_session', $element->get_path() . '/sessions/session');
}
$data->questionattemptid = $this->get_new_parentid('question_attempt');
$data->timecreated = $this->apply_date_offset($data->timecreated);
$data->userid = $this->get_mappingid('user', $data->userid);
/**
* Process question_states
*/
protected function process_question_state($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
// Get complete question mapping, we'll need info
$question = $this->get_mapping('question', $data->question);
// In the quiz_attempt mapping we are storing uniqueid
// and not id, so this gets the correct question_attempt to point to
$data->attempt = $this->get_new_parentid('quiz_attempt');
$data->question = $question->newitemid;
$data->answer = $this->restore_recode_answer($data, $question->info->qtype); // Delegate recoding of answer
$data->timestamp= $this->apply_date_offset($data->timestamp);
// Everything ready, insert and create mapping (needed by question_sessions)
$newitemid = $DB->insert_record('question_attempt_steps', $data);
$this->set_mapping('question_attempt_step', $oldid, $newitemid, true);
// Now process the response data.
$response = $this->questions_recode_response_data(
$this->qtypes[$data->questionattemptid],
$this->newquestionids[$data->questionattemptid],
$data->sequencenumber, $response);
foreach ($response as $name => $value) {
$row = new stdClass();
$row->attemptstepid = $newitemid;
$row->name = $name;
$row->value = $value;
$DB->insert_record('question_attempt_step_data', $row, false);
}
$newitemid = $DB->insert_record('question_states', $data);
$this->set_mapping('question_state', $oldid, $newitemid);
}
/**
* Recode the respones data for a particular step of an attempt at at particular question.
* @param string $qtype the question type.
* @param int $newquestionid the question id.
* @param int $sequencenumber the sequence number.
* @param array $response the response data to recode.
* Process question_sessions
*/
public function questions_recode_response_data(
$qtype, $newquestionid, $sequencenumber, array $response) {
$qtyperestorer = $this->get_qtype_restorer($qtype);
if ($qtyperestorer) {
$response = $qtyperestorer->recode_response($newquestionid, $sequencenumber, $response);
}
return $response;
protected function process_question_session($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
// In the quiz_attempt mapping we are storing uniqueid
// and not id, so this gets the correct question_attempt to point to
$data->attemptid = $this->get_new_parentid('quiz_attempt');
$data->questionid = $this->get_mappingid('question', $data->questionid);
$data->newest = $this->get_mappingid('question_state', $data->newest);
$data->newgraded = $this->get_mappingid('question_state', $data->newgraded);
// Everything ready, insert (no mapping needed)
$newitemid = $DB->insert_record('question_sessions', $data);
// Note: question_sessions haven't files associated. On purpose manualcomment is lacking
// support for them, so we don't need to handle them here.
}
/**
@@ -2815,195 +2684,25 @@ abstract class restore_questions_activity_structure_step extends restore_activit
}
/**
* Get the restore_qtype_plugin subclass for a specific question type.
* @param string $qtype e.g. multichoice.
* @return restore_qtype_plugin instance.
* Given one question_states record, return the answer
* recoded pointing to all the restored stuff
*/
protected function get_qtype_restorer($qtype) {
public function restore_recode_answer($state, $qtype) {
// Build one static cache to store {@link restore_qtype_plugin}
// while we are needing them, just to save zillions of instantiations
// or using static stuff that will break our nice API
static $qtypeplugins = array();
// If we haven't the corresponding restore_qtype_plugin for current qtype
// instantiate it and add to cache
if (!isset($qtypeplugins[$qtype])) {
$classname = 'restore_qtype_' . $qtype . '_plugin';
if (class_exists($classname)) {
$qtypeplugins[$qtype] = new $classname('qtype', $qtype, $this);
} else {
$qtypeplugins[$qtype] = null;
$qtypeplugins[$qtype] = false;
}
}
return $qtypeplugins[$qtype];
}
protected function after_execute() {
parent::after_execute();
// Restore any files belonging to responses.
foreach (question_engine::get_all_response_file_areas() as $filearea) {
$this->add_related_files('question', $filearea, 'question_attempt_step');
}
}
/**
* Attach below $element (usually attempts) the needed restore_path_elements
* to restore question attempt data from Moodle 2.0.
*
* When using this method, the parent element ($element) must be defined with
* $grouped = true. Then, in that elements process method, you must call
* {@link process_legacy_attempt_data()} with the groupded data. See, for
* example, the usage of this method in {@link restore_quiz_activity_structure_step}.
* @param restore_path_element $element the parent element. (E.g. a quiz attempt.)
* @param array $paths the paths array that is being built to describe the
* structure.
*/
protected function add_legacy_question_attempt_data($element, &$paths) {
global $CFG;
require_once($CFG->dirroot . '/question/engine/upgrade/upgradelib.php');
// Check $element is restore_path_element
if (!($element instanceof restore_path_element)) {
throw new restore_step_exception('element_must_be_restore_path_element', $element);
}
// Check $paths is one array
if (!is_array($paths)) {
throw new restore_step_exception('paths_must_be_array', $paths);
}
$paths[] = new restore_path_element('question_state',
$element->get_path() . '/states/state');
$paths[] = new restore_path_element('question_session',
$element->get_path() . '/sessions/session');
}
protected function get_attempt_upgrader() {
if (empty($this->attemptupgrader)) {
$this->attemptupgrader = new question_engine_attempt_upgrader();
$this->attemptupgrader->prepare_to_restore();
}
return $this->attemptupgrader;
}
/**
* Process the attempt data defined by {@link add_legacy_question_attempt_data()}.
* @param object $data contains all the grouped attempt data ot process.
* @param pbject $quiz data about the activity the attempts belong to. Required
* fields are (basically this only works for the quiz module):
* oldquestions => list of question ids in this activity - using old ids.
* preferredbehaviour => the behaviour to use for questionattempts.
*/
protected function process_legacy_quiz_attempt_data($data, $quiz) {
global $DB;
$upgrader = $this->get_attempt_upgrader();
$data = (object)$data;
$layout = explode(',', $data->layout);
$newlayout = $layout;
// Convert each old question_session into a question_attempt.
$qas = array();
foreach (explode(',', $quiz->oldquestions) as $questionid) {
if ($questionid == 0) {
continue;
}
$newquestionid = $this->get_mappingid('question', $questionid);
if (!$newquestionid) {
throw new restore_step_exception('questionattemptreferstomissingquestion',
$questionid, $questionid);
}
$question = $upgrader->load_question($newquestionid, $quiz->id);
foreach ($layout as $key => $qid) {
if ($qid == $questionid) {
$newlayout[$key] = $newquestionid;
}
}
list($qsession, $qstates) = $this->find_question_session_and_states(
$data, $questionid);
if (empty($qsession) || empty($qstates)) {
throw new restore_step_exception('questionattemptdatamissing',
$questionid, $questionid);
}
list($qsession, $qstates) = $this->recode_legacy_response_data(
$question, $qsession, $qstates);
$data->layout = implode(',', $newlayout);
$qas[$newquestionid] = $upgrader->convert_question_attempt(
$quiz, $data, $question, $qsession, $qstates);
}
// Now create a new question_usage.
$usage = new stdClass();
$usage->component = 'mod_quiz';
$usage->contextid = $this->get_mappingid('context', $this->task->get_old_contextid());
$usage->preferredbehaviour = $quiz->preferredbehaviour;
$usage->id = $DB->insert_record('question_usages', $usage);
$this->inform_new_usage_id($usage->id);
$data->uniqueid = $usage->id;
$upgrader->save_usage($quiz->preferredbehaviour, $data, $qas, $quiz->questions);
}
protected function find_question_session_and_states($data, $questionid) {
$qsession = null;
foreach ($data->sessions['session'] as $session) {
if ($session['questionid'] == $questionid) {
$qsession = (object) $session;
break;
}
}
$qstates = array();
foreach ($data->states['state'] as $state) {
if ($state['question'] == $questionid) {
// It would be natural to use $state['seq_number'] as the array-key
// here, but it seems that buggy behaviour in 2.0 and early can
// mean that that is not unique, so we use id, which is guaranteed
// to be unique.
$qstates[$state['id']] = (object) $state;
}
}
ksort($qstates);
$qstates = array_values($qstates);
return array($qsession, $qstates);
}
/**
* Recode any ids in the response data
* @param object $question the question data
* @param object $qsession the question sessions.
* @param array $qstates the question states.
*/
protected function recode_legacy_response_data($question, $qsession, $qstates) {
$qsession->questionid = $question->id;
foreach ($qstates as &$state) {
$state->question = $question->id;
$state->answer = $this->restore_recode_legacy_answer($state, $question->qtype);
}
return array($qsession, $qstates);
}
/**
* Recode the legacy answer field.
* @param object $state the state to recode the answer of.
* @param string $qtype the question type.
*/
public function restore_recode_legacy_answer($state, $qtype) {
$restorer = $this->get_qtype_restorer($qtype);
if ($restorer) {
return $restorer->recode_legacy_state_answer($state);
} else {
return $state->answer;
}
return !empty($qtypeplugins[$qtype]) ? $qtypeplugins[$qtype]->recode_state_answer($state) : $state->answer;
}
}
+1 -7
View File
@@ -5,7 +5,7 @@ require_once('../config.php');
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
$contextid = required_param('contextid', PARAM_INT);
$stage = optional_param('stage', restore_ui::STAGE_CONFIRM, PARAM_INT);
$stage = optional_param('stage', restore_ui::STAGE_CONFIRM, PARAM_INT);
list($context, $course, $cm) = get_context_info_array($contextid);
@@ -30,15 +30,9 @@ if ($stage & restore_ui::STAGE_CONFIRM + restore_ui::STAGE_DESTINATION) {
}
}
if ($rc) {
// check if the format conversion must happen first
if ($rc->get_status() == backup::STATUS_REQUIRE_CONV) {
$rc->convert();
}
$restore = new restore_ui($rc, array('contextid'=>$context->id));
}
}
$outcome = $restore->process();
if (!$restore->is_independent()) {
if ($restore->get_stage() == restore_ui::STAGE_PROCESS && !$restore->requires_substage()) {
+34 -32
View File
@@ -102,45 +102,31 @@ abstract class backup_check {
// Note: all the checks along the function MUST be performed for $userid, that
// is the user who "requested" the course backup, not current $USER at all!!
// First of all, check the main backup[course|section|activity] principal caps
// Lacking the corresponding one makes this to break with exception always
// First of all, decide which caps/contexts are we going to check
// for common backups (general, automated...) based exclusively
// in the type (course, section, activity). And store them into
// one capability => context array structure
$typecapstocheck = array();
switch ($type) {
case backup::TYPE_1COURSE :
$DB->get_record('course', array('id' => $id), '*', MUST_EXIST); // course exists
if (!has_capability('moodle/backup:backupcourse', $coursectx, $userid)) {
$a = new stdclass();
$a->userid = $userid;
$a->courseid = $courseid;
$a->capability = 'moodle/backup:backupcourse';
throw new backup_controller_exception('backup_user_missing_capability', $a);
}
$typecapstocheck['moodle/backup:backupcourse'] = $coursectx;
break;
case backup::TYPE_1SECTION :
$DB->get_record('course_sections', array('course' => $courseid, 'id' => $id), '*', MUST_EXIST); // sec exists
if (!has_capability('moodle/backup:backupsection', $coursectx, $userid)) {
$a = new stdclass();
$a->userid = $userid;
$a->courseid = $courseid;
$a->capability = 'moodle/backup:backupsection';
throw new backup_controller_exception('backup_user_missing_capability', $a);
}
$typecapstocheck['moodle/backup:backupsection'] = $coursectx;
break;
case backup::TYPE_1ACTIVITY :
get_coursemodule_from_id(null, $id, $courseid, false, MUST_EXIST); // cm exists
$modulectx = get_context_instance(CONTEXT_MODULE, $id);
if (!has_capability('moodle/backup:backupactivity', $modulectx, $userid)) {
$a = new stdclass();
$a->userid = $userid;
$a->cmid = $id;
$a->capability = 'moodle/backup:backupactivity';
throw new backup_controller_exception('backup_user_missing_capability', $a);
}
$typecapstocheck['moodle/backup:backupactivity'] = $modulectx;
break;
default :
print_error('unknownbackuptype');
throw new backup_controller_exception('backup_unknown_backup_type', $type);
}
// Now, if backup mode is hub or import, check userid has permissions for those modes
// other modes will perform common checks only (backupxxxx capabilities in $typecapstocheck)
switch ($mode) {
case backup::MODE_HUB:
if (!has_capability('moodle/backup:backuptargethub', $coursectx, $userid)) {
@@ -160,6 +146,18 @@ abstract class backup_check {
throw new backup_controller_exception('backup_user_missing_capability', $a);
}
break;
// Common backup (general, automated...), let's check all the $typecapstocheck
// capability => context pairs
default:
foreach ($typecapstocheck as $capability => $context) {
if (!has_capability($capability, $context, $userid)) {
$a = new stdclass();
$a->userid = $userid;
$a->courseid = $courseid;
$a->capability = $capability;
throw new backup_controller_exception('backup_user_missing_capability', $a);
}
}
}
// Now, enforce 'moodle/backup:userinfo' to 'users' setting, applying changes if allowed,
@@ -219,15 +217,19 @@ abstract class backup_check {
}
// Check the user has the ability to configure the backup. If not then we need
// to lock all settings by permission so that no changes can be made.
$hasconfigcap = has_capability('moodle/backup:configure', $coursectx, $userid);
if (!$hasconfigcap) {
$settings = $backup_controller->get_plan()->get_settings();
foreach ($settings as $setting) {
if ($setting->get_name()=='filename') {
continue;
// to lock all settings by permission so that no changes can be made. This does
// not apply to the import facility, where the activities must be always enabled
// to be able to pick them
if ($mode != backup::MODE_IMPORT) {
$hasconfigcap = has_capability('moodle/backup:configure', $coursectx, $userid);
if (!$hasconfigcap) {
$settings = $backup_controller->get_plan()->get_settings();
foreach ($settings as $setting) {
if ($setting->get_name() == 'filename') {
continue;
}
$setting->set_status(base_setting::LOCKED_BY_PERMISSION);
}
$setting->set_status(base_setting::LOCKED_BY_PERMISSION);
}
}
+32 -30
View File
@@ -68,41 +68,27 @@ abstract class restore_check {
// Note: all the checks along the function MUST be performed for $userid, that
// is the user who "requested" the course restore, not current $USER at all!!
// First of all, check the main restore[course|section|activity] principal caps
// Lacking the corresponding one makes this to break with exception always
// First of all, decide which caps/contexts are we going to check
// for common backups (general, automated...) based exclusively
// in the type (course, section, activity). And store them into
// one capability => context array structure
$typecapstocheck = array();
switch ($type) {
case backup::TYPE_1COURSE :
if (!has_capability('moodle/restore:restorecourse', $coursectx, $userid)) {
$a = new stdclass();
$a->userid = $userid;
$a->courseid = $courseid;
$a->capability = 'moodle/restore:restorecourse';
throw new restore_controller_exception('restore_user_missing_capability', $a);
}
$typecapstocheck['moodle/restore:restorecourse'] = $coursectx;
break;
case backup::TYPE_1SECTION :
if (!has_capability('moodle/restore:restoresection', $coursectx, $userid)) {
$a = new stdclass();
$a->userid = $userid;
$a->courseid = $courseid;
$a->capability = 'moodle/restore:restoresection';
throw new restore_controller_exception('restore_user_missing_capability', $a);
}
$typecapstocheck['moodle/restore:restoresection'] = $coursectx;
break;
case backup::TYPE_1ACTIVITY :
if (!has_capability('moodle/restore:restoreactivity', $coursectx, $userid)) {
$a = new stdclass();
$a->userid = $userid;
$a->courseid = $courseid;
$a->capability = 'moodle/restore:restoreactivity';
throw new restore_controller_exception('restore_user_missing_capability', $a);
}
$typecapstocheck['moodle/restore:restoreactivity'] = $coursectx;
break;
default :
print_error('unknownrestoretype');
throw new restore_controller_exception('restore_unknown_restore_type', $type);
}
// Now, if restore mode is hub or import, check userid has permissions for those modes
// other modes will perform common checks only (restorexxxx capabilities in $typecapstocheck)
switch ($mode) {
case backup::MODE_HUB:
if (!has_capability('moodle/restore:restoretargethub', $coursectx, $userid)) {
@@ -122,6 +108,18 @@ abstract class restore_check {
throw new restore_controller_exception('restore_user_missing_capability', $a);
}
break;
// Common backup (general, automated...), let's check all the $typecapstocheck
// capability => context pairs
default:
foreach ($typecapstocheck as $capability => $context) {
if (!has_capability($capability, $context, $userid)) {
$a = new stdclass();
$a->userid = $userid;
$a->courseid = $courseid;
$a->capability = $capability;
throw new restore_controller_exception('restore_user_missing_capability', $a);
}
}
}
// Now, enforce 'moodle/restore:userinfo' to 'users' setting, applying changes if allowed,
@@ -158,12 +156,16 @@ abstract class restore_check {
}
// Check the user has the ability to configure the restore. If not then we need
// to lock all settings by permission so that no changes can be made.
$hasconfigcap = has_capability('moodle/restore:configure', $coursectx, $userid);
if (!$hasconfigcap) {
$settings = $restore_controller->get_plan()->get_settings();
foreach ($settings as $setting) {
$setting->set_status(base_setting::LOCKED_BY_PERMISSION);
// to lock all settings by permission so that no changes can be made. This does
// not apply to the import facility, where all the activities (picked on backup)
// are restored automatically without restore UI
if ($mode != backup::MODE_IMPORT) {
$hasconfigcap = has_capability('moodle/restore:configure', $coursectx, $userid);
if (!$hasconfigcap) {
$settings = $restore_controller->get_plan()->get_settings();
foreach ($settings as $setting) {
$setting->set_status(base_setting::LOCKED_BY_PERMISSION);
}
}
}
@@ -401,12 +401,40 @@ abstract class backup_controller_dbops extends backup_dbops {
return $DB->get_record('course', array('id' => $courseid), 'fullname, shortname, startdate');
}
/**
* Sets the default values for the settings in a backup operation
*
* Based on the mode of the backup it will delegate the process to
* other methods like {@link apply_general_config_defaults} ...
* to get proper defaults loaded
*
* @param backup_controller $controller
*/
public static function apply_config_defaults(backup_controller $controller) {
// Based on the mode of the backup (general, automated, import, hub...)
// decide the action to perform to get defaults loaded
$mode = $controller->get_mode();
switch ($mode) {
case backup::MODE_GENERAL:
// Load the general defaults
self::apply_general_config_defaults($controller);
break;
case backup::MODE_AUTOMATED:
// TODO: Move the loading from automatic stuff to here
break;
default:
// Nothing to do for other modes (IMPORT/HUB...). Some day we
// can define defaults (admin UI...) for them if we want to
}
}
/**
* Sets the controller settings default values from the backup config.
*
* @param backup_controller $controller
*/
public static function apply_general_config_defaults(backup_controller $controller) {
private static function apply_general_config_defaults(backup_controller $controller) {
$settings = array(
// Config name => Setting name
'backup_general_users' => 'users',
@@ -1,60 +0,0 @@
<?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/>.
/**
* @package core
* @subpackage backup-convert
* @copyright 2011 Mark Nielsen <mark@moodlerooms.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Factory class to create new instances of backup converters
*/
abstract class convert_factory {
/**
* Instantinates the given converter operating on a given directory
*
* @throws coding_exception
* @param $name The converter name
* @param $tempdir The temp directory to operate on
* @param base_logger|null if the conversion should be logged, use this logger
* @return base_converter
*/
public static function get_converter($name, $tempdir, $logger = null) {
global $CFG;
$name = clean_param($name, PARAM_SAFEDIR);
$classfile = "$CFG->dirroot/backup/converter/$name/lib.php";
$classname = "{$name}_converter";
if (!file_exists($classfile)) {
throw new coding_exception("Converter factory error: class file not found $classfile");
}
require_once($classfile);
if (!class_exists($classname)) {
throw new coding_exception("Converter factory error: class not found $classname");
}
return new $classname($tempdir, $logger);
}
}
@@ -123,14 +123,24 @@ abstract class backup_cron_automated_helper {
$backupcourse = $DB->get_record('backup_courses', array('courseid'=>$course->id));
}
// Skip courses that do not yet need backup
$skipped = !(($backupcourse->nextstarttime >= 0 && $backupcourse->nextstarttime < $now) || $rundirective == self::RUN_IMMEDIATELY);
// Skip backup of unavailable courses that have remained unmodified in a month
$skipped = false;
if (empty($course->visible) && ($now - $course->timemodified) > 31*24*60*60) { //Hidden + unmodified last month
$backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_SKIPPED;
$DB->update_record('backup_courses', $backupcourse);
mtrace('Skipping unchanged course '.$course->fullname);
$skipped = true;
} else if (($backupcourse->nextstarttime >= 0 && $backupcourse->nextstarttime < $now) || $rundirective == self::RUN_IMMEDIATELY) {
if (!$skipped && empty($course->visible) && ($now - $course->timemodified) > 31*24*60*60) { //Hidden + settings were unmodified last month
//Check log if there were any modifications to the course content
$sqlwhere = "course=:courseid AND time>:time AND ". $DB->sql_like('action', ':action', false, true, true);
$params = array('courseid' => $course->id, 'time' => $now-31*24*60*60, 'action' => '%view%');
$logexists = $DB->record_exists_select('log', $sqlwhere, $params);
if (!$logexists) {
$backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_SKIPPED;
$backupcourse->nextstarttime = $nextstarttime;
$DB->update_record('backup_courses', $backupcourse);
mtrace('Skipping unchanged course '.$course->fullname);
$skipped = true;
}
}
//Now we backup every non-skipped course
if (!$skipped) {
mtrace('Backing up '.$course->fullname, '...');
//We have to send a email because we have included at least one backup
@@ -312,7 +322,7 @@ abstract class backup_cron_automated_helper {
$settings = array(
'users' => 'backup_auto_users',
'role_assignments' => 'backup_auto_users',
'role_assignments' => 'backup_auto_role_assignments',
'user_files' => 'backup_auto_user_files',
'activities' => 'backup_auto_activities',
'blocks' => 'backup_auto_blocks',
@@ -214,10 +214,8 @@ abstract class backup_general_helper extends backup_helper {
* generated or no. Behavior of various parts of restore are
* dependent of this.
*
* Backups created natively in 2.0 and later declare the hashed
* site identifier. Backups created by conversion from a 1.9
* backup do not declare such identifier, so there is a fallback
* to wwwroot comparison. See MDL-16614.
* Use site_identifier (hashed) and fallback to wwwroot, thought
* any 2.0 backup should have the former. See MDL-16614
*/
public static function backup_is_samesite($info) {
global $CFG;
@@ -230,34 +228,50 @@ abstract class backup_general_helper extends backup_helper {
}
/**
* Detects the format of the given unpacked backup directory
* Given one temp/backup/xxx dir, detect its format
*
* @param string $tempdir the name of the backup directory
* @return string one of backup::FORMAT_xxx constants
* TODO: Move harcoded detection here to delegated classes under backup/format (moodle1, imscc..)
* conversion code will be there too.
*/
public static function detect_backup_format($tempdir) {
global $CFG;
require_once($CFG->dirroot . '/backup/util/helper/convert_helper.class.php');
$filepath = $CFG->dataroot . '/temp/backup/' . $tempdir . '/moodle_backup.xml';
if (convert_helper::detect_moodle2_format($tempdir)) {
return backup::FORMAT_MOODLE;
// Does tempdir exist and is dir
if (!is_dir(dirname($filepath))) {
throw new backup_helper_exception('tmp_backup_directory_not_found', dirname($filepath));
}
// see if a converter can identify the format
$converters = convert_helper::available_converters();
foreach ($converters as $name) {
$classname = "{$name}_converter";
if (!class_exists($classname)) {
throw new coding_exception("available_converters() is supposed to load
converter classes but class $classname not found");
}
$detected = call_user_func($classname .'::detect_format', $tempdir);
if (!empty($detected)) {
return $detected;
// First look for MOODLE (moodle2) format
if (file_exists($filepath)) { // Looks promising, lets load some information
$handle = fopen ($filepath, "r");
$first_chars = fread($handle,200);
$status = fclose ($handle);
// Check if it has the required strings
if (strpos($first_chars,'<?xml version="1.0" encoding="UTF-8"?>') !== false &&
strpos($first_chars,'<moodle_backup>') !== false &&
strpos($first_chars,'<information>') !== false) {
return backup::FORMAT_MOODLE;
}
}
// Then look for MOODLE1 (moodle1) format
$filepath = $CFG->dataroot . '/temp/backup/' . $tempdir . '/moodle.xml';
if (file_exists($filepath)) { // Looks promising, lets load some information
$handle = fopen ($filepath, "r");
$first_chars = fread($handle,200);
$status = fclose ($handle);
// Check if it has the required strings
if (strpos($first_chars,'<?xml version="1.0" encoding="UTF-8"?>') !== false &&
strpos($first_chars,'<MOODLE_BACKUP>') !== false &&
strpos($first_chars,'<INFO>') !== false) {
return backup::FORMAT_MOODLE1;
}
}
// Other formats
// Arrived here, unknown format
return backup::FORMAT_UNKNOWN;
}
}
-340
View File
@@ -1,340 +0,0 @@
<?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/>.
/**
* Provides {@link convert_helper} and {@link convert_helper_exception} classes
*
* @package core
* @subpackage backup-convert
* @copyright 2011 Mark Nielsen <mark@moodlerooms.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/backup/util/includes/convert_includes.php');
/**
* Provides various functionality via its static methods
*/
abstract class convert_helper {
/**
* @param string $entropy
* @return string random identifier
*/
public static function generate_id($entropy) {
return md5(time() . '-' . $entropy . '-' . random_string(20));
}
/**
* Returns the list of all available converters and loads their classes
*
* Converter must be installed as a directory in backup/converter/ and its
* method is_available() must return true to get to the list.
*
* @see base_converter::is_available()
* @return array of strings
*/
public static function available_converters() {
global $CFG;
$converters = array();
$plugins = get_list_of_plugins('backup/converter');
foreach ($plugins as $name) {
$classfile = "$CFG->dirroot/backup/converter/$name/lib.php";
$classname = "{$name}_converter";
if (!file_exists($classfile)) {
throw new convert_helper_exception('converter_classfile_not_found', $classfile);
}
require_once($classfile);
if (!class_exists($classname)) {
throw new convert_helper_exception('converter_classname_not_found', $classname);
}
if (call_user_func($classname .'::is_available')) {
$converters[] = $name;
}
}
return $converters;
}
/**
* Detects if the given folder contains an unpacked moodle2 backup
*
* @param string $tempdir the name of the backup directory
* @return boolean true if moodle2 format detected, false otherwise
*/
public static function detect_moodle2_format($tempdir) {
global $CFG;
$dirpath = $CFG->dataroot . '/temp/backup/' . $tempdir;
$filepath = $dirpath . '/moodle_backup.xml';
if (!is_dir($dirpath)) {
throw new convert_helper_exception('tmp_backup_directory_not_found', $dirpath);
}
if (!file_exists($filepath)) {
return false;
}
$handle = fopen($filepath, 'r');
$firstchars = fread($handle, 200);
$status = fclose($handle);
if (strpos($firstchars,'<?xml version="1.0" encoding="UTF-8"?>') !== false and
strpos($firstchars,'<moodle_backup>') !== false and
strpos($firstchars,'<information>') !== false) {
return true;
}
return false;
}
/**
* Converts the given directory with the backup into moodle2 format
*
* @param string $tempdir The directory to convert
* @param string $format The current format, if already detected
* @param base_logger|null if the conversion should be logged, use this logger
* @throws convert_helper_exception
* @return bool false if unable to find the conversion path, true otherwise
*/
public static function to_moodle2_format($tempdir, $format = null, $logger = null) {
if (is_null($format)) {
$format = backup_general_helper::detect_backup_format($tempdir);
}
// get the supported conversion paths from all available converters
$converters = self::available_converters();
$descriptions = array();
foreach ($converters as $name) {
$classname = "{$name}_converter";
if (!class_exists($classname)) {
throw new convert_helper_exception('class_not_loaded', $classname);
}
if ($logger instanceof base_logger) {
backup_helper::log('available converter', backup::LOG_DEBUG, $classname, 1, false, $logger);
}
$descriptions[$name] = call_user_func($classname .'::description');
}
// choose the best conversion path for the given format
$path = self::choose_conversion_path($format, $descriptions);
if (empty($path)) {
if ($logger instanceof base_logger) {
backup_helper::log('unable to find the conversion path', backup::LOG_ERROR, null, 0, false, $logger);
}
return false;
}
if ($logger instanceof base_logger) {
backup_helper::log('conversion path established', backup::LOG_INFO,
implode(' => ', array_merge($path, array('moodle2'))), 0, false, $logger);
}
foreach ($path as $name) {
if ($logger instanceof base_logger) {
backup_helper::log('running converter', backup::LOG_INFO, $name, 0, false, $logger);
}
$converter = convert_factory::get_converter($name, $tempdir, $logger);
$converter->convert();
}
// make sure we ended with moodle2 format
if (!self::detect_moodle2_format($tempdir)) {
throw new convert_helper_exception('conversion_failed');
}
return true;
}
/**
* Inserts an inforef into the conversion temp table
*/
public static function set_inforef($contextid) {
global $DB;
}
public static function get_inforef($contextid) {
}
/// end of public API //////////////////////////////////////////////////////
/**
* Choose the best conversion path for the given format
*
* Given the source format and the list of available converters and their properties,
* this methods picks the most effective way how to convert the source format into
* the target moodle2 format. The method returns a list of converters that should be
* called, in order.
*
* This implementation uses Dijkstra's algorithm to find the shortest way through
* the oriented graph.
*
* @see http://en.wikipedia.org/wiki/Dijkstra's_algorithm
* @author David Mudrak <david@moodle.com>
* @param string $format the source backup format, one of backup::FORMAT_xxx
* @param array $descriptions list of {@link base_converter::description()} indexed by the converter name
* @return array ordered list of converter names to call (may be empty if not reachable)
*/
protected static function choose_conversion_path($format, array $descriptions) {
// construct an oriented graph of conversion paths. backup formats are nodes
// and the the converters are edges of the graph.
$paths = array(); // [fromnode][tonode] => converter
foreach ($descriptions as $converter => $description) {
$from = $description['from'];
$to = $description['to'];
$cost = $description['cost'];
if (is_null($from) or $from === backup::FORMAT_UNKNOWN or
is_null($to) or $to === backup::FORMAT_UNKNOWN or
is_null($cost) or $cost <= 0) {
throw new convert_helper_exception('invalid_converter_description', $converter);
}
if (!isset($paths[$from][$to])) {
$paths[$from][$to] = $converter;
} else {
// if there are two converters available for the same conversion
// path, choose the one with the lowest cost. if there are more
// available converters with the same cost, the chosen one is
// undefined (depends on the order of processing)
if ($descriptions[$paths[$from][$to]]['cost'] > $cost) {
$paths[$from][$to] = $converter;
}
}
}
if (empty($paths)) {
// no conversion paths available
return array();
}
// now use Dijkstra's algorithm and find the shortest conversion path
$dist = array(); // list of nodes and their distances from the source format
$prev = array(); // list of previous nodes in optimal path from the source format
foreach ($paths as $fromnode => $tonodes) {
$dist[$fromnode] = null; // infinitive distance, can't be reached
$prev[$fromnode] = null; // unknown
foreach ($tonodes as $tonode => $converter) {
$dist[$tonode] = null; // infinitive distance, can't be reached
$prev[$tonode] = null; // unknown
}
}
if (!array_key_exists($format, $dist)) {
return array();
} else {
$dist[$format] = 0;
}
$queue = array_flip(array_keys($dist));
while (!empty($queue)) {
// find the node with the smallest distance from the source in the queue
// in the first iteration, this will find the original format node itself
$closest = null;
foreach ($queue as $node => $undefined) {
if (is_null($dist[$node])) {
continue;
}
if (is_null($closest) or ($dist[$node] < $dist[$closest])) {
$closest = $node;
}
}
if (is_null($closest) or is_null($dist[$closest])) {
// all remaining nodes are inaccessible from source
break;
}
if ($closest === backup::FORMAT_MOODLE) {
// bingo we can break now
break;
}
unset($queue[$closest]);
// visit all neighbors and update distances to them eventually
if (!isset($paths[$closest])) {
continue;
}
$neighbors = array_keys($paths[$closest]);
// keep just neighbors that are in the queue yet
foreach ($neighbors as $ix => $neighbor) {
if (!array_key_exists($neighbor, $queue)) {
unset($neighbors[$ix]);
}
}
foreach ($neighbors as $neighbor) {
// the alternative distance to the neighbor if we went thru the
// current $closest node
$alt = $dist[$closest] + $descriptions[$paths[$closest][$neighbor]]['cost'];
if (is_null($dist[$neighbor]) or $alt < $dist[$neighbor]) {
// we found a shorter way to the $neighbor, remember it
$dist[$neighbor] = $alt;
$prev[$neighbor] = $closest;
}
}
}
if (is_null($dist[backup::FORMAT_MOODLE])) {
// unable to find a conversion path, the target format not reachable
return array();
}
// reconstruct the optimal path from the source format to the target one
$conversionpath = array();
$target = backup::FORMAT_MOODLE;
while (isset($prev[$target])) {
array_unshift($conversionpath, $paths[$prev[$target]][$target]);
$target = $prev[$target];
}
return $conversionpath;
}
}
/**
* General convert_helper related exception
*
* @author David Mudrak <david@moodle.com>
*/
class convert_helper_exception extends moodle_exception {
/**
* Constructor
*
* @param string $errorcode key for the corresponding error string
* @param object $a extra words and phrases that might be required in the error string
* @param string $debuginfo optional debugging information
*/
public function __construct($errorcode, $a = null, $debuginfo = null) {
parent::__construct($errorcode, '', '', $a, $debuginfo);
}
}
@@ -53,12 +53,4 @@ class restore_inforef_parser_processor extends grouped_parser_processor {
$itemid = $data['tags']['id'];
restore_dbops::set_backup_ids_record($this->restoreid, $itemname, $itemid);
}
protected function notify_path_start($path) {
// nothing to do
}
protected function notify_path_end($path) {
// nothing to do
}
}
@@ -51,14 +51,6 @@ class restore_moodlexml_parser_processor extends grouped_parser_processor {
$this->accumchunks[] = $data;
}
protected function notify_path_start($path) {
// nothing to do
}
protected function notify_path_end($path) {
// nothing to do
}
public function get_all_chunks() {
return $this->accumchunks;
}
@@ -75,14 +75,6 @@ class restore_questions_parser_processor extends grouped_parser_processor {
}
}
protected function notify_path_start($path) {
// nothing to do
}
protected function notify_path_end($path) {
// nothing to do
}
/**
* Provide NULL decoding
*/
@@ -55,14 +55,6 @@ class restore_roles_parser_processor extends grouped_parser_processor {
}
}
protected function notify_path_start($path) {
// nothing to do
}
protected function notify_path_end($path) {
// nothing to do
}
/**
* Provide NULL decoding
*/
@@ -102,12 +102,4 @@ class restore_structure_parser_processor extends grouped_parser_processor {
protected function dispatch_chunk($data) {
$this->step->process($data);
}
protected function notify_path_start($path) {
// nothing to do
}
protected function notify_path_end($path) {
// nothing to do
}
}
@@ -66,14 +66,6 @@ class restore_users_parser_processor extends grouped_parser_processor {
}
}
protected function notify_path_start($path) {
// nothing to do
}
protected function notify_path_end($path) {
// nothing to do
}
/**
* Provide NULL decoding
*/
@@ -1,146 +0,0 @@
<?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/>.
/**
* Unit tests for backup/util/helper/convert_helper.class.php
*
* @package core
* @subpackage backup-convert
* @copyright 2011 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/backup/util/helper/convert_helper.class.php');
/**
* Provides access to the protected methods we need to test
*/
class testable_convert_helper extends convert_helper {
public static function choose_conversion_path($format, array $descriptions) {
return parent::choose_conversion_path($format, $descriptions);
}
}
/**
* Defines the test methods
*/
class convert_helper_test extends UnitTestCase {
public static $includecoverage = array();
public function test_choose_conversion_path() {
// no converters available
$descriptions = array();
$path = testable_convert_helper::choose_conversion_path(backup::FORMAT_MOODLE1, $descriptions);
$this->assertEqual($path, array());
// missing source and/or targets
$descriptions = array(
// some custom converter
'exporter' => array(
'from' => backup::FORMAT_MOODLE1,
'to' => 'some_custom_format',
'cost' => 10,
),
// another custom converter
'converter' => array(
'from' => 'yet_another_crazy_custom_format',
'to' => backup::FORMAT_MOODLE,
'cost' => 10,
),
);
$path = testable_convert_helper::choose_conversion_path(backup::FORMAT_MOODLE1, $descriptions);
$this->assertEqual($path, array());
$path = testable_convert_helper::choose_conversion_path('some_other_custom_format', $descriptions);
$this->assertEqual($path, array());
// single step conversion
$path = testable_convert_helper::choose_conversion_path('yet_another_crazy_custom_format', $descriptions);
$this->assertEqual($path, array('converter'));
// no conversion needed - this is supposed to be detected by the caller
$path = testable_convert_helper::choose_conversion_path(backup::FORMAT_MOODLE, $descriptions);
$this->assertEqual($path, array());
// two alternatives
$descriptions = array(
// standard moodle 1.9 -> 2.x converter
'moodle1' => array(
'from' => backup::FORMAT_MOODLE1,
'to' => backup::FORMAT_MOODLE,
'cost' => 10,
),
// alternative moodle 1.9 -> 2.x converter
'alternative' => array(
'from' => backup::FORMAT_MOODLE1,
'to' => backup::FORMAT_MOODLE,
'cost' => 8,
)
);
$path = testable_convert_helper::choose_conversion_path(backup::FORMAT_MOODLE1, $descriptions);
$this->assertEqual($path, array('alternative'));
// complex case
$descriptions = array(
// standard moodle 1.9 -> 2.x converter
'moodle1' => array(
'from' => backup::FORMAT_MOODLE1,
'to' => backup::FORMAT_MOODLE,
'cost' => 10,
),
// alternative moodle 1.9 -> 2.x converter
'alternative' => array(
'from' => backup::FORMAT_MOODLE1,
'to' => backup::FORMAT_MOODLE,
'cost' => 8,
),
// custom converter from 1.9 -> custom 'CFv1' format
'cc1' => array(
'from' => backup::FORMAT_MOODLE1,
'to' => 'CFv1',
'cost' => 2,
),
// custom converter from custom 'CFv1' format -> moodle 2.0 format
'cc2' => array(
'from' => 'CFv1',
'to' => backup::FORMAT_MOODLE,
'cost' => 5,
),
// custom converter from CFv1 -> CFv2 format
'cc3' => array(
'from' => 'CFv1',
'to' => 'CFv2',
'cost' => 2,
),
// custom converter from CFv2 -> moodle 2.0 format
'cc4' => array(
'from' => 'CFv2',
'to' => backup::FORMAT_MOODLE,
'cost' => 2,
),
);
// ask the helper to find the most effective way
$path = testable_convert_helper::choose_conversion_path(backup::FORMAT_MOODLE1, $descriptions);
$this->assertEqual($path, array('cc1', 'cc3', 'cc4'));
}
}
-34
View File
@@ -1,34 +0,0 @@
<?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/>.
/**
* Makes sure that all general code needed by backup-convert code is included
*
* @package core
* @subpackage backup-convert
* @copyright 2011 Mark Nielsen <mark@moodlerooms.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/backup/util/interfaces/loggable.class.php'); // converters are loggable
require_once($CFG->dirroot . '/backup/util/interfaces/checksumable.class.php'); // req by backup.class.php
require_once($CFG->dirroot . '/backup/backup.class.php'); // provides backup::FORMAT_xxx constants
require_once($CFG->dirroot . '/backup/util/helper/convert_helper.class.php');
require_once($CFG->dirroot . '/backup/util/factories/convert_factory.class.php');
require_once($CFG->libdir . '/filelib.php');
+6 -4
View File
@@ -140,14 +140,16 @@ abstract class base_ui {
/**
* Displays the UI for the backup!
*
* @throws base_ui_exception
* @return string HTML code
* Note: The UI makes use of mforms (ewww!) thus it will automatically print
* out the result rather than returning a string of HTML like other parts of Moodle
*
* @return bool
*/
public function display() {
if ($this->progress < self::PROGRESS_SAVED) {
throw new base_ui_exception('backupsavebeforedisplay');
}
return $this->stage->display();
$this->stage->display();
}
/**
* Gets all backup tasks from the controller
@@ -304,4 +306,4 @@ abstract class base_ui {
/**
* Backup user interface exception. Modelled off the backup_exception class
*/
class base_ui_exception extends backup_exception {}
class base_ui_exception extends backup_exception {}
+3 -15
View File
@@ -108,29 +108,17 @@ abstract class base_ui_stage {
final public function get_uniqueid() {
return $this->ui->get_uniqueid();
}
/**
* Displays the stage.
*
* By default this involves instantiating the form for the stage and the calling
* it to display.
*
* @return string HTML code to display
* it to display. Remember this is a moodleform instance so it will print
* rather than return.
*/
public function display() {
$form = $this->initialise_stage_form();
// a nasty hack follows to work around the sad fact that moodle quickforms
// do not allow to actually return the HTML content, just to echo it
flush();
ob_start();
$form->display();
$output = ob_get_contents();
ob_end_clean();
return $output;
}
/**
* Processes the stage.
*
@@ -156,4 +144,4 @@ abstract class base_ui_stage {
public function is_first_stage() {
return $this->stage == 1;
}
}
}
+10 -1
View File
@@ -158,4 +158,13 @@ class import_ui_stage_final extends backup_ui_stage_final {}
/**
* Extends the restore course search to search for import courses.
*/
class import_course_search extends restore_course_search {}
class import_course_search extends restore_course_search {
/**
* Sets up any access restrictions for the courses to be displayed in the search.
*
* This will typically call $this->require_capability().
*/
protected function setup_restrictions() {
$this->require_capability('moodle/backup:backuptargetimport');
}
}
+22 -48
View File
@@ -157,60 +157,17 @@ class core_backup_renderer extends plugin_renderer_base {
return $html;
}
/**
* Displays the general information about a backup file with non-standard format
*
* @param moodle_url $nextstageurl URL to send user to
* @param array $details basic info about the file (format, type)
* @return string HTML code to display
*/
public function backup_details_nonstandard($nextstageurl, array $details) {
$html = html_writer::start_tag('div', array('class' => 'backup-restore nonstandardformat'));
$html .= html_writer::start_tag('div', array('class' => 'backup-section'));
$html .= $this->output->heading(get_string('backupdetails', 'backup'), 2, 'header');
$html .= $this->output->box(get_string('backupdetailsnonstandardinfo', 'backup'), 'noticebox');
$html .= $this->backup_detail_pair(
get_string('backupformat', 'backup'),
get_string('backupformat'.$details['format'], 'backup'));
$html .= $this->backup_detail_pair(
get_string('backuptype', 'backup'),
get_string('backuptype'.$details['type'], 'backup'));
$html .= html_writer::end_tag('div');
$html .= $this->output->single_button($nextstageurl, get_string('continue'), 'post');
$html .= html_writer::end_tag('div');
return $html;
}
/**
* Displays the general information about a backup file with unknown format
*
* @param moodle_url $nextstageurl URL to send user to
* @return string HTML code to display
*/
public function backup_details_unknown(moodle_url $nextstageurl) {
$html = html_writer::start_tag('div', array('class' => 'unknownformat'));
$html .= $this->output->heading(get_string('errorinvalidformat', 'backup'), 2, 'notifyproblem');
$html .= html_writer::tag('div', get_string('errorinvalidformatinfo', 'backup'), array('class' => 'notifyproblem'));
$html .= $this->output->single_button($nextstageurl, get_string('continue'), 'post');
$html .= html_writer::end_tag('div');
return $html;
}
/**
* Displays a course selector for restore
*
* @param moodle_url $nextstageurl
* @param bool $wholecourse true if we are restoring whole course (as with backup::TYPE_1COURSE), false otherwise
* @param stdClass $details
* @param restore_category_search $categories
* @param restore_course_search $courses
* @param int $currentcourse
* @return string
*/
public function course_selector(moodle_url $nextstageurl, $wholecourse = true, restore_category_search $categories = null, restore_course_search $courses=null, $currentcourse = null) {
public function course_selector(moodle_url $nextstageurl, $details, restore_category_search $categories = null, restore_course_search $courses=null, $currentcourse = null) {
global $CFG;
require_once($CFG->dirroot.'/course/lib.php');
@@ -224,7 +181,7 @@ class core_backup_renderer extends plugin_renderer_base {
$hasrestoreoption = false;
$html = html_writer::start_tag('div', array('class'=>'backup-course-selector backup-restore'));
if ($wholecourse && !empty($categories) && ($categories->get_count() > 0 || $categories->get_search())) {
if ($details->type == backup::TYPE_1COURSE && !empty($categories) && ($categories->get_count() > 0 || $categories->get_search())) {
// New course
$hasrestoreoption = true;
$html .= $form;
@@ -237,7 +194,7 @@ class core_backup_renderer extends plugin_renderer_base {
$html .= html_writer::end_tag('form');
}
if ($wholecourse && !empty($currentcourse)) {
if ($details->type == backup::TYPE_1COURSE && !empty($currentcourse)) {
// Current course
$hasrestoreoption = true;
$html .= $form;
@@ -257,7 +214,7 @@ class core_backup_renderer extends plugin_renderer_base {
$html .= $form;
$html .= html_writer::start_tag('div', array('class'=>'bcs-existing-course backup-section'));
$html .= $this->output->heading(get_string('restoretoexistingcourse', 'backup'), 2, array('class'=>'header'));
if ($wholecourse) {
if ($details->type == backup::TYPE_1COURSE) {
$html .= $this->backup_detail_input(get_string('restoretoexistingcourseadding', 'backup'), 'radio', 'target', backup::TARGET_EXISTING_ADDING, array('checked'=>'checked'));
$html .= $this->backup_detail_input(get_string('restoretoexistingcoursedeleting', 'backup'), 'radio', 'target', backup::TARGET_EXISTING_DELETING);
$html .= $this->backup_detail_pair(get_string('selectacourse', 'backup'), $this->render($courses));
@@ -661,6 +618,23 @@ class core_backup_renderer extends plugin_renderer_base {
$output .= html_writer::end_tag('div');
return $output;
}
public function invalid_format($format) {
$html = html_writer::start_tag('div', array('class'=>'invalidformat'));
$html .= html_writer::tag('h2', get_string('errorinvalidformat', 'backup'), array('class'=>'notifyproblem'));
if ($format == 'moodle1') {
// Moodle 1.x backups
$icon = $this->output->help_icon('errormoodle1format', 'backup');
$message = get_string('errormoodle1formatdesc', 'backup').' '.$icon;
} else {
// Totally unknown format
$message = get_string('errorinvalidformatdesc', 'backup');
}
$html .= html_writer::tag('div', $message, array('class'=>'notifyproblem'));
$html .= html_writer::end_tag('div');
return $html;
}
}
/**
+2 -4
View File
@@ -252,19 +252,17 @@ class restore_ui extends base_ui {
}
/**
* Displays this stage
*
* @param core_backup_renderer $renderer
* @return string HTML code to echo
*/
public function display($renderer) {
if ($this->progress < self::PROGRESS_SAVED) {
throw new base_ui_exception('backupsavebeforedisplay');
}
return $this->stage->display($renderer);
$this->stage->display($renderer);
}
}
/**
* restore user interface exception. Modelled off the restore_exception class
*/
class restore_ui_exception extends base_ui_exception {}
class restore_ui_exception extends base_ui_exception {}
+9 -1
View File
@@ -226,10 +226,18 @@ class restore_course_search extends restore_search_base {
*/
public function __construct(array $config=array(), $currentcouseid = null) {
parent::__construct($config);
$this->require_capability('moodle/restore:restorecourse');
$this->setup_restrictions();
$this->currentcourseid = $currentcouseid;
$this->includecurrentcourse = false;
}
/**
* Sets up any access restrictions for the courses to be displayed in the search.
*
* This will typically call $this->require_capability().
*/
protected function setup_restrictions() {
$this->require_capability('moodle/restore:restorecourse');
}
/**
*
* @global moodle_database $DB
+53 -106
View File
@@ -1,5 +1,6 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@@ -170,39 +171,17 @@ class restore_ui_stage_confirm extends restore_ui_independent_stage {
$fb = get_file_packer();
return ($fb->extract_to_pathname("$CFG->dataroot/temp/backup/".$this->filename, "$CFG->dataroot/temp/backup/$this->filepath/"));
}
/**
* Renders the confirmation stage screen
*
* @param core_backup_renderer $renderer renderer instance to use
* @return string HTML code
*/
public function display($renderer) {
$prevstageurl = new moodle_url('/backup/restorefile.php', array('contextid' => $this->contextid));
$nextstageurl = new moodle_url('/backup/restore.php', array(
'contextid' => $this->contextid,
'filepath' => $this->filepath,
'stage' => restore_ui::STAGE_DESTINATION));
// TODO: Remove this when backup formats are better supported
$format = backup_general_helper::detect_backup_format($this->filepath);
if ($format === backup::FORMAT_UNKNOWN) {
// unknown format - we can't do anything here
return $renderer->backup_details_unknown($prevstageurl);
} else if ($format !== backup::FORMAT_MOODLE) {
// non-standard format to be converted
$details = array('format' => $format, 'type' => backup::TYPE_1COURSE); // todo type to be returned by a converter
return $renderer->backup_details_nonstandard($nextstageurl, $details);
} else {
// standard MBZ backup, let us get information from it and display
$this->details = backup_general_helper::get_backup_information($this->filepath);
return $renderer->backup_details($this->details, $nextstageurl);
if ($format !== 'moodle2') {
return $renderer->invalid_format($format);
}
}
$this->details = backup_general_helper::get_backup_information($this->filepath);
return $renderer->backup_details($this->details, new moodle_url('/backup/restore.php', array('contextid'=>$this->contextid, 'filepath'=>$this->filepath, 'stage'=>restore_ui::STAGE_DESTINATION)));
}
public function get_stage_name() {
return get_string('restorestage'.restore_ui::STAGE_CONFIRM, 'backup');
}
@@ -219,6 +198,7 @@ class restore_ui_stage_confirm extends restore_ui_independent_stage {
class restore_ui_stage_destination extends restore_ui_independent_stage {
protected $contextid;
protected $filepath = null;
protected $details;
protected $courseid = null;
protected $target = backup::TARGET_NEW_COURSE;
protected $coursesearch = null;
@@ -255,48 +235,29 @@ class restore_ui_stage_destination extends restore_ui_independent_stage {
}
return false;
}
/**
* Renders the destination stage screen
*
* @param core_backup_renderer $renderer renderer instance to use
* @return string HTML code
* @global moodle_database $DB
* @param core_backup_renderer $renderer
* @return string
*/
public function display($renderer) {
global $DB, $USER, $PAGE;
$format = backup_general_helper::detect_backup_format($this->filepath);
if ($format === backup::FORMAT_MOODLE) {
// standard Moodle 2 format, let use get the type of the backup
$details = backup_general_helper::get_backup_information($this->filepath);
if ($details->type === backup::TYPE_1COURSE) {
$wholecourse = true;
} else {
$wholecourse = false;
}
} else {
// non-standard format to be converted. We assume it contains the
// whole course for now. However, in the future there might be a callback
// to the installed converters
$wholecourse = true;
if ($format !== 'moodle2') {
return $renderer->invalid_format($format);
}
$nextstageurl = new moodle_url('/backup/restore.php', array(
'contextid' => $this->contextid,
'filepath' => $this->filepath,
'stage' => restore_ui::STAGE_SETTINGS));
$this->details = backup_general_helper::get_backup_information($this->filepath);
$url = new moodle_url('/backup/restore.php', array('contextid'=>$this->contextid, 'filepath'=>$this->filepath, 'stage'=>restore_ui::STAGE_SETTINGS));
$context = get_context_instance_by_id($this->contextid);
$currentcourse = ($context->contextlevel == CONTEXT_COURSE && has_capability('moodle/restore:restorecourse', $context))?$context->instanceid:false;
if ($context->contextlevel == CONTEXT_COURSE and has_capability('moodle/restore:restorecourse', $context)) {
$currentcourse = $context->instanceid;
} else {
$currentcourse = false;
}
return $renderer->course_selector($nextstageurl, $wholecourse, $this->categorysearch, $this->coursesearch, $currentcourse);
$html = $renderer->course_selector($url, $this->details, $this->categorysearch, $this->coursesearch, $currentcourse);
return $html;
}
public function get_stage_name() {
return get_string('restorestage'.restore_ui::STAGE_DESTINATION, 'backup');
}
@@ -603,6 +564,7 @@ class restore_ui_stage_review extends restore_ui_stage {
class restore_ui_stage_process extends restore_ui_stage {
const SUBSTAGE_NONE = 0;
const SUBSTAGE_CONVERT = 1;
const SUBSTAGE_PRECHECKS = 2;
protected $substage = 0;
@@ -630,16 +592,20 @@ class restore_ui_stage_process extends restore_ui_stage {
// First decide whether a substage is needed
$rc = $this->ui->get_controller();
if ($rc->get_status() == backup::STATUS_SETTING_UI) {
$rc->finish_ui();
}
if ($rc->get_status() == backup::STATUS_NEED_PRECHECK) {
if (!$rc->precheck_executed()) {
$rc->execute_precheck(true);
if ($rc->get_status() == backup::STATUS_REQUIRE_CONV) {
$this->substage = self::SUBSTAGE_CONVERT;
} else {
if ($rc->get_status() == backup::STATUS_SETTING_UI) {
$rc->finish_ui();
}
$results = $rc->get_precheck_results();
if (!empty($results)) {
$this->substage = self::SUBSTAGE_PRECHECKS;
if ($rc->get_status() == backup::STATUS_NEED_PRECHECK) {
if (!$rc->precheck_executed()) {
$rc->execute_precheck(true);
}
$results = $rc->get_precheck_results();
if (!empty($results)) {
$this->substage = self::SUBSTAGE_PRECHECKS;
}
}
}
@@ -669,52 +635,37 @@ class restore_ui_stage_process extends restore_ui_stage {
protected function initialise_stage_form() {
throw new backup_ui_exception('backup_ui_must_execute_first');
}
/**
* Renders the process stage screen
*
* @param core_backup_renderer $renderer renderer instance to use
* @return string HTML code
* should NEVER be called... throws an exception
*/
public function display($renderer) {
global $PAGE;
$html = '';
$haserrors = false;
$url = new moodle_url($PAGE->url, array(
'restore' => $this->get_uniqueid(),
'stage' => restore_ui::STAGE_PROCESS,
'substage' => $this->substage,
'sesskey' => sesskey()));
$html .= html_writer::start_tag('form', array(
'action' => $url->out_omit_querystring(),
'class' => 'backup-restore',
'method' => 'post'));
foreach ($url->params() as $name => $value) {
$html .= html_writer::empty_tag('input', array(
'type' => 'hidden',
'name' => $name,
'value' => $value));
$url = new moodle_url($PAGE->url, array('restore'=>$this->get_uniqueid(), 'stage'=>restore_ui::STAGE_PROCESS, 'substage'=>$this->substage, 'sesskey'=>sesskey()));
echo html_writer::start_tag('form', array('action'=>$url->out_omit_querystring(), 'class'=>'backup-restore', 'method'=>'post'));
foreach ($url->params() as $name=>$value) {
echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>$name, 'value'=>$value));
}
switch ($this->substage) {
case self::SUBSTAGE_CONVERT :
echo '<h2>Need to show the conversion screens here</h2>';
break;
case self::SUBSTAGE_PRECHECKS :
$results = $this->ui->get_controller()->get_precheck_results();
$info = $this->ui->get_controller()->get_info();
$haserrors = (!empty($results['errors']));
$html .= $renderer->precheck_notices($results);
echo $renderer->precheck_notices($results);
if (!empty($info->role_mappings->mappings)) {
$context = get_context_instance(CONTEXT_COURSE, $this->ui->get_controller()->get_courseid());
$assignableroles = get_assignable_roles($context, ROLENAME_ALIAS, false);
$html .= $renderer->role_mappings($info->role_mappings->mappings, $assignableroles);
echo $renderer->role_mappings($info->role_mappings->mappings, $assignableroles);
}
break;
default:
throw new restore_ui_exception('backup_ui_must_execute_first');
}
$html .= $renderer->substage_buttons($haserrors);
$html .= html_writer::end_tag('form');
return $html;
echo $renderer->substage_buttons($haserrors);
echo html_writer::end_tag('form');
}
public function has_sub_stages() {
@@ -744,24 +695,20 @@ class restore_ui_stage_complete extends restore_ui_stage_process {
parent::__construct($ui, $params);
$this->stage = restore_ui::STAGE_COMPLETE;
}
/**
* Displays the completed backup stage.
*
* Currently this just envolves redirecting to the file browser with an
* appropriate message.
*
* @global core_renderer $OUTPUT
* @param core_backup_renderer $renderer
*/
public function display(core_backup_renderer $renderer) {
$html = '';
$html .= $renderer->box_start();
$html .= $renderer->notification(get_string('restoreexecutionsuccess', 'backup'), 'notifysuccess');
$html .= $renderer->continue_button(new moodle_url('/course/view.php', array(
'id' => $this->get_ui()->get_controller()->get_courseid())), 'get');
$html .= $renderer->box_end();
return $html;
global $OUTPUT;
echo $OUTPUT->box_start();
echo $OUTPUT->notification(get_string('restoreexecutionsuccess', 'backup'), 'notifysuccess');
echo $renderer->continue_button(new moodle_url('/course/view.php', array('id'=>$this->get_ui()->get_controller()->get_courseid())), 'get');
echo $OUTPUT->box_end();
}
}
}
@@ -71,23 +71,9 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
}
/**
* The parser fires this each time one path is going to be parsed
*
* @param string $path xml path which parsing has started
*/
public function before_path($path) {
if (!$this->grouped_parent_exists($path)) {
parent::before_path($path);
}
}
/**
* The parser fires this each time one path has been parsed
*
* @param string $path xml path which parsing has ended
* Dispatch grouped chunks safely once their end tag happens
*/
public function after_path($path) {
// Have finished one grouped path, dispatch it
if ($this->path_is_grouped($path)) {
// Any accumulated information must be in
// currentdata, properly built
@@ -96,11 +82,6 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
// TODO: If running under DEBUG_DEVELOPER notice about >1MB grouped chunks
$this->dispatch_chunk($data);
}
// Normal notification of path end
// Only if path is selected and not child of grouped
if (!$this->grouped_parent_exists($path)) {
parent::after_path($path);
}
}
// Protected API starts here
@@ -130,6 +111,23 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
return in_array($path, $this->groupedpaths);
}
/**
* Function that will look for any
* parent for the given path, returning it if found,
* false if not
*/
protected function processed_parent_exists($path) {
$parentpath = progressive_parser::dirname($path);
while ($parentpath != '/') {
if ($this->path_is_selected($parentpath)) {
return $parentpath;
}
$parentpath = progressive_parser::dirname($parentpath);
}
return false;
}
/**
* Function that will look for any grouped
* parent for the given path, returning it if found,
@@ -41,14 +41,12 @@ abstract class simplified_parser_processor extends progressive_parser_processor
protected $paths; // array of paths we are interested on
protected $parentpaths; // array of parent paths of the $paths
protected $parentsinfo; // array of parent attributes to be added as child tags
protected $startendinfo;// array (stack) of startend information
public function __construct(array $paths = array()) {
public function __construct(array $paths) {
parent::__construct();
$this->paths = array();
$this->parentpaths = array();
$this->parentsinfo = array();
$this->startendinfo = array();
// Add paths and parentpaths. We are looking for attributes there
foreach ($paths as $key => $path) {
$this->add_path($path);
@@ -65,16 +63,6 @@ abstract class simplified_parser_processor extends progressive_parser_processor
*/
abstract protected function dispatch_chunk($data);
/**
* Get one selected path and notify about start
*/
abstract protected function notify_path_start($path);
/**
* Get one selected path and notify about end
*/
abstract protected function notify_path_end($path);
/**
* Get one chunk of parsed data and make it simpler
* adding attributes as tags and delegating to
@@ -97,10 +85,6 @@ abstract class simplified_parser_processor extends progressive_parser_processor
// If the path is a registered one, let's process it
if ($this->path_is_selected($path)) {
// Send all the pending notify_path_start/end() notifications
$this->process_pending_startend_notifications($path, 'start');
// First of all, look for attributes available at parentsinfo
// in order to get them available as normal tags
if (isset($this->parentsinfo[$parentpath][$tag]['attrs'])) {
@@ -152,86 +136,11 @@ abstract class simplified_parser_processor extends progressive_parser_processor
} else {
$this->chunks--; // Chunk skipped
}
return true;
}
/**
* The parser fires this each time one path is going to be parsed
*
* @param string $path xml path which parsing has started
*/
public function before_path($path) {
if ($this->path_is_selected($path)) {
$this->startendinfo[] = array('path' => $path, 'action' => 'start');
}
}
/**
* The parser fires this each time one path has been parsed
*
* @param string $path xml path which parsing has ended
*/
public function after_path($path) {
$toprocess = false;
// If the path being closed matches (same or parent) the first path in the stack
// we process pending startend notifications until one matching end is found
if ($element = reset($this->startendinfo)) {
$elepath = $element['path'];
$eleaction = $element['action'];
if (strpos($elepath, $path) === 0) {
$toprocess = true;
}
// Also, if the stack of startend notifications is empty, we can process current end
// path safely
} else {
$toprocess = true;
}
if ($this->path_is_selected($path)) {
$this->startendinfo[] = array('path' => $path, 'action' => 'end');
}
// Send all the pending startend notifications if decided to do so
if ($toprocess) {
$this->process_pending_startend_notifications($path, 'end');
}
}
// Protected API starts here
/**
* Adjust start/end til finding one match start/end path (included)
*
* This will trigger all the pending {@see notify_path_start} and
* {@see notify_path_end} calls for one given path and action
*
* @param string path the path to look for as limit
* @param string action the action to look for as limit
*/
protected function process_pending_startend_notifications($path, $action) {
// Iterate until one matching path and action is found (or the array is empty)
$elecount = count($this->startendinfo);
$elematch = false;
while ($elecount > 0 && !$elematch) {
$element = array_shift($this->startendinfo);
$elecount--;
$elepath = $element['path'];
$eleaction = $element['action'];
if ($elepath == $path && $eleaction == $action) {
$elematch = true;
}
if ($eleaction == 'start') {
$this->notify_path_start($elepath);
} else {
$this->notify_path_end($elepath);
}
}
}
protected function postprocess_chunk($data) {
$this->dispatch_chunk($data);
}
@@ -243,18 +152,4 @@ abstract class simplified_parser_processor extends progressive_parser_processor
protected function path_is_selected_parent($path) {
return in_array($path, $this->parentpaths);
}
/**
* Returns the first selected parent if available or false
*/
protected function selected_parent_exists($path) {
$parentpath = progressive_parser::dirname($path);
while ($parentpath != '/') {
if ($this->path_is_selected($parentpath)) {
return $parentpath;
}
$parentpath = progressive_parser::dirname($parentpath);
}
return false;
}
}
@@ -1,24 +0,0 @@
<MOODLE_BACKUP>
<COURSE ID="100">
<SECTIONS>
<SECTION>
<ID>200</ID>
<MODS>
<MOD>
<ID>300</ID>
<ROLES_OVERRIDES>
</ROLES_OVERRIDES>
</MOD>
<MOD />
<MOD />
<MOD ID="400" />
<MOD>
<ID>500</ID>
</MOD>
<MOD />
<MOD />
</MODS>
</SECTION>
</SECTIONS>
</COURSE>
</MOODLE_BACKUP>
@@ -307,103 +307,6 @@ class progressive_parser_test extends UnitTestCase {
$this->assertEqual(count($tags), 2);
$this->assertEqual($tags['name'], 4);
$this->assertEqual($tags['value'], 5);
// Now check start notifications
$snotifs = $pr->get_start_notifications();
// Check we have received the correct number of notifications
$this->assertEqual(count($snotifs), 12);
// Check first, sixth and last notifications
$this->assertEqual($snotifs[0], '/activity');
$this->assertEqual($snotifs[5], '/activity/glossary/entries/entry');
$this->assertEqual($snotifs[11], '/activity/glossary/othertest');
// Now check end notifications
$enotifs = $pr->get_end_notifications();
// Check we have received the correct number of notifications
$this->assertEqual(count($snotifs), 12);
// Check first, sixth and last notifications
$this->assertEqual($enotifs[0], '/activity/glossary/entries/entry/aliases/alias');
$this->assertEqual($enotifs[5], '/activity/glossary/entries/entry/ratings/rating');
$this->assertEqual($enotifs[11], '/activity');
// Check start and end notifications are balanced
sort($snotifs);
sort($enotifs);
$this->assertEqual($snotifs, $enotifs);
// Now verify that the start/process/end order is correct
$allnotifs = $pr->get_all_notifications();
$this->assertEqual(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks)); // The count
// Check integrity of the notifications
$errcount = $this->helper_check_notifications_order_integrity($allnotifs);
$this->assertEqual($errcount, 0); // No errors found, plz
}
/**
* test how the simplified processor and the order of start/process/end events happens
* with one real fragment of one backup 1.9 file, where some problems
* were found by David, hence we honor him in the name of the test ;-)
*/
function test_simplified_david_backup19_file_fragment() {
global $CFG;
// Instantiate progressive_parser
$pp = new progressive_parser();
// Instantiate grouped_parser_processor
$pr = new mock_simplified_parser_processor();
// Add interesting paths
$pr->add_path('/MOODLE_BACKUP/COURSE');
$pr->add_path('/MOODLE_BACKUP/COURSE/SECTIONS/SECTION');
$pr->add_path('/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
$pr->add_path('/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD/ROLES_OVERRIDES');
$this->assertTrue($pr instanceof progressive_parser_processor);
// Assign processor to parser
$pp->set_processor($pr);
// Set file from fixtures
$pp->set_file($CFG->dirroot . '/backup/util/xml/parser/simpletest/fixtures/test5.xml');
// Process the file
$pp->process();
// Get all the simplified chunks and perform various validations
$chunks = $pr->get_chunks();
$this->assertEqual(count($chunks), 3); // Only 3, because 7 (COURSE, ROLES_OVERRIDES and 5 MOD) are empty, aka no chunk
// Now check start notifications
$snotifs = $pr->get_start_notifications();
// Check we have received the correct number of notifications
$this->assertEqual(count($snotifs), 10); // Start tags are dispatched for empties (ROLES_OVERRIDES)
// Check first and last notifications
$this->assertEqual($snotifs[0], '/MOODLE_BACKUP/COURSE');
$this->assertEqual($snotifs[1], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION');
$this->assertEqual($snotifs[2], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
$this->assertEqual($snotifs[3], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD/ROLES_OVERRIDES');
$this->assertEqual($snotifs[7], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
$this->assertEqual($snotifs[8], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
$this->assertEqual($snotifs[9], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
// Now check end notifications
$enotifs = $pr->get_end_notifications();
// Check we have received the correct number of notifications
$this->assertEqual(count($snotifs), 10); // End tags are dispatched for empties (ROLES_OVERRIDES)
// Check first, and last notifications
$this->assertEqual($enotifs[0], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD/ROLES_OVERRIDES');
$this->assertEqual($enotifs[1], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
$this->assertEqual($enotifs[2], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
$this->assertEqual($enotifs[3], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
$this->assertEqual($enotifs[7], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
$this->assertEqual($enotifs[8], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION');
$this->assertEqual($enotifs[9], '/MOODLE_BACKUP/COURSE');
// Check start and end notifications are balanced
sort($snotifs);
sort($enotifs);
$this->assertEqual($snotifs, $enotifs);
// Now verify that the start/process/end order is correct
$allnotifs = $pr->get_all_notifications();
$this->assertEqual(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks)); // The count
// Check integrity of the notifications
$errcount = $this->helper_check_notifications_order_integrity($allnotifs);
$this->assertEqual($errcount, 0); // No errors found, plz
}
/*
@@ -551,148 +454,6 @@ class progressive_parser_test extends UnitTestCase {
$this->assertEqual(count($othertest[0]), 2);
$this->assertEqual($othertest[0]['name'], 4);
$this->assertEqual($othertest[0]['value'], 5);
// Now check start notifications
$snotifs = $pr->get_start_notifications();
// Check we have received the correct number of notifications
$this->assertEqual(count($snotifs), 2);
// Check first and last notifications
$this->assertEqual($snotifs[0], '/activity');
$this->assertEqual($snotifs[1], '/activity/glossary');
// Now check end notifications
$enotifs = $pr->get_end_notifications();
// Check we have received the correct number of notifications
$this->assertEqual(count($snotifs), 2);
// Check first, and last notifications
$this->assertEqual($enotifs[0], '/activity/glossary');
$this->assertEqual($enotifs[1], '/activity');
// Check start and end notifications are balanced
sort($snotifs);
sort($enotifs);
$this->assertEqual($snotifs, $enotifs);
// Now verify that the start/process/end order is correct
$allnotifs = $pr->get_all_notifications();
$this->assertEqual(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks)); // The count
// Check integrity of the notifications
$errcount = $this->helper_check_notifications_order_integrity($allnotifs);
$this->assertEqual($errcount, 0); // No errors found, plz
}
/**
* test how the grouped processor and the order of start/process/end events happens
* with one real fragment of one backup 1.9 file, where some problems
* were found by David, hence we honor him in the name of the test ;-)
*/
function test_grouped_david_backup19_file_fragment() {
global $CFG;
// Instantiate progressive_parser
$pp = new progressive_parser();
// Instantiate grouped_parser_processor
$pr = new mock_grouped_parser_processor();
// Add interesting paths
$pr->add_path('/MOODLE_BACKUP/COURSE');
$pr->add_path('/MOODLE_BACKUP/COURSE/SECTIONS/SECTION', true);
$pr->add_path('/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD');
$pr->add_path('/MOODLE_BACKUP/COURSE/SECTIONS/SECTION/MODS/MOD/ROLES_OVERRIDES');
$this->assertTrue($pr instanceof progressive_parser_processor);
// Assign processor to parser
$pp->set_processor($pr);
// Set file from fixtures
$pp->set_file($CFG->dirroot . '/backup/util/xml/parser/simpletest/fixtures/test5.xml');
// Process the file
$pp->process();
// Get all the simplified chunks and perform various validations
$chunks = $pr->get_chunks();
$this->assertEqual(count($chunks), 1); // Only 1, the SECTION one
// Now check start notifications
$snotifs = $pr->get_start_notifications();
// Check we have received the correct number of notifications
$this->assertEqual(count($snotifs), 2);
// Check first and last notifications
$this->assertEqual($snotifs[0], '/MOODLE_BACKUP/COURSE');
$this->assertEqual($snotifs[1], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION');
// Now check end notifications
$enotifs = $pr->get_end_notifications();
// Check we have received the correct number of notifications
$this->assertEqual(count($snotifs), 2); // End tags are dispatched for empties (ROLES_OVERRIDES)
// Check first, and last notifications
$this->assertEqual($enotifs[0], '/MOODLE_BACKUP/COURSE/SECTIONS/SECTION');
$this->assertEqual($enotifs[1], '/MOODLE_BACKUP/COURSE');
// Check start and end notifications are balanced
sort($snotifs);
sort($enotifs);
$this->assertEqual($snotifs, $enotifs);
// Now verify that the start/process/end order is correct
$allnotifs = $pr->get_all_notifications();
$this->assertEqual(count($allnotifs), count($snotifs) + count($enotifs) + count($chunks)); // The count
// Check integrity of the notifications
$errcount = $this->helper_check_notifications_order_integrity($allnotifs);
$this->assertEqual($errcount, 0); // No errors found, plz
}
/**
* Helper function that given one array of ordered start/process/end notifications will
* check it of integrity like:
* - process only happens if start is the previous notification
* - end only happens if dispatch is the previous notification
* - start only happen with level > than last one and if there is no already started like that
*
* @param array $notifications ordered array of notifications with format [start|process|end]:path
* @return int number of integrity problems found (errors)
*/
function helper_check_notifications_order_integrity($notifications) {
$numerrors = 0;
$notifpile = array('pilebase' => 'start');
$lastnotif = 'start:pilebase';
foreach ($notifications as $notif) {
$lastpiletype = end($notifpile);
$lastpilepath = key($notifpile);
$lastpilelevel = strlen(preg_replace('/[^\/]/', '', $lastpilepath));
$lastnotiftype = preg_replace('/:.*/', '', $lastnotif);
$lastnotifpath = preg_replace('/.*:/', '', $lastnotif);
$lastnotiflevel = strlen(preg_replace('/[^\/]/', '', $lastnotifpath));
$notiftype = preg_replace('/:.*/', '', $notif);
$notifpath = preg_replace('/.*:/', '', $notif);
$notiflevel = strlen(preg_replace('/[^\/]/', '', $notifpath));
switch ($notiftype) {
case 'process':
if ($lastnotifpath != $notifpath or $lastnotiftype != 'start') {
$numerrors++; // Only start for same path from last notification is allowed before process
}
$notifpile[$notifpath] = 'process'; // Update the status in the pile
break;
case 'end':
if ($lastpilepath != $notifpath or ($lastpiletype != 'process' and $lastpiletype != 'start')) {
$numerrors++; // Only process and start for same path from last pile is allowed before end
}
unset($notifpile[$notifpath]); // Delete from the pile
break;
case 'start':
if (array_key_exists($notifpath, $notifpile) or $notiflevel <= $lastpilelevel) {
$numerrors++; // Only non existing in pile and with level > last pile is allowed on start
}
$notifpile[$notifpath] = 'start'; // Add to the pile
break;
default:
$numerrors++; // Incorrect type of notification => error
}
// Update lastnotif
$lastnotif = $notif;
}
return $numerrors;
}
}
@@ -765,40 +526,14 @@ class mock_parser_processor extends progressive_parser_processor {
class mock_simplified_parser_processor extends simplified_parser_processor {
private $chunksarr = array(); // To accumulate the found chunks
private $startarr = array(); // To accumulate all the notified path starts
private $endarr = array(); // To accumulate all the notified path ends
private $allnotif = array(); // To accumulate all the notified and dispatched events in an ordered way
public function dispatch_chunk($data) {
$this->chunksarr[] = $data;
$this->allnotif[] = 'process:' . $data['path'];
}
public function notify_path_start($path) {
$this->startarr[] = $path;
$this->allnotif[] = 'start:' . $path;
}
public function notify_path_end($path) {
$this->endarr[] = $path;
$this->allnotif[] = 'end:' . $path;
}
public function get_chunks() {
return $this->chunksarr;
}
public function get_start_notifications() {
return $this->startarr;
}
public function get_end_notifications() {
return $this->endarr;
}
public function get_all_notifications() {
return $this->allnotif;
}
}
/*
@@ -807,38 +542,12 @@ class mock_simplified_parser_processor extends simplified_parser_processor {
class mock_grouped_parser_processor extends grouped_parser_processor {
private $chunksarr = array(); // To accumulate the found chunks
private $startarr = array(); // To accumulate all the notified path starts
private $endarr = array(); // To accumulate all the notified path ends
private $allnotif = array(); // To accumulate all the notified and dispatched events in an ordered way
public function dispatch_chunk($data) {
$this->chunksarr[] = $data;
$this->allnotif[] = 'process:' . $data['path'];
}
public function notify_path_start($path) {
$this->startarr[] = $path;
$this->allnotif[] = 'start:' . $path;
}
public function notify_path_end($path) {
$this->endarr[] = $path;
$this->allnotif[] = 'end:' . $path;
}
public function get_chunks() {
return $this->chunksarr;
}
public function get_start_notifications() {
return $this->startarr;
}
public function get_end_notifications() {
return $this->endarr;
}
public function get_all_notifications() {
return $this->allnotif;
}
}
+34 -10
View File
@@ -19,6 +19,8 @@ class block_calendar_month extends block_base {
if ($this->content !== NULL) {
return $this->content;
}
// Reset the session variables
calendar_session_vars($this->page->course);
$this->content = new stdClass;
$this->content->text = '';
@@ -27,30 +29,52 @@ class block_calendar_month extends block_base {
// [pj] To me it looks like this if would never be needed, but Penny added it
// when committing the /my/ stuff. Reminder to discuss and learn what it's about.
// It definitely needs SOME comment here!
$courseid = $this->page->course->id;
$issite = ($courseid == SITEID);
$courseshown = $this->page->course->id;
if ($issite) {
if ($courseshown == SITEID) {
// Being displayed at site level. This will cause the filter to fall back to auto-detecting
// the list of courses it will be grabbing events from.
$filtercourse = calendar_get_default_courses();
$filtercourse = NULL;
$groupeventsfrom = NULL;
$SESSION->cal_courses_shown = calendar_get_default_courses(true);
calendar_set_referring_course(0);
} else {
// Forcibly filter events to include only those from the particular course we are in.
$filtercourse = array($courseid => $this->page->course);
$filtercourse = array($courseshown => $this->page->course);
$groupeventsfrom = array($courseshown => 1);
}
list($courses, $group, $user) = calendar_set_filters($filtercourse);
if ($issite) {
// We 'll need this later
calendar_set_referring_course($courseshown);
// MDL-9059, set to show this course when admins go into a course, then unset it.
if ($this->page->course->id != SITEID && !isset($SESSION->cal_courses_shown[$this->page->course->id]) && has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_SYSTEM))) {
$courseset = true;
$SESSION->cal_courses_shown[$this->page->course->id] = $this->page->course;
}
// Be VERY careful with the format for default courses arguments!
// Correct formatting is [courseid] => 1 to be concise with moodlelib.php functions.
calendar_set_filters($courses, $group, $user, $filtercourse, $groupeventsfrom, false);
if ($courseshown == SITEID) {
// For the front page
$this->content->text .= calendar_top_controls('frontpage', array('id' => $courseid, 'm' => $cal_m, 'y' => $cal_y));
$this->content->text .= calendar_top_controls('frontpage', array('id' => $courseshown, 'm' => $cal_m, 'y' => $cal_y));
$this->content->text .= calendar_get_mini($courses, $group, $user, $cal_m, $cal_y);
// No filters for now
} else {
// For any other course
$this->content->text .= calendar_top_controls('course', array('id' => $courseid, 'm' => $cal_m, 'y' => $cal_y));
$this->content->text .= calendar_top_controls('course', array('id' => $courseshown, 'm' => $cal_m, 'y' => $cal_y));
$this->content->text .= calendar_get_mini($courses, $group, $user, $cal_m, $cal_y);
$this->content->text .= '<h3 class="eventskey">'.get_string('eventskey', 'calendar').'</h3>';
$this->content->text .= '<div class="filters">'.calendar_filter_controls($this->page->url).'</div>';
$this->content->text .= '<div class="filters">'.calendar_filter_controls('course', '', $this->page->course).'</div>';
}
// MDL-9059, unset this so that it doesn't stay in session
if (!empty($courseset)) {
unset($SESSION->cal_courses_shown[$this->page->course->id]);
}
return $this->content;
@@ -15,12 +15,14 @@ class block_calendar_upcoming extends block_base {
if ($this->content !== NULL) {
return $this->content;
}
// Reset the session variables
calendar_session_vars($this->page->course);
$this->content = new stdClass;
$this->content->text = '';
$filtercourse = array();
if (empty($this->instance)) { // Overrides: use no course at all
$courseshown = false;
$filtercourse = array();
$this->content->footer = '';
} else {
@@ -29,7 +31,8 @@ class block_calendar_upcoming extends block_base {
'/calendar/view.php?view=upcoming&amp;course='.$courseshown.'">'.
get_string('gotocalendar', 'calendar').'</a>...</div>';
$context = get_context_instance(CONTEXT_COURSE, $courseshown);
if (has_any_capability(array('moodle/calendar:manageentries', 'moodle/calendar:manageownentries'), $context)) {
if (has_capability('moodle/calendar:manageentries', $context) ||
has_capability('moodle/calendar:manageownentries', $context)) {
$this->content->footer .= '<div class="newevent"><a href="'.$CFG->wwwroot.
'/calendar/event.php?action=new&amp;course='.$courseshown.'">'.
get_string('newevent', 'calendar').'</a>...</div>';
@@ -37,34 +40,36 @@ class block_calendar_upcoming extends block_base {
if ($courseshown == SITEID) {
// Being displayed at site level. This will cause the filter to fall back to auto-detecting
// the list of courses it will be grabbing events from.
$filtercourse = calendar_get_default_courses();
$filtercourse = NULL;
$groupeventsfrom = NULL;
$SESSION->cal_courses_shown = calendar_get_default_courses(true);
calendar_set_referring_course(0);
} else {
// Forcibly filter events to include only those from the particular course we are in.
$filtercourse = array($courseshown => $this->page->course);
$filtercourse = array($courseshown => $this->page->course);
$groupeventsfrom = array($courseshown => 1);
}
}
list($courses, $group, $user) = calendar_set_filters($filtercourse);
// We 'll need this later
calendar_set_referring_course($courseshown);
$defaultlookahead = CALENDAR_DEFAULT_UPCOMING_LOOKAHEAD;
if (isset($CFG->calendar_lookahead)) {
$defaultlookahead = intval($CFG->calendar_lookahead);
}
$lookahead = get_user_preferences('calendar_lookahead', $defaultlookahead);
// Be VERY careful with the format for default courses arguments!
// Correct formatting is [courseid] => 1 to be concise with moodlelib.php functions.
$defaultmaxevents = CALENDAR_DEFAULT_UPCOMING_MAXEVENTS;
if (isset($CFG->calendar_maxevents)) {
$defaultmaxevents = intval($CFG->calendar_maxevents);
}
$maxevents = get_user_preferences('calendar_maxevents', $defaultmaxevents);
$events = calendar_get_upcoming($courses, $group, $user, $lookahead, $maxevents);
calendar_set_filters($courses, $group, $user, $filtercourse, $groupeventsfrom, false);
$events = calendar_get_upcoming($courses, $group, $user,
get_user_preferences('calendar_lookahead', CALENDAR_UPCOMING_DAYS),
get_user_preferences('calendar_maxevents', CALENDAR_UPCOMING_MAXEVENTS));
if (!empty($this->instance)) {
$this->content->text = calendar_get_block_upcoming($events, 'view.php?view=day&amp;course='.$courseshown.'&amp;');
$this->content->text = calendar_get_block_upcoming($events,
'view.php?view=day&amp;course='.$courseshown.'&amp;');
}
if (empty($this->content->text)) {
$this->content->text = '<div class="post">'. get_string('noupcomingevents', 'calendar').'</div>';
$this->content->text = '<div class="post">'.
get_string('noupcomingevents', 'calendar').'</div>';
}
return $this->content;
-2
View File
@@ -73,8 +73,6 @@ function xmldb_block_community_upgrade($oldversion) {
upgrade_block_savepoint(true, 2010042701, 'community');
}
// Moodle v2.1.0 release upgrade line
// Put any upgrade step following this
return true;
}
+6 -4
View File
@@ -155,10 +155,12 @@ class community_hub_search_form extends moodleform {
array('class' => 'hubscreenshot'));
$hubdescriptiontext = html_writer::tag('span', format_text($hub['description'], FORMAT_PLAIN),
array('class' => 'hubdescription'));
$additionaldesc = get_string('sites', 'block_community') . ': ' . $hub['sites'] . ' - ' .
get_string('courses', 'block_community') . ': ' . $hub['courses'];
$hubdescriptiontext .= html_writer::tag('span', $additionaldesc,
array('class' => 'hubadditionaldesc'));
if (isset($hub['enrollablecourses'])) { //check needed to avoid warnings for Moodle version < 2011081700
$additionaldesc = get_string('enrollablecourses', 'block_community') . ': ' . $hub['enrollablecourses'] . ' - ' .
get_string('downloadablecourses', 'block_community') . ': ' . $hub['downloadablecourses'];
$hubdescriptiontext .= html_writer::tag('span', $additionaldesc,
array('class' => 'hubadditionaldesc'));
}
if ($hub['trusted']) {
$hubtrusted = get_string('hubtrusted', 'block_community');
$hubdescriptiontext .= html_writer::tag('span',
+4 -2
View File
@@ -49,6 +49,7 @@ $string['donotrestore'] = 'No';
$string['dorestore'] = 'Yes';
$string['download'] = 'Download';
$string['downloadable'] = 'courses I can download';
$string['downloadablecourses'] = 'Downloadable courses';
$string['downloadconfirmed'] = 'The backup has been saved in your private files {$a}';
$string['downloaded'] = '...finished.';
$string['downloadingcourse'] = 'Downloading course';
@@ -61,8 +62,9 @@ $string['enroldownload_help'] = 'Some courses listed in the selected hub are bei
Others are course templates provided for you to download and use on your own Moodle site.';
$string['enrollable'] = 'courses I can enrol in';
$string['errorcourselisting'] = 'An error occured when retrieving the course listing from the selected hub, please try again later. ({$a})';
$string['errorhublisting'] = 'An error occured when retrieving the hub listing from Moodle.org, please try again later. ({$a})';
$string['enrollablecourses'] = 'Enrollable courses';
$string['errorcourselisting'] = 'An error occurred when retrieving the course listing from the selected hub, please try again later. ({$a})';
$string['errorhublisting'] = 'An error occurred when retrieving the hub listing from Moodle.org, please try again later. ({$a})';
$string['fileinfo'] = 'Language: {$a->lang} - License: {$a->license} - Time updated: {$a->timeupdated}';
$string['hub'] = 'hub';
$string['hubnottrusted'] = 'Not trusted';
+4 -88
View File
@@ -66,75 +66,7 @@ M.core_dock.init = function(Y) {
// Give the dock item class the event properties/methods
Y.augment(this.item, Y.EventTarget);
Y.augment(this, Y.EventTarget, true);
/**
* A 'dock:actionkey' Event.
* The event consists of the left arrow, right arrow, enter and space keys.
* More keys can be mapped to action meanings.
* actions: collapse , expand, toggle, enter.
*
* This event is subscribed to by dockitems.
* The on() method to subscribe allows specifying the desired trigger actions as JSON.
*
* This event can also be delegated if needed.
* Todo: This could be centralised, a similar Event is defined in blocks/navigation/yui/navigation/navigation.js
*/
Y.Event.define("dock:actionkey", {
// Webkit and IE repeat keydown when you hold down arrow keys.
// Opera links keypress to page scroll; others keydown.
// Firefox prevents page scroll via preventDefault() on either
// keydown or keypress.
_event: (Y.UA.webkit || Y.UA.ie) ? 'keydown' : 'keypress',
_keys: {
//arrows
'37': 'collapse',
'39': 'expand',
//(@todo: lrt/rtl/M.core_dock.cfg.orientation decision to assign arrow to meanings)
'32': 'toggle',
'13': 'enter'
},
_keyHandler: function (e, notifier, args) {
if (!args.actions) {
var actObj = {collapse:true, expand:true, toggle:true, enter:true};
} else {
var actObj = args.actions;
}
if (this._keys[e.keyCode] && actObj[this._keys[e.keyCode]]) {
e.action = this._keys[e.keyCode];
notifier.fire(e);
}
},
on: function (node, sub, notifier) {
// subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions).
if (sub.args == null) {
//no actions given
sub._detacher = node.on(this._event, this._keyHandler,this, notifier, {actions:false});
} else {
sub._detacher = node.on(this._event, this._keyHandler,this, notifier, sub.args[0]);
}
},
detach: function (node, sub, notifier) {
//detach our _detacher handle of the subscription made in on()
sub._detacher.detach();
},
delegate: function (node, sub, notifier, filter) {
// subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions).
if (sub.args == null) {
//no actions given
sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, {actions:false});
} else {
sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, sub.args[0]);
}
},
detachDelegate: function (node, sub, notifier) {
sub._delegateDetacher.detach();
}
});
// Publish the events the dock has
this.publish('dock:beforedraw', {prefix:'dock'});
this.publish('dock:beforeshow', {prefix:'dock'});
@@ -193,10 +125,9 @@ M.core_dock.init = function(Y) {
// Add a removeall button
// Must set the image src seperatly of we get an error with XML strict headers
var removeall = Y.Node.create('<img alt="'+M.str.block.undockall+'" title="'+M.str.block.undockall+'" tabindex="0"/>');
var removeall = Y.Node.create('<img alt="'+M.str.block.undockall+'" title="'+M.str.block.undockall+'" />');
removeall.setAttribute('src',this.cfg.removeallicon);
removeall.on('removeall|click', this.remove_all, this);
removeall.on('dock:actionkey', this.remove_all, this, {actions:{enter:true}});
this.nodes.buttons.appendChild(Y.Node.create('<div class="'+css.controls+'"></div>').append(removeall));
// Create a manager for the height of the tabs. Once set this can be forgotten about
@@ -659,7 +590,7 @@ M.core_dock.resetFirstItem = function() {
* @function
* @return {boolean}
*/
M.core_dock.remove_all = function(e) {
M.core_dock.remove_all = function() {
for (var i in this.items) {
this.remove(i);
}
@@ -909,10 +840,9 @@ M.core_dock.genericblock.prototype = {
}, this);
// Add a close icon
// Must set the image src seperatly of we get an error with XML strict headers
var closeicon = Y.Node.create('<span class="hidepanelicon" tabindex="0"><img alt="" style="width:11px;height:11px;cursor:pointer;" /></span>');
var closeicon = Y.Node.create('<span class="hidepanelicon"><img alt="" style="width:11px;height:11px;cursor:pointer;" /></span>');
closeicon.one('img').setAttribute('src', M.util.image_url('t/dockclose', 'moodle'));
closeicon.on('forceclose|click', this.hide, this);
closeicon.on('dock:actionkey',this.hide, this, {actions:{enter:true,toggle:true}});
this.commands.append(closeicon);
}, dockitem);
// Register an event so that when it is removed we can put it back as a block
@@ -1025,8 +955,7 @@ M.core_dock.item.prototype = {
this.nodes.docktitle = Y.Node.create('<div id="dock_item_'+this.id+'_title" class="'+css.dockedtitle+'"></div>');
this.nodes.docktitle.append(this.title);
this.nodes.dockitem = Y.Node.create('<div id="dock_item_'+this.id+'" class="'+css.dockeditem+'" tabindex="0"></div>');
this.nodes.dockitem.on('dock:actionkey', this.toggle, this);
this.nodes.dockitem = Y.Node.create('<div id="dock_item_'+this.id+'" class="'+css.dockeditem+'"></div>');
if (M.core_dock.count === 1) {
this.nodes.dockitem.addClass('firstdockitem');
}
@@ -1070,19 +999,6 @@ M.core_dock.item.prototype = {
M.core_dock.getPanel().hide();
this.fire('dockeditem:hidecomplete');
},
/**
* A toggle between calling show and hide functions based on css.activeitem
* Applies rules to key press events (dock:actionkey)
* @param {Event} e
*/
toggle : function(e) {
var css = M.core_dock.css;
if (this.nodes.docktitle.hasClass(css.activeitem) && !(e.type == 'dock:actionkey' && e.action=='expand')) {
this.hide();
} else if (!this.nodes.docktitle.hasClass(css.activeitem) && !(e.type == 'dock:actionkey' && e.action=='collapse')) {
this.show();
}
},
/**
* This function removes the node and destroys it's bits
* @param {Event} e
+23 -70
View File
@@ -32,7 +32,6 @@ if (!defined('MOODLE_INTERNAL')) {
}
require_once($CFG->libdir . '/formslib.php');
require_once($CFG->libdir . '/blocklib.php');
/**
* The base class form used by blocks/edit.php to edit block instance configuration.
@@ -90,84 +89,40 @@ class block_edit_form extends moodleform {
$parentcontext = get_context_instance_by_id($this->block->instance->parentcontextid);
$mform->addElement('hidden', 'bui_parentcontextid', $parentcontext->id);
$mform->addElement('static', 'bui_homecontext', get_string('createdat', 'block'), print_context_name($parentcontext));
$mform->addHelpButton('bui_homecontext', 'createdat', 'block');
// parse pagetype patterns
$bits = explode('-', $this->page->pagetype);
$contextoptions = array();
if ( ($parentcontext->contextlevel == CONTEXT_COURSE && $parentcontext->instanceid == SITEID) ||
($parentcontext->contextlevel == CONTEXT_SYSTEM)) { // Home page
if ($bits[0] == 'tag' || $bits[0] == 'admin') {
// tag and admin pages always use system context
// the contexts options don't make differences, so we use
// page type patterns only
$mform->addElement('hidden', 'bui_contexts', BUI_CONTEXTS_ENTIRE_SITE);
} else {
$contextoptions[BUI_CONTEXTS_FRONTPAGE_ONLY] = get_string('showonfrontpageonly', 'block');
$contextoptions[BUI_CONTEXTS_FRONTPAGE_SUBS] = get_string('showonfrontpageandsubs', 'block');
$contextoptions[BUI_CONTEXTS_ENTIRE_SITE] = get_string('showonentiresite', 'block');
$mform->addElement('select', 'bui_contexts', get_string('contexts', 'block'), $contextoptions);
$mform->addHelpButton('bui_contexts', 'contexts', 'block');
}
} else if ($parentcontext->contextlevel == CONTEXT_COURSE) {
// 0 means display on current context only, not child contexts
// but if course managers select mod-* as pagetype patterns, block system will overwrite this option
// to 1 (display on current context and child contexts)
$mform->addElement('hidden', 'bui_contexts', BUI_CONTEXTS_CURRENT);
} else if ($parentcontext->contextlevel == CONTEXT_MODULE or $parentcontext->contextlevel == CONTEXT_USER) {
// module context doesn't have child contexts, so display in current context only
$mform->addElement('hidden', 'bui_contexts', BUI_CONTEXTS_CURRENT);
($parentcontext->contextlevel == CONTEXT_SYSTEM)) { // Home page
$contextoptions[0] = get_string('showonfrontpageonly', 'block');
$contextoptions[1] = get_string('showonfrontpageandsubs', 'block');
$contextoptions[2] = get_string('showonentiresite', 'block');
} else {
$parentcontextname = print_context_name($parentcontext);
$contextoptions[BUI_CONTEXTS_CURRENT] = get_string('showoncontextonly', 'block', $parentcontextname);
$contextoptions[BUI_CONTEXTS_CURRENT_SUBS] = get_string('showoncontextandsubs', 'block', $parentcontextname);
$mform->addElement('select', 'bui_contexts', get_string('contexts', 'block'), $contextoptions);
$contextoptions[0] = get_string('showoncontextonly', 'block', $parentcontextname);
$contextoptions[1] = get_string('showoncontextandsubs', 'block', $parentcontextname);
}
$mform->addElement('select', 'bui_contexts', get_string('contexts', 'block'), $contextoptions);
$displaypagetypewarning = false;
if ($this->page->pagetype == 'site-index') { // No need for pagetype list on home page
$pagetypelist = array('*'=>get_string('page-x', 'pagetype'));
$pagetypelist = array('*');
} else {
// Generate pagetype patterns by callbacks
$pagetypelist = generate_page_type_patterns($this->page->pagetype, $parentcontext, $this->page->context);
if (!array_key_exists($this->block->instance->pagetypepattern, $pagetypelist)) {
// Pushing block's existing page type pattern
$pagetypestringname = 'page-'.str_replace('*', 'x', $this->block->instance->pagetypepattern);
if (get_string_manager()->string_exists($pagetypestringname, 'pagetype')) {
$pagetypelist[$this->block->instance->pagetypepattern] = get_string($pagetypestringname, 'pagetype');
} else {
//as a last resort we could put the page type pattern in the select box
//however this causes mod-data-view to be added if the only option available is mod-data-*
// so we are just showing a warning to users about their prev setting being reset
$displaypagetypewarning = true;
}
$pagetypelist = matching_page_type_patterns($this->page->pagetype);
}
$pagetypeoptions = array();
foreach ($pagetypelist as $pagetype) { // Find human-readable names for the pagetypes
$pagetypeoptions[$pagetype] = $pagetype;
$pagetypestringname = 'page-'.str_replace('*', 'x',$pagetype); // Better names MDL-21375
if (get_string_manager()->string_exists($pagetypestringname, 'pagetype')) {
$pagetypeoptions[$pagetype] .= ' (' . get_string($pagetypestringname, 'pagetype') . ')';
}
}
// hide page type pattern select box if there is only one choice
if (count($pagetypelist) > 1) {
if ($displaypagetypewarning) {
$mform->addElement('static', 'pagetypewarning', '', get_string('pagetypewarning','block'));
}
$mform->addElement('select', 'bui_pagetypepattern', get_string('restrictpagetypes', 'block'), $pagetypelist);
} else {
$value = array_pop(array_keys($pagetypelist));
$mform->addElement('hidden', 'bui_pagetypepattern', $value);
}
$mform->addElement('select', 'bui_pagetypepattern', get_string('restrictpagetypes', 'block'), $pagetypeoptions);
if ($this->page->subpage) {
if ($parentcontext->contextlevel == CONTEXT_USER) {
$mform->addElement('hidden', 'bui_subpagepattern', '%@NULL@%');
} else {
$subpageoptions = array(
'%@NULL@%' => get_string('anypagematchingtheabove', 'block'),
$this->page->subpage => get_string('thisspecificpage', 'block', $this->page->subpage),
);
$mform->addElement('select', 'bui_subpagepattern', get_string('subpages', 'block'), $subpageoptions);
}
$subpageoptions = array(
'%@NULL@%' => get_string('anypagematchingtheabove', 'block'),
$this->page->subpage => get_string('thisspecificpage', 'block', $this->page->subpage),
);
$mform->addElement('select', 'bui_subpagepattern', get_string('subpages', 'block'), $subpageoptions);
}
$defaultregionoptions = $regionoptions;
@@ -176,10 +131,8 @@ class block_edit_form extends moodleform {
$defaultregionoptions[$defaultregion] = $defaultregion;
}
$mform->addElement('select', 'bui_defaultregion', get_string('defaultregion', 'block'), $defaultregionoptions);
$mform->addHelpButton('bui_defaultregion', 'defaultregion', 'block');
$mform->addElement('select', 'bui_defaultweight', get_string('defaultweight', 'block'), $weightoptions);
$mform->addHelpButton('bui_defaultweight', 'defaultweight', 'block');
// Where this block is positioned on this page.
$mform->addElement('header', 'whereheader', get_string('onthispage', 'block'));
@@ -229,7 +182,7 @@ class block_edit_form extends moodleform {
$systemcontext = get_context_instance(CONTEXT_SYSTEM);
if ($defaults->parentcontextid == $systemcontext->id) {
$defaults->bui_contexts = BUI_CONTEXTS_ENTIRE_SITE; // System-wide and sticky
$defaults->bui_contexts = 2; // System-wide and sticky
} else {
$defaults->bui_contexts = $defaults->bui_showinsubcontexts;
}
+8 -1
View File
@@ -62,7 +62,14 @@ class block_html extends block_base {
if (isset($this->config->text)) {
// rewrite url
$this->config->text = file_rewrite_pluginfile_urls($this->config->text, 'pluginfile.php', $this->context->id, 'block_html', 'content', NULL);
$this->content->text = format_text($this->config->text, $this->config->format, $filteropt);
// Default to FORMAT_HTML which is what will have been used before the
// editor was properly implemented for the block.
$format = FORMAT_HTML;
// Check to see if the format has been properly set on the config
if (isset($this->config->format)) {
$format = $this->config->format;
}
$this->content->text = format_text($this->config->text, $format, $filteropt);
} else {
$this->content->text = '';
}
-3
View File
@@ -63,8 +63,5 @@ function xmldb_block_html_upgrade($oldversion) {
upgrade_block_savepoint(true, 2010071900, 'html');
}
// Moodle v2.1.0 release upgrade line
// Put any upgrade step following this
return true;
}
+13
View File
@@ -57,11 +57,24 @@ class block_html_edit_form extends block_edit_form {
} else {
$text = '';
}
if (!$this->block->user_can_edit() && !empty($this->block->config->title)) {
// If a title has been set but the user cannot edit it format it nicely
$title = $this->block->config->title;
$defaults->config_title = format_string($title, true, $this->page->context);
// Remove the title from the config so that parent::set_data doesn't set it.
unset($this->block->config->title);
}
// have to delete text here, otherwise parent::set_data will empty content
// of editor
unset($this->block->config->text);
parent::set_data($defaults);
// restore $text
$this->block->config->text = $text;
if (isset($title)) {
// Reset the preserved title
$this->block->config->title = $title;
}
}
}
-3
View File
@@ -72,8 +72,5 @@ function xmldb_block_navigation_upgrade($oldversion, $block) {
upgrade_block_savepoint(true, 2010091400, 'navigation');
}
// Moodle v2.1.0 release upgrade line
// Put any upgrade step following this
return true;
}
-1
View File
@@ -52,7 +52,6 @@ class block_navigation_renderer extends plugin_renderer_base {
$attributes['class'] = 'dimmed_text';
}
if (is_string($item->action) || empty($item->action) || ($item->type === navigation_node::TYPE_CATEGORY && empty($options['linkcategories']))) {
$attributes['tabindex'] = '0'; //add tab support to span but still maintain character stream sequence.
$content = html_writer::tag('span', $content, $attributes);
} else if ($item->action instanceof action_link) {
//TODO: to be replaced with something else
+8 -108
View File
@@ -1,74 +1,5 @@
YUI.add('moodle-block_navigation-navigation', function(Y){
/**
* A 'actionkey' Event to help with Y.delegate().
* The event consists of the left arrow, right arrow, enter and space keys.
* More keys can be mapped to action meanings.
* actions: collapse , expand, toggle, enter.
*
* This event is delegated to branches in the navigation tree.
* The on() method to subscribe allows specifying the desired trigger actions as JSON.
*
* Todo: This could be centralised, a similar Event is defined in blocks/dock.js
*/
Y.Event.define("actionkey", {
// Webkit and IE repeat keydown when you hold down arrow keys.
// Opera links keypress to page scroll; others keydown.
// Firefox prevents page scroll via preventDefault() on either
// keydown or keypress.
_event: (Y.UA.webkit || Y.UA.ie) ? 'keydown' : 'keypress',
_keys: {
//arrows
'37': 'collapse',
'39': 'expand',
//(@todo: lrt/rtl/M.core_dock.cfg.orientation decision to assign arrow to meanings)
'32': 'toggle',
'13': 'enter'
},
_keyHandler: function (e, notifier, args) {
if (!args.actions) {
var actObj = {collapse:true, expand:true, toggle:true, enter:true};
} else {
var actObj = args.actions;
}
if (this._keys[e.keyCode] && actObj[this._keys[e.keyCode]]) {
e.action = this._keys[e.keyCode];
notifier.fire(e);
}
},
on: function (node, sub, notifier) {
// subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions).
if (sub.args == null) {
//no actions given
sub._detacher = node.on(this._event, this._keyHandler,this, notifier, {actions:false});
} else {
sub._detacher = node.on(this._event, this._keyHandler,this, notifier, sub.args[0]);
}
},
detach: function (node, sub, notifier) {
//detach our _detacher handle of the subscription made in on()
sub._detacher.detach();
},
delegate: function (node, sub, notifier, filter) {
// subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions).
if (sub.args == null) {
//no actions given
sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, {actions:false});
} else {
sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, sub.args[0]);
}
},
detachDelegate: function (node, sub, notifier) {
sub._delegateDetacher.detach();
}
});
var EXPANSIONLIMIT_EVERYTHING = 0,
EXPANSIONLIMIT_COURSE = 20,
EXPANSIONLIMIT_SECTION = 30,
@@ -105,7 +36,6 @@ TREE.prototype = {
// Delegate event to toggle expansion
var self = this;
Y.delegate('click', function(e){self.toggleExpansion(e);}, node.one('.block_tree'), '.tree_item.branch');
Y.delegate('actionkey', function(e){self.toggleExpansion(e);}, node.one('.block_tree'), '.tree_item.branch');
// Gather the expandable branches ready for initialisation.
var expansions = [];
@@ -141,8 +71,8 @@ TREE.prototype = {
// First check if they managed to click on the li iteslf, then find the closest
// LI ancestor and use that
if (e.target.test('a') && (e.keyCode == 0 || e.keyCode == 13)) {
// A link has been clicked (or keypress is 'enter') don't fire any more events just do the default.
if (e.target.test('a')) {
// A link has been clicked don't fire any more events just do the default.
e.stopPropagation();
return;
}
@@ -158,21 +88,7 @@ TREE.prototype = {
// Toggle expand/collapse providing its not a root level branch.
if (!target.hasClass('depth_1')) {
if (e.type == 'actionkey') {
switch (e.action) {
case 'expand' :
target.removeClass('collapsed');
break;
case 'collapse' :
target.addClass('collapsed');
break;
default :
target.toggleClass('collapsed');
}
e.halt();
} else {
target.toggleClass('collapsed');
}
target.toggleClass('collapsed');
}
// If the accordian feature has been enabled collapse all siblings.
@@ -236,10 +152,9 @@ BRANCH.prototype = {
*/
node : null,
/**
* A reference to the ajax load event handlers when created.
* A reference to the ajax load event handle when created.
*/
event_ajaxload : null,
event_ajaxload_actionkey : null,
/**
* Initialises the branch when it is first created.
*/
@@ -278,13 +193,8 @@ BRANCH.prototype = {
var isbranch = (this.get('expandable') || this.get('haschildren'));
var branchli = Y.Node.create('<li></li>');
var link = this.get('link');
var branchp = Y.Node.create('<p class="tree_item"></p>').setAttribute('id', this.get('id'));
if (!link) {
//add tab focus if not link (so still one focus per menu node).
// it was suggested to have 2 foci. one for the node and one for the link in MDL-27428.
branchp.setAttribute('tabindex', '0');
}
if (isbranch) {
branchli.addClass('collapsed').addClass('contains_branch');
branchp.addClass('branch');
@@ -310,6 +220,7 @@ BRANCH.prototype = {
}
}
var link = this.get('link');
if (!link) {
if (branchicon) {
branchp.appendChild(branchicon);
@@ -342,7 +253,6 @@ BRANCH.prototype = {
}
if (this.get('expandable')) {
this.event_ajaxload = this.node.on('ajaxload|click', this.ajaxLoad, this);
this.event_ajaxload_actionkey = this.node.on('actionkey', this.ajaxLoad, this);
}
return this;
},
@@ -364,16 +274,7 @@ BRANCH.prototype = {
* request made here.
*/
ajaxLoad : function(e) {
if (e.type == 'actionkey' && e.action != 'enter') {
e.halt();
} else {
e.stopPropagation();
}
if (e.type = 'actionkey' && e.action == 'enter' && e.target.test('A')) {
this.event_ajaxload_actionkey.detach();
this.event_ajaxload.detach();
return true; // no ajaxLoad for enter
}
e.stopPropagation();
if (this.node.hasClass('loadingbranch')) {
return true;
@@ -406,7 +307,6 @@ BRANCH.prototype = {
ajaxProcessResponse : function(tid, outcome) {
this.node.removeClass('loadingbranch');
this.event_ajaxload.detach();
this.event_ajaxload_actionkey.detach();
try {
var object = Y.JSON.parse(outcome.responseText);
if (object.children && object.children.length > 0) {
@@ -555,4 +455,4 @@ M.block_navigation = M.block_navigation || {
}
};
}, '@VERSION@', {requires:['base', 'core_dock', 'io', 'node', 'dom', 'event-custom', 'event-delegate', 'json-parse']});
}, '@VERSION@', {requires:['base', 'core_dock', 'io', 'node', 'dom', 'event-custom', 'event-delegate', 'json-parse']});
+3 -1
View File
@@ -140,7 +140,9 @@ class feed_edit_form extends moodleform {
return $url;
}
return $rss->subscribe_url();
// return URL without quoting..
$discoveredurl = new moodle_url($rss->subscribe_url());
return $discoveredurl->out(false);
}
}
+1
View File
@@ -46,6 +46,7 @@ class block_search extends block_base {
'<form id="searchquery" method="get" action="'. $CFG->wwwroot .'/search/query.php"><div>'
. '<label for="block_search_q">' . get_string('searchmoodle', 'block_search') . '</label>'
. '<input id="block_search_q" type="text" name="query_string" />'
. '<input id="block_instance_id" type="hidden" name="block_instanceid" value="' . $this->instance->id . '"/>'
. '<input type="submit" value="' . s(get_string('go', 'block_search')) . '" />'
. '</div></form>';
-3
View File
@@ -72,8 +72,5 @@ function xmldb_block_settings_upgrade($oldversion, $block) {
upgrade_block_savepoint(true, 2010091400, 'settings');
}
// Moodle v2.1.0 release upgrade line
// Put any upgrade step following this
return true;
}
-15
View File
@@ -1028,18 +1028,3 @@ function blog_comment_validate($comment_param) {
}
return true;
}
/**
* Return a list of page types
* @param string $pagetype current page type
* @param stdClass $parentcontext Block's parent context
* @param stdClass $currentcontext Current context of block
*/
function blog_page_type_list($pagetype, $parentcontext, $currentcontext) {
return array(
'*'=>get_string('page-x', 'pagetype'),
'blog-*'=>get_string('page-blog-x', 'blog'),
'blog-index'=>get_string('page-blog-index', 'blog'),
'blog-edit'=>get_string('page-blog-edit', 'blog')
);
}
+70 -50
View File
@@ -55,43 +55,26 @@ require_login();
$action = optional_param('action', 'new', PARAM_ALPHA);
$eventid = optional_param('id', 0, PARAM_INT);
$courseid = optional_param('courseid', SITEID, PARAM_INT);
$courseid = optional_param('course', $courseid, PARAM_INT);
$courseid = optional_param('courseid', 0, PARAM_INT);
$cal_y = optional_param('cal_y', 0, PARAM_INT);
$cal_m = optional_param('cal_m', 0, PARAM_INT);
$cal_d = optional_param('cal_d', 0, PARAM_INT);
$url = new moodle_url('/calendar/event.php', array('action' => $action));
if ($eventid != 0) {
$url->param('id', $eventid);
}
if ($courseid != SITEID) {
$url->param('course', $courseid);
}
if ($cal_y !== 0) {
$url->param('cal_y', $cal_y);
}
if ($cal_m !== 0) {
$url->param('cal_m', $cal_m);
}
if ($cal_d !== 0) {
$url->param('cal_d', $cal_d);
if ($courseid === 0) {
$courseid = optional_param('course', 0, PARAM_INT);
}
$url = new moodle_url('/calendar/event.php', array('action'=>$action));
if ($eventid !== 0) $url->param('id', $eventid);
if ($courseid !== 0) $url->param('course', $courseid);
if ($cal_y !== 0) $url->param('cal_y', $cal_y);
if ($cal_m !== 0) $url->param('cal_m', $cal_m);
if ($cal_d !== 0) $url->param('cal_d', $cal_d);
$PAGE->set_url($url);
$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
$PAGE->set_pagelayout('standard');
if ($courseid != SITEID && !empty($courseid)) {
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
$courses = array($course->id => $course);
$issite = false;
} else {
$course = get_site();
$courses = calendar_get_default_courses();
$issite = true;
}
require_login($course, false);
if ($action === 'delete' && $eventid > 0) {
if ($action === 'delete' && $eventid>0) {
$deleteurl = new moodle_url('/calendar/delete.php', array('id'=>$eventid));
if ($courseid > 0) {
$deleteurl->param('course', $courseid);
@@ -99,10 +82,56 @@ if ($action === 'delete' && $eventid > 0) {
redirect($deleteurl);
}
$viewcalendarurl = new moodle_url(CALENDAR_URL.'view.php');
$viewcalendarurl->params($PAGE->url->params());
$viewcalendarurl->remove_params(array('id','action'));
$now = usergetdate(time());
if (isguestuser()) {
// Guests cannot do anything with events
redirect(new moodle_url(CALENDAR_URL.'view.php', array('view'=>'upcoming', 'course'=>$courseid)));
}
$focus = '';
$site = get_site();
calendar_session_vars();
// If a course has been supplied in the URL, change the filters to show that one
$courseexists = false;
if ($courseid > 0) {
if ($courseid == SITEID) {
// If coming from the site page, show all courses
$SESSION->cal_courses_shown = calendar_get_default_courses(true);
calendar_set_referring_course(0);
} else if ($DB->record_exists('course', array('id'=>$courseid))) {
$courseexists = true;
// Otherwise show just this one
$SESSION->cal_courses_shown = $courseid;
calendar_set_referring_course($SESSION->cal_courses_shown);
}
}
if (!empty($SESSION->cal_course_referer)) {
// TODO: This is part of the Great $course Hack in Moodle. Replace it at some point.
$course = $DB->get_record('course', array('id'=>$SESSION->cal_course_referer));
} else {
$course = $site;
}
require_login($course, false);
$calendar = new calendar_information($cal_d, $cal_m, $cal_y);
$calendar->prepare_for_view($course, $courses);
$calendar->courseid = $courseid;
$strcalendar = get_string('calendar', 'calendar');
$link = clone($viewcalendarurl);
$link->param('view', 'upcoming');
$formoptions = new stdClass;
if ($eventid !== 0) {
$title = get_string('editevent', 'calendar');
$event = calendar_event::load($eventid);
@@ -119,13 +148,13 @@ if ($eventid !== 0) {
}
} else {
$title = get_string('newevent', 'calendar');
calendar_get_allowed_types($formoptions->eventtypes, $course);
calendar_get_allowed_types($formoptions->eventtypes, $USER->id);
$event = new stdClass();
$event->action = $action;
$event->course = $courseid;
$event->timeduration = 0;
if ($formoptions->eventtypes->courses) {
if (!$issite) {
if ($courseexists) {
$event->courseid = $courseid;
$event->eventtype = 'course';
} else {
@@ -136,7 +165,6 @@ if ($eventid !== 0) {
if($cal_y && $cal_m && $cal_d && checkdate($cal_m, $cal_d, $cal_y)) {
$event->timestart = make_timestamp($cal_y, $cal_m, $cal_d, 0, 0, 0);
} else if($cal_y && $cal_m && checkdate($cal_m, 1, $cal_y)) {
$now = usergetdate(time());
if($cal_y == $now['year'] && $cal_m == $now['mon']) {
$event->timestart = make_timestamp($cal_y, $cal_m, $now['mday'], 0, 0, 0);
} else {
@@ -165,31 +193,23 @@ if ($data) {
}
$event->update($data);
$params = array(
'view' => 'day',
'cal_d' => date('j', $event->timestart),
'cal_m' => date('n', $event->timestart),
'cal_y' => date('y', $event->timestart),
);
$eventurl = new moodle_url('/calendar/view.php', $params);
if (!empty($event->courseid) && $event->courseid != SITEID) {
$eventurl = new moodle_url(CALENDAR_URL.'view.php', array('view'=>'day'));
if (!empty($event->courseid)) {
$eventurl->param('course', $event->courseid);
}
$eventurl->param('cal_d', date('j', $event->timestart));
$eventurl->param('cal_m', date('n', $event->timestart));
$eventurl->param('cal_y', date('Y', $event->timestart));
$eventurl->set_anchor('event_'.$event->id);
redirect($eventurl);
}
$viewcalendarurl = new moodle_url(CALENDAR_URL.'view.php', $PAGE->url->params());
$viewcalendarurl->remove_params(array('id', 'action'));
$viewcalendarurl->param('view', 'upcoming');
$strcalendar = get_string('calendar', 'calendar');
$PAGE->navbar->add($strcalendar, $viewcalendarurl);
$PAGE->navbar->add($strcalendar, $link);
$PAGE->navbar->add($title);
$PAGE->set_title($course->shortname.': '.$strcalendar.': '.$title);
$PAGE->set_heading($course->fullname);
$PAGE->set_title($site->shortname.': '.$strcalendar.': '.$title);
$PAGE->set_heading($COURSE->fullname);
calendar_set_filters($calendar->courses, $calendar->groups, $calendar->users);
$renderer = $PAGE->get_renderer('core_calendar');
$calendar->add_sidecalendar_blocks($renderer);
+49 -31
View File
@@ -49,27 +49,17 @@
require_once('../config.php');
require_once($CFG->dirroot.'/course/lib.php');
require_once($CFG->dirroot.'/calendar/lib.php');
//require_once($CFG->libdir.'/bennu/bennu.inc.php');
if (empty($CFG->enablecalendarexport)) {
die('no export');
}
$courseid = optional_param('course', SITEID, PARAM_INT);
$action = optional_param('action', '', PARAM_ALPHA);
$day = optional_param('cal_d', 0, PARAM_INT);
$mon = optional_param('cal_m', 0, PARAM_INT);
$yr = optional_param('cal_y', 0, PARAM_INT);
if ($courseid != SITEID && !empty($courseid)) {
$course = $DB->get_record('course', array('id' => $courseid));
$courses = array($course->id => $course);
$issite = false;
if ($courseid = optional_param('course', 0, PARAM_INT)) {
$course = $DB->get_record('course', array('id'=>$courseid));
} else {
$course = get_site();
$courses = calendar_get_default_courses();
$issite = true;
$course = NULL;
}
require_course_login($course);
$url = new moodle_url('/calendar/export.php');
if ($action !== '') {
@@ -89,22 +79,57 @@ if ($course !== NULL) {
}
$PAGE->set_url($url);
$calendar = new calendar_information($day, $mon, $yr);
$calendar->prepare_for_view($course, $courses);
require_login($course);
if (!$course) {
$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM)); //TODO: wrong
}
if (empty($CFG->enablecalendarexport)) {
die('no export');
}
$site = get_site();
// Initialize the session variables
calendar_session_vars();
$pagetitle = get_string('export', 'calendar');
$navlinks = array();
$now = usergetdate(time());
// Print title and header
if ($issite) {
if (!empty($courseid) && $course->id != SITEID) {
$PAGE->navbar->add($course->shortname, new moodle_url('/course/view.php', array('id'=>$course->id)));
}
$calendar = new calendar_information($day, $mon, $yr);
$calendar->courseid = $courseid;
if(!checkdate($mon, $day, $yr)) {
$day = intval($now['mday']);
$mon = intval($now['mon']);
$yr = intval($now['year']);
}
$time = make_timestamp($yr, $mon, $day);
if (!isloggedin() or isguestuser()) {
$defaultcourses = calendar_get_default_courses();
calendar_set_filters($calendar->courses, $calendar->groups, $calendar->users, $defaultcourses, $defaultcourses);
} else {
calendar_set_filters($calendar->courses, $calendar->groups, $calendar->users);
}
$strcalendar = get_string('calendar', 'calendar');
$prefsbutton = calendar_preferences_button();
// Print title and header
$link = new moodle_url(CALENDAR_URL.'view.php', array('view'=>'upcoming', 'course'=>$calendar->courseid));
$PAGE->navbar->add(get_string('calendar', 'calendar'), calendar_get_link_href($link, $now['mday'], $now['mon'], $now['year']));
$PAGE->navbar->add($pagetitle);
$PAGE->set_title($course->shortname.': '.get_string('calendar', 'calendar').': '.$pagetitle);
$PAGE->set_heading($course->fullname);
$PAGE->set_button(calendar_preferences_button($course));
$PAGE->set_title($site->shortname.': '.$strcalendar.': '.$pagetitle);
$PAGE->set_heading($COURSE->fullname);
$PAGE->set_button($prefsbutton);
$PAGE->set_pagelayout('standard');
$renderer = $PAGE->get_renderer('core_calendar');
@@ -114,26 +139,19 @@ echo $OUTPUT->header();
echo $renderer->start_layout();
switch($action) {
case 'advanced':
// Why nothing?
break;
break;
case '':
default:
$weekend = CALENDAR_DEFAULT_WEEKEND;
if (isset($CFG->calendar_weekend)) {
$weekend = intval($CFG->calendar_weekend);
}
$username = $USER->username;
$authtoken = sha1($USER->username . $USER->password . $CFG->calendar_exportsalt);
// Let's populate some vars to let "common tasks" be somewhat smart...
// If today it's weekend, give the "next week" option
$allownextweek = $weekend & (1 << $now['wday']);
$allownextweek = CALENDAR_WEEKEND & (1 << $now['wday']);
// If it's the last week of the month, give the "next month" option
$allownextmonth = calendar_days_in_month($now['mon'], $now['year']) - $now['mday'] < 7;
// If today it's weekend but tomorrow it isn't, do NOT give the "this week" option
$allowthisweek = !(($weekend & (1 << $now['wday'])) && !($weekend & (1 << (($now['wday'] + 1) % 7))));
$allowthisweek = !((CALENDAR_WEEKEND & (1 << $now['wday'])) && !(CALENDAR_WEEKEND & (1 << (($now['wday'] + 1) % 7))));
echo $renderer->basic_export_form($allowthisweek, $allownextweek, $allownextmonth, $username, $authtoken);
break;
}
echo $renderer->complete_layout();
echo $OUTPUT->footer();
+299 -229
View File
@@ -45,29 +45,20 @@ define('CALENDAR_DEFAULT_STARTING_WEEKDAY', 1);
// This is a packed bitfield: day X is "weekend" if $field & (1 << X) is true
// Default value = 65 = 64 + 1 = 2^6 + 2^0 = Saturday & Sunday
define('CALENDAR_DEFAULT_WEEKEND', 65);
define('CALENDAR_UPCOMING_DAYS', isset($CFG->calendar_lookahead) ? intval($CFG->calendar_lookahead) : CALENDAR_DEFAULT_UPCOMING_LOOKAHEAD);
define('CALENDAR_UPCOMING_MAXEVENTS', isset($CFG->calendar_maxevents) ? intval($CFG->calendar_maxevents) : CALENDAR_DEFAULT_UPCOMING_MAXEVENTS);
define('CALENDAR_WEEKEND', isset($CFG->calendar_weekend) ? intval($CFG->calendar_weekend) : CALENDAR_DEFAULT_WEEKEND);
define('CALENDAR_URL', $CFG->wwwroot.'/calendar/');
define('CALENDAR_TF_24', '%H:%M');
define('CALENDAR_TF_12', '%I:%M %p');
define('CALENDAR_EVENT_GLOBAL', 1);
define('CALENDAR_EVENT_COURSE', 2);
define('CALENDAR_EVENT_GROUP', 4);
define('CALENDAR_EVENT_USER', 8);
/**
* CALENDAR_STARTING_WEEKDAY has since been deprecated please call calendar_get_starting_weekday() instead
* @deprecated
*/
define('CALENDAR_STARTING_WEEKDAY', CALENDAR_DEFAULT_STARTING_WEEKDAY);
/**
* Return the days of the week
*
* @return array
*/
function calendar_get_days() {
return array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');
}
$CALENDARDAYS = array('sunday','monday','tuesday','wednesday','thursday','friday','saturday');
/**
* Gets the first day of the week
@@ -206,7 +197,8 @@ function calendar_get_mini($courses, $groups, $users, $cal_month = false, $cal_y
calendar_events_by_day($events, $m, $y, $eventsbyday, $durationbyday, $typesbyday, $courses);
//Accessibility: added summary and <abbr> elements.
$days_title = calendar_get_days();
///global $CALENDARDAYS; appears to be broken.
$days_title = array('sunday','monday','tuesday','wednesday','thursday','friday','saturday');
$summary = get_string('calendarheading', 'calendar', userdate(make_timestamp($y, $m), get_string('strftimemonthyear')));
$summary = get_string('tabledata', 'access', $summary);
@@ -232,11 +224,6 @@ function calendar_get_mini($courses, $groups, $users, $cal_month = false, $cal_y
$content .= '<td class="dayblank">&nbsp;</td>'."\n";
}
$weekend = CALENDAR_DEFAULT_WEEKEND;
if (isset($CFG->calendar_weekend)) {
$weekend = intval($CFG->calendar_weekend);
}
// Now display all the calendar
for($day = 1; $day <= $display->maxdays; ++$day, ++$dayweek) {
if($dayweek > $display->maxwday) {
@@ -247,7 +234,7 @@ function calendar_get_mini($courses, $groups, $users, $cal_month = false, $cal_y
// Reset vars
$cell = '';
if ($weekend & (1 << ($dayweek % 7))) {
if(CALENDAR_WEEKEND & (1 << ($dayweek % 7))) {
// Weekend. This is true no matter what the exact range is.
$class = 'weekend day';
} else {
@@ -678,7 +665,7 @@ function calendar_get_events($tstart, $tend, $users, $groups, $courses, $withdur
}
function calendar_top_controls($type, $data) {
global $CFG;
global $CFG, $CALENDARDAYS;
$content = '';
if(!isset($data['d'])) {
$data['d'] = 1;
@@ -799,12 +786,11 @@ function calendar_top_controls($type, $data) {
$content .= html_writer::end_tag('div')."\n";
break;
case 'day':
$days = calendar_get_days();
$data['d'] = $date['mday']; // Just for convenience
$prevdate = usergetdate(make_timestamp($data['y'], $data['m'], $data['d'] - 1));
$nextdate = usergetdate(make_timestamp($data['y'], $data['m'], $data['d'] + 1));
$prevname = calendar_wday_name($days[$prevdate['wday']]);
$nextname = calendar_wday_name($days[$nextdate['wday']]);
$prevname = calendar_wday_name($CALENDARDAYS[$prevdate['wday']]);
$nextname = calendar_wday_name($CALENDARDAYS[$nextdate['wday']]);
$prevlink = calendar_get_link_previous($prevname, 'view.php?view=day'.$courseid.'&amp;', $prevdate['mday'], $prevdate['mon'], $prevdate['year']);
$nextlink = calendar_get_link_next($nextname, 'view.php?view=day'.$courseid.'&amp;', $nextdate['mday'], $nextdate['mon'], $nextdate['year']);
@@ -828,61 +814,79 @@ function calendar_top_controls($type, $data) {
return $content;
}
function calendar_filter_controls(moodle_url $returnurl) {
global $CFG, $USER, $OUTPUT;
function calendar_filter_controls($type, $vars = NULL, $course = NULL, $courses = NULL) {
global $CFG, $SESSION, $USER, $OUTPUT;
$groupevents = true;
$getvars = '';
$id = optional_param( 'id',0,PARAM_INT );
$seturl = new moodle_url('/calendar/set.php', array('return' => $returnurl));
switch($type) {
case 'event':
case 'upcoming':
case 'day':
case 'month':
$getvars = '&amp;from='.$type;
break;
case 'course':
if ($id > 0) {
$getvars = '&amp;from=course&amp;id='.$id;
} else {
$getvars = '&amp;from=course';
}
if (isset($course->groupmode) and $course->groupmode == NOGROUPS and $course->groupmodeforce) {
$groupevents = false;
}
break;
}
if (!empty($vars)) {
$getvars .= '&amp;'.$vars;
}
$content = '<table>';
$content .= '<tr>';
$seturl->param('var', 'showglobal');
if (calendar_show_event_type(CALENDAR_EVENT_GLOBAL)) {
$content .= '<td class="eventskey calendar_event_global" style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/hide') . '" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_hideglobal', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".$seturl."'".'" /></td>';
$content .= '<td><a href="'.$seturl.'" title="'.get_string('tt_hideglobal', 'calendar').'">'.get_string('global', 'calendar').'</a></td>'."\n";
if($SESSION->cal_show_global) {
$content .= '<td class="eventskey calendar_event_global" style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/hide') . '" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_hideglobal', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showglobal'.$getvars."'".'" /></td>';
$content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showglobal'.$getvars.'" title="'.get_string('tt_hideglobal', 'calendar').'">'.get_string('global', 'calendar').'</a></td>'."\n";
} else {
$content .= '<td style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/show') . '" class="iconsmall" alt="'.get_string('show').'" title="'.get_string('tt_showglobal', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".$seturl."'".'" /></td>';
$content .= '<td><a href="'.$seturl.'" title="'.get_string('tt_showglobal', 'calendar').'">'.get_string('global', 'calendar').'</a></td>'."\n";
$content .= '<td style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/show') . '" class="iconsmall" alt="'.get_string('show').'" title="'.get_string('tt_showglobal', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showglobal'.$getvars."'".'" /></td>';
$content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showglobal'.$getvars.'" title="'.get_string('tt_showglobal', 'calendar').'">'.get_string('global', 'calendar').'</a></td>'."\n";
}
if($SESSION->cal_show_course) {
$content .= '<td class="eventskey calendar_event_course" style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/hide') . '" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_hidecourse', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showcourses'.$getvars."'".'" /></td>';
$content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showcourses'.$getvars.'" title="'.get_string('tt_hidecourse', 'calendar').'">'.get_string('course', 'calendar').'</a></td>'."\n";
} else {
$content .= '<td style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/show') . '" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_showcourse', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showcourses'.$getvars."'".'" /></td>';
$content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showcourses'.$getvars.'" title="'.get_string('tt_showcourse', 'calendar').'">'.get_string('course', 'calendar').'</a></td>'."\n";
}
$seturl->param('var', 'showcourses');
if (calendar_show_event_type(CALENDAR_EVENT_COURSE)) {
$content .= '<td class="eventskey calendar_event_course" style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/hide') . '" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_hidecourse', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".$seturl."'".'" /></td>';
$content .= '<td><a href="'.$seturl.'" title="'.get_string('tt_hidecourse', 'calendar').'">'.get_string('course', 'calendar').'</a></td>'."\n";
} else {
$content .= '<td style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/show') . '" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_showcourse', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".$seturl."'".'" /></td>';
$content .= '<td><a href="'.$seturl.'" title="'.get_string('tt_showcourse', 'calendar').'">'.get_string('course', 'calendar').'</a></td>'."\n";
}
if (isloggedin() && !isguestuser()) {
$content .= "</tr>\n<tr>";
if ($groupevents) {
if($groupevents) {
// This course MIGHT have group events defined, so show the filter
$seturl->param('var', 'showgroups');
if (calendar_show_event_type(CALENDAR_EVENT_GROUP)) {
$content .= '<td class="eventskey calendar_event_group" style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/hide') . '" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_hidegroups', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".$seturl."'".'" /></td>';
$content .= '<td><a href="'.$seturl.'" title="'.get_string('tt_hidegroups', 'calendar').'">'.get_string('group', 'calendar').'</a></td>'."\n";
if($SESSION->cal_show_groups) {
$content .= '<td class="eventskey calendar_event_group" style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/hide') . '" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_hidegroups', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showgroups'.$getvars."'".'" /></td>';
$content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showgroups'.$getvars.'" title="'.get_string('tt_hidegroups', 'calendar').'">'.get_string('group', 'calendar').'</a></td>'."\n";
} else {
$content .= '<td style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/show') . '" class="iconsmall" alt="'.get_string('show').'" title="'.get_string('tt_showgroups', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".$seturl."'".'" /></td>';
$content .= '<td><a href="'.$seturl.'" title="'.get_string('tt_showgroups', 'calendar').'">'.get_string('group', 'calendar').'</a></td>'."\n";
$content .= '<td style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/show') . '" class="iconsmall" alt="'.get_string('show').'" title="'.get_string('tt_showgroups', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showgroups'.$getvars."'".'" /></td>';
$content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showgroups'.$getvars.'" title="'.get_string('tt_showgroups', 'calendar').'">'.get_string('group', 'calendar').'</a></td>'."\n";
}
} else {
// This course CANNOT have group events, so lose the filter
$content .= '<td style="width: 11px;"></td><td>&nbsp;</td>'."\n";
}
$seturl->param('var', 'showuser');
if (calendar_show_event_type(CALENDAR_EVENT_USER)) {
$content .= '<td class="eventskey calendar_event_user" style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/hide') . '" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_hideuser', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".$seturl."'".'" /></td>';
$content .= '<td><a href="'.$seturl.'" title="'.get_string('tt_hideuser', 'calendar').'">'.get_string('user', 'calendar').'</a></td>'."\n";
if($SESSION->cal_show_user) {
$content .= '<td class="eventskey calendar_event_user" style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/hide') . '" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_hideuser', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showuser'.$getvars."'".'" /></td>';
$content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showuser'.$getvars.'" title="'.get_string('tt_hideuser', 'calendar').'">'.get_string('user', 'calendar').'</a></td>'."\n";
} else {
$content .= '<td style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/show') . '" class="iconsmall" alt="'.get_string('show').'" title="'.get_string('tt_showuser', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".$seturl."'".'" /></td>';
$content .= '<td><a href="'.$seturl.'" title="'.get_string('tt_showuser', 'calendar').'">'.get_string('user', 'calendar').'</a></td>'."\n";
$content .= '<td style="width: 11px;"><img src="'.$OUTPUT->pix_url('t/show') . '" class="iconsmall" alt="'.get_string('show').'" title="'.get_string('tt_showuser', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showuser'.$getvars."'".'" /></td>';
$content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showuser'.$getvars.'" title="'.get_string('tt_showuser', 'calendar').'">'.get_string('user', 'calendar').'</a></td>'."\n";
}
}
$content .= "</tr>\n</table>\n";
@@ -1200,89 +1204,212 @@ function calendar_get_course_cached(&$coursecache, $courseid) {
return $coursecache[$courseid];
}
/**
* Returns the courses to load events for, the
*
* @global moodle_database $DB
* @param array $courseeventsfrom An array of courses to load calendar events for
* @param bool $ignorefilters
* @return array An array of courses, groups, and user to load calendar events for based upon filters
*/
function calendar_set_filters(array $courseeventsfrom, $ignorefilters = false) {
global $USER, $CFG, $DB;
function calendar_session_vars($course=null) {
global $SESSION, $USER;
// For backwards compatability we have to check whether the courses array contains
// just id's in which case we need to load course objects.
$coursestoload = array();
foreach ($courseeventsfrom as $id => $something) {
if (!is_object($something)) {
$coursestoload[] = $id;
unset($courseeventsfrom[$id]);
if(!isset($SESSION->cal_course_referer)) {
$SESSION->cal_course_referer = 0;
}
if(!isset($SESSION->cal_show_global)) {
$SESSION->cal_show_global = true;
}
if(!isset($SESSION->cal_show_groups)) {
$SESSION->cal_show_groups = true;
}
if(!isset($SESSION->cal_show_course)) {
$SESSION->cal_show_course = true;
}
if(!isset($SESSION->cal_show_user)) {
$SESSION->cal_show_user = true;
}
if ($course !== null) {
// speedup hack for calendar related blocks
if(isset($course->coursenode)) {
// coursenode has been set up, which seems to break things further down the line.
// Use a clone of $course with coursenode removed.
$course = clone $course;
unset($course->coursenode);
}
$SESSION->cal_courses_shown = array($course->id => $course);
} else {
$SESSION->cal_courses_shown = calendar_get_default_courses(true);
}
if(empty($SESSION->cal_users_shown)) {
// The empty() instead of !isset() here makes a whole world of difference,
// as it will automatically change to the user's id when the user first logs
// in. With !isset(), it would never do that.
$SESSION->cal_users_shown = isloggedin() ? $USER->id : false;
} else if(is_numeric($SESSION->cal_users_shown) && isloggedin() && $SESSION->cal_users_shown != $USER->id) {
// Follow the white rabbit, for example if a teacher logs in as a student
$SESSION->cal_users_shown = $USER->id;
}
}
function calendar_set_referring_course($courseid) {
global $SESSION;
$SESSION->cal_course_referer = intval($courseid);
}
function calendar_set_filters(&$courses, &$group, &$user, $courseeventsfrom = NULL, $groupeventsfrom = NULL, $ignorefilters = false) {
global $SESSION, $USER, $CFG, $DB;
// Insidious bug-wannabe: setting $SESSION->cal_courses_shown to $course->id would cause
// the code to function incorrectly UNLESS we convert it to an integer. One case where
// PHP's loose type system works against us.
if(is_string($SESSION->cal_courses_shown)) {
$SESSION->cal_courses_shown = intval($SESSION->cal_courses_shown);
}
if($courseeventsfrom === NULL) {
$courseeventsfrom = $SESSION->cal_courses_shown;
}
// MDL-9059, $courseeventsfrom can be an int, or an array of ints, or an array of course objects
// convert all to array of objects
// we probably should do some clean up and make sure that session is set to use the proper form
if (is_int($courseeventsfrom)) { // case of an int, e.g. calendar view page
$c = array();
$c[$courseeventsfrom] = $DB->get_record('course', array('id'=>$courseeventsfrom));
$courseeventsfrom = $c;
} else if (is_array($courseeventsfrom)) { // case of an array of ints, e.g. course home page
foreach ($courseeventsfrom as $i=>$courseid) { // TODO: this seems wrong, the array is often constructed as [courseid] => 1 ???
if (is_int($courseid)) {
$courseeventsfrom[$i] = $DB->get_record('course', array('id'=>$courseid));
}
}
}
if (!empty($coursestoload)) {
// TODO remove this in 2.2
debugging('calendar_set_filters now preferes an array of course objects with preloaded contexts', DEBUG_DEVELOPER);
$courseeventsfrom = array_merge($courseeventsfrom, $DB->get_records_list('course', 'id', $coursestoload));
if($groupeventsfrom === NULL) {
$groupeventsfrom = $SESSION->cal_courses_shown;
}
$courses = array();
$user = false;
$group = false;
$isloggedin = isloggedin();
if ($ignorefilters || calendar_show_event_type(CALENDAR_EVENT_COURSE)) {
$courses = array_keys($courseeventsfrom);
if(($SESSION->cal_show_course && $SESSION->cal_show_global) || $ignorefilters) {
if(is_int($courseeventsfrom)) {
$courses = array(SITEID, $courseeventsfrom);
}
else if(is_array($courseeventsfrom)) {
$courses = array_keys($courseeventsfrom);
$courses[] = SITEID;
}
}
if ($ignorefilters || calendar_show_event_type(CALENDAR_EVENT_GLOBAL)) {
$courses[] = SITEID;
else if($SESSION->cal_show_course) {
if(is_int($courseeventsfrom)) {
$courses = array($courseeventsfrom);
}
else if(is_array($courseeventsfrom)) {
$courses = array_keys($courseeventsfrom);
}
$courses = array_diff($courses, array(SITEID));
}
$courses = array_unique($courses);
sort($courses);
else if($SESSION->cal_show_global) {
$courses = array(SITEID);
}
else {
$courses = false;
}
//BUG 6130 clean $courses array as SESSION has bad entries.
// [pj] TODO: See if this has to do with my new change in get_default_courses and can be taken out
if (is_array($courses)) {
foreach ($courses as $index => $value) {
if (empty($value)) unset($courses[$index]);
}
if (!empty($courses) && in_array(SITEID, $courses)) {
// Sort courses for consistent colour highlighting
// Effectively ignoring SITEID as setting as last course id
$key = array_search(SITEID, $courses);
unset($courses[$key]);
$courses[] = SITEID;
if ($key !== false) {
unset($courses[$key]);
sort($courses);
$courses[] = SITEID;
} else {
sort($courses);
}
}
if ($ignorefilters || ($isloggedin && calendar_show_event_type(CALENDAR_EVENT_USER))) {
$user = $USER->id;
if($SESSION->cal_show_user || $ignorefilters) {
// This doesn't work for arrays yet (maybe someday it will)
$user = $SESSION->cal_users_shown;
}
else {
$user = false;
}
if($SESSION->cal_show_groups || $ignorefilters) {
if(is_int($groupeventsfrom)) {
$groupcourses = array($groupeventsfrom);
}
else if(is_array($groupeventsfrom)) {
$groupcourses = array_keys($groupeventsfrom);
}
if (!empty($courseeventsfrom) && (calendar_show_event_type(CALENDAR_EVENT_GROUP) || $ignorefilters)) {
if (!empty($CFG->calendar_adminseesall) && has_capability('moodle/calendar:manageentries', get_system_context())) {
// XXX TODO: not sure how to replace $CFG->calendar_adminseesall
if(has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_SYSTEM)) && !empty($CFG->calendar_adminseesall)) {
$group = true;
} else if ($isloggedin) {
$groupids = array();
}
else {
$grouparray = array();
// We already have the courses to examine in $courses
// For each course...
foreach ($courseeventsfrom as $courseid => $course) {
foreach($groupcourses as $courseid) {
if (!isset($courseeventsfrom[$courseid]->context)) { // SHOULD be set MDL-11221
if (is_object($courseeventsfrom[$courseid])) {
$courseeventsfrom[$courseid]->context = get_context_instance(CONTEXT_COURSE, $courseid);
}
}
// If the user is an editing teacher in there,
if (!empty($USER->groupmember[$course->id])) {
// We've already cached the users groups for this course so we can just use that
$groupids = array_merge($groupids, $USER->groupmember[$course->id]);
} else if (($course->groupmode != NOGROUPS || !$course->groupmodeforce) && has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_COURSE, $course->id))) {
if (isloggedin() && isset($courseeventsfrom[$courseid]->context) && has_capability('moodle/calendar:manageentries', $courseeventsfrom[$courseid]->context)) {
// If this course has groups, show events from all of them
$coursegroups = groups_get_user_groups($course->id, $USER->id);
$groupids = array_merge($groupids, $coursegroups['0']);
if(is_int($groupeventsfrom)) {
if (is_object($courseeventsfrom[$courseid])) { // SHOULD be set MDL-11221
$courserecord = $courseeventsfrom[$courseid];
} else {
$courserecord = $DB->get_record('course', array('id'=>$courseid));
}
$courserecord = $DB->get_record('course', array('id'=>$courseid));
if ($courserecord->groupmode != NOGROUPS || !$courserecord->groupmodeforce) {
$groupids[] = $courseid;
}
}
else if(isset($SESSION->cal_courses_shown[$courseid]) && ($SESSION->cal_courses_shown[$courseid]->groupmode != NOGROUPS || !$SESSION->cal_courses_shown[$courseid]->groupmodeforce)) {
$groupids[] = $courseid;
}
}
// Otherwise (not editing teacher) show events from the group he is a member of
else if(isset($USER->groupmember[$courseid])) {
//changed to 2D array
foreach ($USER->groupmember[$courseid] as $groupid){
$grouparray[] = $groupid;
}
}
}
if (!empty($groupids)) {
$group = $groupids;
$sql = "SELECT *
FROM {groups}
WHERE courseid IN (".implode(',', $groupids).')';
if ($grouprecords = $DB->get_records_sql($sql, null)) {
foreach ($grouprecords as $grouprecord) {
$grouparray[] = $grouprecord->id;
}
}
}
if(empty($grouparray)) {
$group = false;
}
else {
$group = $grouparray;
}
}
}
if (empty($courses)) {
$courses = false;
}
return array($courses, $group, $user);
}
else {
$group = false;
}
}
function calendar_edit_event_allowed($event) {
@@ -1327,32 +1454,23 @@ function calendar_edit_event_allowed($event) {
return false;
}
/**
* Returns the default courses to display on the calendar when there isn't a specific
* course to display.
*
* @global moodle_database $DB
* @return array Array of courses to display
*/
function calendar_get_default_courses() {
global $CFG, $DB;
function calendar_get_default_courses($ignoreref = false) {
global $USER, $CFG, $SESSION, $DB;
if(!empty($SESSION->cal_course_referer) && !$ignoreref) {
return array($SESSION->cal_course_referer => 1);
}
if (!isloggedin()) {
return array();
}
$courses = array();
if (!empty($CFG->calendar_adminseesall) && has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_SYSTEM))) {
list ($select, $join) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
$sql = "SELECT c.* $select
FROM {course} c
JOIN {event} e ON e.courseid = c.id
$join";
$courses = $DB->get_records_sql($sql, null, 0, 20);
foreach ($courses as $course) {
context_instance_preload($course);
if (has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_SYSTEM))) {
if (!empty($CFG->calendar_adminseesall)) {
$courses = $DB->get_records_sql('SELECT id, 1 FROM {course}');
return $courses;
}
return $courses;
}
$courses = enrol_get_my_courses();
@@ -1360,15 +1478,17 @@ function calendar_get_default_courses() {
return $courses;
}
function calendar_preferences_button(stdClass $course) {
global $OUTPUT;
function calendar_preferences_button() {
global $CFG, $USER;
// Guests have no preferences
if (!isloggedin() || isguestuser()) {
return '';
}
return $OUTPUT->single_button(new moodle_url('/calendar/preferences.php', array('course' => $course->id)), get_string("preferences", "calendar"));
return "<form method=\"get\" ".
" action=\"$CFG->wwwroot/calendar/preferences.php\">".
"<div><input type=\"submit\" value=\"".get_string("preferences", "calendar")." ...\" /></div></form>";
}
function calendar_format_event_time($event, $now, $linkparams = null, $usecommonwords = true, $showtime=0) {
@@ -1468,93 +1588,61 @@ function calendar_print_month_selector($name, $selected) {
echo html_writer::select($months, $name, $selected, false);
}
/**
* Checks to see if the requested type of event should be shown for the given user.
*
* @param CALENDAR_EVENT_GLOBAL|CALENDAR_EVENT_COURSE|CALENDAR_EVENT_GROUP|CALENDAR_EVENT_USER $type
* The type to check the display for (default is to display all)
* @param stdClass|int|null $user The user to check for - by default the current user
* @return bool True if the tyep should be displayed false otherwise
*/
function calendar_show_event_type($type, $user = null) {
$default = CALENDAR_EVENT_GLOBAL + CALENDAR_EVENT_COURSE + CALENDAR_EVENT_GROUP + CALENDAR_EVENT_USER;
if (get_user_preferences('calendar_persistflt', 0, $user) === 0) {
global $SESSION;
if (!isset($SESSION->calendarshoweventtype)) {
$SESSION->calendarshoweventtype = $default;
}
return $SESSION->calendarshoweventtype & $type;
} else {
return get_user_preferences('calendar_savedflt', $default, $user) & $type;
function calendar_get_filters_status() {
global $SESSION;
$status = 0;
if($SESSION->cal_show_global) {
$status += 1;
}
if($SESSION->cal_show_course) {
$status += 2;
}
if($SESSION->cal_show_groups) {
$status += 4;
}
if($SESSION->cal_show_user) {
$status += 8;
}
return $status;
}
/**
* Sets the display of the event type given $display.
* If $display = true the event type will be shown.
* If $display = false the event type will NOT be shown.
* If $display = null the current value will be toggled and saved.
*
* @param CALENDAR_EVENT_GLOBAL|CALENDAR_EVENT_COURSE|CALENDAR_EVENT_GROUP|CALENDAR_EVENT_USER $type
* @param true|false|null $display
* @param stdClass|int|null $user
*/
function calendar_set_event_type_display($type, $display = null, $user = null) {
$persist = get_user_preferences('calendar_persistflt', 0, $user);
$default = CALENDAR_EVENT_GLOBAL + CALENDAR_EVENT_COURSE + CALENDAR_EVENT_GROUP + CALENDAR_EVENT_USER;
if ($persist === 0) {
global $SESSION;
if (!isset($SESSION->calendarshoweventtype)) {
$SESSION->calendarshoweventtype = $default;
}
$preference = $SESSION->calendarshoweventtype;
} else {
$preference = get_user_preferences('calendar_savedflt', $default, $user);
}
$current = $preference & $type;
if ($display === null) {
$display = !$current;
}
if ($display && !$current) {
$preference += $type;
} else if (!$display && $current) {
$preference -= $type;
}
if ($persist === 0) {
$SESSION->calendarshoweventtype = $preference;
} else {
if ($preference == $default) {
unset_user_preference('calendar_savedflt', $user);
} else {
set_user_preference('calendar_savedflt', $preference, $user);
}
function calendar_set_filters_status($packed_bitfield) {
global $SESSION, $USER;
if (!isloggedin()) {
return false;
}
$SESSION->cal_show_global = ($packed_bitfield & 1);
$SESSION->cal_show_course = ($packed_bitfield & 2);
$SESSION->cal_show_groups = ($packed_bitfield & 4);
$SESSION->cal_show_user = ($packed_bitfield & 8);
return true;
}
function calendar_get_allowed_types(&$allowed, $course = null) {
global $USER, $CFG, $DB;
$allowed->user = has_capability('moodle/calendar:manageownentries', get_system_context());
function calendar_get_allowed_types(&$allowed) {
global $USER, $CFG, $SESSION, $DB;
$sitecontext = get_context_instance(CONTEXT_SYSTEM);
$allowed->user = has_capability('moodle/calendar:manageownentries', $sitecontext);
$allowed->groups = false; // This may change just below
$allowed->courses = false; // This may change just below
$allowed->site = has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_COURSE, SITEID));
if (!empty($course)) {
if (!is_object($course)) {
$course = $DB->get_record('course', array('id' => $course), '*', MUST_EXIST);
}
if ($course->id != SITEID) {
$coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
if(!empty($SESSION->cal_course_referer) && $SESSION->cal_course_referer != SITEID) {
$course = $DB->get_record('course', array('id'=>$SESSION->cal_course_referer));
$coursecontext = get_context_instance(CONTEXT_COURSE, $SESSION->cal_course_referer);
if (has_capability('moodle/calendar:manageentries', $coursecontext)) {
$allowed->courses = array($course->id => 1);
if(has_capability('moodle/calendar:manageentries', $coursecontext)) {
$allowed->courses = array($course->id => 1);
if ($course->groupmode != NOGROUPS || !$course->groupmodeforce) {
$allowed->groups = groups_get_all_groups($course->id);
}
} else if (has_capability('moodle/calendar:managegroupentries', $coursecontext)) {
if($course->groupmode != NOGROUPS || !$course->groupmodeforce) {
$allowed->groups = groups_get_all_groups($course->id);
}
if($course->groupmode != NOGROUPS || !$course->groupmodeforce) {
$allowed->groups = groups_get_all_groups($SESSION->cal_course_referer);
}
} else if(has_capability('moodle/calendar:managegroupentries', $coursecontext)) {
if($course->groupmode != NOGROUPS || !$course->groupmodeforce) {
$allowed->groups = groups_get_all_groups($SESSION->cal_course_referer, $USER->id);
}
}
}
@@ -1565,11 +1653,8 @@ function calendar_get_allowed_types(&$allowed, $course = null) {
* used to print the "New Event" button
* @return bool
*/
function calendar_user_can_add_event($course) {
if (!isloggedin() || isguestuser()) {
return false;
}
calendar_get_allowed_types($allowed, $course);
function calendar_user_can_add_event() {
calendar_get_allowed_types($allowed);
return (bool)($allowed->user || $allowed->groups || $allowed->courses || $allowed->site);
}
@@ -2375,21 +2460,6 @@ class calendar_information {
$this->year = $year;
}
/**
*
* @param stdClass $course
* @param array $coursestoload An array of courses [$course->id => $course]
* @param type $ignorefilters
*/
public function prepare_for_view(stdClass $course, array $coursestoload, $ignorefilters = false) {
$this->courseid = $course->id;
$this->course = $course;
list($courses, $group, $user) = calendar_set_filters($coursestoload, $ignorefilters);
$this->courses = $courses;
$this->groups = $group;
$this->users = $user;
}
/**
* Ensures the date for the calendar is correct and either sets it to now
* or throws a moodle_exception if not
+22 -26
View File
@@ -6,41 +6,37 @@ require_once('../config.php');
require_once($CFG->dirroot.'/calendar/lib.php');
require_once($CFG->dirroot.'/calendar/preferences_form.php');
$courseid = required_param('course', PARAM_INT);
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
$course = $site = get_site();
if (!empty($SESSION->cal_course_referer)) {
$course = $DB->get_record('course', array('id'=>$SESSION->cal_course_referer), '*', MUST_EXIST);
}
$PAGE->set_url('/calendar/preferences.php', array('id' => $courseid));
$PAGE->set_pagelayout('standard');
$PAGE->set_url('/calendar/preferences.php');
require_login($course);
if ($courseid == SITEID) {
$viewurl = new moodle_url('/calendar/view.php', array('view' => 'month'));
if ($course->id != SITEID) {
require_login($course);
} else {
$viewurl = new moodle_url('/calendar/view.php', array('view' => 'month', 'course' => $courseid));
require_login();
$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM)); //TODO: wrong
}
navigation_node::override_active_url($viewurl);
// Initialize the session variables
calendar_session_vars();
$defaultlookahead = CALENDAR_DEFAULT_UPCOMING_LOOKAHEAD;
if (isset($CFG->calendar_lookahead)) {
$defaultlookahead = intval($CFG->calendar_lookahead);
}
$defaultmaxevents = CALENDAR_DEFAULT_UPCOMING_MAXEVENTS;
if (isset($CFG->calendar_maxevents)) {
$defaultmaxevents = intval($CFG->calendar_maxevents);
}
$prefs = new stdClass;
$prefs->timeformat = get_user_preferences('calendar_timeformat', '');
$prefs->startwday = get_user_preferences('calendar_startwday', calendar_get_starting_weekday());
$prefs->maxevents = get_user_preferences('calendar_maxevents', $defaultmaxevents);
$prefs->lookahead = get_user_preferences('calendar_lookahead', $defaultlookahead);
$prefs->maxevents = get_user_preferences('calendar_maxevents', CALENDAR_UPCOMING_MAXEVENTS);
$prefs->lookahead = get_user_preferences('calendar_lookahead', CALENDAR_UPCOMING_DAYS);
$prefs->persistflt = get_user_preferences('calendar_persistflt', 0);
$form = new calendar_preferences_form();
$form = new calendar_preferences_form($PAGE->url);
$form->set_data($prefs);
if ($data = $form->get_data() && confirm_sesskey()) {
if ($form->is_cancelled()) {
redirect($viewurl);
} else if ($form->is_submitted() && $form->is_validated() && confirm_sesskey()) {
$data = $form->get_data();
if ($data->timeformat != CALENDAR_TF_12 && $data->timeformat != CALENDAR_TF_24) {
$data->timeformat = '';
}
@@ -61,17 +57,17 @@ if ($data = $form->get_data() && confirm_sesskey()) {
}
set_user_preference('calendar_persistflt', intval($data->persistflt));
redirect($viewurl, get_string('changessaved'), 1);
redirect(new moodle_url('/calendar/view.php', array('course'=>$course->id)), get_string('changessaved'), 1);
exit;
}
$strcalendar = get_string('calendar', 'calendar');
$strpreferences = get_string('calendarpreferences', 'calendar');
$PAGE->navbar->add($strpreferences, new moodle_url('/calendar/view.php'));
$PAGE->navbar->add($strpreferences);
$PAGE->set_pagelayout('admin');
$PAGE->set_title("$course->shortname: $strcalendar: $strpreferences");
$PAGE->set_heading($course->fullname);
$PAGE->set_title("$site->shortname: $strcalendar: $strpreferences");
$PAGE->set_heading($COURSE->fullname);
echo $OUTPUT->header();
echo $OUTPUT->heading($strpreferences);
+54 -54
View File
@@ -137,7 +137,8 @@ class core_calendar_renderer extends plugin_renderer_base {
* @return string
*/
public function fake_block_filters($courseid, $day, $month, $year, $view, $courses) {
return html_writer::tag('div', calendar_filter_controls($this->page->url), array('class'=>'calendar_filters filters'));
$getvars = 'id='.$courseid.'&amp;cal_d='.$day.'&amp;cal_m='.$month.'&amp;cal_y='.$year;
return html_writer::tag('div', calendar_filter_controls($view, $getvars, NULL, $courses), array('class'=>'calendar_filters filters'));
}
/**
@@ -215,21 +216,16 @@ class core_calendar_renderer extends plugin_renderer_base {
* @param calendar_information $calendar
* @return string
*/
public function show_day(calendar_information $calendar, moodle_url $returnurl = null) {
if ($returnurl === null) {
$returnurl = $this->page->url;
}
public function show_day(calendar_information $calendar) {
$calendar->checkdate();
$events = calendar_get_upcoming($calendar->courses, $calendar->groups, $calendar->users, 1, 100, $calendar->timestamp_today());
$output = html_writer::start_tag('div', array('class'=>'header'));
if (calendar_user_can_add_event($calendar->course)) {
$output .= $this->add_event_button($calendar->course->id, $calendar->day, $calendar->month, $calendar->year);
if (!isguestuser() && isloggedin() && calendar_user_can_add_event()) {
$output .= $this->add_event_button($calendar->courseid, $calendar->day, $calendar->month, $calendar->year);
}
//$output .= html_writer::tag('label', get_string('dayview', 'calendar'), array('for'=>'cal_course_flt_jump'));
$output .= $this->course_filter_selector($returnurl, get_string('dayview', 'calendar'));
$output .= $this->course_filter_selector(array('from'=>'day', 'cal_d'=>$calendar->day, 'cal_m'=>$calendar->month, 'cal_y'=>$calendar->year), get_string('dayview', 'calendar'));
$output .= html_writer::end_tag('div');
// Controls
$output .= html_writer::tag('div', calendar_top_controls('day', array('id' => $calendar->courseid, 'd' => $calendar->day, 'm' => $calendar->month, 'y' => $calendar->year)), array('class'=>'controls'));
@@ -349,15 +345,12 @@ class core_calendar_renderer extends plugin_renderer_base {
/**
* Displays a month in detail
*
* @global array $CALENDARDAYS
* @param calendar_information $calendar
* @return string
*/
public function show_month_detailed(calendar_information $calendar, moodle_url $returnurl = null) {
global $CFG;
if (empty($returnurl)) {
$returnurl = $this->page->url;
}
public function show_month_detailed(calendar_information $calendar) {
global $CALENDARDAYS;
$date = usergetdate(time());
@@ -403,16 +396,14 @@ class core_calendar_renderer extends plugin_renderer_base {
calendar_events_by_day($events, $calendar->month, $calendar->year, $eventsbyday, $durationbyday, $typesbyday, $calendar->courses);
$output = html_writer::start_tag('div', array('class'=>'header'));
if (calendar_user_can_add_event($calendar->course)) {
$output .= $this->add_event_button($calendar->course->id, null, $calendar->month, $calendar->year);
if(!isguestuser() && isloggedin() && calendar_user_can_add_event()) {
$output .= $this->add_event_button($calendar->courseid, null, $calendar->month, $calendar->year);
}
$output .= get_string('detailedmonthview', 'calendar').': '.$this->course_filter_selector($returnurl);
$output .= get_string('detailedmonthview', 'calendar').': '.$this->course_filter_selector(array('from'=>'month', 'cal_d'=>$calendar->day, 'cal_m'=>$calendar->month, 'cal_y'=>$calendar->year));
$output .= html_writer::end_tag('div', array('class'=>'header'));
// Controls
$output .= html_writer::tag('div', calendar_top_controls('month', array('id' => $calendar->courseid, 'm' => $calendar->month, 'y' => $calendar->year)), array('class'=>'controls'));
$days = calendar_get_days();
$table = new html_table();
$table->attributes = array('class'=>'calendarmonth calendartable');
$table->data = array();
@@ -423,7 +414,7 @@ class core_calendar_renderer extends plugin_renderer_base {
for($i = $display->minwday; $i <= $display->maxwday; ++$i) {
// This uses the % operator to get the correct weekday no matter what shift we have
// applied to the $display->minwday : $display->maxwday range from the default 0 : 6
$cell = new html_table_cell(get_string($days[$i % 7], 'calendar'));
$cell = new html_table_cell(get_string($CALENDARDAYS[$i % 7], 'calendar'));
$cell->header = true;
$header->cells[] = $cell;
}
@@ -432,7 +423,29 @@ class core_calendar_renderer extends plugin_renderer_base {
$week = 1;
$dayweek = $startwday;
// Create an array of all the week days.
$wdays = array(0 => '<strong>'. get_string('sunday', 'calendar'). '</strong>',
1 => '<strong>'. get_string('monday', 'calendar'). '</strong>',
2 => '<strong>'. get_string('tuesday', 'calendar'). '</strong>',
3 => '<strong>'. get_string('wednesday', 'calendar'). '</strong>',
4 => '<strong>'. get_string('thursday', 'calendar'). '</strong>',
5 => '<strong>'. get_string('friday', 'calendar'). '</strong>',
6 => '<strong>'. get_string('saturday', 'calendar'). '</strong>');
// Loop only if the day offset is greater than 0.
// This loop involves shifting the days around until the desired start day
// is at the start of the array.
$daycount = 0;
while ($display->minwday > $daycount++) {
$wdays_end = array_shift($wdays);
array_push($wdays, $wdays_end);
}
// Now we set the (modified) array to the table header to be displayed.
$table->head = $wdays;
$row = new html_table_row(array());
// Paddding (the first week may have blank days in the beginning)
for($i = $display->minwday; $i < $startwday; ++$i) {
$cell = new html_table_cell('&nbsp;');
@@ -441,11 +454,6 @@ class core_calendar_renderer extends plugin_renderer_base {
}
// Now display all the calendar
$weekend = CALENDAR_DEFAULT_WEEKEND;
if (isset($CFG->calendar_weekend)) {
$weekend = intval($CFG->calendar_weekend);
}
for ($calendar->day = 1; $calendar->day <= $display->maxdays; ++$calendar->day, ++$dayweek) {
if($dayweek > $display->maxwday) {
// We need to change week (table row)
@@ -461,7 +469,7 @@ class core_calendar_renderer extends plugin_renderer_base {
$cellclasses = array();
if ($weekend & (1 << ($dayweek % 7))) {
if(CALENDAR_WEEKEND & (1 << ($dayweek % 7))) {
// Weekend. This is true no matter what the exact range is.
$cellclasses[] = 'weekend';
}
@@ -546,20 +554,16 @@ class core_calendar_renderer extends plugin_renderer_base {
* @param calendar_information $calendar
* @return string
*/
protected function filter_selection_table(calendar_information $calendar, moodle_url $returnurl = null) {
protected function filter_selection_table(calendar_information $calendar) {
global $SESSION;
if ($returnurl === null) {
$returnurl = $this->page->url;
}
$output = html_writer::start_tag('div', array('class'=>'filters'));
$output .= html_writer::start_tag('table');
$output .= html_writer::start_tag('tr');
// Global events
$link = new moodle_url(CALENDAR_URL.'set.php', array('var' => 'showglobal', 'return' => $returnurl));
if (calendar_show_event_type(CALENDAR_EVENT_GLOBAL)) {
$link = new moodle_url(CALENDAR_URL.'set.php', array('var'=>'showglobal', 'from'=>'month', 'cal_d'=>$calendar->day, 'cal_m'=>$calendar->month, 'cal_y'=>$calendar->year));
if($SESSION->cal_show_global) {
$output .= html_writer::tag('td', '', array('class'=>'calendar_event_global', 'style'=>'width:8px;'));
$output .= html_writer::tag('td', html_writer::tag('strong', get_string('globalevents', 'calendar')).' '.get_string('shown', 'calendar').' ('.html_writer::link($link, get_string('clickhide', 'calendar')).')');
} else {
@@ -568,8 +572,8 @@ class core_calendar_renderer extends plugin_renderer_base {
}
// Course events
$link = new moodle_url(CALENDAR_URL.'set.php', array('var'=>'showcourses', 'return' => $returnurl));
if (calendar_show_event_type(CALENDAR_EVENT_COURSE)) {
$link = new moodle_url(CALENDAR_URL.'set.php', array('var'=>'showcourses', 'from'=>'month', 'cal_d'=>$calendar->day, 'cal_m'=>$calendar->month, 'cal_y'=>$calendar->year));
if(!empty($SESSION->cal_show_course)) {
$output .= html_writer::tag('td', '', array('class'=>'calendar_event_course', 'style'=>'width:8px;'));
$output .= html_writer::tag('td', html_writer::tag('strong', get_string('courseevents', 'calendar')).' '.get_string('shown', 'calendar').' ('.html_writer::link($link, get_string('clickhide', 'calendar')).')');
} else {
@@ -581,8 +585,8 @@ class core_calendar_renderer extends plugin_renderer_base {
if(isloggedin() && !isguestuser()) {
$output .= html_writer::start_tag('tr');
// Group events
$link = new moodle_url(CALENDAR_URL.'set.php', array('var'=>'showgroups', 'return' => $returnurl));
if (calendar_show_event_type(CALENDAR_EVENT_GROUP)) {
$link = new moodle_url(CALENDAR_URL.'set.php', array('var'=>'showgroups', 'from'=>'month', 'cal_d'=>$calendar->day, 'cal_m'=>$calendar->month, 'cal_y'=>$calendar->year));
if($SESSION->cal_show_groups) {
$output .= html_writer::tag('td', '', array('class'=>'calendar_event_group', 'style'=>'width:8px;'));
$output .= html_writer::tag('td', html_writer::tag('strong', get_string('groupevents', 'calendar')).' '.get_string('shown', 'calendar').' ('.html_writer::link($link, get_string('clickhide', 'calendar')).')');
} else {
@@ -590,8 +594,8 @@ class core_calendar_renderer extends plugin_renderer_base {
$output .= html_writer::tag('td', html_writer::tag('strong', get_string('groupevents', 'calendar')).' '.get_string('hidden', 'calendar').' ('.html_writer::link($link, get_string('clickshow', 'calendar')).')');
}
// User events
$link = new moodle_url(CALENDAR_URL.'set.php', array('var'=>'showuser', 'return' => $returnurl));
if (calendar_show_event_type(CALENDAR_EVENT_USER)) {
$link = new moodle_url(CALENDAR_URL.'set.php', array('var'=>'showuser', 'from'=>'month', 'cal_d'=>$calendar->day, 'cal_m'=>$calendar->month, 'cal_y'=>$calendar->year));
if($SESSION->cal_show_user) {
$output .= html_writer::tag('td', '', array('class'=>'calendar_event_user', 'style'=>'width:8px;'));
$output .= html_writer::tag('td', html_writer::tag('strong', get_string('userevents', 'calendar')).' '.get_string('shown', 'calendar').' ('.html_writer::link($link, get_string('clickhide', 'calendar')).')');
} else {
@@ -613,20 +617,15 @@ class core_calendar_renderer extends plugin_renderer_base {
* @param int $maxevents
* @return string
*/
public function show_upcoming_events(calendar_information $calendar, $futuredays, $maxevents, moodle_url $returnurl = null) {
if ($returnurl === null) {
$returnurl = $this->page->url;
}
public function show_upcoming_events(calendar_information $calendar, $futuredays, $maxevents) {
$events = calendar_get_upcoming($calendar->courses, $calendar->groups, $calendar->users, $futuredays, $maxevents);
$output = html_writer::start_tag('div', array('class'=>'header'));
if (calendar_user_can_add_event($calendar->course)) {
$output .= $this->add_event_button($calendar->course->id);
if (!isguestuser() && isloggedin() && calendar_user_can_add_event()) {
$output .= $this->add_event_button($calendar->courseid);
}
$output .= html_writer::tag('label', get_string('upcomingevents', 'calendar'), array('for'=>'cal_course_flt_jump'));
$output .= $this->course_filter_selector($returnurl);
$output .= $this->course_filter_selector(array('from'=>'upcoming'));
$output .= html_writer::end_tag('div');
if ($events) {
@@ -652,7 +651,7 @@ class core_calendar_renderer extends plugin_renderer_base {
* @param array $getvars
* @return string
*/
protected function course_filter_selector(moodle_url $returnurl, $label=null) {
protected function course_filter_selector(array $getvars = array(), $label=null) {
global $USER, $SESSION, $CFG;
if (!isloggedin() or isguestuser()) {
@@ -673,12 +672,13 @@ class core_calendar_renderer extends plugin_renderer_base {
$courseoptions[$course->id] = format_string($course->shortname);
}
if ($this->page->course->id !== SITEID) {
$selected = $this->page->course->id;
if (is_numeric($SESSION->cal_courses_shown)) {
$selected = $SESSION->cal_courses_shown;
} else {
$selected = '';
}
$select = new single_select(new moodle_url(CALENDAR_URL.'set.php', array('return' => $returnurl, 'var' => 'setcourse')), 'id', $courseoptions, $selected, null);
$getvars['var'] = 'setcourse';
$select = new single_select(new moodle_url(CALENDAR_URL.'set.php', $getvars), 'id', $courseoptions, $selected, null);
$select->class = 'cal_courses_flt';
if ($label !== null) {
$select->label = $label;
+97 -16
View File
@@ -41,26 +41,107 @@
require_once('../config.php');
require_once($CFG->dirroot.'/calendar/lib.php');
$return = required_param('return', PARAM_URL);
$from = required_param('from', PARAM_ALPHA);
$var = required_param('var', PARAM_ALPHA);
$id = optional_param('id', 0, PARAM_INT);
$cal_d = optional_param('cal_d', 0, PARAM_INT);
$cal_m = optional_param('cal_m', 0, PARAM_INT);
$cal_y = optional_param('cal_y', 0, PARAM_INT);
$action = optional_param('action', '', PARAM_ALPHA);
$type = optional_param('type', '', PARAM_ALPHA);
$url = new moodle_url('/calendar/set.php', array('return'=>$return,'var'=>$var));
$url = new moodle_url('/calendar/set.php', array('from'=>$from,'var'=>$var));
if ($id !== 0) {
$url->param('id', $id);
}
if ($cal_d !== 0) {
$url->param('cal_d', $cal_d);
}
if ($cal_m !== 0) {
$url->param('cal_m', $cal_m);
}
if ($cal_y !== 0) {
$url->param('cal_y', $cal_y);
}
if ($action !== 0) {
$url->param('action', $action);
}
if ($type !== 0) {
$url->param('type', $type);
}
$PAGE->set_url($url);
$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM)); //TODO: wrong
switch($var) {
case 'showgroups':
calendar_set_event_type_display(CALENDAR_EVENT_GROUP);
break;
case 'showcourses':
calendar_set_event_type_display(CALENDAR_EVENT_COURSE);
break;
case 'showglobal':
calendar_set_event_type_display(CALENDAR_EVENT_GLOBAL);
break;
case 'showuser':
calendar_set_event_type_display(CALENDAR_EVENT_USER);
break;
// Initialize the session variables
calendar_session_vars();
// Ensure course id passed if relevant
// Required due to changes in view/lib.php mainly (calendar_session_vars())
$courseid = '';
if (!empty($id)) {
$courseid = '&course='.$id;
}
redirect($return);
switch($var) {
case 'setuser':
// Not implemented yet (or possibly at all)
break;
case 'setcourse':
$id = intval($id);
if($id == 0) {
$SESSION->cal_courses_shown = array();
calendar_set_referring_course(0);
}
else if($id == 1) {
$SESSION->cal_courses_shown = calendar_get_default_courses(true);
calendar_set_referring_course(0);
}
else {
if($DB->get_record('course', array('id'=>$id)) === false) {
// There is no such course
$SESSION->cal_courses_shown = array();
calendar_set_referring_course(0);
}
else {
calendar_set_referring_course($id);
$SESSION->cal_courses_shown = $id;
}
}
break;
case 'showgroups':
$SESSION->cal_show_groups = !$SESSION->cal_show_groups;
set_user_preference('calendar_savedflt', calendar_get_filters_status());
break;
case 'showcourses':
$SESSION->cal_show_course = !$SESSION->cal_show_course;
set_user_preference('calendar_savedflt', calendar_get_filters_status());
break;
case 'showglobal':
$SESSION->cal_show_global = !$SESSION->cal_show_global;
set_user_preference('calendar_savedflt', calendar_get_filters_status());
break;
case 'showuser':
$SESSION->cal_show_user = !$SESSION->cal_show_user;
set_user_preference('calendar_savedflt', calendar_get_filters_status());
break;
}
switch($from) {
case 'event':
redirect(CALENDAR_URL.'event.php?action='.$action.'&amp;type='.$type.'&amp;id='.intval($id));
break;
case 'month':
redirect(CALENDAR_URL.'view.php?view=month'.$courseid.'&cal_d='.$cal_d.'&cal_m='.$cal_m.'&cal_y='.$cal_y);
break;
case 'upcoming':
redirect(CALENDAR_URL.'view.php?view=upcoming'.$courseid);
break;
case 'day':
redirect(CALENDAR_URL.'view.php?view=day'.$courseid.'&cal_d='.$cal_d.'&cal_m='.$cal_m.'&cal_y='.$cal_y);
break;
case 'course':
redirect($CFG->wwwroot.'/course/view.php?id='.intval($id));
break;
default:
}
+62 -30
View File
@@ -44,14 +44,16 @@ require_once('../config.php');
require_once($CFG->dirroot.'/course/lib.php');
require_once($CFG->dirroot.'/calendar/lib.php');
$courseid = optional_param('course', SITEID, PARAM_INT);
$courseid = optional_param('course', 0, PARAM_INT);
$view = optional_param('view', 'upcoming', PARAM_ALPHA);
$day = optional_param('cal_d', 0, PARAM_INT);
$mon = optional_param('cal_m', 0, PARAM_INT);
$yr = optional_param('cal_y', 0, PARAM_INT);
$site = get_site();
$url = new moodle_url('/calendar/view.php');
if ($courseid != SITEID) {
if ($courseid !== 0) {
$url->param('course', $courseid);
}
if ($view !== 'upcoming') {
@@ -68,27 +70,34 @@ if ($yr !== 0) {
}
$PAGE->set_url($url);
if ($courseid != SITEID && !empty($courseid)) {
$course = $DB->get_record('course', array('id' => $courseid));
$courses = array($course->id => $course);
$issite = false;
navigation_node::override_active_url(new moodle_url('/course/view.php', array('id' => $course->id)));
//TODO: the courseid handling in /calendar/ is a bloody mess!!!
if ($courseid && $courseid != SITEID) {
require_login($courseid);
} else if ($CFG->forcelogin) {
$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM)); //TODO: wrong
require_login();
} else {
$course = get_site();
$courses = calendar_get_default_courses();
$issite = true;
$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM)); //TODO: wrong
}
require_course_login($course);
$calendar = new calendar_information($day, $mon, $yr);
$calendar->prepare_for_view($course, $courses);
$calendar->courseid = $courseid;
// Initialize the session variables
calendar_session_vars();
//add_to_log($course->id, "course", "view", "view.php?id=$course->id", "$course->id");
$now = usergetdate(time());
$pagetitle = '';
$strcalendar = get_string('calendar', 'calendar');
if (!checkdate($mon, $day, $yr)) {
$link = calendar_get_link_href(new moodle_url(CALENDAR_URL.'view.php', array('view'=>'upcoming', 'course'=>$courseid)),
$now['mday'], $now['mon'], $now['year']);
$PAGE->navbar->add($strcalendar, $link);
if(!checkdate($mon, $day, $yr)) {
$day = intval($now['mday']);
$mon = intval($now['mon']);
$yr = intval($now['year']);
@@ -108,12 +117,47 @@ switch($view) {
$pagetitle = get_string('upcomingevents', 'calendar');
break;
}
// If a course has been supplied in the URL, change the filters to show that one
if (!empty($courseid)) {
if ($course = $DB->get_record('course', array('id'=>$courseid))) {
if ($course->id == SITEID) {
// If coming from the home page, show all courses
$SESSION->cal_courses_shown = calendar_get_default_courses(true);
calendar_set_referring_course(0);
} else {
// Otherwise show just this one
$SESSION->cal_courses_shown = $course->id;
calendar_set_referring_course($SESSION->cal_courses_shown);
}
}
} else {
$course = null;
}
if (!isloggedin() or isguestuser()) {
$defaultcourses = calendar_get_default_courses();
calendar_set_filters($calendar->courses, $calendar->groups, $calendar->users, $defaultcourses, $defaultcourses);
} else {
calendar_set_filters($calendar->courses, $calendar->groups, $calendar->users);
}
// Let's see if we are supposed to provide a referring course link
// but NOT for the "main page" course
if ($SESSION->cal_course_referer != SITEID &&
($shortname = $DB->get_field('course', 'shortname', array('id'=>$SESSION->cal_course_referer))) !== false) {
require_login(); //TODO: very wrong!!
if (empty($course)) {
$course = $DB->get_record('course', array('id'=>$SESSION->cal_course_referer)); // Useful to have around
}
}
$strcalendar = get_string('calendar', 'calendar');
$prefsbutton = calendar_preferences_button();
// Print title and header
$PAGE->set_pagelayout('standard');
$PAGE->set_title("$course->shortname: $strcalendar: $pagetitle");
$PAGE->set_title("$site->shortname: $strcalendar: $pagetitle");
$PAGE->set_heading($COURSE->fullname);
$PAGE->set_button(calendar_preferences_button($course));
$PAGE->set_button($prefsbutton);
$PAGE->set_pagelayout('standard');
$renderer = $PAGE->get_renderer('core_calendar');
$calendar->add_sidecalendar_blocks($renderer, true, $view);
@@ -130,18 +174,7 @@ switch($view) {
echo $renderer->show_month_detailed($calendar);
break;
case 'upcoming':
$defaultlookahead = CALENDAR_DEFAULT_UPCOMING_LOOKAHEAD;
if (isset($CFG->calendar_lookahead)) {
$defaultlookahead = intval($CFG->calendar_lookahead);
}
$lookahead = get_user_preferences('calendar_lookahead', $defaultlookahead);
$defaultmaxevents = CALENDAR_DEFAULT_UPCOMING_MAXEVENTS;
if (isset($CFG->calendar_maxevents)) {
$defaultmaxevents = intval($CFG->calendar_maxevents);
}
$maxevents = get_user_preferences('calendar_maxevents', $defaultmaxevents);
echo $renderer->show_upcoming_events($calendar, $lookahead, $maxevents);
echo $renderer->show_upcoming_events($calendar, get_user_preferences('calendar_lookahead', CALENDAR_UPCOMING_DAYS), get_user_preferences('calendar_maxevents', CALENDAR_UPCOMING_MAXEVENTS));
break;
}
@@ -151,12 +184,11 @@ if (!empty($CFG->enablecalendarexport)) {
echo $OUTPUT->single_button(new moodle_url('export.php', array('course'=>$courseid)), get_string('exportcalendar', 'calendar'));
if (isloggedin()) {
$authtoken = sha1($USER->username . $USER->password . $CFG->calendar_exportsalt);
$link = new moodle_url('/calendar/export_execute.php', array('preset_what'=>'all', 'prest_time'=>'recentupcoming', 'username'=>$USER->username, 'authtoken'=>$authtoken));
$link = new moodle_url('/calendar/export_execute.php', array('preset_what'=>'all', 'preset_time'=>'recentupcoming', 'username'=>$USER->username, 'authtoken'=>$authtoken));
$icon = html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('i/ical'), 'height'=>'14', 'width'=>'36', 'alt'=>get_string('ical', 'calendar'), 'title'=>get_string('quickdownloadcalendar', 'calendar')));
echo html_writer::tag('a', $icon, array('href'=>$link));
}
}
echo $OUTPUT->container_end();
echo html_writer::end_tag('div');
echo $renderer->complete_layout();
-2
View File
@@ -62,8 +62,6 @@ $PAGE->set_heading($COURSE->fullname);
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('assignto', 'cohort', format_string($cohort->name)));
echo $OUTPUT->notification(get_string('removeuserwarning', 'core_cohort'));
// Get the user_selector we will need.
$potentialuserselector = new cohort_candidate_selector('addselect', array('cohortid'=>$cohort->id));
$existinguserselector = new cohort_existing_selector('removeselect', array('cohortid'=>$cohort->id));
+2 -2
View File
@@ -94,12 +94,12 @@ if ($delete and $cohort->id) {
$editoroptions = array('maxfiles'=>0, 'context'=>$context);
if ($cohort->id) {
// edit existing
$cohort = file_prepare_standard_editor($cohort, 'description', $editoroptions);
$cohort = file_prepare_standard_editor($cohort, 'description', $editoroptions, $context);
$strheading = get_string('editcohort', 'cohort');
} else {
// add new
$cohort = file_prepare_standard_editor($cohort, 'description', $editoroptions);
$cohort = file_prepare_standard_editor($cohort, 'description', $editoroptions, $context);
$strheading = get_string('addcohort', 'cohort');
}

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