General developer forum

 
 
TBC
A BUG FOUND in "has_capability" function.
 

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: -
Picture of Andrew Nicols
Re: Use of legacy capabilites
Group DevelopersGroup Moodle HQGroup Particularly helpful MoodlersGroup 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)
TBC
Re: Use of legacy capabilites
 

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

 
Average of ratings: -
TBC
Re: Use of legacy capabilites
 

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

 
Average of ratings: -
Picture of Richard Oelmann
Re: A BUG FOUND in "has_capability" function.
Group Particularly helpful MoodlersGroup 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.

 
Average of ratings: -
TBC
Re: A BUG FOUND in "has_capability" function.
 

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

 
Average of ratings: -
Picture of Richard Oelmann
Re: A BUG FOUND in "has_capability" function.
Group Particularly helpful MoodlersGroup 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. 

 
Average of ratings: -
TBC
Re: A BUG FOUND in "has_capability" function.
 

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

 
Average of ratings: -
Picture of Richard Oelmann
Re: A BUG FOUND in "has_capability" function.
Group Particularly helpful MoodlersGroup 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)
TBC
Re: A BUG FOUND in "has_capability" function.
 

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

 
Average of ratings: -
Picture of sam marshall
Re: A BUG FOUND in "has_capability" function.
Group DevelopersGroup Particularly helpful MoodlersGroup Testers

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)
Picture of Richard Oelmann
Re: A BUG FOUND in "has_capability" function.
Group Particularly helpful MoodlersGroup 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!

 
Average of ratings: -
TBC
Re: A BUG FOUND in "has_capability" function.
 

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

 
Average of ratings: -
Picture of Richard Oelmann
Re: A BUG FOUND in "has_capability" function.
Group Particularly helpful MoodlersGroup 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.

 
Average of ratings: -
TBC
Re: A BUG FOUND in "has_capability" function.
 

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

 
Average of ratings: -
Picture of Richard Oelmann
Re: A BUG FOUND in "has_capability" function.
Group Particularly helpful MoodlersGroup Testers

in the roles table

 
Average of ratings: -
TBC
Re: A BUG FOUND in "has_capability" function.
 

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

 
Average of ratings: -
Picture of Richard Oelmann
Re: A BUG FOUND in "has_capability" function.
Group Particularly helpful MoodlersGroup 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.

 
Average of ratings: -
Gareth J Barnard
Re: A BUG FOUND in "has_capability" function.
Group DevelopersGroup Particularly helpful Moodlers

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)'.

 
Average of ratings: -
Picture of Andrew Nicols
Re: A BUG FOUND in "has_capability" function.
Group DevelopersGroup Moodle HQGroup Particularly helpful MoodlersGroup 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

 
Average of ratings: -
Gareth J Barnard
Re: A BUG FOUND in "has_capability" function.
Group DevelopersGroup Particularly helpful Moodlers

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)
Picture of Andrew Nicols
Re: A BUG FOUND in "has_capability" function.
Group DevelopersGroup Moodle HQGroup Particularly helpful MoodlersGroup 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

 
Average of ratings: -
TBC
Re: A BUG FOUND in "has_capability" function.
 

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

 
Average of ratings: -
Mary Cooch
Re: A BUG FOUND in "has_capability" function.
Group Documentation writersGroup Moodle Course Creator Certificate holdersGroup Moodle HQGroup Particularly helpful MoodlersGroup TestersGroup 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?

 
Average of ratings: -
TBC
Re: A BUG FOUND in "has_capability" function.
 

Hi Mary,

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

Thanks.

Ahmed

 
Average of ratings: -
Picture of Richard Oelmann
Re: A BUG FOUND in "has_capability" function.
Group Particularly helpful MoodlersGroup 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)
Gareth J Barnard
Re: A BUG FOUND in "has_capability" function.
Group DevelopersGroup Particularly helpful Moodlers

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

 
Average of ratings: -
TBC
Re: A BUG FOUND in "has_capability" function.
 

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

 
Average of ratings: -
Gareth J Barnard
Re: A BUG FOUND in "has_capability" function.
Group DevelopersGroup Particularly helpful Moodlers

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.

 
Average of ratings: -
TBC
Re: A BUG FOUND in "has_capability" function.
 

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

 
Average of ratings: -
Picture of Andrew Nicols
Re: A BUG FOUND in "has_capability" function.
Group DevelopersGroup Moodle HQGroup Particularly helpful MoodlersGroup 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)
TBC
Re: A BUG FOUND in "has_capability" function.
 

Thanks Andrew for letting me know about this.

 
Average of ratings: -
Miguel
Re: A BUG FOUND in "has_capability" function.
 

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)
TBC
Re: A BUG FOUND in "has_capability" function.
 

Hi Miguel Santos,

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

Ahmed

 
Average of ratings: -
TBC
Re: A BUG FOUND in "has_capability" function.
 

Hi could you please help me in this:

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

Thanks.

 
Average of ratings: -
Picture of Joseph Rézeau
Re: A BUG FOUND in "has_capability" function.
Group DevelopersGroup Particularly helpful MoodlersGroup TestersGroup 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)
TBC
Re: A BUG FOUND in "has_capability" function.
 

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

 
Average of ratings: -