A BUG FOUND in "has_capability" function.

A BUG FOUND in "has_capability" function.

by Ahmed Eissa -
Number of replies: 36

Hi All,

I am using Moodle 2.7.I am creating a block that could display some information for teachers and stuff only, and display another text for students. After searching in Google, I found this code that could do the job:

            $context = get_context_instance(CONTEXT_COURSE, $courseid);

            if(has_capability('moodle/legacy:student', $context, $sel_user_id))
            {
               $UserType[$recNo] = "Student";
            }
            if(has_capability('moodle/legacy:teacher', $context, $sel_user_id))
            {
               $UserType[$recNo] = "Staff"; //"Assitent Teacher";
            }
            if(has_capability('moodle/legacy:editingteacher', $context, $sel_user_id))
            {
               $UserType[$recNo] = "Staff"; //"Teacher";
            }
            if(has_capability('moodle/legacy:admin', $context, $sel_user_id))
            {
               $UserType[$recNo] = "Staff"; //"ADMIN";
            }

 

Where $sel_user_id is the selected user id been fetched from the database.

 

After running the code, I got this error message:

Legacy capabilities can not be used any more!

 

After searching in Moodle source code for what generating this error, I found in the "\moodle\lib\accesslib.php" at line 367 this code:

    if (strpos($capability, 'moodle/legacy:') === 0) {
        throw new coding_exception('Legacy capabilities can not be used any more!');
    }

 

After commenting this code, the code works fine.

 

Is anyone have any idea about this, and why Moodle developers stopped legacy capabilities?

 

Thanks in advance ;)

 

Best regards,

 

Ahmed

 

 

Average of ratings: -
In reply to Ahmed Eissa

Re: Use of legacy capabilites

by Andrew Lyons -
Picture of Core developers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Testers

Hi Ahmed,

These types of Legacy capabilities have been deprecated for several years - since the release of Moodle 2.0 and should not be used any more. They were removed by MDL-21655.

Rather than using capabilities which define an arbitrary role, you should instead create capabilities for your plugin which describe the functionality that they control. These can be given by default to the various role archetypes but then controlled independently following that point.

One of the primary reasons for doing this is that it is much clearer to end users what they are controlling. Simply stating that a user is a 'student' doesn't actually define the effect. As an example, in forums if we were to state that the ability to moderate discussions was controlled by the 'moodle/legacy:staff' capability, and this same capability controlled the ability to view discussions for other groups of users, it would not be possible to create student moderators without giving that student additional powers which they did not require, or should not have.

For information on how to define your own capabilities, see http://docs.moodle.org/dev/NEWMODULE_Adding_capabilities

Please do not use the legacy roles.

Best wishes,

Andrew

Average of ratings: Useful (3)
In reply to Andrew Lyons

Re: Use of legacy capabilites

by Ahmed Eissa -

Hi Andrew,

Thanks for your reply; If it's not a bug, could you please tell me (in code example) how could I find the role of each user? could you please update my code and make it works?

Thanks.

 

Ahmed

In reply to Andrew Lyons

Re: Use of legacy capabilites

by Ahmed Eissa -

Hi Andrew,

Also, the URL you provided "http://docs.moodle.org/dev/NEWMODULE_Adding_capabilities" explain how to define my own capabilities, which is not what I am looking for.

I need to let the computer decide who is a student and who is a staff for a list of users that are fetched from the log table in Moodle database.

 

Do you have any solutions?

 

Thanks.

 

Ahmed

In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Richard Oelmann -
Picture of Core developers Picture of Plugin developers Picture of Testers

This is NOT a bug Ahmed, but as Andrew points out, it is the removal of old deprecated functionality which has been replaced by better, more appropriate options.

In reply to Richard Oelmann

Re: A BUG FOUND in "has_capability" function.

by Ahmed Eissa -

Hi Richard,

Thanks for your reply; If it's not a bug, could you please tell me (in code example) how could I find the role of each user? could you please update my code and make it works?

Thanks.

 

Ahmed

In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Richard Oelmann -
Picture of Core developers Picture of Plugin developers Picture of Testers

Have you looked at the documentation http://docs.moodle.org/26/en/Category:Capabilities

 

