This is part 1 that does the back-end:
1. New table role_allow_switch.
2. Upgrade that copies all the allows from role_allow_assign, and then drops the old CFG->allowuserswitchrolestheycantassign.
3. Old function get_assignable_roles_for_switchrole renamed to get_switchable_roles and changed to use the new table. Fixes MDL-18604 in HEAD.
4. Switch callers to use the new function name.
5. Unit tests for this new function.
6. To make those unit tests work, new switch_global_user_id and revert_global_user_id methods in UnitTestCaseUsingDatabase for toggling $USER->id.
I still need to do the editing interface under Administration ► Users ► Permissions ► Define roles. That will be done as a second commit.
I did not fix all the DB problems in search, there are too many there for me to be prepared to clean up other people's mess.
(For once, it was not me making this mistake ;-))
Instead we have a new $ACCESSLIB_PRIVATE for all caching. Regrettably, the only way to make this work in PHP (other than rewriting everything to be methods of a class rather than functions) is to make this a global variable. However $ACCESSLIB_PRIVATE should not be thought of a global, it is a private implementation detail of accesslib.php. (And there is a comment saying that.)
There is a new function accesslib_clear_all_caches_for_unit_testing(). In a unit test, you need to call this at the start of your test method, before you set up any test data, and again at the end, after you have discarded all your test data.
This new $ACCESSLIB_PRIVATE subsumes the old $ACCESS, $RDEFS and $DITRYCONTEXTS globals.
Also, I took the opportunity to refactor the (inconsistently) duplicated code for adding a context to the caches code into a cache_context function.
MDL-17647 was referring to moodle/site:candoanything insstead of moodle/site:doanything
MDL-17648 Let get_users_by_capability take an array of capabilities, like has_any_capability
MDL-17649 get_users_by_capability must have unit tests (HEAD only).
The unit tests were briefly working (apart from the system context, which I had to set up by hand in the test contexts table). Then I made the mistake of trying to upgrade the test tables, and it all went horribly wrong (MDL-17644).
* Note: this would never lead to problems with default role definions.
* Also ended up mostly rewriting delete_category_form to simplify the messages that are displayed.
* New helper function require_all_capabilities, a bit like require_any_capability.
Bugs: MDL-17479, MDL-16426, MDL-16063, MDL-16013, MDL-15658, MDL-15556, MDL-15161, MDL-14925, MDL-13742, MDL-11557.
* Simplify category editing permissions to just moodle/category:manage and moodle/category:seehiddencategories.
* Enforce those correctly. (Note MDL 17502 is still outstanding.)
* Don't screw up category sort order when you just edit name or description.
* Niceties like where redirects go when you cancel or submit forms.
* Make sure a global course creator can see the site admin block.
* Don't allow a category to be made the child of one of its children!
* General code cleanup to bring key files more in line with best pracitice.
Apologies for the fact it is one big patch, rather than a series of smaller patches. However, categoryedit.php, category.php and index.php where in pretty bad shape and needed significant cleaning up. categoryedit.php, in particular, was almost completely rewritten.
Merged from MOODLE_19_STABLE.
* Move the show/hide advanced button a bit down the page.
* Improve save button caption when creating a role.
* Don't show defaults on the basic define roles screen.
* Explain the background shading on the advanced roels screen.
* Fix the problem with the risks link to Moodle docs.
* Help icon by the permissions column heading.
* Tables with rotated <th>s, make them vertical-align: bottom.
* Rename explain.php and explainhascapability.php to check.php and explain.php
* Tool tips on the number headers in the explain table.
* Explain table - role names were missing.
* Allow link_to_popup_window to work with full URLs.
* New basic define roles mode, with just an Allow checkbox for each capability.
* Button to toggle this form to/from advanced mode.
* Also, a separate mode for viewing a role definition, rather than just showing disabled checkboxes.
* Now duplicating a role just takes to you a pre-populated add role form, so you can double-check things before saving the new role.
* Deleting a role is now logged.
* Role reordering code cleaned up.
* You can now no longer delete the last role that has admin permissions.
* This includes a general refactor of manage.php, which eliminates manage.html, and splits of define.php.
I have collected code that used to be in lib/adminlib.php, lib/accesslib.php and user/selector/lib.php into a new admin/roles/lib.php file.
And I added standard GPL and Moodle comments to all the files in admin/roles.
* New table role_context_levels
* Populate table with defaults on install
* Populate table on upgrade with the same defaults, plus any additional ones needed to ensure all the role assignments already in the database are allowed.
* Change get_assignable_roles to respect these settings.
* UI for these settings on the add/edit role form.
* Save these settings when a role definition is saved.
* If in a context, there are no roles you can assign, display a polite message.
* Back up these settings.
* Restore these settings. When resotring a <=1.9.x backup file, any newly imported roles are set to be assignable at all contextlevels.
Restore not tested because it is broken in HEAD.