MDL-21655 big scary enrolment and roles improvements - see tacker for list of changes...
authorPetr Skoda <skodak@moodle.org>
Wed, 31 Mar 2010 07:41:31 +0000 (07:41 +0000)
committerPetr Skoda <skodak@moodle.org>
Wed, 31 Mar 2010 07:41:31 +0000 (07:41 +0000)
225 files changed:
admin/cron.php
admin/generator.php
admin/register.php
admin/report/courseoverview/db/access.php
admin/report/questioninstances/db/access.php
admin/report/security/db/access.php
admin/report/security/lib.php
admin/report/unittest/db/access.php
admin/roles/admins.php [new file with mode: 0644]
admin/roles/assign.php
admin/roles/define.php
admin/roles/lib.php
admin/roles/manage.php
admin/settings/appearance.php
admin/settings/security.php
admin/settings/subsystems.php
admin/settings/users.php
admin/uploaduser.php
admin/uploaduser_form.php
admin/webservice/lib.php
auth/cas/auth.php
auth/fc/auth.php
auth/ldap/auth.php
auth/mnet/auth.php
backup/backuplib.php
backup/restore_form.html
backup/restorelib.php
blocks/admin/block_admin.php
blocks/admin_tree/block_admin_tree.php
blocks/comments/block_comments.php
blocks/course_list/block_course_list.php
blocks/global_navigation_tree/block_global_navigation_tree.php
blocks/messages/block_messages.php
blocks/mnet_hosts/block_mnet_hosts.php
blocks/moodleblock.class.php
blocks/news_items/block_news_items.php
blocks/online_users/block_online_users.php
blocks/online_users/db/access.php
blocks/quiz_results/block_quiz_results.php
blocks/rss_client/db/access.php
blocks/section_links/block_section_links.php
blocks/tags/block_tags.php
blog/edit_form.php
blog/lib.php
blog/locallib.php
blog/rsslib.php
calendar/export.php
calendar/lib.php
calendar/view.php
comment/comment_ajax.php
comment/comment_post.php
course/category.php
course/delete_category_form.php
course/edit.php
course/edit_form.php
course/enrol.php
course/external.php
course/info.php
course/lib.php
course/loginas.php
course/recent_form.php
course/report/log/db/access.php
course/report/log/lib.php
course/report/outline/db/access.php
course/report/participation/db/access.php
course/report/participation/index.php
course/report/progress/db/access.php
course/report/stats/db/access.php
course/search.php
course/user.php
enrol/authorize/db/access.php
enrol/authorize/index.php
enrol/flatfile/enrol.php
enrol/manual/enrol.php
enrol/paypal/return.php
filter/censor/filter.php
grade/export/ods/db/access.php
grade/export/txt/db/access.php
grade/export/xls/db/access.php
grade/export/xml/db/access.php
grade/import/csv/db/access.php
grade/import/xml/db/access.php
grade/report/grader/db/access.php
grade/report/outcomes/db/access.php
grade/report/overview/db/access.php
grade/report/user/db/access.php
group/assign.php
group/autogroup.php
group/externallib.php
group/index.php
group/lib.php
group/members.php
index.php
lang/en_utf8/admin.php
lang/en_utf8/role.php
lib/accesslib.php
lib/adminlib.php
lib/blocklib.php
lib/datalib.php
lib/db/access.php
lib/db/install.php
lib/db/install.xml
lib/db/upgrade.php
lib/deprecatedlib.php
lib/externallib.php
lib/moodlelib.php
lib/navigationlib.php
lib/outputrenderers.php
lib/pagelib.php
lib/setuplib.php
lib/simpletest/broken_testfilelib.php
lib/simpletest/testaccesslib.php
lib/statslib.php
lib/upgradelib.php
login/change_password.php
login/index.php
message/discussion.php
message/history.php
message/index.php
message/refresh.php
message/user.php
mod/assignment/db/access.php
mod/assignment/lib.php
mod/assignment/type/upload/assignment.class.php
mod/assignment/type/uploadsingle/assignment.class.php
mod/chat/chat_ajax.php
mod/chat/db/access.php
mod/chat/gui_header_js/insert.php
mod/chat/gui_sockets/index.php
mod/chat/lib.php
mod/choice/db/access.php
mod/choice/lib.php
mod/choice/view.php
mod/data/db/access.php
mod/data/edit.php
mod/data/lib.php
mod/data/rate.php
mod/data/restorelib.php
mod/data/tabs.php
mod/feedback/db/access.php
mod/feedback/lib.php
mod/forum/db/access.php
mod/forum/db/upgrade.php
mod/forum/discuss.php
mod/forum/index.php
mod/forum/lib.php
mod/forum/markposts.php
mod/forum/post.php
mod/forum/rate.php
mod/forum/rate_ajax.php
mod/forum/restorelib.php
mod/forum/subscribe.php
mod/glossary/db/access.php
mod/glossary/edit.php
mod/glossary/index.php
mod/glossary/lib.php
mod/glossary/sql.php
mod/glossary/view.php
mod/hotpot/db/access.php
mod/hotpot/lib.php
mod/lesson/db/access.php
mod/quiz/db/access.php
mod/quiz/report/statistics/db/access.php
mod/scorm/db/access.php
mod/survey/db/access.php
mod/survey/index.php
mod/survey/view.php
mod/url/locallib.php
mod/wiki/db/access.php
mod/wiki/lib.php
mod/workshop/db/access.php
mod/workshop/lib.php
my/index.php
pluginfile.php
question/type/randomsamatch/questiontype.php
repository/alfresco/db/access.php
repository/boxnet/db/access.php
repository/filesystem/db/access.php
repository/flickr/db/access.php
repository/flickr_public/db/access.php
repository/googledocs/db/access.php
repository/lib.php
repository/local/db/access.php
repository/mahara/db/access.php
repository/merlot/db/access.php
repository/picasa/db/access.php
repository/remotemoodle/db/access.php
repository/s3/db/access.php
repository/upload/db/access.php
repository/url/db/access.php
repository/webdav/db/access.php
repository/wikimedia/db/access.php
repository/youtube/db/access.php
rss/file.php
search/add.php
search/delete.php
search/documents/forum_document.php
search/documents/label_document.php
search/documents/physical_doc.php
search/documents/physical_htm.php
search/documents/physical_odt.php
search/documents/physical_pdf.php
search/documents/physical_ppt.php
search/documents/physical_swf.php
search/documents/physical_txt.php
search/documents/physical_xml.php
search/documents/resource_document.php
search/documents/user_document.php
search/indexer.php
search/indexersplash.php
search/query.php
search/querylib.php
search/stats.php
search/tests/index.php
search/update.php
tag/coursetags_more.php
tag/coursetagslib.php
tag/locallib.php
user/editadvanced.php
user/index.php
user/managetoken.php
user/repository.php
user/selector/lib.php
user/view.php
version.php

index b7bd969..b3435c8 100644 (file)
             }
             $rs->close();
         /// Execute the same query again, looking for remaining records and deleting them