PS. I realise from some of your posts that this is urgent for you. However, posting in multiple places with exactly the same question and addressing it to specific individuals is more likely to lead to confusion, delays while one person thinks another is addressing it and so on. Please restrict your self to posting the query in a single thread. You are far more likely to get a quick and successful response that way. 

In reply to Richard Oelmann

Re: A BUG FOUND in "has_capability" function.

by Ahmed Eissa -

Hi Richard,

I realize that I had posted my query in a multiple threads, as I urgently need a solution. I am very sorry for that.

 

After looking into the URL that you gave me, I saw that the Legacy capability is removed.

As a software developer, when someone remove a feature in the code, they should provide an alternative feature, which I couldn't find.

 

Could you please guide me in this and I will be appreciated?

 

I appreciate your help and time.

 

Regards,

 

Ahmed

In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Richard Oelmann -
Picture of Core developers Picture of Plugin developers Picture of Testers

Ahmed, in fairness, as Andrew has already explained, this was a legacy, deprecated feature as far back as 2.0 with replacement features in place which developers have been encouraged to use for several years. It has been maintained this long to provide they support and time for developers to switch to the new system which has been there since then. 

It doesn't have exactly the same features, because it is an improvement and development not a direct replacement. 

Moodle is set up in such a way that roles such as student and teacher are normally set on a course by course basis rather than across the whole site. Those roles have a variety of capabilities and the way to achieve your goal is simply to test for one of those capabilities rather than the legacy roles. For example you might test for the capability to edit a page - in most cases that would be teachers or admits and not the standard teacher role. Or you could test for the capability to submit an assignment, which I believe is true for students but not for teachers. You can see the capabilities and determine appropriate ones for your needs - or even create new ones - from the documentation pages

This system gives a much better fine- grained control of the system. Commands, instructions and so on are often deprecated and removed from software and not replaced as something better is put in their place - would you expect to run a Windows3.11 program in Windows 8 or would you expect something better to be available? 

Average of ratings: Useful (3)
In reply to Richard Oelmann

Re: A BUG FOUND in "has_capability" function.

by Ahmed Eissa -

Hi Richard,

Many thanks for your help and time. I really appreciate it.

I will try your "work around" solution, as I think it might work. But I still say that there should be a proper way of doing that.

 

Also, Thanks for reminding me with the old days (Windows 3.11 and MS DOS 6.22) ;)

 

Thanks.

 

Best regards,

 

Ahmed

In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by sam marshall -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers

Just to explain why there should in fact not be a better way of finding out whether a user is a 'teacher' or a 'student', it's quite simple: Moodle has a configurable role system and depending on the site configuration, it may be the case that there are no students and/or there are no teachers. All the standard roles can be deleted or modified.

For example in our main system we have Tutor instead of Teacher. (And a stack of other roles such as 'Website editor'.) This isn't just renaming, the roles are actually different and are not based on the old 'legacy roles'.

In another installation we replaced the standard roles with just 'Normal user' and 'Editing user'.

If a Moodle developer wrote code that relied on 'teacher' and 'student' it would not be possible to configure it to work properly on either of these systems.

It is easy to use the capability system. In your new block, just add a db/access.php file and define a new capability. The access.php lets you control whether by default, for instance, teachers have the capability and students don't. So it achieves exactly the result you wanted, efficiently, but is more flexible.

Of course there are sometimes cases when you might actually need to know what roles somebody has. The example you've given is definitely not one of those cases, that is a straightforward case for using a capability. But you do sometimes need it; an obvious example is the screens for editing user enrolments. It's possible but is much slower than has_capability (requires db queries) and more complicated.

--sam

Average of ratings: Useful (2)
In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Richard Oelmann -
Picture of Core developers Picture of Plugin developers Picture of Testers

+1 for Sam's explanation, 

But just to clarify my understanding and Sam, Tim, Andrew or someone else with greater knowledge than mine can correct me if Im wrong.

What I have suggested to you Ahmed is NOT a 'workaround' it IS the 'proper way of doing that' in most cases (such as yours) in Moodle2. The fact that it is different from what you are used to in that past does not make the developments and improvements wrong, or create a need for deprecated functions to continue to be supported ad infinitum - they have already been supported through 6 releases!

In reply to Richard Oelmann

Re: A BUG FOUND in "has_capability" function.

