Using the Access API within a Local Plugin

Using the Access API within a Local Plugin

by Ryan Carpenter -
Number of replies: 5

I'm developing a plugin that adds a menu icon to Moodle's navigation bar (left of the notifications & messages menus, in v3).  The best way I could find to add it was with jQuery, using myplugin_extend_navigation() as a trigger to run:

$PAGE->requires->js_call_amd('myplugin/myjscode', 'init', array($myparam))

That seems to work fine for me, but this context seems to be restricting what I want to do next.


I'd like the menu to be rendered differently for admin users, vs. student or teacher users.  Since there isn't a simple isAdmin property to check, I've used the Access API to check the permissions on an action that I assume only admins can take.  This code has been working in my dev environment:

$isAdmin = has_capability('moodle/site:manageblocks', context_module::instance(1) );


The problem is that not every environment will have a context module with the ID 1.  So, I started looking for ways to check for valid module IDs.  A module can get the $cm argument from _extend_navigation(), but a local plugin only gets $nav.  $PAGE->cm is also empty.


Are there other options to identify admin users in this case?  Thanks in advance.

Average of ratings: -
In reply to Ryan Carpenter

Re: Using the Access API within a Local Plugin

by Alexander Bias -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Hi Ryan,

this is not really what you asked for, but might help you:

If you don't insist to add this menu icon at runtime with JQuery, the *_render_navbar_output() callback function (see https://docs.moodle.org/dev/Output_callbacks#render_navbar_output) which you can add to your plugin's lib.php might help you. Within this function, you can check your capabilities and output plain HTML which will then be added to the navbar right where you described it. 

See https://moodle.org/plugins/local_navbarplus for a plugin of my colleague Kathrin as an example how to use this callback function. And, if you think your usecase could fit into our plugin, don't hesitate to create a ticket on Github to discuss it further.

PS: If you want to check if the user is an admin, have a look at the is_siteadmin() function.

Thanks,
Alex

Average of ratings: Useful (1)
In reply to Alexander Bias

Re: Using the Access API within a Local Plugin

by Ryan Carpenter -

Thanks.

I had seen is_siteadmin(), but the documentation had convinced me that using it was a bad idea.  Do you think the warning is overblown?

    It is strongly discouraged to use is_siteadmin() in activity modules, please use standard capabilities and enrolment status instead.

The *_render_navbar_output() suggestion is a good one, but my larger goal is actually to build a tool that can plug into many different platforms, so for me, it makes more sense for the rendering code to be reusable (in JavaScript).

In reply to Ryan Carpenter

Re: Using the Access API within a Local Plugin

by Davo Smith -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Capabilities are definitely prefered over blanket is_siteadmin() checks - but the question really comes down to how do you control who should see the different links.

  • If the icon is one that should be visible to anyone who has the ability to make configuration changes in the specific context of the page you are looking at (e.g. the icon is related to making changes to the configuration of the specific forum activity you are looking at), then there should be a capability check in the relevant context.
  • If the icon is one that should be visible to anyone who has the ability to manage particular configuration settings across the whole site, then a capability check should be done against a relevant capability in the context_system::instance() context.
  • If the icon relates to something that only site admins should ever access, and which will never be delegated to another user via a system-wide role, then is_siteadmin() is a valid check to make

Unfortunately, your description of how & why the icon is different for different user types is a bit vague, so I can't give more insight than the above.

Average of ratings: Useful (1)
In reply to Davo Smith

Re: Using the Access API within a Local Plugin

by Ryan Carpenter -

That makes sense. Sounds like is_siteadmin() will work for me.  Thanks!

In reply to Ryan Carpenter

Re: Using the Access API within a Local Plugin

by Davo Smith -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

If you simply want to check if someone is an admin for the whole site, then is_siteadmin() will tell you (without any need for context checks). Similarly, you can check for the sitewide capability 'moodle/site:config', via: has_capability('moodle/site:config', context_system::instance()). (The two of these are NOT the same - site admins have every capability automatically, it is possible to create and allocate a site-wide user role with moodle/site:config, but without other capabilities).

If you want to find out if a person has certain editing privileges in a particular context, then you are going to need to know the context.

Whilst local_myplugin_extend_navigation($nav) does not include details of the page context, the function local_myplugin_extend_settings_navigation($nav, $context) does include the context and, to the best of my knowledge, is also called on all pages.


Average of ratings: Useful (1)