Compare commits

..

761 Commits

Author SHA1 Message Date
Eloy Lafuente (stronk7) b15cd07d4b Moodle release 2.1.2 2011-10-09 00:49:42 +02:00
Eloy Lafuente (stronk7) ecbd8716f6 weekly release 2.1.1+ 2011-10-07 00:11:22 +02:00
Eloy Lafuente (stronk7) 7820e5047d fix permissions 2011-10-07 00:06:23 +02:00
Eloy Lafuente (stronk7) c4101db016 Merge branch 'install_21_STABLE' of git://github.com/amosbot/moodle into MOODLE_21_STABLE 2011-10-07 00:05:07 +02:00
AMOS bot d1582f14d5 Automatically generated installer lang files 2011-10-06 00:55:37 +00:00
Aparup Banerjee e153abc018 Merge branch 'wip-MDL-28615-m21-squashed' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-10-05 14:52:45 +08:00
Eloy Lafuente (stronk7) f1ae261bc9 Merge branch 'MDL-28469_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-10-05 01:14:47 +02:00
Eloy Lafuente (stronk7) 19fcc09ac7 Merge branch 'wip-MDL-25697-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-10-05 01:10:24 +02:00
Sam Hemelryk 82bd683018 MDL-28615 forum: Fixed up a couple of minor regressions 2011-10-05 11:09:28 +13:00
Eloy Lafuente (stronk7) 19c8fd9e8b Merge branch 'MDL-29644_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-10-04 23:40:23 +02:00
Tim Hunt 0bfc2dde8f MDL-29644 qtype multianswer, hints lost doing Moodle XML export.
This commit also includes a lot of useful tidying up of some of the unit
test helper code. I turned out that I could not use all the helper code
in my new tests, but despite that it will be useful in the future, so I
am committing it here.
2011-10-04 22:28:35 +01:00
Eloy Lafuente (stronk7) 807f806ed7 Merge branch 'MDL-27857-assignment-portfolio_21_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_21_STABLE 2011-10-04 12:46:24 +02:00
Eloy Lafuente (stronk7) 85dd2a674a Merge branch 'MDL-29548_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-10-04 12:37:45 +02:00
Tim Hunt fa8843c424 MDL-29548 allow message plugins to control message
defaults.

At the moment, each message_provider can specify defaults for
each message output, to say whether that message output should be
used for this type of message:
http://docs.moodle.org/dev/Messaging_2.0#Adding_new_message_type.

If the message provider does not set a default, this change allows
the message output to set the default.
2011-10-04 11:24:43 +01:00
Eloy Lafuente (stronk7) fdca6e8321 Merge branch 'MDL-19575-m21' of git://github.com/ankitagarwal/moodle into MOODLE_21_STABLE 2011-10-04 12:12:33 +02:00
Tim Hunt ae3056cb00 MDL-29520 question engine: work-around bad MySQL delete performance.
This is a temporary fix, until the new API from MDL-29589 is available.

(amended to fix comments)
2011-10-04 12:05:04 +02:00
Tim Hunt 74969d8866 MDL-29571 questions: improve class=accesshide screen-reader hints.
This changes the hint that comes before the question text. There are
unit tests to verify the new behaviour.

(amended to fix comments)
2011-10-04 11:53:07 +02:00
Tim Hunt 5e69fe4971 MDL-29571 qtype description refactor unit test code a bit. 2011-10-04 11:52:20 +02:00
Sam Hemelryk 133173e213 Merge branch 'MDL-29621_21_wip' of git://github.com/grabs/moodle into MOODLE_21_STABLE 2011-10-04 17:56:39 +13:00
Sam Hemelryk 747d6b5aac MDL-28615 forum: Fixed missing context regression 2011-10-04 16:37:04 +13:00
Sam Hemelryk 91a7a788aa Merge branch 'MDL-28725_wiki_section2_21' of git://github.com/andyjdavis/moodle into MOODLE_21_STABLE 2011-10-04 16:21:33 +13:00
Eloy Lafuente (stronk7) c3a4009a56 Merge branch 'MDL-29511_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-10-04 01:11:48 +02:00
Eloy Lafuente (stronk7) f0837f65d8 Merge branch 'MDL-29216_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-10-03 22:55:56 +02:00
Eloy Lafuente (stronk7) a70eda6cc8 Merge branch 'MDL-29341_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-10-03 22:50:30 +02:00
Eloy Lafuente (stronk7) c5c9be022d Merge branch 'MDL-29570_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-10-03 21:42:55 +02:00
Andreas Grabs 96909b1597 MDL-29621 - XHTML not welformed when creating Feedback questions 2011-10-03 18:44:55 +02:00
Tim Hunt 8f40d27954 MDL-28469 quiz settings pages should be pagelayout admin. 2011-10-03 16:38:59 +01:00
David Mudrak 59c8be2362 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.
2011-10-03 10:13:11 +02:00
David Mudrak f289c698a9 MDL-27857 Typo in the phpDocs fixed 2011-10-03 10:13:11 +02:00
David Mudrak daf4471a40 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.
2011-10-03 10:13:10 +02:00
Aparup Banerjee b056fee5ba MDL-26486 Lesson : fixed whitespace 2011-10-03 16:01:36 +08:00
Aparup Banerjee c6e321ccaf Merge branch 'MDL-26486_m21' of git://github.com/rwijaya/moodle into MOODLE_21_STABLE 2011-10-03 16:01:00 +08:00
Andrew Davis (andyjdavis) f6705d681a MDL-27640 rating: altered the return url provided by mod_data to ratings 2011-10-03 15:25:00 +08:00
Aparup Banerjee 30ed26a576 Merge branch 'wip-MDL-27867-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-10-03 14:29:46 +08:00
Aparup Banerjee 1e6c738c6c MDL-29541 Administration : fixed whitespace 2011-10-03 14:04:08 +08:00
Aparup Banerjee 4cb89f4df4 Merge branch 'wip-mdl-29244-m21' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-10-03 13:54:09 +08:00
Rajesh Taneja 1f2d15dc62 MDL-29244 Users: Fixed filter for selecting users who never logged in and course roles dropdown show all revelent roles 2011-10-03 13:46:39 +08:00
Sam Hemelryk 7d9cb204be Merge branch 'MDL-29296_m21' of git://github.com/rwijaya/moodle into MOODLE_21_STABLE 2011-10-03 17:08:51 +13:00
Sam Hemelryk e6f5ebe25b Merge branch 'MDL-29605-M21' of git://github.com/lazydaisy/moodle into MOODLE_21_STABLE 2011-10-03 16:43:09 +13:00
Sam Hemelryk 6eeb293e04 Merge branch 'wip-mdl-29539-m21' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-10-03 15:09:53 +13:00
Sam Hemelryk 124414cc5e MDL-28566 theme_base: removed MDL comment 2011-10-03 15:01:06 +13:00
Sam Hemelryk 69a62c2646 Merge branch 'MDL-28566-M21' of git://github.com/lazydaisy/moodle into MOODLE_21_STABLE 2011-10-03 14:37:54 +13:00
Sam Hemelryk add033dafe Merge branch 'MDL-29323-M21' of git://github.com/lazydaisy/moodle into MOODLE_21_STABLE 2011-10-03 14:30:12 +13:00
Sam Hemelryk 90e44b5068 Merge branch 'wip-MDL-25454-MOODLE_21_STABLE' of git://github.com/marinaglancy/moodle into MOODLE_21_STABLE 2011-10-03 14:24:18 +13:00
Sam Hemelryk bf49e4404c Merge branch 'MDL-29558_2_1' of git://github.com/jamiepratt/moodle into MOODLE_21_STABLE 2011-10-03 14:04:47 +13:00
AMOS bot e4346a63ba Automatically generated installer lang files 2011-10-03 00:55:29 +00:00
Eloy Lafuente (stronk7) e438ff9942 MDL-29552 themes - show the name of the picked theme when working with device detection enabled 2011-10-03 13:30:09 +13:00
Sam Hemelryk ddf0d0dcd7 Merge branch 'MDL-29567_21' of git://github.com/stronk7/moodle into MOODLE_21_STABLE 2011-10-03 13:23:24 +13:00
Sam Hemelryk d85d6ccd3e Merge branch 'MDL-29566_21' of git://github.com/stronk7/moodle into MOODLE_21_STABLE 2011-10-03 12:49:54 +13:00
Sam Hemelryk bd90c5891f Merge branch 'MDL-29618_21' of git://github.com/stronk7/moodle into MOODLE_21_STABLE 2011-10-03 12:28:05 +13:00
Dan Poltawski e58c72d050 MDL-27295 Course Category View - Only display count when more than 0 courses 2011-10-03 11:52:09 +13:00
Eloy Lafuente (stronk7) 77be201a0f MDL-29618 backup - back to handling enrolments properly. Regession of MDL-26841, my fault, grrr 2011-10-03 00:47:28 +02:00
Sam Hemelryk 73a48291b3 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:23:56 +13:00
Mary Evans cb7699c3a9 MDL-29605-modify Afterburner menu to allow auto format 2011-10-01 23:20:29 +01:00
Tim Hunt 22ba72591c MDL-29216 multianswer qtype needs intereactive elements on the form. 2011-10-01 00:09:27 +01:00
Tim Hunt 41be2f3587 MDL-29341 qtype numerical/calc: display of mc units badly laid out. 2011-09-30 23:42:27 +01:00
Kordan 7bbad2e268 MDL-29403 fix for M21 2011-09-30 11:15:52 +02:00
Jamie Pratt fc15f0837a MDL-29558 question preview: limit variants drop-down to the first 100
In situations when question has many variants.
2011-09-30 09:43:26 +07:00
Mary Evans 9d0cc2cb4c MDL-29323-FIX invalid border style 2011-09-30 03:16:32 +01:00
AMOS bot f058ea24c9 Automatically generated installer lang files 2011-09-30 00:55:21 +00:00
Tim Hunt b99d21aaa9 MDL-29511 cannot review previous steps of a question attempt since MDL-28679. 2011-09-29 21:53:41 +01:00
Tim Hunt 778854eef5 MDL-29511 Fix problems on the quiz review questions page found while investigating this bug. 2011-09-29 21:53:40 +01:00
Marina Glancy 5c6377900a MDL-25454: using the faster way to check if record exists in db 2011-09-29 17:06:37 +08:00
Andrew Davis (andyjdavis) a00b84e864 MDL-28725 wiki: added urlencode around the section variable when it is being used to construct URLs 2011-09-29 16:49:52 +08:00
Andrew Davis (andyjdavis) 667ffef155 MDL-28725 wiki: added missing string
AMOS BEGIN
 CPY [invalidsection,core_admin],[invalidsection,mod_wiki]
AMOS END
2011-09-29 16:49:43 +08:00
Tim Hunt 8258ddff3b MDL-29570 Quiz editing page displays the wrong time in the status line sometimes. 2011-09-29 09:06:41 +01:00
Rossiani Wijaya 03fb10da20 MDL-26486 lesson mod: fixed grade report error on matching and shortanswers questions. 2011-09-29 13:05:50 +08:00
Ankit Kumar Agarwal 342f224f03 MDL-19575 Global Search Adding capability checks to the search and stat pages 2011-09-29 09:09:54 +05:30
Marina Glancy 0623443356 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:02:08 +08:00
Rajesh Taneja 4a313905bc MDL-29539 HTML Editor: Fixed XHTML formatting for editor 2011-09-29 09:36:22 +08:00
Sam Hemelryk 9c36051feb MDL-28615 mod_forum: Fixed the users page that shows all of the users posts 2011-09-29 14:21:15 +13:00
Sam Hemelryk fa447a513e MDL-25697 theme_base: Improved the alignment of the activity editing icons on the course frontpage 2011-09-29 14:15:24 +13:00
AMOS bot 037afad8c3 Automatically generated installer lang files 2011-09-29 00:55:41 +00:00
Eloy Lafuente (stronk7) 72a32ea968 MDL-29567 postgresql - handle negative defaults in numerical cols properly 2011-09-29 01:22:31 +02:00
Eloy Lafuente (stronk7) 21973a92a4 MDL-29567 unit tests - add some tests to cover negative defaults in numerical cols 2011-09-29 01:22:21 +02:00
Eloy Lafuente (stronk7) af9a00d398 MDL-29566 mysql - length / decimal specs in float columns are optional 2011-09-29 00:33:18 +02:00
Eloy Lafuente (stronk7) 3264974513 MDL-29566 unit tests - add some tests to cover get_columns() with number/float columns 2011-09-29 00:33:15 +02:00
Sam Hemelryk 214784a4af MDL-27867 course: Course and category theme selectors no longer show theme's that should be hidden from the selector 2011-09-29 10:47:52 +13:00
Mary Evans b15ab7630c MDL-28566 - Fix for participants user details 2011-09-28 15:45:20 +01:00
Eloy Lafuente (stronk7) 3973662145 weekly release 2.1.1+ 2011-09-28 11:08:00 +02:00
Eloy Lafuente (stronk7) f7bb84df23 Merge branch 'install_21_STABLE' of git://github.com/amosbot/moodle into MOODLE_21_STABLE 2011-09-28 11:04:28 +02:00
AMOS bot fc316236f5 Automatically generated installer lang files 2011-09-28 00:55:21 +00:00
Aparup Banerjee e9be98eed2 Merge branch 'MDL-29230_m21' of git://github.com/rwijaya/moodle into MOODLE_21_STABLE 2011-09-27 15:00:49 +08:00
Aparup Banerjee ca92a99a2e Merge branch 'MDL-25241_forum_search_ratings_21' of git://github.com/andyjdavis/moodle into MOODLE_21_STABLE 2011-09-27 11:35:44 +08:00
Sam Hemelryk d021250bf0 Merge branch 'm21_MDL-29519' of git://github.com/danmarsden/moodle into MOODLE_21_STABLE 2011-09-27 14:09:50 +13:00
Eloy Lafuente (stronk7) 2b4dcfdcbd Merge branch 'MDL-28686-21' of git://github.com/bostelm/moodle into MOODLE_21_STABLE 2011-09-27 00:54:49 +02:00
Sam Hemelryk fe245b725b Merge branch 'MDL-28424_21' of git://github.com/timhunt/moodle.git with changes 2011-09-27 11:26:37 +13:00
Eloy Lafuente (stronk7) 3dba01a40f Merge branch 'w38_MDL-29535_m21_filters' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-09-26 23:57:30 +02:00
Petr Skoda 5cac28fb2b MDL-29535 fix support for custom filter settings in contrib filters 2011-09-26 23:49:58 +02:00
Eloy Lafuente (stronk7) dc110687c8 Merge branch 'MDL-29462_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-09-26 22:42:09 +02:00
Eloy Lafuente (stronk7) 0518140c31 Merge branch 'MDL-28202_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-09-26 22:28:47 +02:00
Eloy Lafuente (stronk7) 4d7a9cd8f5 Merge branch 'MDL-29427_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-09-26 22:01:35 +02:00
Eloy Lafuente (stronk7) ba1afa0d95 Merge branch 'MDL-29528_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-09-26 21:44:49 +02:00
Tim Hunt f8431a1933 MDL-29528 qtype multichoice and caclulated combined feedback format overwritten during upgrade. 2011-09-26 13:39:11 +01:00
Aparup Banerjee 3cef27bf9f Merge branch 'MDL-29270-question-grade_21_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_21_STABLE 2011-09-26 17:04:28 +08:00
Rossiani Wijaya 9551f03606 MDL-29296 lesson mod: fixed regression for continue button on last lesson page. 2011-09-26 16:40:39 +08:00
Aparup Banerjee 8daff43635 Merge branch 'wip-MDL-29487-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-09-26 16:01:11 +08:00
Aparup Banerjee e90206aaa4 Merge branch 'MDL-29464_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-09-26 14:49:21 +08:00
Aparup Banerjee b967bf6005 Merge branch 'MDL-29333_rating_ajax_21' of git://github.com/andyjdavis/moodle into MOODLE_21_STABLE 2011-09-26 14:07:25 +08:00
Sam Hemelryk ded9134e03 Merge branch 'MDL-29428_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-09-26 14:04:15 +13:00
AMOS bot 9d7b02bec0 Merge branch 'MOODLE_21_STABLE' into install_21_STABLE 2011-09-26 00:55:32 +00:00
Sam Hemelryk d496829c61 Merge branch 'MDL-29484_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-09-26 13:55:27 +13:00
Sam Hemelryk 9c43f8f7e1 Merge branch 'MDL-29493_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-09-26 13:48:11 +13:00
Dan Marsden 7af777217d MDL-29519 move plagiarism cron to after event queue 2011-09-26 13:16:28 +13:00
Sam Hemelryk 585bd02479 Merge branch 'MDL-29336-numerrors-mapping-21_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_21_STABLE 2011-09-26 12:36:46 +13:00
Sam Hemelryk d7749a10a6 Merge branch 'MDL-29478_21' of git://github.com/stronk7/moodle into MOODLE_21_STABLE 2011-09-26 10:53:10 +13:00
Sam Hemelryk 65072bfdc2 Merge branch 'MDL-29139_m21' of git://github.com/nebgor/moodle into MOODLE_21_STABLE 2011-09-26 10:45:40 +13:00
Sam Hemelryk 9f05075c61 Merge branch 'MDL-29190_21_wip' of git://github.com/grabs/moodle into MOODLE_21_STABLE 2011-09-26 10:39:26 +13:00
Jean-Michel Vedrine ef4cf39174 MDL-29270 Fixed question bank backup converter (field rename) 2011-09-25 23:30:40 +02:00
Eloy Lafuente (stronk7) 7294a0649b weekly release 2.1.1+ (emergency) 2011-09-25 17:26:40 +02:00
Eloy Lafuente (stronk7) 9c49600397 MDL-29512 Revert "MDL-25937 Froms Library: Added server side validation for filepicker and filemanager"
This reverts commit b19539bf44.
2011-09-25 17:14:47 +02:00
Eloy Lafuente (stronk7) 0a5afc0583 MDL-29512 Revert "MDL-25937 Forms Library: Added Javascript validation for filepicker and filemanager. Also fixed disbledif rule check for both"
This reverts commit 1f552b4c48.
2011-09-25 17:14:33 +02:00
AMOS bot 2de4e3872c Automatically generated installer lang files 2011-09-25 00:55:21 +00:00
AMOS bot d73581da42 Automatically generated installer lang files 2011-09-24 00:55:24 +00:00
Andreas Grabs dbd388acef MDL-29190 - XHTML not well formed in show_nonrespondents.php 2011-09-23 18:54:18 +02:00
Tim Hunt 51fd4dd261 MDL-29493 questions should be createable with defaultmark a float. 2011-09-23 12:52:39 +01:00
Tim Hunt dddcaf6b6b MDL-29484 qformat xml tests failing. 2011-09-23 12:09:31 +01:00
Sam Hemelryk 8710d49bec MDL-29487 enrol: Fixed typo in enrol_sharing_course 2011-09-23 18:18:10 +12:00
Rossiani Wijaya a672bd8ad5 MDL-29230 lesson_module: fixed question's answer to have 0 value. 2011-09-23 14:10:12 +08:00
Eloy Lafuente (stronk7) 4d1e35d8c0 MDL-29478 unittest - fix rating tests so they can be executed with accesslib caches cleaned 2011-09-23 01:48:09 +02:00
Eloy Lafuente (stronk7) 7bfc279ffb MDL-29478 unittest - explicity include blog/lib.php. Was causing "random" errors 2011-09-23 01:37:58 +02:00
Eloy Lafuente (stronk7) cb59f50fb8 MDL-29478 blog - fixed some recent regressions introduced by MDL-29186 2011-09-23 00:06:10 +02:00
Tim Hunt 5d81093e3c MDL-29427 quiz nav: information items should should have a state tooltip 2011-09-22 18:13:11 +01:00
Tim Hunt a9384ab0d0 MDL-29428 quiz navigation panel should use 'This page' (accessibility improvement) 2011-09-22 17:56:35 +01:00
Kyle Temkin 18d81bdb3c MDL-28202 qtype_calculated fix edge case in the rounding code. 2011-09-22 12:14:44 +01:00
Andrew Davis (andyjdavis) 4b5c0b461c MDL-25241 forum: reimplemented the display of ratings on the forum search page 2011-09-22 15:30:05 +08:00
Aparup Banerjee 0047a8f47d MDL-29139 Forms Library : fixed missing require_once 2011-09-22 14:56:40 +08:00
David Mudrak a39eb49fc2 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:17:44 +02:00
Andrew Davis (andyjdavis) cfb909d013 MDL-29333 rating: prevent the ratings JS from being intialized multiple times 2011-09-22 10:23:26 +08:00
Andrew Davis (andyjdavis) 81fa243ea4 MDL-29333 rating: refactored the ratings ajax 2011-09-22 10:23:15 +08:00
AMOS bot 747d4d3e25 Automatically generated installer lang files 2011-09-22 00:55:33 +00:00
Tim Hunt 74ca90e5fb MDL-29464 quiz add random question popup does not update sumgrades. 2011-09-21 16:43:05 +01:00
Tim Hunt 4e92a71fb3 MDL-29462 html_to_text('0') gives '', not '0'. 2011-09-21 16:42:33 +01:00
Tim Hunt e6674da8ff MDL-28424 Reviewing a quiz in 'secure mode' gives a fatal error.
The problem was when output was being started in relation to when the fake block was added.

Took the opportunity to clean up the quiz renderer API a bit.
2011-09-21 16:41:36 +01:00
Eloy Lafuente (stronk7) 136fa79e34 weekly release 2.1.1+ 2011-09-21 17:11:46 +02:00
Eloy Lafuente (stronk7) 06a22aecb7 Merge branch 'install_21_STABLE' of git://github.com/amosbot/moodle into MOODLE_21_STABLE 2011-09-21 17:04:43 +02:00
AMOS bot f7cf17a853 Automatically generated installer lang files 2011-09-21 00:55:20 +00:00
Eloy Lafuente (stronk7) e63827ad98 Merge branch 'MDL-26567_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-09-21 00:11:14 +02:00
Tim Hunt 84de2336fb 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:15:07 +01:00
Eloy Lafuente (stronk7) 7f0d91d546 Merge branch 'wip-mdl-29079-m21' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-09-20 09:51:18 +02:00
Aparup Banerjee 14312ebc6a Merge branch 'MDL-26890-m21' of git://github.com/ankitagarwal/moodle into MOODLE_21_STABLE 2011-09-20 13:17:00 +08:00
Ankit Kumar Agarwal 292faa4f7d Forums check on filesize if the file is added to the forum from private area 2011-09-20 10:05:36 +05:30
Rajesh Taneja e93bb0ca52 MDL-29079 Administration: Added space on both sides of locked checkbox and for rtl language space will be applied accordingly 2011-09-20 11:50:46 +08:00
Aparup Banerjee a886ad10ea Merge branch 'wip-mdl-28726-m21' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-09-20 10:20:38 +08:00
Sam Hemelryk c4b234ec54 Merge branch 'MDL-26841_21' of git://github.com/stronk7/moodle into MOODLE_21_STABLE 2011-09-20 12:13:48 +12:00
Sam Hemelryk 6831c9ff36 Merge branch 'MDL-29392_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-09-20 11:58:23 +12:00
Colin Chambers 6a49c01825 MDL-29394 form editor - Use hidden field when only 1 format option is available #947 2011-09-20 00:36:35 +02:00
Eloy Lafuente (stronk7) 0ff54e134f Merge branch 'wip-mdl-29079-m21' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-09-20 00:17:42 +02:00
Eloy Lafuente (stronk7) 5af8bbf854 Merge branch 'MDL-28679_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-09-20 00:04:17 +02:00
Eloy Lafuente (stronk7) 75ebacb1ec Merge branch 'MDL-29126_export_separator_21' of git://github.com/andyjdavis/moodle into MOODLE_21_STABLE 2011-09-19 23:37:49 +02:00
M Kassaei 1859247e0c MDL-29392 grade/report/index.php should use $CFG->grade_profilereport 2011-09-19 11:32:18 +01:00
Eloy Lafuente (stronk7) f199117f05 MDL-26841 backup - prevent any enrolments info to be handled in IMPORT/HUB operations 2011-09-19 11:24:24 +02:00
Aparup Banerjee bc24c20388 Merge branch 's13_MDL-29036_ws_upload_21' of git://github.com/dongsheng/moodle into MOODLE_21_STABLE 2011-09-19 16:13:31 +08:00
Dongsheng Cai 4e970a5335 MDL-29036 WEBSERVICE : webservice upload script should respect maxbytes and userquota settings 2011-09-19 15:29:13 +08:00
Sam Hemelryk 955f15a71f Merge branch 'MDL-29366_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-09-19 19:20:17 +12:00
Sam Hemelryk 5585910ea7 Merge branch 'MDL-28329_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-09-19 18:36:55 +12:00
Rajesh Taneja 1b17be9050 MDL-29079 Administration: Added space between checkboxes on general backup setting page 2011-09-19 13:35:56 +08:00
Sam Hemelryk 26c28d0821 Merge branch 'wip-mdl-25937-m21' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-09-19 17:00:40 +12:00
Aparup Banerjee 8104e0f2df Merge branch 's13_MDL-28509_youtube_21' of github.com:dongsheng/moodle into MOODLE_21_STABLE 2011-09-19 12:15:00 +08:00
Dongsheng Cai 4ded0afd16 MDL-28509 repository : fixed youtube repository search keyword 2011-09-19 11:57:14 +08:00
Mark Johnson 2e348a6643 MDL-28509 repository_youtube Enable selection of sort order 2011-09-19 11:57:01 +08:00
Petr Skoda 84cae7bef8 MDL-29406 fix greedy config settings cleanup 2011-09-19 13:33:08 +12:00
Sam Hemelryk 3d2029f3d4 Merge branch 'MDL-29360_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-09-19 11:57:58 +12:00
KNDeepa 9acc5736a8 MDL-28329 local_qeupgradehelper make cron work. 2011-09-16 18:44:06 +01:00
Tim Hunt 08d1ba7106 MDL-28679 question response history displays states incorrectly. 2011-09-16 16:05:59 +01:00
Tim Hunt e9197a3711 MDL-29366 qtype_essay import/export as Moodle XML loses files from graderinfo 2011-09-16 12:00:40 +01:00
Tim Hunt 4394f91b26 MDL-29360 quiz comment.php has broken JS for the Cancel button.
This swtichest it to more modern YUI3 approach.
2011-09-16 12:00:03 +01:00
Tim Hunt 25aa44ea97 MDL-28259 Individual answers Feedback not shown in Cloze questions 2011-09-16 11:59:02 +01:00
Rajesh Taneja f9d4ab44e0 MDL-28726 wiki-2.0: Fixed XSS in wiki comments 2011-09-16 11:10:27 +08:00
Rajesh Taneja 1f552b4c48 MDL-25937 Forms Library: Added Javascript validation for filepicker and filemanager. Also fixed disbledif rule check for both 2011-09-16 09:18:23 +08:00
Rajesh Taneja b19539bf44 MDL-25937 Froms Library: Added server side validation for filepicker and filemanager 2011-09-16 09:18:23 +08:00
Eloy Lafuente (stronk7) ce0cb2451b weekly release 2.1.1+ 2011-09-16 01:38:33 +02:00
Eloy Lafuente (stronk7) 929c1e4a8b Merge branch 'install_21_STABLE' of git://github.com/amosbot/moodle into MOODLE_21_STABLE 2011-09-16 01:34:34 +02:00
Eloy Lafuente (stronk7) 7923d63b16 MDL-29093 auth - help string now specifies MNet exception. Thanks Helen! 2011-09-14 11:37:31 +02:00
Eloy Lafuente (stronk7) efb0aacf37 MDL-29093 auth - help string changed to VBFET suggestion
(very best favourite english translator, aka. Helen :-P)
2011-09-14 10:12:17 +02:00
Sam Hemelryk 9e312ed269 MDL-29188 course_formats Fixed up formatting of section name within navigation 2011-09-14 11:41:36 +12:00
Sam Hemelryk 6aa9352f66 MDL-29093 - Authentication improved new setting name and strings 2011-09-14 00:30:26 +02:00
Iñaki Arenaza 2023ca1f0f MDL-29093 - Authentication for authentication only, not for user creation
There are cases when a moodle installation needs to only deal
user authentication and not user creation (this is especially
interesting when using external authentication sources such as LDAP,
CAS, etc.)

Add an option to prevent automatic user creation if the administrator
does't want users to be automatically created.

Signed-off-by: Iñaki Arenaza <iarenaza@mondragon.edu>
2011-09-14 00:30:17 +02:00
Petr Skoda 6f1156a6c2 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:33 +02:00
Aparup Banerjee a7cb1e62f4 MDL-26257 Authentication : whitespace/style fixes 2011-09-13 19:15:48 +08:00
Aparup Banerjee edb8077e7b Merge branch 'MDL-26257-21' of git://github.com/bostelm/moodle into MOODLE_21_STABLE 2011-09-13 19:11:49 +08:00
Aparup Banerjee d8f2500f46 Merge branch MDL-29186-m21 of git://github.com/samhemelryk/moodle
- resolved conflicts, minor whitespace and fixed quote.
    - note: textlib_get_instance() is already deprecated
2011-09-13 16:19:47 +08:00
Aparup Banerjee 6519a7769d Merge branch MDL-29187-m21 of git://github.com/samhemelryk/moodle
- resolved conflict.
2011-09-13 13:54:43 +08:00
Aparup Banerjee 995b4d16cd Merge branch 'wip-MDL-29188-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-09-13 13:33:56 +08:00
Aparup Banerjee 717c3395be Merge branch 'wip-MDL-29189-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-09-13 11:45:51 +08:00
Sam Hemelryk 6bc526319e Merged branch '28595_m22_installcontinue' of git://github.com/skodak/moodle with changes 2011-09-13 15:35:27 +12:00
Sam Hemelryk b3c64930ff MDL-29189 course Minor fixups after code review 2011-09-13 11:19:17 +12:00
Andrew Davis (andyjdavis) a6f388c664 MDL-22232 messaging: added the ability to temporarily disable notifications to a particular user 2011-09-12 20:24:08 +12:00
Sam Hemelryk 90d14d089c Merge branch 'MDL-29211_M21' of git://github.com/kordan/moodle into MOODLE_21_STABLE 2011-09-12 19:49:26 +12:00
kordan 9d8dbe645c MDL-29211 fox for MOODLE_21_STABLE 2011-09-12 09:40:08 +02:00
Sun Zhigang 937e0a23d9 MDL-29112 trigger event mod_deleted after deleting mod through AJAX 2011-09-12 17:36:10 +12:00
Aparup Banerjee 910671644c MDL-28724 wiki : Fixed bugs in wiki forms 2011-09-12 17:27:56 +12:00
Petr Skoda 9e6ef6ccc2 MDL-29131 fix multiple groups issues on the recent activity report 2011-09-12 17:08:58 +12:00
Sam Hemelryk 4a277f4f4e Merge branch 'w36_MDL-29306_m21_dbenrolroles' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-09-12 15:30:33 +12:00
Sam Hemelryk 786a905607 Merge branch 'w36_MDL-29292_m21_featuretypo' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-09-12 15:17:25 +12:00
Sam Hemelryk 20ff7e3279 Merge branch 'MDL-27635_m21' of git://github.com/rwijaya/moodle into MOODLE_21_STABLE 2011-09-12 14:39:22 +12:00
Sam Hemelryk 2513a2b24f Merge branch 'w36_MDL-29312_m21_cookieless' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-09-12 14:25:02 +12:00
Rossiani Wijaya 4966b0ee71 MDL-27635 hub component: fixed default value for 'secret' field in 'registration_hubs' table 2011-09-12 10:21:45 +08:00
Sam Hemelryk 18fc309097 Merge branch 'MDL-28488_21' of git://github.com/stronk7/moodle into MOODLE_21_STABLE 2011-09-12 13:20:47 +12:00
kordan 3bfe7ce57a MDL-29056 theme-formal_white fix for the report pagelayout that was preventing horizontal scroll 2011-09-12 13:03:02 +12:00
Eloy Lafuente (stronk7) 366c19fabd 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 21:57:00 +02:00
Eloy Lafuente (stronk7) 56a1642c5b MDL-28488 backup - '[backup|restore]:configure cap does not control import mode anymore 2011-09-11 21:56:45 +02:00
Eloy Lafuente (stronk7) 9d74bab3bc MDL-28488 backup - fixup some strings and delete legacy ones 2011-09-11 21:56:31 +02:00
Eloy Lafuente (stronk7) 993261dcff 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:56:13 +02:00
Eloy Lafuente (stronk7) 4b5233f9c4 MDL-28488 backup - activity duplication requires 2 capabilities in ctx 2011-09-11 21:55:43 +02:00
Petr Skoda 0cf269c1fc MDL-29292 fix feature typo
Credit goes to Raminder Singh.
2011-09-11 12:49:16 +02:00
Petr Skoda e1e082a809 MDL-29312 prevent cookieless mode for security reasons 2011-09-11 10:07:27 +02:00
AMOS bot 8cd0f221b6 Automatically generated installer lang files 2011-09-11 00:55:40 +00:00
Petr Skoda 94a720f287 MDL-28595 explain the need to install into new db if something fails during the initial install 2011-09-11 00:08:23 +02:00
Petr Skoda f6090a3531 MDL-28595 do not print continue link if install fails 2011-09-11 00:08:20 +02:00
Petr Skoda 3dfac46e97 MDL-29306 support multiple roles in ext enrol db 2011-09-10 23:34:06 +02:00
AMOS bot 3119ba9a2a Automatically generated installer lang files 2011-09-10 00:55:20 +00:00
AMOS bot 74743b5e48 Automatically generated installer lang files 2011-09-09 00:55:20 +00:00
Henning Bostelmann 033a066e4f MDL-26257 Shibboleth auth: run logout handler only if logged in via Shibboleth 2011-09-08 11:53:44 +01:00
AMOS bot 8ede1d5121 Automatically generated installer lang files 2011-09-08 00:55:31 +00:00
Sam Hemelryk 0347dd4d70 MDL-29186 multilang Reviewed the uses of course fullname and ensured things were being formatted consistently 2011-09-08 09:39:00 +12:00
Sam Hemelryk 5da6f4eeb6 MDL-29187 multilang Reviewed the uses of category name and ensured things are being formatted correctly 2011-09-08 09:36:55 +12:00
Sam Hemelryk 34c46428f1 MDL-29189 mutlilang Reviewed the uses of course shortname and ensured things are being formatted consistently 2011-09-08 09:30:10 +12:00
Sam Hemelryk 9ec4220c84 MDL-29188 multilang Reviewed the uses of section name and ensured things were being formatted consistently 2011-09-08 09:27:55 +12:00
Eloy Lafuente (stronk7) 22e8ad6134 weekly release 2.1.1+ 2011-09-07 17:55:05 +02:00
Eloy Lafuente (stronk7) 0780ba7ca7 Merge branch 'install_21_STABLE' of git://github.com/amosbot/moodle into MOODLE_21_STABLE 2011-09-07 17:49:21 +02:00
Eloy Lafuente (stronk7) 06b66d530b Merge branch 'wip-MDL-28043-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-09-06 13:56:08 +02:00
Eloy Lafuente (stronk7) 57d30b5276 Merge branch 'wip-mdl-28987-m21' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-09-06 01:59:49 +02:00
Sam Hemelryk a640301b81 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:44 +12:00
Eloy Lafuente (stronk7) 593b4518ad Merge branch 'wip-mdl-23520-m21' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-09-06 01:27:51 +02:00
Eloy Lafuente (stronk7) abaff947c6 Merge branch 'wip-MDL-29006-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-09-06 00:38:38 +02:00
Eloy Lafuente (stronk7) ae115cf229 Merge branch 'w35_MDL-29145_m21_imscpregression' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-09-05 21:52:08 +02:00
Eloy Lafuente (stronk7) 152ee16812 MDL-29072 Import course - whitespace fixes 2011-09-05 10:42:55 +02:00
Petr Skoda ed2448a342 MDL-29145 fix regression caused by MDL-27448 2011-09-05 09:47:09 +02:00
Rajesh Taneja 48f6a80092 MDL-28987 Forms Library: Removed onBlur validation. Now the validation will occur on form submit only 2011-09-05 14:26:19 +08:00
Iñaki Arenaza 85f5ab3145 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:31:41 +08:00
Aparup Banerjee 26cfc10584 Merge branch 'wip-MDL-26811-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-09-05 13:18:52 +08:00
Aparup Banerjee 5f856fdfe9 Merge branch 'MDL-29198_21' of git://github.com/stronk7/moodle into MOODLE_21_STABLE 2011-09-05 12:52:15 +08:00
Rajesh Taneja 0d7dcbf1ae MDL-28987 Forms Library: Added tinyMCE onblur event callback for required tinymce fields 2011-09-05 12:21:55 +08:00
Rajesh Taneja 6786f79ab4 MDL-28987 Forms Library: Added tinyMCE save for tinymce editor validation 2011-09-05 12:21:49 +08:00
Adam Olley a010bfe63d MDL-28987: Affix [text] to editor element in JS validation and add blur event 2011-09-05 12:21:43 +08:00
Sam Hemelryk 3cabe2de8c Merge branch 'MDL-29018_m21' of git://github.com/rwijaya/moodle into MOODLE_21_STABLE 2011-09-05 16:08:07 +12:00
Sam Hemelryk 7ecabfdce4 Merge branch 'MDL-28689_m21' of git://github.com/rwijaya/moodle into MOODLE_21_STABLE 2011-09-05 16:03:08 +12:00
Rossiani Wijaya c8fa99de72 MDL-29018 lesson module statistics: fixed statistics diplay for whole the class 2011-09-05 11:16:33 +08:00
Henning Bostelmann 02aac22ff8 MDL-29072 Import course: Use correct capability for course selection 2011-09-05 13:41:34 +12:00
Sam Hemelryk 05956888d7 Merge branch 'MDL-27975_m21' of git://github.com/rwijaya/moodle into MOODLE_21_STABLE 2011-09-05 13:37:33 +12:00
Sam Hemelryk caff2aa640 Merge branch 's13_MDL-29170_risklevel_21' of git://github.com/dongsheng/moodle into MOODLE_21_STABLE 2011-09-05 11:13:17 +12:00
AMOS bot 5031249d84 Automatically generated installer lang files 2011-09-03 00:55:20 +00:00
Eloy Lafuente (stronk7) 3c7a83744e MDL-28080 DML unit tests - cover tweak_param_names() and the new 30 chars limit exception 2011-09-01 19:59:13 +02:00
Eloy Lafuente (stronk7) 436135f52a 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 19:59:13 +02:00
Tim Hunt 41f17b384f MDL-28080 coding_exception for over-long placeholder names. 2011-09-01 19:59:12 +02:00
Rossiani Wijaya 47b9f44c6f MDL-27975 community block: fixed string typo 2011-09-01 17:10:29 +08:00
Eloy Lafuente (stronk7) 7a8a938077 MDL-29198 DB - make delete_records transactional safe when needed 2011-09-01 11:08:09 +02:00
Rossiani Wijaya e3a6a3878e 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-01 16:27:13 +08:00
Andrew Davis (andyjdavis) 35dd29564b MDL-29126 gradebook: made text export with tabs as separator work 2011-09-01 15:32:27 +08:00
Dongsheng Cai 5c71cfca6a WEBSERVICE MDL-29170 reduce createmobiletoken capability risk level 2011-09-01 11:03:47 +08:00
AMOS bot e5df0e3e17 Automatically generated installer lang files 2011-09-01 00:55:25 +00:00
Rajesh Taneja 6b94a62ff8 MDL-23520 mod-wiki-2.0: Added delete page and version feature as it was in 1.9 2011-08-31 13:54:16 +08:00
Sam Hemelryk e9a574454c MDL-29006 block_html Added formatted to title printed on editing form when a hard freeze is in effect 2011-08-31 11:46:44 +12:00
Eloy Lafuente (stronk7) ddf322586e weekly release 2.1.1+ 2011-08-31 01:33:29 +02:00
Sam Hemelryk ed9041c9ce MDL-26811 upgrade Fixed up default handling causing exception on upgrade of used site in MSSQL 2011-08-31 11:33:29 +12:00
Eloy Lafuente (stronk7) 3853dc585c Merge branch 'install_21_STABLE' of git://github.com/amosbot/moodle into MOODLE_21_STABLE 2011-08-31 01:29:39 +02:00
Aparup Banerjee 132c116509 MDL-29005 blocks : clarified comment 2011-08-30 11:20:38 +08:00
Aparup Banerjee 97dd4ec539 Merge branch 'MDL-29005_MOODLE_21_STABLE' of git://github.com/mouneyrac/moodle into MOODLE_21_STABLE 2011-08-30 11:19:57 +08:00
Eloy Lafuente (stronk7) 5266e929da MDL-28489 site news forum - support multilang filter 2011-08-30 11:06:57 +12:00
Eloy Lafuente (stronk7) 9c89f307f8 Merge branch 'MDL-29141_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-29 13:01:57 +02:00
Eloy Lafuente (stronk7) 4524a47a0a Merge branch 'wip-MDL-24202-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-08-29 10:30:59 +02:00
Aparup Banerjee 7816f5acb0 Merge branch 'MDL-29144_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-29 12:01:41 +08:00
Sam Hemelryk ce4285c883 Merge branch 'MDL-28564_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-29 13:59:26 +12:00
Sam Hemelryk 208b9e2a50 MDL-24202 navigation Fixed bug caused by navigation overriding a CFG setting 2011-08-29 13:45:36 +12:00
Eloy Lafuente (stronk7) 5a8f177c73 Merge branch 'MDL-28943_manage_message_name_21' of git://github.com/andyjdavis/moodle into MOODLE_21_STABLE 2011-08-29 03:26:41 +02:00
Eloy Lafuente (stronk7) fa3dff1318 Merge branch 'MDL-26302_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-29 03:23:28 +02:00
Sam Hemelryk a4ad64950b Merge branch 'MDL-26819_21' of git://github.com/stronk7/moodle into MOODLE_21_STABLE 2011-08-29 13:05:22 +12:00
Sam Hemelryk 6870b5dcbb Merge branch 'dev_MDL-27289_boxnet_21' of git://github.com/dongsheng/moodle into MOODLE_21_STABLE 2011-08-29 12:54:40 +12:00
Eloy Lafuente (stronk7) 6e582f1632 Merge branch 'MDL-29064_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-29 02:52:55 +02:00
Eloy Lafuente (stronk7) 3bdb9bfd54 Merge branch 'MOODLE_21_STABLE' of git.moodle.org:/git/integration into MOODLE_21_STABLE 2011-08-29 02:41:27 +02:00
Eloy Lafuente (stronk7) 1dd41f0eb1 Merge branch 'MDL-29062_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-29 02:40:08 +02:00
Sam Hemelryk 78b19caf0a Merge branch 'MDL-29135-mnet-login_21_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_21_STABLE 2011-08-29 12:24:57 +12:00
Eloy Lafuente (stronk7) 4984e712e6 Merge branch 'MDL-29111_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-29 02:02:55 +02:00
David Mudrak 174245497e MDL-29148 MNet - improved handling of a verification function return code 2011-08-29 01:48:41 +02:00
Eloy Lafuente (stronk7) 119b895133 Merge branch 'wip_MDL-16168_2.1_CAS_crash_if_no_LDAP' of https://github.com/iarenaza/moodle into MOODLE_21_STABLE 2011-08-29 01:33:03 +02:00
Eloy Lafuente (stronk7) 04dc7f877b Merge branch 'MDL-25872-21' of git://github.com/bostelm/moodle into MOODLE_21_STABLE 2011-08-29 01:22:42 +02:00
Iñaki Arenaza 5e7d9e3e36 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:08:42 +02:00
Eloy Lafuente (stronk7) c24ccde07f MDL-26819 quiz statistics - use cross-db GROUP BY expression 2011-08-28 22:16:11 +02:00
Iñaki Arenaza b38bcc3a1d MDL-16168 auth/cas CAS crashes if no LDAP is set up
Fix was pending for Moodle 2.1. Credit goes to Ivan Dackiewicz.
2011-08-28 15:32:32 +02:00
David Mudrak 9b81b37eb9 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:36:38 +02:00
David Mudrak 2f2cf818c2 MDL-29135 Reworded login prompt with SSO over MNet enabled 2011-08-27 18:24:55 +02:00
AMOS bot ed32596d3a Automatically generated installer lang files 2011-08-27 00:55:41 +00:00
M Kassaei 9651053bb4 MDL-29144 quiz navigation: Screen-readers speak question state twice 2011-08-26 19:10:54 +01:00
Tim Hunt 15e6246359 MDL-29111 quiz was passing 0 to ->review_url when it should have been null. 2011-08-26 18:16:57 +01:00
Henning Bostelmann b1a24c1eb0 MDL-25872 View assignment submissions: show only students, not teachers
Fixing incorrect capability reference mod/assignment:view to ...:submit
2011-08-26 17:34:35 +01:00
Tim Hunt 362d5c1ed1 MDL-29141 question bank show question text checkbox does not match state. 2011-08-26 17:01:52 +01:00
Henning Bostelmann d5ae2ed112 MDL-28686 QE2 upgrade: recognize manually graded, deleted questions 2011-08-26 14:37:49 +01:00
Eloy Lafuente (stronk7) e4527c5497 weekly release 2.1.1+ 2011-08-26 15:09:00 +02:00
Eloy Lafuente (stronk7) 200cb06bfc Merge branch 'install_21_STABLE' of git://github.com/amosbot/moodle into MOODLE_21_STABLE 2011-08-26 14:56:52 +02:00
Eloy Lafuente (stronk7) 97e4e3953a MDL-28684 QE2 upgrade: fix undefined $a regression. Thanks Henning! 2011-08-25 15:54:41 +02:00
Eloy Lafuente (stronk7) ee4dee99e8 Merge branch 'MDL-27823_bulk_messaging_2_21' of git://github.com/andyjdavis/moodle into MOODLE_21_STABLE 2011-08-25 10:46:11 +02:00
AMOS bot 7adfd55ec2 Automatically generated installer lang files 2011-08-25 00:55:21 +00:00
Eloy Lafuente (stronk7) efc2de0e97 Merge branch 'MDL-28650-MOODLE-21-STABLE' of https://github.com/mouneyrac/moodle into MOODLE_21_STABLE 2011-08-25 01:15:49 +02:00
Eloy Lafuente (stronk7) ddec658859 Merge branch 'MDL-28684_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-24 17:12:18 +02:00
Tim Hunt e9f707d38a MDL-28684 fix failing unit test - which means fix the acutal code.
Sorry for the noise.
2011-08-24 16:02:40 +01:00
Eloy Lafuente (stronk7) 7faa5b4e9c Merge branch 'MDL-28976_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-24 12:57:51 +02:00
Jerome Mouneyrac 2eb3bb390f MDL-29005 display enrollable courses total and downloadable courses total instead of courses/sites total 2011-08-24 14:49:54 +08:00
Aparup Banerjee 2134aa6129 Revert "MDL-28509 repository_youtube Enable selection of sort order"
This reverts commit 0638e55b14.
2011-08-24 14:43:05 +08:00
Eloy Lafuente (stronk7) adc0d74ac9 Merge branch 'w33_MDL-29022_m21_idnumber' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-24 03:51:51 +02:00
Aaron Barnes b5013dc868 MDL-28248 completion: Incorrect SQL for finding enrol start date 2011-08-24 12:07:18 +12:00
Eloy Lafuente (stronk7) b61fd419e8 Merge branch 'MDL-28979_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-24 01:56:06 +02:00
Tim Hunt 8c412f122c MDL-28942 qtype multichoice, multi-response. Avoid computing the wrong random guess score.
It is effectively impossible to compute the right random guess score, so we should not compute anything, rather than computing a number that we know is wrong.

This patch also fixes a multianswer unit test error that was shown up by this fix.
2011-08-24 01:53:26 +02:00
Eloy Lafuente (stronk7) 7a4a1f14ca Merge branch 'MDL-28975_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-24 01:45:23 +02:00
Sun Zhigang fad5ec9b5a MDL-29019 enrol - fix a typo 2011-08-24 01:31:29 +02:00
Petr Skoda 93e8c6c422 MDL-19380 fix redirect when virus found in JS-less mode 2011-08-24 01:21:08 +02:00
Petr Skoda 16dc846eb1 MDL-19380 reimplement antivir scanning in repositories 2011-08-24 01:21:00 +02:00
Petr Skoda c7c1a8cf14 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:08:10 +02:00
Petr Skoda b13eda7e8d MDL-28981 fix forum_user_can_post() call params 2011-08-24 00:53:29 +02:00
Tony Levi a3ad8fd883 MDL-27228: Fix label 'eye' does not match show/hide setting 2011-08-23 23:36:29 +02:00
Eloy Lafuente (stronk7) 4ffedd8b0e Merge branch 'w33_MDL-28708_m21_f304' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-23 23:32:36 +02:00
Eloy Lafuente (stronk7) 71cf843ad2 Merge branch 'w33_MDL-28709_m21_h304' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-23 23:23:15 +02:00
Eloy Lafuente (stronk7) fd7bdf278c Merge branch 'w33_MDL-29011_m21_nomanualenrol' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-23 23:13:28 +02:00
Eloy Lafuente (stronk7) 80fc30b7bd MDL-28684 QE2 upgrade: whitespace fix 2011-08-23 22:53:26 +02:00
Eloy Lafuente (stronk7) 251037cefd Merge branch 'MDL-28684b-21' of git://github.com/bostelm/moodle into MOODLE_21_STABLE 2011-08-23 22:53:11 +02:00
Eloy Lafuente (stronk7) 3d95259d7e Merge branch 'MDL-28444-21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-23 22:48:06 +02:00
Aparup Banerjee 1b502dff19 Merge branch 'w33_MDL-28982_m21_sqlfullname' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-24 02:59:56 +08:00
Aparup Banerjee e9f8af2a1b Merge branch 'MDL-28687_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-24 02:28:21 +08:00
Eloy Lafuente (stronk7) 35dd038144 MDL-28962 enrol imsenterprise - whitespace fix 2011-08-23 18:43:37 +02:00
Eloy Lafuente (stronk7) f403941133 Merge branch 'm21_MDL-28962' of git://github.com/danmarsden/moodle into MOODLE_21_STABLE 2011-08-23 18:43:21 +02:00
Eloy Lafuente (stronk7) a1eeb0185a Merge branch 'MDL-28957_21' of git://github.com/colchambers/moodle into MOODLE_21_STABLE 2011-08-23 18:01:16 +02:00
Eloy Lafuente (stronk7) dc70aa7378 Merge branch 'MDL-28397-21' of https://github.com/totara/moodle into MOODLE_21_STABLE 2011-08-23 17:31:12 +02:00
Sam Hemelryk bb37aab093 MDL-25636 block_html Fixed up missing format config if block restored from early 2.0 backup 2011-08-23 18:41:48 +08:00
Eloy Lafuente (stronk7) 72bd83e0f1 Merge branch 'w33_MDL-28381_m21_cliphpver' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-23 11:03:42 +02:00
Eloy Lafuente (stronk7) 1b69c111cc Merge branch 'MDL-28996_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-23 10:42:52 +02:00
Petr Skoda 23eccfcd77 MDL-28935 use weekdays as calendar table headings 2011-08-23 10:05:14 +02:00
Jason Ilicic 68cfdb72f9 MDL-28935 Add days of week to monthly calendar view 2011-08-23 10:05:04 +02:00
Tim Hunt 0570e81ecb MDL-29062 qtype multianswer refers to old name for the question_delete_questions function. 2011-08-23 08:54:15 +01:00
Tim Hunt 5ce736caa8 MDL-29064 qtype multianswer, question text should be a required field. 2011-08-23 08:41:00 +01:00
Aparup Banerjee 8145290d43 Merge branch 'MDL-28509_21_STABLE' of git://github.com/marxjohnson/moodle into MOODLE_21_STABLE 2011-08-23 14:55:11 +08:00
Eloy Lafuente (stronk7) d94b4b327d Merge branch 'm21_MDL-28999' of git://github.com/danmarsden/moodle into MOODLE_21_STABLE 2011-08-23 02:49:59 +02:00
Petr Skoda c896d5c54d MDL-29016 allow distributions to set dataroot permissions 2011-08-23 02:43:10 +02:00
Eloy Lafuente (stronk7) 5cfb119475 Merge branch 'MDL-28990-MOODLE_21_STABLE' of git://github.com/mouneyrac/moodle into MOODLE_21_STABLE 2011-08-23 02:37:01 +02:00
Eloy Lafuente (stronk7) 092c6089c9 Merge branch 'w33_MDL-29031_m21_oldblock' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-23 02:05:08 +02:00
Eloy Lafuente (stronk7) 8fb3542126 Merge branch 'MDL-28226_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-23 01:42:25 +02:00
Adam Olley 4b0fbfcbd9 MDL-28481: Send headers before any possible output 2011-08-23 01:37:16 +02:00
Eloy Lafuente (stronk7) b1ea3fb2c6 Merge branch 'w33_MDL-28936_m21_msgstrlen' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-23 01:20:24 +02:00
Eloy Lafuente (stronk7) 94aa0fbe8c Merge branch 'MDL-28241_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-23 01:17:17 +02:00
Tom Cubanski 6be8a680e2 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:56:51 +01:00
Tim Hunt 6310adb3f4 MDL-28564 question type importing, improve Jamie's fix. 2011-08-22 23:32:48 +01:00
Jamie Pratt 80fa621c50 MDL-28564 "implement support for extra answer fields in question export and
import" implemented support for extra answer fields in questiontype base
export and import functions.
2011-08-22 23:32:47 +01:00
Tim Hunt 60854b669a MDL-28241 editing multianswer questions broken since the fix for MDL-24594. 2011-08-22 22:36:37 +01:00
Aparup Banerjee 8db14e344b Merge branch 'wip-mdl-28580-m21' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-08-23 01:49:51 +08:00
Andrew Davis (andyjdavis) a47827691a MDL-27823 messaging: preventing html tags from being output to the UI 2011-08-22 15:28:30 +08:00
Aaron Barnes 3b9bf6a949 MDL-28397 completion: Activity completion criteria not showing grading
requirement

Credit goes to Evan Irving-Pease for the patch
2011-08-22 14:57:13 +12:00
Petr Skoda 5eb8c77850 MDL-29011 do not require manual enrol cap on the enrolled users page 2011-08-21 18:18:35 +02:00
Petr Skoda 51606ad2d8 MDL-29031 remove blocks cleanup todo 2011-08-21 17:45:52 +02:00
Petr Skoda 812e3294be MDL-27248 remove forgotten unique sortorder index from the course table 2011-08-21 17:33:19 +02:00
Petr Skoda 181b0dc545 MDL-28982 fix DML use 2011-08-21 15:39:34 +02:00
Petr Skoda 6b3d645e9b MDL-28381 always verify PHP version in CLI scripts
The problem is that people may use different php binary for web and CLI.
2011-08-21 12:22:14 +02:00
Tim Hunt 3d233b9dab MDL-28444 unit test to verify the fix. 2011-08-20 13:18:05 +01:00
Henning Bostelmann 5c364504a6 MDL-28444 synchronized datasets: fix typo in get_variants_selection_seed() 2011-08-20 11:45:41 +01:00
Petr Skoda 0864c8a59d MDL-29022 do not require idnumber in ext courses - backport from MDL-29020 2011-08-20 11:34:58 +02:00
AMOS bot c498bf796b Automatically generated installer lang files 2011-08-20 00:55:28 +00:00
Petr Skoda a32da065ae MDL-28936 fix invalid >200 comparison and utf-8 incompatibility
Credit for discovery goes to Jason Ilicic.
2011-08-19 18:44:33 +02:00
Tony Levi 68d9daa187 MDL-28708: Send 304 Not Modified response when browser If-Modified-Since header is after file mtime 2011-08-19 17:27:20 +02:00
Petr Skoda 4bdcd23e19 MDL-28709 adding HTTP_IF_MODIFIED_SINCE and minor style tweaks 2011-08-19 16:50:16 +02:00
Tony Levi 716f93efdb MDL-28709: Performance: Send cache/contenttype headers with 304 responses 2011-08-19 16:50:16 +02:00
Henning Bostelmann ec5f40b1a9 MDL-28684 QE2 upgrade: recognize empty answer in multichoice questions 2011-08-19 10:33:55 +01:00
Rajesh Taneja 01f9bc7948 MDL-28580 Administration: Added sanity check to grab wrong usage of upgrade_main_savepoint 2011-08-19 07:41:13 +00:00
Jerome Mouneyrac fc218ba9e2 MDL-28990 add web service mobile overview 2011-08-19 11:47:17 +08:00
Dan Marsden f3e0eac04f MDL-28999 SCORM add missing yui2 require 2011-08-19 10:21:11 +12:00
Tim Hunt da45306da5 MDL-28996 Quiz view page list of attempts table is sometimes missing a cell. 2011-08-18 19:27:19 +01:00
Tim Hunt 96bab3e01d MDL-28979 qtype match: correct answer formatted badly. 2011-08-18 13:51:18 +01:00
Tim Hunt cb5a7bba89 MDL-28976 quiz was passing 0 to ->attempt_url when it should have been null.
There was also one other incorrect call that is fixed in this commit.
2011-08-18 13:50:51 +01:00
Tim Hunt 0a20ddbe7d MDL-28975 question engine, JavaScript error in IE. 2011-08-18 13:50:24 +01:00
Tim Hunt 3575052f81 MDL-28687 questions avoid fatal errors when reviewing attempts at deleted questions. 2011-08-18 13:49:33 +01:00
Tim Hunt 6d9ae2adf0 MDL-28226 quiz locallib. Fix PHPdoc comment and code to make the API clearer. 2011-08-18 13:44:01 +01:00
Jerome Mouneyrac f76dc0ff65 MDL-28650 add a page in the administration to the full web service API (API documentation). 2011-08-18 12:08:38 +08:00
Dan Marsden 1b64c78d36 MDL-28962 enrol imsenterprise - incorrect conversion of new dml syntax - thanks to Patrick Gagnon for report and fix. 2011-08-18 13:40:17 +12:00
Eloy Lafuente (stronk7) 24654d977b weekly release 2.1.1+ 2011-08-18 02:42:40 +02:00
Eloy Lafuente (stronk7) cd91adc715 Merge branch 'install_21_STABLE' of git://github.com/amosbot/moodle into MOODLE_21_STABLE 2011-08-18 02:38:43 +02:00
Colin Chambers e5ba71b479 #MDL-28957 outputrequirementslib reduced excessive js console logging 2011-08-17 14:58:15 +01:00
Eloy Lafuente (stronk7) ad307c7121 Merge branch 'MDL-28349_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-17 15:40:00 +02:00
Dongsheng Cai 1c64c52951 MDL-27289, upgrade box.net repository plugin to use new box.net authentication process 2011-08-17 11:45:32 +08:00
Eloy Lafuente (stronk7) 74475bd5d5 Merge branch 'wip-mdl-27219-m21' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-08-17 02:59:38 +02:00
Eloy Lafuente (stronk7) c30dadce6f Merge branch 'MDL-28737_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-17 02:51:57 +02:00
Eloy Lafuente (stronk7) f45cf8cb2c Revert "MDL-25757 SCORM fix issue with duplicate cmi values being saved"
This reverts commit 2c7cc519d8.
2011-08-17 02:28:49 +02:00
Eloy Lafuente (stronk7) 4239318be9 Merge branch 'MDL-21934_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-17 01:29:20 +02:00
Eloy Lafuente (stronk7) 33868528bb Merge branch 'MDL-27752_m21' of git://github.com/rwijaya/moodle into MOODLE_21_STABLE 2011-08-17 01:02:21 +02:00
Eloy Lafuente (stronk7) e3af6a00ba Merge branch 'MDL-28643-m21' of git://github.com/sammarshallou/moodle into MOODLE_21_STABLE 2011-08-17 00:45:25 +02:00
Eloy Lafuente (stronk7) 95caac3cc8 Merge branch 'm21_MDL-28649' of git://github.com/danmarsden/moodle into MOODLE_21_STABLE 2011-08-17 00:33:07 +02:00
Eloy Lafuente (stronk7) c89c390759 Merge branch 'MDL-28652_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-17 00:29:23 +02:00
Eloy Lafuente (stronk7) 25bde46869 Merge branch 'MDL-28653_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-17 00:25:46 +02:00
Tim Hunt 269c653560 MDL-28654 fix path for TinyMCE in lib/thirdpartylibs.xml. 2011-08-17 00:10:09 +02:00
Eloy Lafuente (stronk7) 88b340161b Merge branch 'MDL-28655-21' of git://github.com/bostelm/moodle into MOODLE_21_STABLE 2011-08-17 00:07:44 +02:00
Eloy Lafuente (stronk7) 5b18861bf0 Merge branch 'm21_MDL-28721' of git://github.com/danmarsden/moodle into MOODLE_21_STABLE 2011-08-16 23:44:12 +02:00
Eloy Lafuente (stronk7) 84e093e143 Merge branch 'wip-MDL-26754-MOODLE_21_STABLE' of github.com:marinaglancy/moodle into MOODLE_21_STABLE 2011-08-16 13:11:16 +02:00
Eloy Lafuente (stronk7) 02b36f79d2 Merge branch 'MDL-28365_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-16 13:03:59 +02:00
Eloy Lafuente (stronk7) a6f18c98f4 Merge branch 'MDL-23872_m21' of git://github.com/nebgor/moodle into MOODLE_21_STABLE 2011-08-16 11:51:53 +02:00
Rajesh Taneja 273ac54baa MDL-27219 chat: Beep will not display user fullname if user is not in chat 2011-08-16 16:35:33 +08:00
Andrew Davis (andyjdavis) 549af292b6 MDL-28943 messaging: made messaging admin page use a string instead of the plugin name 2011-08-16 14:33:57 +08:00
Eloy Lafuente (stronk7) 28f9b39287 Merge branch 'MDL-28931_m21' of git://github.com/stronk7/moodle into MOODLE_21_STABLE 2011-08-16 03:06:07 +02:00
Eloy Lafuente (stronk7) e42213ab72 Merge branch 'wip-mdl-27728-m21' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-08-16 02:14:49 +02:00
Eloy Lafuente (stronk7) 68d998c6cf Merge branch 'MDL-27030_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-16 02:07:37 +02:00
Eloy Lafuente (stronk7) bf22dc969c MDL-27896 filters/editor - fix whitespace 2011-08-16 02:01:20 +02:00
Eloy Lafuente (stronk7) 0031600453 Merge branch 'wip-mdl-27896-m21' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-08-16 02:00:36 +02:00
Eloy Lafuente (stronk7) 3bcd0781f1 Merge branch 'm21_MDL-25757' of git://github.com/danmarsden/moodle into MOODLE_21_STABLE 2011-08-16 00:39:18 +02:00
Petr Skoda 26e3dce466 Merge branch 'MDL-27845_rating_aggregation_21' into MOODLE_21_STABLE 2011-08-15 20:41:12 +02:00
Tim Hunt 5e54da0a69 MDL-21934 Removing all questions from the quiz should not delet overall feedback.
Overall feedback was being wiped because the quiz max grade was being set to zero when sumgrades was set to 0. The correct logic is to only set maxgrade to 0 if there are questions in the quiz and sumgrades is 0.
2011-08-15 19:10:47 +01:00
Eloy Lafuente (stronk7) a4f85cc579 Merge branch 'm21_MDL-28603' of git://github.com/danmarsden/moodle into MOODLE_21_STABLE 2011-08-15 20:02:33 +02:00
Dan Poltawski bf1b681560 MDL-28605 repsitory/local - Prevent server running out of memory
Removing useless code..
2011-08-15 19:58:27 +02:00
Eloy Lafuente (stronk7) 2ce0d40694 Merge branch 'MDL-28939_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-15 19:34:59 +02:00
Tim Hunt 7f10fbbf5f MDL-28349 error when GIFT-importing essay questions. 2011-08-15 16:18:03 +01:00
Tim Hunt e67a234c98 MDL-28365 Move question lang string to the right file
All the references to this sring were already referring to it in the new
place.

AMOS BEGIN
 MOV [cannotread,mod_quiz],[cannotread,question]
AMOS END
2011-08-15 15:20:15 +01:00
Tim Hunt 80e3f00091 MDL-28939 Bad lang string reference in grade/import/csv. 2011-08-15 15:12:19 +01:00
Tim Hunt d3fd75d21d MDL-28639 question import should set timemodified and modified by.
Thanks to Jean-Michel Vedrine for the fix.
2011-08-15 14:56:45 +01:00
Tim Hunt 8ad92a30f1 MDL-28438 Aiken question import broken since MDL-24594. 2011-08-15 14:47:16 +01:00
Eloy Lafuente (stronk7) bee0152fda MDL-28931 timezone - update to 2011h (2200 rules) 2011-08-14 18:06:10 +02:00
Dan Marsden 2c7cc519d8 MDL-25757 SCORM fix issue with duplicate cmi values being saved 2011-08-13 13:24:22 +12:00
Tim Hunt 643e2728df MDL-28737 advcheckboxes toggle state every submit if checkbox_controller present. 2011-08-12 19:13:20 +01:00
Rajesh Taneja 3a7de25755 MDL-27896 course - Rectified wrong use of itemid for preparing draft file area 2011-08-12 16:49:29 +08:00
Rajesh Taneja 56d57a9a4e MDL-27896 editor - parent context will be respected by editor in case context is not created. 2011-08-12 16:49:05 +08:00
Rajesh Taneja 1449e4faa2 MDL-27896 editor - added sanity check to pick wrong context passed to editor creation 2011-08-12 16:48:47 +08:00
Rajesh Taneja b51aac313f MDL-27896 context - Fixed editor context to observe filter status 2011-08-12 16:48:22 +08:00
Dan Marsden ee124f531b MDL-28603 SCORM fix regression with ADL scorm 1.2 tests 2011-08-12 17:24:48 +12:00
Rajesh Taneja 63ff326835 MDL-27728 Moodleforms: Added validation for element before checking element values 2011-08-12 10:54:33 +08:00
AMOS bot 5ce30862f2 Automatically generated installer lang files 2011-08-12 00:55:30 +00:00
Dan Marsden dbc61bc225 MDL-28649 SCORM start new attempt if set when skipview used. 2011-08-12 12:53:53 +12:00
Dan Marsden f08cc8276c MDL-28721 SCORM respect hidenav setting 2011-08-12 11:07:28 +12:00
Eloy Lafuente (stronk7) 3a5778ec5a weekly release 2.1.1+ 2011-08-12 00:19:27 +02:00
Eloy Lafuente (stronk7) d0aeb0abfa Merge branch 'install_21_STABLE' of git://github.com/amosbot/moodle into MOODLE_21_STABLE 2011-08-12 00:13:16 +02:00
Marina Glancy f364d3f91d MDL-26754: Removed unnecessary include 2011-08-11 13:40:24 +08:00
AMOS bot 07b5fbb9ca Automatically generated installer lang files 2011-08-11 00:55:47 +00:00
Eloy Lafuente (stronk7) 7637e2e5e4 Merge branch 'MDL-27491-m21' of git://github.com/sammarshallou/moodle into MOODLE_21_STABLE 2011-08-10 23:04:13 +02:00
Eloy Lafuente (stronk7) d980c1d746 Merge branch 'm21_MDL-28295' of git://github.com/danmarsden/moodle into MOODLE_21_STABLE 2011-08-10 22:58:04 +02:00
Daren Chandisingh 339c198ade MDL-23872 Forms Library : Updated MoodleQuickForm to honour setConstant(), prevents injection. 2011-08-10 15:22:07 +08:00
Sam Hemelryk 4f4cbbad8f Merge branch 'MDL-20501_m21' of git://github.com/rwijaya/moodle into MOODLE_21_STABLE 2011-08-10 14:10:12 +08:00
Dan Marsden 6a211fb52d 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:33:39 +12:00
Eloy Lafuente (stronk7) 9271414522 Merge branch 'MDL-27631_21' of git://github.com/mkassaei/moodle into MOODLE_21_STABLE 2011-08-10 03:06:52 +02:00
AMOS bot f715589ee5 Automatically generated installer lang files 2011-08-10 00:55:22 +00:00
Eloy Lafuente (stronk7) 6c506c9a07 Merge branch 'MDL-27550-workshop-feedback_21_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_21_STABLE 2011-08-10 02:49:03 +02:00
Eloy Lafuente (stronk7) a28b6620d6 Merge branch 'w31_MDL-27597_m21_catlike' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-10 02:37:07 +02:00
Dan Poltawski c0d30fbb75 MDL-23967 admin/cron.php - warn about use on CLI
Admins now need to use the explicit CLI script
2011-08-10 02:06:12 +02:00
Dan Poltawski 3b97dedfbd MDL-28059 weblib - don't strip mailto: anchors 2011-08-10 01:59:16 +02:00
Eloy Lafuente (stronk7) d04b3d580e Merge branch 'wip-MDL-28407-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-08-10 01:11:51 +02:00
Eloy Lafuente (stronk7) 0f61d7f97c Merge branch 'w31_MDL-28533_m21_columnperf' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-09 19:33:09 +02:00
sam marshall 37f5c92302 MDL-28643 Fix debugging message when deleting activity with grade completion 2011-08-09 12:47:26 +01:00
Tim Hunt dc4bff71a2 MDL-28653 question output. Add a class to the main div based on question state.
This makes it possible themes do cool things. For example change more of the display depending on whether the answer was correct or not.
2011-08-09 11:32:18 +01:00
Eloy Lafuente (stronk7) fd6a17ecfb Merge branch 'MDL-28565_m21' of git://github.com/nebgor/moodle into MOODLE_21_STABLE 2011-08-09 10:15:48 +02:00
Henning Bostelmann fe34282df6 MDL-28655 qtype_calculated question engine upgrade: fix return value 2011-08-09 09:15:33 +01:00
Eloy Lafuente (stronk7) 6b4422a086 Merge branch 'MDL-28604_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-09 09:42:59 +02:00
AMOS bot 9dba637233 Automatically generated installer lang files 2011-08-09 00:55:22 +00:00
Tony Levi 5c5cb085c0 MDL-27030: Fix quiz overview report showing incorrect grades on regraded attempts
Conflicts:

	mod/quiz/report/overview/report.php
2011-08-08 23:46:19 +01:00
Petr Skoda 1c106106fd Merge branch 'MDL-28620_21' of git://github.com/jbrisland/moodle into MOODLE_21_STABLE 2011-08-08 15:35:05 +02:00
Tim Hunt 65be66e4d4 MDL-28652 qtype calculated, bad display of placeholder names on the editing form. 2011-08-08 13:14:20 +01:00
Aparup Banerjee 006776fc71 MDL-28565 General - updated lang files License link to docs.moodle.org/dev/License 2011-08-08 17:14:06 +08:00
Aparup Banerjee 6f80b9b3e9 MDL-28565 General - updated License and Credits links
to docs.moodle.org/dev/License and docs.moodle.org/dev/Credits
2011-08-08 17:13:36 +08:00
Sagie Maoz 56f2ab3335 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:39:12 +08:00
Sam Hemelryk 5553dcba67 Merge branch 'mdl-28517_2.1' of git://github.com/colchambers/moodle into MOODLE_21_STABLE 2011-08-08 14:22:41 +08:00
Sam Hemelryk 806e82b7fc Merge branch 'MDL-28569' of git://git.luns.net.uk/moodle into MOODLE_21_STABLE 2011-08-08 14:09:53 +08:00
Sam Hemelryk 172007a066 Merged branch 'MDL-28575_MOODLE_21_STABLE' of git://github.com/kordan/moodle.git with conflict resolution 2011-08-08 13:59:08 +08:00
Sam Hemelryk 9a2e30d8bc Merge branch 'MDL-28587_MOODLE_21_STABLE' of git://github.com/kordan/moodle into MOODLE_21_STABLE 2011-08-08 13:44:52 +08:00
Rossiani Wijaya 272d804840 MDL-27752 Calendar export: fixed typo in url parameter 2011-08-08 12:16:59 +08:00
Sam Hemelryk 40b4296d07 Merge branch 'MDL-28406_block_duplicate_21' of git://github.com/andyjdavis/moodle into MOODLE_21_STABLE 2011-08-08 11:18:54 +08:00
Sam Hemelryk f24eca0c6b Merge branch 'MDL-28602_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-08 11:08:08 +08:00
Sam Hemelryk 9d660d5f0e Merge branch 'MDL-28593_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-08 11:04:38 +08:00
Sam Hemelryk cf7daeae7e Merge branch 'MDL-28612_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-08 11:02:11 +08:00
Sam Hemelryk 62bdb79c26 Merge branch 'MDL-28618_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-08 10:57:31 +08:00
Sam Hemelryk 6f7c43c7de Merge branch 'w31_MDL-27586_m21_browser' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-08 10:47:33 +08:00
Sam Hemelryk cf8cc1bab1 Merge branch 'w31_MDL-27685_m21_pglike' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-08 10:25:47 +08:00
Sam Hemelryk 6b9c6cc54e Merge branch 'w31_MDL-28382_m21_iis' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-08 10:20:57 +08:00
Sam Hemelryk 31b4fdabbf Merge branch 'w31_MDL-28450_m21_defgroup' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-08 10:09:46 +08:00
Sam Hemelryk a9fbf9fb87 Merge branch 'w31_MDL-28468_m21_cohortassign' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-08 10:06:21 +08:00
Sam Hemelryk 2e81c307d0 Merge branch 'w31_MDL-28473_m21_blocksupgrade' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-08-08 10:03:07 +08:00
Petr Skoda c2edea7cbd MDL-28382 work around or detect REQUEST_URI IIS bug 2011-08-07 14:45:53 +02:00
Petr Skoda f6589dd72d MDL-27685 fix pg LIKE escape trouble 2011-08-07 13:22:36 +02:00
Petr Skoda 29a27d3ca4 MDL-28450 prefer member group for default 2011-08-07 13:07:54 +02:00
Petr Skoda e24225351c MDL-28634 fix forgotten references to Moodle 2.0 and old PHP version requirements 2011-08-06 22:57:47 +02:00
Petr Skoda 520f687cde MDL-27586 fix file_browser access control 2011-08-06 16:24:04 +02:00
Petr Skoda e25df8c464 MDL-28473 fix $instanceids troubles in blocks upgrade
Credit goes to Mateusz Wójcik.
2011-08-05 22:09:49 +02:00
Petr Skoda a5410db4e3 MDL-28468 fix cohort assign check 2011-08-05 21:47:41 +02:00
Petr Skoda d84336c27d verify where_clause() only in debug mode 2011-08-05 21:34:09 +02:00
Petr Skoda cbe6399300 MDL-27597 fix invalid results of get_categories when shallow is false 2011-08-05 20:14:59 +02:00
Tim Hunt c5fe3d7490 MDL-28618 question combined feedback: inconsistency in file areas.
The (partially|in)?correct feedback fields acutally store their files in a file area with component 'question'. Some code, however, was written as if they were stored in the qtype_whatever area.
2011-08-05 17:38:22 +01:00
James Brisland c04c6e6b8a MDL-28620 - Removed admin/generator.php include as it causes issues if this script is included from any other script that is running in the command line 2011-08-05 16:11:44 +01:00
M Kassaei 6f90ec4703 MDL-27631 question bank Show question text in the question list when top level category is used 2011-08-05 15:00:29 +01:00
Tim Hunt e3b8930087 MDL-28593 Missing include breaks editing quiz grade item. 2011-08-05 08:53:16 +01:00
Andrew Davis (andyjdavis) 70ade8e8d7 MDL-28406 blocks: added JS to prevent the addition of duplicate blocks 2011-08-05 11:33:42 +08:00
Andrew Davis (andyjdavis) b312305ccc MDL-27845 rating: altered the get_ratings() query to avoid possible future duplicate key problems 2011-08-05 11:19:11 +08:00
Sam Hemelryk 1ad4fb6f12 MDL-28407 Fixed up calendar preferences form handling 2011-08-05 09:34:43 +08:00
AMOS bot 056a53e81f Automatically generated installer lang files 2011-08-05 00:55:17 +00:00
Tim Hunt 788e2b30a5 MDL-28612 Quiz statistics report does not always show the 'Actual response' column when it should 2011-08-04 18:15:34 +01:00
Colin Chambers 005900fd2a MDL-28517 question editing fixed duplicate id in hint header field 2011-08-04 14:54:11 +01:00
Tim Hunt f97a14ba27 MDL-28602 Quiz review reports the wrong duration. 2011-08-04 14:20:02 +01:00
Tim Hunt 3e1d47f2cc MDL-28604 Question bank display forgets sort order 2011-08-04 13:55:38 +01:00
Marina Glancy ad66263bc1 MDL-26754 Display blocks in 'manage blocks' alphabetically sorted 2011-08-04 14:12:08 +08:00
AMOS bot 64d8fed91c Automatically generated installer lang files 2011-08-04 00:55:33 +00:00
Petr Skoda 80eb52c415 weekly release 2.1.1+ 2011-08-03 18:04:44 +02:00
Petr Skoda c0852d9a0c Merge branch 'install_21_STABLE' of git://github.com/amosbot/moodle into MOODLE_21_STABLE 2011-08-03 18:02:52 +02:00
kordan 5dd9ee192e MDL-28587 fix for MOODLE_21_STABLE 2011-08-03 15:25:08 +02:00
sam marshall e1bb4741f1 MDL-27491 Add 'complete on view' support to wiki, survey 2011-08-03 11:22:10 +01:00
Sam Hemelryk 4a45ddbae2 Revert "MDL-28284 don't load filepicker module for every page"
This reverts commit 279a874108.
2011-08-03 18:20:30 +08:00
kordan aa34ca4309 MDL-28575 fix for MOODLE_21_STABLE 2011-08-02 23:41:45 +02:00
David Mudrak 11351de2d3 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:32:46 +02:00
David Mudrak 08282ec16c 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:32:25 +02:00
David Mudrak 8981b64a41 MDL-27550 workshop: students do not see peer-assessment that are not graded yet 2011-08-02 23:32:25 +02:00
David Mudrak c6b8bbfa9b MDL-27550 workshop: display the feedback for the submission reviewer when the workshop is closed 2011-08-02 23:32:24 +02:00
David Mudrak 275a6f59d7 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:32:24 +02:00
David Mudrak 308e4280e3 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:32:24 +02:00
Petr Skoda 5d08b03e5b Merge branch 'wip-mdl-27658-m21' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-08-02 15:12:54 +02:00
Petr Skoda e4e3b12325 Merge branch 'MDL-28338_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-02 15:08:48 +02:00
Dan Marsden 97247fdadd MDL-28410 Choice - allow single answer choice to be created 2011-08-02 15:05:01 +02:00
Petr Skoda fb563a9949 Merge branch 'MDL-28507_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-02 14:51:30 +02:00
Dan Marsden f166ab0bec MDL-28535 SCORM remove old IE 6 related warning about zlib 2011-08-02 14:40:41 +02:00
Tim Hunt bae927bebd MDL-28507 fix bad lang string uses, and remove two obsolete strings. 2011-08-02 13:38:39 +01:00
Dan Poltawski 7f62477a87 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-02 13:19:01 +01:00
Sam Hemelryk 5a5e7bb3b1 Merge branch 'MDL-28490_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-02 17:56:14 +08:00
Sam Hemelryk 6f2723ae83 Merge branch 'MDL-28508_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-02 17:47:42 +08:00
Sam Hemelryk 365ed23695 Merge branch 'MDL-28051_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-08-02 17:14:33 +08:00
Andrew Robert Nicols c0c2b3dc1a MDL-28515 Add cli install options for fullname and shortname 2011-08-02 17:07:44 +08:00
Sam Hemelryk 26dcfcb542 Merge branch 'MDL-28340_advanced_search_other_users_21' of git://github.com/andyjdavis/moodle into MOODLE_21_STABLE 2011-08-02 16:59:36 +08:00
Sam Hemelryk 34eee090a7 Merge branch 'wip-mdl-28504-m21' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-08-02 16:51:57 +08:00
Sam Hemelryk 9a1f42da6d Merge branch 'wip-MDL-19907-MOODLE_21_STABLE' of git://github.com/marinaglancy/moodle into MOODLE_21_STABLE 2011-08-02 16:46:07 +08:00
Sam Hemelryk 5be31c5bf2 MDL-27122 admin Improved block protection help string 2011-08-02 16:32:13 +08:00
Sam Hemelryk 3e2569f70d Merge branch 'wip-MDL-27122-MOODLE_21_STABLE' of git://github.com/marinaglancy/moodle into MOODLE_21_STABLE 2011-08-02 16:27:49 +08:00
Sam Hemelryk fa0f970835 Merge branch 'wip-MDL-27754-MOODLE_21_STABLE' of git://github.com/marinaglancy/moodle into MOODLE_21_STABLE 2011-08-02 14:09:30 +08:00
Sam Hemelryk f89a34fb77 Merge branch 's11_MDL-28284_filepicker_module_21' of git://github.com/dongsheng/moodle into MOODLE_21_STABLE 2011-08-02 13:42:12 +08:00
Sam Hemelryk 09e7c66714 Merge branch 'MDL-28510_21_STABLE' of git://github.com/marxjohnson/moodle into MOODLE_21_STABLE 2011-08-02 13:37:17 +08:00
unknown c4eea3e21a Merge branch 'm21_MDL-27876' of git://github.com/danmarsden/moodle into MOODLE_21_STABLE 2011-08-02 13:26:25 +08:00
Piers Harding 189bdcf125 MDL-27876 SCORM auto-adjust the stage height 2011-08-02 17:13:37 +12:00
Sam Hemelryk b587abd989 Merge branch 'MDL-28487-typo_21_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_21_STABLE 2011-08-02 12:23:14 +08:00
Sam Hemelryk 9cacdc07d7 Merged branch 'm21_MDL-28548' of git://github.com/danmarsden/moodle.git with comment changes 2011-08-02 11:46:11 +08:00
AMOS bot e054707e9a Automatically generated installer lang files 2011-08-02 00:55:21 +00:00
Marina Glancy 9cd9d86640 MDL-27754 fixed typo in language string 2011-08-02 08:52:10 +08:00
Marina Glancy 919fcc6f12 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:52:03 +08:00
Marina Glancy f9694db2cb 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:51:40 +08:00
Rossiani Wijaya 2154de3b3c MDL-20501 survey module: fix text alignment for right to left language. Change undefined string to 2011-08-01 17:40:04 +08:00
Sam Hemelryk 0c566ce339 Moodle 2.1.1 release 2011-08-01 16:57:23 +08:00
Rajesh Taneja 5bda1372a1 MDL-27658 javascript: Typo fixed for toUpperCase 2011-08-01 12:53:51 +08:00
Rajesh Taneja 877f061325 MDL-28504 filter: Typo in css fixed 2011-08-01 10:22:57 +08:00
Dan Marsden 263f258ae2 MDL-28548 allow backup to contain info from multiple plagiarism plugins. 2011-08-01 10:28:59 +12:00
Sam Hemelryk 06b04e5c62 weekly release 2.1+ (emergency) 2011-07-29 12:21:57 +08:00
Andrew Davis (andyjdavis) d0752d358e 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:50:51 +08:00
Sam Hemelryk c7f69afe4a Merge branch 'install_21_STABLE' of git://github.com/amosbot/moodle into MOODLE_21_STABLE 2011-07-29 10:13:43 +08:00
Sam Hemelryk 2fa0daefca MDL-28503 comment-caps Slight improvement to allow frontpage and guest users to view comments by default 2011-07-29 09:44:10 +08:00
AMOS bot 89c13e32a0 Automatically generated installer lang files 2011-07-29 00:55:17 +00:00
Wale Olujide 235a394e04 MDL-28051 Question numbers on the question edit page shoud be the same as during the quiz attempt. 2011-07-28 18:03:55 +01:00
Mark Johnson a10ec7f66a MDL-28510 repository_youtube Use smaller thumbnails in search results 2011-07-28 13:46:04 +01:00
Mark Johnson 0638e55b14 MDL-28509 repository_youtube Enable selection of sort order 2011-07-28 13:15:25 +01:00
Tim Hunt a637417d78 MDL-28508 bad string trunction in Aiken format. 2011-07-28 11:52:27 +01:00
Sam Hemelryk 9da3c2efad MDL-28503 Removed the ability for plugins to override comment capabilities and the defaults associated with it 2011-07-28 13:40:06 +08:00
AMOS bot 16e382f8c5 Automatically generated installer lang files 2011-07-28 00:55:17 +00:00
Tim Hunt e12ec6169a MDL-28490 Better class names in the statistics report to help themes. 2011-07-27 19:26:32 +01:00
Tim Hunt 01528075a2 MDL-28338 fix stupid '\n's in the quiz renderer 2011-07-27 19:25:49 +01:00
David Mudrak 3cddd60db7 MDL-28487 Fixed typo in media filter help string 2011-07-27 14:44:17 +02:00
AMOS bot 216113139f Automatically generated installer lang files 2011-07-27 00:55:30 +00:00
Petr Skoda f664cb7c29 weekly release 2.1+ 2011-07-26 11:10:56 +02:00
Petr Skoda 4ac669f1e8 Merge branch 'install_21_STABLE' of git://github.com/amosbot/moodle into MOODLE_21_STABLE 2011-07-26 11:09:49 +02:00
AMOS bot 99b0cba0ec Automatically generated installer lang files 2011-07-26 00:55:24 +00:00
Tim Hunt 526d69522d MDL-28218 allow testclient.php to find the necessary form for services defined in plugins. 2011-07-25 20:05:01 +02:00
Petr Skoda a24681a87a Merge branch 'MDL-28437_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-07-25 19:54:07 +02:00
Petr Skoda e1ad3c38bc Merge branch 'MDL-28369_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-07-25 19:52:26 +02:00
Petr Skoda 7ff71aca59 Merge branch 'MDL-28377_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE 2011-07-25 19:50:18 +02:00
Petr Skoda e205686397 Merge branch 'wip-MDL-28421-MOODLE_21_STABLE' of https://github.com/Beedell/moodle into MOODLE_21_STABLE 2011-07-25 17:03:18 +02:00
Petr Skoda ba295bba29 Merge branch 'wip-MDL-28191-m21' into MOODLE_21_STABLE 2011-07-25 16:46:42 +02:00
Petr Skoda 25f9dae427 Merge branch 'MDL-28453_MOODLE_21_STABLE' into MOODLE_21_STABLE 2011-07-25 16:25:40 +02:00
Tim Hunt d8f77afbb8 MDL-28369 Question hints not being restored. 2011-07-25 10:06:27 +01:00
John Beedell aa4292ad22 MDL-28421 admin config improve class
admin_setting_configmultiselect_modules to include a default
2011-07-25 09:56:55 +01:00
Aparup Banerjee 2d4c4b65d4 MDL-28453 backup - made temporary restoration courses hidden by default. 2011-07-25 16:44:50 +08:00
Tim Hunt ce9423eaa7 MDL-28377 Call to mod_quiz_renderer is screwed up. 2011-07-25 09:16:11 +01:00
Tim Hunt 26a4f319a8 MDL-28437 Question bank pages should all use General type: admin. 2011-07-25 08:52:22 +01:00
Sam Hemelryk 93c5c05423 Merge branch 'MDL-28107_m21' of git://github.com/rwijaya/moodle into MOODLE_21_STABLE 2011-07-25 15:14:27 +08:00
Andrew Davis (andyjdavis) 2f74865eef MDL-27845 rating: split the get_ratings() query into two to reduce query complexity 2011-07-25 14:21:17 +08:00
Andrew Davis (andyjdavis) fc391624f0 MDL-27845 rating: updated rating unit tests 2011-07-25 14:18:38 +08:00
Eloy Lafuente (stronk7) a5224e1f83 rating/lib.php unit tests 1st cut 2011-07-25 14:18:29 +08:00
Sam Hemelryk 30bfe73981 Merge branch 'MDL-28228' of git://git.luns.net.uk/moodle into MOODLE_21_STABLE 2011-07-25 13:04:19 +08:00
Sam Hemelryk b835eebad9 Merge branch 'MDL-28232' of git://git.luns.net.uk/moodle into MOODLE_21_STABLE 2011-07-25 12:57:01 +08:00
Michael Aherne 3152ccf0a4 MDL-27538 Added deprecation details to functions now in $DB 2011-07-25 11:31:39 +08:00
Sam Hemelryk 38a6a195a4 Merge branch 'w29_MDL-22584_m21_monsterpaths' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-25 11:18:37 +08:00
Sam Hemelryk 18c2fcf8f1 Merge branch 'w29_MDL-27464_m21_continue' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-25 11:03:52 +08:00
Sam Hemelryk dbb6d73c8c Merge branch 'w29_MDL-27653_m21_usercasting' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-25 10:59:21 +08:00
Sam Hemelryk ae5375722e Merge branch 'w29_MDL-27796_m21_httphost' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-25 10:55:04 +08:00
Sam Hemelryk 274d9cf950 Merge branch 'w29_MDL-27994_m21_creatorcaps' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-25 10:45:42 +08:00
Sam Hemelryk 7b205e100b Merge branch 'w29_MDL-28145_m21_renderer' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-25 10:39:47 +08:00
Sam Hemelryk 39a84a780b Merge branch 'w29_MDL-28182_m21_userdel' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-25 10:36:55 +08:00
Sam Hemelryk c782b4bb58 Merge branch 'w29_MDL-28337_m21_urlparams' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-25 10:30:00 +08:00
Sam Hemelryk b1591c6568 Merge branch 'w29_MDL-28384_m21_nullurl' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-25 10:14:47 +08:00
Sam Hemelryk 6e48852633 Merge branch 'w29_MDL-28432_m21_cohortconfig' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-25 09:52:49 +08:00
Sam Hemelryk 88b014092d Merge branch 'w29_MDL-28440_m21_jssemicol' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-25 09:45:42 +08:00
Mary Evans 7d8b8d1abe fix for MDL-27768 removed reference to gradient-sb image 2011-07-25 09:40:12 +08:00
Petr Skoda 13d0cc41eb MDL-27653 fix incorrect int | object detection 2011-07-24 15:05:16 +02:00
Petr Skoda f76942869c 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:19:21 +02:00
Petr Skoda 50ecbad305 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:08:27 +02:00
Petr Skoda 1e075c08a0 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:34:43 +02:00
Petr Skoda 4cbc500d1f MDL-28440 add missing semicolon causing JS issues
Credit goes to Mark Nielsen.
2011-07-23 11:49:39 +02:00
Petr Skoda 4e6464937c MDL-22584 deal with oversized dir and file names during upgrade 2011-07-23 11:40:21 +02:00
Petr Skoda cb52b340d3 MDL-28145 fix renderer typo in comments 2011-07-22 23:43:30 +02:00
Petr Skoda f1073b930b MDL-27796 ignore missing HTTP_HOST header 2011-07-22 23:18:13 +02:00
Petr Skoda 4133a3cd5b MDL-28182 always use full user object when deleting users 2011-07-22 22:48:16 +02:00
Petr Skoda bdbb48efe9 MDL-28337 add parameters explanation in URL resource configuration 2011-07-22 22:18:29 +02:00
Petr Skoda 965c9b97ab MDL-28432 use enrol/cohort and enrol/manual capabilities correctly in cohort enrol UI and fix input validation in ajax 2011-07-22 10:14:29 +02:00
Sam Hemelryk 22cf3b24a5 MDL-28191 Continue button after selecting a theme now redirects back to the theme selector 2011-07-22 14:58:06 +08:00
Rossiani Wijaya d19983fac1 MDL-28107 course enrolment icon: Fixed logged in user enrolment icons 2011-07-22 13:22:26 +08:00
AMOS bot 283ccdc71f Automatically generated installer lang files 2011-07-22 00:55:19 +00:00
Dongsheng Cai 279a874108 MDL-28284 don't load filepicker module for every page 2011-07-21 17:27:51 +08:00
AMOS bot e0d9ebc1f2 Automatically generated installer lang files 2011-07-20 00:55:26 +00:00
Petr Skoda aede1fe6a7 weekly release 2.1+ 2011-07-19 15:23:42 +02:00
Petr Skoda f21656d5d0 Merge branch 'install_21_STABLE' of git://github.com/amosbot/moodle into MOODLE_21_STABLE 2011-07-19 15:16:46 +02:00
Petr Skoda feccdaa0ff MDL-27696 initialise arrays
Credit goes to David Mudrak.
2011-07-19 15:04:38 +02:00
Petr Skoda fc7224bac7 MDL-27696 do not use placeholders in GROUP BY because pg does no like that 2011-07-19 10:54:04 +02:00
Petr Skoda 27b4936fcf MDL-27889 use new recaptcha google urls in lang packs 2011-07-19 10:26:30 +02:00
AMOS bot cdf9c89416 Automatically generated installer lang files 2011-07-19 00:55:36 +00:00
Dan Poltawski bf953fe670 MDL-28228 pagelib - incorrect DEBUG constant used 2011-07-19 00:02:56 +01:00
Dan Poltawski 677ee6dee7 MDL-28232 - Course log text export is missing a new line 2011-07-18 23:46:08 +01:00
Petr Skoda 8fa38242d0 Merge branch 'wip-MDL-28040-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-07-18 15:34:09 +02:00
Petr Skoda aa3097da63 Merge branch 'wip-MDL-28184-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-07-18 15:28:54 +02:00
Petr Skoda 719368f8cf Merge branch 'wip-MDL-28205-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-07-18 15:25:31 +02:00
Petr Skoda dd70519ab4 Merge branch 'wip-MDL-28137-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-07-18 15:22:57 +02:00
Petr Skoda 38a1040957 Merge branch 'wip-MDL-27771-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-07-18 15:20:01 +02:00
Petr Skoda ea3317e782 Merge branch 'wip-MDL-27696-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-07-18 15:17:55 +02:00
Petr Skoda f871cc1b8a Merge branch 'wip-MDL-27305-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-07-18 15:14:42 +02:00
Petr Skoda 29d4f2eeb3 Merge branch 'wip-MDL-25870-m21' of git://github.com/samhemelryk/moodle into MOODLE_21_STABLE 2011-07-18 14:57:59 +02:00
Sam Hemelryk a699cbcdbc Merge branch 'wip-MDL-27756-MOODLE_21_STABLE' of github.com:marinaglancy/moodle into MOODLE_21_STABLE 2011-07-18 22:18:52 +10:00
Sam Hemelryk 8910a2d15a Merge branch 'MDL-27555_m21' of git://github.com/rwijaya/moodle into MOODLE_21_STABLE 2011-07-18 21:51:11 +10:00
Sam Hemelryk 0d9cdacf89 Merge branch 'wip-mdl-27837-MOODLE_21_STABLE' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-07-18 21:08:41 +10:00
Sam Hemelryk 982ea16909 Merge branch 'w28_MDL-23344_m21_loginfocus2' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-18 20:26:19 +10:00
Sam Hemelryk 39b10270a1 Merge branch 'w28_MDL-27804_m21_csvauth' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-18 20:19:20 +10:00
Sam Hemelryk 4e579f6067 Merge branch 'w28_MDL-28253_m21_managerupgrade' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-18 20:10:01 +10:00
Sam Hemelryk f6c2b4fc13 Merge branch 'w28_MDL-28313_m21_enroldb' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-18 20:04:01 +10:00
Sam Hemelryk 056c04c9b4 Merge branch 'w28_MDL-28348_m21_meta' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-18 19:39:28 +10:00
Sam Hemelryk 03368c0b2e Merge branch 'w28_MDL-28350_m21_wsra' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-18 19:28:27 +10:00
Petr Skoda 4bc43436b9 Merge branch 'wip-MDL-25125-MOODLE_21_STABLE' of github.com:marinaglancy/moodle into MOODLE_21_STABLE 2011-07-18 09:34:18 +02:00
Sam Hemelryk 5dd5e31616 Merge branch 'w28_MDL-28363_m21_dimmed' of git://github.com/skodak/moodle into MOODLE_21_STABLE 2011-07-19 00:45:35 +10:00
Sam Hemelryk bd202c1531 Merge branch 'MDL-28298-workshop-constant_21_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_21_STABLE 2011-07-19 00:39:36 +10:00
Sam Hemelryk 9190787dff Merge branch 'MDL-28325-enrol-help_21_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_21_STABLE 2011-07-19 00:34:58 +10:00
Sam Hemelryk 3753033ef6 MDL-26482 minor whitespace fix 2011-07-19 00:28:15 +10:00
Sam Hemelryk 0a02548c23 Merge branch 'm21_MDL-26482' of git://github.com/danmarsden/moodle into MOODLE_21_STABLE 2011-07-19 00:27:04 +10:00
Petr Skoda 8399f5a230 MDL-28348 fix spelling and some whitespace issues 2011-07-17 20:40:48 +02:00
Petr Skoda ffbde27300 MDL-28348 fix fatal error caused by unenrolling of incorrect enrol instance 2011-07-17 20:40:47 +02:00
Petr Skoda dd6142b7d2 MDL-28348 prevent circular references in meta handler for enrolments 2011-07-17 20:40:47 +02:00
Petr Skoda d5cb69e9ba MDL-28348 fix meta sync when unassigning roles 2011-07-17 20:40:47 +02:00
Petr Skoda 285e578ed7 MDL-28363 make dimmed selectors more specific to prevent overriding from other themes 2011-07-16 21:04:53 +02:00
AMOS bot e7250e5bd0 Automatically generated installer lang files 2011-07-16 00:55:20 +00:00
Petr Skoda f2b1a6c2ad MDL-28350 prevent bogus role assignment via externallib 2011-07-15 12:24:10 +02:00
Petr Skoda 52bdbe7617 MDL-27804 allow changing of only auth in csv user uploads 2011-07-15 11:08:19 +02:00
David Mudrak bf225ac4c8 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-15 08:53:43 +02:00
AMOS bot 697c3ab6b6 Automatically generated installer lang files 2011-07-15 00:55:18 +00:00
Petr Skoda 0954c43f81 MDL-28313 fix incorrect enrol database settings upgrade 2011-07-14 22:34:03 +02:00
Petr Skoda 536ac72d51 MDL-23344 new option to autofocus username or password on the login form
Nearly everybody else does this login page autofocus. Once we switch to HMTL 5 we should use the new autofocus input option. I believe the admin setting should be enabled by default but it would not be possible to get it through the reviews.
2011-07-14 15:59:21 +02:00
Petr Skoda 1024510a4a MDL-28253 use unique name for new manager role 2011-07-14 13:37:31 +02:00
Marina Glancy 659d31bf25 MDL-27756 Improving move_course() performance 2011-07-14 11:02:43 +08:00
Rajesh Taneja 3012b215f6 MDL-27837 enrol - Fixed checkboxes for multiple self enrolment 2011-07-14 10:04:33 +08:00
Marina Glancy 7a97eccc48 MDL-25125 fix YUI bug with overriding styles 2011-07-14 10:00:52 +08:00
AMOS bot b8dd2bb73c Automatically generated installer lang files 2011-07-14 00:55:18 +00:00
Dan Marsden 2987d698b4 MDL-26482 SCORM add option to disable TOC completely - thanks to Clark Burns for some help! 2011-07-14 11:07:41 +12:00
Dan Marsden 082325c271 MDL-28300 SCORM Fix check for SCORM 2004 thanks to Silvia Bastos for report/patch 2011-07-14 11:02:05 +12:00
Sam Hemelryk 93d82f4601 weekly release 2.1+ 2011-07-13 20:23:04 +08:00
Sam Hemelryk 3a9e75e464 Merge branch 'install_21_STABLE' of git://github.com/amosbot/moodle into MOODLE_21_STABLE 2011-07-13 20:08:56 +08:00
Sam Hemelryk accc55da27 Revert "MDL-23344 fix login form focus"
This reverts commit 2d28584695.
2011-07-13 20:03:56 +08:00
David Mudrak d1c368e050 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:28:04 +02:00
Rossiani Wijaya 35ef97232c MDL-27555 assignment module: remove 'submitted' option from optional setting for offline assignment type. 2011-07-13 15:32:21 +08:00
Sam Hemelryk f3e47fc8d2 MDL-28184 navigation: Tidied up handling of coursenode when adding course essentials 2011-07-13 14:59:31 +08:00
Sam Hemelryk 4479a18d52 MDL-27771 filter-text: Fixed typo contninue 2011-07-13 14:53:12 +08:00
Chris Follin 7869e36193 MDL-27305 forum: Added missing item to forum_get_view_actions 2011-07-13 14:23:08 +08:00
Sam Hemelryk aa132e3f9b MDL-25870 enrol-manual: Fixed pagination of AJAX search results for users when changing search 2011-07-13 14:02:53 +08:00
Sam Hemelryk 34ee79470f MDL-28137 unit tests: Fixed up problem with block manager tests when running unit tests after turning editing on 2011-07-13 13:45:15 +08:00
Sam Hemelryk 9b1ffd0159 MDL-28205 RSS: Fixed up notice and set better pagelayout type on manage feeds page 2011-07-13 10:32:15 +08:00
Sam Hemelryk 9741999e77 MDL-27696 datalib Fixed up misused params in get_logs_usercourse 2011-07-13 10:29:56 +08:00
Sam Hemelryk 3274dc1461 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:00:16 +08:00
Eloy Lafuente (stronk7) fe97a3dc7a Merge branch 'MDL-28221-resource-conversion_21_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_21_STABLE 2011-07-12 19:05:04 +02:00
Eloy Lafuente (stronk7) 6f09ed8643 Merge branch 'm21_MDL-28017' of git://github.com/danmarsden/moodle into MOODLE_21_STABLE 2011-07-12 16:30:33 +02:00
Eloy Lafuente (stronk7) e0dfb65718 MDL-28210 messaging: all includes but config.php must use $CFG-based abosolute paths 2011-07-12 12:21:16 +02:00
Andrew Davis (andyjdavis) 9cf58aba08 MDL-28210 messaging: Fixed requires problems in /message/discussion.php 2011-07-12 12:21:07 +02:00
Petr Skoda c43a4beda8 MDL-28273 waring that removing user from cohorts may unenrol from courses 2011-07-12 16:27:18 +08:00
AMOS bot 64149328dd Automatically generated installer lang files 2011-07-12 00:55:23 +00:00
Dan Marsden 15bec9a365 MDL-28017 SCORM add unset_config for old config var 2011-07-12 09:48:28 +12:00
David Mudrak 665120d4e6 MDL-28221 Legacy resource URL pointing to the course itself are migrated as File module
This patch replays the logic of resource_20_migrate() function. If a
file is referred via URL to the course files of the course being
backed up, then such a resource is converted to the File module
(mod/resource) rather than URL module.
2011-07-11 22:37:34 +02:00
Petr Skoda 74275cf6e5 MDL-22404 add cohort ID to user filters
We are using only ID because there might be hundreds of cohorts in the system at different contexts. There is no special access control because filtering is supposed to be used by admins only.
2011-07-11 20:24:11 +02:00
Eloy Lafuente (stronk7) 1187c38d6d Merge branch 'm21_MDL-26942' of git://github.com/danmarsden/moodle into MOODLE_21_STABLE 2011-07-11 19:48:10 +02:00
Eloy Lafuente (stronk7) a19c77bd24 Merge branch 'MDL-27755_m21' of git://github.com/rwijaya/moodle into MOODLE_21_STABLE 2011-07-11 19:43:53 +02:00
Eloy Lafuente (stronk7) b8cde34b06 Merge branch 'MDL-27741_m21' of git://github.com/rwijaya/moodle into MOODLE_21_STABLE 2011-07-11 19:36:01 +02:00
Petr Skoda 2d28584695 MDL-23344 fix login form focus 2011-07-11 17:23:28 +02:00
Dan Poltawski c261b351cf MDL-23580 course overview - remove debugging junk 2011-07-11 16:47:28 +02:00
Tim Hunt 934c878eaa MDL-26165 quiz submit are-you-sure is potentially confusing. 2011-07-11 16:33:10 +02:00
Tim Hunt b11d374122 MDL-27483 make quiz repagination more robust. 2011-07-11 16:26:36 +02:00
Rossiani Wijaya 337284688d MDL-27931 admin bulk user upload: convert city as required field. Credit goes to Charles Fulton for supplying the patch. 2011-07-11 15:57:45 +02:00
Ruslan Kabalin 661dd2cf61 MDL-28186 messaging: Fix "Enable messagning setting" infuence on the menus
"Enable messaging system" (Site administration > Advanced features) is
supposed to control messaging between site users only, thus it should not
remove user messging preferences menu item. However, it may remove instant
messging preferences from providers list for the user.

Signed-off-by: Ruslan Kabalin <ruslan.kabalin@luns.net.uk>
2011-07-11 15:24:15 +02:00
David Mudrak b0e79df977 MDL-28221 resource: improved file not found handling
When the referenced file is not found, do not rely on the record in
resource_old as the resource can be actually restored from a 1.9 backup.
2011-07-11 12:12:38 +02:00
David Mudrak 6ca0ba0104 MDL-28221 resource: fixed a typo in variable names 2011-07-11 12:04:18 +02:00
Rossiani Wijaya 153694ed0a 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:04:05 +08:00
Sam Hemelryk 1541d1a36b Merge branch 'wip-mdl-27954-MOODLE_21_STABLE' of git://github.com/rajeshtaneja/moodle into MOODLE_21_STABLE 2011-07-11 16:02:18 +08:00
Tim Hunt c159d8e872 MDL-28195 confirm_action should allow the button labels to be customised 2011-07-11 15:03:39 +08:00
Sam Hemelryk a8361fc214 Merge branch 'wip-MDL-27429-m21' of git://github.com/Beedell/moodle into MOODLE_21_STABLE 2011-07-11 13:56:39 +08:00
Jamie Pratt 96c7aa3fe5 MDL-28268 Missing ORDER BY when using extra answer table.
From OU bug #921 "Order of answer fields in Variable numeric keeps changing" Cannot
reproduce this bug on my system but hopefully this will fix the problem. I added
an ORDER BY clause to the sql for fetching answers with extra answer fields.
2011-07-11 13:26:39 +08:00
Tim Hunt a3b71db63b MDL-28192 local_qeupgradehelper fix typo. 2011-07-11 13:18:37 +08:00
Dan Marsden 66c36644d3 MDL-28017 SCORM - remove admin setting incorrectly added as it was never used. 2011-07-11 15:44:50 +12:00
Sam Hemelryk 903c12c74b Merge branch 'm21_MDL-27947' of git://github.com/danmarsden/moodle into MOODLE_21_STABLE 2011-07-11 11:31:48 +08:00
Sam Hemelryk 73d78d8de4 Merge branch 'MDL-27890_m21' of git://github.com/stronk7/moodle into MOODLE_21_STABLE 2011-07-11 11:25:56 +08:00
Sam Hemelryk bbdd6f2dc1 Merge branch 'glossary_multilang_m21' of git://github.com/stronk7/moodle into MOODLE_21_STABLE 2011-07-11 11:15:17 +08:00
Sam Hemelryk f738eb06e7 Merge branch 'mod_url_decode_m21' of git://github.com/stronk7/moodle into MOODLE_21_STABLE 2011-07-11 11:04:18 +08:00
Sam Hemelryk 6f30a86bc7 Merge branch 'backup_groups_m21' of git://github.com/stronk7/moodle into MOODLE_21_STABLE 2011-07-11 10:57:15 +08:00
Rajesh Taneja 4db5d94af5 MDL-27954 mod_database - fixed search navigation link 2011-07-11 10:28:47 +08:00
Eloy Lafuente (stronk7) 5299507674 MDL-28048 glossary - fix double ampersand & missing string 2011-07-11 01:40:27 +02:00
Eloy Lafuente (stronk7) d5a8ec5ccd MDL-28048 glossary - add multilang support to categories 2011-07-11 01:03:58 +02:00
Eloy Lafuente (stronk7) 4daa20bb5b MDL-28156 restore - fix some notices restoring empty courses 2011-07-10 13:12:49 +02:00
Eloy Lafuente (stronk7) 3a32daedb5 MDL-28156 restore - support restoring files without grade items 2011-07-10 00:53:29 +02:00
Eloy Lafuente (stronk7) 130fcbd649 MDL-27438 backup - on course backups add course gropus and groupings 2011-07-09 19:28:50 +02:00
Eloy Lafuente (stronk7) 96ab22afc8 MDL-27018 restore - decode links missing url->externalurl support 2011-07-09 13:35:51 +02:00
AMOS bot b88f5de7ec Automatically generated installer lang files 2011-07-09 00:55:20 +00:00
Dan Marsden 0ae4c47c76 MDL-27947 - fix TOC display on skipview - use correct org in TOC title 2011-07-09 11:48:22 +12:00
Dan Marsden 60201a66e0 SCORM MDL-26942 - merge scorm_get_toc into a single global function 2011-07-09 11:12:18 +12:00
John Beedell 5a062fcd8f MDL-27429 Adding tabindex and on keypress to the blocks show/hide icon. 2011-07-08 12:31:49 +01:00
AMOS bot 4481d845e1 Automatically generated installer lang files 2011-07-08 12:34:51 +02:00
Rossiani Wijaya fefd37d864 MDL-27755 course search: Add course id and shortname to search fields 2011-07-08 17:24:26 +08:00
Eloy Lafuente (stronk7) a938306457 weekly release 2.1+ 2011-07-08 11:22:28 +02:00
Eloy Lafuente (stronk7) 8718d91313 fix permissions 2011-07-08 11:12:55 +02:00
Eloy Lafuente (stronk7) 24813d35f7 Merge branch 'MDL-28015-workshop-sql_21_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_21_STABLE 2011-07-08 01:18:44 +02:00
Eloy Lafuente (stronk7) 8437ce030d Merge branch 'MDL-28168-custommenu_21_STABLE' of git://github.com/mudrd8mz/moodle into MOODLE_21_STABLE 2011-07-08 00:58:08 +02:00
Tim Hunt 583e6a6992 MDL-27890 tinymce - enable 30 as min height within moodle 2011-07-07 19:59:35 +02:00
Eloy Lafuente (stronk7) f738546c8f MDL-NOBUG tinymce - updated instructions to cover local modifications and other minor changes 2011-07-07 18:21:15 +02:00
Eloy Lafuente (stronk7) 0e24cfb800 MDL-27890 tinymce - allow it to be smaller 2011-07-07 17:36:59 +02:00
David Mudrak cabce0e259 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:16:29 +02:00
Sun Zhigang fbe00fbec7 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 10:39:24 +02:00
Aparup Banerjee 2fa78e85e9 MDL-28169 Installation Added 2.1 upgrade (idiot proof) lines to upgrade scripts. 2011-07-07 10:24:38 +02:00
Petr Skoda dd402d1fa3 MDL-28163 custom site frontpage support 2011-07-07 10:15:34 +02:00
Eloy Lafuente (stronk7) 14cf05a2cf Merge branch 'm21_MDL-28110' of git://github.com/danmarsden/moodle into MOODLE_21_STABLE 2011-07-07 03:01:30 +02:00
Eloy Lafuente (stronk7) acfa08a69f MDL-27989 whitespace fix 2011-07-07 02:22:54 +02:00
Eloy Lafuente (stronk7) e986a24a9d Merge branch 'MDL-27989_MOODLE_21_STABLE' of git://github.com/kordan/moodle into MOODLE_21_STABLE 2011-07-07 02:22:22 +02:00
Dan Poltawski 7a0374f6e7 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:11:44 +02:00
Petr Skoda 78087ddfa5 MDL-27375 add missing lowercasing of external column names
Credit goes to Gail Preuninger.
2011-07-07 01:40:35 +02:00
Petr Skoda bde4f81335 MDL-28117 include repo lib when hacking file_picker renderer 2011-07-07 01:34:12 +02:00
Dan Poltawski 334b4f6301 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.
2011-07-07 00:25:11 +02:00
Dan Poltawski e4318be030 MDL-28100 - page resource was not using context for text filtering 2011-07-07 00:12:46 +02:00
Dan Poltawski 4c26ea1713 MDL-27279 lang/en/xmldb - Fix Typo in confirmcheckforeignkeys 2011-07-07 00:01:45 +02:00
Tim Hunt 40ff08d84f MDL-28222 quiz reports missing context in call to quiz_report_feedback_for_grade. 2011-07-06 20:29:20 +02:00
Tim Hunt 9a1da08340 MDL-27040 get_users_by_capability generates u.id IN () when no uesrs have accessallgroups 2011-07-06 19:26:30 +02:00
Tim Hunt eeb78f323a MDL-28166 fix some more instances of my favourite becuase typo. 2011-07-06 19:21:02 +02:00
Tim Hunt 54bf1cf7dc MDL-28166 send quiz event notifications asynchronously.
This avoids the problem that you cannot send messages in transactions.

It also means that the quiz submission will not be prevented, and the
message will still be sent eventually, if any part of the messaging
system is giving intermittent errors when the student wants to submit
their quiz.
2011-07-06 19:20:50 +02:00
Sun Zhigang 376d87ca03 MDL-27934 Upload Assignment - Remove useless code 2011-07-06 13:26:21 +08:00
Dan Poltawski fbb580c38a MDL-27855 navigation - only display participants link with permissions 2011-07-06 13:20:46 +08:00
Dan Poltawski 35a39e35e2 MDL-27168 completionstatus block - Use localized strings 2011-07-06 12:04:16 +08:00
Dan Poltawski 84a05572c9 MDL-26626 course competion block - fix hardcoded string 2011-07-06 11:21:35 +08:00
Dan Poltawski c01d7b4d79 MDL-26611 Roles Language - remove reference to 'legacy role type' 2011-07-06 11:10:08 +08:00
Sam Hemelryk baa97ed623 Merge branch 'MDL-28135_MOODLE_21_STABLE' of git://github.com/nebgor/moodle into MOODLE_21_STABLE 2011-07-06 11:02:55 +08:00
Petr Skoda 05f4555422 MDL-28147 do not double cache theme css/js 2011-07-06 03:15:03 +02:00
Tim Hunt a5dd15e921 MDL-28160 question preview window uses wrong pagelayout in activity contexts 2011-07-06 03:08:41 +02:00
Petr Skoda 05299908b4 MDL-28161 precreate htmlpurifier dir when resetting caches
Includes sloppy whitespace fix.
2011-07-06 02:55:00 +02:00
Petr Skoda 9a49e6004b MDL-28167 fix missing new
And sloppy whitespace.
2011-07-06 02:09:54 +02:00
Sam Hemelryk a3fd215cb8 MDL-28172 forum: Fixed up overzealous check for portfolio enabled. 2011-07-06 02:02:02 +02:00
Tim Hunt 6ff0bacee1 MDL-28179 make failed event hander error message much more useful. 2011-07-06 01:49:02 +02:00
Andrew Robert Nicols 757ca142ca MDL-28193 Add $external arg to get_driver_instance
Signed-off-by: Andrew Robert Nicols <andrew.nicols@luns.net.uk>
2011-07-06 01:40:35 +02:00
Eloy Lafuente (stronk7) 98e86d8b27 MDL-28196 quiz calls get_in_or_equal (fixing missing $DB) 2011-07-05 22:00:51 +02:00
Tim Hunt 69b88de0df MDL-28196 quiz calls get_in_or_equal (not DB->get_in_or_equal) in two places
Also, another minor error in one method call.
2011-07-05 21:56:37 +02:00
Tim Hunt 17b8d59a0a MDL-27821 backup_exception should not throw away debug info. 2011-07-05 19:43:54 +02:00
Eloy Lafuente (stronk7) d396a03bac Merge branch 'MDL-28185_m21' of git://github.com/stronk7/moodle into MOODLE_21_STABLE 2011-07-05 17:59:57 +02:00
Tim Hunt f404343487 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-05 17:47:37 +02:00
Eloy Lafuente (stronk7) f8632149ad MDL-28185 upgrade - fix oracle problem upgrading blocks 2011-07-05 15:38:09 +02:00
David Mudrak a056d4fa9e MDL-28168 Multi-language support for custom_menu reimplemented
This is a reimplementation of the multi-language support for the
custom_menu class. The menu items now accept the forth optional
parameter with the explicit list of languages the item is valid for. If
no languages are listed, the item is valid for any language. The caller
of the custom_menu constructor must provide the user's current language
or null if the multi-language should not be supported (all items are
valid for any language then, regardless the definition).

See the attached unit tests for the examples of usage.
2011-07-05 12:22:26 +02:00
Kordan 3c9cd14006 addition to previous fix for MDL-27989 in MOODLE_21_STABLE 2011-07-05 11:30:50 +02:00
Tim Hunt d5670c612b MDL-25357 Allow maximum number of sections to be set by the admin. Also allow 0 sections at an choice.
Also fix one bad <br/> in another lang string.
2011-07-05 16:59:57 +08:00
David Mudrak 88d9d9fba5 MDL-28168 Improved custom_menu constructor
This improves custom_menu constructor by dropping support for useless
$text parameter and replacing it with the menu definition. This makes
custom_menu instance independent on the place where the menu is defined
($CFG->custommenuitems) and can be unit-tested. Also, multiple instances
of custom_menu can be instantiated now which can be interesting in the
future.
2011-07-05 10:26:01 +02:00
Kordan cc3e8c536c MDL-27989 fix for MOODLE_21_STABLE 2011-07-05 10:21:13 +02:00
Aparup Banerjee a43b8cf330 MDL-28135 general Updated broken and typo docs links 2011-07-05 15:17:23 +08:00
Aparup Banerjee 028fba6878 MDL-28135 general Updated the Copyright notice to point to docs.moodle.org/dev/Releases instead of en/Release 2011-07-05 15:17:15 +08:00
Aparup Banerjee 8f32d623c5 MDL-28135 general Updated doc links related to Release notes to docs.moodle.org/dev/Releases now 2011-07-05 15:17:06 +08:00
Aparup Banerjee 63e8936bb1 MDL-28135 general Updating all hardcoded "docs.moodle.org/en/Development:" type doc links to "docs.moodle.org/dev/" 2011-07-05 15:16:55 +08:00
David Mudrak 5b806d1524 MDL-28168 Revert "MDL-27073 Support multi-language content in custom menu"
This reverts commit 87e0230d0a.
2011-07-05 09:08:49 +02:00
Iñaki Arenaza 7679e8d256 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).

Signed-off-by: Iñaki Arenaza <iarenaza@mondragon.edu>
2011-07-04 21:46:44 +02:00
Dan Marsden e1a1827b59 SCORM MDL-28110 fix string name 2011-07-03 12:54:41 +12:00
Dan Marsden 9f098ef0ec SCORM MDL-28110 set default for forcejavascript to yes - add string explaining what it does. 2011-07-03 12:54:31 +12:00
6489 changed files with 481366 additions and 643155 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ $returnurl = new moodle_url('/admin/settings.php', array('section'=>'manageauths
$PAGE->set_url($returnurl);
$action = optional_param('action', '', PARAM_ACTION);
$auth = optional_param('auth', '', PARAM_PLUGIN);
$auth = optional_param('auth', '', PARAM_SAFEDIR);
get_enabled_auth_plugins(true); // fix the list of enabled auths
if (empty($CFG->auth)) {
+1 -1
View File
@@ -6,7 +6,7 @@
require_once '../config.php';
require_once $CFG->libdir.'/adminlib.php';
$auth = required_param('auth', PARAM_PLUGIN);
$auth = required_param('auth', PARAM_SAFEDIR);
$PAGE->set_pagetype('admin-auth-' . $auth);
admin_externalpage_setup('authsetting'.$auth);
+28 -3
View File
@@ -98,9 +98,34 @@
exit;
} else {
uninstall_plugin('block', $block->name);
// Inform block it's about to be deleted
if (file_exists("$CFG->dirroot/blocks/$block->name/block_$block->name.php")) {
$blockobject = block_instance($block->name);
if ($blockobject) {
$blockobject->before_delete(); //only if we can create instance, block might have been already removed
}
}
// First delete instances and then block
$instances = $DB->get_records('block_instances', array('blockname' => $block->name));
if(!empty($instances)) {
foreach($instances as $instance) {
blocks_delete_instance($instance);
}
}
// Delete block
$DB->delete_records('block', array('id'=>$block->id));
drop_plugin_tables($block->name, "$CFG->dirroot/blocks/$block->name/db/install.xml", false); // old obsoleted table names
drop_plugin_tables('block_'.$block->name, "$CFG->dirroot/blocks/$block->name/db/install.xml", false);
// Delete the capabilities that were defined by this block
capabilities_cleanup('block/'.$block->name);
// Remove event handlers and dequeue pending events
events_uninstall('block/'.$block->name);
$a = new stdClass();
$a->block = $strblockname;
$a->directory = $CFG->dirroot.'/blocks/'.$block->name;
notice(get_string('blockdeletefiles', '', $a), 'blocks.php');
@@ -225,7 +250,7 @@
$tablerows[] = array(strip_tags($strblockname), $row); // first element will be used for sorting
}
collatorlib::asort($tablerows);
textlib_get_instance()->asort($tablerows);
foreach ($tablerows as $row) {
$table->add_data($row[1]);
}
+152
View File
@@ -0,0 +1,152 @@
<?php
/// Create "blog" forums in each course and copy blog entries from these courses' participants in these forums
define('NO_OUTPUT_BUFFERING', true);
require_once('../config.php');
require_once($CFG->dirroot.'/course/lib.php');
require_once($CFG->dirroot.'/blog/lib.php');
require_once($CFG->dirroot.'/mod/forum/lib.php');
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('bloglevelupgrade');
$PAGE->set_pagelayout('maintenance');
$go = optional_param('go', 0, PARAM_BOOL);
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('bloglevelupgrade', 'admin'));
$strbloglevelupgrade = get_string('bloglevelupgradeinfo', 'admin');
if (!$go or !data_submitted() or !confirm_sesskey()) { /// Print a form
$optionsyes = array('go'=>1, 'sesskey'=>sesskey());
echo $OUTPUT->confirm($strbloglevelupgrade, new moodle_url('bloglevelupgrade.php', $optionsyes), 'index.php');
echo $OUTPUT->footer();
die;
}
echo $OUTPUT->box_start();
/// Turn off time limits, sometimes upgrades can be slow.
set_time_limit(0);
$i = 0;
// If $CFG->bloglevel is set to BLOG_GROUP_LEVEL or BLOG_COURSE_LEVEL, create a new "blog" forum in each course
// whose enrolled students have written blog entries, copy these entries in that forum and switch off blogs at site level
if ($CFG->bloglevel == BLOG_COURSE_LEVEL || $CFG->bloglevel == BLOG_GROUP_LEVEL) {
$pbar = new progress_bar('bloglevelupgrade', 500, true);
$bloggers = $DB->get_records_sql("SELECT userid FROM {post} WHERE module = 'blog' GROUP BY userid");
require_once($CFG->dirroot.'/mod/forum/lib.php');
$a = new stdClass();
$a->userscount = 0;
$a->blogcount = 0;
foreach ($bloggers as $blogger) {
$courses = enrol_get_users_courses($blogger->userid, true, 'groupmode,groupmodeforce');
$blogentries = $DB->get_records('post', array('module' => 'blog', 'userid' => $blogger->userid));
foreach ($courses as $course) {
$forum = forum_get_course_forum($course->id, 'blog');
$cm = get_coursemodule_from_instance('forum', $forum->id);
if ($CFG->bloglevel == BLOG_GROUP_LEVEL && $course->groupmode != NOGROUPS) {
// Unless the course is set to separate groups forced, force the forum to Separate groups
if (!($course->groupmode == SEPARATEGROUPS && $course->groupmodeforce)) {
$cm->groupmode = SEPARATEGROUPS;
$DB->update_record('course_modules', $cm);
}
$groups = groups_get_user_groups($course->id, $blogger->userid);
foreach ($groups[0] as $groupid) { // [0] is for all groupings combined
$a->blogcount += bloglevelupgrade_entries($blogentries, $forum, $cm, $groupid);
}
} else {
$a->blogcount += bloglevelupgrade_entries($blogentries, $forum, $cm);
}
}
$a->userscount = $i . '/' . count($bloggers);
$pbar->update($i, count($bloggers), get_string('bloglevelupgradeprogress', 'admin', $a));
$i++;
}
}
function bloglevelupgrade_entries($blogentries, $forum, $cm, $groupid=-1) {
$count = 0;
$forumcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
$sitecontext = get_context_instance(CONTEXT_SYSTEM);
foreach ($blogentries as $blogentry) {
$discussion = new stdClass();
$discussion->course = $forum->course;
$discussion->forum = $forum->id;
$discussion->name = $blogentry->subject;
$discussion->assessed = $forum->assessed;
$discussion->message = $blogentry->summary;
$discussion->messageformat = $blogentry->summaryformat;
$discussion->messagetrust = 0;
$discussion->attachments = 0;
$discussion->mailnow = false;
$discussion->timemodified = $blogentry->created;
$discussion->itemid = null;
$discussion->groupid = $groupid;
$message = '';
$discussionid = forum_add_discussion($discussion, null, $message);
// Copy file attachment records
$fs = get_file_storage();
$files = $fs->get_area_files($sitecontext->id, 'blog', 'attachment', $blogentry->id);
if (!empty($files)) {
foreach ($files as $storedfile) {
$newfile = new stdClass();
$newfile->component = 'mod_forum';
$newfile->filearea = 'attachment';
$newfile->itemid = $discussion->firstpost;
$newfile->contextid = $forumcontext->id;
$fs->create_file_from_storedfile($newfile, $storedfile->get_id());
}
}
$files = $fs->get_area_files($sitecontext->id, 'blog', 'post', $blogentry->id);
if (!empty($files)) {
foreach ($files as $storedfile) {
$newfile = new stdClass();
$newfile->component = 'mod_forum';
$newfile->filearea = 'post';
$newfile->itemid = $discussion->firstpost;
$newfile->contextid = $forumcontext->id;
$fs->create_file_from_storedfile($newfile, $storedfile->get_id());
}
}
$count++;
}
return $count;
}
// END OF LOOP
// set conversion flag - switches to new plugin automatically
set_config('bloglevel_upgrade_complete', 1);
// Finally switch bloglevel to 0 (disabled)
set_config('bloglevel', 0);
echo $OUTPUT->box_end();
/// Rebuild course cache which might be incorrect now
echo $OUTPUT->notification('Rebuilding course cache...', 'notifysuccess');
rebuild_course_cache();
echo $OUTPUT->notification('...finished', 'notifysuccess');
echo $OUTPUT->continue_button('index.php');
echo $OUTPUT->footer();
die;
+13 -49
View File
@@ -20,6 +20,7 @@
*
* This script is not intended for beginners!
* Potential problems:
* - environment check is not present yet
* - su to apache account or sudo before execution
* - not compatible with Windows platform
*
@@ -78,16 +79,6 @@ Example:
"; //TODO: localize, mark as needed in install - to be translated later when everything is finished
// distro specific customisation
$distrolibfile = dirname(dirname(dirname(__FILE__))).'/install/distrolib.php';
$distro = null;
if (file_exists($distrolibfile)) {
require_once($distrolibfile);
if (function_exists('distro_get_config')) {
$distro = distro_get_config();
}
}
// Nothing to do if config.php exists
$configfile = dirname(dirname(dirname(__FILE__))).'/config.php';
if (file_exists($configfile)) {
@@ -100,16 +91,12 @@ if (file_exists($configfile)) {
echo "\n\n";
}
if ($DB->get_manager()->table_exists('config')) {
cli_error(get_string('clialreadyinstalled', 'install'));
} else {
cli_error(get_string('clialreadyconfigured', 'install'));
}
cli_error(get_string('clialreadyinstalled', 'install'));
}
$olddir = getcwd();
// change directory so that includes below work properly
// change directory so that includes bellow work properly
chdir(dirname($_SERVER['argv'][0]));
// Servers should define a default timezone in php.ini, but if they don't then make sure something is defined.
@@ -143,6 +130,7 @@ $CFG->dirroot = dirname(dirname(dirname(__FILE__)));
$CFG->libdir = "$CFG->dirroot/lib";
$CFG->wwwroot = "http://localhost";
$CFG->httpswwwroot = $CFG->wwwroot;
$CFG->dataroot = str_replace('\\', '/', dirname(dirname(dirname(dirname(__FILE__)))).'/moodledata');
$CFG->docroot = 'http://docs.moodle.org';
$CFG->running_installer = true;
$CFG->early_install_lang = true;
@@ -190,14 +178,14 @@ if (empty($databases)) {
// now get cli options
list($options, $unrecognized) = cli_get_params(
array(
'chmod' => isset($distro->directorypermissions) ? sprintf('%04o',$distro->directorypermissions) : '2777', // let distros set dir permissions
'chmod' => '2777',
'lang' => $CFG->lang,
'wwwroot' => '',
'dataroot' => empty($distro->dataroot) ? str_replace('\\', '/', dirname(dirname(dirname(dirname(__FILE__)))).'/moodledata'): $distro->dataroot, // initialised later after including libs or by distro
'dbtype' => empty($distro->dbtype) ? $defaultdb : $distro->dbtype, // let distro skip dbtype selection
'dbhost' => empty($distro->dbhost) ? 'localhost' : $distro->dbhost, // let distros set dbhost
'dataroot' => $CFG->dataroot,
'dbtype' => $defaultdb,
'dbhost' => 'localhost',
'dbname' => 'moodle',
'dbuser' => empty($distro->dbuser) ? 'root' : $distro->dbuser, // let distros set dbuser
'dbuser' => 'root',
'dbpass' => '',
'dbsocket' => false,
'prefix' => 'mdl_',
@@ -277,7 +265,7 @@ if ($interactive) {
$chmod = octdec(clean_param($options['chmod'], PARAM_INT));
if ($interactive) {
cli_separator();
cli_heading(get_string('datarootpermission', 'install'));
cli_heading('Data directories permission'); // todo localize
$prompt = get_string('clitypevaluedefault', 'admin', decoct($chmod));
$error = '';
do {
@@ -337,7 +325,9 @@ $CFG->httpswwwroot = $CFG->wwwroot;
//We need dataroot before lang download
$CFG->dataroot = $options['dataroot'];
if (!empty($options['dataroot'])) {
$CFG->dataroot = $options['dataroot'];
}
if ($interactive) {
cli_separator();
$i=0;
@@ -385,8 +375,6 @@ if ($interactive) {
cli_error(get_string('pathserrcreatedataroot', 'install', $a));
}
}
$CFG->tempdir = $CFG->dataroot.'/temp';
$CFG->cachedir = $CFG->dataroot.'/cache';
// download required lang packs
if ($CFG->lang !== 'en') {
@@ -528,9 +516,6 @@ if ($interactive) {
}
$CFG->dbpass = cli_input($prompt, $options['dbpass']);
if (function_exists('distro_pre_create_db')) { // Hook for distros needing to do something before DB creation
$distro = distro_pre_create_db($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, array('dbpersist'=>0, 'dbsocket'=>$options['dbsocket']), $distro);
}
$hint_database = install_db_validate($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, array('dbpersist'=>0, 'dbsocket'=>$options['dbsocket']));
} while ($hint_database !== '');
@@ -660,27 +645,6 @@ require($configfile);
$CFG->lang = $installlang;
$SESSION->lang = $CFG->lang;
require("$CFG->dirroot/version.php");
// Test environment first.
require_once($CFG->libdir . '/environmentlib.php');
list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
if (!$envstatus) {
$errors = environment_get_errors($environment_results);
cli_heading(get_string('environment', 'admin'));
foreach ($errors as $error) {
list($info, $report) = $error;
echo "!! $info !!\n$report\n\n";
}
exit(1);
}
// Test plugin dependencies.
require_once($CFG->libdir . '/pluginlib.php');
if (!plugin_manager::instance()->all_plugins_ok($version)) {
cli_error(get_string('pluginschecktodo', 'admin'));
}
install_cli_database($options, $interactive);
echo get_string('cliinstallfinished', 'install')."\n";
+2 -22
View File
@@ -46,8 +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=STRING Name of the site
--shortname=STRING Name of the site
--fullname Name of the site
--shortname Name of the site
-h, --help Print out this help
Example:
@@ -144,26 +144,6 @@ if ($CFG->lang !== 'en') {
$CFG->early_install_lang = false;
get_string_manager(true);
require("$CFG->dirroot/version.php");
// Test environment first.
require_once($CFG->libdir . '/environmentlib.php');
list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
if (!$envstatus) {
$errors = environment_get_errors($environment_results);
cli_heading(get_string('environment', 'admin'));
foreach ($errors as $error) {
list($info, $report) = $error;
echo "!! $info !!\n$report\n\n";
}
exit(1);
}
// Test plugin dependencies.
require_once($CFG->libdir . '/pluginlib.php');
if (!plugin_manager::instance()->all_plugins_ok($version)) {
cli_error(get_string('pluginschecktodo', 'admin'));
}
install_cli_database($options, true);
-211
View File
@@ -1,211 +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/>.
/**
* MySQL collation conversion tool.
*
* @package core
* @copyright 2012 Petr Skoda (http://skodak.org)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once($CFG->libdir.'/clilib.php'); // cli only functions
if ($DB->get_dbfamily() !== 'mysql') {
cli_error('This function is designed for MySQL databases only!');
}
// now get cli options
list($options, $unrecognized) = cli_get_params(array('help'=>false, 'list'=>false, 'collation'=>false, 'available'=>false),
array('h'=>'help', 'l'=>'list', 'a'=>'available'));
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
$help =
"MySQL collation conversions script.
It is strongly recommended to stop the web server before the conversion.
This script may be executed before the main upgrade - 1.9.x data for example.
Options:
--collation=COLLATION Convert MySQL tables to different collation
-l, --list Show table and column information
-a, --available Show list of available collations
-h, --help Print out this help
Example:
\$ sudo -u www-data /usr/bin/php admin/cli/mysql_collation.php --collation=utf8_general_ci
";
if (!empty($options['collation'])) {
$collations = mysql_get_collations();
$collation = clean_param($options['collation'], PARAM_ALPHANUMEXT);
$collation = strtolower($collation);
if (!isset($collations[$collation])) {
cli_error("Error: collation '$collation' is not available on this server!");
}
echo "Converting tables and columns to '$collation' for $CFG->wwwroot:\n";
$prefix = $DB->get_prefix();
$prefix = str_replace('_', '\\_', $prefix);
$sql = "SHOW TABLE STATUS WHERE Name LIKE BINARY '$prefix%'";
$rs = $DB->get_recordset_sql($sql);
$converted = 0;
$skipped = 0;
$errors = 0;
foreach ($rs as $table) {
echo str_pad($table->name, 40). " - ";
if ($table->collation === $collation) {
echo "NO CHANGE\n";
$skipped++;
} else {
$DB->change_database_structure("ALTER TABLE $table->name DEFAULT COLLATE = $collation");
echo "CONVERTED\n";
$converted++;
}
$sql = "SHOW FULL COLUMNS FROM $table->name WHERE collation IS NOT NULL";
$rs2 = $DB->get_recordset_sql($sql);
foreach ($rs2 as $column) {
$column = (object)array_change_key_case((array)$column, CASE_LOWER);
echo ' '.str_pad($column->field, 36). " - ";
if ($column->collation === $collation) {
echo "NO CHANGE\n";
$skipped++;
continue;
}
if ($column->type === 'tinytext' or $column->type === 'mediumtext' or $column->type === 'text' or $column->type === 'longtext') {
$notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
$default = (!is_null($column->default) and $column->default !== '') ? "DEFAULT '$column->default'" : '';
// primary, unique and inc are not supported for texts
$sql = "ALTER TABLE $table->name MODIFY COLUMN $column->field $column->type COLLATE $collation $notnull $default";
$DB->change_database_structure($sql);
} else if (strpos($column->type, 'varchar') === 0) {
$notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
$default = !is_null($column->default) ? "DEFAULT '$column->default'" : '';
// primary, unique and inc are not supported for texts
$sql = "ALTER TABLE $table->name MODIFY COLUMN $column->field $column->type COLLATE $collation $notnull $default";
$DB->change_database_structure($sql);
} else {
echo "ERROR (unknown column type: $column->type)\n";
$error++;
continue;
}
echo "CONVERTED\n";
$converted++;
}
$rs2->close();
}
$rs->close();
echo "Converted: $converted, skipped: $skipped, errors: $errors\n";
exit(0); // success
} else if (!empty($options['list'])) {
echo "List of tables for $CFG->wwwroot:\n";
$prefix = $DB->get_prefix();
$prefix = str_replace('_', '\\_', $prefix);
$sql = "SHOW TABLE STATUS WHERE Name LIKE BINARY '$prefix%'";
$rs = $DB->get_recordset_sql($sql);
$counts = array();
foreach ($rs as $table) {
if (isset($counts[$table->collation])) {
$counts[$table->collation]++;
} else {
$counts[$table->collation] = 1;
}
echo str_pad($table->name, 40);
echo $table->collation. "\n";
$collations = mysql_get_column_collations($table->name);
foreach ($collations as $columname=>$collation) {
if (isset($counts[$collation])) {
$counts[$collation]++;
} else {
$counts[$collation] = 1;
}
echo ' ';
echo str_pad($columname, 36);
echo $collation. "\n";
}
}
$rs->close();
echo "\n";
echo "Table collations summary for $CFG->wwwroot:\n";
foreach ($counts as $collation => $count) {
echo "$collation: $count\n";
}
exit(0); // success
} else if (!empty($options['available'])) {
echo "List of available MySQL collations for $CFG->wwwroot:\n";
$collations = mysql_get_collations();
foreach ($collations as $collation) {
echo " $collation\n";
}
die;
} else {
echo $help;
die;
}
// ========== Some functions ==============
function mysql_get_collations() {
global $DB;
$collations = array();
$sql = "SHOW COLLATION WHERE Collation LIKE 'utf8\_%' AND Charset = 'utf8'";
$rs = $DB->get_recordset_sql($sql);
foreach ($rs as $collation) {
$collations[$collation->collation] = $collation->collation;
}
$rs->close();
$collation = $DB->get_dbcollation();
if (isset($collations[$collation])) {
$collations[$collation] .= ' (default)';
}
return $collations;
}
function mysql_get_column_collations($tablename) {
global $DB;
$collations = array();
$sql = "SELECT column_name, collation_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = DATABASE() AND table_name = ? AND collation_name IS NOT NULL";
$rs = $DB->get_recordset_sql($sql, array($tablename));
foreach($rs as $record) {
$collations[$record->column_name] = $record->collation_name;
}
$rs->close();
return $collations;
}
+1 -7
View File
@@ -76,13 +76,7 @@ if (!empty($options['engine'])) {
}
echo str_pad($table->name, 40). " - ";
try {
$DB->change_database_structure("ALTER TABLE {$table->name} ENGINE = $engine");
} catch (moodle_exception $e) {
echo $e->getMessage()."\n";
$skipped++;
continue;
}
$DB->change_database_structure("ALTER TABLE {$table->name} TYPE = $engine");
echo "DONE\n";
$converted++;
}
-53
View File
@@ -1,53 +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 cli
* @copyright 2011 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once($CFG->libdir.'/clilib.php');
list($options, $unrecognized) = cli_get_params(array('help' => false), array('h' => 'help'));
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized), 2);
}
if ($options['help']) {
$help =
"Invalidates all Moodle internal caches
Options:
-h, --help Print out this help
Example:
\$sudo -u www-data /usr/bin/php admin/cli/purge_caches.php
";
echo $help;
exit(0);
}
purge_all_caches();
exit(0);
+4 -13
View File
@@ -20,6 +20,7 @@
*
* This script is not intended for beginners!
* Potential problems:
* - environment check is not present yet
* - su to apache account or sudo before execution
* - not compatible with Windows platform
*
@@ -36,7 +37,7 @@ require_once($CFG->libdir.'/adminlib.php'); // various admin-only function
require_once($CFG->libdir.'/upgradelib.php'); // general upgrade/install related functions
require_once($CFG->libdir.'/clilib.php'); // cli only functions
require_once($CFG->libdir.'/environmentlib.php');
require_once($CFG->libdir.'/pluginlib.php');
// now get cli options
list($options, $unrecognized) = cli_get_params(
@@ -92,13 +93,8 @@ if ($version < $CFG->version) {
$oldversion = "$CFG->release ($CFG->version)";
$newversion = "$release ($version)";
if (!moodle_needs_upgrading()) {
cli_error(get_string('cliupgradenoneed', 'core_admin', $newversion), 0);
}
// Test environment first.
list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
if (!$envstatus) {
// test environment first
if (!check_moodle_environment(normalize_version($release), $environment_results, false, ENV_SELECT_RELEASE)) {
$errors = environment_get_errors($environment_results);
cli_heading(get_string('environment', 'admin'));
foreach ($errors as $error) {
@@ -108,11 +104,6 @@ if (!$envstatus) {
exit(1);
}
// Test plugin dependencies.
if (!plugin_manager::instance()->all_plugins_ok($version)) {
cli_error(get_string('pluginschecktodo', 'admin'));
}
if ($interactive) {
$a = new stdClass();
$a->oldversion = $oldversion;
+32
View File
@@ -0,0 +1,32 @@
<?PHP
// dbperformance.php - shows latest ADOdb stats for the current server
// disable moodle specific debug messages and any errors in output
define('NO_DEBUG_DISPLAY', true);
require_once('../config.php');
error('TODO: rewrite db perf code'); // TODO: rewrite
$topframe = optional_param('topframe', 0, PARAM_BOOL);
$bottomframe = optional_param('bottomframe', 0, PARAM_BOOL);
$do = optional_param('do', '', PARAM_ALPHA);
require_login();
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
$strdatabaseperformance = get_string("databaseperformance");
$stradministration = get_string("administration");
$site = get_site();
if (!empty($topframe)) {
$PAGE->set_url('/admin/dbperformance.php');
$PAGE->navbar->add($stradministration, new moodle_url('/admin/index.php'));
$PAGE->navbar->add($strdatabaseperformance);
$PAGE->set_title("$site->shortname: $strdatabaseperformance");
$PAGE->set_heading($site->fullname);
echo $OUTPUT->header();
exit;
}
+19
View File
@@ -0,0 +1,19 @@
<?php
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class database_export_form extends moodleform {
function definition() {
$mform = $this->_form;
$mform->addElement('header', 'database', get_string('dbexport', 'dbtransfer'));
$mform->addElement('textarea', 'description', get_string('description'), array('rows'=>5, 'cols'=>60));
$this->add_action_buttons(false, get_string('exportdata', 'dbtransfer'));
}
}
@@ -0,0 +1,48 @@
<?php
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class database_transfer_form extends moodleform {
function definition() {
$mform = $this->_form;
$mform->addElement('header', 'database', get_string('dbtransfer', 'dbtransfer'));
$supported = array (
'mysqli/native',
'pgsql/native',
'mssql/native',
'oci/native',
'sqlite3/pdo',
);
$drivers = array();
foreach($supported as $driver) {
list($dbtype, $dblibrary) = explode('/', $driver);
$targetdb = moodle_database::get_driver_instance($dbtype, $dblibrary);
if ($targetdb->driver_installed() !== true) {
continue;
}
$drivers[$driver] = $driver;
}
$mform->addElement('select', 'driver', get_string('dbtype', 'install'), $drivers);
$mform->addElement('text', 'dbhost', get_string('dbhost', 'install'));
$mform->addElement('text', 'dbname', get_string('database', 'install'));
$mform->addElement('text', 'dbuser', get_string('user'));
$mform->addElement('text', 'dbpass', get_string('password'));
$mform->addElement('text', 'prefix', get_string('dbprefix', 'install'));
$mform->addRule('dbhost', get_string('required'), 'required', null);
$mform->addRule('dbname', get_string('required'), 'required', null);
$mform->addRule('dbuser', get_string('required'), 'required', null);
$mform->addRule('dbpass', get_string('required'), 'required', null);
$mform->addRule('prefix', get_string('required'), 'required', null);
$this->add_action_buttons(false, get_string('transferdata', 'dbtransfer'));
}
}
+21
View File
@@ -0,0 +1,21 @@
<?php
require('../../config.php');
require_once('lib.php');
require_once('database_export_form.php');
require_login();
admin_externalpage_setup('dbexport');
//create form
$form = new database_export_form();
if ($data = $form->get_data()) {
dbtransfer_export_xml_database($data->description, $DB);
die;
}
echo $OUTPUT->header();
// TODO: add some more info here
$form->display();
echo $OUTPUT->footer();
+47
View File
@@ -0,0 +1,47 @@
<?php
require('../../config.php');
require_once('lib.php');
require_once('database_transfer_form.php');
require_login();
admin_externalpage_setup('dbtransfer');
// Create the form
$form = new database_transfer_form();
// If we have valid input.
if ($data = $form->get_data()) {
// Connect to the other database.
list($dbtype, $dblibrary) = explode('/', $data->driver);
$targetdb = moodle_database::get_driver_instance($dbtype, $dblibrary);
if (!$targetdb->connect($data->dbhost, $data->dbuser, $data->dbpass, $data->dbname, $data->prefix, null)) {
throw new dbtransfer_exception('notargetconectexception', null, "$CFG->wwwroot/$CFG->admin/dbtransfer/");
}
if ($targetdb->get_tables()) {
throw new dbtransfer_exception('targetdatabasenotempty', null, "$CFG->wwwroot/$CFG->admin/dbtransfer/");
}
// Start output.
echo $OUTPUT->header();
$data->dbtype = $dbtype;
echo $OUTPUT->heading(get_string('transferringdbto', 'dbtransfer', $data));
// Do the transfer.
$feedback = new html_list_progress_trace();
dbtransfer_transfer_database($DB, $targetdb, $feedback);
$feedback->finished();
// Finish up.
echo $OUTPUT->notification(get_string('success'), 'notifysuccess');
echo $OUTPUT->continue_button("$CFG->wwwroot/$CFG->admin/");
echo $OUTPUT->footer();
die;
}
// Otherwise display the settings form.
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('transferdbtoserver', 'dbtransfer'));
echo '<p>', get_string('transferdbintro', 'dbtransfer'), "</p>\n\n";
$form->display();
echo $OUTPUT->footer();
+52
View File
@@ -0,0 +1,52 @@
<?php
/*
TODO:
- exporting to server file >2GB fails in 32bit operating systems - needs warning
- we may run out of disk space exporting to srever file - we must verify the file is not truncated; read from the end of file?
- when sending file >4GB - FAT32 limit, Apache limit, browser limit - needs warning
- there must be some form of progress bar during export, transfer - new tracking class could be passed around
- command line operation - could work around some 2G/4G limits in PHP; useful for cron full backups
- by default allow exporting into empty database only (no tables with the same prefix yet)
- all dangerous operation (like deleting of all data) should be confirmed by key found in special file in dataroot
(user would need file access to dataroot which might prevent various "accidents")
- implement "Export/import running" notification in lib/setup.php (similar to new upgrade flag in config table)
- gzip compression when storing xml file - the xml is very verbose and full of repeated tags (zip is not suitable here at all)
this could help us keep the files bellow 2G (expected ratio is > 10:1)
*/
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/dtllib.php');
function dbtransfer_export_xml_database($description, $mdb) {
@set_time_limit(0);
session_get_instance()->write_close(); // release session
header('Content-Type: application/xhtml+xml; charset=utf-8');
header('Content-Disposition: attachment; filename=database.xml');
header('Expires: 0');
header('Cache-Control: must-revalidate,post-check=0,pre-check=0');
header('Pragma: public');
while(@ob_flush());
$var = new file_xml_database_exporter('php://output', $mdb);
$var->export_database($description);
// no more output
die;
}
function dbtransfer_transfer_database($sourcedb, $targetdb, $feedback = null) {
@set_time_limit(0);
session_get_instance()->write_close(); // release session
$var = new database_mover($sourcedb, $targetdb, true, $feedback);
$var->export_database(null);
}
+86
View File
@@ -0,0 +1,86 @@
<?php
// Deletes the moodledata directory, COMPLETELY!!
// BE VERY CAREFUL USING THIS!
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('purgemoodledata');
require_login();
$sure = optional_param('sure', 0, PARAM_BOOL);
$reallysure = optional_param('reallysure', 0, PARAM_BOOL);
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
$deletedir = $CFG->dataroot; // The directory to delete!
echo $OUTPUT->header();
echo $OUTPUT->heading('Purge moodledata');
if (empty($sure)) {
$optionsyes = array('sure'=>'yes', 'sesskey'=>sesskey());
$formcontinue = new single_button(new moodle_url('delete.php', $optionsyes), get_string('yes'));
$formcancel = new single_button('index.php', get_string('no'), 'get');
echo $OUTPUT->confirm('Are you completely sure you want to delete everything inside the directory '. $deletedir .' ?', $formcontinue, $formcancel);
echo $OUTPUT->footer();
exit;
}
if (!data_submitted() or empty($reallysure)) {
$optionsyes = array('sure'=>'yes', 'sesskey'=>sesskey(), 'reallysure'=>'yes');
$formcontinue = new single_button(new moodle_url('delete.php', $optionsyes), get_string('yes'));
$formcancel = new single_button('index.php', get_string('no'), 'get');
echo $OUTPUT->confirm('Are you REALLY REALLY completely sure you want to delete everything inside the directory '.
$deletedir .' (this includes all user images, and any other course files that have been created) ?',
$formcontinue, $formcancel);
echo $OUTPUT->footer();
exit;
}
if (!confirm_sesskey()) {
print_error('wrongcall', 'error');
}
/// OK, here goes ...
delete_subdirectories($deletedir);
echo '<h1 align="center">Done!</h1>';
echo $OUTPUT->continue_button($CFG->wwwroot);
echo $OUTPUT->footer();
exit;
function delete_subdirectories($rootdir) {
$dir = opendir($rootdir);
while (false !== ($file = readdir($dir))) {
if ($file != '.' and $file != '..') {
$fullfile = $rootdir .'/'. $file;
if (filetype($fullfile) == 'dir') {
delete_subdirectories($fullfile);
echo 'Deleting '. $fullfile .' ... ';
if (rmdir($fullfile)) {
echo 'Done.<br />';
} else {
echo 'FAILED.<br />';
}
} else {
echo 'Deleting '. $fullfile .' ... ';
if (unlink($fullfile)) {
echo 'Done.<br />';
} else {
echo 'FAILED.<br />';
}
}
}
}
closedir($dir);
}
+1 -1
View File
@@ -14,7 +14,7 @@ require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
$returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=manageeditors";
$action = optional_param('action', '', PARAM_ACTION);
$editor = optional_param('editor', '', PARAM_PLUGIN);
$editor = optional_param('editor', '', PARAM_SAFEDIR);
// get currently installed and enabled auth plugins
$available_editors = editors_get_available();
+1 -8
View File
@@ -27,11 +27,10 @@ require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
$action = required_param('action', PARAM_ACTION);
$enrol = required_param('enrol', PARAM_PLUGIN);
$enrol = required_param('enrol', PARAM_SAFEDIR);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$PAGE->set_url('/admin/enrol.php');
$PAGE->set_context(context_system::instance());
require_login();
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
@@ -42,13 +41,10 @@ $all = enrol_get_plugins(false);
$return = new moodle_url('/admin/settings.php', array('section'=>'manageenrols'));
$syscontext = context_system::instance();
switch ($action) {
case 'disable':
unset($enabled[$enrol]);
set_config('enrol_plugins_enabled', implode(',', array_keys($enabled)));
$syscontext->mark_dirty(); // resets all enrol caches
break;
case 'enable':
@@ -58,7 +54,6 @@ switch ($action) {
$enabled = array_keys($enabled);
$enabled[] = $enrol;
set_config('enrol_plugins_enabled', implode(',', $enabled));
$syscontext->mark_dirty(); // resets all enrol caches
break;
case 'up':
@@ -111,9 +106,7 @@ switch ($action) {
} else { // Delete everything!!
uninstall_plugin('enrol', $enrol);
$syscontext->mark_dirty(); // resets all enrol caches
$a = new stdClass();
$a->plugin = $strplugin;
$a->directory = "$CFG->dirroot/enrol/$enrol";
echo $OUTPUT->notification(get_string('uninstalldeletefiles', 'enrol', $a), 'notifysuccess');
+124 -96
View File
@@ -1,109 +1,137 @@
<?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/>.
/**
* This file is the admin frontend to execute all the checks available
* in the environment.xml file. It includes database, php and
* php_extensions. Also, it's possible to update the xml file
* from moodle.org be able to check more and more versions.
*
* @package core
* @subpackage admin
* @copyright 2006 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
// (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com //
// //
// This program 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 2 of the License, or //
// (at your option) any later version. //
// //
// This program 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: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
// This file is the admin frontend to execute all the checks available
// in the environment.xml file. It includes database, php and
// php_extensions. Also, it's possible to update the xml file
// from moodle.org be able to check more and more versions.
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/environmentlib.php');
require_once($CFG->libdir.'/componentlib.class.php');
admin_externalpage_setup('environment');
/// Parameters
$action = optional_param('action', '', PARAM_ACTION);
$version = optional_param('version', '', PARAM_FILE); //
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/environmentlib.php');
require_once($CFG->libdir.'/componentlib.class.php');
/// Get some strings
$stradmin = get_string('administration');
$stradminhelpenvironment = get_string("adminhelpenvironment");
$strenvironment = get_string('environment', 'admin');
$strerror = get_string('error');
$strmoodleversion = get_string('moodleversion');
$strupdate = get_string('updatecomponent', 'admin');
$strupwards = get_string('upwards', 'admin');
$strmisc = get_string('miscellaneous');
// Parameters
$action = optional_param('action', '', PARAM_ACTION);
$version = optional_param('version', '', PARAM_FILE); //
/// Print the header stuff
echo $OUTPUT->header();
$extraurlparams = array();
if ($version) {
$extraurlparams['version'] = $version;
}
admin_externalpage_setup('environment', '', $extraurlparams);
/// Print the component download link
echo '<div class="reportlink"><a href="environment.php?action=updatecomponent&amp;sesskey='.sesskey().'">'.$strupdate.'</a></div>';
// Handle the 'updatecomponent' action
if ($action == 'updatecomponent' && confirm_sesskey()) {
// Create component installer and execute it
if ($cd = new component_installer('http://download.moodle.org',
'environment',
'environment.zip')) {
$status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED)
switch ($status) {
case COMPONENT_ERROR:
if ($cd->get_error() == 'remotedownloaderror') {
$a = new stdClass();
$a->url = 'http://download.moodle.org/environment/environment.zip';
$a->dest = $CFG->dataroot . '/';
print_error($cd->get_error(), 'error', $PAGE->url, $a);
die();
echo $OUTPUT->heading($strenvironment);
} else {
print_error($cd->get_error(), 'error', $PAGE->url);
die();
}
case COMPONENT_UPTODATE:
redirect($PAGE->url, get_string($cd->get_error(), 'error'));
die;
case COMPONENT_INSTALLED:
redirect($PAGE->url, get_string('componentinstalled', 'admin'));
die;
}
}
}
// Get current Moodle version
$current_version = $CFG->release;
// Calculate list of versions
$versions = array();
if ($contents = load_environment_xml()) {
if ($env_versions = get_list_of_environment_versions($contents)) {
// Set the current version at the beginning
$env_version = normalize_version($current_version); //We need this later (for the upwards)
$versions[$env_version] = $current_version;
// If no version has been previously selected, default to $current_version
if (empty($version)) {
$version = $env_version;
}
//Iterate over each version, adding bigger than current
foreach ($env_versions as $env_version) {
if (version_compare(normalize_version($current_version), $env_version, '<')) {
$versions[$env_version] = $env_version;
/// Handle the 'updatecomponent' action
if ($action == 'updatecomponent' && confirm_sesskey()) {
/// Create component installer and execute it
if ($cd = new component_installer('http://download.moodle.org',
'environment',
'environment.zip')) {
$status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED)
switch ($status) {
case COMPONENT_ERROR:
if ($cd->get_error() == 'remotedownloaderror') {
$a = new stdClass();
$a->url = 'http://download.moodle.org/environment/environment.zip';
$a->dest= $CFG->dataroot.'/';
echo $OUTPUT->box(get_string($cd->get_error(), 'error', $a), 'errorbox');
} else {
echo $OUTPUT->box(get_string($cd->get_error(), 'error'), 'errorbox');
}
break;
case COMPONENT_UPTODATE:
echo $OUTPUT->box(get_string($cd->get_error(), 'error'));
break;
case COMPONENT_INSTALLED:
echo $OUTPUT->box(get_string('componentinstalled', 'admin'));
break;
}
}
// Add 'upwards' to the last element
$versions[$env_version] = $env_version.' '.get_string('upwards', 'admin');
} else {
$versions = array('error' => get_string('error'));
}
}
// Get the results of the environment check.
list($envstatus, $environment_results) = check_moodle_environment($version);
/// Start of main box
echo $OUTPUT->box_start();
echo "<div style=\"text-align:center\">".$stradminhelpenvironment."</div><br />";
/// Get current Moodle version
$current_version = $CFG->release;
/// Calculate list of versions
$versions = array();
if ($contents = load_environment_xml()) {
if ($env_versions = get_list_of_environment_versions($contents)) {
/// Set the current version at the beginning
$env_version = normalize_version($current_version); //We need this later (for the upwards)
$versions[$env_version] = $current_version;
/// If no version has been previously selected, default to $current_version
if (empty($version)) {
$version = $env_version;
}
///Iterate over each version, adding bigger than current
foreach ($env_versions as $env_version) {
if (version_compare(normalize_version($current_version), $env_version, '<')) {
$versions[$env_version] = $env_version;
}
}
/// Add 'upwards' to the last element
$versions[$env_version] = $env_version.' '.$strupwards;
} else {
$versions = array('error' => $strerror);
}
}
/// Print form and popup menu
echo '<div style="text-align:center"> ';
$select = new single_select(new moodle_url('/admin/environment.php'), 'version', $versions, $version, null);
$select->label = $strmoodleversion;
echo $OUTPUT->render($select);
echo '</div>';
/// End of main box
echo $OUTPUT->box_end();
/// Gather and show results
$status = check_moodle_environment($version, $environment_results);
/// Print footer
echo $OUTPUT->footer();
// Display the page.
$output = $PAGE->get_renderer('core', 'admin');
echo $output->environment_check_page($versions, $version, $envstatus, $environment_results);
+10 -334
View File
@@ -214,7 +214,11 @@
</FEEDBACK>
</UNICODE>
<DATABASE level="required">
<VENDOR name="mysql" version="5.0.25" />
<VENDOR name="mysql" version="5.0.25">
<FEEDBACK>
<ON_ERROR message="mysql416required" />
</FEEDBACK>
</VENDOR>
<VENDOR name="postgres" version="8.3" />
<VENDOR name="mssql" version="9.0" />
<VENDOR name="odbc_mssql" version="9.0" />
@@ -331,7 +335,11 @@
</FEEDBACK>
</UNICODE>
<DATABASE level="required">
<VENDOR name="mysql" version="5.0.25" />
<VENDOR name="mysql" version="5.0.25">
<FEEDBACK>
<ON_ERROR message="mysql416required" />
</FEEDBACK>
</VENDOR>
<VENDOR name="postgres" version="8.3" />
<VENDOR name="mssql" version="9.0" />
<VENDOR name="odbc_mssql" version="9.0" />
@@ -434,336 +442,4 @@
</PHP_SETTING>
</PHP_SETTINGS>
</MOODLE>
<MOODLE version="2.2" requires="1.9">
<UNICODE level="required">
<FEEDBACK>
<ON_ERROR message="unicoderequired" />
</FEEDBACK>
</UNICODE>
<DATABASE level="required">
<VENDOR name="mysql" version="5.0.25" />
<VENDOR name="postgres" version="8.3" />
<VENDOR name="mssql" version="9.0" />
<VENDOR name="odbc_mssql" version="9.0" />
<VENDOR name="mssql_n" version="9.0" />
<VENDOR name="oracle" version="10.2" />
<VENDOR name="sqlite" version="2.0" />
</DATABASE>
<PHP version="5.3.2" level="required">
</PHP>
<PHP_EXTENSIONS>
<PHP_EXTENSION name="iconv" level="required">
<FEEDBACK>
<ON_CHECK message="iconvrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="mbstring" level="optional">
<FEEDBACK>
<ON_CHECK message="mbstringrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="curl" level="required">
<FEEDBACK>
<ON_CHECK message="curlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="openssl" level="optional">
<FEEDBACK>
<ON_CHECK message="opensslrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="tokenizer" level="optional">
<FEEDBACK>
<ON_CHECK message="tokenizerrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="xmlrpc" level="optional">
<FEEDBACK>
<ON_CHECK message="xmlrpcrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="soap" level="optional">
<FEEDBACK>
<ON_CHECK message="soaprecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="ctype" level="required">
<FEEDBACK>
<ON_ERROR message="ctyperequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="zip" level="required">
<FEEDBACK>
<ON_ERROR message="ziprequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="gd" level="optional">
<FEEDBACK>
<ON_CHECK message="gdrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="simplexml" level="required">
<FEEDBACK>
<ON_CHECK message="simplexmlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="spl" level="required">
<FEEDBACK>
<ON_CHECK message="splrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="pcre" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="dom" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="xml" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="intl" level="optional">
<FEEDBACK>
<ON_CHECK message="intlrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="json" level="required">
</PHP_EXTENSION>
</PHP_EXTENSIONS>
<PHP_SETTINGS>
<PHP_SETTING name="memory_limit" value="40M" level="required">
<FEEDBACK>
<ON_ERROR message="settingmemorylimit" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="safe_mode" value="0" level="optional">
<FEEDBACK>
<ON_CHECK message="settingsafemode" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="file_uploads" value="1" level="optional">
<FEEDBACK>
<ON_CHECK message="settingfileuploads" />
</FEEDBACK>
</PHP_SETTING>
</PHP_SETTINGS>
</MOODLE>
<MOODLE version="2.3" requires="2.2">
<UNICODE level="required">
<FEEDBACK>
<ON_ERROR message="unicoderequired" />
</FEEDBACK>
</UNICODE>
<DATABASE level="required">
<VENDOR name="mysql" version="5.1.33" />
<VENDOR name="postgres" version="8.3" />
<VENDOR name="mssql" version="9.0" />
<VENDOR name="odbc_mssql" version="9.0" />
<VENDOR name="mssql_n" version="9.0" />
<VENDOR name="oracle" version="10.2" />
<VENDOR name="sqlite" version="2.0" />
</DATABASE>
<PHP version="5.3.2" level="required">
</PHP>
<PHP_EXTENSIONS>
<PHP_EXTENSION name="iconv" level="required">
<FEEDBACK>
<ON_CHECK message="iconvrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="mbstring" level="optional">
<FEEDBACK>
<ON_CHECK message="mbstringrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="curl" level="required">
<FEEDBACK>
<ON_CHECK message="curlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="openssl" level="optional">
<FEEDBACK>
<ON_CHECK message="opensslrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="tokenizer" level="optional">
<FEEDBACK>
<ON_CHECK message="tokenizerrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="xmlrpc" level="optional">
<FEEDBACK>
<ON_CHECK message="xmlrpcrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="soap" level="optional">
<FEEDBACK>
<ON_CHECK message="soaprecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="ctype" level="required">
<FEEDBACK>
<ON_ERROR message="ctyperequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="zip" level="required">
<FEEDBACK>
<ON_ERROR message="ziprequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="gd" level="optional">
<FEEDBACK>
<ON_CHECK message="gdrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="simplexml" level="required">
<FEEDBACK>
<ON_CHECK message="simplexmlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="spl" level="required">
<FEEDBACK>
<ON_CHECK message="splrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="pcre" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="dom" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="xml" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="intl" level="optional">
<FEEDBACK>
<ON_CHECK message="intlrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="json" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="hash" level="required"/>
</PHP_EXTENSIONS>
<PHP_SETTINGS>
<PHP_SETTING name="memory_limit" value="40M" level="required">
<FEEDBACK>
<ON_ERROR message="settingmemorylimit" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="safe_mode" value="0" level="optional">
<FEEDBACK>
<ON_CHECK message="settingsafemode" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="file_uploads" value="1" level="optional">
<FEEDBACK>
<ON_CHECK message="settingfileuploads" />
</FEEDBACK>
</PHP_SETTING>
</PHP_SETTINGS>
</MOODLE>
<MOODLE version="2.4" requires="2.2">
<UNICODE level="required">
<FEEDBACK>
<ON_ERROR message="unicoderequired" />
</FEEDBACK>
</UNICODE>
<DATABASE level="required">
<VENDOR name="mysql" version="5.1.33" />
<VENDOR name="postgres" version="8.3" />
<VENDOR name="mssql" version="9.0" />
<VENDOR name="odbc_mssql" version="9.0" />
<VENDOR name="mssql_n" version="9.0" />
<VENDOR name="oracle" version="10.2" />
<VENDOR name="sqlite" version="2.0" />
</DATABASE>
<PHP version="5.3.2" level="required">
</PHP>
<PHP_EXTENSIONS>
<PHP_EXTENSION name="iconv" level="required">
<FEEDBACK>
<ON_CHECK message="iconvrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="mbstring" level="optional">
<FEEDBACK>
<ON_CHECK message="mbstringrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="curl" level="required">
<FEEDBACK>
<ON_CHECK message="curlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="openssl" level="optional">
<FEEDBACK>
<ON_CHECK message="opensslrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="tokenizer" level="optional">
<FEEDBACK>
<ON_CHECK message="tokenizerrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="xmlrpc" level="optional">
<FEEDBACK>
<ON_CHECK message="xmlrpcrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="soap" level="optional">
<FEEDBACK>
<ON_CHECK message="soaprecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="ctype" level="required">
<FEEDBACK>
<ON_ERROR message="ctyperequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="zip" level="required">
<FEEDBACK>
<ON_ERROR message="ziprequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="gd" level="optional">
<FEEDBACK>
<ON_CHECK message="gdrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="simplexml" level="required">
<FEEDBACK>
<ON_CHECK message="simplexmlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="spl" level="required">
<FEEDBACK>
<ON_CHECK message="splrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="pcre" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="dom" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="xml" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="intl" level="optional">
<FEEDBACK>
<ON_CHECK message="intlrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="json" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="hash" level="required"/>
</PHP_EXTENSIONS>
<PHP_SETTINGS>
<PHP_SETTING name="memory_limit" value="40M" level="required">
<FEEDBACK>
<ON_ERROR message="settingmemorylimit" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="safe_mode" value="0" level="optional">
<FEEDBACK>
<ON_CHECK message="settingsafemode" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="file_uploads" value="1" level="optional">
<FEEDBACK>
<ON_CHECK message="settingfileuploads" />
</FEEDBACK>
</PHP_SETTING>
</PHP_SETTINGS>
</MOODLE>
</COMPATIBILITY_MATRIX>
-2
View File
@@ -242,7 +242,6 @@ function get_table_row($filterinfo, $isfirstrow, $islastactive, $applytostrings)
// Disable/off/on
$select = new single_select(filters_action_url($filter, 'setstate'), 'newstate', $activechoices, $filterinfo->active, null, 'active' . basename($filter));
$select->set_label(get_string('isactive', 'filters'), array('class' => 'accesshide'));
$row[] = $OUTPUT->render($select);
// Re-order
@@ -264,7 +263,6 @@ function get_table_row($filterinfo, $isfirstrow, $islastactive, $applytostrings)
// Apply to strings.
$select = new single_select(filters_action_url($filter, 'setapplyto'), 'stringstoo', $applytochoices, $applytostrings, null, 'applyto' . basename($filter));
$select->set_label(get_string('applyto', 'filters'), array('class' => 'accesshide'));
$select->disabled = $filterinfo->active == TEXTFILTER_DISABLED;
$row[] = $OUTPUT->render($select);
+1336
View File
File diff suppressed because it is too large Load Diff
+790
View File
@@ -0,0 +1,790 @@
<?php
ob_start(); //for whitespace test
require_once('../config.php');
// extra whitespace test - intentionally breaks cookieless mode
$extraws = '';
while (ob_get_level()) {
$extraws .= ob_get_contents();
ob_end_clean();
}
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('healthcenter');
define('SEVERITY_NOTICE', 'notice');
define('SEVERITY_ANNOYANCE', 'annoyance');
define('SEVERITY_SIGNIFICANT', 'significant');
define('SEVERITY_CRITICAL', 'critical');
$solution = optional_param('solution', 0, PARAM_SAFEDIR); //in fact it is class name alhanumeric and _
require_login();
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
$site = get_site();
echo $OUTPUT->header();
echo <<<STYLES
<style type="text/css">
div#healthnoproblemsfound {
width: 60%;
margin: auto;
padding: 1em;
border: 1px black solid;
-moz-border-radius: 6px;
}
dl.healthissues {
width: 60%;
margin: auto;
}
dl.critical dt, dl.critical dd {
background-color: #a71501;
}
dl.significant dt, dl.significant dd {
background-color: #d36707;
}
dl.annoyance dt, dl.annoyance dd {
background-color: #dba707;
}
dl.notice dt, dl.notice dd {
background-color: #e5db36;
}
dt.solution, dd.solution, div#healthnoproblemsfound {
background-color: #5BB83E !important;
}
dl.healthissues dt, dl.healthissues dd {
margin: 0px;
padding: 1em;
border: 1px black solid;
}
dl.healthissues dt {
font-weight: bold;
border-bottom: none;
padding-bottom: 0.5em;
}
dl.healthissues dd {
border-top: none;
padding-top: 0.5em;
margin-bottom: 10px;
}
dl.healthissues dd form {
margin-top: 0.5em;
text-align: right;
}
form#healthformreturn {
text-align: center;
margin: 2em;
}
dd.solution p {
padding: 0px;
margin: 1em 0px;
}
dd.solution li {
margin-top: 1em;
}
</style>
STYLES;
if(strpos($solution, 'problem_') === 0 && class_exists($solution)) {
health_print_solution($solution);
}
else {
health_find_problems();
}
echo $OUTPUT->footer();
function health_find_problems() {
global $OUTPUT;
echo $OUTPUT->heading(get_string('healthcenter'));
$issues = array(
SEVERITY_CRITICAL => array(),
SEVERITY_SIGNIFICANT => array(),
SEVERITY_ANNOYANCE => array(),
SEVERITY_NOTICE => array(),
);
$problems = 0;
for($i = 1; $i < 1000000; ++$i) {
$classname = sprintf('problem_%06d', $i);
if(!class_exists($classname)) {
break;
}
$problem = new $classname;
if($problem->exists()) {
$severity = $problem->severity();
$issues[$severity][$classname] = array(
'severity' => $severity,
'description' => $problem->description(),
'title' => $problem->title()
);
++$problems;
}
unset($problem);
}
if($problems == 0) {
echo '<div id="healthnoproblemsfound">';
echo get_string('healthnoproblemsfound');
echo '</div>';
}
else {
echo $OUTPUT->heading(get_string('healthproblemsdetected'));
$severities = array(SEVERITY_CRITICAL, SEVERITY_SIGNIFICANT, SEVERITY_ANNOYANCE, SEVERITY_NOTICE);
foreach($severities as $severity) {
if(!empty($issues[$severity])) {
echo '<dl class="healthissues '.$severity.'">';
foreach($issues[$severity] as $classname => $data) {
echo '<dt id="'.$classname.'">'.$data['title'].'</dt>';
echo '<dd>'.$data['description'];
echo '<form action="health.php#solution" method="get">';
echo '<input type="hidden" name="solution" value="'.$classname.'" /><input type="submit" value="'.get_string('viewsolution').'" />';
echo '</form></dd>';
}
echo '</dl>';
}
}
}
}
function health_print_solution($classname) {
global $OUTPUT;
$problem = new $classname;
$data = array(
'title' => $problem->title(),
'severity' => $problem->severity(),
'description' => $problem->description(),
'solution' => $problem->solution()
);
echo $OUTPUT->heading(get_string('healthcenter'));
echo $OUTPUT->heading(get_string('healthproblemsolution'));
echo '<dl class="healthissues '.$data['severity'].'">';
echo '<dt>'.$data['title'].'</dt>';
echo '<dd>'.$data['description'].'</dd>';
echo '<dt id="solution" class="solution">'.get_string('healthsolution').'</dt>';
echo '<dd class="solution">'.$data['solution'].'</dd></dl>';
echo '<form id="healthformreturn" action="health.php#'.$classname.'" method="get">';
echo '<input type="submit" value="'.get_string('healthreturntomain').'" />';
echo '</form>';
}
class problem_base {
function exists() {
return false;
}
function title() {
return '???';
}
function severity() {
return SEVERITY_NOTICE;
}
function description() {
return '';
}
function solution() {
return '';
}
}
class problem_000002 extends problem_base {
function title() {
return 'Extra characters at the end of config.php or other library function';
}
function exists() {
global $extraws;
if($extraws === '') {
return false;
}
return true;
}
function severity() {
return SEVERITY_SIGNIFICANT;
}
function description() {
return 'Your Moodle configuration file config.php or another library file, contains some characters after the closing PHP tag (?>). This causes Moodle to exhibit several kinds of problems (such as broken downloaded files) and must be fixed.';
}
function solution() {
global $CFG;
return 'You need to edit <strong>'.$CFG->dirroot.'/config.php</strong> and remove all characters (including spaces and returns) after the ending ?> tag. These two characters should be the very last in that file. The extra trailing whitespace may be also present in other PHP files that are included from lib/setup.php.';
}
}
class problem_000003 extends problem_base {
function title() {
return '$CFG->dataroot does not exist or does not have write permissions';
}
function exists() {
global $CFG;
if(!is_dir($CFG->dataroot) || !is_writable($CFG->dataroot)) {
return true;
}
return false;
}
function severity() {
return SEVERITY_SIGNIFICANT;
}
function description() {
global $CFG;
return 'Your <strong>config.php</strong> says that your "data root" directory is <strong>'.$CFG->dataroot.'</strong>. However, this directory either does not exist or cannot be written to by Moodle. This means that a variety of problems will be present, such as users not being able to log in and not being able to upload any files. It is imperative that you address this problem for Moodle to work correctly.';
}
function solution() {
global $CFG;
return 'First of all, make sure that the directory <strong>'.$CFG->dataroot.'</strong> exists. If the directory does exist, then you must make sure that Moodle is able to write to it. Contact your web server administrator and request that he gives write permissions for that directory to the user that the web server process is running as.';
}
}
class problem_000004 extends problem_base {
function title() {
return 'cron.php is not set up to run automatically';
}
function exists() {
global $DB;
$lastcron = $DB->get_field_sql('SELECT max(lastcron) FROM {modules}');
return (time() - $lastcron > 3600 * 24);
}
function severity() {
return SEVERITY_SIGNIFICANT;
}
function description() {
return 'The cron.php mainenance script has not been run in the past 24 hours. This probably means that your server is not configured to automatically run this script in regular time intervals. If this is the case, then Moodle will mostly work as it should but some operations (notably sending email to users) will not be carried out at all.';
}
function solution() {
global $CFG;
return 'For detailed instructions on how to enable cron, see <a href="'.$CFG->wwwroot.'/doc/?file=install.html#cron">this section</a> of the installation manual.';
}
}
class problem_000005 extends problem_base {
function title() {
return 'PHP: session.auto_start is enabled';
}
function exists() {
return ini_get_bool('session.auto_start');
}
function severity() {
return SEVERITY_CRITICAL;
}
function description() {
return 'Your PHP configuration includes an enabled setting, session.auto_start, that <strong>must be disabled</strong> in order for Moodle to work correctly. Notable symptoms arising from this misconfiguration include fatal errors and/or blank pages when trying to log in.';
}
function solution() {
global $CFG;
return '<p>There are two ways you can solve this problem:</p><ol><li>If you have access to your main <strong>php.ini</strong> file, then find the line that looks like this: <pre>session.auto_start = 1</pre> and change it to <pre>session.auto_start = 0</pre> and then restart your web server. Be warned that this, as any other PHP setting change, might affect other web applications running on the server.</li><li>Finally, you may be able to change this setting just for your site by creating or editing the file <strong>'.$CFG->dirroot.'/.htaccess</strong> to contain this line: <pre>php_value session.auto_start "0"</pre></li></ol>';
}
}
class problem_000006 extends problem_base {
function title() {
return 'PHP: magic_quotes_runtime is enabled';
}
function exists() {
return (ini_get_bool('magic_quotes_runtime'));
}
function severity() {
return SEVERITY_SIGNIFICANT;
}
function description() {
return 'Your PHP configuration includes an enabled setting, magic_quotes_runtime, that <strong>must be disabled</strong> in order for Moodle to work correctly. Notable symptoms arising from this misconfiguration include strange display errors whenever a text field that includes single or double quotes is processed.';
}
function solution() {
global $CFG;
return '<p>There are two ways you can solve this problem:</p><ol><li>If you have access to your main <strong>php.ini</strong> file, then find the line that looks like this: <pre>magic_quotes_runtime = On</pre> and change it to <pre>magic_quotes_runtime = Off</pre> and then restart your web server. Be warned that this, as any other PHP setting change, might affect other web applications running on the server.</li><li>Finally, you may be able to change this setting just for your site by creating or editing the file <strong>'.$CFG->dirroot.'/.htaccess</strong> to contain this line: <pre>php_value magic_quotes_runtime "Off"</pre></li></ol>';
}
}
class problem_000007 extends problem_base {
function title() {
return 'PHP: file_uploads is disabled';
}
function exists() {
return !ini_get_bool('file_uploads');
}
function severity() {
return SEVERITY_SIGNIFICANT;
}
function description() {
return 'Your PHP configuration includes a disabled setting, file_uploads, that <strong>must be enabled</strong> to let Moodle offer its full functionality. Until this setting is enabled, it will not be possible to upload any files into Moodle. This includes, for example, course content and user pictures.';
}
function solution() {
global $CFG;
return '<p>There are two ways you can solve this problem:</p><ol><li>If you have access to your main <strong>php.ini</strong> file, then find the line that looks like this: <pre>file_uploads = Off</pre> and change it to <pre>file_uploads = On</pre> and then restart your web server. Be warned that this, as any other PHP setting change, might affect other web applications running on the server.</li><li>Finally, you may be able to change this setting just for your site by creating or editing the file <strong>'.$CFG->dirroot.'/.htaccess</strong> to contain this line: <pre>php_value file_uploads "On"</pre></li></ol>';
}
}
class problem_000008 extends problem_base {
function title() {
return 'PHP: memory_limit cannot be controlled by Moodle';
}
function exists() {
global $CFG;
$oldmemlimit = @ini_get('memory_limit');
if (empty($oldmemlimit)) {
// PHP not compiled with memory limits, this means that it's
// probably limited to 8M or in case of Windows not at all.
// We can ignore it for now - there is not much to test anyway
// TODO: add manual test that fills memory??
return false;
}
$oldmemlimit = get_real_size($oldmemlimit);
//now lets change the memory limit to something higher
$newmemlimit = ($oldmemlimit + 1024*1024*5);
raise_memory_limit($newmemlimit);
$testmemlimit = get_real_size(@ini_get('memory_limit'));
//verify the change had any effect at all
if ($oldmemlimit == $testmemlimit) {
//memory limit can not be changed - is it big enough then?
if ($oldmemlimit < get_real_size('128M')) {
return true;
} else {
return false;
}
}
reduce_memory_limit($oldmemlimit);
return false;
}
function severity() {
return SEVERITY_NOTICE;
}
function description() {
return 'The settings for PHP on your server do not allow a script to request more memory during its execution. '.
'This means that there is a hard limit of '.@ini_get('memory_limit').' for each script. '.
'It is possible that certain operations within Moodle will require more than this amount in order '.
'to complete successfully, especially if there are lots of data to be processed.';
}
function solution() {
return 'It is recommended that you contact your web server administrator to address this issue.';
}
}
class problem_000009 extends problem_base {
function title() {
return 'SQL: using account without password';
}
function exists() {
global $CFG;
return empty($CFG->dbpass);
}
function severity() {
return SEVERITY_CRITICAL;
}
function description() {
global $CFG;
return 'The user account your are connecting to the database server with is set up without a password. This is a very big security risk and is only somewhat lessened if your database is configured to not accept connections from any hosts other than the server Moodle is running on. Unless you use a strong password to connect to the database, you risk unauthorized access to and manipulation of your data.'.($CFG->dbuser != 'root'?'':' <strong>This is especially alarming because such access to the database would be as the superuser (root)!</strong>');
}
function solution() {
global $CFG;
return 'You should change the password of the user <strong>'.$CFG->dbuser.'</strong> both in your database and in your Moodle <strong>config.php</strong> immediately!'.($CFG->dbuser != 'root'?'':' It would also be a good idea to change the user account from root to something else, because this would lessen the impact in the event that your database is compromised anyway.');
}
}
/* // not implemented in 2.0 yet
class problem_000010 extends problem_base {
function title() {
return 'Uploaded files: slasharguments disabled or not working';
}
function exists() {
if (!$this->is_enabled()) {
return true;
}
if ($this->status() < 1) {
return true;
}
return false;
}
function severity() {
if ($this->is_enabled() and $this->status() == 0) {
return SEVERITY_SIGNIFICANT;
} else {
return SEVERITY_ANNOYANCE;
}
}
function description() {
global $CFG;
$desc = 'Slasharguments are needed for relative linking in uploaded resources:<ul>';
if (!$this->is_enabled()) {
$desc .= '<li>slasharguments are <strong>disabled</strong> in Moodle configuration</li>';
} else {
$desc .= '<li>slasharguments are enabled in Moodle configuration</li>';
}
if ($this->status() == -1) {
$desc .= '<li>can not run automatic test, you can verify it <a href="'.$CFG->wwwroot.'/file.php/testslasharguments" target="_blank">here</a> manually</li>';
} else if ($this->status() == 0) {
$desc .= '<li>slashargument test <strong>failed</strong>, please check server configuration</li>';
} else {
$desc .= '<li>slashargument test passed</li>';
}
$desc .= '</ul>';
return $desc;
}
function solution() {
global $CFG;
$enabled = $this->is_enabled();
$status = $this->status();
$solution = '';
if ($enabled and ($status == 0)) {
$solution .= 'Slasharguments are enabled, but the test failed. Please disable slasharguments in Moodle configuration or fix the server configuration.<hr />';
} else if ((!$enabled) and ($status == 0)) {
$solution .= 'Slasharguments are disabled and the test failed. You may try to fix the server configuration.<hr />';
} else if ($enabled and ($status == -1)) {
$solution .= 'Slasharguments are enabled, <a href="'.$CFG->wwwroot.'/file.php/testslasharguments">automatic testing</a> not possible.<hr />';
} else if ((!$enabled) and ($status == -1)) {
$solution .= 'Slasharguments are disabled, <a href="'.$CFG->wwwroot.'/file.php/testslasharguments">automatic testing</a> not possible.<hr />';
} else if ((!$enabled) and ($status > 0)) {
$solution .= 'Slasharguments are disabled though the iternal test is OK. You should enable slasharguments in Moodle configuration.';
} else if ($enabled and ($status > 0)) {
$solution .= 'Congratulations - everything seems OK now :-D';
}
if ($status < 1) {
$solution .= '<p>IIS:<ul><li>try to add <code>cgi.fix_pathinfo=1</code> to php.ini</li><li>do NOT enable AllowPathInfoForScriptMappings !!!</li><li>slasharguments may not work when using ISAPI and PHP 4.3.10 and older</li></ul></p>';
$solution .= '<p>Apache 1:<ul><li>try to add <code>cgi.fix_pathinfo=1</code> to php.ini</li></ul></p>';
$solution .= '<p>Apache 2:<ul><li>you must add <code>AcceptPathInfo on</code> to php.ini or .htaccess</li><li>try to add <code>cgi.fix_pathinfo=1</code> to php.ini</li></ul></p>';
}
return $solution;
}
function is_enabled() {
global $CFG;
return !empty($CFG->slasharguments);
}
function status() {
global $CFG;
$handle = @fopen($CFG->wwwroot.'/file.php?file=/testslasharguments', "r");
$contents = @trim(fread($handle, 10));
@fclose($handle);
if ($contents != 'test -1') {
return -1;
}
$handle = @fopen($CFG->wwwroot.'/file.php/testslasharguments', "r");
$contents = trim(@fread($handle, 10));
@fclose($handle);
switch ($contents) {
case 'test 1': return 1;
case 'test 2': return 2;
default: return 0;
}
}
}*/
class problem_000012 extends problem_base {
function title() {
return 'Random questions data consistency';
}
function exists() {
global $DB;
return $DB->record_exists_select('question', "qtype = 'random' AND parent <> id", array());
}
function severity() {
return SEVERITY_ANNOYANCE;
}
function description() {
return '<p>For random questions, question.parent should equal question.id. ' .
'There are some questions in your database for which this is not true. ' .
'One way that this could have happened is for random questions restored from backup before ' .
'<a href="http://tracker.moodle.org/browse/MDL-5482">MDL-5482</a> was fixed.</p>';
}
function solution() {
global $CFG;
return '<p>Upgrade to Moodle 1.9.1 or later, or manually execute the SQL</p>' .
'<pre>UPDATE ' . $CFG->prefix . 'question SET parent = id WHERE qtype = \'random\' and parent &lt;> id;</pre>';
}
}
class problem_000013 extends problem_base {
function title() {
return 'Multi-answer questions data consistency';
}
function exists() {
global $DB;
$positionexpr = $DB->sql_position($DB->sql_concat("','", "q.id", "','"),
$DB->sql_concat("','", "qma.sequence", "','"));
return $DB->record_exists_sql("
SELECT * FROM {question} q
JOIN {question_multianswer} qma ON $positionexpr > 0
WHERE qma.question <> q.parent") ||
$DB->record_exists_sql("
SELECT * FROM {question} q
JOIN {question} parent_q ON parent_q.id = q.parent
WHERE q.category <> parent_q.category");
}
function severity() {
return SEVERITY_ANNOYANCE;
}
function description() {
return '<p>For each sub-question whose id is listed in ' .
'question_multianswer.sequence, its question.parent field should equal ' .
'question_multianswer.question; and each sub-question should be in the same ' .
'category as its parent. There are questions in your database for ' .
'which this is not the case. One way that this could have happened is ' .
'for multi-answer questions restored from backup before ' .
'<a href="http://tracker.moodle.org/browse/MDL-14750">MDL-14750</a> was fixed.</p>';
}
function solution() {
return '<p>Upgrade to Moodle 1.9.1 or later, or manually execute the ' .
'code in question_multianswer_fix_subquestion_parents_and_categories in ' .
'<a href="http://cvs.moodle.org/moodle/question/type/multianswer/db/upgrade.php?revision=1.1.10.2&amp;view=markup">/question/type/multianswer/db/upgrade.php' .
'from the 1.9 stable branch</a>.</p>';
}
}
class problem_000014 extends problem_base {
function title() {
return 'Only multianswer and random questions should be the parent of another question';
}
function exists() {
global $DB;
return $DB->record_exists_sql("
SELECT * FROM {question} q
JOIN {question} parent_q ON parent_q.id = q.parent
WHERE parent_q.qtype NOT IN ('random', 'multianswer')");
}
function severity() {
return SEVERITY_ANNOYANCE;
}
function description() {
return '<p>You have questions that violate this in your databse. ' .
'You will need to investigate to determine how this happened.</p>';
}
function solution() {
return '<p>It is impossible to give a solution without knowing more about ' .
' how the problem was caused. You may be able to get help from the ' .
'<a href="http://moodle.org/mod/forum/view.php?f=121">Quiz forum</a>.</p>';
}
}
class problem_000015 extends problem_base {
function title() {
return 'Question categories should belong to a valid context';
}
function exists() {
global $DB;
return $DB->record_exists_sql("
SELECT qc.*, (SELECT COUNT(1) FROM {question} q WHERE q.category = qc.id) AS numquestions
FROM {question_categories} qc
LEFT JOIN {context} con ON qc.contextid = con.id
WHERE con.id IS NULL");
}
function severity() {
return SEVERITY_ANNOYANCE;
}
function description() {
global $DB;
$problemcategories = $DB->get_records_sql("
SELECT qc.id, qc.name, qc.contextid, (SELECT COUNT(1) FROM {question} q WHERE q.category = qc.id) AS numquestions
FROM {question_categories} qc
LEFT JOIN {context} con ON qc.contextid = con.id
WHERE con.id IS NULL
ORDER BY numquestions DESC, qc.name");
$table = '<table><thead><tr><th>Cat id</th><th>Category name</th>' .
"<th>Context id</th><th>Num Questions</th></tr></thead><tbody>\n";
foreach ($problemcategories as $cat) {
$table .= "<tr><td>$cat->id</td><td>" . s($cat->name) . "</td><td>" .
$cat->contextid ."</td><td>$cat->numquestions</td></tr>\n";
}
$table .= '</tbody></table>';
return '<p>All question categories are linked to a context id, and, ' .
'the context they are linked to must exist. The following categories ' .
'belong to a non-existant category:</p>' . $table . '<p>Any of these ' .
'categories that contain no questions can just be deleted form the database. ' .
'Other categories will require more thought.</p>';
}
function solution() {
global $CFG;
return '<p>You can delete the empty categories by executing the following SQL:</p><pre>
DELETE FROM ' . $CFG->prefix . 'question_categories
WHERE
NOT EXISTS (SELECT * FROM ' . $CFG->prefix . 'question q WHERE q.category = ' . $CFG->prefix . 'question_categories.id)
AND NOT EXISTS (SELECT * FROM ' . $CFG->prefix . 'context con WHERE contextid = con.id)
</pre><p>Any remaining categories that contain questions will require more thought. ' .
'People in the <a href="http://moodle.org/mod/forum/view.php?f=121">Quiz forum</a> may be able to help.</p>';
}
}
class problem_000016 extends problem_base {
function title() {
return 'Question categories should belong to the same context as their parent';
}
function exists() {
global $DB;
return $DB->record_exists_sql("
SELECT parent_qc.id AS parent, child_qc.id AS child, child_qc.contextid
FROM {question_categories} child_qc
JOIN {question_categories} parent_qc ON child_qc.parent = parent_qc.id
WHERE child_qc.contextid <> parent_qc.contextid");
}
function severity() {
return SEVERITY_ANNOYANCE;
}
function description() {
global $DB;
$problemcategories = $DB->get_records_sql("
SELECT
parent_qc.id AS parentid, parent_qc.name AS parentname, parent_qc.contextid AS parentcon,
child_qc.id AS childid, child_qc.name AS childname, child_qc.contextid AS childcon
FROM {question_categories} child_qc
JOIN {question_categories} parent_qc ON child_qc.parent = parent_qc.id
WHERE child_qc.contextid <> parent_qc.contextid");
$table = '<table><thead><tr><th colspan="3">Child category</th><th colspan="3">Parent category</th></tr><tr>' .
'<th>Id</th><th>Name</th><th>Context id</th>' .
'<th>Id</th><th>Name</th><th>Context id</th>' .
"</tr></thead><tbody>\n";
foreach ($problemcategories as $cat) {
$table .= "<tr><td>$cat->childid</td><td>" . s($cat->childname) .
"</td><td>$cat->childcon</td><td>$cat->parentid</td><td>" . s($cat->parentname) .
"</td><td>$cat->parentcon</td></tr>\n";
}
$table .= '</tbody></table>';
return '<p>When one question category is the parent of another, then they ' .
'should both belong to the same context. This is not true for the following categories:</p>' .
$table;
}
function solution() {
return '<p>An automated solution is difficult. It depends whether the ' .
'parent or child category is in the wrong pace.' .
'People in the <a href="http://moodle.org/mod/forum/view.php?f=121">Quiz forum</a> may be able to help.</p>';
}
}
class problem_000017 extends problem_base {
function title() {
return 'Question categories tree structure';
}
function find_problems() {
global $DB;
static $answer = null;
if (is_null($answer)) {
$categories = $DB->get_records('question_categories', array(), 'id');
// Look for missing parents.
$missingparent = array();
foreach ($categories as $category) {
if ($category->parent != 0 && !array_key_exists($category->parent, $categories)) {
$missingparent[$category->id] = $category;
}
}
// Look for loops.
$loops = array();
while (!empty($categories)) {
$current = array_pop($categories);
$thisloop = array($current->id => $current);
while (true) {
if (isset($thisloop[$current->parent])) {
// Loop detected
$loops[$current->id] = $thisloop;
break;
} else if (!isset($categories[$current->parent])) {
// Got to the top level, or a category we already know is OK.
break;
} else {
// Continue following the path.
$current = $categories[$current->parent];
$thisloop[$current->id] = $current;
unset($categories[$current->id]);
}
}
}
$answer = array($missingparent, $loops);
}
return $answer;
}
function exists() {
list($missingparent, $loops) = $this->find_problems();
return !empty($missingparent) || !empty($loops);
}
function severity() {
return SEVERITY_ANNOYANCE;
}
function description() {
list($missingparent, $loops) = $this->find_problems();
$description = '<p>The question categories should be arranged into tree ' .
' structures by the question_categories.parent field. Sometimes ' .
' this tree structure gets messed up.</p>';
if (!empty($missingparent)) {
$description .= '<p>The following categories are missing their parents:</p><ul>';
foreach ($missingparent as $cat) {
$description .= "<li>Category $cat->id: " . s($cat->name) . "</li>\n";
}
$description .= "</ul>\n";
}
if (!empty($loops)) {
$description .= '<p>The following categories form a loop of parents:</p><ul>';
foreach ($loops as $loop) {
$description .= "<li><ul>\n";
foreach ($loop as $cat) {
$description .= "<li>Category $cat->id: " . s($cat->name) . " has parent $cat->parent</li>\n";
}
$description .= "</ul></li>\n";
}
$description .= "</ul>\n";
}
return $description;
}
function solution() {
global $CFG;
list($missingparent, $loops) = $this->find_problems();
$solution = '<p>Consider executing the following SQL queries. These fix ' .
'the problem by moving some categories to the top level.</p>';
if (!empty($missingparent)) {
$solution .= "<pre>UPDATE " . $CFG->prefix . "question_categories\n" .
" SET parent = 0\n" .
" WHERE id IN (" . implode(',', array_keys($missingparent)) . ");</pre>\n";
}
if (!empty($loops)) {
$solution .= "<pre>UPDATE " . $CFG->prefix . "question_categories\n" .
" SET parent = 0\n" .
" WHERE id IN (" . implode(',', array_keys($loops)) . ");</pre>\n";
}
return $solution;
}
}
class problem_00000x extends problem_base {
function title() {
return '';
}
function exists() {
return false;
}
function severity() {
return SEVERITY_SIGNIFICANT;
}
function description() {
return '';
}
function solution() {
global $CFG;
return '';
}
}
/*
TODO:
session.save_path -- it doesn't really matter because we are already IN a session, right?
detect unsupported characters in $CFG->wwwroot - see bug Bug #6091 - relative vs absolute path during backup/restore process
*/
+173 -75
View File
@@ -26,7 +26,7 @@
// Check that config.php exists, if not then call the install script
if (!file_exists('../config.php')) {
header('Location: ../install.php');
die();
die;
}
// Check that PHP is of a sufficient version as soon as possible
@@ -35,19 +35,7 @@ if (version_compare(phpversion(), '5.3.2') < 0) {
// do NOT localise - lang strings would not work here and we CAN NOT move it to later place
echo "Moodle 2.1 or later requires at least PHP 5.3.2 (currently using version $phpversion).<br />";
echo "Please upgrade your server software or install older Moodle version.";
die();
}
// make sure iconv is available and actually works
if (!function_exists('iconv')) {
// this should not happen, this must be very borked install
echo 'Moodle requires the iconv PHP extension. Please install or enable the iconv extension.';
die();
}
if (iconv('UTF-8', 'UTF-8//IGNORE', 'abc') !== 'abc') {
// known to be broken in mid-2011 MAMP installations
echo 'Broken iconv PHP extension detected, installation/upgrade can not continue.';
die();
die;
}
define('NO_OUTPUT_BUFFERING', true);
@@ -87,6 +75,9 @@ if (is_float_problem()) {
}
// Set some necessary variables during set-up to avoid PHP warnings later on this page
if (!isset($CFG->framename)) {
$CFG->framename = '_top';
}
if (!isset($CFG->release)) {
$CFG->release = '';
}
@@ -103,11 +94,6 @@ if (!$version or !$release) {
print_error('withoutversion', 'debug'); // without version, stop
}
if (!isset($maturity)) {
// Fallback for now. Should probably be removed in the future.
$maturity = MATURITY_STABLE;
}
// Turn off xmlstrictheaders during upgrade.
$origxmlstrictheaders = !empty($CFG->xmlstrictheaders);
$CFG->xmlstrictheaders = false;
@@ -126,43 +112,65 @@ if (!core_tables_exist()) {
if (empty($agreelicense)) {
$strlicense = get_string('license');
$PAGE->navbar->add($strlicense);
$PAGE->set_title($strinstallation.' - Moodle '.$CFG->target_release);
$PAGE->set_heading($strinstallation);
$PAGE->set_cacheable(false);
$output = $PAGE->get_renderer('core', 'admin');
echo $output->install_licence_page();
die();
echo $OUTPUT->header();
echo $OUTPUT->heading('<a href="http://moodle.org">Moodle</a> - Modular Object-Oriented Dynamic Learning Environment');
echo $OUTPUT->heading(get_string('copyrightnotice'));
$copyrightnotice = text_to_html(get_string('gpl3'));
$copyrightnotice = str_replace('target="_blank"', 'onclick="this.target=\'_blank\'"', $copyrightnotice); // extremely ugly validation hack
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/dev/License");
echo $OUTPUT->footer();
die;
}
if (empty($confirmrelease)) {
require_once($CFG->libdir.'/environmentlib.php');
list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
$strcurrentrelease = get_string('currentrelease');
$PAGE->navbar->add($strcurrentrelease);
$PAGE->set_title($strinstallation);
$PAGE->set_heading($strinstallation . ' - Moodle ' . $CFG->target_release);
$PAGE->set_cacheable(false);
echo $OUTPUT->header();
echo $OUTPUT->heading("Moodle $release");
$output = $PAGE->get_renderer('core', 'admin');
echo $output->install_environment_page($maturity, $envstatus, $environment_results, $release);
die();
if (isset($maturity)) {
// main version.php declares moodle code maturity
if ($maturity < MATURITY_STABLE) {
$maturitylevel = get_string('maturity'.$maturity, 'admin');
echo $OUTPUT->box(
$OUTPUT->container(get_string('maturitycorewarning', 'admin', $maturitylevel)) .
$OUTPUT->container($OUTPUT->doc_link('admin/versions', get_string('morehelp'))),
'generalbox maturitywarning');
}
}
$releasenoteslink = get_string('releasenoteslink', 'admin', 'http://docs.moodle.org/dev/Releases');
$releasenoteslink = str_replace('target="_blank"', 'onclick="this.target=\'_blank\'"', $releasenoteslink); // extremely ugly validation hack
echo $OUTPUT->box($releasenoteslink, 'generalbox releasenoteslink');
require_once($CFG->libdir.'/environmentlib.php');
if (!check_moodle_environment(normalize_version($release), $environment_results, true, ENV_SELECT_RELEASE)) {
print_upgrade_reload("index.php?agreelicense=1&amp;lang=$CFG->lang");
} else {
echo $OUTPUT->notification(get_string('environmentok', 'admin'), 'notifysuccess');
echo $OUTPUT->continue_button(new moodle_url('/admin/index.php', array('agreelicense'=>1, 'confirmrelease'=>1, 'lang'=>$CFG->lang)));
}
echo $OUTPUT->footer();
die;
}
//TODO: add a page with list of non-standard plugins here
$strdatabasesetup = get_string('databasesetup');
upgrade_init_javascript();
$PAGE->navbar->add($strdatabasesetup);
$PAGE->set_title($strinstallation.' - Moodle '.$CFG->target_release);
$PAGE->set_heading($strinstallation);
$PAGE->set_cacheable(false);
$output = $PAGE->get_renderer('core', 'admin');
echo $output->header();
echo $OUTPUT->header();
if (!$DB->setup_is_unicodedb()) {
if (!$DB->change_db_encoding()) {
@@ -190,45 +198,78 @@ if ($version > $CFG->version) { // upgrade
$PAGE->set_pagelayout('maintenance');
$PAGE->set_popup_notification_allowed(false);
if (empty($confirmupgrade)) {
$a->oldversion = "$CFG->release ($CFG->version)";
$a->newversion = "$release ($version)";
$strdatabasechecking = get_string('databasechecking', '', $a);
$a->oldversion = "$CFG->release ($CFG->version)";
$a->newversion = "$release ($version)";
$strdatabasechecking = get_string('databasechecking', '', $a);
if (empty($confirmupgrade)) {
$PAGE->set_title($stradministration);
$PAGE->set_heading($strdatabasechecking);
$PAGE->set_cacheable(false);
$output = $PAGE->get_renderer('core', 'admin');
echo $output->upgrade_confirm_page($a->newversion, $maturity);
die();
echo $OUTPUT->header();
if (isset($maturity)) {
// main version.php declares moodle code maturity
if ($maturity < MATURITY_STABLE) {
$maturitylevel = get_string('maturity'.$maturity, 'admin');
echo $OUTPUT->box(
$OUTPUT->container(get_string('maturitycorewarning', 'admin', $maturitylevel)) .
$OUTPUT->container($OUTPUT->doc_link('admin/versions', get_string('morehelp'))),
'generalbox maturitywarning');
}
}
$continueurl = new moodle_url('index.php', array('confirmupgrade' => 1));
$cancelurl = new moodle_url('index.php');
echo $OUTPUT->confirm(get_string('upgradesure', 'admin', $a->newversion), $continueurl, $cancelurl);
echo $OUTPUT->footer();
exit;
} else if (empty($confirmrelease)){
require_once($CFG->libdir.'/environmentlib.php');
list($envstatus, $environment_results) = check_moodle_environment($release, ENV_SELECT_RELEASE);
$strcurrentrelease = get_string('currentrelease');
$PAGE->navbar->add($strcurrentrelease);
$PAGE->set_title($strcurrentrelease);
$PAGE->set_heading($strcurrentrelease);
$PAGE->set_cacheable(false);
echo $OUTPUT->header();
echo $OUTPUT->heading("Moodle $release");
$releasenoteslink = get_string('releasenoteslink', 'admin', 'http://docs.moodle.org/dev/Releases');
$releasenoteslink = str_replace('target="_blank"', 'onclick="this.target=\'_blank\'"', $releasenoteslink); // extremely ugly validation hack
echo $OUTPUT->box($releasenoteslink);
$output = $PAGE->get_renderer('core', 'admin');
echo $output->upgrade_environment_page($release, $envstatus, $environment_results);
die();
require_once($CFG->libdir.'/environmentlib.php');
if (!check_moodle_environment($release, $environment_results, true, ENV_SELECT_RELEASE)) {
print_upgrade_reload('index.php?confirmupgrade=1');
} else {
echo $OUTPUT->notification(get_string('environmentok', 'admin'), 'notifysuccess');
if (empty($CFG->skiplangupgrade)) {
echo $OUTPUT->box_start('generalbox', 'notice');
print_string('langpackwillbeupdated', 'admin');
echo $OUTPUT->box_end();
}
echo $OUTPUT->continue_button('index.php?confirmupgrade=1&confirmrelease=1');
}
} else if (empty($confirmplugins)) {
echo $OUTPUT->footer();
die;
} elseif (empty($confirmplugins)) {
$strplugincheck = get_string('plugincheck');
$PAGE->navbar->add($strplugincheck);
$PAGE->set_title($strplugincheck);
$PAGE->set_heading($strplugincheck);
$PAGE->set_cacheable(false);
$output = $PAGE->get_renderer('core', 'admin');
echo $output->upgrade_plugin_check_page(plugin_manager::instance(), $version, $showallplugins,
new moodle_url('/admin/index.php', array('confirmupgrade' => 1, 'confirmrelease' => 1)),
new moodle_url('/admin/index.php', array('confirmupgrade'=>1, 'confirmrelease'=>1, 'confirmplugincheck'=>1)));
$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();
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();
die();
} else {
@@ -249,19 +290,26 @@ if (moodle_needs_upgrading()) {
if (!$PAGE->headerprinted) {
// means core upgrade or installation was not already done
if (!$confirmplugins) {
$strplugincheck = get_string('plugincheck');
$PAGE->set_pagelayout('maintenance');
$PAGE->set_popup_notification_allowed(false);
$strplugincheck = get_string('plugincheck');
$PAGE->navbar->add($strplugincheck);
$PAGE->set_title($strplugincheck);
$PAGE->set_heading($strplugincheck);
$PAGE->set_cacheable(false);
$output = $PAGE->get_renderer('core', 'admin');
echo $output->upgrade_plugin_check_page(plugin_manager::instance(), $version, $showallplugins,
new moodle_url('/admin/index.php'),
new moodle_url('/admin/index.php', array('confirmplugincheck'=>1)));
$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();
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();
die();
}
}
@@ -297,8 +345,8 @@ if (during_initial_install()) {
}
}
// at this stage there can be only one admin unless more were added by install - users may change username, so do not rely on that
$adminuser = get_complete_user_data('id', reset(explode(',', $CFG->siteadmins)));
// at this stage there can be only one admin - users may change username, so do not rely on that
$adminuser = get_complete_user_data('id', $CFG->siteadmins);
if ($adminuser->password === 'adminsetuppending') {
// prevent installation hijacking
@@ -307,7 +355,7 @@ if (during_initial_install()) {
}
// login user and let him set password and admin details
$adminuser->newadminuser = 1;
complete_user_login($adminuser);
complete_user_login($adminuser, false);
redirect("$CFG->wwwroot/user/editadvanced.php?id=$adminuser->id"); // Edit thyself
} else {
@@ -356,14 +404,64 @@ if (any_new_admin_settings($adminroot)){
// Everything should now be set up, and the user is an admin
// Print default admin page with notifications.
$errorsdisplayed = defined('WARN_DISPLAY_ERRORS_ENABLED');
$lastcron = $DB->get_field_sql('SELECT MAX(lastcron) FROM {modules}');
$cronoverdue = ($lastcron < time() - 3600 * 24);
$dbproblems = $DB->diagnose();
$maintenancemode = !empty($CFG->maintenance_enabled);
admin_externalpage_setup('adminnotifications');
$output = $PAGE->get_renderer('core', 'admin');
echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed,
$cronoverdue, $dbproblems, $maintenancemode);
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) {
echo $OUTPUT->box(get_string('datarootsecurityerror', 'admin', $CFG->dataroot), 'generalbox adminerror');
}
if (defined('WARN_DISPLAY_ERRORS_ENABLED')) {
echo $OUTPUT->box(get_string('displayerrorswarning', 'admin'), 'generalbox adminwarning');
}
// If no recently cron run
$lastcron = $DB->get_field_sql('SELECT MAX(lastcron) FROM {modules}');
if (time() - $lastcron > 3600 * 24) {
$helpbutton = $OUTPUT->help_icon('cron', 'admin');
echo $OUTPUT->box(get_string('cronwarning', 'admin').'&nbsp;'.$helpbutton, 'generalbox adminwarning');
}
// Hidden bloglevel upgrade
$showbloglevelupgrade = ($CFG->bloglevel == BLOG_COURSE_LEVEL || $CFG->bloglevel == BLOG_GROUP_LEVEL) && empty($CFG->bloglevel_upgrade_complete);
if ($showbloglevelupgrade) {
echo $OUTPUT->box(get_string('bloglevelupgradenotice', 'admin'), 'generalbox adminwarning');
}
// diagnose DB, especially the sloppy MyISAM tables
$diagnose = $DB->diagnose();
if ($diagnose !== NULL) {
echo $OUTPUT->box($diagnose, 'generalbox adminwarning');
}
// Alert if we are currently in maintenance mode
if (!empty($CFG->maintenance_enabled)) {
echo $OUTPUT->box(get_string('sitemaintenancewarning2', 'admin', "$CFG->wwwroot/$CFG->admin/settings.php?section=maintenancemode"), 'generalbox adminwarning');
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//// IT IS ILLEGAL AND A VIOLATION OF THE GPL TO HIDE, REMOVE OR MODIFY THIS COPYRIGHT NOTICE ///
$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/dev/Credits">many other contributors</a>.<br />'.
'<a href="http://docs.moodle.org/dev/License">GNU Public License</a>';
echo $OUTPUT->box($copyrighttext, 'copyright');
//////////////////////////////////////////////////////////////////////////////////////////////////
echo $OUTPUT->footer();
+45
View File
@@ -0,0 +1,45 @@
<?php
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('toinodb');
$confirm = optional_param('confirm', 0, PARAM_BOOL);
require_login();
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
echo $OUTPUT->header();
echo $OUTPUT->heading('Convert all MySQL tables from MYISAM to InnoDB');
if ($DB->get_dbfamily() != 'mysql') {
notice('This function is for MySQL databases only!', 'index.php');
}
if (data_submitted() and $confirm and confirm_sesskey()) {
echo $OUTPUT->notification('Please be patient and wait for this to complete...', 'notifysuccess');
if ($tables = $DB->get_tables()) {
$DB->set_debug(true);
foreach ($tables as $table) {
$fulltable = $DB->get_prefix().$table;
$DB->change_database_structure("ALTER TABLE $fulltable TYPE=INNODB");
}
$DB->set_debug(false);
}
echo $OUTPUT->notification('... done.', 'notifysuccess');
echo $OUTPUT->continue_button('index.php');
echo $OUTPUT->footer();
} else {
$optionsyes = array('confirm'=>'1', 'sesskey'=>sesskey());
$formcontinue = new single_button(new moodle_url('/admin/innodb.php', $optionsyes), get_string('yes'));
$formcancel = new single_button(new moodle_url('/admin/index.php'), get_string('no'), 'get');
echo $OUTPUT->confirm('Are you sure you want convert all your tables to the InnoDB format?', $formcontinue, $formcancel);
echo $OUTPUT->footer();
}
+341
View File
@@ -0,0 +1,341 @@
<?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/>.
/**
* Fetches language packages from download.moodle.org server
*
* Language packages are available at http://download.moodle.org/langpack/
* in ZIP format together with a file languages.md5 containing their hashes
* and meta info.
* Locally, language packs are saved into $CFG->dataroot/lang/
*
* @package core
* @copyright 2005 Yu Zhang
* @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.'/filelib.php');
require_once($CFG->libdir.'/componentlib.class.php');
admin_externalpage_setup('langimport');
if (!empty($CFG->skiplangupgrade)) {
echo $OUTPUT->header();
echo $OUTPUT->box(get_string('langimportdisabled', 'admin'));
echo $OUTPUT->footer();
die;
}
$mode = optional_param('mode', 0, PARAM_INT); // action
$pack = optional_param('pack', array(), PARAM_SAFEDIR); // pack to install
$uninstalllang = optional_param('uninstalllang', '', PARAM_LANG); // installed pack to uninstall
$confirm = optional_param('confirm', 0, PARAM_BOOL); // uninstallation confirmation
define('INSTALLATION_OF_SELECTED_LANG', 2);
define('DELETION_OF_SELECTED_LANG', 4);
define('UPDATE_ALL_LANG', 5);
get_string_manager()->reset_caches();
$notice_ok = array();
$notice_error = array();
if (($mode == INSTALLATION_OF_SELECTED_LANG) and confirm_sesskey() and !empty($pack)) {
set_time_limit(0);
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 ($mode == DELETION_OF_SELECTED_LANG and !empty($uninstalllang)) {
if ($uninstalllang == 'en') {
$notice_error[] = 'English language pack can not be uninstalled';
} else if (!$confirm and confirm_sesskey()) {
echo $OUTPUT->header();
echo $OUTPUT->confirm(get_string('uninstallconfirm', 'admin', $uninstalllang),
'langimport.php?mode='.DELETION_OF_SELECTED_LANG.'&uninstalllang='.$uninstalllang.'&confirm=1',
'langimport.php');
echo $OUTPUT->footer();
die;
} else if (confirm_sesskey()) {
$dest1 = $CFG->dataroot.'/lang/'.$uninstalllang;
$dest2 = $CFG->dirroot.'/lang/'.$uninstalllang;
$rm1 = false;
$rm2 = false;
if (file_exists($dest1)){
$rm1 = remove_dir($dest1);
}
if (file_exists($dest2)){
$rm2 = remove_dir($dest2);
}
if ($rm1 or $rm2) {
$notice_ok[] = get_string('langpackremoved','admin');
} else { //nothing deleted, possibly due to permission error
$notice_error[] = 'An error has occurred, language pack is not completely uninstalled, please check file permissions';
}
}
}
if ($mode == UPDATE_ALL_LANG) {
set_time_limit(0);
$installer = new lang_installer();
if (!$availablelangs = $installer->get_remote_list_of_languages()) {
print_error('cannotdownloadlanguageupdatelist', 'error');
}
$md5array = array(); // (string)langcode => (string)md5
foreach ($availablelangs as $alang) {
$md5array[$alang[0]] = $alang[1];
}
// filter out unofficial packs
$currentlangs = array_keys(get_string_manager()->get_list_of_translations(true));
$updateablelangs = array();
foreach ($currentlangs as $clang) {
if (!array_key_exists($clang, $md5array)) {
$notice_ok[] = get_string('langpackupdateskipped', 'admin', $clang);
continue;
}
$dest1 = $CFG->dataroot.'/lang/'.$clang;
$dest2 = $CFG->dirroot.'/lang/'.$clang;
if (file_exists($dest1.'/langconfig.php') || file_exists($dest2.'/langconfig.php')){
$updateablelangs[] = $clang;
}
}
// then filter out packs that have the same md5 key
$neededlangs = array(); // all the packs that needs updating
foreach ($updateablelangs as $ulang) {
if (!is_installed_lang($ulang, $md5array[$ulang])) {
$neededlangs[] = $ulang;
}
}
make_upload_directory('temp');
make_upload_directory('lang');
// clean-up currently installed versions of the packs
foreach ($neededlangs as $packindex => $pack) {
if ($pack == 'en') {
continue;
}
// delete old directories
$dest1 = $CFG->dataroot.'/lang/'.$pack;
$dest2 = $CFG->dirroot.'/lang/'.$pack;
$rm1 = false;
$rm2 = false;
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;
}
}
if ($updated) {
$notice_ok[] = get_string('langupdatecomplete','admin');
} else {
$notice_ok[] = get_string('nolangupdateneeded','admin');
}
unset($installer);
}
get_string_manager()->reset_caches();
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('langimport', 'admin'));
$installedlangs = get_string_manager()->get_list_of_translations(true);
$missingparents = array();
foreach ($installedlangs as $installedlang => $unused) {
$parent = get_parent_language($installedlang);
if (empty($parent)) {
continue;
}
if (!isset($installedlangs[$parent])) {
$missingparents[$installedlang] = $parent;
}
}
$installer = new lang_installer();
if ($availablelangs = $installer->get_remote_list_of_languages()) {
$remote = true;
} else {
$remote = false;
$availablelangs = array();
echo $OUTPUT->box_start();
print_string('remotelangnotavailable', 'admin', $CFG->dataroot.'/lang/');
echo $OUTPUT->box_end();
}
if ($notice_ok) {
$info = implode('<br />', $notice_ok);
echo $OUTPUT->notification($info, 'notifysuccess');
}
if ($notice_error) {
$info = implode('<br />', $notice_error);
echo $OUTPUT->notification($info, 'notifyproblem');
}
if ($missingparents) {
foreach ($missingparents as $l=>$parent) {
$a = new stdClass();
$a->lang = $installedlangs[$l];
$a->parent = $parent;
foreach ($availablelangs as $alang) {
if ($alang[0] == $parent) {
$shortlang = $alang[0];
$a->parent = $alang[2].' ('.$shortlang.')';
}
}
$info = get_string('missinglangparent', 'admin', $a);
echo $OUTPUT->notification($info, 'notifyproblem');
}
}
echo $OUTPUT->box_start();
echo html_writer::start_tag('table');
echo html_writer::start_tag('tr');
// list of installed languages
$url = new moodle_url('/admin/langimport.php', array('mode' => DELETION_OF_SELECTED_LANG));
echo html_writer::start_tag('td', array('valign' => 'top'));
echo html_writer::start_tag('form', array('id' => 'uninstallform', 'action' => $url->out(), 'method' => 'post'));
echo html_writer::start_tag('fieldset');
echo html_writer::label(get_string('installedlangs','admin'), 'uninstalllang');
echo html_writer::empty_tag('br');
echo html_writer::select($installedlangs, 'uninstalllang', '', false, array('size' => 15));
echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
echo html_writer::empty_tag('br');
echo html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('uninstall','admin')));
echo html_writer::end_tag('fieldset');
echo html_writer::end_tag('form');
if ($remote) {
$url = new moodle_url('/admin/langimport.php', array('mode' => UPDATE_ALL_LANG));
echo html_writer::start_tag('form', array('id' => 'updateform', 'action' => $url->out(), 'method' => 'post'));
echo html_writer::tag('fieldset', html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('updatelangs','admin'))));
echo html_writer::end_tag('form');
}
echo html_writer::end_tag('td');
// list of available languages
$options = array();
foreach ($availablelangs as $alang) {
if (!empty($alang[0]) and trim($alang[0]) !== 'en' and !is_installed_lang($alang[0], $alang[1])) {
$options[$alang[0]] = $alang[2].' ('.$alang[0].')';
}
}
if (!empty($options)) {
echo html_writer::start_tag('td', array('valign' => 'top'));
$url = new moodle_url('/admin/langimport.php', array('mode' => INSTALLATION_OF_SELECTED_LANG));
echo html_writer::start_tag('form', array('id' => 'installform', 'action' => $url->out(), 'method' => 'post'));
echo html_writer::start_tag('fieldset');
echo html_writer::label(get_string('availablelangs','install'), 'pack');
echo html_writer::empty_tag('br');
echo html_writer::select($options, 'pack[]', '', false, array('size' => 15, 'multiple' => 'multiple'));
echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
echo html_writer::empty_tag('br');
echo html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('install','admin')));
echo html_writer::end_tag('fieldset');
echo html_writer::end_tag('form');
echo html_writer::end_tag('td');
}
echo html_writer::end_tag('tr');
echo html_writer::end_tag('table');
echo $OUTPUT->box_end();
echo $OUTPUT->footer();
die();
////////////////////////////////////////////////////////////////////////////////
// Local functions /////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* checks the md5 of the zip file, grabbed from download.moodle.org,
* against the md5 of the local language file from last update
* @param string $lang
* @param string $md5check
* @return bool
*/
function is_installed_lang($lang, $md5check) {
global $CFG;
$md5file = $CFG->dataroot.'/lang/'.$lang.'/'.$lang.'.md5';
if (file_exists($md5file)){
return (file_get_contents($md5file) == $md5check);
}
return false;
}
+1 -12
View File
@@ -35,16 +35,5 @@ function admin_page_type_list($pagetype, $parentcontext, $currentcontext) {
'admin-*' => get_string('page-admin-x', 'pagetype'),
$pagetype => get_string('page-admin-current', 'pagetype')
);
// Add the missing * (any page) option for them. MDL-30340
// TODO: These pages are really 'pagetype-varying' - MDL-30564 -
// and some day we should stop behaving that way, so proper pagetypes
// can be specified for it (like course-category-* or so).
// Luckly... the option we are introducing '*' is independent
// of that varying behavior, so will work.
if ($pagetype == 'admin-course-category') {
$array += array(
'*' => get_string('page-x', 'pagetype')
);
}
return $array;
}
}
+2 -2
View File
@@ -33,7 +33,7 @@ require_once($CFG->libdir.'/tablelib.php');
admin_externalpage_setup('managelocalplugins');
$delete = optional_param('delete', '', PARAM_PLUGIN);
$delete = optional_param('delete', '', PARAM_SAFEDIR);
$confirm = optional_param('confirm', '', PARAM_BOOL);
/// If data submitted, then process and store.
@@ -89,7 +89,7 @@ foreach (get_plugin_list('local') as $plugin => $plugindir) {
}
$plugins[$plugin] = $strpluginname;
}
collatorlib::asort($plugins);
textlib_get_instance()->asort($plugins);
foreach ($plugins as $plugin => $name) {
$delete = new moodle_url($PAGE->url, array('delete' => $plugin, 'sesskey' => sesskey()));
+3 -4
View File
@@ -203,18 +203,17 @@ echo get_string('username') . ":\n";
if (!empty($formerror['username'])) {
echo '<span class="error"> * </span>';
}
echo html_writer::label(get_string('username'), 'menuusername', false, array('class' => 'accesshide'));
echo '<input id="menuusername" type="text" name="username" size="20" maxlength="100" />';
echo '<input type="text" name="username" size="20" maxlength="100" />';
// choose a remote host
echo " " . html_writer::label(get_string('remotehost', 'mnet'), 'menumnet_host_id') . ":\n";
echo " " . get_string('remotehost', 'mnet') . ":\n";
if (!empty($formerror['mnet_host_id'])) {
echo '<span class="error"> * </span>';
}
echo html_writer::select($mnethosts, 'mnet_host_id');
// choose an access level
echo " " . html_writer::label(get_string('accesslevel', 'mnet'), 'menuaccessctrl') . ":\n";
echo " " . get_string('accesslevel', 'mnet') . ":\n";
if (!empty($formerror['accessctrl'])) {
echo '<span class="error"> * </span>';
}
+16 -25
View File
@@ -38,10 +38,9 @@ class mnet_simple_host_form extends moodleform {
$mform = $this->_form;
$mform->addElement('text', 'wwwroot', get_string('hostname', 'mnet'), array('maxlength' => 255, 'size' => 50));
$mform->addElement('text', 'wwwroot', get_string('hostname', 'mnet'));
$mform->setType('wwwroot', PARAM_URL);
$mform->addRule('wwwroot', null, 'required', null, 'client');
$mform->addRule('wwwroot', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
$mform->addElement('select', 'applicationid', get_string('applicationtype', 'mnet'),
$DB->get_records_menu('mnet_application', array(), 'id,display_name'));
@@ -50,7 +49,7 @@ class mnet_simple_host_form extends moodleform {
$this->add_action_buttons(false, get_string('addhost', 'mnet'));
}
function validation($data, $files) {
function validation($data) {
global $DB;
$wwwroot = $data['wwwroot'];
@@ -82,13 +81,11 @@ class mnet_review_host_form extends moodleform {
$mform->addElement('hidden', 'applicationid');
$mform->addElement('hidden', 'oldpublickey');
$mform->addElement('text', 'name', get_string('site'), array('maxlength' => 80, 'size' => 50));
$mform->addElement('text', 'name', get_string('site'));
$mform->setType('name', PARAM_NOTAGS);
$mform->addRule('name', get_string('maximumchars', '', 80), 'maxlength', 80, 'client');
$mform->addElement('text', 'wwwroot', get_string('hostname', 'mnet'), array('maxlength' => 255, 'size' => 50));
$mform->addElement('text', 'wwwroot', get_string('hostname', 'mnet'));
$mform->setType('wwwroot', PARAM_URL);
$mform->addRule('wwwroot', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
$themes = array('' => get_string('forceno'));
foreach (array_keys(get_plugin_list('theme')) as $themename) {
@@ -98,7 +95,15 @@ class mnet_review_host_form extends moodleform {
$mform->addElement('textarea', 'public_key', get_string('publickey', 'mnet'), array('rows' => 17, 'cols' => 100, 'class' => 'smalltext'));
$mform->setType('public_key', PARAM_PEM);
$mform->addRule('public_key', get_string('required'), 'required');
if ($mnet_peer && !empty($mnet_peer->deleted)) {
$radioarray = array();
$radioarray[] = MoodleQuickForm::createElement('radio', 'deleted', '', get_string('yes'), 1);
$radioarray[] = MoodleQuickForm::createElement('radio', 'deleted', '', get_string('no'), 0);
$mform->addGroup($radioarray, 'radioar', get_string('deleted'), array(' '), false);
} else {
$mform->addElement('hidden', 'deleted');
}
// finished with form controls, now the static informational stuff
if ($mnet_peer && !empty($mnet_peer->bootstrapped)) {
@@ -135,35 +140,21 @@ class mnet_review_host_form extends moodleform {
}
}
$mform->addElement('static', 'certdetails', get_string('certdetails', 'mnet'),
$OUTPUT->box('<pre>' . $credstr . '</pre>', 'generalbox certdetails'));
}
if ($mnet_peer && !empty($mnet_peer->deleted)) {
$radioarray = array();
$radioarray[] = MoodleQuickForm::createElement('static', 'deletedinfo', '',
$OUTPUT->container(get_string('deletedhostinfo', 'mnet'), 'deletedhostinfo'));
$radioarray[] = MoodleQuickForm::createElement('radio', 'deleted', '', get_string('yes'), 1);
$radioarray[] = MoodleQuickForm::createElement('radio', 'deleted', '', get_string('no'), 0);
$mform->addGroup($radioarray, 'radioar', get_string('deleted'), array(' ', ' '), false);
} else {
$mform->addElement('hidden', 'deleted');
$mform->addElement('static', 'certdetails', get_string('certdetails', 'mnet'), $OUTPUT->box('<pre>' . $credstr . '</pre>'));
}
// finished with static stuff, print save button
$this->add_action_buttons(false);
}
function validation($data, $files) {
function validation($data) {
$errors = array();
if ($data['oldpublickey'] == $data['public_key']) {
return;
}
$mnet_peer = new mnet_peer(); // idiotic api
$mnet_peer->wwwroot = $data['wwwroot']; // just hard-set this rather than bootstrap the object
if (empty($data['public_key'])) {
$errors['public_key'] = get_string('publickeyrequired', 'mnet');
} else if (!$credentials = $mnet_peer->check_credentials($data['public_key'])) {
if (!$credentials = $mnet_peer->check_credentials($data['public_key'])) {
$errmsg = '';
foreach ($mnet_peer->error as $err) {
$errmsg .= $err['code'] . ': ' . $err['text'].'<br />';
+5 -20
View File
@@ -30,7 +30,7 @@
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->dirroot.'/mnet/lib.php');
require_once($CFG->dirroot.'/'.$CFG->admin.'/mnet/peer_forms.php');
require_once($CFG->dirroot.'/admin/mnet/peer_forms.php');
require_login();
@@ -190,7 +190,7 @@ if ($formdata = $reviewform->get_data()) {
// normal flow - just display all hosts with links
echo $OUTPUT->header();
$hosts = mnet_get_hosts(true);
$hosts = mnet_get_hosts();
// print the table to display the register all hosts setting
$table = new html_table();
@@ -231,43 +231,28 @@ $table->head = array(
);
$table->wrap = array('nowrap', 'nowrap', 'nowrap', 'nowrap');
$baseurl = new moodle_url('/admin/mnet/peers.php');
$deleted = array();
foreach($hosts as $host) {
$hosturl = new moodle_url($baseurl, array('hostid' => $host->id));
if (trim($host->name) === '') {
// should not happen but...
$host->name = '???';
}
// process all hosts first since it's the easiest
if ($host->id == $CFG->mnet_all_hosts_id) {
$table->data[] = array(html_writer::link($hosturl, get_string('allhosts', 'core_mnet')), '*', '', '');
continue;
}
// populate the list of deleted hosts
if ($host->deleted) {
$deleted[] = html_writer::link($hosturl, $host->name);
$table->data[] = array(html_writer::tag('a', $host->name, array('href'=>$hosturl)), '', '', '');
continue;
}
if ($host->last_connect_time == 0) {
$last_connect = get_string('never');
} else {
$last_connect = userdate($host->last_connect_time, get_string('strftimedatetime', 'core_langconfig'));
$last_connect = date('H:i:s d/m/Y', $host->last_connect_time);
}
$table->data[] = array(
html_writer::link($hosturl, $host->name),
html_writer::link($host->wwwroot, $host->wwwroot),
html_writer::link($hosturl, $host->wwwroot),
$last_connect,
$OUTPUT->single_button(new moodle_url('/admin/mnet/delete.php', array('hostid' => $host->id)), get_string('delete'))
);
}
echo html_writer::table($table);
if ($deleted) {
echo $OUTPUT->box(get_string('deletedhosts', 'core_mnet', join(', ', $deleted)), 'deletedhosts');
}
// finally, print the initial form to add a new host
echo $OUTPUT->box_start();
echo $OUTPUT->heading(get_string('addnewhost', 'mnet'), 3);
+2 -11
View File
@@ -39,15 +39,6 @@ class mnet_profile_form extends moodleform {
global $CFG;
$mform =& $this->_form;
$mnetprofileimportfields = '';
if (isset($CFG->mnetprofileimportfields)) {
$mnetprofileimportfields = str_replace(',', ', ', $CFG->mnetprofileimportfields);
}
$mnetprofileexportfields = '';
if (isset($CFG->mnetprofileexportfields)) {
$mnetprofileexportfields = str_replace(',', ', ', $CFG->mnetprofileexportfields);
}
$mform->addElement('hidden', 'hostid', $this->_customdata['hostid']);
$fields = mnet_profile_field_options();
@@ -58,7 +49,7 @@ class mnet_profile_form extends moodleform {
$select = $mform->addElement('select', 'importfields', get_string('importfields', 'mnet'), $fields['optional']);
$select->setMultiple(true);
$mform->addElement('checkbox', 'importdefault', get_string('leavedefault', 'mnet'), $mnetprofileimportfields);
$mform->addElement('checkbox', 'importdefault', get_string('leavedefault', 'mnet'), str_replace(',', ', ', $CFG->mnetprofileimportfields));
// Fields to export ----------------------------------------------------
$mform->addElement('header', 'export', get_string('exportfields', 'mnet'));
@@ -66,7 +57,7 @@ class mnet_profile_form extends moodleform {
$select = $mform->addElement('select', 'exportfields', get_string('exportfields', 'mnet'), $fields['optional']);
$select->setMultiple(true);
$mform->addElement('checkbox', 'exportdefault', get_string('leavedefault', 'mnet'), $mnetprofileexportfields);
$mform->addElement('checkbox', 'exportdefault', get_string('leavedefault', 'mnet'), str_replace(',', ', ', $CFG->mnetprofileexportfields));
$this->add_action_buttons();
}
+1 -1
View File
@@ -36,7 +36,7 @@ class mnet_services_form extends moodleform {
function definition() {
$mform =& $this->_form;
$mnet_peer =& $this->_customdata['peer'];
$myservices = mnet_get_service_info($mnet_peer);
$myservices =& mnet_get_service_info($mnet_peer);
$mform->addElement('hidden', 'hostid', $mnet_peer->id);
+1 -1
View File
@@ -38,7 +38,7 @@ $strmnetlog = get_string('mnetlog', 'mnet');
$strmnetedithost = get_string('reviewhostdetails', 'mnet');
$logurl = $CFG->wwwroot.
'/report/log/index.php?chooselog=1&amp;showusers=1&amp;showcourses=1&amp;host_course='.$mnet_peer->id.
'/course/report/log/index.php?chooselog=1&amp;showusers=1&amp;showcourses=1&amp;host_course='.$mnet_peer->id.
'%2F1&amp;user='.'0'.
'&amp;date=0'.
'&amp;modid=&amp;modaction=0&amp;logformat=showashtml';
+3 -4
View File
@@ -11,9 +11,9 @@
admin_externalpage_setup('managemodules');
$show = optional_param('show', '', PARAM_PLUGIN);
$hide = optional_param('hide', '', PARAM_PLUGIN);
$delete = optional_param('delete', '', PARAM_PLUGIN);
$show = optional_param('show', '', PARAM_SAFEDIR);
$hide = optional_param('hide', '', PARAM_SAFEDIR);
$delete = optional_param('delete', '', PARAM_SAFEDIR);
$confirm = optional_param('confirm', '', PARAM_BOOL);
@@ -92,7 +92,6 @@
}
uninstall_plugin('mod', $delete);
$a = new stdClass();
$a->module = $strmodulename;
$a->directory = "$CFG->dirroot/mod/$delete";
echo $OUTPUT->notification(get_string("moduledeletefiles", "", $a), 'notifysuccess');
+117
View File
@@ -0,0 +1,117 @@
<?php
/// Search and replace strings throughout all texts in the whole database
define('NO_OUTPUT_BUFFERING', true);
require_once('../config.php');
require_once($CFG->dirroot.'/course/lib.php');
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('multilangupgrade');
$go = optional_param('go', 0, PARAM_BOOL);
###################################################################
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('multilangupgrade', 'admin'));
$strmultilangupgrade = get_String('multilangupgradeinfo', 'admin');
if (!$go or !data_submitted() or !confirm_sesskey()) { /// Print a form
$optionsyes = array('go'=>1, 'sesskey'=>sesskey());
echo $OUTPUT->confirm($strmultilangupgrade, new moodle_url('multilangupgrade.php', $optionsyes), 'index.php');
echo $OUTPUT->footer();
die;
}
if (!$tables = $DB->get_tables() ) { // No tables yet at all.
print_error('notables', 'debug');
}
echo $OUTPUT->box_start();
/// Turn off time limits, sometimes upgrades can be slow.
@set_time_limit(0);
echo '<strong>Progress:</strong>';
$i = 0;
$skiptables = array('config', 'user_students', 'user_teachers');
foreach ($tables as $table) {
if (strpos($table,'pma') === 0) { // Not our tables
continue;
}
if (in_array($table, $skiptables)) { // Don't process these
continue;
}
$fulltable = $DB->get_prefix().$table;
if ($columns = $DB->get_columns($table)) {
if (!array_key_exists('id', $columns)) {
continue; // moodle tables have id
}
foreach ($columns as $column => $data) {
if (in_array($data->type, array('text','mediumtext','longtext','varchar'))) { // Text stuff only
// first find candidate records
$sql = "SELECT id, $column FROM $fulltable WHERE $column LIKE '%</lang>%' OR $column LIKE '%<span lang=%'";
$rs = $DB->get_recordset_sql($sql);
foreach ($rs as $data) {
$text = $data->$column;
$id = $data->id;
if ($i % 600 == 0) {
echo '<br />';
}
if ($i % 10 == 0) {
echo '.';
}
$i++;
if (empty($text) or is_numeric($text)) {
continue; // nothing to do
}
$search = '/(<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.+?<\/(?:lang|span)>)(\s*<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.+?<\/(?:lang|span)>)+/is';
$newtext = preg_replace_callback($search, 'multilangupgrade_impl', $text);
if (is_null($newtext)) {
continue; // regex error
}
if ($newtext != $text) {
$DB->execute("UPDATE $fulltable SET $column=? WHERE id=?", array($newtext, $id));
}
}
$rs->close();
}
}
}
}
// set conversion flag - switches to new plugin automatically
set_config('filter_multilang_converted', 1);
echo $OUTPUT->box_end();
/// Rebuild course cache which might be incorrect now
echo $OUTPUT->notification('Rebuilding course cache...', 'notifysuccess');
rebuild_course_cache();
echo $OUTPUT->notification('...finished', 'notifysuccess');
echo $OUTPUT->continue_button('index.php');
echo $OUTPUT->footer();
die;
function multilangupgrade_impl($langblock) {
$searchtosplit = '/<(?:lang|span) lang="([a-zA-Z0-9_-]*)".*?>(.+?)<\/(?:lang|span)>/is';
preg_match_all($searchtosplit, $langblock[0], $rawlanglist);
$return = '';
foreach ($rawlanglist[1] as $index=>$lang) {
$return .= '<span lang="'.$lang.'" class="multilang">'.$rawlanglist[2][$index].'</span>';
}
return $return;
}
+8 -1
View File
@@ -31,4 +31,11 @@ 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');
echo $output->plugin_management_page(plugin_manager::instance());
$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();
-2
View File
@@ -197,7 +197,6 @@ if (($action == 'edit') || ($action == 'new')) {
$currentaction = 'hide';
}
$select = new single_select(portfolio_action_url($pluginid, 'pf'), 'action', $actionchoicesforexisting, $currentaction, null, 'applyto' . $pluginid);
$select->set_label(get_string('action'), array('class' => 'accesshide'));
$table->data[] = array($pluginname, $OUTPUT->render($select), $settings);
}
if (!in_array($plugin, $usedplugins)) {
@@ -219,7 +218,6 @@ if (($action == 'edit') || ($action == 'new')) {
$insaneplugins[] = $p;
} else {
$select = new single_select(portfolio_action_url($p, 'pf'), 'action', $actionchoicesfornew, 'delete', null, 'applyto' . $p);
$select->set_label(get_string('action'), array('class' => 'accesshide'));
$table->data[] = array(portfolio_static_function($p, 'get_name'), $OUTPUT->render($select), '');
}
}
+21 -21
View File
@@ -28,7 +28,6 @@
require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->libdir . '/questionlib.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/pluginlib.php');
require_once($CFG->libdir . '/tablelib.php');
// Check permissions.
@@ -40,7 +39,6 @@ admin_externalpage_setup('manageqbehaviours');
$thispageurl = new moodle_url('/admin/qbehaviours.php');
$behaviours = get_plugin_list('qbehaviour');
$pluginmanager = plugin_manager::instance();
// Get some data we will need - question counts and which types are needed.
$counts = $DB->get_records_sql_menu("
@@ -52,16 +50,20 @@ foreach ($behaviours as $behaviour => $notused) {
if (!array_key_exists($behaviour, $counts)) {
$counts[$behaviour] = 0;
}
$needed[$behaviour] = ($counts[$behaviour] > 0) ||
$pluginmanager->other_plugins_that_require('qbehaviour_' . $behaviour);
$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['missing'] += $count;
$counts['missingtype'] += $count;
}
}
$needed['missing'] = true;
// Work of the correct sort order.
$config = get_config('question');
@@ -83,7 +85,7 @@ if (!empty($config->disabledbehaviours)) {
// Process actions ============================================================
// Disable.
if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (($disable = optional_param('disable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($behaviours[$disable])) {
print_error('unknownbehaviour', 'question', $thispageurl, $disable);
}
@@ -96,7 +98,7 @@ if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey(
}
// Enable.
if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (($enable = optional_param('enable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($behaviours[$enable])) {
print_error('unknownbehaviour', 'question', $thispageurl, $enable);
}
@@ -113,7 +115,7 @@ if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey())
}
// Move up in order.
if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (($up = optional_param('up', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($behaviours[$up])) {
print_error('unknownbehaviour', 'question', $thispageurl, $up);
}
@@ -125,7 +127,7 @@ if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
}
// Move down in order.
if (($down = optional_param('down', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (($down = optional_param('down', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($behaviours[$down])) {
print_error('unknownbehaviour', 'question', $thispageurl, $down);
}
@@ -137,7 +139,7 @@ if (($down = optional_param('down', '', PARAM_PLUGIN)) && confirm_sesskey()) {
}
// Delete.
if (($delete = optional_param('delete', '', PARAM_PLUGIN)) && confirm_sesskey()) {
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);
@@ -179,7 +181,7 @@ if (($delete = optional_param('delete', '', PARAM_PLUGIN)) && confirm_sesskey())
unset($disabledbehaviours[$key]);
set_config('disabledbehaviours', implode(',', $disabledbehaviours), 'question');
}
$behaviourorder = array_keys($sortedbehaviours);
$behaviourorder = explode(',', $config->behavioursortorder);
if (($key = array_search($delete, $behaviourorder)) !== false) {
unset($behaviourorder[$key]);
set_config('behavioursortorder', implode(',', $behaviourorder), 'question');
@@ -191,7 +193,6 @@ if (($delete = optional_param('delete', '', PARAM_PLUGIN)) && confirm_sesskey())
// Remove event handlers and dequeue pending events
events_uninstall('qbehaviour_' . $delete);
$a = new stdClass();
$a->behaviour = $behaviourname;
$a->directory = get_plugin_directory('qbehaviour', $delete);
echo $OUTPUT->box(get_string('qbehaviourdeletefiles', 'question', $a), 'generalbox', 'notice');
@@ -237,19 +238,18 @@ foreach ($sortedbehaviours as $behaviour => $behaviourname) {
}
// Other question types required by this one.
$plugin = $pluginmanager->get_plugin_info('qbehaviour_' . $behaviour);
$required = $plugin->get_other_required_plugins();
if (!empty($required)) {
$strrequired = array();
foreach ($required as $component => $notused) {
$strrequired[] = $pluginmanager->plugin_name($component);
$requiredbehaviours = question_engine::get_behaviour_required_behaviours($behaviour);
if (!empty($requiredbehaviours)) {
$strrequiredbehaviours = array();
foreach ($requiredbehaviours as $required) {
$strrequiredbehaviours[] = $sortedbehaviours[$required];
}
$row[] = implode(', ', $strrequired);
$row[] = implode(', ', $strrequiredbehaviours);
} else {
$row[] = '';
}
// Are people allowed to select this behaviour?
// Are people allowed to create new questions of this type?
$rowclass = '';
if ($archetypal[$behaviour]) {
$enabled = array_search($behaviour, $disabledbehaviours) === false;
+15 -15
View File
@@ -28,7 +28,6 @@
require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->libdir . '/questionlib.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/pluginlib.php');
require_once($CFG->libdir . '/tablelib.php');
// Check permissions.
@@ -41,7 +40,6 @@ admin_externalpage_setup('manageqtypes');
$thispageurl = new moodle_url('/admin/qtypes.php');
$qtypes = question_bank::get_all_qtypes();
$pluginmanager = plugin_manager::instance();
// Get some data we will need - question counts and which types are needed.
$counts = $DB->get_records_sql("
@@ -54,11 +52,15 @@ foreach ($qtypes as $qtypename => $qtype) {
$counts[$qtypename]->numquestions = 0;
$counts[$qtypename]->numhidden = 0;
}
$needed[$qtypename] = $counts[$qtypename]->numquestions > 0 ||
$pluginmanager->other_plugins_that_require($qtype->plugin_name());
$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;
}
}
foreach ($counts as $qtypename => $count) {
if (!isset($qtypes[$qtypename])) {
$counts['missingtype']->numquestions += $count->numquestions - $count->numhidden;
@@ -77,7 +79,7 @@ $sortedqtypes = question_bank::sort_qtype_array($sortedqtypes, $config);
// Process actions ============================================================
// Disable.
if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (($disable = optional_param('disable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($qtypes[$disable])) {
print_error('unknownquestiontype', 'question', $thispageurl, $disable);
}
@@ -87,7 +89,7 @@ if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey(
}
// Enable.
if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (($enable = optional_param('enable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($qtypes[$enable])) {
print_error('unknownquestiontype', 'question', $thispageurl, $enable);
}
@@ -101,7 +103,7 @@ if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey())
}
// Move up in order.
if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (($up = optional_param('up', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($qtypes[$up])) {
print_error('unknownquestiontype', 'question', $thispageurl, $up);
}
@@ -112,7 +114,7 @@ if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
}
// Move down in order.
if (($down = optional_param('down', '', PARAM_PLUGIN)) && confirm_sesskey()) {
if (($down = optional_param('down', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
if (!isset($qtypes[$down])) {
print_error('unknownquestiontype', 'question', $thispageurl, $down);
}
@@ -123,7 +125,7 @@ if (($down = optional_param('down', '', PARAM_PLUGIN)) && confirm_sesskey()) {
}
// Delete.
if (($delete = optional_param('delete', '', PARAM_PLUGIN)) && confirm_sesskey()) {
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);
@@ -171,7 +173,6 @@ if (($delete = optional_param('delete', '', PARAM_PLUGIN)) && confirm_sesskey())
// Remove event handlers and dequeue pending events
events_uninstall('qtype_' . $delete);
$a = new stdClass();
$a->qtype = $qtypename;
$a->directory = $qtypes[$delete]->plugin_dir();
echo $OUTPUT->box(get_string('qtypedeletefiles', 'question', $a), 'generalbox', 'notice');
@@ -218,7 +219,7 @@ foreach ($sortedqtypes as $qtypename => $localname) {
$strcount = $counts[$qtypename]->numquestions;
}
if ($canviewreports) {
$row[] = html_writer::link(new moodle_url('/report/questioninstances/index.php',
$row[] = html_writer::link(new moodle_url('/admin/report/questioninstances/index.php',
array('qtype' => $qtypename)), $strcount, array('title' => get_string('showdetails', 'admin')));
} else {
$strcount;
@@ -236,12 +237,11 @@ foreach ($sortedqtypes as $qtypename => $localname) {
}
// Other question types required by this one.
$plugin = $pluginmanager->get_plugin_info($qtype->plugin_name());
$requiredtypes = $plugin->get_other_required_plugins();
$requiredtypes = $qtype->requires_qtypes();
$strtypes = array();
if (!empty($requiredtypes)) {
foreach ($requiredtypes as $required => $notused) {
$strtypes[] = $pluginmanager->plugin_name($required);
foreach ($requiredtypes as $required) {
$strtypes[] = $qtypes[$required]->local_name();
}
$row[] = implode(', ', $strtypes);
} else {
+3 -3
View File
@@ -136,8 +136,8 @@ class hub_selector_form extends moodleform {
$options = array();
foreach ($hubs as $hub) {
//to not display a name longer than 100 character (too big)
if (textlib::strlen($hub['name']) > 100) {
$hubname = textlib::substr($hub['name'], 0, 100);
if (strlen($hub['name']) > 100) {
$hubname = substr($hub['name'], 0, 100);
$hubname = $hubname . "...";
} else {
$hubname = $hub['name'];
@@ -283,7 +283,7 @@ class site_registration_form extends moodleform {
$mform->addHelpButton('urlstring', 'siteurl', 'hub');
$languages = get_string_manager()->get_list_of_languages();
collatorlib::asort($languages);
textlib_get_instance()->asort($languages);
$mform->addElement('select', 'language', get_string('sitelang', 'hub'),
$languages);
$mform->setType('language', PARAM_ALPHANUMEXT);
+11 -643
View File
@@ -32,394 +32,6 @@ require_once($CFG->libdir . '/pluginlib.php');
*/
class core_admin_renderer extends plugin_renderer_base {
/**
* Display the 'Do you acknowledge the terms of the GPL' page. The first page
* during install.
* @return string HTML to output.
*/
public function install_licence_page() {
global $CFG;
$output = '';
$copyrightnotice = text_to_html(get_string('gpl3'));
$copyrightnotice = str_replace('target="_blank"', 'onclick="this.target=\'_blank\'"', $copyrightnotice); // extremely ugly validation hack
$continue = new single_button(new moodle_url('/admin/index.php', array('lang'=>$CFG->lang, 'agreelicense'=>1)), get_string('continue'), 'get');
$output .= $this->header();
$output .= $this->heading('<a href="http://moodle.org">Moodle</a> - Modular Object-Oriented Dynamic Learning Environment');
$output .= $this->heading(get_string('copyrightnotice'));
$output .= $this->box($copyrightnotice, 'copyrightnotice');
$output .= html_writer::empty_tag('br');
$output .= $this->confirm(get_string('doyouagree'), $continue, "http://docs.moodle.org/dev/License");
$output .= $this->footer();
return $output;
}
/**
* Display the 'environment check' page that is displayed during install.
* @param int $maturity
* @param boolean $envstatus final result of the check (true/false)
* @param array $environment_results array of results gathered
* @param string $release moodle release
* @return string HTML to output.
*/
public function install_environment_page($maturity, $envstatus, $environment_results, $release) {
global $CFG;
$output = '';
$output .= $this->header();
$output .= $this->maturity_warning($maturity);
$output .= $this->heading("Moodle $release");
$output .= $this->release_notes_link();
$output .= $this->environment_check_table($envstatus, $environment_results);
if (!$envstatus) {
$output .= $this->upgrade_reload(new moodle_url('/admin/index.php', array('agreelicense' => 1, 'lang' => $CFG->lang)));
} else {
$output .= $this->notification(get_string('environmentok', 'admin'), 'notifysuccess');
$output .= $this->continue_button(new moodle_url('/admin/index.php', array('agreelicense'=>1, 'confirmrelease'=>1, 'lang'=>$CFG->lang)));
}
$output .= $this->footer();
return $output;
}
/**
* Display the 'You are about to upgrade Moodle' page. The first page
* during upgrade.
* @param string $strnewversion
* @param int $maturity
* @return string HTML to output.
*/
public function upgrade_confirm_page($strnewversion, $maturity) {
$output = '';
$continueurl = new moodle_url('index.php', array('confirmupgrade' => 1));
$cancelurl = new moodle_url('index.php');
$output .= $this->header();
$output .= $this->maturity_warning($maturity);
$output .= $this->confirm(get_string('upgradesure', 'admin', $strnewversion), $continueurl, $cancelurl);
$output .= $this->footer();
return $output;
}
/**
* Display the environment page during the upgrade process.
* @param string $release
* @param boolean $envstatus final result of env check (true/false)
* @param array $environment_results array of results gathered
* @return string HTML to output.
*/
public function upgrade_environment_page($release, $envstatus, $environment_results) {
global $CFG;
$output = '';
$output .= $this->header();
$output .= $this->heading("Moodle $release");
$output .= $this->release_notes_link();
$output .= $this->environment_check_table($envstatus, $environment_results);
if (!$envstatus) {
$output .= $this->upgrade_reload(new moodle_url('/admin/index.php'), array('confirmupgrade' => 1));
} else {
$output .= $this->notification(get_string('environmentok', 'admin'), 'notifysuccess');
if (empty($CFG->skiplangupgrade) and current_language() !== 'en') {
$output .= $this->box(get_string('langpackwillbeupdated', 'admin'), 'generalbox', 'notice');
}
$output .= $this->continue_button(new moodle_url('/admin/index.php', array('confirmupgrade' => 1, 'confirmrelease' => 1)));
}
$output .= $this->footer();
return $output;
}
/**
* Display the upgrade page that lists all the plugins that require attention.
* @param plugin_manager $pluginman provides information about the plugins.
* @param int $version the version of the Moodle code from version.php.
* @param bool $showallplugins
* @param moodle_url $reloadurl
* @param moodle_url $continueurl
* @return string HTML to output.
*/
public function upgrade_plugin_check_page(plugin_manager $pluginman, $version, $showallplugins, $reloadurl, $continueurl) {
$output = '';
$output .= $this->header();
$output .= $this->box_start('generalbox');
$output .= $this->container(get_string('pluginchecknotice', 'core_plugin'), 'generalbox', 'notice');
$output .= $this->plugins_check_table($pluginman, $version, array('full' => $showallplugins));
$output .= $this->box_end();
$output .= $this->upgrade_reload($reloadurl);
if ($pluginman->all_plugins_ok($version)) {
$button = new single_button($continueurl, get_string('upgradestart', 'admin'), 'get');
$button->class = 'continuebutton';
$output .= $this->render($button);
} else {
$output .= $this->box(get_string('pluginschecktodo', 'admin'), 'environmentbox errorbox');
}
$output .= $this->footer();
return $output;
}
/**
* Display the admin notifications page.
* @param int $maturity
* @param bool $insecuredataroot warn dataroot is invalid
* @param bool $errorsdisplayed warn invalid dispaly error setting
* @param bool $cronoverdue warn cron not running
* @param bool $dbproblems warn db has problems
* @param bool $maintenancemode warn in maintenance mode
* @return string HTML to output.
*/
public function admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed,
$cronoverdue, $dbproblems, $maintenancemode) {
$output = '';
$output .= $this->header();
$output .= $this->maturity_info($maturity);
$output .= $this->insecure_dataroot_warning($insecuredataroot);
$output .= $this->display_errors_warning($errorsdisplayed);
$output .= $this->cron_overdue_warning($cronoverdue);
$output .= $this->db_problems($dbproblems);
$output .= $this->maintenance_mode_warning($maintenancemode);
//////////////////////////////////////////////////////////////////////////////////////////////////
//// IT IS ILLEGAL AND A VIOLATION OF THE GPL TO HIDE, REMOVE OR MODIFY THIS COPYRIGHT NOTICE ///
$output .= $this->moodle_copyright();
//////////////////////////////////////////////////////////////////////////////////////////////////
$output .= $this->footer();
return $output;
}
/**
* Display the plugin management page (admin/plugins.php).
* @param plugin_manager $pluginman
* @return string HTML to output.
*/
public function plugin_management_page(plugin_manager $pluginman) {
$output = '';
$output .= $this->header();
$output .= $this->heading(get_string('pluginsoverview', 'core_admin'));
$output .= $this->box_start('generalbox');
$output .= $this->plugins_control_panel($pluginman);
$output .= $this->box_end();
$output .= $this->footer();
return $output;
}
/**
* Display the plugin management page (admin/environment.php).
* @param array $versions
* @param string $version
* @param boolean $envstatus final result of env check (true/false)
* @param array $environment_results array of results gathered
* @return string HTML to output.
*/
public function environment_check_page($versions, $version, $envstatus, $environment_results) {
$output = '';
$output .= $this->header();
// Print the component download link
$output .= html_writer::tag('div', html_writer::link(
new moodle_url('/admin/environment.php', array('action' => 'updatecomponent', 'sesskey' => sesskey())),
get_string('updatecomponent', 'admin')),
array('class' => 'reportlink'));
// Heading.
$output .= $this->heading(get_string('environment', 'admin'));
// Box with info and a menu to choose the version.
$output .= $this->box_start();
$output .= html_writer::tag('div', get_string('adminhelpenvironment'));
$select = new single_select(new moodle_url('/admin/environment.php'), 'version', $versions, $version, null);
$select->label = get_string('moodleversion');
$output .= $this->render($select);
$output .= $this->box_end();
// The results
$output .= $this->environment_check_table($envstatus, $environment_results);
$output .= $this->footer();
return $output;
}
/**
* Output a warning message, of the type that appears on the admin notifications page.
* @param string $message the message to display.
* @param string $type type class
* @return string HTML to output.
*/
protected function warning($message, $type = 'warning') {
return $this->box($message, 'generalbox admin' . $type);
}
/**
* Render an appropriate message if dataroot is insecure.
* @param bool $insecuredataroot
* @return string HTML to output.
*/
protected function insecure_dataroot_warning($insecuredataroot) {
global $CFG;
if ($insecuredataroot == INSECURE_DATAROOT_WARNING) {
return $this->warning(get_string('datarootsecuritywarning', 'admin', $CFG->dataroot));
} else if ($insecuredataroot == INSECURE_DATAROOT_ERROR) {
return $this->warning(get_string('datarootsecurityerror', 'admin', $CFG->dataroot), 'error');
} else {
return '';
}
}
/**
* Render an appropriate message if dataroot is insecure.
* @param bool $errorsdisplayed
* @return string HTML to output.
*/
protected function display_errors_warning($errorsdisplayed) {
if (!$errorsdisplayed) {
return '';
}
return $this->warning(get_string('displayerrorswarning', 'admin'));
}
/**
* Render an appropriate message if cron has not been run recently.
* @param bool $cronoverdue
* @return string HTML to output.
*/
public function cron_overdue_warning($cronoverdue) {
if (!$cronoverdue) {
return '';
}
return $this->warning(get_string('cronwarning', 'admin') . '&nbsp;' .
$this->help_icon('cron', 'admin'));
}
/**
* Render an appropriate message if there are any problems with the DB set-up.
* @param bool $dbproblems
* @return string HTML to output.
*/
public function db_problems($dbproblems) {
if (!$dbproblems) {
return '';
}
return $this->warning($dbproblems);
}
/**
* Render an appropriate message if the site in in maintenance mode.
* @param bool $maintenancemode
* @return string HTML to output.
*/
public function maintenance_mode_warning($maintenancemode) {
if (!$maintenancemode) {
return '';
}
$url = new moodle_url('/admin/settings.php', array('section' => 'maintenancemode'));
$url = $url->out(); // get_string() does not support objects in params
return $this->warning(get_string('sitemaintenancewarning2', 'admin', $url));
}
/**
* Display a warning about installing development code if necesary.
* @param int $maturity
* @return string HTML to output.
*/
protected function maturity_warning($maturity) {
if ($maturity == MATURITY_STABLE) {
return ''; // No worries.
}
$maturitylevel = get_string('maturity' . $maturity, 'admin');
return $this->box(
$this->container(get_string('maturitycorewarning', 'admin', $maturitylevel)) .
$this->container($this->doc_link('admin/versions', get_string('morehelp'))),
'generalbox maturitywarning');
}
/**
* Output the copyright notice.
* @return string HTML to output.
*/
protected function moodle_copyright() {
global $CFG;
//////////////////////////////////////////////////////////////////////////////////////////////////
//// IT IS ILLEGAL AND A VIOLATION OF THE GPL TO HIDE, REMOVE OR MODIFY THIS COPYRIGHT NOTICE ///
$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/dev/Credits">many other contributors</a>.<br />'.
'<a href="http://docs.moodle.org/dev/License">GNU Public License</a>';
//////////////////////////////////////////////////////////////////////////////////////////////////
return $this->box($copyrighttext, 'copyright');
}
/**
* Display a warning about installing development code if necesary.
* @param int $maturity
* @return string HTML to output.
*/
protected function maturity_info($maturity) {
if ($maturity == MATURITY_STABLE) {
return ''; // No worries.
}
$maturitylevel = get_string('maturity' . $maturity, 'admin');
return $this->box(
get_string('maturitycoreinfo', 'admin', $maturitylevel) . ' ' .
$this->doc_link('admin/versions', get_string('morehelp')),
'generalbox adminwarning maturityinfo');
}
/**
* Display a link to the release notes.
* @return string HTML to output.
*/
protected function release_notes_link() {
$releasenoteslink = get_string('releasenoteslink', 'admin', 'http://docs.moodle.org/dev/Releases');
$releasenoteslink = str_replace('target="_blank"', 'onclick="this.target=\'_blank\'"', $releasenoteslink); // extremely ugly validation hack
return $this->box($releasenoteslink, 'generalbox releasenoteslink');
}
/**
* Display the reload link that appears on several upgrade/install pages.
* @return string HTML to output.
*/
function upgrade_reload($url) {
return html_writer::empty_tag('br') .
html_writer::tag('div',
html_writer::link($url, $this->pix_icon('i/reload', '') .
get_string('reload'), array('title' => get_string('reload'))),
array('class' => 'continuebutton')) . html_writer::empty_tag('br');
}
/**
* Displays all known plugins and information about their installation or upgrade
*
@@ -427,13 +39,11 @@ class core_admin_renderer extends plugin_renderer_base {
* options support:
* (bool)full = false: whether to display up-to-date plugins, too
*
* @param plugin_manager $pluginman provides information about the plugins.
* @param int $version the version of the Moodle code from version.php.
* @param array $plugininfo as returned by {@see plugin_manager::get_plugins()}
* @param array $options rendering options
* @return string HTML code
*/
public function plugins_check_table(plugin_manager $pluginman, $version, array $options = null) {
$plugininfo = $pluginman->get_plugins();
public function plugins_check(array $plugininfo, array $options = null) {
if (empty($plugininfo)) {
return '';
@@ -445,6 +55,8 @@ class core_admin_renderer extends plugin_renderer_base {
);
}
$pluginman = plugin_manager::instance();
$table = new html_table();
$table->id = 'plugins-check';
$table->head = array(
@@ -453,11 +65,10 @@ class core_admin_renderer extends plugin_renderer_base {
get_string('source', 'core_plugin'),
get_string('versiondb', 'core_plugin'),
get_string('versiondisk', 'core_plugin'),
get_string('requires', 'core_plugin'),
get_string('status', 'core_plugin'),
);
$table->colclasses = array(
'displayname', 'rootdir', 'source', 'versiondb', 'versiondisk', 'requires', 'status',
'displayname', 'rootdir', 'source', 'versiondb', 'versiondisk', 'status',
);
$table->data = array();
@@ -515,13 +126,7 @@ class core_admin_renderer extends plugin_renderer_base {
$status = new html_table_cell(get_string('status_' . $statuscode, 'core_plugin'));
$requires = new html_table_cell($this->required_column($plugin, $pluginman, $version));
$statusisboring = in_array($statuscode, array(
plugin_manager::PLUGIN_STATUS_NODB, plugin_manager::PLUGIN_STATUS_UPTODATE));
$dependenciesok = $pluginman->are_dependencies_satisfied(
$plugin->get_other_required_plugins());
if ($isstandard and $statusisboring and $dependenciesok) {
if ($isstandard and in_array($statuscode, array(plugin_manager::PLUGIN_STATUS_NODB, plugin_manager::PLUGIN_STATUS_UPTODATE))) {
if (empty($options['full'])) {
continue;
}
@@ -529,8 +134,7 @@ class core_admin_renderer extends plugin_renderer_base {
$numofhighlighted[$type]++;
}
$row->cells = array($displayname, $rootdir, $source,
$versiondb, $versiondisk, $requires, $status);
$row->cells = array($displayname, $rootdir, $source, $versiondb, $versiondisk, $status);
$plugintyperows[] = $row;
}
@@ -572,75 +176,22 @@ class core_admin_renderer extends plugin_renderer_base {
return $out;
}
/**
* Formats the information that needs to go in the 'Requires' column.
* @param plugin_information $plugin the plugin we are rendering the row for.
* @param plugin_manager $pluginman provides data on all the plugins.
* @param string $version
* @return string HTML code
*/
protected function required_column(plugin_information $plugin, plugin_manager $pluginman, $version) {
$requires = array();
if (!empty($plugin->versionrequires)) {
if ($plugin->versionrequires <= $version) {
$class = 'requires-ok';
} else {
$class = 'requires-failed';
}
$requires[] = html_writer::tag('li',
get_string('moodleversion', 'core_plugin', $plugin->versionrequires),
array('class' => $class));
}
foreach ($plugin->get_other_required_plugins() as $component => $requiredversion) {
$ok = true;
$otherplugin = $pluginman->get_plugin_info($component);
if (is_null($otherplugin)) {
$ok = false;
} else if ($requiredversion != ANY_VERSION and $otherplugin->versiondisk < $requiredversion) {
$ok = false;
}
if ($ok) {
$class = 'requires-ok';
} else {
$class = 'requires-failed';
}
if ($requiredversion != ANY_VERSION) {
$str = 'otherpluginversion';
} else {
$str = 'otherplugin';
}
$requires[] = html_writer::tag('li',
get_string($str, 'core_plugin',
array('component' => $component, 'version' => $requiredversion)),
array('class' => $class));
}
if (!$requires) {
return '';
}
return html_writer::tag('ul', implode("\n", $requires));
}
/**
* Displays all known plugins and links to manage them
*
* This default implementation renders all plugins into one big table.
*
* @param plugin_manager $pluginman provides information about the plugins.
* @param array $plugininfo as returned by {@see plugin_manager::get_plugins()}
* @return string HTML code
*/
public function plugins_control_panel(plugin_manager $pluginman) {
$plugininfo = $pluginman->get_plugins();
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(
@@ -726,12 +277,8 @@ class core_admin_renderer extends plugin_renderer_base {
}
$uninstallurl = $plugin->get_uninstall_url();
$requriedby = $pluginman->other_plugins_that_require($plugin->component);
if (is_null($uninstallurl)) {
$uninstall = new html_table_cell('');
} else if ($requriedby) {
$uninstall = new html_table_cell(get_string('requiredby', 'core_plugin', implode(', ', $requriedby)));
$uninstall->attributes['class'] = 'requiredby';
} else {
$uninstall = html_writer::link($uninstallurl, get_string('uninstall', 'core_plugin'));
$uninstall = new html_table_cell($uninstall);
@@ -746,183 +293,4 @@ class core_admin_renderer extends plugin_renderer_base {
return html_writer::table($table);
}
/**
* This function will render one beautiful table with all the environmental
* configuration and how it suits Moodle needs.
*
* @param boolean $result final result of the check (true/false)
* @param array $environment_results array of results gathered
* @return string HTML to output.
*/
public function environment_check_table($result, $environment_results) {
global $CFG;
// Table headers
$servertable = new html_table();//table for server checks
$servertable->head = array(
get_string('name'),
get_string('info'),
get_string('report'),
get_string('status'),
);
$servertable->align = array('center', 'center', 'left', 'center');
$servertable->wrap = array('nowrap', '', '', 'nowrap');
$servertable->size = array('10', 10, '100%', '10');
$servertable->attributes['class'] = 'environmenttable generaltable';
$serverdata = array('ok'=>array(), 'warn'=>array(), 'error'=>array());
$othertable = new html_table();//table for custom checks
$othertable->head = array(
get_string('info'),
get_string('report'),
get_string('status'),
);
$othertable->align = array('center', 'left', 'center');
$othertable->wrap = array('', '', 'nowrap');
$othertable->size = array(10, '100%', '10');
$othertable->attributes['class'] = 'environmenttable generaltable';
$otherdata = array('ok'=>array(), 'warn'=>array(), 'error'=>array());
// Iterate over each environment_result
$continue = true;
foreach ($environment_results as $environment_result) {
$errorline = false;
$warningline = false;
$stringtouse = '';
if ($continue) {
$type = $environment_result->getPart();
$info = $environment_result->getInfo();
$status = $environment_result->getStatus();
$error_code = $environment_result->getErrorCode();
// Process Report field
$rec = new stdClass();
// Something has gone wrong at parsing time
if ($error_code) {
$stringtouse = 'environmentxmlerror';
$rec->error_code = $error_code;
$status = get_string('error');
$errorline = true;
$continue = false;
}
if ($continue) {
if ($rec->needed = $environment_result->getNeededVersion()) {
// We are comparing versions
$rec->current = $environment_result->getCurrentVersion();
if ($environment_result->getLevel() == 'required') {
$stringtouse = 'environmentrequireversion';
} else {
$stringtouse = 'environmentrecommendversion';
}
} else if ($environment_result->getPart() == 'custom_check') {
// We are checking installed & enabled things
if ($environment_result->getLevel() == 'required') {
$stringtouse = 'environmentrequirecustomcheck';
} else {
$stringtouse = 'environmentrecommendcustomcheck';
}
} else if ($environment_result->getPart() == 'php_setting') {
if ($status) {
$stringtouse = 'environmentsettingok';
} else if ($environment_result->getLevel() == 'required') {
$stringtouse = 'environmentmustfixsetting';
} else {
$stringtouse = 'environmentshouldfixsetting';
}
} else {
if ($environment_result->getLevel() == 'required') {
$stringtouse = 'environmentrequireinstall';
} else {
$stringtouse = 'environmentrecommendinstall';
}
}
// Calculate the status value
if ($environment_result->getBypassStr() != '') { //Handle bypassed result (warning)
$status = get_string('bypassed');
$warningline = true;
} else if ($environment_result->getRestrictStr() != '') { //Handle restricted result (error)
$status = get_string('restricted');
$errorline = true;
} else {
if ($status) { //Handle ok result (ok)
$status = get_string('ok');
} else {
if ($environment_result->getLevel() == 'optional') {//Handle check result (warning)
$status = get_string('check');
$warningline = true;
} else { //Handle error result (error)
$status = get_string('check');
$errorline = true;
}
}
}
}
// Build the text
$linkparts = array();
$linkparts[] = 'admin/environment';
$linkparts[] = $type;
if (!empty($info)){
$linkparts[] = $info;
}
if (empty($CFG->docroot)) {
$report = get_string($stringtouse, 'admin', $rec);
} else {
$report = $this->doc_link(join($linkparts, '/'), get_string($stringtouse, 'admin', $rec));
}
// Format error or warning line
if ($errorline || $warningline) {
$messagetype = $errorline? 'error':'warn';
} else {
$messagetype = 'ok';
}
$status = '<span class="'.$messagetype.'">'.$status.'</span>';
// Here we'll store all the feedback found
$feedbacktext = '';
// Append the feedback if there is some
$feedbacktext .= $environment_result->strToReport($environment_result->getFeedbackStr(), $messagetype);
//Append the bypass if there is some
$feedbacktext .= $environment_result->strToReport($environment_result->getBypassStr(), 'warn');
//Append the restrict if there is some
$feedbacktext .= $environment_result->strToReport($environment_result->getRestrictStr(), 'error');
$report .= $feedbacktext;
// Add the row to the table
if ($environment_result->getPart() == 'custom_check'){
$otherdata[$messagetype][] = array ($info, $report, $status);
} else {
$serverdata[$messagetype][] = array ($type, $info, $report, $status);
}
}
}
//put errors first in
$servertable->data = array_merge($serverdata['error'], $serverdata['warn'], $serverdata['ok']);
$othertable->data = array_merge($otherdata['error'], $otherdata['warn'], $otherdata['ok']);
// Print table
$output = '';
$output .= $this->heading(get_string('serverchecks', 'admin'));
$output .= html_writer::table($servertable);
if (count($othertable->data)){
$output .= $this->heading(get_string('customcheck', 'admin'));
$output .= html_writer::table($othertable);
}
// Finally, if any error has happened, print the summary box
if (!$result) {
$output .= $this->box(get_string('environmenterrortodo', 'admin'), 'environmentbox errorbox');
}
return $output;
}
}
+59
View File
@@ -0,0 +1,59 @@
<?php
/// Search and replace strings throughout all texts in the whole database
define('NO_OUTPUT_BUFFERING', true);
require_once('../config.php');
require_once($CFG->dirroot.'/course/lib.php');
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('replace');
$search = optional_param('search', '', PARAM_RAW);
$replace = optional_param('replace', '', PARAM_RAW);
$sure = optional_param('sure', 0, PARAM_BOOL);
###################################################################
echo $OUTPUT->header();
echo $OUTPUT->heading('Search and replace text throughout the whole database');
if ($DB->get_dbfamily() !== 'mysql' and $DB->get_dbfamily() !== 'postgres') {
//TODO: add $DB->text_replace() to DML drivers
echo $OUTPUT->notification('Sorry, this feature is implemented only for MySQL and PostgreSQL databases.');
echo $OUTPUT->footer();
die;
}
if (!data_submitted() or !$search or !$replace or !confirm_sesskey() or !$sure) { /// Print a form
echo $OUTPUT->notification('This script is not supported, always make complete backup before proceeding!<br />This operation can not be reverted!');
echo $OUTPUT->box_start();
echo '<div class="mdl-align">';
echo '<form action="replace.php" method="post"><div>';
echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
echo '<div><label for="search">Search whole database for: </label><input id="search" type="text" name="search" size="40" /> (usually previous server URL)</div>';
echo '<div><label for="replace">Replace with this string: </label><input type="text" id="replace" name="replace" size="40" /> (usually new server URL)</div>';
echo '<div><label for="sure">I understand the risks of this operation: </label><input type="checkbox" id="sure" name="sure" value="1" /></div>';
echo '<div class="buttons"><input type="submit" class="singlebutton" value="Yes, do it now" /></div>';
echo '</div></form>';
echo '</div>';
echo $OUTPUT->box_end();
echo $OUTPUT->footer();
die;
}
echo $OUTPUT->box_start();
db_replace($search, $replace);
echo $OUTPUT->box_end();
/// Rebuild course cache which might be incorrect now
echo $OUTPUT->notification('Rebuilding course cache...', 'notifysuccess');
rebuild_course_cache();
echo $OUTPUT->notification('...finished', 'notifysuccess');
echo $OUTPUT->continue_button('index.php');
echo $OUTPUT->footer();
+128
View File
@@ -0,0 +1,128 @@
<?php
// index.php - scheduled backup logs
require_once('../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->dirroot.'/backup/lib.php');
$courseid = optional_param('courseid', 0, PARAM_INT);
admin_externalpage_setup('reportbackups');
echo $OUTPUT->header();
/// Automated backups aren't active by the site admin
$backup_config = backup_get_config();
if (empty($backup_config->backup_auto_active)) {
echo $OUTPUT->notification(get_string('automatedbackupsinactive', 'backup'));
}
/// Get needed strings
$backuploglaststatus = get_string("backuploglaststatus");
$backuplogdetailed = get_string("backuplogdetailed");
$stradmin = get_string("administration");
$strconfiguration = get_string("configuration");
$strbackup = get_string("backup");
$strbackupdetails = get_string("backupdetails");
$strlogs = get_string("logs");
$strftimedatetime = get_string("strftimerecent");
$strftimetime = get_string("strftimetime").":%S";
$strerror = get_string("error");
$strok = get_string("ok");
$strunfinished = get_string("unfinished");
$strskipped = get_string("skipped");
$strcourse = get_string("course");
$strtimetaken = get_string("timetaken","quiz");
$strstatus = get_string("status");
$strnext = get_string("backupnext");
/// Decide when to show last execution logs or detailed logs
/// Lastlog view
if (!$courseid) {
echo $OUTPUT->heading($backuploglaststatus);
echo $OUTPUT->box_start();
/// Now, get every record from backup_courses
$courses = $DB->get_records("backup_courses");
if (!$courses) {
echo $OUTPUT->notification(get_string('nologsfound'));
} else {
echo "<table border=\"0\" align=\"center\" cellpadding=\"3\" cellspacing=\"3\">";
//Print table header
echo "<tr>";
echo "<td nowrap=\"nowrap\" align=\"center\"><font size=\"3\">$strcourse</font></td>";
echo "<td nowrap=\"nowrap\" align=\"center\" colspan=\"3\"><font size=\"3\">$strtimetaken</font></td>";
echo "<td nowrap=\"nowrap\" align=\"center\"><font size=\"3\">$strstatus</font></td>";
echo "<td nowrap=\"nowrap\" align=\"center\"><font size=\"3\">$strnext</font></td></tr>";
foreach ($courses as $course) {
/// Get the course shortname
$coursename = $DB->get_field ("course", "fullname", array("id"=>$course->courseid));
if ($coursename) {
echo "<tr>";
echo "<td nowrap=\"nowrap\"><font size=\"2\"><a href=\"index.php?courseid=$course->courseid\">".$coursename."</a></font></td>";
echo "<td nowrap=\"nowrap\"><font size=\"2\">".userdate($course->laststarttime,$strftimedatetime)."</font></td>";
echo "<td nowrap=\"nowrap\"><font size=\"2\"> - </font></td>";
echo "<td nowrap=\"nowrap\"><font size=\"2\">".userdate($course->lastendtime,$strftimedatetime)."</font></td>";
if ($course->laststatus == 1) {
echo "<td nowrap=\"nowrap\" align=\"center\"><font size=\"2\" color=\"green\">".$strok."</font></td>";
} else if ($course->laststatus == 2) {
echo "<td nowrap=\"nowrap\" align=\"center\"><font size=\"2\" color=\"red\">".$strunfinished."</font></td>";
} else if ($course->laststatus == 3) {
echo "<td nowrap=\"nowrap\" align=\"center\"><font size=\"2\" color=\"green\">".$strskipped."</font></td>";
} else {
echo "<td nowrap=\"nowrap\" align=\"center\"><font size=\"2\" color=\"red\">".$strerror."</font></td>";
}
echo "<td nowrap=\"nowrap\"><font size=\"2\">".userdate($course->nextstarttime,$strftimedatetime)."</font></td>";
echo "</tr>";
}
}
echo "</table>";
}
echo $OUTPUT->box_end();
/// Detailed View !!
} else {
echo $OUTPUT->heading($backuplogdetailed);
$coursename = $DB->get_field("course", "fullname", array("id"=>"$courseid"));
echo $OUTPUT->heading("$strcourse: $coursename");
echo $OUTPUT->box_start();
/// First, me get all the distinct backups for that course in backup_log
$executions = $DB->get_records_sql("SELECT DISTINCT laststarttime
FROM {backup_log}
WHERE courseid = ? AND backuptype = ?
ORDER BY laststarttime DESC", array($courseid,'scheduledbackup'));
/// Iterate over backup executions
if (!$executions) {
echo $OUTPUT->notification(get_string('nologsfound'));
} else {
echo "<table border=\"0\" align=\"center\" cellpadding=\"3\" cellspacing=\"3\">";
foreach($executions as $execution) {
echo "<tr>";
echo "<td nowrap=\"nowrap\" align=\"center\" colspan=\"3\">";
echo $OUTPUT->box(userdate($execution->laststarttime));
echo "</td>";
echo "</tr>";
$logs = $DB->get_records_sql("SELECT *
FROM {backup_log}
WHERE courseid = ? AND laststarttime = ? AND backuptype = ?
ORDER BY id", array($courseid, $execution->laststarttime,'scheduledbackup'));
if ($logs) {
foreach ($logs as $log) {
echo "<tr>";
echo "<td nowrap=\"nowrap\"><font size=\"2\">".userdate($log->time,$strftimetime)."</font></td>";
$log->info = str_replace("- ERROR!!","- <font color=\"red\">ERROR!!</font>",$log->info);
$log->info = str_replace("- OK","- <font color=\"green\">OK</font>",$log->info);
echo "<td nowrap=\"nowrap\"><font size=\"2\">".str_replace(" ","&nbsp;&nbsp;&nbsp;&nbsp;",$log->info)."</font></td>";
echo "</tr>";
}
}
}
echo "</table>";
}
echo $OUTPUT->box_end();
}
echo $OUTPUT->footer();
+5
View File
@@ -0,0 +1,5 @@
<?php
defined('MOODLE_INTERNAL') || die;
$ADMIN->add('reports', new admin_externalpage('reportbackups', get_string('backups', 'admin'), "$CFG->wwwroot/$CFG->admin/report/backups/index.php",'moodle/backup:backupcourse'));
+214
View File
@@ -0,0 +1,214 @@
<?php
/**
* For a given capability, show what permission it has for every role, and
* everywhere that it is overridden.
*
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package roles
*/
/** */
require_once(dirname(__FILE__).'/../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
// Check permissions.
require_login();
$systemcontext = get_context_instance(CONTEXT_SYSTEM);
require_capability('moodle/role:manage', $systemcontext);
// Get URL parameters.
$capability = optional_param('capability', '', PARAM_CAPABILITY);
$roleids = optional_param('roles', array('0'), PARAM_INTEGER);
// Clean the passed in list of role ids. If 'All' selected as an option, or
// if none were selected, do all roles.
$allroles = get_all_roles();
$cleanedroleids = array();
foreach ($roleids as $roleid) {
if ($roleid == 0) {
$cleanedroleids = array_keys($allroles);
break;
}
if (array_key_exists($roleid, $allroles)) {
$cleanedroleids[] = $roleid;
}
}
if (empty($cleanedroleids)) {
$cleanedroleids = array_keys($allroles);
}
// Include the required JavaScript.
$PAGE->requires->js_init_call('M.report_capability.init', array(get_string('search')));
// Log.
add_to_log(SITEID, "admin", "report capability", "report/capability/index.php?capability=$capability", $capability);
// Print the header.
admin_externalpage_setup('reportcapability');
echo $OUTPUT->header();
// Prepare the list of capabilities to choose from
$allcapabilities = fetch_context_capabilities($systemcontext);
$capabilitychoices = array();
foreach ($allcapabilities as $cap) {
$capabilitychoices[$cap->name] = $cap->name . ': ' . get_capability_string($cap->name);
}
// Prepare the list of roles to choose from
$rolechoices = array('0' => get_string('all'));
foreach ($allroles as $role) {
$rolechoices[$role->id] = $role->name;
}
if (count($cleanedroleids) == count($allroles)) {
// Select 'All', rather than each role individually.
$selectedroleids = array('0');
} else {
$selectedroleids = $cleanedroleids;
}
// Print the settings form.
echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
echo '<form method="get" action="." id="settingsform"><div>';
echo $OUTPUT->heading(get_string('reportsettings', 'report_capability'));
echo '<p id="intro">', get_string('intro', 'report_capability') , '</p>';
echo '<p><label for="menucapability"> ' . get_string('capabilitylabel', 'report_capability') . '</label></p>';
echo html_writer::select($capabilitychoices, 'capability', $capability, array(''=>'choose'), array('size'=>10));
echo '<p><label for="menuroles"> ' . get_string('roleslabel', 'report_capability') . '</label></p>';
echo html_writer::select($rolechoices, 'roles[]', $selectedroleids, false, array('size'=>10, 'multiple'=>'multiple'));
echo '<p><input type="submit" id="settingssubmit" value="' . get_string('getreport', 'report_capability') . '" /></p>';
echo '</div></form>';
echo $OUTPUT->box_end();
// If we have a capability, generate the report.
if ($capability) {
// Work out the bits needed for the SQL WHERE clauses.
$params = array($capability);
$sqlroletest = '';
if (count($cleanedroleids) != count($allroles)) {
list($sqlroletest, $roleparams) = $DB->get_in_or_equal($cleanedroleids);
$params = array_merge($params, $roleparams);
$sqlroletest = 'AND roleid ' . $sqlroletest;
}
// Get all the role_capabilities rows for this capability - that is, all
// role definitions, and all role overrides.
$rolecaps = $DB->get_records_sql("
SELECT id, roleid, contextid, permission
FROM {role_capabilities}
WHERE capability = ? $sqlroletest", $params);
// In order to display a nice tree of contexts, we need to get all the
// ancestors of all the contexts in the query we just did.
$relevantpaths = $DB->get_records_sql_menu("
SELECT DISTINCT con.path, 1
FROM {context} con JOIN {role_capabilities} rc ON rc.contextid = con.id
WHERE capability = ? $sqlroletest", $params);
$requiredcontexts = array($systemcontext->id);
foreach ($relevantpaths as $path => $notused) {
$requiredcontexts = array_merge($requiredcontexts, explode('/', trim($path, '/')));
}
$requiredcontexts = array_unique($requiredcontexts);
// Now load those contexts.
list($sqlcontexttest, $contextparams) = $DB->get_in_or_equal($requiredcontexts);
$contexts = get_sorted_contexts('ctx.id ' . $sqlcontexttest, $contextparams);
// Prepare some empty arrays to hold the data we are about to compute.
foreach ($contexts as $conid => $con) {
$contexts[$conid]->children = array();
$contexts[$conid]->rolecapabilities = array();
}
// Put the contexts into a tree structure.
foreach ($contexts as $conid => $con) {
$parentcontextid = get_parent_contextid($con);
if ($parentcontextid) {
$contexts[$parentcontextid]->children[] = $conid;
}
}
// Put the role capabilities into the context tree.
foreach ($rolecaps as $rolecap) {
$contexts[$rolecap->contextid]->rolecapabilities[$rolecap->roleid] = $rolecap->permission;
}
// Fill in any missing rolecaps for the system context.
foreach ($cleanedroleids as $roleid) {
if (!isset($contexts[$systemcontext->id]->rolecapabilities[$roleid])) {
$contexts[$systemcontext->id]->rolecapabilities[$roleid] = CAP_INHERIT;
}
}
// Print the report heading.
echo $OUTPUT->heading(get_string('reportforcapability', 'report_capability', get_capability_string($capability)), 2, 'main', 'report');
if (count($cleanedroleids) != count($allroles)) {
$rolenames = array();
foreach ($cleanedroleids as $roleid) {
$rolenames[] = $allroles[$roleid]->name;
}
echo '<p>', get_string('forroles', 'report_capability', implode(', ', $rolenames)), '</p>';
}
// Now, recursively print the contexts, and the role information.
print_report_tree($systemcontext->id, $contexts, $allroles);
}
// Footer.
echo $OUTPUT->footer();
function print_report_tree($contextid, $contexts, $allroles) {
global $CFG;
// Array for holding lang strings.
static $strpermissions = null;
if (is_null($strpermissions)) {
$strpermissions = array(
CAP_INHERIT => get_string('notset','role'),
CAP_ALLOW => get_string('allow','role'),
CAP_PREVENT => get_string('prevent','role'),
CAP_PROHIBIT => get_string('prohibit','role')
);
}
// Start the list item, and print the context name as a link to the place to
// make changes.
if ($contextid == get_system_context()->id) {
$url = "$CFG->wwwroot/$CFG->admin/roles/manage.php";
$title = get_string('changeroles', 'report_capability');
} else {
$url = "$CFG->wwwroot/$CFG->admin/roles/override.php?contextid=$contextid";
$title = get_string('changeoverrides', 'report_capability');
}
echo '<h3><a href="' . $url . '" title="' . $title . '">', print_context_name($contexts[$contextid]), '</a></h3>';
// If there are any role overrides here, print them.
if (!empty($contexts[$contextid]->rolecapabilities)) {
$rowcounter = 0;
echo '<table class="generaltable rolecaps"><tbody>';
foreach ($allroles as $role) {
if (isset($contexts[$contextid]->rolecapabilities[$role->id])) {
$permission = $contexts[$contextid]->rolecapabilities[$role->id];
echo '<tr class="r' . ($rowcounter % 2) . '"><th class="cell">', $role->name,
'</th><td class="cell">' . $strpermissions[$permission] . '</td></tr>';
$rowcounter++;
}
}
echo '</tbody></table>';
}
// After we have done the site context, change the string for CAP_INHERIT
// from 'notset' to 'inherit'.
$strpermissions[CAP_INHERIT] = get_string('inherit','role');
// If there are any child contexts, print them recursively.
if (!empty($contexts[$contextid]->children)) {
echo '<ul>';
foreach ($contexts[$contextid]->children as $childcontextid) {
echo '<li>';
print_report_tree($childcontextid, $contexts, $allroles);
echo '</li>';
}
echo '</ul>';
}
}
@@ -0,0 +1,36 @@
<?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/>.
/**
* Strings for component 'report_capability', language 'en', branch 'MOODLE_20_STABLE'
*
* @package report_capability
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['capabilitylabel'] = 'Capability:';
$string['capabilityreport'] = 'Capability report';
$string['forroles'] = 'For roles {$a}';
$string['getreport'] = 'Get the report';
$string['changeoverrides'] = 'Change overrides in this context';
$string['changeroles'] = 'Change role definitions';
$string['intro'] = 'This report shows, for a particular capability, what permission that capability has in the definition of every role (or a selection of roles), and everywhere in the site where that capability is overridden.';
$string['pluginname'] = 'Capability report';
$string['reportforcapability'] = 'Report for capability \'{$a}\'';
$string['reportsettings'] = 'Report settings';
$string['roleslabel'] = 'Roles:';
+75
View File
@@ -0,0 +1,75 @@
M.report_capability = {
select: null,
input: null,
button: null,
init: function(Y, strsearch) {
var context = M.report_capability;
// Find the form controls.
context.select = document.getElementById('menucapability');
context.button = document.getElementById('settingssubmit');
// Create a div to hold the search UI.
var div = document.createElement('div');
div.id = 'capabilitysearchui';
// Find the capability search input.
var input = document.createElement('input');
input.type = 'text';
input.id = 'capabilitysearch';
context.input = input;
// Create a label for the search input.
var label = document.createElement('label');
label.htmlFor = input.id;
label.appendChild(document.createTextNode(strsearch + ' '));
// Tie it all together
div.appendChild(label);
div.appendChild(input);
context.select.parentNode.insertBefore(div, context.select);
Y.on('keyup', context.typed, input);
Y.on('change', context.validate, context.select);
context.select.options[0].style.display = 'none';
context.validate();
},
typed: function() {
var context = M.report_capability;
var filtertext = context.input.value;
var options = context.select.options;
var onlycapability = -1;
for (var i = 1; i < options.length; i++) {
if (options[i].text.indexOf(filtertext) >= 0) {
options[i].disabled = false;
options[i].style.display = 'block';
if (onlycapability == -1) {
onlycapability = i;
} else {
onlycapability = -2;
}
} else {
options[i].disabled = true;
options[i].selected = false;
options[i].style.display = 'none';
}
}
if (onlycapability >= 0) {
options[onlycapability].selected = true;
}
if (onlycapability == -1) {
context.input.className = "error";
} else {
context.input.className = "";
}
context.validate();
},
validate: function() {
var context = M.report_capability;
context.button.disabled = (context.select.value == '');
}
}
+5
View File
@@ -0,0 +1,5 @@
<?php
defined('MOODLE_INTERNAL') || die;
$ADMIN->add('roles', new admin_externalpage('reportcapability', get_string('pluginname', 'report_capability'), "$CFG->wwwroot/$CFG->admin/report/capability/index.php",'moodle/role:manage'));
+110
View File
@@ -0,0 +1,110 @@
<?php
require_once(dirname(__FILE__).'/../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
// page parameters
$page = optional_param('page', 0, PARAM_INT);
$perpage = optional_param('perpage', 30, PARAM_INT); // how many per page
$sort = optional_param('sort', 'timemodified', PARAM_ALPHA);
$dir = optional_param('dir', 'DESC', PARAM_ALPHA);
admin_externalpage_setup('reportconfiglog');
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('configlog', 'report_configlog'));
$changescount = $DB->count_records('config_log');
$columns = array('firstname' => get_string('firstname'),
'lastname' => get_string('lastname'),
'timemodified' => get_string('timemodified', 'report_configlog'),
'plugin' => get_string('plugin', 'report_configlog'),
'name' => get_string('setting', 'report_configlog'),
'value' => get_string('value', 'report_configlog'),
'oldvalue' => get_string('oldvalue', 'report_configlog'),
);
$hcolumns = array();
if (!isset($columns[$sort])) {
$sort = 'lastname';
}
foreach ($columns as $column=>$strcolumn) {
if ($sort != $column) {
$columnicon = '';
if ($column == 'lastaccess') {
$columndir = 'DESC';
} else {
$columndir = 'ASC';
}
} else {
$columndir = $dir == 'ASC' ? 'DESC':'ASC';
if ($column == 'lastaccess') {
$columnicon = $dir == 'ASC' ? 'up':'down';
} else {
$columnicon = $dir == 'ASC' ? 'down':'up';
}
$columnicon = " <img src=\"" . $OUTPUT->pix_url('t/' . $columnicon) . "\" alt=\"\" />";
}
$hcolumns[$column] = "<a href=\"index.php?sort=$column&amp;dir=$columndir&amp;page=$page&amp;perpage=$perpage\">".$strcolumn."</a>$columnicon";
}
$baseurl = new moodle_url('index.php', array('sort' => $sort, 'dir' => $dir, 'perpage' => $perpage));
echo $OUTPUT->paging_bar($changescount, $page, $perpage, $baseurl);
$override = new stdClass();
$override->firstname = 'firstname';
$override->lastname = 'lastname';
$fullnamelanguage = get_string('fullnamedisplay', '', $override);
if (($CFG->fullnamedisplay == 'firstname lastname') or
($CFG->fullnamedisplay == 'firstname') or
($CFG->fullnamedisplay == 'language' and $fullnamelanguage == 'firstname lastname' )) {
$fullnamedisplay = $hcolumns['firstname'].' / '.$hcolumns['lastname'];
} else { // ($CFG->fullnamedisplay == 'language' and $fullnamelanguage == 'lastname firstname')
$fullnamedisplay = $hcolumns['lastname'].' / '.$hcolumns['firstname'];
}
$table = new html_table();
$table->head = array($hcolumns['timemodified'], $fullnamedisplay, $hcolumns['plugin'], $hcolumns['name'], $hcolumns['value'], $hcolumns['oldvalue']);
$table->align = array('left', 'left', 'left', 'left', 'left', 'left');
$table->size = array('30%', '10%', '10%', '10%', '20%', '20%');
$table->width = '95%';
$table->data = array();
if ($sort == 'firstname' or $sort == 'lastname') {
$orderby = "u.$sort $dir";
} else {
$orderby = "cl.$sort $dir";
}
$ufields = user_picture::fields('u');
$sql = "SELECT $ufields,
cl.timemodified, cl.plugin, cl.name, cl.value, cl.oldvalue
FROM {config_log} cl
JOIN {user} u ON u.id = cl.userid
ORDER BY $orderby";
$rs = $DB->get_recordset_sql($sql, array(), $page*$perpage, $perpage);
foreach ($rs as $log) {
$row = array();
$row[] = userdate($log->timemodified);
$row[] = fullname($log);
if (is_null($log->plugin)) {
$row[] = 'core';
} else {
$row[] = $log->plugin;
}
$row[] = $log->name;
$row[] = s($log->value);
$row[] = s($log->oldvalue);
$table->data[] = $row;
}
$rs->close();
echo html_writer::table($table);
echo $OUTPUT->footer();
@@ -1,4 +1,5 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@@ -17,16 +18,14 @@
/**
* Strings for component 'report_configlog', language 'en', branch 'MOODLE_20_STABLE'
*
* @package report
* @subplugin configlog
* @copyright 2009 petr Skoda
* @package report_configlog
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['configlog'] = 'Config changes';
$string['oldvalue'] = 'Original value';
$string['plugin'] = 'Plugin';
$string['pluginname'] = 'Config changes';
$string['setting'] = 'Setting';
$string['timemodified'] = 'Date';
$string['value'] = 'New value';
+5
View File
@@ -0,0 +1,5 @@
<?php
defined('MOODLE_INTERNAL') || die;
$ADMIN->add('reports', new admin_externalpage('reportconfiglog', get_string('configlog', 'report_configlog'), "$CFG->wwwroot/$CFG->admin/report/configlog/index.php"));
+40
View File
@@ -0,0 +1,40 @@
<?php
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
// //
// This program 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 2 of the License, or //
// (at your option) any later version. //
// //
// This program 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: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
$capabilities = array(
'report/courseoverview:view' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:viewreports',
)
);
+122
View File
@@ -0,0 +1,122 @@
<?php
require_once('../../../config.php');
require_once($CFG->dirroot.'/lib/statslib.php');
require_once($CFG->libdir.'/adminlib.php');
$report = optional_param('report', STATS_REPORT_ACTIVE_COURSES, PARAM_INT);
$time = optional_param('time', 0, PARAM_INT);
$numcourses = optional_param('numcourses', 20, PARAM_INT);
if (empty($CFG->enablestats)) {
if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) {
redirect("$CFG->wwwroot/$CFG->admin/settings.php?section=stats", get_string('mustenablestats', 'admin'), 3);
} else {
print_error('statsdisable');
}
}
admin_externalpage_setup('reportcourseoverview');
echo $OUTPUT->header();
$course = get_site();
stats_check_uptodate($course->id);
$strreports = get_string('reports');
$strcourseoverview = get_string('courseoverview');
$reportoptions = stats_get_report_options($course->id,STATS_MODE_RANKED);
$earliestday = $DB->get_field_sql('SELECT MIN(timeend) FROM {stats_daily}');
$earliestweek = $DB->get_field_sql('SELECT MIN(timeend) FROM {stats_weekly}');
$earliestmonth = $DB->get_field_sql('SELECT MIN(timeend) FROM {stats_monthly}');
if (empty($earliestday)) $earliestday = time();
if (empty($earliestweek)) $earliestweek = time();
if (empty($earliestmonth)) $earliestmonth = time();
$now = stats_get_base_daily();
$lastweekend = stats_get_base_weekly();
$lastmonthend = stats_get_base_monthly();
$timeoptions = stats_get_time_options($now,$lastweekend,$lastmonthend,$earliestday,$earliestweek,$earliestmonth);
if (empty($timeoptions)) {
print_error('nostatstodisplay', 'error', $CFG->wwwroot.'/course/view.php?id='.$course->id);
}
echo '<form action="index.php" method="post">'."\n";
echo '<div>';
$table = new html_table();
$table->width = '*';
$table->align = array('left','left','left','left','left','left');
$reporttypemenu = html_writer::select($reportoptions,'report',$report, false);
$timeoptionsmenu = html_writer::select($timeoptions,'time',$time, false);
$table->data[] = array(get_string('statsreporttype'),$reporttypemenu,
get_string('statstimeperiod'),$timeoptionsmenu,
'<input type="text" name="numcourses" size="3" maxlength="2" value="'.$numcourses.'" />',
'<input type="submit" value="'.get_string('view').'" />') ;
echo html_writer::table($table);
echo '</div>';
echo '</form>';
echo $OUTPUT->heading($reportoptions[$report]);
if (!empty($report) && !empty($time)) {
$param = stats_get_parameters($time,$report,SITEID,STATS_MODE_RANKED);
if (!empty($param->sql)) {
$sql = $param->sql;
} else {
$sql = "SELECT courseid,".$param->fields."
FROM {".'stats_'.$param->table."}
WHERE timeend >= $param->timeafter AND stattype = 'activity' AND roleid = 0
GROUP BY courseid
$param->extras
ORDER BY $param->orderby";
}
$courses = $DB->get_records_sql($sql, $param->params, 0, $numcourses);
if (empty($courses)) {
echo $OUTPUT->notification(get_string('statsnodata'));
echo '</td></tr></table>';
} else {
if (empty($CFG->gdversion)) {
echo '<div class="graph">(' . get_string("gdneed") .')</div>';
} else {
echo '<div class="graph"><img alt="'.get_string('courseoverviewgraph').'" src="'.$CFG->wwwroot.'/'.$CFG->admin.'/report/courseoverview/reportsgraph.php?time='.$time.'&report='.$report.'&numcourses='.$numcourses.'" /></div>';
}
$table = new html_table();
$table->align = array('left','center','center','center');
$table->head = array(get_string('course'),$param->line1);
if (!empty($param->line2)) {
$table->head[] = $param->line2;
}
if (!empty($param->line3)) {
$table->head[] = $param->line3;
}
foreach ($courses as $c) {
$a = array();
$a[] = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$c->courseid.'">'.$DB->get_field('course', 'shortname', array('id'=>$c->courseid)).'</a>';
$a[] = $c->line1;
if (isset($c->line2)) {
$a[] = $c->line2;
}
if (isset($c->line3)) {
$a[] = round($c->line3,2);
}
$table->data[] = $a;
}
echo html_writer::table($table);
}
}
echo $OUTPUT->footer();
@@ -0,0 +1,27 @@
<?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/>.
/**
* Strings for component 'report_courseoverview', language 'en', branch 'MOODLE_20_STABLE'
*
* @package report_courseoverview
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['courseoverview:view'] = 'View course overview report';
$string['pluginname'] = 'Course overview';
@@ -0,0 +1,57 @@
<?php
require_once('../../../config.php');
require_once($CFG->dirroot.'/lib/statslib.php');
require_once($CFG->dirroot.'/lib/graphlib.php');
$report = required_param('report', PARAM_INT);
$time = required_param('time', PARAM_INT);
$numcourses = required_param('numcourses', PARAM_INT);
require_login();
require_capability('report/courseoverview:view', get_context_instance(CONTEXT_SYSTEM));
stats_check_uptodate();
$param = stats_get_parameters($time,$report,SITEID,STATS_MODE_RANKED);
if (!empty($param->sql)) {
$sql = $param->sql;
} else {
$sql = "SELECT courseid, $param->fields
FROM {".'stats_'.$param->table."}
WHERE timeend >= $param->timeafter AND stattype = 'activity' AND roleid = 0
GROUP BY courseid
$param->extras
ORDER BY $param->orderby";
}
$courses = $DB->get_records_sql($sql, $param->params, 0, $numcourses);
if (empty($courses)) {
$PAGE->set_url('/admin/report/courseoverview/index.php');
print_error('statsnodata', 'error', $PAGE->url->out());
}
$graph = new graph(750,400);
$graph->parameter['legend'] = 'outside-right';
$graph->parameter['legend_size'] = 10;
$graph->parameter['x_axis_angle'] = 90;
$graph->parameter['title'] = false; // moodle will do a nicer job.
$graph->y_tick_labels = null;
$graph->offset_relation = null;
if ($report != STATS_REPORT_ACTIVE_COURSES) {
$graph->parameter['y_decimal_left'] = 2;
}
foreach ($courses as $c) {
$graph->x_data[] = $DB->get_field('course', 'shortname', array('id'=>$c->courseid));
$graph->y_data['bar1'][] = $c->{$param->graphline};
}
$graph->y_order = array('bar1');
$graph->y_format['bar1'] = array('colour' => 'blue','bar' => 'fill','legend' => $param->{$param->graphline});
$graph->draw_stack();
+5
View File
@@ -0,0 +1,5 @@
<?php
defined('MOODLE_INTERNAL') || die;
$ADMIN->add('reports', new admin_externalpage('reportcourseoverview', get_string('pluginname', 'report_courseoverview'), "$CFG->wwwroot/$CFG->admin/report/courseoverview/index.php",'report/courseoverview:view'));
+27
View File
@@ -0,0 +1,27 @@
<?PHP
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
// //
// This program 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 2 of the License, or //
// (at your option) any later version. //
// //
// This program 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: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
$plugin->version = 2010090501;
$plugin->requires = 2010090501;
+51
View File
@@ -0,0 +1,51 @@
<?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/>.
/**
* Defines the capabilities used by the Language customization admin report
*
* @package report
* @subpackage customlang
* @copyright 2010 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
/* allows the user to view the current language customization */
'report/customlang:view' => array(
'riskbitmask' => RISK_CONFIG,
'captype' => 'read',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW
),
),
/* allows the user to edit the current language customization */
'report/customlang:edit' => array(
'riskbitmask' => RISK_CONFIG | RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW
),
),
);
+40
View File
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="admin/report/customlang/db" VERSION="20110419" COMMENT="XMLDB file for Moodle admin/report/customlang"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="report_customlang" COMMENT="Contains the working checkout of all strings and their customization" NEXT="report_customlang_components">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="lang"/>
<FIELD NAME="lang" TYPE="char" LENGTH="20" NOTNULL="true" SEQUENCE="false" COMMENT="The code of the language this string belongs to. Like en, cs or es" PREVIOUS="id" NEXT="componentid"/>
<FIELD NAME="componentid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="The id of the component" PREVIOUS="lang" NEXT="stringid"/>
<FIELD NAME="stringid" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="The identifier of the string" PREVIOUS="componentid" NEXT="original"/>
<FIELD NAME="original" TYPE="text" LENGTH="big" NOTNULL="true" SEQUENCE="false" COMMENT="English original of the string" PREVIOUS="stringid" NEXT="master"/>
<FIELD NAME="master" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="Master translation of the string as is distributed in the official lang pack, null if not translated" PREVIOUS="original" NEXT="local"/>
<FIELD NAME="local" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="Local customization of the string, null if not customized" PREVIOUS="master" NEXT="timemodified"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="The timestamp of when the original or master was recently modified" PREVIOUS="local" NEXT="timecustomized"/>
<FIELD NAME="timecustomized" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" COMMENT="The timestamp of when the value of the local translation was recently modified, null if not customized yet" PREVIOUS="timemodified" NEXT="outdated"/>
<FIELD NAME="outdated" TYPE="int" LENGTH="3" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Either the English original or the master translation changed and the customization may be outdated" PREVIOUS="timecustomized" NEXT="modified"/>
<FIELD NAME="modified" TYPE="int" LENGTH="3" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Has the string been modified via the translator?" PREVIOUS="outdated"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="fk_component"/>
<KEY NAME="fk_component" TYPE="foreign" FIELDS="componentid" REFTABLE="report_customlang_components" REFFIELDS="id" PREVIOUS="primary"/>
</KEYS>
<INDEXES>
<INDEX NAME="uq_lang_component_string" UNIQUE="true" FIELDS="lang, componentid, stringid" COMMENT="For a given language and component, string identifiers must be unique"/>
</INDEXES>
</TABLE>
<TABLE NAME="report_customlang_components" COMMENT="Contains the list of all installed plugins that provide their own language pack" PREVIOUS="report_customlang">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="name"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="The normalized name of the plugin" PREVIOUS="id" NEXT="version"/>
<FIELD NAME="version" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="The checked out version of the plugin, null if the version is unknown" PREVIOUS="name"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
</TABLES>
</XMLDB>
+74
View File
@@ -0,0 +1,74 @@
<?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/>.
/**
* Language customization report upgrades
*
* @package report
* @subpackage customlang
* @copyright 2010 David Mudrak <david.mudrak@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
function xmldb_report_customlang_upgrade($oldversion) {
global $CFG, $DB, $OUTPUT;
$dbman = $DB->get_manager();
$result = true;
/**
* Use proper plugin prefix for tables
*/
if ($oldversion < 2010111200) {
if ($dbman->table_exists('customlang')) {
$dbman->rename_table(new xmldb_table('customlang'), 'report_customlang');
}
if ($dbman->table_exists('customlang_components')) {
$dbman->rename_table(new xmldb_table('customlang_components'), 'report_customlang_components');
}
upgrade_plugin_savepoint(true, 2010111200, 'report', 'customlang');
}
/**
* Regenerate the foreign key after the tables rename
*/
if ($oldversion < 2010111500) {
$table = new xmldb_table('report_customlang');
$oldkey = new xmldb_key('fk_component', XMLDB_KEY_FOREIGN, array('componentid'), 'customlang_components', array('id'));
$newkey = new xmldb_key('fk_component', XMLDB_KEY_FOREIGN, array('componentid'), 'report_customlang_components', array('id'));
$dbman->drop_key($table, $oldkey);
$dbman->add_key($table, $newkey);
upgrade_plugin_savepoint(true, 2010111500, 'report', 'customlang');
}
/**
* Change the version field from integer to varchar
*/
if ($oldversion < 2011041900) {
$table = new xmldb_table('report_customlang_components');
$field = new xmldb_field('version', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'name');
$dbman->change_field_type($table, $field);
upgrade_plugin_savepoint(true, 2011041900, 'report', 'customlang');
}
return $result;
}
+126
View File
@@ -0,0 +1,126 @@
<?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 report
* @subpackage customlang
* @copyright 2010 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require(dirname(dirname(dirname(dirname(__FILE__)))).'/config.php');
require_once($CFG->dirroot.'/'.$CFG->admin.'/report/customlang/locallib.php');
require_once($CFG->dirroot.'/'.$CFG->admin.'/report/customlang/filter_form.php');
require_login(SITEID, false);
require_capability('report/customlang:edit', get_system_context());
$lng = required_param('lng', PARAM_LANG);
$currentpage = optional_param('p', 0, PARAM_INT);
$translatorsubmitted = optional_param('translatorsubmitted', 0, PARAM_BOOL);
$PAGE->set_pagelayout('standard');
$PAGE->set_url('/admin/report/customlang/edit.php', array('lng' => $lng));
navigation_node::override_active_url(new moodle_url('/admin/report/customlang/index.php'));
$PAGE->set_title(get_string('pluginname', 'report_customlang'));
$PAGE->set_heading(get_string('pluginname', 'report_customlang'));
$PAGE->requires->js_init_call('M.report_customlang.init_editor', array(), true);
if (empty($lng)) {
// PARAM_LANG validation failed
print_error('missingparameter');
}
// pre-output processing
$filter = new report_customlang_filter_form($PAGE->url, null, 'post', '', array('class'=>'filterform'));
$filterdata = report_customlang_utils::load_filter($USER);
$filter->set_data($filterdata);
if ($filter->is_cancelled()) {
redirect($PAGE->url);
} elseif ($submitted = $filter->get_data()) {
report_customlang_utils::save_filter($submitted, $USER);
redirect(new moodle_url($PAGE->url, array('p'=>0)));
}
if ($translatorsubmitted) {
$strings = optional_param('cust', array(), PARAM_RAW);
$updates = optional_param('updates', array(), PARAM_INT);
$checkin = optional_param('savecheckin', false, PARAM_RAW);
if ($checkin === false) {
$nexturl = $PAGE->url;
} else {
$nexturl = new moodle_url('/admin/report/customlang/index.php', array('action'=>'checkin', 'lng' => $lng, 'sesskey'=>sesskey()));
}
if (!is_array($strings)) {
$strings = array();
}
$current = $DB->get_records_list('report_customlang', 'id', array_keys($strings));
$now = time();
foreach ($strings as $recordid => $customization) {
$customization = trim($customization);
if (empty($customization) and !is_null($current[$recordid]->local)) {
$current[$recordid]->local = null;
$current[$recordid]->modified = 1;
$current[$recordid]->outdated = 0;
$current[$recordid]->timecustomized = null;
$DB->update_record('report_customlang', $current[$recordid]);
continue;
}
if (empty($customization)) {
continue;
}
if ($customization !== $current[$recordid]->local) {
$current[$recordid]->local = $customization;
$current[$recordid]->modified = 1;
$current[$recordid]->outdated = 0;
$current[$recordid]->timecustomized = $now;
$DB->update_record('report_customlang', $current[$recordid]);
continue;
}
}
if (!is_array($updates)) {
$updates = array();
}
if (!empty($updates)) {
list($sql, $params) = $DB->get_in_or_equal($updates);
$DB->set_field_select('report_customlang', 'outdated', 0, "local IS NOT NULL AND id $sql", $params);
}
redirect($nexturl);
}
$translator = new report_customlang_translator($PAGE->url, $lng, $filterdata, $currentpage);
// output starts here
$output = $PAGE->get_renderer('report_customlang');
$paginator = $output->paging_bar($translator->numofrows, $currentpage, report_customlang_translator::PERPAGE, $PAGE->url, 'p');
echo $output->header();
$filter->display();
echo $paginator;
echo $output->render($translator);
echo $paginator;
echo $output->footer();
@@ -1,4 +1,5 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@@ -15,7 +16,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool
* @package report
* @subpackage customlang
* @copyright 2010 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -28,51 +29,51 @@ require_once($CFG->dirroot . '/lib/formslib.php');
/**
* Form for filtering the strings to customize
*/
class tool_customlang_filter_form extends moodleform {
class report_customlang_filter_form extends moodleform {
function definition() {
$mform = $this->_form;
$current = $this->_customdata['current'];
$mform->addElement('header', 'filtersettings', get_string('filter', 'tool_customlang'));
$mform->addElement('header', 'filtersettings', get_string('filter', 'report_customlang'));
// Component
$options = array();
foreach (tool_customlang_utils::list_components() as $component => $normalized) {
foreach (report_customlang_utils::list_components() as $component => $normalized) {
list($type, $plugin) = normalize_component($normalized);
if ($type == 'core' and is_null($plugin)) {
$plugin = 'moodle';
}
$options[$type][$normalized] = $component.'.php';
}
$mform->addElement('selectgroups', 'component', get_string('filtercomponent', 'tool_customlang'), $options,
$mform->addElement('selectgroups', 'component', get_string('filtercomponent', 'report_customlang'), $options,
array('multiple'=>'multiple', 'size'=>7));
// Customized only
$mform->addElement('advcheckbox', 'customized', get_string('filtercustomized', 'tool_customlang'));
$mform->addElement('advcheckbox', 'customized', get_string('filtercustomized', 'report_customlang'));
$mform->setType('customized', PARAM_BOOL);
$mform->setDefault('customized', 0);
// Only helps
$mform->addElement('advcheckbox', 'helps', get_string('filteronlyhelps', 'tool_customlang'));
$mform->addElement('advcheckbox', 'helps', get_string('filteronlyhelps', 'report_customlang'));
$mform->setType('helps', PARAM_BOOL);
$mform->setDefault('helps', 0);
// Modified only
$mform->addElement('advcheckbox', 'modified', get_string('filtermodified', 'tool_customlang'));
$mform->addElement('advcheckbox', 'modified', get_string('filtermodified', 'report_customlang'));
$mform->setType('filtermodified', PARAM_BOOL);
$mform->setDefault('filtermodified', 0);
// Substring
$mform->addElement('text', 'substring', get_string('filtersubstring', 'tool_customlang'));
$mform->addElement('text', 'substring', get_string('filtersubstring', 'report_customlang'));
$mform->setType('substring', PARAM_RAW);
// String identifier
$mform->addElement('text', 'stringid', get_string('filterstringid', 'tool_customlang'));
$mform->addElement('text', 'stringid', get_string('filterstringid', 'report_customlang'));
$mform->setType('stringid', PARAM_STRINGID);
// Show strings - submit button
$mform->addElement('submit', 'submit', get_string('filtershowstrings', 'tool_customlang'));
$mform->addElement('submit', 'submit', get_string('filtershowstrings', 'report_customlang'));
}
}
+139
View File
@@ -0,0 +1,139 @@
<?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/>.
/**
* Performs checkout of the strings into the translation table
*
* @package report
* @subpackage customlang
* @copyright 2010 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('NO_OUTPUT_BUFFERING', true); // progress bar is used here
require(dirname(dirname(dirname(dirname(__FILE__)))).'/config.php');
require_once($CFG->dirroot.'/'.$CFG->admin.'/report/customlang/locallib.php');
require_once($CFG->libdir.'/adminlib.php');
require_login(SITEID, false);
require_capability('report/customlang:view', get_system_context());
$action = optional_param('action', '', PARAM_ALPHA);
$confirm = optional_param('confirm', false, PARAM_BOOL);
$lng = optional_param('lng', '', PARAM_LANG);
admin_externalpage_setup('reportcustomlang');
$langs = get_string_manager()->get_list_of_translations();
// pre-output actions
if ($action === 'checkout') {
require_sesskey();
require_capability('report/customlang:edit', get_system_context());
if (empty($lng)) {
print_error('missingparameter');
}
$PAGE->set_cacheable(false); // progress bar is used here
$output = $PAGE->get_renderer('report_customlang');
echo $output->header();
echo $output->heading(get_string('pluginname', 'report_customlang'));
$progressbar = new progress_bar();
$progressbar->create(); // prints the HTML code of the progress bar
// we may need a bit of extra execution time and memory here
@set_time_limit(HOURSECS);
raise_memory_limit(MEMORY_EXTRA);
report_customlang_utils::checkout($lng, $progressbar);
echo $output->continue_button(new moodle_url('/admin/report/customlang/edit.php', array('lng' => $lng)), 'get');
echo $output->footer();
exit;
}
if ($action === 'checkin') {
require_sesskey();
require_capability('report/customlang:edit', get_system_context());
if (empty($lng)) {
print_error('missingparameter');
}
if (!$confirm) {
$output = $PAGE->get_renderer('report_customlang');
echo $output->header();
echo $output->heading(get_string('pluginname', 'report_customlang'));
echo $output->heading($langs[$lng], 3);
$numofmodified = report_customlang_utils::get_count_of_modified($lng);
if ($numofmodified != 0) {
echo $output->heading(get_string('modifiednum', 'report_customlang', $numofmodified), 3);
echo $output->confirm(get_string('confirmcheckin', 'report_customlang'),
new moodle_url($PAGE->url, array('action'=>'checkin', 'lng'=>$lng, 'confirm'=>1)),
new moodle_url($PAGE->url, array('lng'=>$lng)));
} else {
echo $output->heading(get_string('modifiedno', 'report_customlang', $numofmodified), 3);
echo $output->continue_button(new moodle_url($PAGE->url, array('lng' => $lng)));
}
echo $output->footer();
die();
} else {
report_customlang_utils::checkin($lng);
redirect($PAGE->url);
}
}
$output = $PAGE->get_renderer('report_customlang');
// output starts here
echo $output->header();
echo $output->heading(get_string('pluginname', 'report_customlang'));
if (empty($lng)) {
$s = new single_select($PAGE->url, 'lng', $langs);
$s->label = get_accesshide(get_string('language'));
$s->class = 'langselector';
echo $output->box($OUTPUT->render($s), 'langselectorbox');
echo $OUTPUT->footer();
exit;
}
echo $output->heading($langs[$lng], 3);
$numofmodified = report_customlang_utils::get_count_of_modified($lng);
if ($numofmodified != 0) {
echo $output->heading(get_string('modifiednum', 'report_customlang', $numofmodified), 3);
}
$menu = array();
if (has_capability('report/customlang:edit', get_system_context())) {
$menu['checkout'] = array(
'title' => get_string('checkout', 'report_customlang'),
'url' => new moodle_url($PAGE->url, array('action' => 'checkout', 'lng' => $lng)),
'method' => 'post',
);
if ($numofmodified != 0) {
$menu['checkin'] = array(
'title' => get_string('checkin', 'report_customlang'),
'url' => new moodle_url($PAGE->url, array('action' => 'checkin', 'lng' => $lng)),
'method' => 'post',
);
}
}
echo $output->render(new report_customlang_menu($menu));
echo $output->footer();
@@ -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/>.
/**
* Strings for Language customization admin report
*
* @package report
* @subpackage customlang
* @copyright 2010 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$string['checkin'] = 'Check in strings into disk';
$string['checkout'] = 'Check out strings into the translator';
$string['checkoutdone'] = 'Strings checked out successfully into the translator';
$string['checkoutinprogress'] = 'Checking out strings into the translator';
$string['confirmcheckin'] = 'You are about to check in modified strings into your local language pack. This will export the customized strings from the translator into the data directory and Moodle will start using the modified strings. Press \'Continue\' button to proceed check in.';
$string['customlang:edit'] = 'Edit local translation';
$string['customlang:view'] = 'View local translation';
$string['filter'] = 'Filter strings';
$string['filtercomponent'] = 'Show strings of these components';
$string['filtercustomized'] = 'Customized only';
$string['filtermodified'] = 'Modified only';
$string['filteronlyhelps'] = 'Help only';
$string['filtershowstrings'] = 'Show strings';
$string['filterstringid'] = 'String identifier';
$string['filtersubstring'] = 'Only strings containing';
$string['headingcomponent'] = 'Component';
$string['headinglocal'] = 'Local customization';
$string['headingstandard'] = 'Standard text';
$string['headingstringid'] = 'String';
$string['markinguptodate'] = 'Marking the customization as up-to-date';
$string['markinguptodate_help'] = 'The customized translation may get outdated if either the English original or the master translation has modified since the string was customized on your site. Review the customized translation. If you find it up-to-date, click the checkbox. Edit it otherwise.';
$string['markuptodate'] = 'mark as up-to-date';
$string['modifiedno'] = 'There are no modified strings to check in.';
$string['modifiednum'] = 'There are {$a} modified strings. You must check in them into disk to store them permanently.';
$string['nostringsfound'] = 'No strings found, please modify the filter settings';
$string['placeholder'] = 'Placeholders';
$string['placeholder_help'] = 'Placeholders are special statements like `{$a}` or `{$a->something}` within the string. They are replaced with a value when the string is actually printed.
It is important to copy them exactly as they are in the original string. Do not translate them nor change their left-to-right orientation.';
$string['placeholderwarning'] = 'string contains a placeholder';
$string['pluginname'] = 'Language customization';
$string['savecheckin'] = 'Save and check in strings into files';
$string['savecontinue'] = 'Save and continue editing';
+25
View File
@@ -0,0 +1,25 @@
<?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 report
* @subpackage customlang
* @copyright 2010 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
+535
View File
@@ -0,0 +1,535 @@
<?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/>.
/**
* Definition of classes used by language customization admin report
*
* @package report
* @subpackage customlang
* @copyright 2010 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Provides various utilities to be used by the plugin
*
* All the public methods here are static ones, this class can not be instantiated
*/
class report_customlang_utils {
/**
* Rough number of strings that are being processed during a full checkout.
* This is used to estimate the progress of the checkout.
*/
const ROUGH_NUMBER_OF_STRINGS = 16500;
/** @var array cache of {@link self::list_components()} results */
protected static $components = null;
/**
* This class can not be instantiated
*/
private function __construct() {
}
/**
* Returns a list of all components installed on the server
*
* @return array (string)legacyname => (string)frankenstylename
*/
public static function list_components() {
$list['moodle'] = 'core';
$coresubsystems = get_core_subsystems();
ksort($coresubsystems); // should be but just in case
foreach ($coresubsystems as $name => $location) {
if ($name != 'moodle.org') {
$list[$name] = 'core_'.$name;
}
}
$plugintypes = get_plugin_types();
foreach ($plugintypes as $type => $location) {
$pluginlist = get_plugin_list($type);
foreach ($pluginlist as $name => $ununsed) {
if ($type == 'mod') {
if (array_key_exists($name, $list)) {
throw new Exception('Activity module and core subsystem name collision');
}
$list[$name] = $type.'_'.$name;
} else {
$list[$type.'_'.$name] = $type.'_'.$name;
}
}
}
return $list;
}
/**
* Updates the translator database with the strings from files
*
* This should be executed each time before going to the translation page
*
* @param string $lang language code to checkout
* @param progress_bar $progressbar optionally, the given progress bar can be updated
*/
public static function checkout($lang, progress_bar $progressbar = null) {
global $DB;
// make sure that all components are registered
$current = $DB->get_records('report_customlang_components', null, 'name', 'name,version,id');
foreach (self::list_components() as $component) {
if (empty($current[$component])) {
$record = new stdclass();
$record->name = $component;
if (!$version = get_component_version($component)) {
$record->version = null;
} else {
$record->version = $version;
}
$DB->insert_record('report_customlang_components', $record);
} elseif ($version = get_component_version($component)) {
if (is_null($current[$component]->version) or ($version > $current[$component]->version)) {
$DB->set_field('report_customlang_components', 'version', $version, array('id' => $current[$component]->id));
}
}
}
unset($current);
// initialize the progress counter - stores the number of processed strings
$done = 0;
$strinprogress = get_string('checkoutinprogress', 'report_customlang');
// reload components and fetch their strings
$stringman = get_string_manager();
$components = $DB->get_records('report_customlang_components');
foreach ($components as $component) {
$sql = "SELECT stringid, id, lang, componentid, original, master, local, timemodified, timecustomized, outdated, modified
FROM {report_customlang} s
WHERE lang = ? AND componentid = ?
ORDER BY stringid";
$current = $DB->get_records_sql($sql, array($lang, $component->id));
$english = $stringman->load_component_strings($component->name, 'en', true, true);
if ($lang == 'en') {
$master =& $english;
} else {
$master = $stringman->load_component_strings($component->name, $lang, true, true);
}
$local = $stringman->load_component_strings($component->name, $lang, true, false);
foreach ($english as $stringid => $stringoriginal) {
$stringmaster = isset($master[$stringid]) ? $master[$stringid] : null;
$stringlocal = isset($local[$stringid]) ? $local[$stringid] : null;
$now = time();
if (!is_null($progressbar)) {
$done++;
$donepercent = floor(min($done, self::ROUGH_NUMBER_OF_STRINGS) / self::ROUGH_NUMBER_OF_STRINGS * 100);
$progressbar->update_full($donepercent, $strinprogress);
}
if (isset($current[$stringid])) {
$needsupdate = false;
$currentoriginal = $current[$stringid]->original;
$currentmaster = $current[$stringid]->master;
$currentlocal = $current[$stringid]->local;
if ($currentoriginal !== $stringoriginal or $currentmaster !== $stringmaster) {
$needsupdate = true;
$current[$stringid]->original = $stringoriginal;
$current[$stringid]->master = $stringmaster;
$current[$stringid]->timemodified = $now;
$current[$stringid]->outdated = 1;
}
if ($stringmaster !== $stringlocal) {
$needsupdate = true;
$current[$stringid]->local = $stringlocal;
$current[$stringid]->timecustomized = $now;
}
if ($needsupdate) {
$DB->update_record('report_customlang', $current[$stringid]);
continue;
}
} else {
$record = new stdclass();
$record->lang = $lang;
$record->componentid = $component->id;
$record->stringid = $stringid;
$record->original = $stringoriginal;
$record->master = $stringmaster;
$record->timemodified = $now;
$record->outdated = 0;
if ($stringmaster !== $stringlocal) {
$record->local = $stringlocal;
$record->timecustomized = $now;
} else {
$record->local = null;
$record->timecustomized = null;
}
$DB->insert_record('report_customlang', $record);
}
}
}
if (!is_null($progressbar)) {
$progressbar->update_full(100, get_string('checkoutdone', 'report_customlang'));
}
}
/**
* Exports the translator database into disk files
*
* @param mixed $lang language code
*/
public static function checkin($lang) {
global $DB, $USER, $CFG;
require_once($CFG->libdir.'/filelib.php');
if ($lang !== clean_param($lang, PARAM_LANG)) {
return false;
}
// get all customized strings from updated components
$sql = "SELECT s.*, c.name AS component
FROM {report_customlang} s
JOIN {report_customlang_components} c ON s.componentid = c.id
WHERE s.lang = ?
AND (s.local IS NOT NULL OR s.modified = 1)
ORDER BY componentid, stringid";
$strings = $DB->get_records_sql($sql, array($lang));
$files = array();
foreach ($strings as $string) {
if (!is_null($string->local)) {
$files[$string->component][$string->stringid] = $string->local;
}
}
fulldelete(self::get_localpack_location($lang));
foreach ($files as $component => $strings) {
self::dump_strings($lang, $component, $strings);
}
$DB->set_field_select('report_customlang', 'modified', 0, 'lang = ?', array($lang));
$sm = get_string_manager();
$sm->reset_caches();
}
/**
* Returns full path to the directory where local packs are dumped into
*
* @param string $lang language code
* @return string full path
*/
protected static function get_localpack_location($lang) {
global $CFG;
return $CFG->langlocalroot.'/'.$lang.'_local';
}
/**
* Writes strings into a local language pack file
*
* @param string $component the name of the component
* @param array $strings
*/
protected static function dump_strings($lang, $component, $strings) {
global $CFG;
if ($lang !== clean_param($lang, PARAM_LANG)) {
debugging('Unable to dump local strings for non-installed language pack .'.s($lang));
return false;
}
if ($component !== clean_param($component, PARAM_SAFEDIR)) {
throw new coding_exception('Incorrect component name');
}
if (!$filename = self::get_component_filename($component)) {
debugging('Unable to find the filename for the component '.s($component));
return false;
}
if ($filename !== clean_param($filename, PARAM_FILE)) {
throw new coding_exception('Incorrect file name '.s($filename));
}
list($package, $subpackage) = normalize_component($component);
$packageinfo = " * @package $package";
if (!is_null($subpackage)) {
$packageinfo .= "\n * @subpackage $subpackage";
}
$filepath = self::get_localpack_location($lang);
$filepath = $filepath.'/'.$filename;
if (!is_dir(dirname($filepath))) {
check_dir_exists(dirname($filepath));
}
if (!$f = fopen($filepath, 'w')) {
debugging('Unable to write '.s($filepath));
return false;
}
fwrite($f, <<<EOF
<?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/>.
/**
* Local language pack from $CFG->wwwroot
*
$packageinfo
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
EOF
);
foreach ($strings as $stringid => $text) {
if ($stringid !== clean_param($stringid, PARAM_STRINGID)) {
debugging('Invalid string identifier '.s($stringid));
continue;
}
fwrite($f, '$string[\'' . $stringid . '\'] = ');
fwrite($f, var_export($text, true));
fwrite($f, ";\n");
}
fclose($f);
}
/**
* Returns the name of the file where the component's local strings should be exported into
*
* @param string $component normalized name of the component, eg 'core' or 'mod_workshop'
* @return string|boolean filename eg 'moodle.php' or 'workshop.php', false if not found
*/
protected static function get_component_filename($component) {
if (is_null(self::$components)) {
self::$components = self::list_components();
}
$return = false;
foreach (self::$components as $legacy => $normalized) {
if ($component === $normalized) {
$return = $legacy.'.php';
break;
}
}
return $return;
}
/**
* Returns the number of modified strings checked out in the translator
*
* @param string $lang language code
* @return int
*/
public static function get_count_of_modified($lang) {
global $DB;
return $DB->count_records('report_customlang', array('lang'=>$lang, 'modified'=>1));
}
/**
* Saves filter data into a persistant storage such as user session
*
* @see self::load_filter()
* @param stdclass $data filter values
* @param stdclass $persistant storage object
*/
public static function save_filter(stdclass $data, stdclass $persistant) {
if (!isset($persistant->report_customlang_filter)) {
$persistant->report_customlang_filter = array();
}
foreach ($data as $key => $value) {
if ($key !== 'submit') {
$persistant->report_customlang_filter[$key] = serialize($value);
}
}
}
/**
* Loads the previously saved filter settings from a persistent storage
*
* @see self::save_filter()
* @param stdclass $persistant storage object
* @return stdclass filter data
*/
public static function load_filter(stdclass $persistant) {
$data = new stdclass();
if (isset($persistant->report_customlang_filter)) {
foreach ($persistant->report_customlang_filter as $key => $value) {
$data->{$key} = unserialize($value);
}
}
return $data;
}
}
/**
* Represents the action menu of the report
*/
class report_customlang_menu implements renderable {
/** @var menu items */
protected $items = array();
public function __construct(array $items = array()) {
global $CFG;
foreach ($items as $itemkey => $item) {
$this->add_item($itemkey, $item['title'], $item['url'], empty($item['method']) ? 'post' : $item['method']);
}
}
/**
* Returns the menu items
*
* @return array (string)key => (object)[->(string)title ->(moodle_url)url ->(string)method]
*/
public function get_items() {
return $this->items;
}
/**
* Adds item into the menu
*
* @param string $key item identifier
* @param string $title localized action title
* @param moodle_url $url action handler
* @param string $method form method
*/
public function add_item($key, $title, moodle_url $url, $method) {
if (isset($this->items[$key])) {
throw new coding_exception('Menu item already exists');
}
if (empty($title) or empty($key)) {
throw new coding_exception('Empty title or item key not allowed');
}
$item = new stdclass();
$item->title = $title;
$item->url = $url;
$item->method = $method;
$this->items[$key] = $item;
}
}
/**
* Represents the translation tool
*/
class report_customlang_translator implements renderable {
/** @const int number of rows per page */
const PERPAGE = 100;
/** @var int total number of the rows int the table */
public $numofrows = 0;
/** @var moodle_url */
public $handler;
/** @var string language code */
public $lang;
/** @var int page to display, starting with page 0 */
public $currentpage = 0;
/** @var array of stdclass strings to display */
public $strings = array();
/** @var stdclass */
protected $filter;
public function __construct(moodle_url $handler, $lang, $filter, $currentpage = 0) {
global $DB;
$this->handler = $handler;
$this->lang = $lang;
$this->filter = $filter;
$this->currentpage = $currentpage;
if (empty($filter) or empty($filter->component)) {
// nothing to do
$this->currentpage = 1;
return;
}
list($insql, $inparams) = $DB->get_in_or_equal($filter->component, SQL_PARAMS_NAMED);
$csql = "SELECT COUNT(*)";
$fsql = "SELECT s.id, s.*, c.name AS component";
$sql = " FROM {report_customlang_components} c
JOIN {report_customlang} s ON s.componentid = c.id
WHERE s.lang = :lang
AND c.name $insql";
$params = array_merge(array('lang' => $lang), $inparams);
if (!empty($filter->customized)) {
$sql .= " AND s.local IS NOT NULL";
}
if (!empty($filter->modified)) {
$sql .= " AND s.modified = 1";
}
if (!empty($filter->stringid)) {
$sql .= " AND s.stringid = :stringid";
$params['stringid'] = $filter->stringid;
}
if (!empty($filter->substring)) {
$sql .= " AND (".$DB->sql_like('s.original', ':substringoriginal', false)." OR
".$DB->sql_like('s.master', ':substringmaster', false)." OR
".$DB->sql_like('s.local', ':substringlocal', false).")";
$params['substringoriginal'] = '%'.$filter->substring.'%';
$params['substringmaster'] = '%'.$filter->substring.'%';
$params['substringlocal'] = '%'.$filter->substring.'%';
}
if (!empty($filter->helps)) {
$sql .= " AND ".$DB->sql_like('s.stringid', ':help', false); //ILIKE
$params['help'] = '%\_help';
} else {
$sql .= " AND ".$DB->sql_like('s.stringid', ':link', false, true, true); //NOT ILIKE
$params['link'] = '%\_link';
}
$osql = " ORDER BY c.name, s.stringid";
$this->numofrows = $DB->count_records_sql($csql.$sql, $params);
$this->strings = $DB->get_records_sql($fsql.$sql.$osql, $params, ($this->currentpage) * self::PERPAGE, self::PERPAGE);
}
}
+45
View File
@@ -0,0 +1,45 @@
// 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 report
* @subpackage customlang
* @copyright 2010 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @namespace
*/
M.report_customlang = M.report_customlang || {};
/**
* YUI instance holder
*/
M.report_customlang.Y = {};
/**
* Initialize JS support for the edit.php
*
* @param {Object} Y YUI instance
*/
M.report_customlang.init_editor = function(Y) {
M.report_customlang.Y = Y;
Y.all('#translator .local textarea').each(function (textarea) {
var cell = textarea.get('parentNode');
textarea.setStyle('height', cell.getComputedStyle('height'));
});
}
+147
View File
@@ -0,0 +1,147 @@
<?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/>.
/**
* Output rendering of Language customization admin report
*
* @package report
* @subpackage customlang
* @copyright 2010 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Rendering methods for the report widgets
*/
class report_customlang_renderer extends plugin_renderer_base {
/**
* Renders customlang report menu
*
* @return string HTML
*/
protected function render_report_customlang_menu(report_customlang_menu $menu) {
$output = '';
foreach ($menu->get_items() as $item) {
$output .= $this->single_button($item->url, $item->title, $item->method);
}
return $this->box($output, 'menu');
}
/**
* Renders customlang translation table
*
* @param report_customlang_translator $translator
* @return string HTML
*/
protected function render_report_customlang_translator(report_customlang_translator $translator) {
$output = '';
if (empty($translator->strings)) {
return $this->heading(get_string('nostringsfound', 'report_customlang'), 3);
}
$table = new html_table();
$table->id = 'translator';
$table->head = array(
get_string('headingcomponent', 'report_customlang'),
get_string('headingstringid', 'report_customlang'),
get_string('headingstandard', 'report_customlang'),
get_string('headinglocal', 'report_customlang'),
);
foreach ($translator->strings as $string) {
$cells = array();
// component name
$cells[0] = new html_table_cell($string->component);
$cells[0]->attributes['class'] = 'component';
// string identification code
$cells[1] = new html_table_cell(html_writer::tag('div', s($string->stringid), array('class' => 'stringid')));
$cells[1]->attributes['class'] = 'stringid';
// master translation of the string
$master = html_writer::tag('div', s($string->master), array('class' => 'preformatted'));
$minheight = strlen($string->master) / 200;
if (preg_match('/\{\$a(->.+)?\}/', $string->master)) {
$master .= html_writer::tag('div', $this->help_icon('placeholder', 'report_customlang',
get_string('placeholderwarning', 'report_customlang')), array('class' => 'placeholderinfo'));
}
$cells[2] = new html_table_cell($master);
$cells[2]->attributes['class'] = 'standard master';
// local customization of the string
$textareaattributes = array('name'=>'cust['.$string->id.']', 'cols'=>40, 'rows'=>3);
if ($minheight>1) {
$textareaattributes['style'] = 'min-height:' . (int) 4*$minheight . 'em;';
}
$textarea = html_writer::tag('textarea', s($string->local), $textareaattributes);
$cells[3] = new html_table_cell($textarea);
if (!is_null($string->local) and $string->outdated) {
$mark = html_writer::empty_tag('input', array('type' => 'checkbox', 'id' => 'update_' . $string->id,
'name' => 'updates[]', 'value' => $string->id));
$help = $this->help_icon('markinguptodate', 'report_customlang');
$mark .= html_writer::tag('label', get_string('markuptodate', 'report_customlang') . $help,
array('for' => 'update_' . $string->id));
$mark = html_writer::tag('div', $mark, array('class' => 'uptodatewrapper'));
} else {
$mark = '';
}
$cells[3] = new html_table_cell($textarea."\n".$mark);
$cells[3]->attributes['class'] = 'local';
$cells[3]->id = 'id_'.$string->id;
if (!is_null($string->local)) {
$cells[3]->attributes['class'] .= ' customized';
}
if ($string->outdated) {
$cells[3]->attributes['class'] .= ' outdated';
}
if ($string->modified) {
$cells[3]->attributes['class'] .= ' modified';
}
if ($string->original !== $string->master) {
$cells[0]->rowspan = $cells[1]->rowspan = $cells[3]->rowspan = 2;
}
$row = new html_table_row($cells);
$table->data[] = $row;
if ($string->original !== $string->master) {
$cells = array();
// original of the string
$cells[2] = new html_table_cell(html_writer::tag('div', s($string->original), array('class' => 'preformatted')));
$cells[2]->attributes['class'] = 'standard original';
$row = new html_table_row($cells);
$table->data[] = $row;
}
}
$output .= html_writer::start_tag('form', array('method'=>'post', 'action'=>$translator->handler->out()));
$output .= html_writer::start_tag('div');
$output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'translatorsubmitted', 'value'=>1));
$output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'sesskey', 'value'=>sesskey()));
$save1 = html_writer::empty_tag('input', array('type'=>'submit', 'name'=>'savecontinue', 'value'=>get_string('savecontinue', 'report_customlang')));
$save2 = html_writer::empty_tag('input', array('type'=>'submit', 'name'=>'savecheckin', 'value'=>get_string('savecheckin', 'report_customlang')));
$output .= html_writer::tag('fieldset', $save1.$save2, array('class'=>'buttonsbar'));
$output .= html_writer::table($table);
$output .= html_writer::tag('fieldset', $save1.$save2, array('class'=>'buttonsbar'));
$output .= html_writer::end_tag('div');
$output .= html_writer::end_tag('form');
return $output;
}
}
+27
View File
@@ -0,0 +1,27 @@
<?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 report
* @subpackage customlang
* @copyright 2010 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$ADMIN->add('language', new admin_externalpage('reportcustomlang', get_string('pluginname', 'report_customlang'), "$CFG->wwwroot/$CFG->admin/report/customlang/index.php", 'report/customlang:view'));
+69
View File
@@ -0,0 +1,69 @@
.path-admin-report-customlang .langselectorbox,
.path-admin-report-customlang fieldset.buttonsbar,
.path-admin-report-customlang .menu {
margin: 5px auto;
text-align: center;
}
.path-admin-report-customlang .menu .singlebutton,
.path-admin-report-customlang .menu .singlebutton form,
.path-admin-report-customlang .menu .singlebutton form div {
display: inline;
}
.path-admin-report-customlang .mform.filterform {
width: 70%;
margin-left: auto;
margin-right: auto;
}
.path-admin-report-customlang .mform.filterform .fitem .fitemtitle {
width: 30%;
}
.path-admin-report-customlang .mform.filterform .fitem .felement {
width: 60%;
margin-left: 31%;
}
.path-admin-report-customlang #translator {
width: 100%;
}
.path-admin-report-customlang #translator .standard,
.path-admin-report-customlang #translator .local {
min-width: 35%;
}
.path-admin-report-customlang #translator .customized {
background-color: #e7f1c3;
}
.path-admin-report-customlang #translator .customized.outdated {
background-color: #f3f2aa;
}
.path-admin-report-customlang #translator .modified {
background-color: #ffd3d9;
}
.path-admin-report-customlang #translator .customized.modified {
background-color: #d2ebff;
}
.path-admin-report-customlang #translator textarea {
width: 100%;
min-height: 4em;
}
.path-admin-report-customlang #translator .placeholderinfo {
text-align: center;
border: 1px dotted #ddd;
background-color: #f6f6f6;
margin-top: 0.5em;
}
#page-admin-report-customlang-index .continuebutton {
margin-top: 1em;
}
+28
View File
@@ -0,0 +1,28 @@
<?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 report
* @subpackage customlang
* @copyright 2010 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2011041900;
$plugin->requires = 2010120700;
+7
View File
@@ -0,0 +1,7 @@
<?php
defined('MOODLE_INTERNAL') || die;
// just a link to course report
$ADMIN->add('reports', new admin_externalpage('reportlog', get_string('log', 'admin'), "$CFG->wwwroot/course/report/log/index.php?id=".SITEID, 'coursereport/log:view'));
$ADMIN->add('reports', new admin_externalpage('reportloglive', get_string('loglive', 'coursereport_log'), "$CFG->wwwroot/course/report/log/indexlive.php?id=".SITEID, 'coursereport/log:viewlive'));
+186
View File
@@ -0,0 +1,186 @@
<?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 profiling
* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// TODO: Move all the DB stuff to profiling_db_xxxx() function in xhprof_moodle.php
require_once(dirname(__FILE__).'/../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir . '/xhprof/xhprof_moodle.php');
define('PROFILING_RUNSPERPAGE', 50);
// page parameters
$script = optional_param('script', null, PARAM_PATH);
$runid = optional_param('runid', null, PARAM_ALPHANUM);
$runid2 = optional_param('runid2', null, PARAM_ALPHANUM);
$listurl = optional_param('listurl', null, PARAM_PATH);
$runreference= optional_param('runreference', 0, PARAM_INT);
$runcomment = optional_param('runcomment', null, PARAM_TEXT);
$dbfields = 'runid, url, totalexecutiontime, totalcputime, ' .
'totalcalls, totalmemory, runreference, runcomment, timecreated';
admin_externalpage_setup('reportprofiling');
// Always add listurl if available
if ($listurl) {
$listurlnav = new moodle_url('/admin/report/profiling/index.php', array('listurl' => $listurl));
$PAGE->navbar->add($listurl, $listurlnav);
}
// Header
echo $OUTPUT->header();
// We have requested the last available run for one script
if (isset($script)) {
// Get the last available run for the given script
$run = $DB->get_record_sql("SELECT $dbfields
FROM {profiling}
WHERE url = ?
AND id = (SELECT MAX(id)
FROM {profiling}
WHERE url = ?)",
array($script, $script), IGNORE_MISSING);
// No run found for script, warn and exit
if (!$run) {
notice(get_string('cannotfindanyrunforurl', 'report_profiling', $script), 'index.php');
}
// Check if there is any previous run marked as reference one
$prevreferences = $DB->get_records_select('profiling',
'url = ? AND runreference = 1 AND timecreated < ?',
array($run->url, $run->timecreated),
'timecreated DESC', 'runid', 0, 1);
$prevrunid = $prevreferences ? reset($prevreferences)->runid : false;
echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
$header = get_string('lastrunof', 'report_profiling', $script);
echo $OUTPUT->heading($header);
$table = profiling_print_run($run, $prevrunid);
echo $table;
echo $OUTPUT->box_end();
// We have requested the diff between 2 runs
} else if (isset($runid) && isset($runid2)) {
$run1 = $DB->get_record('profiling', array('runid'=>$runid), $dbfields, MUST_EXIST);
$run2 = $DB->get_record('profiling', array('runid'=>$runid2), $dbfields, MUST_EXIST);
if ($run1->url == $run2->url && $run1->runid != $run2->runid) {
if ($run2->timecreated < $run1->timecreated) {
$runtemp = $run1;
$run1 = $run2;
$run2 = $runtemp;
}
echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
$header = get_string('differencesbetween2runsof', 'report_profiling', $run1->url);
echo $OUTPUT->heading($header);
$table = profiling_print_rundiff($run1, $run2);
echo $table;
echo $OUTPUT->box_end();
}
// We have requested one run, invoke it
} else if (isset($runid)) {
// Check if we are trying to update the runreference/runcomment for the run
if (isset($runcomment) && confirm_sesskey()) {
$id = $DB->get_field('profiling', 'id', array('runid' => $runid), MUST_EXIST);
$rec = new stdClass();
$rec->id = $id;
$rec->runreference = (bool)$runreference;
$rec->runcomment = $runcomment;
$DB->update_record('profiling', $rec);
}
// Get the requested runid
$run = $DB->get_record('profiling', array('runid'=>$runid), $dbfields, IGNORE_MISSING);
// No run found for runid, warn and exit
if (!$run) {
notice(get_string('cannotfindanyrunforrunid', 'report_profiling', $runid), 'index.php');
}
// Check if there is any previous run marked as reference one
$prevreferences = $DB->get_records_select('profiling',
'url = ? AND runreference = 1 AND timecreated < ?',
array($run->url, $run->timecreated),
'timecreated DESC', 'runid', 0, 1);
$prevrunid = $prevreferences ? reset($prevreferences)->runid : false;
echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
$header = get_string('summaryof', 'report_profiling', $run->url);
echo $OUTPUT->heading($header);
$table = profiling_print_run($run, $prevrunid);
echo $table;
echo $OUTPUT->box_end();
// Default: List one page of runs
} else {
// The flexitable that will root listings
$table = new xhprof_table_sql('profiling-list-table');
$baseurl = $CFG->wwwroot . '/admin/report/profiling/index.php';
// Check if we are listing all or some URL ones
$sqlconditions = '';
$sqlparams = array();
if (!isset($listurl)) {
$header = get_string('pluginname', 'report_profiling');
$sqlconditions = '1 = 1';
$table->set_listurlmode(false);
} else {
$header = get_string('profilingrunsfor', 'report_profiling', $listurl);
$sqlconditions = 'url = :url';
$sqlparams['url'] = $listurl;
$table->set_listurlmode(true);
$baseurl .= '?listurl=' . urlencode($listurl);
}
echo $OUTPUT->heading($header);
// TODO: Fix flexitable to validate tsort/thide/tshow/tifirs/tilast/page
// TODO: Fix table_sql to allow it to work without WHERE clause
// add silly condition (1 = 1) because of table_sql bug
$table->set_sql($dbfields, '{profiling}', $sqlconditions, $sqlparams);
$table->set_count_sql("SELECT COUNT(*) FROM {profiling} WHERE $sqlconditions", $sqlparams);
$columns = array(
'url', 'timecreated', 'totalexecutiontime', 'totalcputime',
'totalcalls', 'totalmemory', 'runcomment');
$headers = array(
get_string('url'), get_string('date'), get_string('executiontime', 'report_profiling'),
get_string('cputime', 'report_profiling'), get_string('calls', 'report_profiling'),
get_string('memory', 'report_profiling'), get_string('comment', 'report_profiling'));
$table->define_columns($columns);
$table->define_headers($headers);
$table->sortable(true, 'timecreated', SORT_DESC);
$table->define_baseurl($baseurl);
$table->column_suppress('url');
$table->out(PROFILING_RUNSPERPAGE, true);
// Print the controller block with different options
echo profiling_list_controls($listurl);
}
// Footer.
echo $OUTPUT->footer();
@@ -0,0 +1,45 @@
<?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/>.
/**
* Strings for component 'report_profiling', language 'en', branch 'MOODLE_20_STABLE'
*
* @package report_profiling
* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['calls'] = 'Function calls';
$string['cannotfindanyrunforurl'] = 'Sorry, cannot find any profiling run for the \'{$a}\' URL';
$string['cannotfindanyrunforrunid'] = 'Sorry, cannot find the \'{$a}\' profiling run';
$string['comment'] = 'Comment';
$string['differencesbetween2runsof'] = 'Differences between 2 runs of {$a}';
$string['executiontime'] = 'Execution time';
$string['cputime'] = 'CPU time';
$string['lastrunof'] = 'Summary of last run of {$a}';
$string['markreferencerun'] = 'Mark as reference run/comment';
$string['memory'] = 'Memory used';
$string['pluginname'] = 'Profiling runs';
$string['profilingfocusscript'] = 'Focus on profiling runs for the script: {$a}';
$string['profilingruns'] = 'Profiling runs';
$string['profilingrunsfor'] = 'Profiling runs for {$a}';
$string['referencerun'] = 'Reference run/comment';
$string['runid'] = 'Run ID';
$string['summaryof'] = 'Summary of {$a}';
$string['viewdetails'] = 'View profiling details';
$string['viewdiff'] = 'View profiling differences with last reference run';
$string['viewdiffdetails'] = 'View profiling diff details';
+8
View File
@@ -0,0 +1,8 @@
<?php
defined('MOODLE_INTERNAL') || die;
// profiling report, added to development
if (extension_loaded('xhprof') && function_exists('xhprof_enable') && (!empty($CFG->profilingenabled) || !empty($CFG->earlyprofilingenabled))) {
$ADMIN->add('development', new admin_externalpage('reportprofiling', get_string('pluginname', 'report_profiling'), "$CFG->wwwroot/$CFG->admin/report/profiling/index.php", 'moodle/site:config'));
}
+25
View File
@@ -0,0 +1,25 @@
/* report_profiling styles */
.path-admin-report-profiling .profilingruntable .label {
font-weight: bold;
}
.path-admin-report-profiling .profiling_worse {
color: red;
}
.path-admin-report-profiling .profiling_better {
color: green;
}
.path-admin-report-profiling .profiling_same {
color: dimgrey;
}
.path-admin-report-profiling .profiling_important,
.path-admin-report-profiling .flexible .referencerun {
font-weight: bold;
}
.path-admin-report-profiling .flexible .r1 .cell {
background-color: whitesmoke;
}
.path-admin-report-profiling .flexible {
margin-left:auto;
margin-right:auto
}
@@ -0,0 +1,37 @@
<?php
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
// //
// This program 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 2 of the License, or //
// (at your option) any later version. //
// //
// This program 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: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
$capabilities = array(
'report/questioninstances:view' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:config',
)
);
+131
View File
@@ -0,0 +1,131 @@
<?php
/**
* For a given question type, list the number of
*
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package roles
*/
/** */
require_once(dirname(__FILE__).'/../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/questionlib.php');
// Get URL parameters.
$requestedqtype = optional_param('qtype', '', PARAM_SAFEDIR);
// Print the header & check permissions.
admin_externalpage_setup('reportquestioninstances');
echo $OUTPUT->header();
// Log.
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) {
$qtypechoices[$qtype->name()] = $qtype->local_name();
}
// Print the settings form.
echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter centerpara');
echo '<form method="get" action="." id="settingsform"><div>';
echo $OUTPUT->heading(get_string('reportsettings', 'report_questioninstances'));
echo '<p id="intro">', get_string('intro', 'report_questioninstances') , '</p>';
echo '<p><label for="menuqtype"> ' . get_string('questiontype', 'admin') . '</label> ';
echo html_writer::select($qtypechoices, 'qtype', $requestedqtype, array('_all_'=>get_string('all')));
echo '</p>';
echo '<p><input type="submit" id="settingssubmit" value="' .
get_string('getreport', 'report_questioninstances') . '" /></p>';
echo '</div></form>';
echo $OUTPUT->box_end();
// If we have a qtype to report on, generate the report.
if ($requestedqtype) {
// Work out the bits needed for the SQL WHERE clauses.
if ($requestedqtype == 'missingtype') {
$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);
$sqlqtypetest = 'WHERE qtype ' . $sqlqtypetest;
$title = get_string('reportformissingqtypes', 'report_questioninstances');
} else if ($requestedqtype == '_all_') {
$sqlqtypetest = '';
$params = array();
$title = get_string('reportforallqtypes', 'report_questioninstances');
} else {
$sqlqtypetest = 'WHERE qtype = ?';
$params = array($requestedqtype);
$title = get_string('reportforqtype', 'report_questioninstances',
question_bank::get_qtype($requestedqtype)->local_name());
}
// Get the question counts, and all the context information, for each
// context. That is, rows of these results can be used as $context objects.
$counts = $DB->get_records_sql("
SELECT qc.contextid, count(1) as numquestions, sum(hidden) as numhidden, con.id, con.contextlevel, con.instanceid, con.path, con.depth
FROM {question} q
JOIN {question_categories} qc ON q.category = qc.id
JOIN {context} con ON con.id = qc.contextid
$sqlqtypetest
GROUP BY contextid, con.id, con.contextlevel, con.instanceid, con.path, con.depth
ORDER BY numquestions DESC, numhidden ASC, con.contextlevel ASC, con.id ASC", $params);
// Print the report heading.
echo $OUTPUT->heading($title);
// Initialise the table.
$table = new html_table();
$table->head = array(
get_string('context', 'role'),
get_string('totalquestions', 'report_questioninstances'),
get_string('visiblequestions', 'report_questioninstances'),
get_string('hiddenquestions', 'report_questioninstances'));
$table->data = array();
$table->class = '';
$table->id = '';
// Add the data for each row.
$totalquestions = 0;
$totalvisible = 0;
$totalhidden = 0;
foreach ($counts as $count) {
// Work out a link for editing questions in this context.
$contextname = print_context_name($count);
$url = question_edit_url($count);
if ($url) {
$contextname = '<a href="' . $url . '" title="' .
get_string('editquestionshere', 'report_questioninstances') .
'">' . $contextname . '</a>';
}
// Put the scores in the table.
$numvisible = $count->numquestions - $count->numhidden;
$table->data[] = array(
$contextname,
$count->numquestions,
$numvisible,
$count->numhidden);
// Update the totals.
$totalquestions += $count->numquestions;
$totalvisible += $numvisible;
$totalhidden += $count->numhidden;
}
// Add a totals row.
$table->data[] = array(
'<b>' . get_string('total') . '</b>',
$totalquestions,
$totalvisible,
$totalhidden);
// Print it.
echo html_writer::table($table);
}
// Footer.
echo $OUTPUT->footer();
@@ -1,4 +1,5 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@@ -15,12 +16,11 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* lang strings
* Strings for component 'report_questioninstances', language 'en', branch 'MOODLE_20_STABLE'
*
* @package report
* @subpackage questioninstances
* @copyright 2008 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @package report_questioninstances
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['editquestionshere'] = 'Edit questions in this context';
@@ -0,0 +1,5 @@
<?php
defined('MOODLE_INTERNAL') || die;
$ADMIN->add('reports', new admin_externalpage('reportquestioninstances', get_string('pluginname', 'report_questioninstances'), "$CFG->wwwroot/$CFG->admin/report/questioninstances/index.php", 'report/questioninstances:view'));
@@ -0,0 +1,27 @@
<?PHP
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
// //
// This program 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 2 of the License, or //
// (at your option) any later version. //
// //
// This program 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: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
$plugin->version = 2010090501;
$plugin->requires = 2010090501;
+36
View File
@@ -0,0 +1,36 @@
<?php
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
// //
// This program 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 2 of the License, or //
// (at your option) any later version. //
// //
// This program 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: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
$capabilities = array(
'report/security:view' => array(
'riskbitmask' => RISK_CONFIG,
'captype' => 'read',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW
),
)
);
+127
View File
@@ -0,0 +1,127 @@
<?php
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.org //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
// //
// This program 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 2 of the License, or //
// (at your option) any later version. //
// //
// This program 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: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
define('NO_OUTPUT_BUFFERING', true);
require_once('../../../config.php');
require_once($CFG->dirroot.'/'.$CFG->admin.'/report/security/lib.php');
require_once($CFG->libdir.'/adminlib.php');
require_login();
$issue = optional_param('issue', '', PARAM_ALPHANUMEXT); // show detailed info about one issue only
$issues = report_security_get_issue_list();
// test if issue valid string
if (array_search($issue, $issues, true) === false) {
$issue = '';
}
// we may need a bit more memory and this may take a long time to process
raise_memory_limit(MEMORY_EXTRA);
@set_time_limit(0);
// Print the header.
admin_externalpage_setup('reportsecurity');
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('pluginname', 'report_security'));
echo '<div id="timewarning">'.get_string('timewarning', 'report_security').'</div>';
$strok = '<span class="statusok">'.get_string('statusok', 'report_security').'</span>';
$strinfo = '<span class="statusinfo">'.get_string('statusinfo', 'report_security').'</span>';
$strwarning = '<span class="statuswarning">'.get_string('statuswarning', 'report_security').'</span>';
$strserious = '<span class="statusserious">'.get_string('statusserious', 'report_security').'</span>';
$strcritical = '<span class="statuscritical">'.get_string('statuscritical', 'report_security').'</span>';
$strissue = get_string('issue', 'report_security');
$strstatus = get_string('status', 'report_security');
$strdesc = get_string('description', 'report_security');
$strconfig = get_string('configuration', 'report_security');
$statusarr = array(REPORT_SECURITY_OK => $strok,
REPORT_SECURITY_INFO => $strinfo,
REPORT_SECURITY_WARNING => $strwarning,
REPORT_SECURITY_SERIOUS => $strserious,
REPORT_SECURITY_CRITICAL => $strcritical);
$url = "$CFG->wwwroot/$CFG->admin/report/security/index.php";
if ($issue and ($result = $issue(true))) {
report_security_hide_timearning();
$table = new html_table();
$table->head = array($strissue, $strstatus, $strdesc, $strconfig);
$table->size = array('30%', '10%', '50%', '10%' );
$table->align = array('left', 'left', 'left', 'left');
$table->attributes = array('class'=>'scurityreporttable generaltable');
$table->data = array();
// print detail of one issue only
$row = array();
$row[0] = report_security_doc_link($issue, $result->name);
$row[1] = $statusarr[$result->status];
$row[2] = $result->info;
$row[3] = is_null($result->link) ? '&nbsp;' : $result->link;
$PAGE->set_docs_path('admin/report/security/' . $issue);
$table->data[] = $row;
echo html_writer::table($table);
echo $OUTPUT->box($result->details, 'generalbox boxwidthnormal boxaligncenter'); // TODO: add proper css
echo $OUTPUT->continue_button($url);
} else {
report_security_hide_timearning();
$table = new html_table();
$table->head = array($strissue, $strstatus, $strdesc);
$table->size = array('30%', '10%', '60%' );
$table->align = array('left', 'left', 'left');
$table->attributes = array('class'=>'scurityreporttable generaltable');
$table->data = array();
foreach ($issues as $issue) {
$result = $issue(false);
if (!$result) {
// ignore this test
continue;
}
$row = array();
$row[0] = "<a href='$url?issue=$result->issue'>$result->name</a>";
$row[1] = $statusarr[$result->status];
$row[2] = $result->info;
$table->data[] = $row;
}
echo html_writer::table($table);
}
echo $OUTPUT->footer();
@@ -1,4 +1,5 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@@ -15,12 +16,11 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Lang strings
* Strings for component 'report_security', language 'en', branch 'MOODLE_20_STABLE'
*
* @package report
* @subpackage security
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @package report_security
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['configuration'] = 'Configuration';
+883
View File
@@ -0,0 +1,883 @@
<?php
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.org //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
// //
// This program 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 2 of the License, or //
// (at your option) any later version. //
// //
// This program 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: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
require_once("$CFG->libdir/adminlib.php");
define('REPORT_SECURITY_OK', 'ok');
define('REPORT_SECURITY_INFO', 'info');
define('REPORT_SECURITY_WARNING', 'warning');
define('REPORT_SECURITY_SERIOUS', 'serious');
define('REPORT_SECURITY_CRITICAL', 'critical');
function report_security_hide_timearning() {
global $PAGE;
$PAGE->requires->js_init_code("Y.one('#timewarning').addClass('timewarninghidden')");
}
function report_security_get_issue_list() {
return array(
'report_security_check_globals',
'report_security_check_unsecuredataroot',
'report_security_check_displayerrors',
'report_security_check_noauth',
'report_security_check_embed',
'report_security_check_mediafilterswf',
'report_security_check_openprofiles',
'report_security_check_google',
'report_security_check_passwordpolicy',
'report_security_check_passwordsaltmain',
'report_security_check_emailchangeconfirmation',
'report_security_check_cookiesecure',
'report_security_check_configrw',
'report_security_check_riskxss',
'report_security_check_riskadmin',
'report_security_check_riskbackup',
'report_security_check_defaultuserrole',
'report_security_check_guestrole',
'report_security_check_frontpagerole',
);
}
function report_security_doc_link($issue, $name) {
global $CFG, $OUTPUT;
if (empty($CFG->docroot)) {
return $name;
}
return $OUTPUT->doc_link('report/security/'.$issue, $name);
}
///=============================================
/// Issue checks
///=============================================
/**
* Verifies register globals PHP setting.
* @param bool $detailed
* @return object result
*/
function report_security_check_globals($detailed=false) {
$result = new stdClass();
$result->issue = 'report_security_check_globals';
$result->name = get_string('check_globals_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = null;
if (ini_get_bool('register_globals')) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_globals_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_globals_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_globals_details', 'report_security');
}
return $result;
}
/**
* Verifies unsupported noauth setting
* @param bool $detailed
* @return object result
*/
function report_security_check_noauth($detailed=false) {
global $CFG;
$result = new stdClass();
$result->issue = 'report_security_check_noauth';
$result->name = get_string('check_noauth_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = null;
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=manageauths\">".get_string('authsettings', 'admin').'</a>';
if (is_enabled_auth('none')) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_noauth_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_noauth_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_noauth_details', 'report_security');
}
return $result;
}
/**
* Verifies if password policy set
* @param bool $detailed
* @return object result
*/
function report_security_check_passwordpolicy($detailed=false) {
global $CFG;
$result = new stdClass();
$result->issue = 'report_security_check_passwordpolicy';
$result->name = get_string('check_passwordpolicy_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
if (empty($CFG->passwordpolicy)) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_passwordpolicy_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_passwordpolicy_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_passwordpolicy_details', 'report_security');
}
return $result;
}
/**
* Verifies sloppy embedding - this should have been removed long ago!!
* @param bool $detailed
* @return object result
*/
function report_security_check_embed($detailed=false) {
global $CFG;
$result = new stdClass();
$result->issue = 'report_security_check_embed';
$result->name = get_string('check_embed_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
if (!empty($CFG->allowobjectembed)) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_embed_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_embed_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_embed_details', 'report_security');
}
return $result;
}
/**
* Verifies sloppy swf embedding - this should have been removed long ago!!
* @param bool $detailed
* @return object result
*/
function report_security_check_mediafilterswf($detailed=false) {
global $CFG;
$result = new stdClass();
$result->issue = 'report_security_check_mediafilterswf';
$result->name = get_string('check_mediafilterswf_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=filtersettingfiltermediaplugin\">".get_string('filtersettings', 'admin').'</a>';
$activefilters = filter_get_globally_enabled();
if (array_search('filter/mediaplugin', $activefilters) !== false and !empty($CFG->filter_mediaplugin_enable_swf)) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_mediafilterswf_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_mediafilterswf_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_mediafilterswf_details', 'report_security');
}
return $result;
}
/**
* Verifies fatal misconfiguration of dataroot
* @param bool $detailed
* @return object result
*/
function report_security_check_unsecuredataroot($detailed=false) {
global $CFG;
$result = new stdClass();
$result->issue = 'report_security_check_unsecuredataroot';
$result->name = get_string('check_unsecuredataroot_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = null;
$insecuredataroot = is_dataroot_insecure(true);
if ($insecuredataroot == INSECURE_DATAROOT_WARNING) {
$result->status = REPORT_SECURITY_SERIOUS;
$result->info = get_string('check_unsecuredataroot_warning', 'report_security', $CFG->dataroot);
} else if ($insecuredataroot == INSECURE_DATAROOT_ERROR) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_unsecuredataroot_error', 'report_security', $CFG->dataroot);
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_unsecuredataroot_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_unsecuredataroot_details', 'report_security');
}
return $result;
}
/**
* Verifies displaying of errors - problem for lib files and 3rd party code
* because we can not disable debugging in these scripts (they do not include config.php)
* @param bool $detailed
* @return object result
*/
function report_security_check_displayerrors($detailed=false) {
$result = new stdClass();
$result->issue = 'report_security_check_displayerrors';
$result->name = get_string('check_displayerrors_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = null;
if (defined('WARN_DISPLAY_ERRORS_ENABLED')) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_displayerrors_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_displayerrors_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_displayerrors_details', 'report_security');
}
return $result;
}
/**
* Verifies open profiles - originally open by default, not anymore because spammer abused it a lot
* @param bool $detailed
* @return object result
*/
function report_security_check_openprofiles($detailed=false) {
global $CFG;
$result = new stdClass();
$result->issue = 'report_security_check_openprofiles';
$result->name = get_string('check_openprofiles_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
if (empty($CFG->forcelogin) and empty($CFG->forceloginforprofiles)) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_openprofiles_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_openprofiles_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_openprofiles_details', 'report_security');
}
return $result;
}
/**
* Verifies google access not combined with disabled guest access
* because attackers might gain guest access by modifying browser signature.
* @param bool $detailed
* @return object result
*/
function report_security_check_google($detailed=false) {
global $CFG;
$result = new stdClass();
$result->issue = 'report_security_check_google';
$result->name = get_string('check_google_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
if (empty($CFG->opentogoogle)) {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_google_ok', 'report_security');
} else if (!empty($CFG->guestloginbutton)) {
$result->status = REPORT_SECURITY_INFO;
$result->info = get_string('check_google_info', 'report_security');
} else {
$result->status = REPORT_SECURITY_SERIOUS;
$result->info = get_string('check_google_error', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_google_details', 'report_security');
}
return $result;
}
/**
* Verifies email confirmation - spammers were changing mails very often
* @param bool $detailed
* @return object result
*/
function report_security_check_emailchangeconfirmation($detailed=false) {
global $CFG;
$result = new stdClass();
$result->issue = 'report_security_check_emailchangeconfirmation';
$result->name = get_string('check_emailchangeconfirmation_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
if (empty($CFG->emailchangeconfirmation)) {
if (empty($CFG->allowemailaddresses)) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_emailchangeconfirmation_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_INFO;
$result->info = get_string('check_emailchangeconfirmation_info', 'report_security');
}
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_emailchangeconfirmation_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_emailchangeconfirmation_details', 'report_security');
}
return $result;
}
/**
* Verifies if https enabled only secure cookies allowed,
* this prevents redirections and sending of cookies to unsecure port.
* @param bool $detailed
* @return object result
*/
function report_security_check_cookiesecure($detailed=false) {
global $CFG;
if (strpos($CFG->wwwroot, 'https://') !== 0) {
return null;
}
$result = new stdClass();
$result->issue = 'report_security_check_cookiesecure';
$result->name = get_string('check_cookiesecure_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=httpsecurity\">".get_string('httpsecurity', 'admin').'</a>';
if (empty($CFG->cookiesecure)) {
$result->status = REPORT_SECURITY_SERIOUS;
$result->info = get_string('check_cookiesecure_error', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_cookiesecure_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_cookiesecure_details', 'report_security');
}
return $result;
}
/**
* Verifies config.php is not writable anymore after installation,
* config files were changed on several outdated server.
* @param bool $detailed
* @return object result
*/
function report_security_check_configrw($detailed=false) {
global $CFG;
$result = new stdClass();
$result->issue = 'report_security_check_configrw';
$result->name = get_string('check_configrw_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = null;
if (is_writable($CFG->dirroot.'/config.php')) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_configrw_warning', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_configrw_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_configrw_details', 'report_security');
}
return $result;
}
function report_security_check_passwordsaltmain($detailed=false) {
global $CFG;
$result = new stdClass();
$result->issue = 'report_security_check_passwordsaltmain';
$result->name = get_string('check_passwordsaltmain_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = null;
if (empty($CFG->passwordsaltmain)) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_passwordsaltmain_warning', 'report_security');
} else if ($CFG->passwordsaltmain === 'some long random string here with lots of characters'
|| trim($CFG->passwordsaltmain) === '' || preg_match('/^([a-z0-9]{0,10})$/i', $CFG->passwordsaltmain)) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_passwordsaltmain_weak', 'report_security');
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_passwordsaltmain_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_passwordsaltmain_details', 'report_security', get_docs_url('report/security/report_security_check_passwordsaltmain'));
}
return $result;
}
/**
* Lists all users with XSS risk, it would be great to combine this with risk trusts in user table,
* unfortunately nobody implemented user trust UI yet :-(
* @param bool $detailed
* @return object result
*/
function report_security_check_riskxss($detailed=false) {
global $DB;
$result = new stdClass();
$result->issue = 'report_security_check_riskxss';
$result->name = get_string('check_riskxss_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = REPORT_SECURITY_WARNING;
$result->link = null;
$params = array('capallow'=>CAP_ALLOW);
$sqlfrom = "FROM (SELECT rcx.*
FROM {role_capabilities} rcx
JOIN {capabilities} cap ON (cap.name = rcx.capability AND ".$DB->sql_bitand('cap.riskbitmask', RISK_XSS)." <> 0)
WHERE rcx.permission = :capallow) rc,
{context} c,
{context} sc,
{role_assignments} ra,
{user} u
WHERE c.id = rc.contextid
AND (sc.path = c.path OR sc.path LIKE ".$DB->sql_concat('c.path', "'/%'")." OR c.path LIKE ".$DB->sql_concat('sc.path', "'/%'").")
AND u.id = ra.userid AND u.deleted = 0
AND ra.contextid = sc.id AND ra.roleid = rc.roleid";
$count = $DB->count_records_sql("SELECT COUNT(DISTINCT u.id) $sqlfrom", $params);
$result->info = get_string('check_riskxss_warning', 'report_security', $count);
if ($detailed) {
$users = $DB->get_records_sql("SELECT DISTINCT u.id, u.firstname, u.lastname, u.picture, u.imagealt $sqlfrom", $params);
foreach ($users as $uid=>$user) {
$users[$uid] = fullname($user);
}
$users = implode(', ', $users);
$result->details = get_string('check_riskxss_details', 'report_security', $users);
}
return $result;
}
/**
* Verifies sanity of default user role.
* @param bool $detailed
* @return object result
*/
function report_security_check_defaultuserrole($detailed=false) {
global $DB, $CFG;
$result = new stdClass();
$result->issue = 'report_security_check_defaultuserrole';
$result->name = get_string('check_defaultuserrole_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=userpolicies\">".get_string('userpolicies', 'admin').'</a>';;
if (!$default_role = $DB->get_record('role', array('id'=>$CFG->defaultuserroleid))) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_defaultuserrole_notset', 'report_security');
$result->details = $result->info;
return $result;
}
// risky caps - usually very dangerous
$params = array('capallow'=>CAP_ALLOW, 'roleid'=>$default_role->id);
$sql = "SELECT COUNT(DISTINCT rc.contextid)
FROM {role_capabilities} rc
JOIN {capabilities} cap ON cap.name = rc.capability
WHERE ".$DB->sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))." <> 0
AND rc.permission = :capallow
AND rc.roleid = :roleid";
$riskycount = $DB->count_records_sql($sql, $params);
// it may have either none or 'user' archetype - nothing else, or else it would break during upgrades badly
if ($default_role->archetype === '' or $default_role->archetype === 'user') {
$legacyok = true;
} else {
$legacyok = false;
}
if ($riskycount or !$legacyok) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_defaultuserrole_error', 'report_security', format_string($default_role->name));
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_defaultuserrole_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_defaultuserrole_details', 'report_security');
}
return $result;
}
/**
* Verifies sanity of guest role
* @param bool $detailed
* @return object result
*/
function report_security_check_guestrole($detailed=false) {
global $DB, $CFG;
$result = new stdClass();
$result->issue = 'report_security_check_guestrole';
$result->name = get_string('check_guestrole_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=userpolicies\">".get_string('userpolicies', 'admin').'</a>';;
if (!$guest_role = $DB->get_record('role', array('id'=>$CFG->guestroleid))) {
$result->status = REPORT_SECURITY_WARNING;
$result->info = get_string('check_guestrole_notset', 'report_security');
$result->details = $result->info;
return $result;
}
// risky caps - usually very dangerous
$params = array('capallow'=>CAP_ALLOW, 'roleid'=>$guest_role->id);
$sql = "SELECT COUNT(DISTINCT rc.contextid)
FROM {role_capabilities} rc
JOIN {capabilities} cap ON cap.name = rc.capability
WHERE ".$DB->sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))." <> 0
AND rc.permission = :capallow
AND rc.roleid = :roleid";
$riskycount = $DB->count_records_sql($sql, $params);
// it may have either no or 'guest' archetype - nothing else, or else it would break during upgrades badly
if ($guest_role->archetype === '' or $guest_role->archetype === 'guest') {
$legacyok = true;
} else {
$legacyok = false;
}
if ($riskycount or !$legacyok) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_guestrole_error', 'report_security', format_string($guest_role->name));
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_guestrole_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_guestrole_details', 'report_security');
}
return $result;
}
/**
* Verifies sanity of frontpage role
* @param bool $detailed
* @return object result
*/
function report_security_check_frontpagerole($detailed=false) {
global $DB, $CFG;
$result = new stdClass();
$result->issue = 'report_security_check_frontpagerole';
$result->name = get_string('check_frontpagerole_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=frontpagesettings\">".get_string('frontpagesettings','admin').'</a>';;
if (!$frontpage_role = $DB->get_record('role', array('id'=>$CFG->defaultfrontpageroleid))) {
$result->status = REPORT_SECURITY_INFO;
$result->info = get_string('check_frontpagerole_notset', 'report_security');
$result->details = get_string('check_frontpagerole_details', 'report_security');
return $result;
}
// risky caps - usually very dangerous
$params = array('capallow'=>CAP_ALLOW, 'roleid'=>$frontpage_role->id);
$sql = "SELECT COUNT(DISTINCT rc.contextid)
FROM {role_capabilities} rc
JOIN {capabilities} cap ON cap.name = rc.capability
WHERE ".$DB->sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))." <> 0
AND rc.permission = :capallow
AND rc.roleid = :roleid";
$riskycount = $DB->count_records_sql($sql, $params);
// there is no legacy role type for frontpage yet - anyway we can not allow teachers or admins there!
if ($frontpage_role->archetype === 'teacher' or $frontpage_role->archetype === 'editingteacher'
or $frontpage_role->archetype === 'coursecreator' or $frontpage_role->archetype === 'manager') {
$legacyok = false;
} else {
$legacyok = true;
}
if ($riskycount or !$legacyok) {
$result->status = REPORT_SECURITY_CRITICAL;
$result->info = get_string('check_frontpagerole_error', 'report_security', format_string($frontpage_role->name));
} else {
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_frontpagerole_ok', 'report_security');
}
if ($detailed) {
$result->details = get_string('check_frontpagerole_details', 'report_security');
}
return $result;
}
/**
* Lists all admins.
* @param bool $detailed
* @return object result
*/
function report_security_check_riskadmin($detailed=false) {
global $DB, $CFG;
$result = new stdClass();
$result->issue = 'report_security_check_riskadmin';
$result->name = get_string('check_riskadmin_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = null;
$sql = "SELECT u.id, u.firstname, u.lastname, u.picture, u.imagealt, u.email
FROM {user} u
WHERE u.id IN ($CFG->siteadmins)";
$admins = $DB->get_records_sql($sql);
$admincount = count($admins);
if ($detailed) {
foreach ($admins as $uid=>$user) {
$url = "$CFG->wwwroot/user/view.php?id=$user->id";
$admins[$uid] = '<li><a href="'.$url.'">'.fullname($user).' ('.$user->email.')</a></li>';
}
$admins = '<ul>'.implode($admins).'</ul>';
}
$result->status = REPORT_SECURITY_OK;
$result->info = get_string('check_riskadmin_ok', 'report_security', $admincount);
if ($detailed) {
$result->details = get_string('check_riskadmin_detailsok', 'report_security', $admins);
}
return $result;
}
/**
* Lists all roles that have the ability to backup user data, as well as users
* @param bool $detailed
* @return object result
*/
function report_security_check_riskbackup($detailed=false) {
global $CFG, $DB;
$result = new stdClass();
$result->issue = 'report_security_check_riskbackup';
$result->name = get_string('check_riskbackup_name', 'report_security');
$result->info = null;
$result->details = null;
$result->status = null;
$result->link = null;
$syscontext = get_context_instance(CONTEXT_SYSTEM);
$params = array('capability'=>'moodle/backup:userinfo', 'permission'=>CAP_ALLOW, 'contextid'=>$syscontext->id);
$sql = "SELECT DISTINCT r.id, r.name, r.shortname, r.sortorder, r.archetype
FROM {role} r
JOIN {role_capabilities} rc ON rc.roleid = r.id
WHERE rc.capability = :capability
AND rc.contextid = :contextid
AND rc.permission = :permission";
$systemroles = $DB->get_records_sql($sql, $params);
$params = array('capability'=>'moodle/backup:userinfo', 'permission'=>CAP_ALLOW, 'contextid'=>$syscontext->id);
$sql = "SELECT DISTINCT r.id, r.name, r.shortname, r.sortorder, r.archetype, rc.contextid
FROM {role} r
JOIN {role_capabilities} rc ON rc.roleid = r.id
WHERE rc.capability = :capability
AND rc.contextid <> :contextid
AND rc.permission = :permission";
$overriddenroles = $DB->get_records_sql($sql, $params);
// list of users that are able to backup personal info
// note: "sc" is context where is role assigned,
// "c" is context where is role overridden or system context if in role definition
$params = array('capability'=>'moodle/backup:userinfo', 'permission'=>CAP_ALLOW, 'context1'=>CONTEXT_COURSE, 'context2'=>CONTEXT_COURSE);
$sqluserinfo = "
FROM (SELECT rcx.*
FROM {role_capabilities} rcx
WHERE rcx.permission = :permission AND rcx.capability = :capability) rc,
{context} c,
{context} sc,
{role_assignments} ra,
{user} u
WHERE c.id = rc.contextid
AND (sc.path = c.path OR sc.path LIKE ".$DB->sql_concat('c.path', "'/%'")." OR c.path LIKE ".$DB->sql_concat('sc.path', "'/%'").")
AND u.id = ra.userid AND u.deleted = 0
AND ra.contextid = sc.id AND ra.roleid = rc.roleid
AND sc.contextlevel <= :context1 AND c.contextlevel <= :context2";
$usercount = $DB->count_records_sql("SELECT COUNT('x') FROM (SELECT DISTINCT u.id $sqluserinfo) userinfo", $params);
$systemrolecount = empty($systemroles) ? 0 : count($systemroles);
$overriddenrolecount = empty($overriddenroles) ? 0 : count($overriddenroles);
$result->status = REPORT_SECURITY_WARNING; // there is always at least one admin
$a = (object)array('rolecount'=>$systemrolecount,'overridecount'=>$overriddenrolecount,'usercount'=>$usercount);
$result->info = get_string('check_riskbackup_warning', 'report_security', $a);
if ($detailed) {
$result->details = ''; // Will be added to later
// Make a list of roles
if ($systemroles) {
$links = array();
foreach ($systemroles as $role) {
$role->url = "$CFG->wwwroot/$CFG->admin/roles/manage.php?action=edit&amp;roleid=$role->id";
$links[] = '<li>'.get_string('check_riskbackup_editrole', 'report_security', $role).'</li>';
}
$links = '<ul>'.implode($links).'</ul>';
$result->details .= get_string('check_riskbackup_details_systemroles', 'report_security', $links);
}
// Make a list of overrides to roles
$rolelinks2 = array();
if ($overriddenroles) {
$links = array();
foreach ($overriddenroles as $role) {
$context = get_context_instance_by_id($role->contextid);
if ($context->contextlevel == CONTEXT_COURSE) {
$role->name = role_get_name($role, $context);
}
$role->contextname = print_context_name($context);
$role->url = "$CFG->wwwroot/$CFG->admin/roles/override.php?contextid=$role->contextid&amp;roleid=$role->id";
$links[] = '<li>'.get_string('check_riskbackup_editoverride', 'report_security', $role).'</li>';
}
$links = '<ul>'.implode($links).'</ul>';
$result->details .= get_string('check_riskbackup_details_overriddenroles', 'report_security', $links);
}
// Get a list of affected users as well
$users = array();
$rs = $DB->get_recordset_sql("SELECT DISTINCT u.id, u.firstname, u.lastname, u.picture, u.imagealt, u.email, ra.contextid, ra.roleid
$sqluserinfo ORDER BY u.lastname, u.firstname", $params);
foreach ($rs as $user) {
$context = get_context_instance_by_id($user->contextid);
$url = "$CFG->wwwroot/$CFG->admin/roles/assign.php?contextid=$user->contextid&amp;roleid=$user->roleid";
$a = (object)array('fullname'=>fullname($user), 'url'=>$url, 'email'=>$user->email,
'contextname'=>print_context_name($context));
$users[] = '<li>'.get_string('check_riskbackup_unassign', 'report_security', $a).'</li>';
}
if (!empty($users)) {
$users = '<ul>'.implode($users).'</ul>';
$result->details .= get_string('check_riskbackup_details_users', 'report_security', $users);
}
}
return $result;
}
+5
View File
@@ -0,0 +1,5 @@
<?php
defined('MOODLE_INTERNAL') || die;
$ADMIN->add('reports', new admin_externalpage('reportsecurity', get_string('pluginname', 'report_security'), "$CFG->wwwroot/$CFG->admin/report/security/index.php",'report/security:view'));
+27
View File
@@ -0,0 +1,27 @@
<?PHP
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
// //
// This program 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 2 of the License, or //
// (at your option) any later version. //
// //
// This program 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: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
$plugin->version = 2010090501;
$plugin->requires = 2010090501;
+286
View File
@@ -0,0 +1,286 @@
<?php
/**
* Spam Cleaner
*
* Helps an admin to clean up spam in Moodle
*
* @authors Dongsheng Cai, Martin Dougiamas, Amr Hourani
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
*/
// List of known spammy keywords, please add more here
/////////////////////////////////////////////////////////////////////////////////
require_once('../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
// Configuration
$autokeywords = array(
"<img",
"fuck",
"casino",
"porn",
"xxx",
"cialis",
"viagra",
"poker",
"warcraft"
);
$keyword = optional_param('keyword', '', PARAM_RAW);
$autodetect = optional_param('autodetect', '', PARAM_RAW);
$del = optional_param('del', '', PARAM_RAW);
$delall = optional_param('delall', '', PARAM_RAW);
$ignore = optional_param('ignore', '', PARAM_RAW);
$reset = optional_param('reset', '', PARAM_RAW);
$id = optional_param('id', '', PARAM_INT);
require_login();
admin_externalpage_setup('reportspamcleaner');
// Delete one user
if (!empty($del) && confirm_sesskey() && ($id != $USER->id)) {
if (isset($SESSION->users_result[$id])) {
$user = $SESSION->users_result[$id];
if (delete_user($user)) {
unset($SESSION->users_result[$id]);
echo json_encode(true);
} else {
echo json_encode(false);
}
} else {
echo json_encode(false);
}
exit;
}
// Delete lots of users
if (!empty($delall) && confirm_sesskey()) {
if (!empty($SESSION->users_result)) {
foreach ($SESSION->users_result as $userid => $user) {
if ($userid != $USER->id) {
if (delete_user($user)) {
unset($SESSION->users_result[$userid]);
}
}
}
}
echo json_encode(true);
exit;
}
if (!empty($ignore)) {
unset($SESSION->users_result[$id]);
echo json_encode(true);
exit;
}
$PAGE->requires->js_init_call('M.report_spamcleaner.init', array(me()), true);
$strings = Array('spaminvalidresult','spamdeleteallconfirm','spamcannotdelete','spamdeleteconfirm');
$PAGE->requires->strings_for_js($strings, 'report_spamcleaner');
echo $OUTPUT->header();
// Print headers and things
echo $OUTPUT->box(get_string('spamcleanerintro', 'report_spamcleaner'));
echo $OUTPUT->box_start(); // The forms section at the top
?>
<div class="mdl-align">
<form method="post" action="index.php">
<div>
<input type="text" name="keyword" id="keyword_el" value="<?php p($keyword) ?>" />
<input type="hidden" name="sesskey" value="<?php echo sesskey();?>" />
<input type="submit" value="<?php echo get_string('spamsearch', 'report_spamcleaner')?>" />
</div>
</form>
<p><?php echo get_string('spameg', 'report_spamcleaner');?></p>
<hr />
<form method="post" action="index.php">
<div>
<input type="submit" name="autodetect" value="<?php echo get_string('spamauto', 'report_spamcleaner');?>" />
</div>
</form>
</div>
<?php
echo $OUTPUT->box_end();
echo '<div id="result" class="mdl-align">';
// Print list of resulting profiles
if (!empty($keyword)) { // Use the keyword(s) supplied by the user
$keywords = explode(',', $keyword);
foreach ($keywords as $key => $keyword) {
$keywords[$key] = trim($keyword);
}
search_spammers($keywords);
} else if (!empty($autodetect)) { // Use the inbuilt keyword list to detect users
search_spammers($autokeywords);
}
echo '</div>';
/////////////////////////////////////////////////////////////////////////////////
/// Functions
function search_spammers($keywords) {
global $CFG, $USER, $DB, $OUTPUT;
if (!is_array($keywords)) {
$keywords = array($keywords); // Make it into an array
}
$params = array('userid'=>$USER->id);
$keywordfull = array();
$i = 0;
foreach ($keywords as $keyword) {
$keywordfull[] = $DB->sql_like('description', ':descpat'.$i, false);
$params['descpat'.$i] = "%$keyword%";
$keywordfull2[] = $DB->sql_like('p.summary', ':sumpat'.$i, false);
$params['sumpat'.$i] = "%$keyword%";
$i++;
}
$conditions = '( '.implode(' OR ', $keywordfull).' )';
$conditions2 = '( '.implode(' OR ', $keywordfull2).' )';
$sql = "SELECT * FROM {user} WHERE deleted = 0 AND id <> :userid AND $conditions"; // Exclude oneself
$sql2 = "SELECT u.*, p.summary FROM {user} AS u, {post} AS p WHERE $conditions2 AND u.deleted = 0 AND u.id=p.userid AND u.id <> :userid";
$spamusers_desc = $DB->get_recordset_sql($sql, $params);
$spamusers_blog = $DB->get_recordset_sql($sql2, $params);
$keywordlist = implode(', ', $keywords);
echo $OUTPUT->box(get_string('spamresult', 'report_spamcleaner').s($keywordlist)).' ...';
print_user_list(array($spamusers_desc, $spamusers_blog), $keywords);
}
function print_user_list($users_rs, $keywords) {
global $CFG, $SESSION;
// reset session everytime this function is called
$SESSION->users_result = array();
$count = 0;
foreach ($users_rs as $rs){
foreach ($rs as $user) {
if (!$count) {
echo '<table border="1" width="100%" id="data-grid"><tr><th>&nbsp;</th><th>'.get_string('user','admin').'</th><th>'.get_string('spamdesc', 'report_spamcleaner').'</th><th>'.get_string('spamoperation', 'report_spamcleaner').'</th></tr>';
}
$count++;
filter_user($user, $keywords, $count);
}
}
if (!$count) {
echo get_string('spamcannotfinduser', 'report_spamcleaner');
} else {
echo '</table>';
echo '<div class="mld-align">
<button id="removeall_btn">'.get_string('spamdeleteall', 'report_spamcleaner').'</button>
</div>';
}
}
function filter_user($user, $keywords, $count) {
global $CFG;
$image_search = false;
if (in_array('<img', $keywords)) {
$image_search = true;
}
if (isset($user->summary)) {
$user->description = '<h3>'.get_string('spamfromblog', 'report_spamcleaner').'</h3>'.$user->summary;
unset($user->summary);
}
if (preg_match('#<img.*src=[\"\']('.$CFG->wwwroot.')#', $user->description, $matches)
&& $image_search) {
$result = false;
foreach ($keywords as $keyword) {
if (preg_match('#'.$keyword.'#', $user->description)
&& ($keyword != '<img')) {
$result = true;
}
}
if ($result) {
echo print_user_entry($user, $keywords, $count);
} else {
unset($user);
}
} else {
echo print_user_entry($user, $keywords, $count);
}
}
function print_user_entry($user, $keywords, $count) {
global $SESSION, $CFG;
$smalluserobject = new stdClass(); // All we need to delete them later
$smalluserobject->id = $user->id;
$smalluserobject->email = $user->email;
$smalluserobject->auth = $user->auth;
$smalluserobject->firstname = $user->firstname;
$smalluserobject->lastname = $user->lastname;
$smalluserobject->username = $user->username;
if (empty($SESSION->users_result[$user->id])) {
$SESSION->users_result[$user->id] = $smalluserobject;
$html = '<tr valign="top" id="row-'.$user->id.'" class="result-row">';
$html .= '<td width="10">'.$count.'</td>';
$html .= '<td width="30%" align="left"><a href="'.$CFG->wwwroot."/user/view.php?course=1&amp;id=".$user->id.'" title="'.s($user->username).'">'.fullname($user).'</a>';
$html .= "<ul>";
$profile_set = array('city'=>true, 'country'=>true, 'email'=>true);
foreach ($profile_set as $key=>$value) {
if (isset($user->$key)){
$html .= '<li>'.$user->$key.'</li>';
}
}
$html .= "</ul>";
$html .= '</td>';
foreach ($keywords as $keyword) {
$user->description = highlight($keyword, $user->description);
}
if (!isset($user->descriptionformat)) {
$user->descriptionformat = FORMAT_MOODLE;
}
$html .= '<td align="left">'.format_text($user->description, $user->descriptionformat, array('overflowdiv'=>true)).'</td>';
$html .= '<td width="100px" align="center">';
$html .= '<button onclick="M.report_spamcleaner.del_user(this,'.$user->id.')">'.get_string('deleteuser', 'admin').'</button><br />';
$html .= '<button onclick="M.report_spamcleaner.ignore_user(this,'.$user->id.')">'.get_string('ignore', 'admin').'</button>';
$html .= '</td>';
$html .= '</tr>';
return $html;
} else {
return null;
}
}
echo $OUTPUT->footer();
@@ -0,0 +1,40 @@
<?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/>.
/**
* Strings for component 'report_spamcleaner', language 'en', branch 'MOODLE_20_STABLE'
*
* @package report_spamcleaner
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'Spam cleaner';
$string['spamauto'] = 'Autodetect common spam patterns';
$string['spamcannotdelete'] = 'Cannot delete this user';
$string['spamcannotfinduser'] = 'No users matching your search';
$string['spamcleanerintro'] = 'This script allows you to search all user profiles for certain strings and then delete those accounts which are obviously created by spammers. You can search for multiple keywords using commas (eg casino, porn)<br /><br />Moodle docs has more information about <a href="http://docs.moodle.org/en/Reducing_spam_in_Moodle">Reducing spam in Moodle</a>.';
$string['spamdeleteall'] = 'Delete all these user accounts';
$string['spamdeleteallconfirm'] = 'Are you sure you want to delete all these user accounts? You can not undo this.';
$string['spamdeleteconfirm'] = 'Are you sure you want to delete this entry? You can not undo this.';
$string['spamdesc'] = 'Description';
$string['spameg'] = 'eg: casino, porn, xxx';
$string['spamfromblog'] = 'From blog post:';
$string['spaminvalidresult'] = 'Unknown but invalid result';
$string['spamoperation'] = 'Operation';
$string['spamresult'] = 'Results of searching user profiles containing:';
$string['spamsearch'] = 'Search for these keywords';
+115
View File
@@ -0,0 +1,115 @@
M.report_spamcleaner = {
Y: null,
row: null,
me: null,
del_all: function() {
var context = M.report_spamcleaner;
var yes = confirm(M.str.report_spamcleaner.spamdeleteallconfirm);
if (yes) {
var cfg = {
method: "POST",
on: {
success : function(id, o, args) {
try {
var resp = context.Y.JSON.parse(o.responseText);
} catch(e) {
alert(M.str.report_spamcleaner.spaminvalidresult);
return;
}
if (resp == true) {
window.location.href=window.location.href;
}
}
}
};
context.Y.io(context.me+'?delall=yes&sesskey='+M.cfg.sesskey, cfg);
}
},
del_user: function(obj, id) {
var context = M.report_spamcleaner;
if (context.Y == null) {
// not initialised yet
return;
}
var yes = confirm(M.str.report_spamcleaner.spamdeleteconfirm);
if (yes) {
context.row = obj;
var cfg = {
method: "POST",
on: {
success : function(id, o, args) {
try {
var resp = context.Y.JSON.parse(o.responseText);
} catch(e) {
alert(M.str.report_spamcleaner.spaminvalidresult);
return;
}
if (context.row) {
if (resp == true) {
while(context.row.tagName != 'TR') {
context.row = context.row.parentNode;
}
context.row.parentNode.removeChild(context.row);
context.row = null;
} else {
alert(M.str.report_spamcleaner.spamcannotdelete);
}
}
}
}
}
context.Y.io(context.me+'?del=yes&sesskey='+M.cfg.sesskey+'&id='+id, cfg);
}
},
ignore_user: function(obj, id) {
var context = M.report_spamcleaner;
if (context.Y == null) {
// not initilised yet
return;
}
context.row = obj;
var cfg = {
method: "POST",
on: {
success : function(id, o, args) {
try {
var resp = context.Y.JSON.parse(o.responseText);
} catch(e) {
alert(M.str.report_spamcleaner.spaminvalidresult);
return;
}
if (context.row) {
if (resp == true){
while(context.row.tagName != 'TR') {
context.row = context.row.parentNode;
}
context.row.parentNode.removeChild(context.row);
context.row = null;
}
}
}
}
}
context.Y.io(context.me+'?ignore=yes&sesskey='+M.cfg.sesskey+'&id='+id, cfg);
},
init: function(Y, me) {
var context = M.report_spamcleaner;
Y.use('json', 'io', function (Y) {
context.Y = Y;
context.me = me;
if (Y.one("#removeall_btn")) {
Y.on("click", context.del_all, "#removeall_btn");
}
});
}
}
+7
View File
@@ -0,0 +1,7 @@
<?php
defined('MOODLE_INTERNAL') || die;
// spam cleaner
$ADMIN->add('reports', new admin_externalpage('reportspamcleaner', get_string('pluginname', 'report_spamcleaner'), "$CFG->wwwroot/$CFG->admin/report/spamcleaner/index.php", 'moodle/site:config'));
+6
View File
@@ -0,0 +1,6 @@
<?php
defined('MOODLE_INTERNAL') || die;
// just a link to course report
$ADMIN->add('reports', new admin_externalpage('reportstats', get_string('stats', 'admin'), "$CFG->wwwroot/course/report/stats/index.php", 'coursereport/stats:view'));
@@ -1,4 +1,5 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@@ -20,8 +21,8 @@
* Syntax: coveragefile.php/path/to/file/file.html
* coveragefile.php?file=path/to/file/file.html
*
* @package tool
* @subpackage unittest
* @package moodlecore
* @subpackage simpletestcoverage
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -29,12 +30,12 @@
// disable moodle specific debug messages and any errors in output
define('NO_DEBUG_DISPLAY', true);
require(dirname(__FILE__) . '/../../../config.php');
require_once(dirname(__FILE__) . '/../../../config.php');
require_once($CFG->libdir . '/filelib.php');
// basic security, require login + require site config cap
require_login();
require_capability('tool/unittest:execute', get_context_instance(CONTEXT_SYSTEM));
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
// get file requested
$relativepath = get_file_argument();
+38
View File
@@ -0,0 +1,38 @@
<?php
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
// //
// This program 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 2 of the License, or //
// (at your option) any later version. //
// //
// This program 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: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
$capabilities = array(
'report/unittest:view' => array(
'riskbitmask' => RISK_DATALOSS,
'captype' => 'read',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:config',
)
);
@@ -1,43 +1,23 @@
<?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/>.
/**
* Run database functional tests.
*
* @package tool
* @subpackage unittest
* @copyright 2008 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @package SimpleTestEx
*/
define('NO_OUTPUT_BUFFERING', true);
require(dirname(__FILE__) . '/../../../config.php');
require_once(dirname(__FILE__).'/../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once('simpletestlib.php');
require_once('simpletestcoveragelib.php');
require_once($CFG->libdir.'/simpletestcoveragelib.php');
require_once('ex_simple_test.php');
require_once('ex_reporter.php');
$showpasses = optional_param('showpasses', false, PARAM_BOOL);
$codecoverage = optional_param('codecoverage', false, PARAM_BOOL);
$selected = optional_param_array('selected', array(), PARAM_INT);
$selected = optional_param('selected', array(), PARAM_INT);
// Print the header and check access.
admin_externalpage_setup('tooldbtest');
admin_externalpage_setup('reportdbtest');
echo $OUTPUT->header();
global $UNITTEST;
@@ -128,11 +108,11 @@ echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
echo '<form method="post" action="dbtest.php">';
echo '<div>';
echo $OUTPUT->heading("Run functional database tests"); // TODO: localise
echo '<p>'.html_writer::checkbox('showpasses', 1, $showpasses, get_string('showpasses', 'tool_unittest')).'</p>';
echo '<p>'.html_writer::checkbox('showpasses', 1, $showpasses, get_string('showpasses', 'simpletest')).'</p>';
if (moodle_coverage_recorder::can_run_codecoverage()) {
echo '<p>'.html_writer::checkbox('codecoverage', 1, $codecoverage, get_string('codecoverageanalysis', 'tool_unittest')).'</p>';
echo '<p>'.html_writer::checkbox('codecoverage', 1, $codecoverage, get_string('codecoverageanalysis', 'simpletest')).'</p>';
} else {
echo '<p>'; print_string('codecoveragedisabled', 'tool_unittest'); echo '<input type="hidden" name="codecoverage" value="0" /></p>';
echo '<p>'; print_string('codecoveragedisabled', 'simpletest'); echo '<input type="hidden" name="codecoverage" value="0" /></p>';
}
echo '<p><strong>'."Databases:".'</strong></p>';
echo '<ul>';
@@ -154,7 +134,7 @@ $CFG->func_test_db_1 = array("native", "pgsql", "localhost", "moodleuser", "pass
$CFG->func_test_db_2 = array("native", "mssql", "localhost", "moodleuser", "password", "moodle", "test", null);
</pre>
<p>where order of parameters is: dblibrary, dbtype, dbhost, dbuser, dbpass, dbname, prefix, dboptions</p>';
echo '<p><input type="submit" value="' . get_string('runtests', 'tool_unittest') . '" /></p>';
echo '<p><input type="submit" value="' . get_string('runtests', 'simpletest') . '" /></p>';
echo '</div>';
echo '</form>';
echo $OUTPUT->box_end();
@@ -1,27 +1,11 @@
<?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/>.
/**
* A SimpleTest report format for Moodle.
*
* @package tool
* @subpackage unittest
* @copyright &copy; 2006 The Open University
* @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright &copy; 2006 The Open University
* @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package SimpleTestEx
*/
if (!defined('MOODLE_INTERNAL')) {
@@ -180,7 +164,7 @@ class ExHtmlReporter extends HtmlReporter {
foreach ($stacktrace as $frame) {
if (empty($frame['file']) || (strpos($frame['file'], 'simpletestlib') === false &&
strpos($frame['file'], 'simpletestcoveragelib') === false
&& strpos($frame['file'], 'tool/unittest') === false)) {
&& strpos($frame['file'], 'report/unittest') === false)) {
$filteredstacktrace[] = $frame;
$interestinglines += 1;
$dotsadded = false;
@@ -287,11 +271,6 @@ class ExHtmlReporter extends HtmlReporter {
* Look up a lang string in the appropriate file.
*/
function get_string($identifier, $a = NULL) {
return get_string($identifier, 'tool_unittest', $a);
}
function _htmlEntities($message) {
// Override subclass message that breaks UTF8.
return s($message);
return get_string($identifier, 'simpletest', $a);
}
}
@@ -1,28 +1,12 @@
<?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/>.
/**
* A SimpleTest GroupTest that automatically finds all the
* test files in a directory tree according to certain rules.
*
* @package tool
* @subpackage unittest
* @copyright &copy; 2006 The Open University
* @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright &copy; 2006 The Open University
* @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package SimpleTestEx
*/
if (!defined('MOODLE_INTERNAL')) {
+136
View File
@@ -0,0 +1,136 @@
<?php
/**
* Run the unit tests.
*
* @copyright &copy; 2006 The Open University
* @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package SimpleTestEx
*/
define('NO_OUTPUT_BUFFERING', true);
require_once(dirname(__FILE__).'/../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/simpletestcoveragelib.php');
require_once('ex_simple_test.php');
require_once('ex_reporter.php');
// Always run the unit tests in developer debug mode.
$CFG->debug = DEBUG_DEVELOPER;
error_reporting($CFG->debug);
raise_memory_limit(MEMORY_EXTRA);
// page parameters
$path = optional_param('path', null, PARAM_PATH);
$showpasses = optional_param('showpasses', false, PARAM_BOOL);
$codecoverage = optional_param('codecoverage', false, PARAM_BOOL);
$showsearch = optional_param('showsearch', false, PARAM_BOOL);
admin_externalpage_setup('reportsimpletest', '', array('showpasses'=>$showpasses, 'showsearch'=>$showsearch));
$unittest = true;
global $UNITTEST;
$UNITTEST = new stdClass();
// This limit is the time allowed per individual test function. Please do not
// increase this value. If you get a PHP time limit when running unit tests,
// find the unit test which is running slowly, and either make it faster,
// split it into multiple tests, or call set_time_limit within that test.
define('TIME_ALLOWED_PER_UNIT_TEST', 60);
// Print the header.
$strtitle = get_string('unittests', 'simpletest');
if (!is_null($path)) {
//trim so user doesn't get an error if they include a space on the end of the path (ie by pasting path)
$path = trim($path);
// Turn off xmlstrictheaders during the unit test run.
$origxmlstrictheaders = !empty($CFG->xmlstrictheaders);
$CFG->xmlstrictheaders = false;
echo $OUTPUT->header();
$CFG->xmlstrictheaders = $origxmlstrictheaders;
unset($origxmlstrictheaders);
// Create the group of tests.
$test = new autogroup_test_coverage($showsearch, true, $codecoverage, 'Moodle Unit Tests Code Coverage Report', 'unittest');
// OU specific. We use the _nonproject folder for stuff we want to
// keep in CVS, but which is not really relevant. It does no harm
// to leave this here.
$test->addIgnoreFolder($CFG->dirroot . '/_nonproject');
// Make the reporter, which is what displays the results.
$reporter = new ExHtmlReporter($showpasses);
if ($showsearch) {
echo $OUTPUT->heading('Searching for test cases');
}
flush();
// Work out what to test.
if (substr($path, 0, 1) == '/') {
$path = substr($path, 1);
}
$path = $CFG->dirroot . '/' . $path;
if (substr($path, -1) == '/') {
$path = substr($path, 0, -1);
}
$displaypath = substr($path, strlen($CFG->dirroot) + 1);
$ok = true;
if (is_file($path)) {
$test->addTestFile($path);
} else if (is_dir($path)){
$test->findTestFiles($path);
} else {
echo $OUTPUT->box(get_string('pathdoesnotexist', 'simpletest', $path), 'errorbox');
$ok = false;
}
// If we have something to test, do it.
if ($ok) {
if ($path == $CFG->dirroot) {
$title = get_string('moodleunittests', 'simpletest', get_string('all', 'simpletest'));
} else {
$title = get_string('moodleunittests', 'simpletest', $displaypath);
}
echo $OUTPUT->heading($title);
$test->run($reporter);
}
$formheader = get_string('retest', 'simpletest');
} else {
$displaypath = '';
echo $OUTPUT->header();
$formheader = get_string('rununittests', 'simpletest');
}
// Print the form for adjusting options.
echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
echo $OUTPUT->heading($formheader);
echo '<form method="get" action="index.php">';
echo '<fieldset class="invisiblefieldset">';
echo '<p>'.html_writer::checkbox('showpasses', 1, $showpasses, get_string('showpasses', 'simpletest')).'</p>';
echo '<p>'.html_writer::checkbox('showsearch', 1, $showsearch, get_string('showsearch', 'simpletest')).'</p>';
if (moodle_coverage_recorder::can_run_codecoverage()) {
echo '<p>'.html_writer::checkbox('codecoverage', 1, $codecoverage, get_string('codecoverageanalysis', 'simpletest')).'</p>';
} else {
echo '<p>'; print_string('codecoveragedisabled', 'simpletest'); echo '<input type="hidden" name="codecoverage" value="0" /></p>';
}
echo '<p>';
echo '<label for="path">', get_string('onlytest', 'simpletest'), '</label> ';
echo '<input type="text" id="path" name="path" value="', $displaypath, '" size="40" />';
echo '</p>';
echo '<input type="submit" value="' . get_string('runtests', 'simpletest') . '" />';
echo '</fieldset>';
echo '</form>';
echo $OUTPUT->box_end();
// Print link to latest code coverage for this report type
if (is_null($path) || !$codecoverage) {
moodle_coverage_reporter::print_link_to_latest('unittest');
}
// Footer.
echo $OUTPUT->footer();

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