by Ahmed Eissa -

Thanks Richard and everyone who contribute in this case as I surfed the net looking for some function or even SQL statement that allow me to know who is student and who is stuff, but with no joy.

But I am still saying that it should be a sort of function to serve this purpose, even though the capabilities are now configurable, the proposed function should look into the DB and know that. Just a suggestion.

 

Anyway, Thanks.

Best regards,

 

Ahmed

In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Richard Oelmann -
Picture of Core developers Picture of Plugin developers Picture of Testers

Ahmed, well, if you want to use the sql, check out the user_enrolment table. That will tell you who is enrolled as what role in any particular course (you'll need to reference to other tables as well, but that's the core information in the database).

If you feel there should be a function to do this then the place to put it is as an 'improvement' in the Tracker where the development team and other interested parties can comment and vote on it.

In reply to Richard Oelmann

Re: A BUG FOUND in "has_capability" function.

by Ahmed Eissa -

Hi Richard,

I've checked the table, in fact, I am getting the data from DB, but the role data that stored is numbers (like 1, 2, 3, 4 and 5) and I don't know what is this numbers. Any ideas?

 

Thanks.

 

Ahmed

In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Richard Oelmann -
Picture of Core developers Picture of Plugin developers Picture of Testers

in the roles table

In reply to Richard Oelmann

Re: A BUG FOUND in "has_capability" function.

by Ahmed Eissa -

Could you please explain more? As I seen the role table and couldn't get anything. Thanks.

In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Richard Oelmann -
Picture of Core developers Picture of Plugin developers Picture of Testers

The roleid in the user_enrolment table = id in the role table, so the user_enrolment table tells you the id number of the role which you can look up (or use an SQL join) to give you the readable name of the role e.g. teacher, student.

In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Gareth J Barnard -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers

Typically, students, teachers and editing teachers etc. have different defined capabilities.  With Sam's example of only two, there is still a difference where one reads and the other can edit.  Why don't you pin down the information to what those legacy roles typically do have the capability for.  I.e. students cannot see hidden activities / resources or edit courses.  So base your decisions upon those sort of core capabilities.

And for admins there is still the function 'is_siteadmin($USER)'.

In reply to Gareth J Barnard

Re: A BUG FOUND in "has_capability" function.

by Andrew Lyons -
Picture of Core developers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Testers

Sorry, but it really wouldn't recommend doing this. Capabilities change and changing a capability for one thing will then give you very unexpected results.

The only true solution to this issue is to write capabilities and use those.

Andrew

In reply to Andrew Lyons

Re: A BUG FOUND in "has_capability" function.

by Gareth J Barnard -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers

Hi Ahmed,

As an example of defining and using custom capabilities in a contributed plugin then I use them in Collapsed Topics.  Defined here:

https://github.com/gjb2048/moodle-format_topcoll/blob/MOODLE_26/db/access.php

Where you only need to list the archetypes allowed and then used, i,e:

https://github.com/gjb2048/moodle-format_topcoll/blob/MOODLE_26/lib.php#L435

To make them work, it is essential that after definition you update your version number:

https://github.com/gjb2048/moodle-format_topcoll/blob/MOODLE_26/version.php#L36

Then as a part of installation process you would inform the administrator to assign the created capabilities to the user roles you want.

Cheers,

Gareth

P.S. On http://docs.moodle.org/dev/NEWMODULE_Adding_capabilities just fixed a typo 'archtypes' -> 'archetypes'.

 

Average of ratings: Useful (2)
In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Andrew Lyons -
Picture of Core developers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Testers

HI Ahmed,

As we've all been trying to tell you, you should not be trying to determine who is a student and who is staff, but instead trying to see who can do x, or who can do y.

There can be many roles who are some kind of student, staff member, parent. guest, etc.

It is also possible for a user to be in multiple roles. You do see cases where a user has both a student type role, and a staff type role. This can happen for example when a student is given an elevated permission for one activity. In this example, they are both student and staff and your model breaks. Please, read the documentation provided by myself, and Richard; write your own capability definitions; and base your blocks content on these rather the long-since removed legacy roles.

Andrew

In reply to Andrew Lyons

Re: A BUG FOUND in "has_capability" function.

by Ahmed Eissa -

Hi ALL,

