A BUG FOUND in "has_capability" function.

A BUG FOUND in "has_capability" function.

Ahmed Eissa -
回帖数: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

 

 

回复Ahmed Eissa

Re: Use of legacy capabilites

Andrew Lyons -
Core developers的头像 Moodle HQ的头像 Particularly helpful Moodlers的头像 Peer reviewers的头像 Plugin developers的头像 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

回复Andrew Lyons

Re: Use of legacy capabilites

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

回复Andrew Lyons

Re: Use of legacy capabilites

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

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Richard Oelmann -
Core developers的头像 Plugin developers的头像 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.

回复Richard Oelmann

Re: A BUG FOUND in "has_capability" function.

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

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Richard Oelmann -
Core developers的头像 Plugin developers的头像 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. 

回复Richard Oelmann

Re: A BUG FOUND in "has_capability" function.

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

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Richard Oelmann -
Core developers的头像 Plugin developers的头像 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? 

回复Richard Oelmann

Re: A BUG FOUND in "has_capability" function.

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

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

sam marshall -
Core developers的头像 Peer reviewers的头像 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

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Richard Oelmann -
Core developers的头像 Plugin developers的头像 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!

回复Richard Oelmann

Re: A BUG FOUND in "has_capability" function.

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

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Richard Oelmann -
Core developers的头像 Plugin developers的头像 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.

回复Richard Oelmann

Re: A BUG FOUND in "has_capability" function.

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

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Richard Oelmann -
Core developers的头像 Plugin developers的头像 Testers的头像

in the roles table

回复Richard Oelmann

Re: A BUG FOUND in "has_capability" function.

Ahmed Eissa -

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

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Richard Oelmann -
Core developers的头像 Plugin developers的头像 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.

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Gareth J Barnard -
Core developers的头像 Particularly helpful Moodlers的头像 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)'.

回复Gareth J Barnard

Re: A BUG FOUND in "has_capability" function.

Andrew Lyons -
Core developers的头像 Moodle HQ的头像 Particularly helpful Moodlers的头像 Peer reviewers的头像 Plugin developers的头像 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

回复Andrew Lyons

Re: A BUG FOUND in "has_capability" function.

Gareth J Barnard -
Core developers的头像 Particularly helpful Moodlers的头像 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'.

 

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Andrew Lyons -
Core developers的头像 Moodle HQ的头像 Particularly helpful Moodlers的头像 Peer reviewers的头像 Plugin developers的头像 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

回复Andrew Lyons

Re: A BUG FOUND in "has_capability" function.

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

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Mary Cooch -
Documentation writers的头像 Moodle HQ的头像 Particularly helpful Moodlers的头像 Testers的头像 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?

回复Mary Cooch

Re: A BUG FOUND in "has_capability" function.

Ahmed Eissa -

Hi Mary,

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

Thanks.

Ahmed

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Richard Oelmann -
Core developers的头像 Plugin developers的头像 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

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Gareth J Barnard -
Core developers的头像 Particularly helpful Moodlers的头像 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

回复Gareth J Barnard

Re: A BUG FOUND in "has_capability" function.

Ahmed Eissa -

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

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Gareth J Barnard -
Core developers的头像 Particularly helpful Moodlers的头像 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.

回复Gareth J Barnard

Re: A BUG FOUND in "has_capability" function.

Ahmed Eissa -

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

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Andrew Lyons -
Core developers的头像 Moodle HQ的头像 Particularly helpful Moodlers的头像 Peer reviewers的头像 Plugin developers的头像 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

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

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

 

回复Miguel Santos

Re: A BUG FOUND in "has_capability" function.

Ahmed Eissa -

Hi Miguel Santos,

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

Ahmed

回复Miguel Santos

Re: A BUG FOUND in "has_capability" function.

Ahmed Eissa -

Hi could you please help me in this:

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

Thanks.

回复Ahmed Eissa

Re: A BUG FOUND in "has_capability" function.

Joseph Rézeau -
Core developers的头像 Particularly helpful Moodlers的头像 Plugin developers的头像 Testers的头像 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. 伤心

Joseph