-        /// if the user hasn't moodle/course:view in the CONTEXT_COURSE context (orphan records)
+        /// if the user hasn't moodle/course:participate in the CONTEXT_COURSE context (orphan records)
             $rs = $DB->get_recordset_sql ("SELECT id, userid, courseid
                                              FROM {user_lastaccess}
                                             WHERE courseid != ".SITEID."
                                                   AND timeaccess < ?", array($cuttime));
             foreach ($rs as $assign) {
                 if ($context = get_context_instance(CONTEXT_COURSE, $assign->courseid)) {
-                    if (!has_capability('moodle/course:view', $context, $assign->userid)) {
+                    if (!is_enrolled($context, $assign->userid) and !is_viewing($context, $assign->userid)) {
                         $DB->delete_records('user_lastaccess', array('userid'=>$assign->userid, 'courseid'=>$assign->courseid));
                         mtrace("Deleted orphan user_lastaccess for user $assign->userid from course $assign->courseid");
                     }
index 499afa3..c5b0be8 100755 (executable)
@@ -1187,7 +1187,8 @@ class generator_cli extends generator {
             }
             complete_user_login($user);
             $systemcontext = get_context_instance(CONTEXT_SYSTEM);
-            if (!has_capability('moodle/site:doanything', $systemcontext)) {
+
+            if (!is_siteadmin($user->id)) {//TODO: add some proper access control check here!!
                 echo "You do not have administration privileges on this Moodle site. "
                     ."These are required for running the generation script.{$this->eolchar}";
                 die();
index 78c4480..c4bcdb3 100644 (file)
               FROM {role_capabilities} rc,
                    {role_assignments} ra,
                    {user} u
-             WHERE (rc.capability = ? or rc.capability = ?)
+             WHERE (rc.capability = ?)
                    AND rc.roleid = ra.roleid
                    AND u.id = ra.userid";
 
-    $count = $DB->count_records_sql($sql, array('moodle/course:update', 'moodle/site:doanything'));
+    $count = $DB->count_records_sql($sql, array('moodle/course:update'));
     echo get_string("teachers").": ".$count;
     echo "<input type=\"hidden\" name=\"courseupdaters\" value=\"$count\" />\n";
     echo '<br />';
index c2145dc..ca8a508 100644 (file)
@@ -32,7 +32,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         ),
 
         'clonepermissionsfrom' => 'moodle/site:viewreports',
index 7afd65a..b537c35 100644 (file)
@@ -29,7 +29,7 @@ $capabilities = array(
         'captype' => 'read',
         'contextlevel' => CONTEXT_SYSTEM,
         'legacy' => array(
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         ),
 
         'clonepermissionsfrom' => 'moodle/site:config',
index 479e71b..6aefdca 100644 (file)
@@ -30,7 +30,7 @@ $capabilities = array(
         'captype' => 'read',
         'contextlevel' => CONTEXT_SYSTEM,
         'legacy' => array(
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         ),
     )
 );
index 7f86e0f..2d59c76 100644 (file)
@@ -576,16 +576,6 @@ function report_security_check_defaultuserrole($detailed=false) {
         return $result;
     }
 
-    // first test if do anything enabled - that would be really crazy!
-    $params = array('doanything'=>'moodle/site:doanything', 'capallow'=>CAP_ALLOW, 'roleid'=>$default_role->id);
-    $sql = "SELECT COUNT(DISTINCT rc.contextid)
-              FROM {role_capabilities} rc
-             WHERE rc.capability = :doanything
-                   AND rc.permission = :capallow
-                   AND rc.roleid = :roleid";
-
-    $anythingcount = $DB->count_records_sql($sql, $params);
-
     // risky caps - usually very dangerous
     $params = array('capallow'=>CAP_ALLOW, 'roleid'=>$default_role->id);
     $sql = "SELECT COUNT(DISTINCT rc.contextid)
@@ -598,24 +588,16 @@ function report_security_check_defaultuserrole($detailed=false) {
     $riskycount = $DB->count_records_sql($sql, $params);
 
     // default role can not have view cap in all courses - this would break moodle badly
-    $viewcap = $DB->record_exists('role_capabilities', array('roleid'=>$default_role->id, 'permission'=>CAP_ALLOW, 'capability'=>'moodle/course:view'));
+    $viewcap = $DB->record_exists('role_capabilities', array('roleid'=>$default_role->id, 'permission'=>CAP_ALLOW, 'capability'=>'moodle/course:participate'));
 
-    // it may have either no or 'user' legacy type - nothing else, or else it would break during upgrades badly
-    $legacyok = false;
-    $params = array('capallow'=>CAP_ALLOW, 'roleid'=>$default_role->id, 'legacy'=>'moodle/legacy:%');
-    $sql = "SELECT rc.capability, 1
-              FROM {role_capabilities} rc
-             WHERE rc.capability LIKE :legacy
-                   AND rc.permission = :capallow
-                   AND rc.roleid = :roleid";
-    $legacycaps = $DB->get_records_sql($sql, $params);
-    if (!$legacycaps) {
-        $legacyok = true;
-    } else if (count($legacycaps) == 1 and isset($legacycaps['moodle/legacy:user'])) {
+    // 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 ($anythingcount or $riskycount or $viewcap or !$legacyok) {
+    if ($riskycount or $viewcap or !$legacyok) {
         $result->status  = REPORT_SECURITY_CRITICAL;
         $result->info    = get_string('check_defaultuserrole_error', 'report_security', format_string($default_role->name));
 
@@ -655,16 +637,6 @@ function report_security_check_guestrole($detailed=false) {
         return $result;
     }
 
-    // first test if do anything enabled - that would be really crazy!
-    $params = array('doanything'=>'moodle/site:doanything', 'capallow'=>CAP_ALLOW, 'roleid'=>$guest_role->id);
-    $sql = "SELECT COUNT(DISTINCT rc.contextid)
-              FROM {role_capabilities} rc
-             WHERE rc.capability = :doanything
-                   AND rc.permission = :capallow
-                   AND rc.roleid = :roleid";
-
-    $anythingcount = $DB->count_records_sql($sql, $params);
-
     // risky caps - usually very dangerous
     $params = array('capallow'=>CAP_ALLOW, 'roleid'=>$guest_role->id);
     $sql = "SELECT COUNT(DISTINCT rc.contextid)
@@ -676,22 +648,14 @@ function report_security_check_guestrole($detailed=false) {
 
     $riskycount = $DB->count_records_sql($sql, $params);
 
-    // it may have either no or 'guest' legacy type - nothing else, or else it would break during upgrades badly
-    $legacyok = false;
-    $params = array('capallow'=>CAP_ALLOW, 'roleid'=>$guest_role->id, 'legacy'=>'moodle/legacy:%');
-    $sql = "SELECT rc.capability, 1
-              FROM {role_capabilities} rc
-             WHERE rc.capability LIKE :legacy
-                   AND rc.permission = :capallow
-                   AND rc.roleid = :roleid";
-    $legacycaps = $DB->get_records_sql($sql, $params);
-    if (!$legacycaps) {
-        $legacyok = true;
-    } else if (count($legacycaps) == 1 and isset($legacycaps['moodle/legacy:guest'])) {
+    // 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 ($anythingcount or $riskycount or !$legacyok) {
+    if ($riskycount or !$legacyok) {
         $result->status  = REPORT_SECURITY_CRITICAL;
         $result->info    = get_string('check_guestrole_error', 'report_security', format_string($guest_role->name));
 
@@ -731,16 +695,6 @@ function report_security_check_frontpagerole($detailed=false) {
         return $result;
     }
 
-    // first test if do anything enabled - that would be really crazy!
-    $params = array('doanything'=>'moodle/site:doanything', 'capallow'=>CAP_ALLOW, 'roleid'=>$frontpage_role->id);
-    $sql = "SELECT COUNT(DISTINCT rc.contextid)
-              FROM {role_capabilities} rc
-             WHERE rc.capability = :doanything
-                   AND rc.permission = :capallow
-                   AND rc.roleid = :roleid";
-
-    $anythingcount = $DB->count_records_sql($sql, $params);
-
     // risky caps - usually very dangerous
     $params = array('capallow'=>CAP_ALLOW, 'roleid'=>$frontpage_role->id);
     $sql = "SELECT COUNT(DISTINCT rc.contextid)
@@ -753,19 +707,14 @@ function report_security_check_frontpagerole($detailed=false) {
     $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!
-    $params = array('capallow'=>CAP_ALLOW, 'roleid'=>$frontpage_role->id, 'legacy'=>'moodle/legacy:%');
-    $sql = "SELECT rc.capability, 1
-              FROM {role_capabilities} rc
-             WHERE rc.capability LIKE :legacy
-                   AND rc.permission = :capallow
-                   AND rc.roleid = :roleid";
-    $legacycaps = $DB->get_records_sql($sql, $params);
-    $legacyok = (!isset($legacycaps['moodle/legacy:teacher'])
-                 and !isset($legacycaps['moodle/legacy:editingteacher'])
-                 and !isset($legacycaps['moodle/legacy:coursecreator'])
-                 and !isset($legacycaps['moodle/legacy:admin']));
+    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 ($anythingcount or $riskycount or !$legacyok) {
+    if ($riskycount or !$legacyok) {
         $result->status  = REPORT_SECURITY_CRITICAL;
         $result->info    = get_string('check_frontpagerole_error', 'report_security', format_string($frontpage_role->name));
 
@@ -811,25 +760,6 @@ function report_security_check_defaultcourserole($detailed=false) {
         return $result;
     }
 
-    // first test if do anything enabled - that would be really crazy!
-    $params = array('doanything'=>'moodle/site:doanything', 'capallow'=>CAP_ALLOW, 'roleid'=>$student_role->id);
-    $sql = "SELECT DISTINCT rc.contextid
-              FROM {role_capabilities} rc
-             WHERE rc.capability = :doanything
-                   AND rc.permission = :capallow
-                   AND rc.roleid = :roleid";
-
-    if ($anything_contexts = $DB->get_records_sql($sql, $params)) {
-        foreach($anything_contexts as $contextid) {
-            if ($contextid == SYSCONTEXTID) {
-                $a = "$CFG->wwwroot/$CFG->admin/roles/define.php?action=view&amp;roleid=$CFG->defaultcourseroleid";
-            } else {
-                $a = "$CFG->wwwroot/$CFG->admin/roles/override.php?contextid=$contextid&amp;roleid=$CFG->defaultcourseroleid";
-            }
-            $problems[] = get_string('check_defaultcourserole_anything', 'report_security', $a);
-        }
-    }
-
     // risky caps - usually very dangerous
     $params = array('capallow'=>CAP_ALLOW, 'roleid'=>$student_role->id);
     $sql = "SELECT DISTINCT rc.contextid
@@ -851,14 +781,7 @@ function report_security_check_defaultcourserole($detailed=false) {
     }
 
     // course creator or administrator does not make any sense here
-    $params = array('capallow'=>CAP_ALLOW, 'roleid'=>$student_role->id, 'legacy'=>'moodle/legacy:%');
-    $sql = "SELECT rc.capability, 1
-              FROM {role_capabilities} rc
-             WHERE rc.capability LIKE :legacy
-                   AND rc.permission = :capallow
-                   AND rc.roleid = :roleid";
-    $legacycaps = $DB->get_records_sql($sql, $params);
-    if (isset($legacycaps['moodle/legacy:coursecreator']) or isset($legacycaps['moodle/legacy:admin'])) {
+    if ($student_role->archetype === 'coursecreator' or $student_role->archetype === 'manager') {
         $problems[] = get_string('check_defaultcourserole_legacy', 'report_security');
     }
 
@@ -922,43 +845,16 @@ function report_security_check_courserole($detailed=false) {
 
     $sql = "SELECT DISTINCT rc.roleid
               FROM {role_capabilities} rc
-             WHERE (rc.capability = :coursecreator OR rc.capability = :admin OR rc.capability = :teacher OR rc.capability = :editingteacher)
-                   AND rc.permission = ".CAP_ALLOW."";
-    $params = array('coursecreator'  => 'moodle/legacy:coursecreator',
-                    'admin'          => 'moodle/legacy:admin',
-                    'teacher'        => 'moodle/legacy:teacher',
-                    'editingteacher' => 'moodle/legacy:editingteacher');
+              JOIN {role} r ON r.id = rc.roleid
+             WHERE (r.archetype = :coursecreator OR r.archetype = :teacher OR r.archetype = :editingteacher OR r.archetype = :manager)";
+    $params = array('coursecreator'  => 'coursecreator',
+                    'teacher'        => 'teacher',
+                    'editingteacher' => 'editingteacher',
+                    'manager'        => 'manager');
 
     $riskyroleids = $DB->get_records_sql($sql, $params);
     $riskyroleids = array_keys($riskyroleids);
 
-
-    // first test if do anything enabled - that would be really crazy!!!!!!
-    list($inroles, $params) = $DB->get_in_or_equal($roleids, SQL_PARAMS_NAMED, 'r0', true);
-    $params = array_merge($params, array('doanything'=>'moodle/site:doanything', 'capallow'=>CAP_ALLOW));
-    $params['doanything'] = 'moodle/site:doanything';
-    $params['capallow']   = CAP_ALLOW;
-    $sql = "SELECT rc.roleid, rc.contextid
-              FROM {role_capabilities} rc
-             WHERE rc.capability = :doanything
-                   AND rc.permission = :capallow
-                   AND rc.roleid $inroles
-          GROUP BY rc.roleid, rc.contextid
-          ORDER BY rc.roleid, rc.contextid";
-
-    $rs = $DB->get_recordset_sql($sql, $params);
-    foreach($rs as $res) {
-        $roleid    = $res->roleid;
-        $contextid = $res->contextid;
-        if ($contextid == SYSCONTEXTID) {
-            $a = "$CFG->wwwroot/$CFG->admin/roles/define.php?action=view&amp;roleid=$roleid";
-        } else {
-            $a = "$CFG->wwwroot/$CFG->admin/roles/override.php?contextid=$contextid&amp;roleid=$roleid";
-        }
-        $problems[] = get_string('check_courserole_anything', 'report_security', $a);
-    }
-    $rs->close();
-
     // any XSS legacy cap does not make any sense here!
     list($inroles, $params) = $DB->get_in_or_equal($roleids, SQL_PARAMS_NAMED, 'r0', true);
     $sql = "SELECT DISTINCT c.id, c.shortname
@@ -1034,37 +930,13 @@ function report_security_check_riskadmin($detailed=false) {
     $result->status  = null;
     $result->link    = null;
 
-    $params = array('doanything'=>'moodle/site:doanything', 'syscontextid'=>SYSCONTEXTID, 'capallow'=>CAP_ALLOW);
+    $sql = "SELECT u.id, u.firstname, u.lastname, u.picture, u.imagealt, u.email
+              FROM {user} u
+             WHERE u.id IN ($CFG->siteadmins)";
 
-    $sql = "SELECT DISTINCT u.id, u.firstname, u.lastname, u.picture, u.imagealt, u.email
-              FROM {role_capabilities} rc
-              JOIN {role_assignments} ra ON (ra.contextid = rc.contextid AND ra.roleid = rc.roleid)
-              JOIN {user} u ON u.id = ra.userid
-             WHERE rc.capability = :doanything
-                   AND rc.permission = :capallow
-                   AND u.deleted = 0
-                   AND rc.contextid = :syscontextid";
-
-    $admins = $DB->get_records_sql($sql, $params);
+    $admins = $DB->get_records_sql($sql);
     $admincount = count($admins);
 
-    $sqlunsup = "SELECT u.id, u.firstname, u.lastname, u.picture, u.imagealt, u.email, ra.contextid, ra.roleid
-                  FROM (SELECT rcx.*
-                       FROM {role_capabilities} rcx
-                       WHERE rcx.capability = :doanything AND 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 AND ra.contextid <> :syscontextid
-            GROUP BY u.id, u.firstname, u.lastname, u.picture, u.imagealt, u.email, ra.contextid, ra.roleid
-            ORDER BY u.lastname, u.firstname";
-
-    $unsupcount = $DB->count_records_sql("SELECT COUNT('x') FROM ($sqlunsup) unsup", $params);
-
     if ($detailed) {
         foreach ($admins as $uid=>$user) {
             $url = "$CFG->wwwroot/user/view.php?id=$user->id";
@@ -1073,32 +945,11 @@ function report_security_check_riskadmin($detailed=false) {
         $admins = '<ul>'.implode($admins).'</ul>';
     }
 
-    if (!$unsupcount) {
-        $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);
-        }
-
-    } else {
-        $result->status  = REPORT_SECURITY_WARNING;
-        $a = (object)array('admincount'=>$admincount, 'unsupcount'=>$unsupcount);
-        $result->info = get_string('check_riskadmin_warning', 'report_security', $a);
+    $result->status  = REPORT_SECURITY_OK;
+    $result->info = get_string('check_riskadmin_ok', 'report_security', $admincount);
 
-        if ($detailed) {
-            $rs = $DB->get_recordset_sql($sqlunsup, $params);
-            $users = array();
-            foreach ($rs as $user) {
-                $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);
-                $users[] = '<li>'.get_string('check_riskadmin_unassign', 'report_security', $a).'</li>';
-            }
-            $rs->close();
-            $users = '<ul>'.implode($users).'</ul>';
-            $a = (object)array('admins'=>$admins, 'unsupported'=>$users);
-            $result->details = get_string('check_riskadmin_detailswarning', 'report_security', $a);
-        }
+    if ($detailed) {
+        $result->details = get_string('check_riskadmin_detailsok', 'report_security', $admins);
     }
 
     return $result;
index 73d906b..0821a99 100644 (file)
@@ -30,7 +30,7 @@ $capabilities = array(
         'captype' => 'read',
         'contextlevel' => CONTEXT_SYSTEM,
         'legacy' => array(
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         ),
 
         'clonepermissionsfrom' => 'moodle/site:config',
diff --git a/admin/roles/admins.php b/admin/roles/admins.php
new file mode 100644 (file)
index 0000000..065e29a
--- /dev/null
@@ -0,0 +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/>.
+
+/**
+ * Lets you site administrators
+ *
+ * @package    moodlecore
+ * @subpackage role
+ * @copyright  2010 Petr Skoda (skodak) http://skodak.org
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(dirname(__FILE__) . '/../../config.php');
+require_once($CFG->dirroot . '/' . $CFG->admin . '/roles/lib.php');
+
+$confirmadd = optional_param('confirmadd', 0, PARAM_INT);
+$confirmdel = optional_param('confirmdel', 0, PARAM_INT);
+
+$PAGE->set_url('/admin/roles/admins.php');
+
+admin_externalpage_setup('admins');
+if (!is_siteadmin()) {
+    die;
+}
+
+$admisselector = new admins_existing_selector();
+$admisselector->set_extra_fields(array('username', 'email'));
+
+$potentialadmisselector = new admins_potential_selector();
+$potentialadmisselector->set_extra_fields(array('username', 'email'));
+
+if (optional_param('add', false, PARAM_BOOL) and confirm_sesskey()) {
+    if ($userstoadd = $potentialadmisselector->get_selected_users()) {
+        $user = reset($userstoadd);
+        $username = fullname($user) . " ($user->username, $user->email)";
+        echo $OUTPUT->header();
+        echo $OUTPUT->confirm(get_string('confirmaddadmin', 'role', $username), new moodle_url('/admin/roles/admins.php', array('confirmadd'=>$user->id, 'sesskey'=>sesskey())), $PAGE->url);
+        echo $OUTPUT->footer();
+        die;
+    }
+
+} else if (optional_param('remove', false, PARAM_BOOL) and confirm_sesskey()) {
+    if ($userstoremove = $admisselector->get_selected_users()) {
+        $user = reset($userstoremove);
+        if ($USER->id == $user->id) {
+            //can not remove self
+        } else {
+            $username = fullname($user) . " ($user->username, $user->email)";
+            echo $OUTPUT->header();
+            echo $OUTPUT->confirm(get_string('confirmdeladmin', 'role', $username), new moodle_url('/admin/roles/admins.php', array('confirmdel'=>$user->id, 'sesskey'=>sesskey())), $PAGE->url);
+            echo $OUTPUT->footer();
+            die;
+        }
+    }
+
+} else if ($confirmadd and confirm_sesskey()) {
+    $admins = array();
+    foreach(explode(',', $CFG->siteadmins) as $admin) {
+        $admin = (int)$admin;
+        if ($admin) {
+            $admins[$admin] = $admin;
+        }
+    }
+    $admins[$confirmadd] = $confirmadd;
+    set_config('siteadmins', implode(',', $admins));
+    redirect($PAGE->url);
+
+} else if ($confirmdel and confirm_sesskey() and $confirmdel != $USER->id) {
+    $admins = array();
+    foreach(explode(',', $CFG->siteadmins) as $admin) {
+        $admin = (int)$admin;
+        if ($admin) {
+            $admins[$admin] = $admin;
+        }
+    }
+    unset($admins[$confirmdel]);
+    set_config('siteadmins', implode(',', $admins));
+    redirect($PAGE->url);
+}
+
+/// Print header
+echo $OUTPUT->header();
+?>
+
+<div id="addadmisform">
+    <h3 class="main"><?php print_string('manageadmins', 'role'); ?></h3>
+
+    <form id="assignform" method="post" action="<?php echo $PAGE->url ?>">
+    <div>
+    <input type="hidden" name="sesskey" value="<?php p(sesskey()); ?>" />
+
+    <table class="generaltable generalbox groupmanagementtable boxaligncenter" summary="">
+    <tr>
+      <td id='existingcell'>
+          <p>
+            <label for="removeselect"><?php print_string('existingadmins', 'role'); ?></label>
+          </p>
+          <?php $admisselector->display(); ?>
+          </td>
+      <td id='buttonscell'>
+        <p class="arrow_button">
+            <input name="add" id="add" type="submit" value="<?php echo $OUTPUT->larrow().'&nbsp;'.get_string('add'); ?>" title="<?php print_string('add'); ?>" /><br />
+            <input name="remove" id="remove" type="submit" value="<?php echo get_string('remove').'&nbsp;'.$OUTPUT->rarrow(); ?>" title="<?php print_string('remove'); ?>" />
+        </p>
+      </td>
+      <td id='potentialcell'>
+          <p>
+            <label for="addselect"><?php print_string('users'); ?></label>
+          </p>
+          <?php $potentialadmisselector->display(); ?>
+      </td>
+    </tr>
+    </table>
+    </div>
+    </form>
+</div>
+
+<?php
+
+//this must be after calling display() on the selectors so their setup JS executes first
+//////$PAGE->requires->js_function_call('init_add_remove_admis_page');
+
+echo $OUTPUT->footer();
index 268788e..32ebadf 100755 (executable)
@@ -33,7 +33,6 @@
     $roleid         = optional_param('roleid', 0, PARAM_INT);
     $userid         = optional_param('userid', 0, PARAM_INT); // needed for user tabs
     $courseid       = optional_param('courseid', 0, PARAM_INT); // needed for user tabs
-    $hidden         = optional_param('hidden', 0, PARAM_BOOL); // whether this assignment is hidden
     $extendperiod   = optional_param('extendperiod', 0, PARAM_INT);
     $extendbase     = optional_param('extendbase', 3, PARAM_INT);
 
         $options = array('context' => $context, 'roleid' => $roleid);
 
         $potentialuserselector = roles_get_potential_user_selector($context, 'addselect', $options);
-        if ($context->contextlevel == CONTEXT_SYSTEM && is_admin_role($roleid)) {
-            $currentuserselector = new existing_role_holders_site_admin('removeselect', $options);
-        } else {
-            $currentuserselector = new existing_role_holders('removeselect', $options);
-        }
+        $currentuserselector = new existing_role_holders('removeselect', $options);
 
     /// Process incoming role assignments
         $errors = array();
                         } else {
                             $timeend = 0;
                         }
-                        if (! role_assign($roleid, $adduser->id, 0, $context->id, $timestart, $timeend, $hidden)) {
+                        if (! role_assign($roleid, $adduser->id, 0, $context->id, $timestart, $timeend)) {
                             $a = new stdClass;
                             $a->role = $assignableroles[$roleid];
                             $a->user = fullname($adduser);
 
               <?php print_collapsible_region_start('', 'assignoptions', get_string('enrolmentoptions', 'role'),
                     'assignoptionscollapse', true); ?>
-              <p><input type="checkbox" name="hidden" id="hidden" value="1" <?php
-              if ($hidden) { echo 'checked="checked" '; } ?>/>
-              <label for="hidden" title="<?php print_string('createhiddenassign', 'role'); ?>">
-                  <?php print_string('hidden', 'role'); ?>
-                  <?php echo $OUTPUT->help_icon('hiddenassign', get_string('createhiddenassign', 'role')); ?>
-              </label></p>
 
               <p><label for="extendperiod"><?php print_string('enrolperiod') ?></label><br />
               <?php echo html_writer::select($periodmenu, 'extendperiod', $defaultperiod, $unlimitedperiod); ?></p>
index 3ba2e3c..9e6e219 100755 (executable)
     admin_externalpage_print_header();
 
     $currenttab = 'manage';
-    include_once('managetabs.php');
+    include('managetabs.php');
 
     if ($action == 'add') {
         $title = get_string('addinganewrole', 'role');
         $options['action'] = 'edit';
         echo $OUTPUT->single_button(new moodle_url($defineurl, $options), get_string('edit'));
         $options['action'] = 'reset';
-        if ($definitiontable->get_legacy_type()) {
+        if ($definitiontable->get_archetype()) {
             echo $OUTPUT->single_button(new moodle_url($manageurl, $options), get_string('resetrole', 'role'));
         } else {
             echo $OUTPUT->single_button(new moodle_url($manageurl, $options), get_string('resetrolenolegacy', 'role'));
index 09c1131..dde9aca 100644 (file)
@@ -144,7 +144,7 @@ abstract class capability_table_base {
     protected abstract function num_extra_columns();
 
     /**
-     * For subclasses to override. Allows certain capabilties (e.g. legacy capabilities)
+     * For subclasses to override. Allows certain capabilties
      * to be left out of the table.
      *
      * @param object $capability the capability this row relates to.
@@ -213,10 +213,6 @@ class check_capability_table extends capability_table_base {
         return 1;
     }
 
-    protected function skip_row($capability) {
-        return $capability->name != 'moodle/site:doanything' && is_legacy($capability->name);
-    }
-
     protected function get_row_classes($capability) {
         $this->hascap = has_capability($capability->name, $this->context, $this->user->id);
         if ($this->hascap) {
@@ -285,10 +281,6 @@ class permissions_table extends capability_table_base {
         return 3;
     }
 
-    protected function skip_row($capability) {
-        return $capability->name != 'moodle/site:doanything' && is_legacy($capability->name);
-    }
-
     protected function add_row_cells($capability) {
         global $OUTPUT, $PAGE;
 
@@ -554,7 +546,6 @@ class define_role_table_advanced extends capability_table_with_risks {
     protected $errors;
     protected $contextlevels;
     protected $allcontextlevels;
-    protected $legacyroles;
     protected $disabled = '';
 
     public function __construct($context, $roleid) {
@@ -571,8 +562,6 @@ class define_role_table_advanced extends capability_table_with_risks {
             CONTEXT_MODULE => get_string('activitymodule'),
             CONTEXT_BLOCK => get_string('block')
         );
-
-        $this->legacyroles = get_legacy_roles();
     }
 
     protected function load_current_permissions() {
@@ -581,7 +570,6 @@ class define_role_table_advanced extends capability_table_with_risks {
             if (!$this->role = $DB->get_record('role', array('id' => $this->roleid))) {
                 throw new moodle_exception('invalidroleid');
             }
-            $this->role->legacytype = get_legacy_type($this->roleid);
             $contextlevels = get_role_contextlevels($this->roleid);
             // Put the contextlevels in the array keys, as well as the values.
             if (!empty($contextlevels)) {
@@ -594,7 +582,7 @@ class define_role_table_advanced extends capability_table_with_risks {
             $this->role->name = '';
             $this->role->shortname = '';
             $this->role->description = '';
-            $this->role->legacytype = '';
+            $this->role->archetype = '';
             $this->contextlevels = array();
         }
         parent::load_current_permissions();
@@ -638,12 +626,13 @@ class define_role_table_advanced extends capability_table_with_risks {
         }
 
         // Legacy type.
-        $legacytype = optional_param('legacytype', null, PARAM_RAW);
-        if (!is_null($legacytype)) {
-            if (array_key_exists($legacytype, $this->legacyroles)) {
-                $this->role->legacytype = $legacytype;
+        $archetype = optional_param('archetype', null, PARAM_RAW);
+        if ($archetype) {
+            $archetypes = get_role_archetypes();
+            if (isset($archetypes[$archetype])){
+                $this->role->archetype = $archetype;
             } else {
-                $this->role->legacytype = '';
+                $this->role->archetype = '';
             }
         }
 
@@ -686,16 +675,12 @@ class define_role_table_advanced extends capability_table_with_risks {
         return $this->role->id;
     }
 
-    public function get_legacy_type() {
-        return $this->role->legacytype;
+    public function get_archetype() {
+        return $this->role->archetype;
     }
 
     protected function load_parent_permissions() {
-        if ($this->role->legacytype) {
-            $this->parentpermissions = get_default_capabilities($this->role->legacytype);
-        } else {
-            $this->parentpermissions = array();
-        }
+        $this->parentpermissions = get_default_capabilities($this->role->archetype);
     }
 
     public function save_changes() {
@@ -703,25 +688,11 @@ class define_role_table_advanced extends capability_table_with_risks {
 
         if (!$this->roleid) {
             // Creating role
-            if (isset($this->legacyroles[$this->role->legacytype])) {
-                $legacycap = $this->legacyroles[$this->role->legacytype];
-            } else {
-                $legacycap = '';
-            }
-            $this->role->id = create_role($this->role->name, $this->role->shortname, $this->role->description, $legacycap);
+            $this->role->id = create_role($this->role->name, $this->role->shortname, $this->role->description, $this->role->archetype);
             $this->roleid = $this->role->id; // Needed to make the parent::save_changes(); call work.
         } else {
             // Updating role
             $DB->update_record('role', $this->role);
-
-            // Legacy type
-            foreach($this->legacyroles as $type => $cap) {
-                if ($type == $this->role->legacytype) {
-                    assign_capability($cap, CAP_ALLOW, $this->role->id, $this->context->id);
-                } else {
-                    unassign_capability($cap, $this->role->id);
-                }
-            }
         }
 
         // Assignable contexts.
@@ -731,10 +702,6 @@ class define_role_table_advanced extends capability_table_with_risks {
         parent::save_changes();
     }
 
-    protected function skip_row($capability) {
-        return is_legacy($capability->name);
-    }
-
     protected function get_name_field($id) {
         return '<input type="text" id="' . $id . '" name="' . $id . '" maxlength="254" value="' . s($this->role->name) . '" />';
     }
@@ -747,14 +714,14 @@ class define_role_table_advanced extends capability_table_with_risks {
         return print_textarea(true, 10, 50, 50, 10, 'description', $this->role->description, 0, true);
     }
 
-    protected function get_legacy_type_field($id) {
+    protected function get_archetype_field($id) {
         global $OUTPUT;
         $options = array();
         $options[''] = get_string('none');
-        foreach($this->legacyroles as $type => $cap) {
-            $options[$type] = get_string('legacy:'.$type, 'role');
+        foreach(get_role_archetypes() as $type) {
+            $options[$type] = get_string('archetype'.$type, 'role');
         }
-        return html_writer::select($options, 'legacytype', $this->role->legacytype, false);
+        return html_writer::select($options, 'archetype', $this->role->archetype, false);
     }
 
     protected function get_assignable_levels_control() {
@@ -814,7 +781,7 @@ class define_role_table_advanced extends capability_table_with_risks {
         $this->print_field('name', get_string('name'), $this->get_name_field('name'));
         $this->print_field('shortname', get_string('shortname'), $this->get_shortname_field('shortname'));
         $this->print_field('edit-description', get_string('description'), $this->get_description_field('description'));
-        $this->print_field('menulegacytype', get_string('legacytype', 'role'), $this->get_legacy_type_field('legacytype'));
+        $this->print_field('menuarchetype', get_string('archetype', 'role'), $this->get_archetype_field('archetype'));
         $this->print_field('', get_string('maybeassignedin', 'role'), $this->get_assignable_levels_control());
         echo "</div>";
 
@@ -905,11 +872,11 @@ class view_role_definition_table extends define_role_table_advanced {
         return format_text($this->role->description, FORMAT_HTML);
     }
 
-    protected function get_legacy_type_field($id) {
-        if (empty($this->role->legacytype)) {
+    protected function get_archetype_field($id) {
+        if (empty($this->role->archetype)) {
             return get_string('none');
         } else {
-            return get_string('legacy:'.$this->role->legacytype, 'role');
+            return get_string('archetype'.$this->role->archetype, 'role');
         }
     }
 
@@ -976,10 +943,6 @@ class override_permissions_table_advanced extends capability_table_with_risks {
         return $this->haslockedcapabiltites;
     }
 
-    protected function skip_row($capability) {
-        return is_legacy($capability->name);
-    }
-
     protected function add_permission_cells($capability) {
         $disabled = '';
         if ($capability->locked || $this->parentpermissions[$capability->name] == CAP_PROHIBIT) {
@@ -1058,7 +1021,7 @@ abstract class role_assign_user_selector_base extends user_selector_base {
  * some CONTEXT_BLOCK).
  *
  * In this case we replicate part of get_users_by_capability() get the users
- * with moodle/course:view (or moodle/site:doanything). We can't use
+ * with moodle/course:participate. We can't use
  * get_users_by_capability() becuase
  *   1) get_users_by_capability() does not deal with searching by name
  *   2) exceptions array can be potentially large for large courses
@@ -1067,26 +1030,20 @@ class potential_assignees_below_course extends role_assign_user_selector_base {
     public function find_users($search) {
         global $DB;
 
-        // Get roles with some assignement to the 'moodle/course:view' capability.
-        $possibleroles = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $this->context);
+        // Get roles with some assignement to the 'moodle/course:participate' capability.
+        $possibleroles = get_roles_with_capability('moodle/course:participate', CAP_ALLOW, $this->context);
         if (empty($possibleroles)) {
             // If there aren't any, we are done.
             return array();
         }
 
         // Now exclude the admin roles, and check the actual permission on
-        // 'moodle/course:view' to make sure it is allow.
-        $doanythingroles = get_roles_with_capability('moodle/site:doanything',
-                CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM));
+        // 'moodle/course:participate' to make sure it is allow.
         $validroleids = array();
 
         foreach ($possibleroles as $possiblerole) {
-            if (isset($doanythingroles[$possiblerole->id])) {
-                    continue;
-            }
-
-            if ($caps = role_context_capabilities($possiblerole->id, $this->context, 'moodle/course:view')) { // resolved list
-                if (isset($caps['moodle/course:view']) && $caps['moodle/course:view'] > 0) { // resolved capability > 0
+            if ($caps = role_context_capabilities($possiblerole->id, $this->context, 'moodle/course:participate')) { // resolved list
+                if (isset($caps['moodle/course:participate']) && $caps['moodle/course:participate'] > 0) { // resolved capability > 0
                     $validroleids[] = $possiblerole->id;
                 }
             }
@@ -1116,13 +1073,13 @@ class potential_assignees_below_course extends role_assign_user_selector_base {
                         AND u.id NOT IN (
                            SELECT u.id
                              FROM {role_assignments} r, {user} u
-                            WHERE r.contextid = ?
+                            WHERE r.contextid = :contextid
                                   AND u.id = r.userid
-                                  AND r.roleid = ?)";
+                                  AND r.roleid = :roleid)";
         $order = ' ORDER BY lastname ASC, firstname ASC';
 
-        $params[] = $this->context->id;
-        $params[] = $this->roleid;
+        $params['contextid'] = $this->context->id;
+        $params['roleid'] = $this->roleid;
 
         // Check to see if there are too many to show sensibly.
         if (!$this->is_validating()) {
@@ -1168,13 +1125,13 @@ class potential_assignees_course_and_above extends role_assign_user_selector_bas
                       AND id NOT IN (
                          SELECT u.id
                            FROM {role_assignments} r, {user} u
-                          WHERE r.contextid = ?
+                          WHERE r.contextid = :contextid
                                 AND u.id = r.userid
-                                AND r.roleid = ?)";
+                                AND r.roleid = :roleid)";
         $order = ' ORDER BY lastname ASC, firstname ASC';
 
-        $params[] = $this->context->id;
-        $params[] = $this->roleid;
+        $params['contextid'] = $this->context->id;
+        $params['roleid'] = $this->roleid;
 
         if (!$this->is_validating()) {
             $potentialmemberscount = $DB->count_records_sql($countfields . $sql, $params);
@@ -1204,29 +1161,27 @@ class potential_assignees_course_and_above extends role_assign_user_selector_bas
  * question on the assign roles page.
  */
 class existing_role_holders extends role_assign_user_selector_base {
-    protected $strhidden;
 
     public function __construct($name, $options) {
         parent::__construct($name, $options);
-        $this->strhidden = get_string('hiddenassign');
     }
 
     public function find_users($search) {
         global $DB;
 
         list($wherecondition, $params) = $this->search_sql($search, 'u');
-        list($ctxcondition, $ctxparams) = $DB->get_in_or_equal(get_parent_contexts($this->context, true));
+        list($ctxcondition, $ctxparams) = $DB->get_in_or_equal(get_parent_contexts($this->context, true), SQL_PARAMS_NAMED, 'ctx00');
         $params = array_merge($params, $ctxparams);
-        $params[] = $this->roleid;
+        $params['roleid'] = $this->roleid;
 
-        $sql = "SELECT ra.id as raid," . $this->required_fields_sql('u') . ",ra.hidden,ra.contextid
+        $sql = "SELECT ra.id as raid," . $this->required_fields_sql('u') . ",ra.contextid
                 FROM {role_assignments} ra
                 JOIN {user} u ON u.id = ra.userid
                 JOIN {context} ctx ON ra.contextid = ctx.id
                 WHERE
                     $wherecondition AND
                     ctx.id $ctxcondition AND
-                    ra.roleid = ?
+                    ra.roleid = :roleid
                 ORDER BY ctx.depth DESC, u.lastname, u.firstname";
         $contextusers = $DB->get_records_sql($sql, $params);
 
@@ -1314,34 +1269,6 @@ class existing_role_holders extends role_assign_user_selector_base {
             return get_string('usersfrom', 'role', $contextname);
         }
     }
-
-    // Override to add (hidden) to hidden role assignments.
-    public function output_user($user) {
-        $output = parent::output_user($user);
-        if ($user->hidden) {
-            $output .= ' (' . $this->strhidden . ')';
-        }
-        return $output;
-    }
-}
-
-/**
- * A special subclass to use when unassigning admins at site level. Disables
- * the option for admins to unassign themselves.
- */
-class existing_role_holders_site_admin extends existing_role_holders {
-    public function find_users($search) {
-        global $USER;
-        $groupedusers = parent::find_users($search);
-        foreach ($groupedusers as $group) {
-            foreach ($group as &$user) {
-                if ($user->id == $USER->id) {
-                    $user->disabled = true;
-                }
-            }
-        }
-        return $groupedusers;
-    }
 }
 
 /**
@@ -1590,3 +1517,82 @@ function roles_get_potential_user_selector($context, $name, $options) {
     return $potentialuserselector;
 }
 
+class admins_potential_selector extends user_selector_base {
+    /**
+     * @param string $name control name
+     * @param array $options should have two elements with keys groupid and courseid.
+     */
+    public function __construct() {
+        global $CFG, $USER;
+        $admins = explode(',', $CFG->siteadmins);
+        parent::__construct('addselect', array('multiselect'=>false, 'exclude'=>$admins));
+    }
+
+    public function find_users($search) {
+        global $DB;
+        list($wherecondition, $params) = $this->search_sql($search, '');
+
+        $fields      = 'SELECT ' . $this->required_fields_sql('');
+        $countfields = 'SELECT COUNT(1)';
+
+        $sql = " FROM {user}
+                WHERE $wherecondition";
+        $order = ' ORDER BY lastname ASC, firstname ASC';
+
+        $availableusers = $DB->get_records_sql($fields . $sql . $order, $params);
+
+        if (empty($availableusers)) {
+            return array();
+        }
+
+        if ($search) {
+            $groupname = get_string('potusersmatching', 'role', $search);
+        } else {
+            $groupname = get_string('potusers', 'role');
+        }
+
+        return array($groupname => $availableusers);
+    }
+}
+
+class admins_existing_selector extends user_selector_base {
+    /**
+     * @param string $name control name
+     * @param array $options should have two elements with keys groupid and courseid.
+     */
+    public function __construct() {
+        global $CFG, $USER;
+        parent::__construct('removeselect', array('multiselect'=>false));
+    }
+
+    public function find_users($search) {
+        global $DB, $CFG;
+        list($wherecondition, $params) = $this->search_sql($search, '');
+
+        $fields      = 'SELECT ' . $this->required_fields_sql('');
+        $countfields = 'SELECT COUNT(1)';
+
+        if ($wherecondition) {
+            $wherecondition = "$wherecondition AND id IN ($CFG->siteadmins)";
+        } else {
+            $wherecondition = "id IN ($CFG->siteadmins)";
+        }
+        $sql = " FROM {user}
+                WHERE $wherecondition";
+        $order = ' ORDER BY lastname ASC, firstname ASC';
+
+        $availableusers = $DB->get_records_sql($fields . $sql . $order, $params);
+
+        if (empty($availableusers)) {
+            return array();
+        }
+
+        if ($search) {
+            $groupname = get_string('extusersmatching', 'role', $search);
+        } else {
+            $groupname = get_string('extusers', 'role');
+        }
+
+        return array($groupname => $availableusers);
+    }
+}
index 81e693e..f09efb5 100755 (executable)
     $undeletableroles[$CFG->guestroleid] = 1;
     $undeletableroles[$CFG->defaultuserroleid] = 1;
     $undeletableroles[$CFG->defaultcourseroleid] = 1;
-    // If there is only one admin role, add that to $undeletableroles too.
-    $adminroles = get_admin_roles();
-    if (count($adminroles) == 1) {
-        $undeletableroles[reset($adminroles)->id] = 1;
-    }
 
 ///.Process submitted data.
     $confirmed = optional_param('confirm', false, PARAM_BOOL) && data_submitted() && confirm_sesskey();
                 $a->id = $roleid;
                 $a->name = $roles[$roleid]->name;
                 $a->shortname = $roles[$roleid]->shortname;
-                $a->legacytype = get_legacy_type($roleid);
+                $a->legacytype = $roles[$roleid]->archetype;
                 if (empty($a->legacytype)) {
                     $warning = get_string('resetrolesurenolegacy', 'role', $a);
                 } else {
                 }
                 $formcontinue = new single_button(new moodle_url('manage.php', $optionsyes), get_string('yes'));
                 $formcancel = new single_button(new moodle_url('manage.php', $optionsno), get_string('no'), 'get');
-                echo $OUTPUT->confirm(get_string('confirmmessage', 'bulkusers', $usernames), $formcontinue, $formcancel);
+                echo $OUTPUT->confirm($warning, $formcontinue, $formcancel);
                 echo $OUTPUT->footer();
                 die;
             }
 
             // Do the reset.
-            $legacytype = get_legacy_type($roleid);
-            if ($legacytype) {
-                set_role_contextlevels($roleid, get_default_contextlevels($legacytype));
+            if ($roles[$roleid]->archetype) {
+                set_role_contextlevels($roleid, get_default_contextlevels($roles[$roleid]->archetype));
             }
             reset_role_capabilities($roleid);
 
             // Mark context dirty, log and redirect.
             mark_context_dirty($systemcontext->path);
             add_to_log(SITEID, 'role', 'reset', 'admin/roles/manage.php?action=reset&roleid=' . $roleid, $roles[$roleid]->localname, '', $USER->id);
-            redirect($defineurl . '?action=view&amp;roleid=' . $roleid);
+            redirect($defineurl . '?action=view&roleid=' . $roleid);
             break;
     }
 
index 941122e..7f09dbd 100644 (file)
@@ -128,7 +128,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
     $temp->add(new admin_setting_configtext('mycoursesperpage', get_string('mycoursesperpage', 'admin'), get_string('configmycoursesperpage', 'admin'), 21, PARAM_INT));
     $ADMIN->add('appearance', $temp);
 
-    // new CFG variable for coursemanager (what roles to display)
+    // coursemanager is the person responsible for course - usually manages enrolments, receives notification, etc.
     $temp = new admin_settingpage('coursemanager', get_string('coursemanager', 'admin'));
     $temp->add(new admin_setting_special_coursemanager());
     $ADMIN->add('appearance', $temp);
index e59b8a2..6c1081d 100644 (file)
@@ -17,7 +17,11 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
     $temp->add(new admin_setting_configcheckbox('forcelogin', get_string('forcelogin', 'admin'), get_string('configforcelogin', 'admin'), 0));
     $temp->add(new admin_setting_configcheckbox('forceloginforprofiles', get_string('forceloginforprofiles', 'admin'), get_string('configforceloginforprofiles', 'admin'), 1));
     $temp->add(new admin_setting_configcheckbox('opentogoogle', get_string('opentogoogle', 'admin'), get_string('configopentogoogle', 'admin'), 0));
-
+    $temp->add(new admin_setting_pickroles('profileroles',
+        get_string('profileroles','admin'),
+        get_string('configprofileroles', 'admin'),
+        array('student', 'teacher', 'editingteacher')));
+    
     $max_upload_choices = get_max_upload_sizes();
     // maxbytes set to 0 will allow the maxium server lmit for uploads
     $max_upload_choices[0] = get_string('serverlimit', 'admin');
index d4e46e6..2fa348c 100644 (file)
@@ -37,7 +37,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
     $optionalsubsystems->add(new admin_setting_pickroles('progresstrackedroles',
         get_string('progresstrackedroles','completion'),
         get_string('configprogresstrackedroles', 'completion'),
-        array('moodle/legacy:student')));
+        array('student')));
     $optionalsubsystems->add(new admin_setting_configcheckbox('enableavailability',
         get_string('enableavailability','condition'),
         get_string('configenableavailability','condition'), 0));
index 2a5ebf3..3029472 100644 (file)
@@ -84,65 +84,78 @@ if ($hassiteconfig
     if ($ADMIN->fulltree) {
         if (!during_initial_install()) {
             $context = get_context_instance(CONTEXT_SYSTEM);
-            if (!$guestrole = get_guest_role()) {
-                $guestrole->id = 0;
-            }
-            if ($studentroles = get_roles_with_capability('moodle/legacy:student', CAP_ALLOW)) {
-                $studentrole = array_shift($studentroles);   /// Take the first one
-            } else {
-                $studentrole->id = 0;
-            }
-            if ($userroles = get_roles_with_capability('moodle/legacy:user', CAP_ALLOW)) {
-                $userrole = array_shift($userroles);   /// Take the first one
-            } else {
-                $userrole->id = 0;
-            }
-            if (empty($CFG->creatornewroleid)) {
-                if ($teacherroles = get_roles_with_capability('moodle/legacy:editingteacher', CAP_ALLOW, $context)) {
-                    $teachereditrole = array_shift($teacherroles);
-                    set_config('creatornewroleid', $teachereditrole->id);
-                } else {
-                    set_config('creatornewroleid', 0);
+            $allroles        = array();
+            $generalroles    = array();
+            $guestroles      = array();
+            $userroles       = array();
+            $studentroles    = array();
+            $teacherroles    = array();
+            $creatornewroles = array();
+            
+            foreach (get_all_roles() as $role) {
+                $rolename = strip_tags(format_string($role->name)) . ' ('. $role->shortname . ')';
+                $allroles[$role->id] = $rolename;
+                switch ($role->archetype) {
+                    case 'manager':
+                        $creatornewroles[$role->id] = $rolename;
+                        break;
+                    case 'coursecreator':
+                        break;
+                    case 'editingteacher':
+                        $teacherroles[$role->id] = $rolename;
+                        $creatornewroles[$role->id] = $rolename;
+                        break;
+                    case 'teacher':
+                        $creatornewroles[$role->id] = $rolename;
+                        break;
+                    case 'student':
+                        $studentroles[$role->id] = $rolename;
+                        break;
+                    case 'guest':
+                        $guestroles[$role->id] = $rolename;
+                        break;
+                    case 'user':
+                        $userroles[$role->id] = $rolename;
+                        break;
+                    case 'frontpage':
+                        break;
+                    default:
+                        $creatornewroles[$role->id] = $rolename;
+                        $generalroles[$role->id] = $rolename;
+                        break;
                 }
             }
-            if (!$guestroles = get_roles_with_capability('moodle/legacy:guest', CAP_ALLOW)) {
-                $guestroles = array();
-                $defaultguestid = null;
-            } else {
-                $defaultguestid = reset($guestroles);
-                $defaultguestid = $defaultguestid->id;
-            }
 
-            // we must not use assignable roles here:
-            //   1/ unsetting roles as assignable for admin might bork the settings!
-            //   2/ default user role should not be assignable anyway
-            $allroles = array();
-            $nonguestroles = array();
-            if ($roles = get_all_roles()) {
-                foreach ($roles as $role) {
-                    $rolename = strip_tags(format_string($role->name, true));
-                    $allroles[$role->id] = $rolename;
-                    if (!isset($guestroles[$role->id])) {
-                        $nonguestroles[$role->id] = $rolename;
-                    }
-                }
+            reset($guestroles);
+            $defaultguestid = key($guestroles);
+            reset($studentroles);
+            $defaultstudentid = key($studentroles);
+            reset($teacherroles);
+            $defaultteacherid = key($teacherroles);
+            
+            if ($userroles) {
+                reset($userroles);
+                $defaultuserid = key($userroles);
+            } else {
+                $userroles = array('0'=>get_string('none'));
+                $defaultuserid = 0;
             }
 
             $temp->add(new admin_setting_configselect('notloggedinroleid', get_string('notloggedinroleid', 'admin'),
-                          get_string('confignotloggedinroleid', 'admin'), $defaultguestid, $allroles ));
+                          get_string('confignotloggedinroleid', 'admin'), $defaultguestid, ($guestroles + $generalroles)));
             $temp->add(new admin_setting_configselect('guestroleid', get_string('guestroleid', 'admin'),
-                          get_string('configguestroleid', 'admin'), $defaultguestid, $allroles));
+                          get_string('configguestroleid', 'admin'), $defaultguestid, ($guestroles + $generalroles)));
             $temp->add(new admin_setting_configselect('defaultuserroleid', get_string('defaultuserroleid', 'admin'),
-                          get_string('configdefaultuserroleid', 'admin'), $userrole->id, $nonguestroles)); // guest role here breaks a lot of stuff
+                          get_string('configdefaultuserroleid', 'admin'), $defaultuserid, ($userroles + $generalroles)));
         }
 
         $temp->add(new admin_setting_configcheckbox('nodefaultuserrolelists', get_string('nodefaultuserrolelists', 'admin'), get_string('confignodefaultuserrolelists', 'admin'), 0));
 
         if (!during_initial_install()) {
             $temp->add(new admin_setting_configselect('defaultcourseroleid', get_string('defaultcourseroleid', 'admin'),
-                          get_string('configdefaultcourseroleid', 'admin'), $studentrole->id, $allroles));
+                          get_string('configdefaultcourseroleid', 'admin'), $defaultstudentid, $allroles));
             $temp->add(new admin_setting_configselect('creatornewroleid', get_string('creatornewroleid', 'admin'),
-                          get_string('configcreatornewroleid', 'admin'), $CFG->creatornewroleid, $allroles));
+                          get_string('configcreatornewroleid', 'admin'), $defaultteacherid, $creatornewroles));
         }
 
         $temp->add(new admin_setting_configcheckbox('autologinguests', get_string('autologinguests', 'admin'), get_string('configautologinguests', 'admin'), 0));
@@ -174,6 +187,9 @@ if ($hassiteconfig
     }
     $ADMIN->add('roles', $temp);
 
+    if (is_siteadmin()) {
+        $ADMIN->add('roles', new admin_externalpage('admins', get_string('siteadministrators', 'role'), "$CFG->wwwroot/$CFG->admin/roles/admins.php"));
+    }
     $ADMIN->add('roles', new admin_externalpage('defineroles', get_string('defineroles', 'role'), "$CFG->wwwroot/$CFG->admin/roles/manage.php", 'moodle/role:manage'));
     $ADMIN->add('roles', new admin_externalpage('assignroles', get_string('assignglobalroles', 'role'), "$CFG->wwwroot/$CFG->admin/roles/assign.php?contextid=".$systemcontext->id, 'moodle/role:assign'));
     $ADMIN->add('roles', new admin_externalpage('checkpermissions', get_string('checkglobalpermissions', 'role'), "$CFG->wwwroot/$CFG->admin/roles/check.php?contextid=".$systemcontext->id, array('moodle/role:assign', 'moodle/role:safeoverride', 'moodle/role:override', 'moodle/role:manage')));
index b085ddc..39669f9 100755 (executable)
@@ -322,7 +322,7 @@ if ($formdata = $mform->is_cancelled()) {
                 continue;
             }
             if ($existinguser) {
-                if (has_capability('moodle/site:doanything', $systemcontext, $existinguser->id)) {
+                if (is_siteadmin($existinguser->id)) {
                     $upt->track('status', $strusernotdeletedadmin, 'error');
                     $deleteerrors++;
                     continue;
@@ -360,7 +360,7 @@ if ($formdata = $mform->is_cancelled()) {
 
             if ($olduser = $DB->get_record('user', array('username'=>$oldusername, 'mnethostid'=>$user->mnethostid))) {
                 $upt->track('id', $olduser->id, 'normal', false);
-                if (has_capability('moodle/site:doanything', $systemcontext, $olduser->id)) {
+                if (is_siteadmin($olduser->id)) {
                     $upt->track('status', $strusernotrenamedadmin, 'error');
                     $renameerrors++;
                     continue;
@@ -423,7 +423,7 @@ if ($formdata = $mform->is_cancelled()) {
         if ($existinguser) {
             $user->id = $existinguser->id;
 
-            if (has_capability('moodle/site:doanything', $systemcontext, $user->id)) {
+            if (is_siteadmin($user->id)) {
                 $upt->track('status', $strusernotupdatedadmin, 'error');
                 $userserrors++;
                 continue;
@@ -668,7 +668,7 @@ if ($formdata = $mform->is_cancelled()) {
             // find group to add to
             if (!empty($user->{'group'.$i})) {
                 // make sure user is enrolled into course before adding into groups
-                if (!has_capability('moodle/course:view', $coursecontext, $user->id, false)) {
+                if (!is_enrolled($coursecontext, $user->id)) {
                     $upt->track('enrolments', get_string('addedtogroupnotenrolled', '', $gname), 'error');
                     continue;
                 }
@@ -1175,12 +1175,6 @@ function uu_allowed_roles($shortname=false) {
             $choices[$role->id] = format_string($role->name);
         }
     }
-    // get rid of all admin roles
-    if ($adminroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW)) {
-        foreach($adminroles as $adminrole) {
-            unset($choices[$adminrole->id]);
-        }
-    }
 
     return $choices;
 }
index 48a9158..14c40ab 100644 (file)
@@ -121,7 +121,7 @@ class admin_uploaduser_form2 extends moodleform {
             unset($choices[0]);
 
             $mform->addElement('select', 'uulegacy2', get_string('uulegacy2role', 'admin'), $choices);
-            if ($editteacherroles = get_roles_with_capability('moodle/legacy:editingteacher', CAP_ALLOW)) {
+            if ($editteacherroles = get_archetype_roles('editingteacher')) {
                 $editteacherrole = array_shift($editteacherroles);   /// Take the first one
                 $mform->setDefault('uulegacy2', $editteacherrole->id);
                 unset($editteacherroles);
@@ -130,7 +130,7 @@ class admin_uploaduser_form2 extends moodleform {
             }
 
             $mform->addElement('select', 'uulegacy3', get_string('uulegacy3role', 'admin'), $choices);
-            if ($teacherroles = get_roles_with_capability('moodle/legacy:teacher', CAP_ALLOW)) {
+            if ($teacherroles = get_archetype_roles('teacher')) {
                 $teacherrole = array_shift($teacherroles);   /// Take the first one
                 $mform->setDefault('uulegacy3', $teacherrole->id);
                 unset($teacherroles);
index 0e6ed07..c192dc2 100644 (file)
@@ -59,7 +59,7 @@ class service_user_selector extends user_selector_base {
         //by default wherecondition retrieves all users except the deleted, not
         //confirmed and guest
         list($wherecondition, $params) = $this->search_sql($search, 'u');
-        $params[] = $this->serviceid;
+        $params['serviceid'] = $this->serviceid;
 
 
         $fields      = 'SELECT ' . $this->required_fields_sql('u');
@@ -70,13 +70,13 @@ class service_user_selector extends user_selector_base {
             $sql = " FROM {user} u, {external_services_users} esu
                  WHERE $wherecondition
                        AND esu.userid = u.id
-                       AND esu.externalserviceid = ?";
+                       AND esu.externalserviceid = :serviceid";
         }
         else {
             ///the following SQL retrieve all users that are not allowed to the serviceid
             $sql = " FROM {user} u WHERE $wherecondition
                  AND NOT EXISTS (SELECT esu.userid FROM {external_services_users} esu
-                                                  WHERE esu.externalserviceid = ?
+                                                  WHERE esu.externalserviceid = :serviceid
                                                         AND esu.userid = u.id)";
         }
 
index 9687cdd..7652e0d 100644 (file)
@@ -797,7 +797,7 @@ if ( !is_object($PHPCAS_CLIENT) ) {
 
                 $sitecontext = get_context_instance(CONTEXT_SYSTEM);
                 if (!empty($this->config->creators) and !empty($this->config->memberattribute)
-                  and $roles = get_roles_with_capability('moodle/legacy:coursecreator', CAP_ALLOW)) {
+                  and $roles = get_archetype_roles('coursecreator')) {
                     $creatorrole = array_shift($roles);      // We can only use one, let's use the first one
                 } else {
                     $creatorrole = false;
@@ -846,7 +846,7 @@ if ( !is_object($PHPCAS_CLIENT) ) {
 
             $sitecontext = get_context_instance(CONTEXT_SYSTEM);
             if (!empty($this->config->creators) and !empty($this->config->memberattribute)
-              and $roles = get_roles_with_capability('moodle/legacy:coursecreator', CAP_ALLOW)) {
+              and $roles = get_archetype_roles('coursecreator')) {
                 $creatorrole = array_shift($roles);      // We can only use one, let's use the first one
             } else {
                 $creatorrole = false;
@@ -1118,7 +1118,7 @@ if (!empty($this->config->attrcreators)) {
         if ($iscreator === null) {
             return; //nothing to sync - creators not configured
         }
-        if ($roles = get_roles_with_capability('moodle/legacy:coursecreator', CAP_ALLOW)) {
+        if ($roles = get_archetype_roles('coursecreator')) {
             $creatorrole = array_shift($roles);      // We can only use one, let's use the first one
             $systemcontext = get_context_instance(CONTEXT_SYSTEM);
             if ($iscreator) { // Following calls will not create duplicates
index 8e90182..ce9a593 100644 (file)
@@ -178,7 +178,7 @@ class auth_plugin_fc extends auth_plugin_base {
             return; //nothing to sync - creators not configured
         }
 
-        if ($roles = get_roles_with_capability('moodle/legacy:coursecreator', CAP_ALLOW)) {
+        if ($roles = get_archetype_roles('coursecreator')) {
             $creatorrole = array_shift($roles);      // We can only use one, let's use the first one
             $systemcontext = get_context_instance(CONTEXT_SYSTEM);
 
index 57ab132..e92af76 100644 (file)
@@ -724,7 +724,7 @@ class auth_plugin_ldap extends auth_plugin_base {
 
                 $sitecontext = get_context_instance(CONTEXT_SYSTEM);
                 if (!empty($this->config->creators) and !empty($this->config->memberattribute)
-                  and $roles = get_roles_with_capability('moodle/legacy:coursecreator', CAP_ALLOW)) {
+                  and $roles = get_archetype_roles('coursecreator')) {
                     $creatorrole = array_shift($roles);      // We can only use one, let's use the first one
                 } else {
                     $creatorrole = false;
@@ -774,7 +774,7 @@ class auth_plugin_ldap extends auth_plugin_base {
 
             $sitecontext = get_context_instance(CONTEXT_SYSTEM);
             if (!empty($this->config->creators) and !empty($this->config->memberattribute)
-              and $roles = get_roles_with_capability('moodle/legacy:coursecreator', CAP_ALLOW)) {
+              and $roles = get_archetype_roles('coursecreator')) {
                 $creatorrole = array_shift($roles);      // We can only use one, let's use the first one
             } else {
                 $creatorrole = false;
@@ -1945,7 +1945,7 @@ class auth_plugin_ldap extends auth_plugin_base {
             return; //nothing to sync - creators not configured
         }
 
-        if ($roles = get_roles_with_capability('moodle/legacy:coursecreator', CAP_ALLOW)) {
+        if ($roles = get_archetype_roles('coursecreator')) {
             $creatorrole = array_shift($roles);      // We can only use one, let's use the first one
             $systemcontext = get_context_instance(CONTEXT_SYSTEM);
 
index 29fe238..7ca250a 100644 (file)
@@ -141,8 +141,8 @@ class auth_plugin_mnet extends auth_plugin_base {
         // check remote login permissions
         if (! has_capability('moodle/site:mnetlogintoremote', get_context_instance(CONTEXT_SYSTEM))
                 or is_mnet_remote_user($USER)
-                or $USER->username == 'guest'
-                or empty($USER->id)) {
+                or isguestuser()
+                or !isloggedin()) {
             print_error('notpermittedtojump', 'mnet');
         }
 
index 64571d6..775bfed 100644 (file)
     function backup_get_enrolled_users ($courseid) {
         global $CFG;
 
-        // get all users with moodle/course:view capability, this will include people
+        // get all users with moodle/course:participate capability, this will include people
         // assigned at cat level, or site level
         // but it should be ok if they have no direct assignment at course, mod, block level
-        return get_users_by_capability(get_context_instance(CONTEXT_COURSE, $courseid), 'moodle/course:view', '', '', '', '', '', '', false);
+        return get_users_by_capability(get_context_instance(CONTEXT_COURSE, $courseid), 'moodle/course:participate', '', '', '', '', '', '', false);
     }
 
     //Returns all users ids (every record in users table)
                         if (backup_getid($preferences->backup_unique_code, 'user', $assignment->userid)) {
                             fwrite ($bf, start_tag("ASSIGNMENT", $startlevel+3, true));
                             fwrite ($bf, full_tag("USERID", $startlevel+4, false, $assignment->userid));
-                            fwrite ($bf, full_tag("HIDDEN", $startlevel+4, false, $assignment->hidden));
                             fwrite ($bf, full_tag("TIMESTART", $startlevel+4, false, $assignment->timestart));
                             fwrite ($bf, full_tag("TIMEEND", $startlevel+4, false, $assignment->timeend));
                             fwrite ($bf, full_tag("TIMEMODIFIED", $startlevel+4, false, $assignment->timemodified));
index 3ec04cb..3331d27 100644 (file)
@@ -636,7 +636,7 @@ if ($restoreuserinfo) {
         echo ('</td><td algin="left">');
 
         // get the first teacheredit legacy
-        $roles = get_roles_with_capability('moodle/legacy:editingteacher', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM));
+        $roles = get_archetype_roles('editingteacher');
 
         $editteacher = reset($roles);
         echo html_writer::select($siterolesarray, "defaultteacheredit", $editteacher->id, array(''=>'new role'));
@@ -649,7 +649,7 @@ if ($restoreuserinfo) {
         echo ('</td><td algin="left">');
 
         // get the first teacheredit legacy
-        $roles = get_roles_with_capability('moodle/legacy:teacher', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM));
+        $roles = get_archetype_roles('teacher');
         $teacher = reset($roles);
 
         echo html_writer::select($siterolesarray, "defaultteacher", $teacher->id, array(''=>'new role'));
@@ -662,7 +662,7 @@ if ($restoreuserinfo) {
         echo ('</td><td algin="left">');
 
         // get the first teacheredit legacy
-        $roles = get_roles_with_capability('moodle/legacy:student', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM));
+        $roles = get_archetype_roles('student');
         $studentrole = array_shift($roles);
 
         echo html_writer::select($siterolesarray, "defaultstudent", $studentrole->id, array(''=>'new role'));
index e018a9e..6e4fab0 100644 (file)
@@ -1557,7 +1557,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
                     // anything except id
                     $restore->userswhocanviewcourse=get_users_by_capability(
                         get_context_instance(CONTEXT_COURSE, $restore->course_id),
-                        'moodle/course:view','u.id');
+                        'moodle/course:participate','u.id');
                 }
 
                 foreach($info->completiondata as $data) {
@@ -5952,9 +5952,6 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
                                 $this->info->tempuser = $this->getContents();
                                 $this->info->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->userid = $this->getContents();
                             break;
-                            case "HIDDEN":
-                                $this->info->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->hidden = $this->getContents();
-                            break;
                             case "TIMESTART":
                                 $this->info->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->timestart = $this->getContents();
                             break;
@@ -6175,9 +6172,6 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
 
                                 $this->info->tempinstance->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->userid = $this->getContents();
                             break;
-                            case "HIDDEN":
-                                $this->info->tempinstance->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->hidden = $this->getContents();
-                            break;
                             case "TIMESTART":
                                 $this->info->tempinstance->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->timestart = $this->getContents();
                             break;
@@ -6428,9 +6422,6 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
 
                                 $this->info->tempsection->mods[$this->info->tempmod->id]->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->userid = $this->getContents();
                             break;
-                            case "HIDDEN":
-                                $this->info->tempsection->mods[$this->info->tempmod->id]->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->hidden = $this->getContents();
-                            break;
                             case "TIMESTART":
                                 $this->info->tempsection->mods[$this->info->tempmod->id]->roleassignments[$this->info->tempid]->assignments[$this->info->tempuser]->timestart = $this->getContents();
                             break;
@@ -7315,9 +7306,6 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
 
                                 $this->info->tempuser->roleassignments[$this->info->tempid]->assignments[$this->info->tempuserid]->userid = $this->getContents();
                             break;
-                            case "HIDDEN":
-                                $this->info->tempuser->roleassignments[$this->info->tempid]->assignments[$this->info->tempuserid]->hidden = $this->getContents();
-                            break;
                             case "TIMESTART":
                                 $this->info->tempuser->roleassignments[$this->info->tempid]->assignments[$this->info->tempuserid]->timestart = $this->getContents();
                             break;
@@ -9171,7 +9159,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
                 if ($CFG->creatornewroleid) {
                     role_assign($CFG->creatornewroleid, $USER->id, 0, $newcontext->id);
                 } else {
-                    if ($legacyteachers = get_roles_with_capability('moodle/legacy:editingteacher', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM))) {
+                    if ($legacyteachers = get_archetype_roles('editingteacher')) {
                         if ($legacyteacher = array_shift($legacyteachers)) {
                             role_assign($legacyteacher->id, $USER->id, 0, $newcontext->id);
                         }
index 27eafb1..bda3cb2 100644 (file)
@@ -20,16 +20,15 @@ class block_admin extends block_list {
 
         $course = $this->page->course;
 
-        if (!has_capability('moodle/course:view', $this->page->context)) {  // Just return
-            return $this->content;
-        }
-
         if (empty($CFG->loginhttps)) {
             $securewwwroot = $CFG->wwwroot;
         } else {
             $securewwwroot = str_replace('http:','https:',$CFG->wwwroot);
         }
 
+        $isenrolled = is_enrolled($this->page->context);
+        $isviewing = is_viewing($this->page->context);
+
     /// Course editing on/off
         if ($course->id !== SITEID and has_capability('moodle/course:update', $this->page->context)) {
             $this->content->icons[]='<img src="'.$OUTPUT->pix_url('i/edit') . '" class="icon" alt="" />';
@@ -56,7 +55,7 @@ class block_admin extends block_list {
 
     /// View course grades (or just your own grades, same link)
     /// find all accessible reports
-        if ($course->id !== SITEID) {
+        if ($course->id !== SITEID and ($isenrolled or $isviewing)) {
             $reportavailable = false;
             if (has_capability('moodle/grade:viewall', $this->page->context)) {
                 $reportavailable = true;
@@ -194,17 +193,23 @@ class block_admin extends block_list {
 
     /// Unenrol link
         if (empty($course->metacourse) && ($course->id!==SITEID)) {
-            if (has_capability('moodle/legacy:guest', $this->page->context, NULL, false)) {   // Are a guest now
+            if ($isenrolled) {
+                if (has_capability('moodle/role:unassignself', $this->page->context, NULL, false) and get_user_roles($this->page->context, $USER->id, false)) {  // Have some role
+                    $this->content->items[]='<a href="'.$CFG->wwwroot.'/course/unenrol.php?id='.$course->id.'">'.get_string('unenrolme', '', format_string($course->shortname)).'</a>';
+                    $this->content->icons[]='<img src="'.$OUTPUT->pix_url('i/user') . '" class="icon" alt="" />';
+                }
+                
+            } else if ($isviewing) {
+                // inspector, manager, etc. - do not show anything
+            } else {
+                // access because otherwise they would not get into this course at all
                 $this->content->items[]='<a href="'.$CFG->wwwroot.'/course/enrol.php?id='.$course->id.'">'.get_string('enrolme', '', format_string($course->shortname)).'</a>';
                 $this->content->icons[]='<img src="'.$OUTPUT->pix_url('i/user') . '" class="icon" alt="" />';
-            } else if (has_capability('moodle/role:unassignself', $this->page->context, NULL, false) and get_user_roles($this->page->context, $USER->id, false)) {  // Have some role
-                $this->content->items[]='<a href="'.$CFG->wwwroot.'/course/unenrol.php?id='.$course->id.'">'.get_string('unenrolme', '', format_string($course->shortname)).'</a>';
-                $this->content->icons[]='<img src="'.$OUTPUT->pix_url('i/user') . '" class="icon" alt="" />';
             }
         }
 
-    /// Link to the user own profile (except guests)
-        if (!isguestuser() and isloggedin()) {
+    /// Link to the user own profile if they are enrolled
+        if ($isenrolled) {
             $this->content->items[]='<a href="'.$CFG->wwwroot.'/user/view.php?id='.$USER->id.'&amp;course='.$course->id.'">'.get_string('profile').'</a>';
             $this->content->icons[]='<img src="'.$OUTPUT->pix_url('i/user') . '" alt="" />';
         }
index 8da9137..f99922c 100644 (file)
@@ -108,7 +108,7 @@ class block_admin_tree extends block_base {
         }
 
         if (isguestuser() or !isloggedin()) {
-            // these users can not change any settings
+            // shortcut - these users can not change any settings
             $this->content = '';
             return '';
         }
index 4f90864..1ed7932 100644 (file)
@@ -38,9 +38,10 @@ class block_comments extends block_base {
         }
         $this->content->footer = '';
         $this->content->text = '';
+        //TODO: guest and not-logged-in shoudl be able to read comments, right?
         if (isloggedin() && !isguestuser()) {   // Show the block
             $cmt = new stdclass;
-            $cmt->context   = $this->instance->context;
+            $cmt->context   = $this->context;
             $cmt->area      = 'block_comments';
             $cmt->itemid    = $this->instance->id;
             $cmt->course    = $this->page->course;
index 010f914..3a1923a 100644 (file)
@@ -34,10 +34,8 @@ class block_course_list extends block_list {
            }
         }
 
-        if (empty($CFG->disablemycourses) and
-            !empty($USER->id) and
-            !(has_capability('moodle/course:update', get_context_instance(CONTEXT_SYSTEM)) and $adminseesall) and
-            !isguestuser()) {    // Just print My Courses
+        if (empty($CFG->disablemycourses) and isloggedin() and !isguestuser() and
+          !(has_capability('moodle/course:update', get_context_instance(CONTEXT_SYSTEM)) and $adminseesall)) {    // Just print My Courses
             if ($courses = get_my_courses($USER->id, 'visible DESC, fullname ASC')) {
                 foreach ($courses as $course) {
                     if ($course->id == SITEID) {
@@ -118,7 +116,7 @@ class block_course_list extends block_list {
 
         $icon  = '<img src="'.$OUTPUT->pix_url('i/mnethost') . '" class="icon" alt="'.get_string('course').'" />';
 
-        // only for logged in users!
+        // shortcut - the rest is only for logged in users!
         if (!isloggedin() || isguestuser()) {
             return false;
         }
index 9590718..9f501ab 100644 (file)
@@ -94,7 +94,7 @@ class block_global_navigation_tree extends block_tree {
         global $CFG, $OUTPUT;
         // First check if we have already generated, don't waste cycles
         if ($this->contentgenerated === true) {
-            return true;
+            return $this->content;
         }
         $this->page->requires->yui2_lib('dom');
         // JS for navigation moved to the standard theme, the code will probably have to depend on the actual page structure
@@ -158,7 +158,7 @@ class block_global_navigation_tree extends block_tree {
         $module = array('name'=>'block_navigation', 'fullpath'=>'/blocks/global_navigation_tree/navigation.js', 'requires'=>array('core_dock', 'io', 'node', 'dom', 'event-custom', 'json-parse'));
         $arguments = array($this->instance->id, array('expansions'=>$expandable, 'instance'=>$this->instance->id, 'candock'=>$this->instance_can_be_docked()));
         $this->page->requires->js_init_call('M.block_navigation.init_add_tree', $arguments, false, $module);
-        
+
         // Grab the items to display
         $this->content->items = array($this->page->navigation);
 
@@ -168,7 +168,8 @@ class block_global_navigation_tree extends block_tree {
 
         // Set content generated to true so that we know it has been done
         $this->contentgenerated = true;
-        return true;
+
+        return $this->content;
     }
 
     /**
index 9275854..19ba42f 100644 (file)
@@ -25,7 +25,7 @@ class block_messages extends block_base {
         $this->content->text = '';
         $this->content->footer = '';
 
-        if (empty($this->instance) or empty($USER->id) or isguestuser() or empty($CFG->messaging)) {
+        if (empty($this->instance) or !isloggedin() or isguestuser() or empty($CFG->messaging)) {
             return $this->content;
         }
 
index 111af03..4242a0d 100644 (file)
@@ -21,7 +21,7 @@ class block_mnet_hosts extends block_list {
     function get_content() {
         global $CFG, $USER, $DB, $OUTPUT;
 
-        // only for logged in users!
+        // shortcut -  only for logged in users!
         if (!isloggedin() || isguestuser()) {
             return false;
         }
index 7601d98..0e7c2a7 100644 (file)
@@ -555,11 +555,7 @@ class block_base {
             $this->config = unserialize(base64_decode($instance->configdata));
         }
         $this->instance = $instance;
-        if (isset($instance->context)) {
-            $this->context = $instance->context;
-        } else {
-            $this->context = get_context_instance(CONTEXT_BLOCK, $instance->id);
-        }
+        $this->context = get_context_instance(CONTEXT_BLOCK, $instance->id);
         $this->page = $page;
         $this->specialization();
         $this->get_required_javascript();
index 34b12cb..b94c651 100644 (file)
@@ -102,7 +102,7 @@ class block_news_items extends block_base {
                 } else {
                     $tooltiptext = get_string('rsssubscriberssposts','forum',format_string($forum->name));
                 }
-                if (empty($USER->id)) {
+                if (!isloggedin()) {
                     $userid = 0;
                 } else {
                     $userid = $USER->id;
index 8a2243e..7cc7556 100644 (file)
@@ -55,12 +55,14 @@ class block_online_users extends block_base {
             $params['currentgroup'] = $currentgroup;
         }
 
+        $userfields = user_picture::fields('u').', username';
+
         if ($this->page->course->id == SITEID) {  // Site-level
-            $sql = "SELECT u.id, u.username, u.firstname, u.lastname, u.picture, MAX(u.lastaccess) AS lastaccess
+            $sql = "SELECT $userfields, MAX(u.lastaccess) AS lastaccess
                       FROM {user} u $groupmembers
                      WHERE u.lastaccess > $timefrom
                            $groupselect
-                  GROUP BY u.id, u.username, u.firstname, u.lastname, u.picture
+                  GROUP BY $userfields
                   ORDER BY lastaccess DESC ";
 
            $csql = "SELECT COUNT(u.id), u.id
@@ -69,24 +71,26 @@ class block_online_users extends block_base {
                            $groupselect
                   GROUP BY u.id";
 
-        } else { // Course-level
-            if (!has_capability('moodle/role:viewhiddenassigns', $this->page->context)) {
-                $pcontext = get_related_contexts_string($this->page->context);
-                $rafrom  = ", {role_assignments} ra";
-                $rawhere = " AND ra.userid = u.id AND ra.contextid $pcontext AND ra.hidden = 0";
-            }
+        } else {
+            // Course level - show only enrolled users for now
+            // TODO: add a new capability for viewing of all users (guests+enrolled+viewing)
+
+            list($esqljoin, $eparams) = get_enrolled_sql($this->page->context);
+            $params = array_merge($params, $eparams);
 
-            $sql = "SELECT u.id, u.username, u.firstname, u.lastname, u.picture, MAX(ul.timeaccess) AS lastaccess
+            $sql = "SELECT $userfields, MAX(ul.timeaccess) AS lastaccess
                       FROM {user_lastaccess} ul, {user} u $groupmembers $rafrom
+                      JOIN ($esqljoin) euj ON euj.id = u.id     
                      WHERE ul.timeaccess > $timefrom
                            AND u.id = ul.userid
                            AND ul.courseid = :courseid
                            $groupselect $rawhere
-                  GROUP BY u.id, u.username, u.firstname, u.lastname, u.picture
+                  GROUP BY $userfields
                   ORDER BY lastaccess DESC";
 
            $csql = "SELECT u.id
                       FROM {user_lastaccess} ul, {user} u $groupmembers $rafrom
+                      JOIN ($esqljoin) euj ON euj.id = u.id
                      WHERE ul.timeaccess > $timefrom
                            AND u.id = ul.userid
                            AND ul.courseid = :courseid
@@ -131,7 +135,7 @@ class block_online_users extends block_base {
             //Accessibility: Don't want 'Alt' text for the user picture; DO want it for the envelope/message link (existing lang string).
             //Accessibility: Converted <div> to <ul>, inherit existing classes & styles.
             $this->content->text .= "<ul class='list'>\n";
-            if (!empty($USER->id) && has_capability('moodle/site:sendmessage', $this->page->context)
+            if (isloggedin() && has_capability('moodle/site:sendmessage', $this->page->context)
                            && !empty($CFG->messaging) && !isguestuser()) {
                 $canshowicon = true;
             } else {
index 3cddaad..c7735fd 100644 (file)
@@ -35,7 +35,7 @@ $capabilities = array(
             'student' => CAP_ALLOW,
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     )
 );
index f086790..008219d 100644 (file)
@@ -286,7 +286,7 @@ class block_quiz_results extends block_base {
             case SEPARATEGROUPS:
             // This is going to be just like no-groups mode, only we 'll filter
             // out the grades from people not in our group.
-            if(empty($USER) || empty($USER->id)) {
+            if (!isloggedin()) {
                 // Not logged in, so show nothing
                 return $this->content;
             }
index 616ac49..9b1e623 100644 (file)
@@ -37,7 +37,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     ),
 
@@ -48,7 +48,7 @@ $capabilities = array(
         'captype' => 'write',
         'contextlevel' => CONTEXT_BLOCK,
         'legacy' => array(
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     )
 
index d6b7067..aa37097 100644 (file)
@@ -102,7 +102,7 @@ class block_section_links extends block_base {
             }
         }
 
-        if (!empty($USER->id)) {
+        if (isloggedin()) {
             $display = $DB->get_field('course_display', 'display', array('course'=>$this->page->course->id, 'userid'=>$USER->id));
         }
         if (!empty($display)) {
index 8421d14..dbd75d4 100644 (file)
@@ -79,8 +79,7 @@ class block_tags extends block_base {
 
             // Permissions and page awareness
             $systemcontext = get_context_instance(CONTEXT_SYSTEM);
-            $isguest = has_capability('moodle/legacy:guest', $systemcontext, $USER->id, false);
-            $loggedin = isloggedin() && !$isguest;
+            $loggedin = isloggedin() && !isguestuser();
             $coursepage = $canedit = false;
             $coursepage = (isset($this->page->course->id) && $this->page->course->id != SITEID);
             $mymoodlepage = ($SCRIPT == '/my/index.php') ? true : false;
index c16ff95..d255be0 100644 (file)
@@ -132,7 +132,7 @@ class blog_edit_form extends moodleform {
             $coursecontext = $DB->get_record('context', array('id' => $data['courseassoc'], 'contextlevel' => CONTEXT_COURSE));
 
             if ($coursecontext)  {
-                if (!has_capability('moodle/course:view', $coursecontext, $USER->id)) {
+                if (!is_enrolled($coursecontext) and !is_viewing($coursecontext)) {
                     $errors['courseassoc'] = get_string('studentnotallowed', '', fullname($USER, true));
                 }
             } else {
@@ -161,7 +161,7 @@ class blog_edit_form extends moodleform {
                 }
 
                 // ensure the user has access to each mod's course
-                if (!has_capability('moodle/course:view', $coursecontext)) {
+                if (!is_enrolled($modcontext) and !is_viewing($modcontext)) {
                     $errors['modassoc'] = get_string('studentnotallowed', '', fullname($USER, true));
                 }
             } else {
index 27776e1..596e0d1 100755 (executable)
@@ -67,7 +67,7 @@ function blog_user_can_view_user_entry($targetuserid, $blogentry=null) {
         return false; // blog system disabled
     }
 
-    if (!empty($USER->id) && $USER->id == $targetuserid) {
+    if (isloggdin() && $USER->id == $targetuserid) {
         return true; // can view own entries in any case
     }
 
@@ -92,7 +92,7 @@ function blog_user_can_view_user_entry($targetuserid, $blogentry=null) {
         break;
 
         case BLOG_SITE_LEVEL:
-            if (!empty($USER->id)) { // not logged in viewers forbidden
+            if (isloggedin()) { // not logged in viewers forbidden
                 return true;
             }
             return false;
@@ -366,7 +366,6 @@ function blog_get_headers() {
         $cm = $DB->get_record('course_modules', array('id' => $modid));
         $cm->modname = $DB->get_field('modules', 'name', array('id' => $cm->module));
         $cm->name = $DB->get_field($cm->modname, 'name', array('id' => $cm->instance));
-        $cm->context = get_context_instance(CONTEXT_MODULE, $modid);
         $a->type = get_string('modulename', $cm->modname);
         $PAGE->set_cm($cm, $course);
         $headers['stradd'] = get_string('blogaboutthis', 'blog', $a);
index 567da35..15307e1 100644 (file)
@@ -588,7 +588,7 @@ class blog_entry {
             return false; // blog system disabled or user has no blog view capability
         }
 
-        if (!empty($USER->id) && $USER->id == $targetuserid) {
+        if (isloggedin() && $USER->id == $targetuserid) {
             return true; // can view own entries in any case
         }
 
@@ -612,7 +612,7 @@ class blog_entry {
                 break;
 
             case BLOG_SITE_LEVEL:
-                if (!empty($USER->id)) { // not logged in viewers forbidden
+                if (isloggedin()) { // not logged in viewers forbidden
                     return true;
                 }
                 return false;
@@ -743,7 +743,7 @@ class blog_listing {
             // don't add permission constraints
 
         } else {
-            if (isloggedin() && !has_capability('moodle/legacy:guest', get_context_instance(CONTEXT_SYSTEM, SITEID), $userid, false)) {
+            if (isloggedin() and !isguestuser()) {
                 $assocexists = $DB->record_exists('blog_association', array());  //dont check association records if there aren't any
 
                 //begin permission sql clause
index 11cd91c..9963053 100755 (executable)
@@ -9,8 +9,8 @@ function blog_rss_print_link($filtertype, $filterselect, $tagid=0, $tooltiptext=
 
     global $CFG, $USER, $OUTPUT;
 
-    if (empty($USER->id)) {
-        $userid = 1;
+    if (!isloggedin()) {
+        $userid = $CFG->siteguest;
     } else {
         $userid = $USER->id;
     }
index 0fb11f8..0a85a14 100644 (file)
@@ -105,19 +105,9 @@ if(!checkdate($mon, $day, $yr)) {
 }
 $time = make_timestamp($yr, $mon, $day);
 
-$isguest = has_capability('moodle/legacy:guest', get_context_instance(CONTEXT_SYSTEM), 0, false);
-
-if (empty($USER->id) or $isguest) {
-    $defaultcourses = calendar_get_default_courses();
-    calendar_set_filters($courses, $groups, $users, $defaultcourses, $defaultcourses);
-} else {
-    calendar_set_filters($courses, $groups, $users);
-}
-
-if (empty($USER->id) or $isguest) {
+if (!isloggedin() or isguestuser()) {
     $defaultcourses = calendar_get_default_courses();
     calendar_set_filters($courses, $groups, $users, $defaultcourses, $defaultcourses);
-
 } else {
     calendar_set_filters($courses, $groups, $users);
 }
index 8392b89..c3015a1 100644 (file)
@@ -858,7 +858,7 @@ function calendar_filter_controls($type, $vars = NULL, $course = NULL, $courses
     }
 
 
-    if(!empty($USER->id) && !has_capability('moodle/legacy:guest', get_context_instance(CONTEXT_SYSTEM), 0, false)) {
+    if (isloggedin() && !isguestuser()) {
         $content .= "</tr>\n<tr>";
 
         if($groupevents) {
@@ -1191,8 +1191,8 @@ function calendar_session_vars($course=null) {
         // The empty() instead of !isset() here makes a whole world of difference,
         // as it will automatically change to the user's id when the user first logs
         // in. With !isset(), it would never do that.
-        $SESSION->cal_users_shown = !empty($USER->id) ? $USER->id : false;
-    } else if(is_numeric($SESSION->cal_users_shown) && !empty($USER->id) && $SESSION->cal_users_shown != $USER->id) {
+        $SESSION->cal_users_shown = isloggedin() ? $USER->id : false;
+    } else if(is_numeric($SESSION->cal_users_shown) && isloggedin() && $SESSION->cal_users_shown != $USER->id) {
         // Follow the white rabbit, for example if a teacher logs in as a student
         $SESSION->cal_users_shown = $USER->id;
     }
@@ -1312,7 +1312,7 @@ function calendar_set_filters(&$courses, &$group, &$user, $courseeventsfrom = NU
                 }
 
                 // If the user is an editing teacher in there,
-                if (!empty($USER->id) && isset($courseeventsfrom[$courseid]->context) && has_capability('moodle/calendar:manageentries', $courseeventsfrom[$courseid]->context)) {
+                if (isloggedin() && isset($courseeventsfrom[$courseid]->context) && has_capability('moodle/calendar:manageentries', $courseeventsfrom[$courseid]->context)) {
                     // If this course has groups, show events from all of them
                     if(is_int($groupeventsfrom)) {
                         if (is_object($courseeventsfrom[$courseid])) { // SHOULD be set MDL-11221
@@ -1412,7 +1412,7 @@ function calendar_get_default_courses($ignoreref = false) {
         return array($SESSION->cal_course_referer => 1);
     }
 
-    if(empty($USER->id)) {
+    if (!isloggedin()) {
         return array();
     }
 
@@ -1438,7 +1438,7 @@ function calendar_preferences_button() {
     global $CFG, $USER;
 
     // Guests have no preferences
-    if (empty($USER->id) || has_capability('moodle/legacy:guest', get_context_instance(CONTEXT_SYSTEM), 0, false)) {
+    if (!isloggedin() || isguestuser()) {
         return '';
     }
 
@@ -1559,7 +1559,7 @@ function calendar_get_filters_status() {
 function calendar_set_filters_status($packed_bitfield) {
     global $SESSION, $USER;
 
-    if(!isset($USER) || empty($USER->id)) {
+    if (!isloggedin()) {
         return false;
     }
 
@@ -1617,7 +1617,7 @@ function calendar_add_event_allowed($event) {
     global $USER, $DB;
 
     // can not be using guest account
-    if (empty($USER->id) or $USER->username == 'guest') {
+    if (!isloggedin() or isguestuser()) {
         return false;
     }
 
index dce28d8..be41627 100644 (file)
@@ -128,7 +128,7 @@ if (!empty($courseid)) {
     $course = null;
 }
 
-if (empty($USER->id) or has_capability('moodle/legacy:guest', get_context_instance(CONTEXT_SYSTEM), 0, false)) {
+if (!isloggedin() or isguestuser()) {
     $defaultcourses = calendar_get_default_courses();
     calendar_set_filters($courses, $groups, $users, $defaultcourses, $defaultcourses);
 
@@ -182,7 +182,7 @@ echo $OUTPUT->container_start('bottom');
 if (!empty($CFG->enablecalendarexport)) {
     echo $OUTPUT->single_button(new moodle_url('export.php', array('course'=>$courseid)), get_string('exportcalendar', 'calendar'));
 
-    if (!empty($USER->id)) {
+    if (isloggedin()) {
         $authtoken = sha1($USER->username . $USER->password . $CFG->calendar_exportsalt);
         $usernameencoded = urlencode($USER->username);
 
@@ -257,7 +257,7 @@ function calendar_show_day($d, $m, $y, $courses, $groups, $users, $courseid) {
     $events = calendar_get_upcoming($courses, $groups, $users, 1, 100, $starttime);
 
     $text = '';
-    if (!has_capability('moodle/legacy:guest', get_context_instance(CONTEXT_SYSTEM), 0, false) && !empty($USER->id) && calendar_user_can_add_event()) {
+    if (!isguestuser() && isloggedin() && calendar_user_can_add_event()) {
         $text.= '<div class="buttons">';
         $text.= '<form action="'.CALENDAR_URL.'event.php" method="get">';
         $text.= '<div>';
@@ -403,7 +403,7 @@ function calendar_show_month_detailed($m, $y, $courses, $groups, $users, $course
     calendar_events_by_day($events, $m, $y, $eventsbyday, $durationbyday, $typesbyday, $courses);
 
     $text = '';
-    if(!has_capability('moodle/legacy:guest', get_context_instance(CONTEXT_SYSTEM), 0, false) && !empty($USER->id) && calendar_user_can_add_event()) {
+    if(!isguestuser() && isloggedin() && calendar_user_can_add_event()) {
         $text.= '<div class="buttons"><form action="'.CALENDAR_URL.'event.php" method="get">';
         $text.= '<div>';
         $text.= '<input type="hidden" name="action" value="new" />';
@@ -562,7 +562,7 @@ function calendar_show_month_detailed($m, $y, $courses, $groups, $users, $course
 
     echo "</tr>\n";
 
-    if(!empty($USER->id) && !has_capability('moodle/legacy:guest', get_context_instance(CONTEXT_SYSTEM), 0, false)) {
+    if(isloggedin() && !isguestuser()) {
         echo '<tr>';
         // Group events
         if($SESSION->cal_show_groups) {
@@ -593,7 +593,7 @@ function calendar_show_upcoming_events($courses, $groups, $users, $futuredays, $
 
     $text = '';
 
-    if(!has_capability('moodle/legacy:guest', get_context_instance(CONTEXT_SYSTEM), 0, false) && !empty($USER->id) && calendar_user_can_add_event()) {
+    if(!isguestuser() && isloggedin() && calendar_user_can_add_event()) {
         $text.= '<div class="buttons">';
         $text.= '<form action="'.CALENDAR_URL.'event.php" method="get">';
         $text.= '<div>';
@@ -629,7 +629,7 @@ function calendar_show_upcoming_events($courses, $groups, $users, $futuredays, $
 function calendar_course_filter_selector($getvars = '') {
     global $USER, $SESSION, $OUTPUT;
 
-    if (empty($USER->id) or has_capability('moodle/legacy:guest', get_context_instance(CONTEXT_SYSTEM), 0, false)) {
+    if (!isloggedin() or isguestuser()) {
         return '';
     }
 
index b5c1192..e5cd555 100644 (file)
@@ -29,12 +29,6 @@ list($context, $course, $cm) = get_context_info_array($contextid);
 require_login($course, true, $cm);
 require_sesskey();
 
-if (isguestuser()) {
-       $err = new stdclass;
-    $err->error = get_string('loggedinnot');
-    die(json_encode($err));
-}
-
 $action    = optional_param('action',    '',     PARAM_ALPHA);
 $area      = optional_param('area',      '',     PARAM_ALPHAEXT);
 $client_id = optional_param('client_id', '',     PARAM_RAW);
index 3b4849a..354805f 100644 (file)
@@ -27,10 +27,6 @@ list($context, $course, $cm) = get_context_info_array($contextid);
 require_login($course, true, $cm);
 require_sesskey();
 
-if (isguestuser()) {
-    print_error('loggedinnot');
-}
-
 $action    = optional_param('action',    '',     PARAM_ALPHA);
 $area      = optional_param('area',      '',     PARAM_ALPHAEXT);
 $commentid = optional_param('commentid', -1,     PARAM_INT);
index 1257ff1..793640f 100644 (file)
 
         $spacer = '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="iconsmall" alt="" /> ';
         foreach ($courses as $acourse) {
-            if (isset($acourse->context)) {
-                $coursecontext = $acourse->context;
-            } else {
-                $coursecontext = get_context_instance(CONTEXT_COURSE, $acourse->id);
-            }
+            $coursecontext = get_context_instance(CONTEXT_COURSE, $acourse->id);
 
             $count++;
             $up = ($count > 1 || !$atfirstpage);
index 8c18dbc..5c02da4 100644 (file)
@@ -12,7 +12,7 @@ class delete_category_form extends moodleform {
 
         $mform    =& $this->_form;
         $category = $this->_customdata;
-        ensure_context_subobj_present($category, CONTEXT_COURSECAT);
+        $categorycontext = get_context_instance(CONTEXT_COURSECAT, $category->id);
         $this->_category = $category;
 
     /// Check permissions, to see if it OK to give the option to delete
@@ -26,7 +26,8 @@ class delete_category_form extends moodleform {
             $checkcat = array_pop($tocheck);
             $childcategoryids[] = $checkcat->id;
             $tocheck = $tocheck + get_child_categories($checkcat->id);
-            if ($candeletecontent && !has_capability('moodle/category:manage', $checkcat->context)) {
+            $chcontext = get_context_instance(CONTEXT_COURSECAT, $checkcat->id);
+            if ($candeletecontent && !has_capability('moodle/category:manage', $chcontext)) {
                 $candeletecontent = false;
             }
         }
@@ -47,7 +48,7 @@ class delete_category_form extends moodleform {
         }
 
     /// Are there any questions in the question bank here?
-        $containsquestions = question_context_has_any_questions($category->context);
+        $containsquestions = question_context_has_any_questions($categorycontext);
 
     /// Get the list of categories we might be able to move to.
         $testcaps = array();
index c0040d2..2d8a045 100644 (file)
             $DB->update_record('course', $editordata);
 
             // assign default role to creator if not already having permission to manage course assignments
-            if (!has_capability('moodle/course:view', $context) or !has_capability('moodle/role:assign', $context)) {
+            if (!is_viewing($context, NULL, 'moodle/role:assign') and !is_enrolled($context, NULL, 'moodle/role:assign')) {
                 role_assign($CFG->creatornewroleid, $USER->id, 0, $context->id);
             }
 
index 3c6f0e0..cc26d5c 100644 (file)
@@ -35,7 +35,7 @@ class course_edit_form extends moodleform {
                 // users with metacourse manage permission are exception
                 // please note that we do not need exact results - anything unexpected here prevents metacourse
                 $managers = get_users_by_capability($coursecontext, 'moodle/course:managemetacourse', 'u.id');
-                $enrolroles = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $coursecontext);
+                $enrolroles = get_roles_with_capability('moodle/course:participate', CAP_ALLOW, $coursecontext);
                 if ($users = get_role_users(array_keys($enrolroles), $coursecontext, false, 'u.id', 'u.id ASC')) {
                     foreach($users as $user) {
                         if (!isset($managers[$user->id])) {
index e590793..bd1ed4b 100644 (file)
@@ -38,7 +38,7 @@ if ($loginasguest !== 0) {
 }
 $PAGE->set_url($url);
 
-if (!isloggedin()) {
+if (!isloggedin() or isguestuser()) {
     // do not use require_login here because we are usually comming from it
     redirect(get_login_url());
 }
@@ -66,7 +66,7 @@ load_all_capabilities();
 /// thus got to this script by mistake.  This might occur if enrolments
 /// changed during this session or something
 
-if (has_capability('moodle/course:view', $context) and !has_capability('moodle/legacy:guest', $context, NULL, false)) {
+if (has_capability('moodle/course:participate', $context)) {
     if (!empty($SESSION->wantsurl)) {
         $destination = $SESSION->wantsurl;
         unset($SESSION->wantsurl);
index c3abbe3..d5476dc 100644 (file)
@@ -84,7 +84,7 @@ final class course_external extends moodle_external {
      */
     static function get_courses($params) {
         global $USER;
-        if (has_capability('moodle/course:view', get_context_instance(CONTEXT_SYSTEM))) {
+        if (has_capability('moodle/course:participate', get_context_instance(CONTEXT_SYSTEM))) {
             $courses = array();
             foreach ($params as $param) {
                 $course = new stdClass();
@@ -681,7 +681,7 @@ final class course_external extends moodle_external {
      */
     static function get_course_modules($params, $type=null) {
         global $DB;
-        if (has_capability('moodle/course:view', get_context_instance(CONTEXT_SYSTEM))) {
+        if (has_capability('moodle/course:participate', get_context_instance(CONTEXT_SYSTEM))) {
             $modules = array();
             foreach ($params as $courseparams) {
                 if (array_key_exists('id', $courseparams)) {
index 9e4b999..2732c48 100644 (file)
     $course->summary = file_rewrite_pluginfile_urls($course->summary, 'pluginfile.php', $context->id, 'course_summary', $course->id);
     echo format_text($course->summary, $course->summaryformat, NULL, $course->id);
 
-    if ($managerroles = get_config('', 'coursemanager')) {
-        $coursemanagerroles = split(',', $managerroles);
+    if (!empty($CFG->coursemanager)) {
+        $coursemanagerroles = explode(',', $CFG->coursemanager);
         foreach ($coursemanagerroles as $roleid) {
             $role = $DB->get_record('role', array('id'=>$roleid));
-            $canseehidden = has_capability('moodle/role:viewhiddenassigns', $context);
             $roleid = (int) $roleid;
-            if ($users = get_role_users($roleid, $context, true, '', 'u.lastname ASC', $canseehidden)) {
+            if ($users = get_role_users($roleid, $context, true)) {
                 foreach ($users as $teacher) {
                     $fullname = fullname($teacher, has_capability('moodle/site:viewfullnames', $context));
                     $namesarray[] = format_string(role_get_name($role, $context)).': <a href="'.$CFG->wwwroot.'/user/view.php?id='.
index d3f6b0c..4f110e9 100644 (file)
@@ -889,7 +889,7 @@ function print_recent_activity($course) {
 
     $timestart = round(time() - COURSE_MAX_RECENT_PERIOD, -2); // better db caching for guests - 100 seconds
 
-    if (!has_capability('moodle/legacy:guest', $context, NULL, false)) {
+    if (!isguestuser()) {
         if (!empty($USER->lastcourseaccess[$course->id])) {
             if ($USER->lastcourseaccess[$course->id] > $timestart) {
                 $timestart = $USER->lastcourseaccess[$course->id];
@@ -1184,7 +1184,7 @@ function course_set_display($courseid, $display=0) {
         $display = 0;
     }
 
-    if (empty($USER->id) or $USER->username == 'guest') {
+    if (!isloggedin() or isguestuser()) {
         //do not store settings in db for guests
     } else if ($DB->record_exists("course_display", array("userid" => $USER->id, "course"=>$courseid))) {
         $DB->set_field("course_display", "display", $display, array("userid"=>$USER->id, "course"=>$courseid));
@@ -2036,7 +2036,7 @@ function print_course_request_buttons($systemcontext) {
     if (empty($CFG->enablecourserequests)) {
         return;
     }
-    if (isloggedin() && !isguestuser() && !has_capability('moodle/course:create', $systemcontext) && has_capability('moodle/course:request', $systemcontext)) {
+    if (!has_capability('moodle/course:create', $systemcontext) && has_capability('moodle/course:request', $systemcontext)) {
     /// Print a button to request a new course
         echo $OUTPUT->single_button('request.php', get_string('requestcourse'), 'get');
     }
@@ -2121,8 +2121,8 @@ function print_courses($category) {
     if ($courses) {
         echo '<ul class="unlist">';
         foreach ($courses as $course) {
-            if ($course->visible == 1
-                || has_capability('moodle/course:viewhiddencourses',$course->context)) {
+            $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
+            if ($course->visible == 1 || has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
                 echo '<li>';
                 print_course($course);
                 echo "</li>\n";
@@ -2151,11 +2151,7 @@ function print_courses($category) {
 function print_course($course, $highlightterms = '') {
     global $CFG, $USER, $DB, $OUTPUT;
 
-    if (isset($course->context)) {
-        $context = $course->context;
-    } else {
-        $context = get_context_instance(CONTEXT_COURSE, $course->id);
-    }
+    $context = get_context_instance(CONTEXT_COURSE, $course->id);
 
     // Rewrite file URLs so that they are correct
     $course->summary = file_rewrite_pluginfile_urls($course->summary, 'pluginfile.php', $context->id, 'course_summary', $course->id);
@@ -2172,7 +2168,6 @@ function print_course($course, $highlightterms = '') {
 
     if (!empty($CFG->coursemanager)) {
         $managerroles = split(',', $CFG->coursemanager);
-        $canseehidden = has_capability('moodle/role:viewhiddenassigns', $context);
         $namesarray = array();
         if (isset($course->managers)) {
             if (count($course->managers)) {
@@ -2194,27 +2189,20 @@ function print_course($course, $highlightterms = '') {
                     }
                     $usersshown[] = $ra->user->id;
 
-                    if ($ra->hidden == 0 || $canseehidden) {
-                        $fullname = fullname($ra->user, $canviewfullnames);
-                        if ($ra->hidden == 1) {
-                            $status = " <img src=\"" . $OUTPUT->pix_url('t/show') . "\" title=\"".get_string('userhashiddenassignments', 'role')."\" alt=\"".get_string('hiddenassign')."\" class=\"hide-show-image\"/>";
-                        } else {
-                            $status = '';
-                        }
-
-                        if (isset($aliasnames[$ra->roleid])) {
-                            $ra->rolename = $aliasnames[$ra->roleid]->name;
-                        }
+                    $fullname = fullname($ra->user, $canviewfullnames);
 
-                        $namesarray[] = format_string($ra->rolename)
-                            . ': <a href="'.$CFG->wwwroot.'/user/view.php?id='.$ra->user->id.'&amp;course='.SITEID.'">'
-                            . $fullname . '</a>' . $status;
+                    if (isset($aliasnames[$ra->roleid])) {
+                        $ra->rolename = $aliasnames[$ra->roleid]->name;
                     }
+
+                    $namesarray[] = format_string($ra->rolename)
+                        . ': <a href="'.$CFG->wwwroot.'/user/view.php?id='.$ra->user->id.'&amp;course='.SITEID.'">'
+                        . $fullname . '</a>';
                 }
             }
         } else {
             $rusers = get_role_users($managerroles, $context,
-                                     true, '', 'r.sortorder ASC, u.lastname ASC', $canseehidden);
+                                     true, '', 'r.sortorder ASC, u.lastname ASC');
             if (is_array($rusers) && count($rusers)) {
                 $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
 
@@ -2268,7 +2256,7 @@ function print_course($course, $highlightterms = '') {
 function print_my_moodle() {
     global $USER, $CFG, $DB, $OUTPUT;
 
-    if (empty($USER->id)) {
+    if (!isloggedin() or isguestuser()) {
         print_error('nopermissions', '', '', 'See My Moodle');
     }
 
@@ -3402,43 +3390,6 @@ function update_course($data) {
     return false;
 }
 
-/**
- * Return all course participant for a given course
- * @global object $DB
- * @param integer $courseid
- * @return array of user
- */
-function get_course_participants ($courseid) {
-    global $DB;
-    $users = get_users_by_capability(
-                        get_context_instance(CONTEXT_COURSE, $courseid),
-                        'moodle/course:view');
-    return $users;
-}
-
-
-/**
- * Return true if the user is a participant for a given course
- * @global object $DB
- * @param integer $userid
- * @param integer $courseid
- * @return boolean
- */
-function is_course_participant ($userid, $courseid) {
-    global $DB;
-    $users = get_users_by_capability(
-                        get_context_instance(CONTEXT_COURSE, $courseid),
-                        'moodle/course:view','u.id');
-
-    foreach($users as $user) {
-        if ($user->id == $userid) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
 function get_course_by_id ($id) {
     global $DB;
     return $DB->get_record('course', array('id' => $id));
@@ -3759,8 +3710,8 @@ class course_request {
         if ($course->id) {
             $course = $DB->get_record('course', array('id' => $course->id));
             blocks_add_default_course_blocks($course);
-            $course->context = get_context_instance(CONTEXT_COURSE, $course->id);
-            role_assign($CFG->creatornewroleid, $this->properties->requester, 0, $course->context->id); // assing teacher role
+            $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
+            role_assign($CFG->creatornewroleid, $this->properties->requester, 0, $coursecontext->id); // assing teacher role
             if (!empty($CFG->restrictmodulesfor) && $CFG->restrictmodulesfor != 'none' && !empty($CFG->restrictbydefault)) {
                 // if we're all or requested we're ok.
                 $allowedmods = explode(',',$CFG->defaultallowedmodules);
@@ -3823,8 +3774,9 @@ class course_request {
             $fs = get_file_storage();
             $files = $fs->get_area_files(self::summary_editor_context()->id, self::summary_editor_filearea(), $this->properties->id);
             foreach ($files as $file) {
+                $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
                 if (!$file->is_directory()) {
-                    $filerecord = array('contextid'=>$course->context->id, 'filearea'=>'course_summary', 'itemid'=>$course->id, 'filepath'=>$file->get_filepath(), 'filename'=>$file->get_filename());
+                    $filerecord = array('contextid'=>$coursecontext->id, 'filearea'=>'course_summary', 'itemid'=>$course->id, 'filepath'=>$file->get_filepath(), 'filename'=>$file->get_filename());
                     $fs->create_file_from_storedfile($filerecord, $file);
                 }
             }
index 29723e4..7714fe0 100644 (file)
     require_login();
 
     if (has_capability('moodle/user:loginas', $systemcontext)) {
-        if (has_capability('moodle/site:doanything', $systemcontext, $userid, false)) {
+        if (is_siteadmin($userid)) {
             print_error('nologinas');
         }
         $context = $systemcontext;
     } else {
         require_login($course);
         require_capability('moodle/user:loginas', $coursecontext);
-        if (!has_capability('moodle/course:view', $coursecontext, $userid, false)) {
-            print_error('usernotincourse');
-        }
-        if (has_capability('moodle/site:doanything', $coursecontext, $userid, false)) {
+        if (is_siteadmin($userid)) {
             print_error('nologinas');
         }
+        if (!is_enrolled($coursecontext, $userid)) {
+            print_error('usernotincourse');
+        }
         $context = $coursecontext;
     }
 
index d90048a..dc76b14 100644 (file)
@@ -52,14 +52,14 @@ class recent_form extends moodleform {
 
             if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS) {
                 $groups = groups_get_user_groups($COURSE->id);
-                $groups = $groups[0];
+                $group = $groups[0];
             } else {
-                $groups = '';
+                $group = '';
             }
 
-            if ($courseusers = get_users_by_capability($context, 'moodle/course:view', 'u.id, u.firstname, u.lastname', 'lastname ASC, firstname DESC', '', '', $groups)) {
-                foreach ($courseusers as $courseuser) {
-                    $options[$courseuser->id] = fullname($courseuser, $viewfullnames);
+            if ($enrolled = get_enrolled_users($context, null, $group, user_picture::fields('u'))) {
+                foreach ($enrolled as $euser) {
+                    $options[$euser->id] = fullname($euser, $viewfullnames);
                 }
             }
             $mform->addElement('select', 'user', get_string('participants'), $options);
index 18f079a..dbd4dab 100644 (file)
@@ -32,7 +32,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         ),
 
         'clonepermissionsfrom' => 'moodle/site:viewreports',
@@ -45,7 +45,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         ),
 
         'clonepermissionsfrom' => 'moodle/site:viewreports',
@@ -58,7 +58,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         ),
 
         'clonepermissionsfrom' => 'moodle/site:viewreports',
index 336093d..c9beb58 100644 (file)
@@ -88,7 +88,7 @@ function print_mnet_log_selector_form($hostid, $course, $selecteduser=0, $select
 
     // If looking at a different host, we're interested in all our site users
     if ($hostid == $CFG->mnet_localhost_id && $course->id != SITEID) {
-        $courseusers = get_users_by_capability($context, 'moodle/course:view', 'u.id, u.firstname, u.lastname, u.idnumber', 'lastname ASC, firstname ASC', $limitfrom, $limitnum, $selectedgroup,'', false);
+        $courseusers = get_users_by_capability($context, 'moodle/course:participate', 'u.id, u.firstname, u.lastname, u.idnumber', 'lastname ASC, firstname ASC', $limitfrom, $limitnum, $selectedgroup,'', false);
     } else {
         // this may be a lot of users :-(
         $courseusers = $DB->get_records('user', array('deleted'=>0), 'lastaccess DESC', 'id, firstname, lastname, idnumber', $limitfrom, $limitnum);
@@ -357,7 +357,7 @@ function print_log_selector_form($course, $selecteduser=0, $selecteddate='today'
     $users = array();
 
     if ($course->id != SITEID) {
-        $courseusers = get_users_by_capability($context, 'moodle/course:view', 'u.id, u.firstname, u.lastname, u.idnumber', 'lastname ASC, firstname ASC', '','',$selectedgroup,null, false);
+        $courseusers = get_users_by_capability($context, 'moodle/course:participate', 'u.id, u.firstname, u.lastname, u.idnumber', 'lastname ASC, firstname ASC', '','',$selectedgroup,null, false);
     } else {
         // this may be a lot of users :-(
         $courseusers = $DB->get_records('user', array('deleted'=>0), 'lastaccess DESC', 'id, firstname, lastname, idnumber');
index 328d0c7..7e666ed 100644 (file)
@@ -32,7 +32,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         ),
 
         'clonepermissionsfrom' => 'moodle/site:viewreports',
index 5edafb6..341b586 100644 (file)
@@ -32,7 +32,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         ),
 
         'clonepermissionsfrom' => 'moodle/site:viewreports',
index ac588eb..b8c81ed 100644 (file)
     }
 
     $roleoptions = array();
+    // TODO: we need a new list of roles that are visible here
     if ($roles = get_roles_used_in_context($context)) {
         foreach ($roles as $r) {
             $roleoptions[$r->id] = $r->name;
index 0e89482..83035a3 100644 (file)
@@ -32,7 +32,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         ),
 
         'clonepermissionsfrom' => 'moodle/site:viewreports',
index f993528..25414ba 100644 (file)
@@ -32,7 +32,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         ),
 
         'clonepermissionsfrom' => 'moodle/site:viewreports',
index 1587791..e28281f 100644 (file)
         if (!$adminediting) {
             foreach ($courses as $course) {
 
-                if (isset($course->context)) {
-                    $coursecontext = $course->context;
-                } else {
-                    $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
-                }
+                $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
 
                 $course->summary .= "<br /><p class=\"category\">";
                 $course->summary .= "$strcategory: <a href=\"category.php?id=$course->category\">";
 
             foreach ($courses as $course) {
 
-                if (isset($course->context)) {
-                    $coursecontext = $course->context;
-                } else {
-                    $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
-                }
+                $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
 
                 $linkcss = $course->visible ? "" : " class=\"dimmed\" ";
 
index 414bac2..419b5fc 100644 (file)
@@ -54,7 +54,7 @@ $coursecontext   = get_context_instance(CONTEXT_COURSE, $course->id);
 $personalcontext = get_context_instance(CONTEXT_USER, $user->id);
 
 require_login();
-if (has_capability('moodle/user:viewuseractivitiesreport', $personalcontext) and !has_capability('moodle/course:view', $coursecontext)) {
+if (has_capability('moodle/user:viewuseractivitiesreport', $personalcontext) and !has_capability('moodle/course:participate', $coursecontext)) {
     // do not require parents to be enrolled in courses ;-)
     $PAGE->set_course($course);
 } else {
index 26973c2..483ca77 100644 (file)
@@ -7,7 +7,7 @@ $capabilities = array(
         'captype' => 'write',
         'contextlevel' => CONTEXT_SYSTEM,
         'legacy' => array(
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     ),
 
@@ -16,7 +16,7 @@ $capabilities = array(
         'captype' => 'write',
         'contextlevel' => CONTEXT_SYSTEM,
         'legacy' => array(
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     )
 
index 7df2b8d..3fd83a8 100644 (file)
@@ -31,7 +31,7 @@
 
 /// Only SITE users can access to this page
     require_login(); // Don't use $courseid! User may want to see old orders.
-    if (has_capability('moodle/legacy:guest', get_context_instance(CONTEXT_SYSTEM), $USER->id, false)) {
+    if (isguestuser()) {
         print_error('noguest');
     }
 
index b917742..e6a7107 100644 (file)
@@ -197,12 +197,10 @@ function get_access_icons($course) {
 
                         if ($fields[1] == "student") {
 
-                            if ($teachers = get_users_by_capability($context, 'moodle/course:update', 'u.*,ra.hidden', 'ra.sortorder ASC')) {
+                            // TODO: replace this with check for $CFG->couremanager, 'moodle/course:update' is definitely wrong
+                            if ($teachers = get_users_by_capability($context, 'moodle/course:update', 'u.*', 'ra.sortorder ASC')) {
                                 foreach ($teachers as $u) {
-                                    if (!$u->hidden || has_capability('moodle/role:viewhiddenassigns', $context)) {
-                                        $teacher = $u;
-                                        break;
-                                    }
+                                    $teacher = $u;
                                 }
                             }
 
@@ -233,22 +231,19 @@ function get_access_icons($course) {
                         if (!empty($CFG->enrol_mailteachers) && $teachers) {
 
                             foreach($teachers as $teacher) {
-
-                                if (!$u->hidden || has_capability('moodle/role:viewhiddenassigns', $context)) {
-                                    $a->course = "$course->fullname";
-                                    $a->user = fullname($user);
-
-                                    $eventdata = new object();
-                                    $eventdata->modulename        = 'moodle';
-                                    $eventdata->userfrom          = $user;
-                                    $eventdata->userto            = $teacher;
-                                    $eventdata->subject           = get_string("enrolmentnew", '', $course->shortname);
-                                    $eventdata->fullmessage       = get_string('enrolmentnewuser', '', $a);
-                                    $eventdata->fullmessageformat = FORMAT_PLAIN;
-                                    $eventdata->fullmessagehtml   = '';
-                                    $eventdata->smallmessage      = '';
-                                    message_send($eventdata);
-                                }
+                                $a->course = "$course->fullname";
+                                $a->user = fullname($user);
+
+                                $eventdata = new object();
+                                $eventdata->modulename        = 'moodle';
+                                $eventdata->userfrom          = $user;
+                                $eventdata->userto            = $teacher;
+                                $eventdata->subject           = get_string("enrolmentnew", '', $course->shortname);
+                                $eventdata->fullmessage       = get_string('enrolmentnewuser', '', $a);
+                                $eventdata->fullmessageformat = FORMAT_PLAIN;
+                                $eventdata->fullmessagehtml   = '';
+                                $eventdata->smallmessage      = '';
+                                message_send($eventdata);
                             }
                         }
                     }
index 4f209c0..eeff293 100644 (file)
@@ -62,7 +62,7 @@ function print_entry($course) {
 
     if ($course->password == '') {   // no password, so enrol
 
-        if (has_capability('moodle/legacy:guest', $context, $USER->id, false)) {
+        if (isguestuser()) {
             add_to_log($course->id, 'course', 'guest', 'view.php?id='.$course->id, getremoteaddr());
 
         } else if (empty($_GET['confirm']) && empty($_GET['cancel'])) {
@@ -404,19 +404,16 @@ function get_access_icons($course) {
  * A bit clunky because I didn't want to change the standard strings
  */
 function print_enrolmentkeyfrom($course) {
-    global $CFG;
-    global $USER;
+    global $CFG, $USER;
 
     $context = get_context_instance(CONTEXT_SYSTEM);
-    $guest = has_capability('moodle/legacy:guest', $context, $USER->id, false);
 
     // if a keyholder role is defined we list teachers in that role (if any exist)
     $contactslisted = false;
-    $canseehidden = has_capability('moodle/role:viewhiddenassigns', $context);
     if (!empty($CFG->enrol_manual_keyholderrole)) {
-        if ($contacts = get_role_users($CFG->enrol_manual_keyholderrole, get_context_instance(CONTEXT_COURSE, $course->id),true,'','u.lastname ASC',$canseehidden  )) {
+        if ($contacts = get_role_users($CFG->enrol_manual_keyholderrole, get_context_instance(CONTEXT_COURSE, $course->id),true,'','u.lastname ASC')) {
             // guest user has a slightly different message
-            if ($guest) {
+            if (isguestuser()) {
                 print_string('enrolmentkeyfromguest', '', ':<br />' );
             }
             else {
@@ -444,7 +441,7 @@ function print_enrolmentkeyfrom($course) {
         }
 
         // guest user has a slightly different message
-        if ($guest) {
+        if (isguestuser()) {
             print_string('enrolmentkeyfromguest', '', $teachername );
         }
         else {
index e4dc86b..80c2072 100644 (file)
@@ -25,7 +25,7 @@
         $destination = "$CFG->wwwroot/course/view.php?id=$course->id";
     }
 
-    if (has_capability('moodle/course:view', $context)) {
+    if (has_capability('moodle/course:participate', $context)) {
         redirect($destination, get_string('paymentthanks', '', $course->fullname));
 
     } else {   /// Somehow they aren't enrolled yet!  :-(
index 2a0fe1b..72b8c2e 100644 (file)
 /// options to be filtered (In HTML form).
 class censor_filter extends moodle_text_filter {
     private function _canseecensor() {
-        $cansee = false;
-        $context = get_context_instance(CONTEXT_SYSTEM, SITEID);
-        if (has_capability('moodle/site:doanything', $context)) {
-            $cansee = true;
-        }
-        return $cansee;
+        return is_siteadmin(); //TODO: add proper access control
     }
     function hash(){
         $cap = "mod/filter:censor";
-        $context = get_context_instance(CONTEXT_SYSTEM, SITEID);
-        if (has_capability('moodle/site:doanything', $context)) {
+        if (is_siteadmin()) {  //TODO: add proper access control
             $cap = "mod/filter:seecensor";
         }
         return $cap;
index e160cd3..ba248d6 100644 (file)
@@ -24,7 +24,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     ),
 
@@ -33,7 +33,7 @@ $capabilities = array(
         'captype' => 'read',
         'contextlevel' => CONTEXT_COURSE,
         'legacy' => array(
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     )
 
index 3a9ba9e..f3f8b11 100644 (file)
@@ -24,7 +24,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     ),
 
@@ -33,7 +33,7 @@ $capabilities = array(
         'captype' => 'read',
         'contextlevel' => CONTEXT_COURSE,
         'legacy' => array(
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     )
 
index cacc0b1..c8242c4 100644 (file)
@@ -24,7 +24,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     ),
 
@@ -33,7 +33,7 @@ $capabilities = array(
         'captype' => 'read',
         'contextlevel' => CONTEXT_COURSE,
         'legacy' => array(
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     )
 
index 1c0aa51..4843ffa 100644 (file)
@@ -24,7 +24,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     ),
 
@@ -33,7 +33,7 @@ $capabilities = array(
         'captype' => 'read',
         'contextlevel' => CONTEXT_COURSE,
         'legacy' => array(
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     )
 
index fc70ede..b7791bf 100644 (file)
@@ -22,7 +22,7 @@ $capabilities = array(
         'contextlevel' => CONTEXT_COURSE,
         'legacy' => array(
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     )
 );
index 12124fb..48cfe29 100644 (file)
@@ -22,7 +22,7 @@ $capabilities = array(
         'contextlevel' => CONTEXT_COURSE,
         'legacy' => array(
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     ),
 
@@ -30,7 +30,7 @@ $capabilities = array(
         'captype' => 'write',
         'contextlevel' => CONTEXT_COURSE,
         'legacy' => array(
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     )
 );
index 98b75a7..fcfe824 100644 (file)
@@ -24,7 +24,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     )
 );
index bc8df57..99e39a9 100644 (file)
@@ -24,7 +24,7 @@ $capabilities = array(
         'legacy' => array(
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     )
 
index 3e3d978..a358853 100644 (file)
@@ -23,7 +23,7 @@ $capabilities = array(
         'contextlevel' => CONTEXT_COURSE,
         'legacy' => array(
             'student' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     )
 
index a8b0e79..eb460bc 100644 (file)
@@ -25,7 +25,7 @@ $capabilities = array(
             'student' => CAP_ALLOW,
             'teacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
-            'admin' => CAP_ALLOW
+            'manager' => CAP_ALLOW
         )
     ),
 );
index 2f1f8e6..8cf1249 100644 (file)
@@ -90,8 +90,7 @@ if ($currentmembers) {
         $coursemanagerroles = split(',', $managerroles);
         foreach ($coursemanagerroles as $roleid) {
             $role = $DB->get_record('role', array('id'=>$roleid));
-            $canseehidden = has_capability('moodle/role:viewhiddenassigns', $context);
-            $managers = get_role_users($roleid, $context, true, 'u.id', 'u.id ASC', $canseehidden);
+            $managers = get_role_users($roleid, $context, true, 'u.id', 'u.id ASC');
         }
     }
 } else {
index 34057dc..830ad5d 100644 (file)
@@ -42,17 +42,8 @@ $error = '';
 
 /// Get applicable roles
 $rolenames = array();
-if ($roles = get_roles_used_in_context($context, true)) {
-    $canviewroles    = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context);
-    $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $systemcontext);
-
+if ($roles = get_profile_roles($context)) {
     foreach ($roles as $role) {
-        if (!isset($canviewroles[$role->id])) {   // Avoid this role (eg course creator)
-            continue;
-        }
-        if (isset($doanythingroles[$role->id])) {   // Avoid this role (ie admin)
-            continue;
-        }
         $rolenames[$role->id] = strip_tags(role_get_name($role, $context));   // Used in menus etc later on
     }
 }
index 3dea054..8a73299 100644 (file)
@@ -368,8 +368,10 @@ class moodle_group_external extends external_api {
             require_capability('moodle/course:managegroups', $context);
 
             // now make sure user is enrolled in course - this is mandatory requirement,
-            // unfortunately this is extermely slow
-            require_capability('moodle/course:view', $context, $userid, false);
+            // unfortunately this is slow
+            if (!is_enrolled($context, $userid)) {
+                throw new invalid_parameter_exception('Only enrolled users may be members of groups');
+            }
 
             groups_add_member($group, $user);
         }
index ce5e16b..2c0eb1c 100644 (file)
@@ -20,21 +20,18 @@ $userid   = optional_param('user', false, PARAM_INT);
 $action   = groups_param_action();
 // Support either single group= parameter, or array groups[]
 if ($groupid) {
-    $groupids=array($groupid);
+    $groupids = array($groupid);
 } else {
     $groupids = optional_param('groups', array(), PARAM_INT);
 }
-$singlegroup=count($groupids) == 1;
+$singlegroup = (count($groupids) == 1);
 
 $returnurl = $CFG->wwwroot.'/group/index.php?id='.$courseid;
 
 // Get the course information so we can print the header and
 // check the course id is valid
 
-if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
-    $success = false;
-    print_error('invalidcourse'); //'The course ID is invalid'
-}
+$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
 
 $url = new moodle_url('/group/index.php', array('id'=>$courseid));
 if ($userid) {
@@ -48,19 +45,19 @@ $PAGE->set_url($url);
 // Make sure that the user has permissions to manage groups.
 require_login($course);
 
-$context = get_context_instance(CONTEXT_COURSE, $courseid);
-if (! has_capability('moodle/course:managegroups', $context)) {
-    redirect(); //"group.php?id=$course->id");   // Not allowed to see all groups
+$context = get_context_instance(CONTEXT_COURSE, $course->id);
+if (!has_capability('moodle/course:managegroups', $context)) {
+    redirect('/course/view.php', array('id'=>$course->id)); // Not allowed to manage all groups
 }
 
 // Check for multiple/no group errors
-if(!$singlegroup) {
+if (!$singlegroup) {
     switch($action) {
         case 'ajax_getmembersingroup':
         case 'showgroupsettingsform':
         case 'showaddmembersform':
         case 'updatemembers':
-            print_error('errorselectone','group',$returnurl);
+            print_error('errorselectone', 'group', $returnurl);
     }
 }
 
@@ -70,41 +67,41 @@ switch ($action) {
 
     case 'ajax_getmembersingroup':
         $roles = array();
-        if ($groupmemberroles = groups_get_members_by_role($groupids[0],$courseid,'u.id,u.firstname,u.lastname')) {
+        if ($groupmemberroles = groups_get_members_by_role($groupids[0], $courseid, 'u.id,u.firstname,u.lastname')) {
             foreach($groupmemberroles as $roleid=>$roledata) {
-                $shortroledata=new StdClass;
-                $shortroledata->name=$roledata->name;
-                $shortroledata->users=array();
+                $shortroledata = new stdClass();
+                $shortroledata->name = $roledata->name;
+                $shortroledata->users = array();
                 foreach($roledata->users as $member) {
-                    $shortmember=new StdClass;
-                    $shortmember->id=$member->id;
-                    $shortmember->name=fullname($member, true);
-                    $shortroledata->users[]=$shortmember;
+                    $shortmember = new stdClass();
+                    $shortmember->id = $member->id;
+                    $shortmember->name = fullname($member, true);
+                    $shortroledata->users[] = $shortmember;
                 }
-                $roles[]=$shortroledata;
+                $roles[] = $shortroledata;
             }
         }
         echo json_encode($roles);
         die;  // Client side JavaScript takes it from here.
 
     case 'deletegroup':
-        if(count($groupids)==0) {
+        if (count($groupids) == 0) {
             print_error('errorselectsome','group',$returnurl);
         }
-        $groupidlist=implode(',',$groupids);
-        redirect('delete.php?courseid='.$courseid.'&groups='.$groupidlist);
+        $groupidlist = implode(',', $groupids);
+        redirect(new moodle_url('/group/delete.php', array('courseid'=>$courseid, 'groups'=>$groupidlist)));
         break;
 
     case 'showcreateorphangroupform':
-        redirect('group.php?courseid='.$courseid);
+        redirect(new moodle_url('/group/group.php', array('courseid'=>$courseid)));
         break;
 
     case 'showautocreategroupsform':
-        redirect('autogroup.php?courseid='.$courseid);
+        redirect(new moodle_url('/group/autogroup.php', array('courseid'=>$courseid)));
         break;
 
     case 'showgroupsettingsform':
-        redirect('group.php?courseid='.$courseid.'&amp;id='.$groupids[0]);
+        redirect(new moodle_url('/group/group.php', array('courseid'=>$courseid, 'id'=>$groupids[0])));
         break;
 
     case 'updategroups': //Currently reloading.
@@ -114,17 +111,15 @@ switch ($action) {
         break;
 
     case 'showaddmembersform':
-        redirect('members.php?group='.$groupids[0]);
+        redirect(new moodle_url('/group/members.php', array('group'=>$groupids[0])));
         break;
 
     case 'updatemembers': //Currently reloading.
         break;
 
     default: //ERROR.
-        if (debugging()) {
-            print_error('unknowaction', '', $returnurl);
+        print_error('unknowaction', '', $returnurl);
         break;
-    }
 }
 
 // Print the page and form
index 26e0f2a..9274b2f 100644 (file)
@@ -40,7 +40,7 @@ function groups_add_member($grouporid, $userorid) {
     }
 
     //check if the user a participant of the group course
-    if (!is_course_participant ($userid, $group->courseid)) {
+    if (!is_enrolled(get_context_instance(CONTEXT_COURSE, $group->courseid), $userid)) {
         return false;
     }
 
@@ -487,25 +487,12 @@ function groups_delete_groupings($courseid, $showfeedback=false) {
  * @return Array of role ID integers, or false if error/none.
  */
 function groups_get_possible_roles($context) {
-    $capability = 'moodle/course:view';
-    $doanything = false;
+    $capability = 'moodle/course:participate';
 
     // find all possible "student" roles
     if ($possibleroles = get_roles_with_capability($capability, CAP_ALLOW, $context)) {
-        if (!$doanything) {
-            if (!$sitecontext = get_context_instance(CONTEXT_SYSTEM)) {
-                return false;    // Something is seriously wrong
-            }
-            $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $sitecontext);
-        }
-
         $validroleids = array();
         foreach ($possibleroles as $possiblerole) {
-            if (!$doanything) {
-                if (isset($doanythingroles[$possiblerole->id])) {  // We don't want these included
-                    continue;
-                }
-            }
             if ($caps = role_context_capabilities($possiblerole->id, $context, $capability)) { // resolved list
                 if (isset($caps[$capability]) && $caps[$capability] > 0) { // resolved capability > 0
                     $validroleids[] = $possiblerole->id;
@@ -529,64 +516,30 @@ function groups_get_possible_roles($context) {
  * @param string $orderby The colum to sort users by
  * @return array An array of the users
  */
-function groups_get_potential_members($courseid, $roleid = null, $orderby = 'lastname,firstname') {
+function groups_get_potential_members($courseid, $roleid = null, $orderby = 'lastname ASC, firstname ASC') {
     global $DB;
 
     $context = get_context_instance(CONTEXT_COURSE, $courseid);
-    $sitecontext = get_context_instance(CONTEXT_SYSTEM);
-    $rolenames = array();
-    $avoidroles = array();
-
-    if ($roles = get_roles_used_in_context($context, true)) {
-
-        $canviewroles    = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context);
-        $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $sitecontext);
-
-        foreach ($roles as $role) {
-            if (!isset($canviewroles[$role->id])) {   // Avoid this role (eg course creator)
-                $avoidroles[] = $role->id;
-                unset($roles[$role->id]);
-                continue;
-            }
-            if (isset($doanythingroles[$role->id])) {   // Avoid this role (ie admin)
-                $avoidroles[] = $role->id;
-                unset($roles[$role->id]);
-                continue;
-            }
-            $rolenames[$role->id] = strip_tags(role_get_name($role, $context));   // Used in menus etc later on
-        }
-    }
-
-    if ($avoidroles) {
-        list($adminroles, $params) = $DB->get_in_or_equal($avoidroles, SQL_PARAMS_NAMED, 'ar0', false);
-        $adminroles = "AND r.roleid $adminroles";
-    } else {
-        $adminroles = "";
-        $params = array();
-    }
 
     // we are looking for all users with this role assigned in this context or higher
-    if ($usercontexts = get_parent_contexts($context)) {
-        $listofcontexts = 'IN ('.implode(',', $usercontexts).')';
-    } else {
-        $listofcontexts = '='.$sitecontext->id.')'; // must be site
-    }
+    $listofcontexts = get_related_contexts_string($context);
 
+    list($esql, $params) = get_enrolled_sql($context);
+    
     if ($roleid) {
-        $selectrole = "AND r.roleid = :roleid";
         $params['roleid'] = $roleid;
+        $where = "WHERE u.id IN (SELECT userid
+                                   FROM {role_assignments}
+                                  WHERE roleid = :roleid AND contextid $listofcontexts)";
     } else {
-        $selectrole = "";
+        $where = "";
     }
 
     $sql = "SELECT u.id, u.username, u.firstname, u.lastname, u.idnumber
               FROM {user} u
-              JOIN {role_assignments} r on u.id=r.userid
-             WHERE (r.contextid = :contextid OR r.contextid $listofcontexts)
-                   AND u.deleted = 0 AND u.username != 'guest'
-                   $selectrole $adminroles
+              JOIN ($esql) e ON e.id = u.id
+            $where
           ORDER BY $orderby";
-    $params['contextid'] = $context->id;
 
     return $DB->get_records_sql($sql, $params);
 
@@ -660,7 +613,7 @@ function groups_unassign_grouping($groupingid, $groupid) {
  * @param string $fields List of fields from user table prefixed with u, default 'u.*'
  * @param string $sort SQL ORDER BY clause, default 'u.lastname ASC'
  * @param string $extrawheretest extra SQL conditions ANDed with the existing where clause.
- * @param array $whereparams any parameters required by $extrawheretest.
+ * @param array $whereparams any parameters required by $extrawheretest (named parameters).
  * @return array Complex array as described above
  */
 function groups_get_members_by_role($groupid, $courseid, $fields='u.*',
@@ -681,11 +634,11 @@ function groups_get_members_by_role($groupid, $courseid, $fields='u.*',
               JOIN {user} u ON u.id = gm.userid
               JOIN {role_assignments} ra ON ra.userid = u.id
               JOIN {role} r ON r.id = ra.roleid
-             WHERE gm.groupid=?
+             WHERE gm.groupid=:mgroupid
                    AND ra.contextid ".get_related_contexts_string($context).
                    $extrawheretest."
           ORDER BY r.sortorder, $sort";
-    array_unshift($whereparams, $groupid);
+    $whereparams['mgroupid'] = $groupid;
     $rs = $DB->get_recordset_sql($sql, $whereparams);
 
     return groups_calculate_role_people($rs, $context);
index aa51780..1dd704b 100644 (file)
@@ -14,33 +14,26 @@ require_once($CFG->dirroot . '/user/selector/lib.php');
 require_once($CFG->dirroot . '/course/lib.php');
 
 $groupid = required_param('group', PARAM_INT);
+$cancel  = optional_param('cancel', false, PARAM_BOOL);
 
-if (!$group = $DB->get_record('groups', array('id'=>$groupid))) {
-    print_error('invalidgroupid');
-}
-
-if (!$course = $DB->get_record('course', array('id'=>$group->courseid))) {
-    print_error('invalidcourse');
-}
-$courseid = $course->id;
+$group = $DB->get_record('groups', array('id'=>$groupid), '*', MUST_EXIST);
+$course = $DB->get_record('course', array('id'=>$group->courseid), '*', MUST_EXIST);
 
 $PAGE->set_url('/groups/members.php', array('id'=>$groupid));
 
 require_login($course);
-$context = get_context_instance(CONTEXT_COURSE, $courseid);
+$context = get_context_instance(CONTEXT_COURSE, $course->id);
 require_capability('moodle/course:managegroups', $context);
 
-$returnurl = $CFG->wwwroot.'/group/index.php?id='.$courseid.'&group='.$group->id;
+$returnurl = $CFG->wwwroot.'/group/index.php?id='.$course->id.'&group='.$group->id;
 
-if (optional_param('cancel', false, PARAM_BOOL)) {
+if ($cancel) {
     redirect($returnurl);
 }
 
-$groupmembersselector = new group_members_selector('removeselect',
-        array('groupid' => $groupid, 'courseid' => $course->id));
+$groupmembersselector = new group_members_selector('removeselect', array('groupid' => $groupid, 'courseid' => $course->id));
 $groupmembersselector->set_extra_fields(array());
-$potentialmembersselector = new group_non_members_selector('addselect',
-        array('groupid' => $groupid, 'courseid' => $course->id));
+$potentialmembersselector = new group_non_members_selector('addselect', array('groupid' => $groupid, 'courseid' => $course->id));
 $potentialmembersselector->set_extra_fields(array());
 
 if (optional_param('add', false, PARAM_BOOL) && confirm_sesskey()) {
@@ -79,8 +72,8 @@ $groupname = format_string($group->name);
 
 $PAGE->requires->yui2_lib('connection');
 $PAGE->requires->js('/group/clientlib.js');
-$PAGE->navbar->add($strparticipants, new moodle_url('/user/index.php', array('id'=>$courseid)));
-$PAGE->navbar->add($strgroups, new moodle_url('/group/index.php', array('id'=>$courseid)));
+$PAGE->navbar->add($strparticipants, new moodle_url('/user/index.php', array('id'=>$course->id)));
+$PAGE->navbar->add($strgroups, new moodle_url('/group/index.php', array('id'=>$course->id)));
 $PAGE->navbar->add($stradduserstogroup);
 
 /// Print header
index 68a5735..bc34b53 100644 (file)
--- a/index.php
+++ b/index.php
@@ -62,7 +62,7 @@
         set_moodle_cookie('nobody');   // To help search for cookies on login page
     }
 
-    if (!empty($USER->id)) {
+    if (isloggedin()) {
         add_to_log(SITEID, 'course', 'view', 'view.php?id='.SITEID, SITEID);
     }
 
                         print_error('cannotfindorcreateforum', 'forum');
                     }
 
-                    if (!empty($USER->id)) {
+                    if (isloggedin()) {
                         $SESSION->fromdiscussion = $CFG->wwwroot;
                         $subtext = '';
                         if (forum_is_subscribed($USER->id, $newsforum)) {
index 2f51165..afe5d10 100644 (file)
@@ -246,6 +246,7 @@ $string['configpathtodu'] = 'Path to du. Probably something like /usr/bin/du. If
 $string['configperfdebug'] = 'If you turn this on, performance info will be printed in the footer of the standard theme';
 $string['configprofilesforenrolledusersonly'] = 'To prevent misuse by spammers, profile descriptions of users who are not yet enrolled in any course are hidden. New users must enrol in at least one course before they can add a profile description.';
 $string['configprotectusernames'] = 'By default forget_password.php does not display any hints that would allow guessing of usernames or email addresses.';
+$string['configprofileroles'] = 'List of roles that are visible on user profiles and participation page.';
 $string['configproxybypass'] = 'Comma separated list of (partial) hostnames or IPs that should bypass proxy (e.g., 192.168., .mydomain.com)';
 $string['configproxyhost'] = 'If this <b>server</b> needs to use a proxy computer (eg a firewall) to access the Internet, then provide the proxy hostname here.  Otherwise leave it blank.';
 $string['configproxypassword'] = 'Password needed to access internet through proxy if required, empty if none (PHP cURL extension required).';
@@ -737,6 +738,7 @@ $string['profilemenuoptions'] = 'Menu options (one per line)';
 $string['profilemenutoofewoptions'] = 'You must provide at least 2 options';
 $string['profilename'] = 'Name';
 $string['profilenofieldsdefined'] = 'No fields have been defined';
+$string['profileroles'] = 'Profile visible roles';
 $string['profileshortname'] = 'Short name (must be unique)';
 $string['profileshortnamenotunique'] = 'This short name is already in use';
 $string['profilesignup'] = 'Display on signup page?';
index a62ba20..b0a5aa6 100644 (file)
@@ -14,6 +14,7 @@ $string['allowroletooverride'] = 'Allow users with role $a->fromrole to override
 $string['allowroletoswitch'] = 'Allow users with role $a->fromrole to switch roles to the role $a->targetrole';
 $string['allowswitch'] = 'Allow role switches';
 $string['allsiteusers'] = 'All site users';
+$string['archetype'] = 'Role archetype';
 $string['assignanotherrole'] = 'Assign another role';
 $string['assignerror'] = 'Error while assigning the role $a->role to user $a->user.';
 $string['assignrolenameincontext'] = 'Assign role \'$a->role\' in $a->context';
@@ -23,6 +24,14 @@ $string['assignrolesrelativetothisuser'] = 'Assign roles relative to this user';
 $string['assignglobalroles'] = 'Assign system roles';
 $string['assignmentcontext'] = 'Assignment context';
 $string['assignmentoptions'] = 'Assignment options';
+$string['archetypecoursecreator'] = 'ARCHETYPE: Course Creator';
+$string['archetypeeditingteacher'] = 'ARCHETYPE: Teacher (editing)';
+$string['archetypefrontpage'] = 'ARCHETYPE: Authenticated user on frontpage';
+$string['archetypeguest'] = 'ARCHETYPE: Guest';
+$string['archetypemanager'] = 'ARCHETYPE: Manager';
+$string['archetypestudent'] = 'ARCHETYPE: Student';
+$string['archetypeteacher'] = 'ARCHETYPE: Teacher (non-editing)';
+$string['archetypeuser'] = 'ARCHETYPE: Authenticated user';
 $string['backtoallroles'] = 'Back to the list of all roles';
 $string['backup:backupcourse'] = 'Backup courses';
 $string['backup:downloadfile'] = 'Download files from backup areas';
@@ -59,6 +68,8 @@ $string['chooseroletoassign'] = 'Please choose a role to assign';
 $string['comment:delete'] = 'Delete comments';
 $string['comment:post'] = 'Post comments';
 $string['comment:view'] = 'Read comments';
+$string['confirmaddadmin'] = 'Do you really want to add user <strong>$a</strong> as new site administrator?';
+$string['confirmdeladmin'] = 'Do you really want to remove user <strong>$a</strong> from the list of site administrators?';
 $string['context'] = 'Context';
 $string['course:activityvisibility'] = 'Hide/show activities';
 $string['course:bulkmessaging'] = 'Send a message to many people';
@@ -74,13 +85,14 @@ $string['course:managefiles'] = 'Manage files';
 $string['course:managegroups'] = 'Manage groups';
 $string['course:managemetacourse'] = 'Manage metacourse';
 $string['course:managescales'] = 'Manage scales';
+$string['course:participate'] = 'Participate in courses';
 $string['course:request'] = 'Request new courses';
 $string['course:reset'] = 'Reset course';
 $string['course:sectionvisibility'] = 'Control section visibility';
 $string['course:setcurrentsection'] = 'Set current section';
 $string['course:update'] = 'Update course settings';
 $string['course:useremail'] = 'Enable/disable email address';
-$string['course:view'] = 'View courses';
+$string['course:view'] = 'View courses without participation';
 $string['course:viewhiddenactivities'] = 'View hidden activities';
 $string['course:viewhiddencourses'] = 'View hidden courses';
 $string['course:viewhiddensections'] = 'View hidden sections';
@@ -110,14 +122,16 @@ $string['errorbadrolename'] = 'Incorrect role name';
 $string['errorbadroleshortname'] = 'Incorrect role short name';
 $string['errorexistsrolename'] = 'Role name already exists';
 $string['errorexistsroleshortname'] = 'Role name already exists';
+$string['existingadmins'] = 'Current site administrators';
 $string['existingusers'] = '$a existing users';
 $string['explanation'] = 'Explanation';
 $string['explainpermission'] = 'Explain permission';
 $string['explainpermissionsinfo'] = '<p>To use this table:</p><ol><li>First look to see if there are any Prohibits. If there are, has_capability will return false.</li><li>Otherwise, read across the rows, left-to-right, top-to-bottom, and find the first cell where the number of Prevents and Allows are different. If there are more Allows than Prevents in that cell, then has_capability will return true, otherwise it will return false.</li><li>If no cell has different numbers of Prevents and Allows, then has_capability will return false.</li></ol>';
-$string['explainpermissionsdoanything'] = 'Note that this user has the moodle/site:doanything capability, so even though the table above shows that has_capability will return false, this user will actually be deemed to have the capability $a in most circumstances.';
 $string['extusers'] = 'Existing users';
 $string['extusersmatching'] = 'Existing users matching \'$a\'';
 $string['filter:manage'] = 'Manage local filter settings';
+$string['frontpageuser'] = 'Authenticated user on frontpage';
+$string['frontpageuserdescription'] = 'All logged in users in the frontpage course.';
 $string['globalrole'] = 'System role';
 $string['globalroleswarning'] = 'WARNING! Any roles you assign from this page will apply to the assigned users throughout the entire system, including the front page and all the courses.';
 $string['gotoassignroles'] = 'Go to Assign roles for this $a->contextlevel';
@@ -151,7 +165,10 @@ $string['legacy:user'] = 'LEGACY ROLE: Authenticated user';
 $string['legacytype'] = 'Legacy role type';
 $string['listallroles'] = 'List all roles';
 $string['localroles'] = 'Locally assigned roles';
+$string['manageadmins'] = 'Manage site administrators';
 $string['manageroles'] = 'Manage roles';
+$string['manager'] = 'Manager';
+$string['managerdescription'] = 'Managers can access course and modify them, they usually do not participate in courses.';
 $string['maybeassignedin'] = 'Context types where this role may be assigned';
 $string['metaassignerror'] = 'Can not assign this role to user \"$a\" because Manage metacourse capability is needed.';
 $string['metaunassignerror'] = 'Role of user \"$a\" was automatically reassigned, please unassign the role in child courses instead.';
@@ -199,7 +216,7 @@ $string['question:viewall'] = 'View all questions';
 $string['question:viewmine'] = 'View your own questions';
 $string['resetrole'] = 'Reset to defaults';
 $string['resetrolenolegacy'] = 'Clear permissions';
-$string['resetrolesure'] = 'Are you sure that you want to reset role \"$a->name ($a->shortname)\" to defaults?<p></p>The defaults are taken from the selected legacy capability ($a->legacytype).';
+$string['resetrolesure'] = 'Are you sure that you want to reset role \"$a->name ($a->shortname)\" to defaults?<p></p>The defaults are taken from the selected archetype ($a->legacytype).';
 $string['resetrolesurenolegacy'] = 'Are you sure that you want to clear all permissions defined in this role \"$a->name ($a->shortname)\"?';
 $string['restore:createuser'] = 'Create users on restore';
 $string['restore:restorecourse'] = 'Restore courses';
@@ -226,6 +243,7 @@ $string['selectanotheruser'] = 'Select another user';
 $string['selectrole'] = 'Select a role';
 $string['showallroles'] = 'Show all roles';
 $string['showthisuserspermissions'] = 'Show this user\'s permissions';
+$string['siteadministrators'] =  'Site administrators';
 $string['site:accessallgroups'] = 'Access all groups';
 $string['site:approvecourse'] = 'Approve course creation';
 $string['site:backup'] = 'Backup courses';
index f8cd300..d26f2a0 100755 (executable)
@@ -188,13 +188,13 @@ if (!defined('MAX_CONTEXT_CACHE_SIZE')) {
 $ACCESSLIB_PRIVATE = new stdClass;
 $ACCESSLIB_PRIVATE->contexts = array(); // Cache of context objects by level and instance
 $ACCESSLIB_PRIVATE->contextsbyid = array(); // Cache of context objects by id
-$ACCESSLIB_PRIVATE->systemcontext = null; // Used in get_system_context
-$ACCESSLIB_PRIVATE->dirtycontexts = null; // Dirty contexts cache
+$ACCESSLIB_PRIVATE->systemcontext = NULL; // Used in get_system_context
+$ACCESSLIB_PRIVATE->dirtycontexts = NULL; // Dirty contexts cache
 $ACCESSLIB_PRIVATE->accessdatabyuser = array(); // Holds the $accessdata structure for users other than $USER
 $ACCESSLIB_PRIVATE->roledefinitions = array(); // role definitions cache - helps a lot with mem usage in cron
 $ACCESSLIB_PRIVATE->croncache = array(); // Used in get_role_access
 $ACCESSLIB_PRIVATE->preloadedcourses = array(); // Used in preload_course_contexts.
-$ACCESSLIB_PRIVATE->capabilitynames = null; // Used in is_valid_capability (only in developer debug mode)
+$ACCESSLIB_PRIVATE->capabilities = NULL; // detailed information about the capabilities
 
 /**
  * Clears accesslib's private caches. ONLY BE USED BY UNIT TESTS
@@ -213,13 +213,13 @@ function accesslib_clear_all_caches_for_unit_testing() {
     }
     $ACCESSLIB_PRIVATE->contexts = array();
     $ACCESSLIB_PRIVATE->contextsbyid = array();
-    $ACCESSLIB_PRIVATE->systemcontext = null;
-    $ACCESSLIB_PRIVATE->dirtycontexts = null;
+    $ACCESSLIB_PRIVATE->systemcontext = NULL;
+    $ACCESSLIB_PRIVATE->dirtycontexts = NULL;
     $ACCESSLIB_PRIVATE->accessdatabyuser = array();
     $ACCESSLIB_PRIVATE->roledefinitions = array();
     $ACCESSLIB_PRIVATE->croncache = array();
     $ACCESSLIB_PRIVATE->preloadedcourses = array();
-    $ACCESSLIB_PRIVATE->capabilitynames = null;
+    $ACCESSLIB_PRIVATE->capabilities = NULL;
 
     unset($USER->access);
 }
@@ -295,7 +295,7 @@ function get_role_context_caps($roleid, $context) {
  * @global object
  * @global object
  * @param int $roleid
- * @param array $accessdata defaults to null
+ * @param array $accessdata defaults to NULL
  * @return array
  */
 function get_role_access($roleid, $accessdata=NULL) {
@@ -366,7 +366,7 @@ function get_role_access($roleid, $accessdata=NULL) {
  * @global object
  * @global object
  * @param int $roleid
- * @param array $accessdata defaults to null
+ * @param array $accessdata defaults to NULL
  * @return array
  */
 function get_default_frontpage_role_access($roleid, $accessdata=NULL) {
@@ -414,7 +414,7 @@ function get_guest_role() {
     global $CFG, $DB;
 
     if (empty($CFG->guestroleid)) {
-        if ($roles = get_roles_with_capability('moodle/legacy:guest', CAP_ALLOW)) {
+        if ($roles = $DB->get_records('role', array('archetype'=>'guest'))) {
             $guestrole = array_shift($roles);   // Pick the first one
             set_config('guestroleid', $guestrole->id);
             return $guestrole;
@@ -441,16 +441,18 @@ function get_guest_role() {
  *      has_capability('mod/forum:replypost',$context)
  *
  * By default checks the capabilties of the current user, but you can pass a
- * different userid. By default will return true for admin-like users who have the
- * moodle/site:doanything capability, but you can override that with the fourth argument.
+ * different userid. By default will return true for admin users, but you can override that with the fourth argument.
+ *
+ * Guest and not-logged-in users can never get any dangerous capability - that is any write capability
+ * or capabilities with XSS, config or data loss risks.
  *
  * @param string $capability the name of the capability to check. For example mod/forum:view
  * @param object $context the context to check the capability in. You normally get this with {@link get_context_instance}.
- * @param integer $userid A user id. By default (null) checks the permissions of the current user.
- * @param boolean $doanything If false, ignore the special moodle/site:doanything capability that admin-like roles have.
+ * @param integer|object $user A user id or object. By default (NULL) checks the permissions of the current user.
+ * @param boolean $doanything If false, ignores effect of admin role assignment
  * @return boolean true if the user has this capability. Otherwise false.
  */
-function has_capability($capability, $context, $userid=NULL, $doanything=true) {
+function has_capability($capability, $context, $user = NULL, $doanything=true) {
     global $USER, $CFG, $DB, $SCRIPT, $ACCESSLIB_PRIVATE;
 
     if (during_initial_install()) {
@@ -462,29 +464,36 @@ function has_capability($capability, $context, $userid=NULL, $doanything=true) {
         }
     }
 
+    if (strpos($capability, 'moodle/legacy:') === 0) {
+        throw new coding_exception('Legacy capabilities can not be used any more!');
+    }
+
     // the original $CONTEXT here was hiding serious errors
     // for security reasons do not reuse previous context
     if (empty($context)) {
         debugging('Incorrect context specified');
         return false;
     }
+    if (!is_bool($doanything)) {
+        throw new coding_exception('Capability parameter "doanything" is wierd ("'.$doanything.'"). This has to be fixed in code.');
+    }
 
-/// Some sanity checks
-    if (debugging('',DEBUG_DEVELOPER)) {
-        if (!is_valid_capability($capability)) {
-            debugging('Capability "'.$capability.'" was not found! This should be fixed in code.');
-        }
-        if (!is_bool($doanything)) {
-            debugging('Capability parameter "doanything" is wierd ("'.$doanything.'"). This should be fixed in code.');
-        }
+    // make sure there is a real user specified
+    if ($user === NULL) {
+        $userid = !empty($USER->id) ? $USER->id : 0;
+    } else {
+        $userid = !empty($user->id) ? $user->id : $user;
     }
 
-    if (empty($userid)) { // we must accept null, 0, '0', '' etc. in $userid
-        if (empty($USER->id)) {
-            // Session not set up yet.
-            $userid = 0;
-        } else {
-            $userid = $USER->id;
+    // capability must exist
+    if (!$capinfo = get_capability_info($capability)) {
+        debugging('Capability "'.$capability.'" was not found! This should be fixed in code.');
+        return false;
+    }
+    // make sure the guest account and not-logged-in users never get any risky caps no matter what the actual settings are.
+    if (($capinfo->captype === 'write') or ((int)$capinfo->riskbitmask & (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))) {
+        if (isguestuser($userid) or $userid == 0) {
+            return false;
         }
     }
 
@@ -546,6 +555,14 @@ function has_capability($capability, $context, $userid=NULL, $doanything=true) {
         }
     }
 
+    // Find out if user is admin - it is not possible to override the doanything in any way
+    // and it is not possible to switch to admin role either.
+    if ($doanything) {
+        if (is_siteadmin($userid)) {
+            return true;
+        }
+    }
+
     // divulge how many times we are called
     //// error_log("has_capability: id:{$context->id} path:{$context->path} userid:$userid cap:$capability");
 
@@ -561,7 +578,7 @@ function has_capability($capability, $context, $userid=NULL, $doanything=true) {
         //
         if ($context->contextlevel <= CONTEXT_COURSE) {
             // Course and above are always preloaded
-            return has_capability_in_accessdata($capability, $context, $USER->access, $doanything);
+            return has_capability_in_accessdata($capability, $context, $USER->access);
         }
         // Load accessdata for below-the-course contexts
         if (!path_inaccessdata($context->path,$USER->access)) {
@@ -570,15 +587,16 @@ function has_capability($capability, $context, $userid=NULL, $doanything=true) {
             // error_log("bt {$bt[0]['file']} {$bt[0]['line']}");
             load_subcontext($USER->id, $context, $USER->access);
         }
-        return has_capability_in_accessdata($capability, $context, $USER->access, $doanything);
+        return has_capability_in_accessdata($capability, $context, $USER->access);
     }
 
     if (!isset($ACCESSLIB_PRIVATE->accessdatabyuser[$userid])) {
         load_user_accessdata($userid);
     }
+
     if ($context->contextlevel <= CONTEXT_COURSE) {
         // Course and above are always preloaded
-        return has_capability_in_accessdata($capability, $context, $ACCESSLIB_PRIVATE->accessdatabyuser[$userid], $doanything);
+        return has_capability_in_accessdata($capability, $context, $ACCESSLIB_PRIVATE->accessdatabyuser[$userid]);
     }
     // Load accessdata for below-the-course contexts as needed
     if (!path_inaccessdata($context->path, $ACCESSLIB_PRIVATE->accessdatabyuser[$userid])) {
@@ -587,7 +605,7 @@ function has_capability($capability, $context, $userid=NULL, $doanything=true) {
         // error_log("bt {$bt[0]['file']} {$bt[0]['line']}");
         load_subcontext($userid, $context, $ACCESSLIB_PRIVATE->accessdatabyuser[$userid]);
     }
-    return has_capability_in_accessdata($capability, $context, $ACCESSLIB_PRIVATE->accessdatabyuser[$userid], $doanything);
+    return has_capability_in_accessdata($capability, $context, $ACCESSLIB_PRIVATE->accessdatabyuser[$userid]);
 }
 
 /**
@@ -603,8 +621,8 @@ function has_capability($capability, $context, $userid=NULL, $doanything=true) {
  * @see has_capability()
  * @param array $capabilities an array of capability names.
  * @param object $context the context to check the capability in. You normally get this with {@link get_context_instance}.
- * @param integer $userid A user id. By default (null) checks the permissions of the current user.
- * @param boolean $doanything If false, ignore the special moodle/site:doanything capability that admin-like roles have.
+ * @param integer $userid A user id. By default (NULL) checks the permissions of the current user.
+ * @param boolean $doanything If false, ignore effect of admin role assignment
  * @return boolean true if the user has any of these capabilities. Otherwise false.
  */
 function has_any_capability($capabilities, $context, $userid=NULL, $doanything=true) {
@@ -633,8 +651,8 @@ function has_any_capability($capabilities, $context, $userid=NULL, $doanything=t
  * @see has_capability()
  * @param array $capabilities an array of capability names.
  * @param object $context the context to check the capability in. You normally get this with {@link get_context_instance}.
- * @param integer $userid A user id. By default (null) checks the permissions of the current user.
- * @param boolean $doanything If false, ignore the special moodle/site:doanything capability that admin-like roles have.
+ * @param integer $userid A user id. By default (NULL) checks the permissions of the current user.
+ * @param boolean $doanything If false, ignore effect of admin role assignment
  * @return boolean true if the user has all of these capabilities. Otherwise false.
  */
 function has_all_capabilities($capabilities, $context, $userid=NULL, $doanything=true) {
@@ -651,101 +669,58 @@ function has_all_capabilities($capabilities, $context, $userid=NULL, $doanything
 }
 
 /**
- * Check if the user is an admin at the site level
+ * Check if the user is an admin at the site level.
  *
- * Uses 1 DB query to answer whether a user is an admin at the sitelevel.
- * It depends on DB schema >=1.7 but does not depend on the new datastructures
- * in v1.9 (context.path, or $USER->access)
+ * Please note that use of proper capabilities is always encouraged,
+ * this function is supposed to be used from core or for temporary hacks.
  *
- * Will return true if the userid has any of
- *  - moodle/site:config
- *  - moodle/legacy:admin
- *  - moodle/site:doanything
- *
- * @global object
- * @global object
- * @param   int  $userid
- * @returns bool true is user can administer server settings
+ * @param   int|object  $user_or_id user id or user object
+ * @returns bool true if user is one of the administrators, false otherwise
  */
-function is_siteadmin($userid) {
-    global $CFG, $DB;
+function is_siteadmin($user_or_id = NULL) {
+    global $CFG, $USER;
 
-    $sql = "SELECT SUM(rc.permission)
-              FROM {role_capabilities} rc
-              JOIN {context} ctx
-                   ON ctx.id=rc.contextid
-              JOIN {role_assignments} ra
-                   ON ra.roleid=rc.roleid AND ra.contextid=ctx.id
-             WHERE ctx.contextlevel=10
-                   AND ra.userid=?
-                   AND rc.capability IN (?, ?, ?)
-          GROUP BY rc.capability
-            HAVING SUM(rc.permission) > 0";
-    $params = array($userid, 'moodle/site:config', 'moodle/legacy:admin', 'moodle/site:doanything');
-
-    return $DB->record_exists_sql($sql, $params);
-}
-
-/**
- * Check whether a role is an admin at the site level
- *
- * Will return true if the userid has any of
- *  - moodle/site:config
- *  - moodle/legacy:admin
- *  - moodle/site:doanything
- *
- * @global object
- * @param integer $roleid a role id.
- * @return boolean, whether this role is an admin role.
- */
-function is_admin_role($roleid) {
-    global $DB;
+    if ($user_or_id === NULL) {
+        $user_or_id = $USER;
+    }
 
-    $sql = "SELECT 1
-              FROM {role_capabilities} rc
-              JOIN {context} ctx ON ctx.id = rc.contextid
-             WHERE ctx.contextlevel = 10
-                   AND rc.roleid = ?
-                   AND rc.capability IN (?, ?, ?)
-          GROUP BY rc.capability
-            HAVING SUM(rc.permission) > 0";
-    $params = array($roleid, 'moodle/site:config', 'moodle/legacy:admin', 'moodle/site:doanything');
+    if (empty($user_or_id)) {
+        return false;
+    }
+    if (!empty($user_or_id->id)) {
+        // we support
+        $userid = $user_or_id->id;
+    } else {
+        $userid = $user_or_id;
+    }
 
-    return $DB->record_exists_sql($sql, $params);
+    $siteadmins = explode(',', $CFG->siteadmins);
+    return in_array($userid, $siteadmins);
 }
 
 /**
- * Returns all the roles for which is_admin_role($role->id) is true.
- *
- * @global object
- * @return array
+ * Returns true if user has at least one role assign
+ * of 'coursemanager' role (is potentially listed in some course descriptions).
+ * @param $userid
+ * @return unknown_type
  */
-function get_admin_roles() {
+function has_coursemanager_role($userid) {
     global $DB;
 
-    $sql = "SELECT *
-              FROM {role} r
-             WHERE EXISTS (
-                    SELECT 1
-                      FROM {role_capabilities} rc
-                      JOIN {context} ctx ON ctx.id = rc.contextid
-                     WHERE ctx.contextlevel = 10
-                           AND rc.roleid = r.id
-                           AND rc.capability IN (?, ?, ?)
-                  GROUP BY rc.capability
-                    HAVING SUM(rc.permission) > 0
-             )
-          ORDER BY r.sortorder";
-    $params = array('moodle/site:config', 'moodle/legacy:admin', 'moodle/site:doanything');
-
-    return $DB->get_records_sql($sql, $params);
+    if (empty($CFG->coursemanager)) {
+        return false;
+    }
+    $sql = "SELECT 1
+              FROM {role_assignments}
+             WHERE userid = :userid AND roleid IN ($CFG->coursemanager)";
+    return $DB->record_exists($sql, array('userid'=>$userid));
 }
 
 /**
  * @param string $path
  * @return string
  */
-function get_course_from_path ($path) {
+function get_course_from_path($path) {
     // assume that nothing is more than 1 course deep
     if (preg_match('!^(/.+)/\d+$!', $path, $matches)) {
         return $matches[1];
@@ -759,6 +734,9 @@ function get_course_from_path ($path) {
  * @return bool
  */
 function path_inaccessdata($path, $accessdata) {
+    if (empty($accessdata['loaded'])) {
+        return false;
+    }
 
     // assume that contexts hang from sys or from a course
     // this will only work well with stuff that hangs from a course
@@ -813,23 +791,12 @@ function path_inaccessdata($path, $accessdata) {
  * and then verify if user has at least one role with allow
  * and at the same time no role with prohibit.
  *
- * Incorrectly set Guest role as Default user role
- * -----------------------------------------------
- * Admins have to make sure that the "Default user role" does
- * not have 'moodle/course:view' or 'moodle/legacy:guest'!
- *
- * Incorrectly set Frontpage role
- * ------------------------------
- * Admins have to make sure that the "Frontpage role" does
- * not have 'moodle/legacy:guest'.
- *
  * @param string $capability
  * @param object $context
  * @param array $accessdata
- * @param bool $doanything
  * @return bool
  */
-function has_capability_in_accessdata($capability, $context, array $accessdata, $doanything) {
+function has_capability_in_accessdata($capability, $context, array $accessdata) {
     global $CFG;
 
     if (empty($context->id)) {
@@ -845,11 +812,6 @@ function has_capability_in_accessdata($capability, $context, array $accessdata,
     }
     unset($contextids);
 
-    if ($doanything and strpos($capability, 'moodle/legacy:') === 0) {
-        // admins do not have any legacy capabilities
-        $doanything = false;
-    }
-
     $roles = array();
     $switchedrole = false;
 
@@ -859,7 +821,7 @@ function has_capability_in_accessdata($capability, $context, array $accessdata,
         foreach ($paths as $path) {
             if (isset($accessdata['rsw'][$path])) {
                 // Found a switchrole assignment - check for that role _plus_ the default user role
-                $roles = array($accessdata['rsw'][$path]=>null, $CFG->defaultuserroleid=>null);
+                $roles = array($accessdata['rsw'][$path]=>NULL, $CFG->defaultuserroleid=>NULL);
                 $switchedrole = true;
                 break;
             }
@@ -871,25 +833,10 @@ function has_capability_in_accessdata($capability, $context, array $accessdata,
         foreach ($paths as $path) {
             if (isset($accessdata['ra'][$path])) {
                 foreach ($accessdata['ra'][$path] as $roleid) {
-                    $roles[$roleid] = null;
+                    $roles[$roleid] = NULL;
                 }
             }
         }
-
-        // Find out if user is admin - it is not possible to override the doanything in any way
-        // and it is not possible to switch to admin role either.
-        if ($doanything or $capability === 'moodle/site:doanything') {
-            $systempath = '/'.SYSCONTEXTID;
-            foreach ($roles as $roleid=>$ignored) {
-                if (isset($accessdata['rdef']["{$systempath}:$roleid"]['moodle/site:doanything']) and $accessdata['rdef']["{$systempath}:$roleid"]['moodle/site:doanything'] == CAP_ALLOW) {
-                    return true;
-                }
-            }
-            if ($capability === 'moodle/site:doanything') {
-                // do anything can not be overridden, prevented or prohibited
-                return false;
-            }
-        }
     }
 
     // Now find out what access is given to each role, going bottom-->up direction
@@ -958,8 +905,8 @@ function aggregate_roles_from_accessdata($context, $accessdata) {
  *
  * @param string $capability the name of the capability to check. For example mod/forum:view
  * @param object $context the context to check the capability in. You normally get this with {@link get_context_instance}.
- * @param integer $userid A user id. By default (null) checks the permissions of the current user.
- * @param bool $doanything If false, ignore the special moodle/site:doanything capability that admin-like roles have.
+ * @param integer $userid A user id. By default (NULL) checks the permissions of the current user.
+ * @param bool $doanything If false, ignore effect of admin role assignment
  * @param string $errorstring The error string to to user. Defaults to 'nopermissions'.
  * @param string $stringfile The language file to load the error string from. Defaults to 'error'.
  * @return void terminates with an error if the user does not have the given capability.
@@ -1015,13 +962,13 @@ function require_capability($capability, $context, $userid = NULL, $doanything =
  * @global object
  * @param string $capability - name of the capability
  * @param array  $accessdata - accessdata session array
- * @param bool   $doanything - if false, ignore do anything
+ * @param bool   $doanything_ignored - admin roles are completely ignored here
  * @param string $sort - sorting fields - prefix each fieldname with "c."
  * @param array  $fields - additional fields you are interested in...
  * @param int    $limit  - set if you want to limit the number of courses
  * @return array $courses - ordered array of course objects - see notes above
  */
-function get_user_courses_bycap($userid, $cap, $accessdata, $doanything, $sort='c.sortorder ASC', $fields=NULL, $limit=0) {
+function get_user_courses_bycap($userid, $cap, $accessdata, $doanything_ignored, $sort='c.sortorder ASC', $fields=NULL, $limit=0) {
 
     global $CFG, $DB;
 
@@ -1047,7 +994,7 @@ function get_user_courses_bycap($userid, $cap, $accessdata, $doanything, $sort='
     }
 
     $sysctx = get_context_instance(CONTEXT_SYSTEM);
-    if (has_capability_in_accessdata($cap, $sysctx, $accessdata, $doanything)) {
+    if (has_capability_in_accessdata($cap, $sysctx, $accessdata)) {
         //
         // Apparently the user has the cap sitewide, so walk *every* course
         // (the cap checks are moderately fast, but this moves massive bandwidth w the db)
@@ -1080,7 +1027,7 @@ function get_user_courses_bycap($userid, $cap, $accessdata, $doanything, $sort='
         $catpaths = array();
         foreach ($rs as $catctx) {
             if ($catctx->path != ''
-                && has_capability_in_accessdata($cap, $catctx, $accessdata, $doanything)) {
+                && has_capability_in_accessdata($cap, $catctx, $accessdata)) {
                 $catpaths[] = $catctx->path;
             }
         }
@@ -1096,12 +1043,6 @@ function get_user_courses_bycap($userid, $cap, $accessdata, $doanything, $sort='
         }
         unset($catpaths);
 
-        $capany = '';
-        if ($doanything) {
-            $capany = " OR rc.capability=:doany";
-            $params['doany'] = 'moodle/site:doanything';
-        }
-
         /// UNION 3 queries:
         /// - user role assignments in courses
         /// - user capability (override - any status) in courses
@@ -1109,11 +1050,11 @@ function get_user_courses_bycap($userid, $cap, $accessdata, $doanything, $sort='
         /// Enclosing the 3-UNION into an inline_view to avoid column names conflict and making the ORDER BY cross-db
         /// and to allow selection of TEXT columns in the query (MSSQL and Oracle limitation). MDL-16209
         $sql = "
-            SELECT $coursefields, ctxid, ctxpath, ctxdepth, ctxlevel, categorypath
+            SELECT $coursefields, ctxid, ctxpath, ctxdepth, ctxlevel, ctxinstance, categorypath
               FROM (
                     SELECT c.id,
                            ctx.id AS ctxid, ctx.path AS ctxpath,
-                           ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel,
+                           ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel, ctx.instanceid AS ctxinstance,
                            cc.path AS categorypath
                     FROM {course} c
                     JOIN {course_categories} cc
@@ -1125,7 +1066,7 @@ function get_user_courses_bycap($userid, $cap, $accessdata, $doanything, $sort='
                     UNION
                     SELECT c.id,
                            ctx.id AS ctxid, ctx.path AS ctxpath,
-                           ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel,
+                           ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel, ctx.instanceid AS ctxinstance,
                            cc.path AS categorypath
                     FROM {course} c
                     JOIN {course_categories} cc
@@ -1133,14 +1074,14 @@ function get_user_courses_bycap($userid, $cap, $accessdata, $doanything, $sort='
                     JOIN {context} ctx
                       ON (c.id=ctx.instanceid AND ctx.contextlevel=".CONTEXT_COURSE.")
                     JOIN {role_capabilities} rc
-                      ON (rc.contextid=ctx.id AND (rc.capability=:cap $capany)) ";
+                      ON (rc.contextid=ctx.id AND (rc.capability=:cap)) ";
 
         if (!empty($catclause)) { /// If we have found the right in categories, add child courses here too
             $sql .= "
                     UNION
                     SELECT c.id,
                            ctx.id AS ctxid, ctx.path AS ctxpath,
-                           ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel,
+                           ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel, ctx.instanceid AS ctxinstance,
                            cc.path AS categorypath
                     FROM {course} c
                     JOIN {course_categories} cc
@@ -1171,9 +1112,10 @@ function get_user_courses_bycap($userid, $cap, $accessdata, $doanything, $sort='
     if ($rs) {
         foreach ($rs as $c) {
             // build the context obj
-            $c = make_context_subobj($c);
+            context_instance_preload($c);
+            $context = get_context_instance(CONTEXT_COURSE, $c->id);
 
-            if (has_capability_in_accessdata($cap, $c->context, $accessdata, $doanything)) {
+            if (has_capability_in_accessdata($cap, $context, $accessdata)) {
                 if ($limit > 0 && $cc >= $limit) {
                     break;
                 }
@@ -1489,7 +1431,7 @@ function load_subcontext($userid, $context, &$accessdata) {
  * @global object
  * @param integer $roleid the id of the user
  * @param object $context needs path!
- * @param array $accessdata accessdata array null by default
+ * @param array $accessdata accessdata array NULL by default
  * @return array
  */
 function get_role_access_bycontext($roleid, $context, $accessdata=NULL) {
@@ -1850,46 +1792,23 @@ function check_enrolment_plugins(&$user) {
 }
 
 /**
- * Returns array of all legacy roles.
+ * Returns array of all role archetypes.
  *
  * @return array
  */
-function get_legacy_roles() {
+function get_role_archetypes() {
     return array(
-        'admin'          => 'moodle/legacy:admin',
-        'coursecreator'  => 'moodle/legacy:coursecreator',
-        'editingteacher' => 'moodle/legacy:editingteacher',
-        'teacher'        => 'moodle/legacy:teacher',
-        'student'        => 'moodle/legacy:student',
-        'guest'          => 'moodle/legacy:guest',
-        'user'           => 'moodle/legacy:user'
+        'manager'        => 'manager',
+        'coursecreator'  => 'coursecreator',
+        'editingteacher' => 'editingteacher',
+        'teacher'        => 'teacher',
+        'student'        => 'student',
+        'guest'          => 'guest',
+        'user'           => 'user',
+        'frontpage'      => 'frontpage'
     );
 }
 
-/**
- * @param int roleid
- * @return string
- */
-function get_legacy_type($roleid) {
-    $sitecontext = get_context_instance(CONTEXT_SYSTEM);
-    $legacyroles = get_legacy_roles();
-
-    $result = '';
-    foreach($legacyroles as $ltype=>$lcap) {
-        $localoverride = get_local_override($roleid, $sitecontext->id, $lcap);
-        if (!empty($localoverride->permission) and $localoverride->permission == CAP_ALLOW) {
-            //choose first selected legacy capability - reset the rest
-            if (empty($result)) {
-                $result = $ltype;
-            } else {
-                unassign_capability($lcap, $roleid);
-            }
-        }
-    }
-
-    return $result;
-}
-
 /**
  * Assign the defaults found in this capabality definition to roles that have
  * the corresponding legacy capabilities assigned to them.
@@ -1901,22 +1820,26 @@ function get_legacy_type($roleid) {
  *                      'teacher' => CAP_ALLOW,
  *                      'editingteacher' => CAP_ALLOW,
  *                      'coursecreator' => CAP_ALLOW,
- *                      'admin' => CAP_ALLOW
+ *                      'manager' => CAP_ALLOW
  * @return boolean success or failure.
  */
 function assign_legacy_capabilities($capability, $legacyperms) {
 
-    $legacyroles = get_legacy_roles();
+    $archetypes = get_role_archetypes();
 
     foreach ($legacyperms as $type => $perm) {
 
         $systemcontext = get_context_instance(CONTEXT_SYSTEM);
+        if ($type === 'admin') {
+            debugging('Legacy type admin in access.php was renamed to manager, please update the code.');
+            $type = 'manager';
+        }
 
-        if (!array_key_exists($type, $legacyroles)) {
+        if (!array_key_exists($type, $archetypes)) {
             print_error('invalidlegacy', '', '', $type);
         }
 
-        if ($roles = get_roles_with_capability($legacyroles[$type], CAP_ALLOW)) {
+        if ($roles = get_archetype_roles($type)) {
             foreach ($roles as $role) {
                 // Assign a site level capability.
                 if (!assign_capability($capability, $perm, $role->id, $systemcontext->id)) {
@@ -1928,24 +1851,6 @@ function assign_legacy_capabilities($capability, $legacyperms) {
     return true;
 }
 
-
-/**
- * Checks to see if a capability is one of the special capabilities
- *
- * Checks to see if a capability is one of the special capabilities
- *      (either a legacy capability, or moodle/site:doanything).
- *
- * @param string $capabilityname the capability name, e.g. mod/forum:view.
- * @return boolean whether this is one of the special capabilities.
- */
-function is_legacy($capabilityname) {
-    if ($capabilityname == 'moodle/site:doanything' || strpos($capabilityname, 'moodle/legacy') === 0) {
-        return true;
-    } else {
-        return false;
-    }
-}
-
 /**
  * @param object $capability a capbility - a row from the capabilitites table.
  * @return boolean whether this capability is safe - that is, wether people with the
@@ -1969,9 +1874,10 @@ function is_safe_capability($capability) {
  * @global object
  * @param int $contextlevel
  * @param int $instanceid
+ * @param int $strictness
  * @return object newly created context
  */
-function create_context($contextlevel, $instanceid) {
+function create_context($contextlevel, $instanceid, $strictness=IGNORE_MISSING) {
 
     global $CFG, $DB;
 
@@ -1989,7 +1895,7 @@ function create_context($contextlevel, $instanceid) {
     $basedepth = 1;
 
     $result = true;
-    $error_message = null;
+    $error_message = NULL;
 
     switch ($contextlevel) {
         case CONTEXT_COURSECAT:
@@ -2002,7 +1908,7 @@ function create_context($contextlevel, $instanceid) {
             if ($p = $DB->get_record_sql($sql, $params)) {
                 $basepath  = $p->path;
                 $basedepth = $p->depth;
-            } else if ($category = $DB->get_record('course_categories', array('id'=>$instanceid))) {
+            } else if ($category = $DB->get_record('course_categories', array('id'=>$instanceid), '*', $strictness)) {
                 if (empty($category->parent)) {
                     // ok - this is a top category
                 } else if ($parent = get_context_instance(CONTEXT_COURSECAT, $category->parent)) {
@@ -2010,7 +1916,7 @@ function create_context($contextlevel, $instanceid) {
                     $basedepth = $parent->depth;
                 } else {
                     // wrong parent category - no big deal, this can be fixed later
-                    $basepath  = null;
+                    $basepath  = NULL;
                     $basedepth = 0;
                 }
             } else {
@@ -2030,7 +1936,7 @@ function create_context($contextlevel, $instanceid) {
             if ($p = $DB->get_record_sql($sql, $params)) {
                 $basepath  = $p->path;
                 $basedepth = $p->depth;
-            } else if ($course = $DB->get_record('course', array('id'=>$instanceid))) {
+            } else if ($course = $DB->get_record('course', array('id'=>$instanceid), '*', $strictness)) {
                 if ($course->id == SITEID) {
                     //ok - no parent category
                 } else if ($parent = get_context_instance(CONTEXT_COURSECAT, $course->category)) {
@@ -2038,7 +1944,7 @@ function create_context($contextlevel, $instanceid) {
                     $basedepth = $parent->depth;
                 } else {
                     // wrong parent category of course - no big deal, this can be fixed later
-                    $basepath  = null;
+                    $basepath  = NULL;
                     $basedepth = 0;
                 }
             } else if ($instanceid == SITEID) {
@@ -2061,8 +1967,8 @@ function create_context($contextlevel, $instanceid) {
             if ($p = $DB->get_record_sql($sql, $params)) {
                 $basepath  = $p->path;
                 $basedepth = $p->depth;
-            } else if ($cm = $DB->get_record('course_modules', array('id'=>$instanceid))) {
-                if ($parent = get_context_instance(CONTEXT_COURSE, $cm->course)) {
+            } else if ($cm = $DB->get_record('course_modules', array('id'=>$instanceid), '*', $strictness)) {
+                if ($parent = get_context_instance(CONTEXT_COURSE, $cm->course, $strictness)) {
                     $basepath  = $parent->path;
                     $basedepth = $parent->depth;
                 } else {
@@ -2083,7 +1989,7 @@ function create_context($contextlevel, $instanceid) {
                       JOIN {block_instances} bi ON (bi.parentcontextid=ctx.id)
                      WHERE bi.id = ?";
             $params = array($instanceid, CONTEXT_COURSE);
-            if ($p = $DB->get_record_sql($sql, $params)) {
+            if ($p = $DB->get_record_sql($sql, $params, '*', $strictness)) {
                 $basepath  = $p->path;
                 $basedepth = $p->depth;
             } else {
@@ -2102,24 +2008,24 @@ function create_context($contextlevel, $instanceid) {
         $context->depth = $basedepth+1;
     }
 
-    if ($result and $id = $DB->insert_record('context', $context)) {
-        // can't set the full path till we know the id!
-        if ($basedepth != 0 and !empty($basepath)) {
-            $DB->set_field('context', 'path', $basepath.'/'. $id, array('id'=>$id));
-        }
-        return get_context_instance_by_id($id);
-
-    } else {
+    if (!$result) {
         debugging('Error: could not insert new context level "'.
                   s($contextlevel).'", instance "'.
                   s($instanceid).'". ' . $error_message);
 
         return false;
     }
+
+    $id = $DB->insert_record('context', $context);
+    // can't set the full path till we know the id!
+    if ($basedepth != 0 and !empty($basepath)) {
+        $DB->set_field('context', 'path', $basepath.'/'. $id, array('id'=>$id));
+    }
+    return get_context_instance_by_id($id);
 }
 
 /**
- * Returns system context or null if can not be created yet.
+ * Returns system context or NULL if can not be created yet.
  *
  * @todo can not use get_record() because we do not know if query failed :-(
  * switch to get_record() later
@@ -2127,7 +2033,7 @@ function create_context($contextlevel, $instanceid) {
  * @global object
  * @global object
  * @param bool $cache use caching
- * @return mixed system context or null
+ * @return mixed system context or NULL
  */
 function get_system_context($cache=true) {
     global $DB, $ACCESSLIB_PRIVATE;
@@ -2146,7 +2052,7 @@ function get_system_context($cache=true) {
         $context = $DB->get_record('context', array('contextlevel'=>CONTEXT_SYSTEM));
     } catch (dml_exception $e) {
         //table does not exist yet, sorry
-        return null;
+        return NULL;
     }
 
     if (!$context) {
@@ -2160,7 +2066,7 @@ function get_system_context($cache=true) {
             $context->id = $DB->insert_record('context', $context);
         } catch (dml_exception $e) {
             // can not create context yet, sorry
-            return null;
+            return NULL;
         }
     }
 
@@ -2227,7 +2133,7 @@ function delete_context($contextlevel, $instanceid) {
  * @param bool $buildpaths update paths and depths
  * @return void
  */
-function create_contexts($contextlevel=null, $buildpaths=true) {
+function create_contexts($contextlevel=NULL, $buildpaths=true) {
     global $DB;
 
     //make sure system context exists
@@ -2404,9 +2310,11 @@ function preload_course_contexts($courseid) {
  * @param integer $level The context level, for example CONTEXT_COURSE, or CONTEXT_MODULE.
  * @param integer $instance The instance id. For $level = CONTEXT_COURSE, this would be $course->id,
  *      for $level = CONTEXT_MODULE, this would be $cm->id. And so on. Defaults to 0
+ * @param int $strictness IGNORE_MISSING means compatible mode, false returned if record not found, debug message if more found;
+ *      MUST_EXIST means throw exception if no record or multiple records found
  * @return object The context object.
  */
-function get_context_instance($contextlevel, $instance=0) {
+function get_context_instance($contextlevel, $instance=0, $strictness=IGNORE_MISSING) {
 
     global $DB, $ACCESSLIB_PRIVATE;
     static $allowed_contexts = array(CONTEXT_SYSTEM, CONTEXT_USER, CONTEXT_COURSECAT, CONTEXT_COURSE, CONTEXT_MODULE, CONTEXT_BLOCK);
@@ -2439,7 +2347,7 @@ function get_context_instance($contextlevel, $instance=0) {
 
     /// Get it from the database, or create it
         if (!$context = $DB->get_record('context', array('contextlevel'=>$contextlevel, 'instanceid'=>$instance))) {
-            $context = create_context($contextlevel, $instance);
+            $context = create_context($contextlevel, $instance, $strictness);
         }
 
     /// Only add to cache if context isn't empty.
@@ -2544,8 +2452,8 @@ function get_context_info_array($contextid) {
     global $DB;
 
     $context = get_context_instance_by_id($contextid, MUST_EXIST);
-    $course  = null;
-    $cm      = null;
+    $course  = NULL;
+    $cm      = NULL;
 
     if ($context->contextlevel == CONTEXT_COURSE) {
         $course = $DB->get_record('course', array('id'=>$context->instanceid), '*', MUST_EXIST);
@@ -2582,12 +2490,22 @@ function get_context_info_array($contextid) {
  * @param string $name role name
  * @param string $shortname role short name
  * @param string $description role description
- * @param string $legacy optional legacy capability
+ * @param string $archetype
  * @return mixed id or dml_exception
  */
-function create_role($name, $shortname, $description, $legacy='') {
+function create_role($name, $shortname, $description, $archetype='') {
     global $DB;
 
+    if (strpos($archetype, 'moodle/legacy:') !== false) {
+        throw new coding_exception('Use new role archetype parameter in create_role() instead of old legacy capabilities.');
+    }
+
+    // verify role archetype actually exists
+    $archetypes = get_role_archetypes();
+    if (empty($archetypes[$archetype])) {
+        $archetype = '';
+    }
+
     // Get the system context.
     $context = get_context_instance(CONTEXT_SYSTEM);
 
@@ -2596,6 +2514,7 @@ function create_role($name, $shortname, $description, $legacy='') {
     $role->name        = $name;
     $role->shortname   = $shortname;
     $role->description = $description;
+    $role->archetype   = $archetype;
 
     //find free sortorder number
     $role->sortorder = $DB->get_field('role', 'MAX(sortorder) + 1', array());
@@ -2604,83 +2523,39 @@ function create_role($name, $shortname, $description, $legacy='') {
     }
     $id = $DB->insert_record('role', $role);
 
-    if ($legacy) {
-        assign_capability($legacy, CAP_ALLOW, $id, $context->id);
-    }
-
     return $id;
 }
 
 /**
  * Function that deletes a role and cleanups up after it
  *
- * @global object
- * @global object
  * @param int $roleid id of role to delete
- * @return bool
+ * @return bool lways true
  */
 function delete_role($roleid) {
     global $CFG, $DB;
-    $success = true;
 
-// mdl 10149, check if this is the last active admin role
-// if we make the admin role not deletable then this part can go
+    // first unssign all users
+    role_unassign($roleid);
 
-    $systemcontext = get_context_instance(CONTEXT_SYSTEM);
+    // cleanup all references to this role, ignore errors
+    $DB->delete_records('role_capabilities',   array('roleid'=>$roleid));
+    $DB->delete_records('role_allow_assign',   array('roleid'=>$roleid));
+    $DB->delete_records('role_allow_assign',   array('allowassign'=>$roleid));
+    $DB->delete_records('role_allow_override', array('roleid'=>$roleid));
+    $DB->delete_records('role_allow_override', array('allowoverride'=>$roleid));
+    $DB->delete_records('role_names',          array('roleid'=>$roleid));
+    $DB->delete_records('role_context_levels', array('roleid'=>$roleid));
 
-    if ($role = $DB->get_record('role', array('id'=>$roleid))) {
-        if ($DB->record_exists('role_capabilities', array('contextid'=>$systemcontext->id, 'roleid'=>$roleid, 'capability'=>'moodle/site:doanything'))) {
-            // deleting an admin role
-            $status = false;
-            if ($adminroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $systemcontext)) {
-                foreach ($adminroles as $adminrole) {
-                    if ($adminrole->id != $roleid) {
-                        // some other admin role
-                        if ($DB->record_exists('role_assignments', array('roleid'=>$adminrole->id, 'contextid'=>$systemcontext->id))) {
-                            // found another admin role with at least 1 user assigned
-                            $status = true;
-                            break;
-                        }
-                    }
-                }
-            }
-            if ($status !== true) {
-                print_error('cannotdeleterolenoadmin', 'access');
-            }
-        }
-    }
-
-// first unssign all users
-    if (!role_unassign($roleid)) {
-        debugging("Error while unassigning all users from role with ID $roleid!");
-        $success = false;
-    }
-
-// cleanup all references to this role, ignore errors
-    if ($success) {
-        $DB->delete_records('role_capabilities',   array('roleid'=>$roleid));
-        $DB->delete_records('role_allow_assign',   array('roleid'=>$roleid));
-        $DB->delete_records('role_allow_assign',   array('allowassign'=>$roleid));
-        $DB->delete_records('role_allow_override', array('roleid'=>$roleid));
-        $DB->delete_records('role_allow_override', array('allowoverride'=>$roleid));
-        $DB->delete_records('role_names',          array('roleid'=>$roleid));
-        $DB->delete_records('role_context_levels', array('roleid'=>$roleid));
-    }
-
-// finally delete the role itself
+    // finally delete the role itself
     // get this before the name is gone for logging
     $rolename = $DB->get_field('role', 'name', array('id'=>$roleid));
 
-    if ($success and !$DB->delete_records('role', array('id'=>$roleid))) {
-        debugging("Could not delete role record with ID $roleid!");
-        $success = false;
-    }
+    $DB->delete_records('role', array('id'=>$roleid));
 
-    if ($success) {
-        add_to_log(SITEID, 'role', 'delete', 'admin/roles/action=delete&roleid='.$roleid, $rolename, '');
-    }
+    add_to_log(SITEID, 'role', 'delete', 'admin/roles/action=delete&roleid='.$roleid, $rolename, '');
 
-    return $success;
+    return true;
 }
 
 /**
@@ -2696,7 +2571,6 @@ function delete_role($roleid) {
  * @return bool
  */
 function assign_capability($capability, $permission, $roleid, $contextid, $overwrite=false) {
-
     global $USER, $DB;
 
     if (empty($permission) || $permission == CAP_INHERIT) { // if permission is not set
@@ -2720,11 +2594,12 @@ function assign_capability($capability, $permission, $roleid, $contextid, $overw
 
     if ($existing) {
         $cap->id = $existing->id;
-        return $DB->update_record('role_capabilities', $cap);
+        $DB->update_record('role_capabilities', $cap);
     } else {
         $c = $DB->get_record('context', array('id'=>$contextid));
-        return $DB->insert_record('role_capabilities', $cap);
+        $DB->insert_record('role_capabilities', $cap);
     }
+    return true;
 }
 
 /**
@@ -2738,15 +2613,13 @@ function assign_capability($capability, $permission, $roleid, $contextid, $overw
 function unassign_capability($capability, $roleid, $contextid=NULL) {
     global $DB;
 
-    if (isset($contextid)) {
+    if (!empty($contextid)) {
         // delete from context rel, if this is the last override in this context
-        $status = $DB->delete_records('role_capabilities', array('capability'=>$capability,
-                'roleid'=>$roleid, 'contextid'=>$contextid));
+        $DB->delete_records('role_capabilities', array('capability'=>$capability, 'roleid'=>$roleid, 'contextid'=>$contextid));
     } else {
-        $status = $DB->delete_records('role_capabilities', array('capability'=>$capability,
-                'roleid'=>$roleid));
+        $DB->delete_records('role_capabilities', array('capability'=>$capability, 'roleid'=>$roleid));
     }
-    return $status;
+    return true;
 }
 
 
@@ -2759,13 +2632,12 @@ function unassign_capability($capability, $roleid, $contextid=NULL) {
  * @global object
  * @global object
  * @param string $capability - capability name (string)
- * @param null $permission - optional, the permission defined for this capability
+ * @param string $permission - optional, the permission defined for this capability
  *                      either CAP_ALLOW, CAP_PREVENT or CAP_PROHIBIT. Defaults to NULL
  * @param object $contect
  * @return mixed array or role objects
  */
-function get_roles_with_capability($capability, $permission=NULL, $context='') {
-
+function get_roles_with_capability($capability, $permission=NULL, $context=NULL) {
     global $CFG, $DB;
 
     $params = array();
@@ -2802,21 +2674,18 @@ function get_roles_with_capability($capability, $permission=NULL, $context='') {
 /**
  * This function makes a role-assignment (a role for a user or group in a particular context)
  *
- * @global object
- * @global object
- * @global object
  * @param int $roleid the role of the id
  * @param int $userid userid
  * @param int $groupid group id
  * @param int $contextid id of the context
  * @param int $timestart time this assignment becomes effective defaults to 0
  * @param int $timeend time this assignemnt ceases to be effective defaults to 0
- * @param int $hidden defaults to 0
+ * @param int $hidden_ignored - use roels with moodle/course:view capability or enrolemnt instead
  * @param string $enrol defaults to 'manual'
  * @param string $timemodified defaults to ''
  * @return int new id of the assigment
  */
-function role_assign($roleid, $userid, $groupid, $contextid, $timestart=0, $timeend=0, $hidden=0, $enrol='manual',$timemodified='') {
+function role_assign($roleid, $userid, $groupid, $contextid, $timestart=0, $timeend=0, $hidden_ignored=0, $enrol='manual',$timemodified='') {
     global $USER, $CFG, $DB;
 
 /// Do some data validation
@@ -2867,7 +2736,6 @@ function role_assign($roleid, $userid, $groupid, $contextid, $timestart=0, $time
         $ra->roleid = $roleid;
         $ra->contextid = $context->id;
         $ra->userid = $userid;
-        $ra->hidden = $hidden;
         $ra->enrol = $enrol;
     /// Always round timestart downto 100 secs to help DBs to use their own caching algorithms
     /// by repeating queries with the same exact parameters in a 100 secs time window
@@ -2880,7 +2748,6 @@ function role_assign($roleid, $userid, $groupid, $contextid, $timestart=0, $time
 
     } else {                      // We already have one, just update it
         $ra->id = $ra->id;
-        $ra->hidden = $hidden;
         $ra->enrol = $enrol;
     /// Always round timestart downto 100 secs to help DBs to use their own caching algorithms
     /// by repeating queries with the same exact parameters in a 100 secs time window
@@ -2944,8 +2811,6 @@ function role_unassign($roleid=0, $userid=0, $groupid=0, $contextid=0, $enrol=NU
     global $USER, $CFG, $DB;
     require_once($CFG->dirroot.'/group/lib.php');
 
-    $success = true;
-
     $args = array('roleid', 'userid', 'groupid', 'contextid');
     $select = array();
     $params = array();
@@ -2965,16 +2830,11 @@ function role_unassign($roleid=0, $userid=0, $groupid=0, $contextid=0, $enrol=NU
         if ($ras = $DB->get_records_select('role_assignments', implode(' AND ', $select), $params)) {
             $mods = get_plugin_list('mod');
             foreach($ras as $ra) {
-                $fireevent = false;
                 /// infinite loop protection when deleting recursively
                 if (!$ra = $DB->get_record('role_assignments', array('id'=>$ra->id))) {
                     continue;
                 }
-                if ($DB->delete_records('role_assignments', array('id'=>$ra->id))) {
-                    $fireevent = true;
-                } else {
-                    $success = false;
-                }
+                $DB->delete_records('role_assignments', array('id'=>$ra->id));
 
                 if (!$context = get_context_instance_by_id($ra->contextid)) {
                     // strange error, not much to do
@@ -3001,80 +2861,482 @@ function role_unassign($roleid=0, $userid=0, $groupid=0, $contextid=0, $enrol=NU
                     }
                 }
 
-                /// now handle metacourse role unassigment and removing from goups if in course context
-                if ($context->contextlevel == CONTEXT_COURSE) {
+                /// now handle metacourse role unassigment and removing from goups if in course context
+                if ($context->contextlevel == CONTEXT_COURSE) {
+
+                    // cleanup leftover course groups/subscriptions etc when user has
+                    // no capability to view course
+                    // this may be slow, but this is the proper way of doing it
+                    if (!has_capability('moodle/course:participate', $context, $ra->userid)) {
+                        // remove from groups
+                        groups_delete_group_members($context->instanceid, $ra->userid);
+
+                        // delete lastaccess records
+                        $DB->delete_records('user_lastaccess', array('userid'=>$ra->userid, 'courseid'=>$context->instanceid));
+                    }
+
+                    //unassign roles in metacourses if needed
+                    if ($parents = $DB->get_records('course_meta', array('child_course'=>$context->instanceid))) {
+                        foreach ($parents as $parent) {
+                            sync_metacourse($parent->parent_course);
+                        }
+                    }
+                }
+
+                events_trigger('role_unassigned', $ra);
+            }
+        }
+    }
+
+    return true;
+}
+
+/**
+ * Enrol someone without using the default role in a course
+ *
+ * A convenience function to take care of the common case where you
+ * just want to enrol someone using the default role into a course
+ *
+ * @param object $course
+ * @param object $user
+ * @param string $enrol the plugin used to do this enrolment
+ * @return bool
+ */
+function enrol_into_course($course, $user, $enrol) {
+
+    $timestart = time();
+    // remove time part from the timestamp and keep only the date part
+    $timestart = make_timestamp(date('Y', $timestart), date('m', $timestart), date('d', $timestart), 0, 0, 0);
+    if ($course->enrolperiod) {
+        $timeend = $timestart + $course->enrolperiod;
+    } else {
+        $timeend = 0;
+    }
+
+    if ($role = get_default_course_role($course)) {
+
+        $context = get_context_instance(CONTEXT_COURSE, $course->id);
+
+        if (!role_assign($role->id, $user->id, 0, $context->id, $timestart, $timeend, 0, $enrol)) {
+            return false;
+        }
+
+        // force accessdata refresh for users visiting this context...
+        mark_context_dirty($context->path);
+
+        email_welcome_message_to_user($course, $user);
+
+        add_to_log($course->id, 'course', 'enrol',
+                'view.php?id='.$course->id, $course->id);
+
+        return true;
+    }
+
+    return false;
+}
+
+/**
+ * Determines if a user is currently logged in
+ *
+ * @return bool
+ */
+function isloggedin() {
+    global $USER;
+
+    return (!empty($USER->id));
+}
+
+/**
+ * Determines if a user is logged in as real guest user with username 'guest'.
+ *
+ * @param int $user mixed user object or id, $USER if not specified
+ * @return bool true if user is the real guest user, false if not logged in or other user
+ */
+function isguestuser($user = NULL) {
+    global $USER, $DB, $CFG;
+
+    // make sure we have the user id cached in config table, because we are going to use it a lot
+    if (empty($CFG->siteguest)) {
+        if (!$guestid = $DB->get_field('user', 'id', array('username'=>'guest', 'mnethostid'=>$CFG->mnet_localhost_id))) {
+            // guest does not exist yet, weird
+            return false;
+        }
+        set_config('siteguest', $guestid);
+    }
+    if ($user === NULL) {
+        $user = $USER;
+    }
+
+    if ($user === NULL) {
+        // happens when setting the $USER
+        return false;
+
+    } else if (is_numeric($user)) {
+        return ($CFG->siteguest == $user);
+
+    } else if (is_object($user)) {
+        if (empty($user->id)) {
+            return false; // not logged in means is not be guest
+        } else {
+            return ($CFG->siteguest == $user->id);
+        }
+
+    } else {
+        throw new coding_exception('Invalid user parameter supplied for isguestuser() function!');
+    }
+}
+
+/**
+ * Does user have a (temporary or real) guest access to course?
+ *
+ * @param object $context
+ * @param object|int $user
+ * @return bool
+ */
+function is_guest($context, $user = NULL) {
+    // first find the course context
+    $coursecontext = get_course_context($context);
+
+    // make sure there is a real user specified
+    if ($user === NULL) {
+        $userid = !empty($USER->id) ? $USER->id : 0;
+    } else {
+        $userid = !empty($user->id) ? $user->id : $user;
+    }
+
+    if (isguestuser($userid)) {
+        // can not inspect or be enrolled
+        return true;
+    }
+
+    if (has_capability('moodle/course:view', $coursecontext, $user)) {
+        // viewing users appear out of nowhere, they are neither guests nor participants
+        return false;
+    }
+
+    if (has_capability('moodle/course:participate', $coursecontext, $userid, false)) {
+        return false;
+    }
+
+    return true;
+}
+
+
+/**
+ * Returns true if user has course:inspect capability in course,
+ * this is intended for admins, managers (aka small admins), inspectors, etc.
+ *
+ * @param object $context
+ * @param int|object $user, if NULL $USER is used
+ * @param string $withcapability extra capability name
+ * @return bool
+ */
+function is_viewing($context, $user = NULL, $withcapability = '') {
+    global $USER;
+
+    // first find the course context
+    $coursecontext = get_course_context($context);
+
+    if (isguestuser($user)) {
+        // can not inspect
+        return true;
+    }
+
+    if (!has_capability('moodle/course:view', $coursecontext, $user)) {
+        // admins are allowed to inspect courses
+        return false;
+    }
+
+    if ($withcapability and !has_capability($withcapability, $context, $user)) {
+        // site admins always have the capability, but the enrolment above blocks
+        return false;
+    }
+
+    return true;
+}
+
+/**
+ * Returns true if user is enrolled (is participating) in course
+ * this is intended for students and teachers.
+ *
+ * @param object $context
+ * @param int|object $user, if NULL $USER is used, oherwise user object or id expected
+ * @param string $withcapability extra capability name
+ * @return bool
+ */
+function is_enrolled($context, $user = NULL, $withcapability = '') {
+    global $USER;
+
+    // first find the course context
+    $coursecontext = get_course_context($context);
+
+    // make sure there is a real user specified
+    if ($user === NULL) {
+        $userid = !empty($USER->id) ? $USER->id : 0;
+    } else {
+        $userid = !empty($user->id) ? $user->id : $user;
+    }
+
+    if (empty($userid)) {
+        // not-logged-in!
+        return false;
+    } else if (isguestuser($userid)) {
+        // guest account can not be enrolled anywhere
+        return false;
+    }
+
+    if ($coursecontext->instanceid != SITEID and !has_capability('moodle/course:participate', $coursecontext, $userid, false)) {
+        // admins are not enrolled, everybody is "enrolled" in the frontpage course
+        return false;
+    }
+
+    if ($withcapability and !has_capability($withcapability, $context, $userid)) {
+        return false;
+    }
+
+    return true;
+}
+
+/**
+ * Returns array with sql code and parameters returning all ids
+ * of users enrolled into course.
+ * @param object $context
+ * @param string $withcapability
+ * @param int $groupid 0 means ignore groups, any other value limits the result by group id
+ * @param string $prefix used for alias of user table, parameter names and in aliases of other used tables
+ * @return array list($sql, $params)
+ */
+function get_enrolled_sql($context, $withcapability = '', $groupid = 0, $prefix = 'eu') {
+    global $DB;
+
+    if ($context->contextlevel < CONTEXT_COURSE) {
+        throw new coding_exception('get_enrolled_sql() expects course context and bellow!');
+    }
+
+    // first find the course context
+    if ($context->contextlevel == CONTEXT_COURSE) {
+        $coursecontext = $context;
+
+    } else if ($context->contextlevel == CONTEXT_MODULE) {
+        $coursecontext = get_context_instance_by_id(get_parent_contextid($context, MUST_EXIST));
+
+    } else if ($context->contextlevel == CONTEXT_BLOCK) {
+        $parentcontext = get_context_instance_by_id(get_parent_contextid($context, MUST_EXIST));
+        if ($parentcontext->contextlevel == CONTEXT_COURSE) {
+            $coursecontext = $parentcontext;
+        } else if ($parentcontext->contextlevel == CONTEXT_MODULE) {
+            $coursecontext = get_context_instance_by_id(get_parent_contextid($parentcontext, MUST_EXIST));
+        } else {
+            throw new coding_exception('Invalid context supplied to get_enrolled_sql()!');
+        }
+
+    } else {
+        throw new coding_exception('Invalid context supplied to get_enrolled_sql()!');
+    }
+
+    list($contextids, $contextpaths) = get_context_info_list($context);
+    list($coursecontextids, $coursecontextpaths) = get_context_info_list($coursecontext);
+
+    // get all relevant capability info for all roles
+    if ($withcapability) {
+        list($incontexts, $params) = $DB->get_in_or_equal($contextids, SQL_PARAMS_NAMED, 'con00');
+        $incaps = "IN (:participate, :withcap)";
+        $params['participate'] = 'moodle/course:participate';
+        $params['withcap']     = $withcapability;
+    } else {
+        list($incontexts, $params) = $DB->get_in_or_equal($coursecontextids, SQL_PARAMS_NAMED, 'con00');
+        $incaps = "= :participate";
+        $params['participate'] = 'moodle/course:participate';
+    }
+    $defs = array();
+    $sql = "SELECT rc.id, rc.roleid, rc.permission, rc.capability, ctx.path
+              FROM {role_capabilities} rc
+              JOIN {context} ctx on rc.contextid = ctx.id
+             WHERE rc.contextid $incontexts AND rc.capability $incaps";
+    $rcs = $DB->get_records_sql($sql, $params);
+    foreach ($rcs as $rc) {
+        $defs[$rc->capability][$rc->path][$rc->roleid] = $rc->permission;
+    }
+
+    $courseaccess = array();
+    if (!empty($defs['moodle/course:participate'])) {
+        foreach ($coursecontextpaths as $path) {
+            if (empty($defs['moodle/course:participate'][$path])) {
+                continue;
+            }
+
+            foreach($defs['moodle/course:participate'][$path] as $roleid => $perm) {
+                if ($perm == CAP_PROHIBIT) {
+                    $courseaccess[$roleid] = CAP_PROHIBIT;
+                    continue;
+                }
+                if (!isset($courseaccess[$roleid])) {
+                    $courseaccess[$roleid] = (int)$perm;
+                }
+            }
+        }
+    }
+
+    $access = array();
+    if (!empty($defs[$withcapability])) {
+        foreach ($contextpaths as $path) {
+            if (empty($defs[$withcapability][$path])) {
+                continue;
+            }
+            foreach($defs[$withcapability][$path] as $roleid => $perm) {
+                if ($perm == CAP_PROHIBIT) {
+                    $access[$roleid] = CAP_PROHIBIT;
+                    continue;
+                }
+                if (!isset($access[$roleid])) {
+                    $access[$roleid] = (int)$perm;
+                }
+            }
+        }
+    }
+
+    unset($defs);
+
+    // make lists of roles that are needed and prohibited
+    $courseneeded     = array(); // one of these is enough
+    $courseprohibited = array(); // must not have any of these
+    foreach ($courseaccess as $roleid => $perm) {
+        if ($perm == CAP_PROHIBIT) {
+            unset($courseneeded[$roleid]);
+            $courseprohibited[$roleid] = true;
+        } else if ($perm == CAP_ALLOW and empty($courseprohibited[$roleid])) {
+            $courseneeded[$roleid] = true;
+        }
+    }
+    $needed     = array(); // one of these is enough
+    $prohibited = array(); // must not have any of these
+    if ($withcapability) {
+        foreach ($access as $roleid => $perm) {
+            if ($perm == CAP_PROHIBIT) {
+                unset($needed[$roleid]);
+                $prohibited[$roleid] = true;
+            } else if ($perm == CAP_ALLOW and empty($prohibited[$roleid])) {
+                $needed[$roleid] = true;
+            }
+        }
+    }
+
+    $isfrontpage = ($coursecontext->instanceid == SITEID);
 
-           &nbs