Well basically, I am building an Moodle Analytics tool which could do some calculations and produce reports.

One of the requirements is to see who is student and who is staff. So I need this to be done.

 

Any ideas?

 

Thanks.

 

Ahmed

In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Mary Cooch -
Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Testers Picture of Translators

Hello Ahmed. I am not a technical person so I can't help you but I was just wondering how your tool would work with users who were both students AND staff, as  has been mentioned in previous posts? I could be a student in the Maths course and a teacher in the French course. Would your tool be able to handle that?

In reply to Mary Cooch

Re: A BUG FOUND in "has_capability" function.

by Ahmed Eissa -

Hi Mary,

It will focus on each course. I can't say more as it's secret.

Thanks.

Ahmed

In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Richard Oelmann -
Picture of Core developers Picture of Plugin developers Picture of Testers

If it focuses on each course then you don't need the site wide legacy role that you have been on about! You need exactly what we have been telling you!

On a single course, a member of staff on that course will have certain capabilities that students wont - eg.  grading an assignment (staff) submitting an assignment (student), editing the course (staff), etc. Decide on one of those capabilities and use the has_capability function. Its a one line check in the code, based on the docs that Andrew, myself and others have linked you to. No need for database calls, no need for legacy roles.

An example from Julian's Essential theme (ability to view hidden sections would be teachers/admins)

$canviewhidden = has_capability('moodle/course:viewhiddensections', context_course::instance($course->id))

Or from Decaf (!has_capability = does not have the capability -> student)

if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {

HTH

Richard

Average of ratings: Useful (1)
In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Gareth J Barnard -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers

Hi Ahmed,

If we knew more then perhaps we could offer alternative solutions.  Is it bound by a confidentiality agreement, contract of work, law or something?

Cheers,

Gareth

In reply to Gareth J Barnard

Re: A BUG FOUND in "has_capability" function.

by Ahmed Eissa -

Yes, as I am working for King's College London - Dental Institute.

In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Gareth J Barnard -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers

Given that, then I take it that you are working on this: KEATS Analytics: Researching virtual learning within Moodle - under '2011-2012 Funded projects' on http://www.kcl.ac.uk/study/learningteaching/kings/funding/ctfprojects.aspx.  So the abstract of the work appears to be public and provides some more information.

In reply to Gareth J Barnard

Re: A BUG FOUND in "has_capability" function.

by Ahmed Eissa -

No, I am working on something else. I wasn't know about this. Thanks.

In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Andrew Lyons -
Picture of Core developers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Testers

Hi Ahmed,

You may also be in interested in the London Moodle User Group. As I recall, there is one which the London Universities hold on a regular basis and whose members includes amongst others, developers.

Andrew

Average of ratings: Useful (1)
In reply to Andrew Lyons

Re: A BUG FOUND in "has_capability" function.

by Ahmed Eissa -

Thanks Andrew for letting me know about this.

In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Miguel Santos -

Hi Ahmed,

   Have you looked in lib/accesslib.php?

    It has a few functions that might give you what you seem to be looking for:

  • function get_user_roles_in_course($userid,$courseid)
  • function get_user_roles(context $context, $userid = 0, $checkparentcontexts = true, $order = 'c.contextlevel DESC, r.sortorder ASC')
     

 

Average of ratings: Useful (2)
In reply to Miguel Santos

Re: A BUG FOUND in "has_capability" function.

by Ahmed Eissa -

Hi Miguel Santos,

1+ for your post. I will try this function. Thanks.

Ahmed

In reply to Miguel Santos

Re: A BUG FOUND in "has_capability" function.

by Ahmed Eissa -

Hi could you please help me in this:

https://moodle.org/mod/forum/discuss.php?d=254345

Thanks.

In reply to Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

by Joseph Rézeau -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers Picture of Translators

Hi Ahmed,

I'm afraid you have not learnt the lesson the Moodle community tried to teach you about "no cross-posting please".

Your latest post in this discussion (dated Friday, 14 February 2014, 4:41 PM) is not only totally useless, it is against the rules. sad

Joseph

Average of ratings: Useful (1)
In reply to Joseph Rézeau

Re: A BUG FOUND in "has_capability" function.

by Ahmed Eissa -

I am sorry.... But could anyone help?