<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sadaf3d</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sadaf3d"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Sadaf3d"/>
	<updated>2026-08-11T04:53:53Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=NEWMODULE_Adding_capabilities&amp;diff=58291</id>
		<title>NEWMODULE Adding capabilities</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=NEWMODULE_Adding_capabilities&amp;diff=58291"/>
		<updated>2021-02-03T13:57:37Z</updated>

		<summary type="html">&lt;p&gt;Sadaf3d: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{New_Module}}&lt;br /&gt;
In order to add a capabilities for your &amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt; you need to:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==1. Create a file access.php in the &amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt;/db directory==&lt;br /&gt;
&lt;br /&gt;
This should contain a list of the capabilities that you want to define. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$capabilities = array(&lt;br /&gt;
    &#039;mod/&amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt;:&amp;lt;&amp;lt;CAPABILITYNAME&amp;gt;&amp;gt;&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;riskbitmask&#039;  =&amp;gt; RISK_SPAM | RISK_PERSONAL | RISK_XSS | RISK_CONFIG,&lt;br /&gt;
        &#039;captype&#039;      =&amp;gt; &#039;write&#039;,&lt;br /&gt;
        &#039;contextlevel&#039; =&amp;gt; CONTEXT_MODULE,&lt;br /&gt;
        &#039;archetypes&#039;   =&amp;gt; array(&lt;br /&gt;
            &#039;student&#039;        =&amp;gt; CAP_ALLOW,&lt;br /&gt;
            &#039;teacher&#039;        =&amp;gt; CAP_ALLOW,&lt;br /&gt;
            &#039;editingteacher&#039; =&amp;gt; CAP_ALLOW,&lt;br /&gt;
            &#039;manager&#039;          =&amp;gt; CAP_ALLOW&lt;br /&gt;
        )&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Add more capabilities here ...&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The various parts of the capability definition are:&lt;br /&gt;
&lt;br /&gt;
===Capability name (&#039;mod/&amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt;:&amp;lt;&amp;lt;CAPABILITYNAME&amp;gt;&amp;gt;)===&lt;br /&gt;
&lt;br /&gt;
This is the internal name used for this this capability. In addition to this internal name, you should also add the language string &amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt;:&amp;lt;&amp;lt;CAPABILITYNAME&amp;gt;&amp;gt; to your module&#039;s language file, to give the capability a name that users will see in the interface.&lt;br /&gt;
&lt;br /&gt;
===riskbitmask===&lt;br /&gt;
&lt;br /&gt;
Allowing people to do various things sometimes requires introducing possible security risks. For example, if you can post to a forum, you can post unsolicited advertising. To a certain extent users have to be trusted. To help administrators and teachers know what the issues are, each capability should list any associated risks. See [[Hardening_new_Roles_system]]. will be reflected in the list of icons of each row of the &#039;Override permissions&#039;-&amp;gt;roles page.&lt;br /&gt;
&lt;br /&gt;
Technically, this value is a bit field, so you should combine the relevant risks constants with the &#039;|&#039; operator. So typical values might be:&lt;br /&gt;
* RISK_SPAM&lt;br /&gt;
* RISK_PERSONAL | RISK_XSS | RISK_DATALOSS&lt;br /&gt;
&lt;br /&gt;
===captype===&lt;br /&gt;
&lt;br /&gt;
Should be either &#039;read&#039; or &#039;write&#039;. &#039;read&#039; is for capabilities that just let you view things. &#039;write&#039; for capabilities that let you change things.&lt;br /&gt;
&lt;br /&gt;
===contextlevel===&lt;br /&gt;
&lt;br /&gt;
The context level where this capability is most relevant. If you are writing a module this will almost always be [[Context|CONTEXT_MODULE]]. (This does not have much effect. It is just used to sort and group capabilities on the define roles and override roles pages.)&lt;br /&gt;
&lt;br /&gt;
===archetypes===&lt;br /&gt;
&lt;br /&gt;
This section defines, for each role type, what default permissions those roles should be given when your module is first installed (or when a new capability is detected on upgrade).&lt;br /&gt;
&lt;br /&gt;
Normally, you just add one line for each role that you want to give the capability to. The line should look like &#039;roletype&#039; =&amp;gt; CAP_ALLOW. Just leave out roles that you do not want to get the capability by default. Very exceptionally, you may need to specify a default permission of CAP_PREVENT, CAP_PROHIBIT.&lt;br /&gt;
&lt;br /&gt;
Note that once a capability is established, permissions will not be automatically overwritten when a module is updated. If permissions have changed, an administrator must manually change or force capabilities to be [[:en:Manage_roles#Reset_role_to_defaults|reset to default]] for a role.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to specify any roles that will be given your capability by default, you can pass a blank array to the &#039;archetypes&#039; parameter:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&#039;mod/newmodule:dosomething&#039; =&amp;gt; array(&lt;br /&gt;
    &#039;captype&#039; =&amp;gt; &#039;read&#039;,&lt;br /&gt;
    &#039;contextlevel&#039; =&amp;gt; CONTEXT_MODULE,&lt;br /&gt;
    &#039;archetypes&#039; =&amp;gt; array()&lt;br /&gt;
),&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==2. Get Moodle to load the updated capabilities==&lt;br /&gt;
&lt;br /&gt;
The capabilities you defined are only read (and copied into the Moodle database) when your module is installed or upgraded. So every time you edit the db/access.php file you must&lt;br /&gt;
# Increase your module&#039;s version number by editing the file mod/&amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt;/version.php.&lt;br /&gt;
# Go to the the Administration ► Notifications page, and click through the steps to let Moodle upgrade itself. You should see the name of your module in one of the steps.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==3. Checking the capability in your code==&lt;br /&gt;
&lt;br /&gt;
In order to check whether the current user has a particular capability, you need to use the has_capability function. To do that, first you have to get the appropriate context. In this case, it will be a module context.&lt;br /&gt;
&lt;br /&gt;
1. First we need to get the $cm id, and verify that it is correct (there are lots of different ways you might do this, this is only an example.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$cmid = required_param(&#039;cmid&#039;, PARAM_INT);&lt;br /&gt;
if (!$cm = get_coursemodule_from_id(&#039;&amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt;&#039;, $cmid)) {&lt;br /&gt;
    error(&amp;quot;Course module ID was incorrect&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Then you get the module context:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$context = context_module::instance($cm-&amp;gt;id);&lt;br /&gt;
//for course use below code&lt;br /&gt;
//$context = context_course::instance($cm-&amp;gt;id);&lt;br /&gt;
//for system &lt;br /&gt;
//$context = context_system::instance($cm-&amp;gt;id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Finally, you can actually check the permission&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (has_capability(&#039;mod/&amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt;:&amp;lt;&amp;lt;CAPABILITYNAME&amp;gt;&amp;gt;&#039;, $context)) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Normally, you do 1. and 2. once at the top of a script, and then call has_capability as needed within the script with the appropriate capabilities.&lt;br /&gt;
&lt;br /&gt;
===Useful variations===&lt;br /&gt;
&lt;br /&gt;
====Controlling overall access to a script====&lt;br /&gt;
&lt;br /&gt;
Suppose you have a page that should only be available to users with a particular capability. For example, only users with mod/quiz:viewreports should be able to access mod/quiz/report.php. In cases like this, you can use the require_capability function:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_capability($capability, $context);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
near the top of your script. (As soon as you have got the context and called require_login is a good time.) All this does internally is&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!has_capability($capability, $context)) {&lt;br /&gt;
    // Display error and exit.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
but using require_capability makes your code simpler and is recommended. (Of course, anywhere you might print a link to a page like this, you should only print the link if the user has the right capability.)&lt;br /&gt;
&lt;br /&gt;
====Getting a list of users with a capability====&lt;br /&gt;
&lt;br /&gt;
Suppose you need to get a list of all the users with a particular capability. (For example, the quiz reports list all the users with the mod/quiz:attempt capability. Then you can use the get_users_by_capability function. &lt;br /&gt;
&lt;br /&gt;
====Checking the permissions of another user====&lt;br /&gt;
&lt;br /&gt;
There is an optional 3rd parameter to has_capability that you can use to check another user&#039;s permissions:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
has_capability($capability, $context, $otheruser-&amp;gt;id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Excluding administrators====&lt;br /&gt;
&lt;br /&gt;
Administrators have a magic &#039;moodle/site:doanything&#039; capability that gives them every other capability. If you wish to disable that magic override for one particular capability check, you can use the optional 4th parameter to has capability:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
has_capability($capability, $context, NULL, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
However, you normally should not do this.&lt;br /&gt;
&lt;br /&gt;
====Performance considerations====&lt;br /&gt;
&lt;br /&gt;
The has_capability function has been carefully optimised, and is pretty fast and you should not really worry. However, it has to perform a fairly complex computation, and if you are going to make exactly the same has_capability call several times in a page (perhaps in a loop) it is probably worth moving the permission check outside the loop. For example don&#039;t do:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
foreach ($attempts as $attempt) {&lt;br /&gt;
    if (has_capability(&#039;mod/quiz:viewreports&#039;, $context)) {&lt;br /&gt;
        // ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Instead do&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$canviewreports = has_capability(&#039;mod/quiz:viewreports&#039;, $context);&lt;br /&gt;
foreach ($attempts as $attempt) {&lt;br /&gt;
    if ($canviewreports) {&lt;br /&gt;
        // ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get_users_by_capability is a very expensive computation. If you are calling it more than once in your script, you are probably doing something wrong ;-)&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Access API]]&lt;br /&gt;
* [[Roles]]&lt;br /&gt;
* [[Hardening_new_Roles_system]] - information about risks&lt;br /&gt;
* [[NEWMODULE_Documentation]] - NEWMODULE Documentation front page&lt;br /&gt;
&lt;br /&gt;
[[Category:Roles]]&lt;/div&gt;</summary>
		<author><name>Sadaf3d</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=NEWMODULE_Adding_capabilities&amp;diff=58290</id>
		<title>NEWMODULE Adding capabilities</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=NEWMODULE_Adding_capabilities&amp;diff=58290"/>
		<updated>2021-02-03T13:38:25Z</updated>

		<summary type="html">&lt;p&gt;Sadaf3d: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{New_Module}}&lt;br /&gt;
In order to add a capabilities for your &amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt; you need to:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==1. Create a file access.php in the &amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt;/db directory==&lt;br /&gt;
&lt;br /&gt;
This should contain a list of the capabilities that you want to define. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$capabilities = array(&lt;br /&gt;
    &#039;mod/&amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt;:&amp;lt;&amp;lt;CAPABILITYNAME&amp;gt;&amp;gt;&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;riskbitmask&#039;  =&amp;gt; RISK_SPAM | RISK_PERSONAL | RISK_XSS | RISK_CONFIG,&lt;br /&gt;
        &#039;captype&#039;      =&amp;gt; &#039;write&#039;,&lt;br /&gt;
        &#039;contextlevel&#039; =&amp;gt; CONTEXT_MODULE,&lt;br /&gt;
        &#039;archetypes&#039;   =&amp;gt; array(&lt;br /&gt;
            &#039;student&#039;        =&amp;gt; CAP_ALLOW,&lt;br /&gt;
            &#039;teacher&#039;        =&amp;gt; CAP_ALLOW,&lt;br /&gt;
            &#039;editingteacher&#039; =&amp;gt; CAP_ALLOW,&lt;br /&gt;
            &#039;manager&#039;          =&amp;gt; CAP_ALLOW&lt;br /&gt;
        )&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Add more capabilities here ...&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The various parts of the capability definition are:&lt;br /&gt;
&lt;br /&gt;
===Capability name (&#039;mod/&amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt;:&amp;lt;&amp;lt;CAPABILITYNAME&amp;gt;&amp;gt;)===&lt;br /&gt;
&lt;br /&gt;
This is the internal name used for this this capability. In addition to this internal name, you should also add the language string &amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt;:&amp;lt;&amp;lt;CAPABILITYNAME&amp;gt;&amp;gt; to your module&#039;s language file, to give the capability a name that users will see in the interface.&lt;br /&gt;
&lt;br /&gt;
===riskbitmask===&lt;br /&gt;
&lt;br /&gt;
Allowing people to do various things sometimes requires introducing possible security risks. For example, if you can post to a forum, you can post unsolicited advertising. To a certain extent users have to be trusted. To help administrators and teachers know what the issues are, each capability should list any associated risks. See [[Hardening_new_Roles_system]]. will be reflected in the list of icons of each row of the &#039;Override permissions&#039;-&amp;gt;roles page.&lt;br /&gt;
&lt;br /&gt;
Technically, this value is a bit field, so you should combine the relevant risks constants with the &#039;|&#039; operator. So typical values might be:&lt;br /&gt;
* RISK_SPAM&lt;br /&gt;
* RISK_PERSONAL | RISK_XSS | RISK_DATALOSS&lt;br /&gt;
&lt;br /&gt;
===captype===&lt;br /&gt;
&lt;br /&gt;
Should be either &#039;read&#039; or &#039;write&#039;. &#039;read&#039; is for capabilities that just let you view things. &#039;write&#039; for capabilities that let you change things.&lt;br /&gt;
&lt;br /&gt;
===contextlevel===&lt;br /&gt;
&lt;br /&gt;
The context level where this capability is most relevant. If you are writing a module this will almost always be [[Context|CONTEXT_MODULE]]. (This does not have much effect. It is just used to sort and group capabilities on the define roles and override roles pages.)&lt;br /&gt;
&lt;br /&gt;
===archetypes===&lt;br /&gt;
&lt;br /&gt;
This section defines, for each role type, what default permissions those roles should be given when your module is first installed (or when a new capability is detected on upgrade).&lt;br /&gt;
&lt;br /&gt;
Normally, you just add one line for each role that you want to give the capability to. The line should look like &#039;roletype&#039; =&amp;gt; CAP_ALLOW. Just leave out roles that you do not want to get the capability by default. Very exceptionally, you may need to specify a default permission of CAP_PREVENT, CAP_PROHIBIT.&lt;br /&gt;
&lt;br /&gt;
Note that once a capability is established, permissions will not be automatically overwritten when a module is updated. If permissions have changed, an administrator must manually change or force capabilities to be [[:en:Manage_roles#Reset_role_to_defaults|reset to default]] for a role.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to specify any roles that will be given your capability by default, you can pass a blank array to the &#039;archetypes&#039; parameter:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&#039;mod/newmodule:dosomething&#039; =&amp;gt; array(&lt;br /&gt;
    &#039;captype&#039; =&amp;gt; &#039;read&#039;,&lt;br /&gt;
    &#039;contextlevel&#039; =&amp;gt; CONTEXT_MODULE,&lt;br /&gt;
    &#039;archetypes&#039; =&amp;gt; array()&lt;br /&gt;
),&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==2. Get Moodle to load the updated capabilities==&lt;br /&gt;
&lt;br /&gt;
The capabilities you defined are only read (and copied into the Moodle database) when your module is installed or upgraded. So every time you edit the db/access.php file you must&lt;br /&gt;
# Increase your module&#039;s version number by editing the file mod/&amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt;/version.php.&lt;br /&gt;
# Go to the the Administration ► Notifications page, and click through the steps to let Moodle upgrade itself. You should see the name of your module in one of the steps.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==3. Checking the capability in your code==&lt;br /&gt;
&lt;br /&gt;
In order to check whether the current user has a particular capability, you need to use the has_capability function. To do that, first you have to get the appropriate context. In this case, it will be a module context.&lt;br /&gt;
&lt;br /&gt;
1. First we need to get the $cm id, and verify that it is correct (there are lots of different ways you might do this, this is only an example.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$cmid = required_param(&#039;cmid&#039;, PARAM_INT);&lt;br /&gt;
if (!$cm = get_coursemodule_from_id(&#039;&amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt;&#039;, $cmid)) {&lt;br /&gt;
    error(&amp;quot;Course module ID was incorrect&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Then you get the module context:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$context = context_module::instance($cm-&amp;gt;id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Finally, you can actually check the permission&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (has_capability(&#039;mod/&amp;lt;&amp;lt;NEWMODULE&amp;gt;&amp;gt;:&amp;lt;&amp;lt;CAPABILITYNAME&amp;gt;&amp;gt;&#039;, $context)) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Normally, you do 1. and 2. once at the top of a script, and then call has_capability as needed within the script with the appropriate capabilities.&lt;br /&gt;
&lt;br /&gt;
===Useful variations===&lt;br /&gt;
&lt;br /&gt;
====Controlling overall access to a script====&lt;br /&gt;
&lt;br /&gt;
Suppose you have a page that should only be available to users with a particular capability. For example, only users with mod/quiz:viewreports should be able to access mod/quiz/report.php. In cases like this, you can use the require_capability function:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_capability($capability, $context);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
near the top of your script. (As soon as you have got the context and called require_login is a good time.) All this does internally is&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!has_capability($capability, $context)) {&lt;br /&gt;
    // Display error and exit.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
but using require_capability makes your code simpler and is recommended. (Of course, anywhere you might print a link to a page like this, you should only print the link if the user has the right capability.)&lt;br /&gt;
&lt;br /&gt;
====Getting a list of users with a capability====&lt;br /&gt;
&lt;br /&gt;
Suppose you need to get a list of all the users with a particular capability. (For example, the quiz reports list all the users with the mod/quiz:attempt capability. Then you can use the get_users_by_capability function. &lt;br /&gt;
&lt;br /&gt;
====Checking the permissions of another user====&lt;br /&gt;
&lt;br /&gt;
There is an optional 3rd parameter to has_capability that you can use to check another user&#039;s permissions:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
has_capability($capability, $context, $otheruser-&amp;gt;id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Excluding administrators====&lt;br /&gt;
&lt;br /&gt;
Administrators have a magic &#039;moodle/site:doanything&#039; capability that gives them every other capability. If you wish to disable that magic override for one particular capability check, you can use the optional 4th parameter to has capability:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
has_capability($capability, $context, NULL, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
However, you normally should not do this.&lt;br /&gt;
&lt;br /&gt;
====Performance considerations====&lt;br /&gt;
&lt;br /&gt;
The has_capability function has been carefully optimised, and is pretty fast and you should not really worry. However, it has to perform a fairly complex computation, and if you are going to make exactly the same has_capability call several times in a page (perhaps in a loop) it is probably worth moving the permission check outside the loop. For example don&#039;t do:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
foreach ($attempts as $attempt) {&lt;br /&gt;
    if (has_capability(&#039;mod/quiz:viewreports&#039;, $context)) {&lt;br /&gt;
        // ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Instead do&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$canviewreports = has_capability(&#039;mod/quiz:viewreports&#039;, $context);&lt;br /&gt;
foreach ($attempts as $attempt) {&lt;br /&gt;
    if ($canviewreports) {&lt;br /&gt;
        // ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get_users_by_capability is a very expensive computation. If you are calling it more than once in your script, you are probably doing something wrong ;-)&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Access API]]&lt;br /&gt;
* [[Roles]]&lt;br /&gt;
* [[Hardening_new_Roles_system]] - information about risks&lt;br /&gt;
* [[NEWMODULE_Documentation]] - NEWMODULE Documentation front page&lt;br /&gt;
&lt;br /&gt;
[[Category:Roles]]&lt;/div&gt;</summary>
		<author><name>Sadaf3d</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Gradebook_reports&amp;diff=57452</id>
		<title>Gradebook reports</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Gradebook_reports&amp;diff=57452"/>
		<updated>2020-05-09T22:34:59Z</updated>

		<summary type="html">&lt;p&gt;Sadaf3d: /* Bare minimum */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
One of the great features of the new gradebook implementation in Moodle 1.9 is the support for plug-in reports. A few reports are already included in the release, but it is fast and easy to create new reports of any kind.&lt;br /&gt;
&lt;br /&gt;
This page is a small tutorial on how to create a new report for the Moodle gradebook. The first section highlights the basic setup steps, the bare minimum to get your plug-in detected and usable. The second section gives an example of a possible implementation, although you are free to develop outside of these suggestions.&lt;br /&gt;
&lt;br /&gt;
The simplest example report to look at while following this guide is &#039;&#039;&#039;grade/report/overview&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Bare minimum ==&lt;br /&gt;
&lt;br /&gt;
These steps all involve creating new files, but in all cases they can be copy-pasted from existing reports, to make your life easier.&lt;br /&gt;
&lt;br /&gt;
1. Create a new folder under grade/report &lt;br /&gt;
    grade/report/[newreport]&lt;br /&gt;
2. Create a /db sub-folder under the new report folder &lt;br /&gt;
    grade/report/[newreport]/db&lt;br /&gt;
3. Create an access.php file in the db folder with the following content. You should change the capabilities as needed.&lt;br /&gt;
    grade/report/[newreport]/db/access.php&lt;br /&gt;
  &lt;br /&gt;
    &amp;lt;?php&lt;br /&gt;
    $capabilities = array(&lt;br /&gt;
        &#039;gradereport/[newreport]:view&#039; =&amp;gt; array(&lt;br /&gt;
            &#039;riskbitmask&#039; =&amp;gt; RISK_PERSONAL,&lt;br /&gt;
            &#039;captype&#039; =&amp;gt; &#039;read&#039;,&lt;br /&gt;
            &#039;contextlevel&#039; =&amp;gt; CONTEXT_COURSE,&lt;br /&gt;
            &#039;legacy&#039; =&amp;gt; array(&lt;br /&gt;
                &#039;student&#039; =&amp;gt; CAP_ALLOW,&lt;br /&gt;
                &#039;teacher&#039; =&amp;gt; CAP_ALLOW,&lt;br /&gt;
                &#039;editingteacher&#039; =&amp;gt; CAP_ALLOW,&lt;br /&gt;
                &#039;manager&#039; =&amp;gt; CAP_ALLOW&lt;br /&gt;
            )&lt;br /&gt;
        ),&lt;br /&gt;
    );&lt;br /&gt;
    ?&amp;gt;&lt;br /&gt;
4. Create a version.php file with the current dates:&lt;br /&gt;
    grade/report/[newreport]/version.php&lt;br /&gt;
    &amp;lt;?php&lt;br /&gt;
    $plugin-&amp;gt;version  = 2007081000;&lt;br /&gt;
    $plugin-&amp;gt;requires = 2007081000;&lt;br /&gt;
    ?&amp;gt;&lt;br /&gt;
5.Create an index.php&lt;br /&gt;
    grade/report/[newreport]/index.php&lt;br /&gt;
6.Create a language file for your report. Include at least the modulename, and optionally the strings for different capabilities. &lt;br /&gt;
    grade/report/[newreport]/lang/en_utf8/gradereport_[newreport].php&lt;br /&gt;
    &lt;br /&gt;
    Example from user report here:&lt;br /&gt;
    &lt;br /&gt;
    $string[&#039;modulename&#039;] = &#039;User report&#039;;&lt;br /&gt;
    $string[&#039;user:view&#039;] = &#039;View your own grade report&#039;;&lt;br /&gt;
&lt;br /&gt;
You do not need to create a new link to your report, it will be automatically detected and added to the gradebook plugin drop-down menu, if you&#039;ve followed all these steps!&lt;br /&gt;
7. Create an upgrade.php file in the db folder with the following content:&lt;br /&gt;
grade/report/[newreport]/db/upgrade.php&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
This is all you need to do to create a new report! Now, of course, you&#039;ll want the code to actually DO something, usually fetch and display some data. The next section discusses one easy approach using flexitable.&lt;br /&gt;
&lt;br /&gt;
== Possible step 8 ==&lt;br /&gt;
&lt;br /&gt;
I also needed to include the &#039;&#039;&#039;settings.php&#039;&#039;&#039; file in my new &#039;&#039;grade\report\[directory name]&#039;&#039; directory.  If the file was not present, i received this error &#039;&#039;&#039;&amp;quot;Section Error!&amp;quot;&#039;&#039;&#039;.  Once i added the file to the grade\report\[directory name] directory, it corrected.  The settings.php file is empty.  I am using Moodle 1.9.&lt;br /&gt;
&lt;br /&gt;
I did not need to add setting.php file using Moodle 2.1.&lt;br /&gt;
&lt;br /&gt;
== Possible step 9 ==&lt;br /&gt;
&lt;br /&gt;
If the report is made available to multiple users you may need to update the tables by going to the admin section of your Moodle installation, just like when you are upgrading. Then go the the define roles and make sure that your permissions are set correct. I&#039;m using Moodle 1.9&lt;br /&gt;
&lt;br /&gt;
== Extending the grade_report class == &lt;br /&gt;
 &lt;br /&gt;
You are free to develop that class any way you want, but by using the existing methods set up in grade_report, you can avoid tedious repetition of code. We use flexitable for simple reports, as you can see in the user report (grade_report_user class).    The rest of this tutorial will follow the path of flexitable.&lt;br /&gt;
&lt;br /&gt;
=== New file ===&lt;br /&gt;
#Create a lib.php file (or copy it from other report).&lt;br /&gt;
    grade/report/[newreport]/lib.php&lt;br /&gt;
&lt;br /&gt;
#The lib.php contains an extension of the grade_report class, and should be named&lt;br /&gt;
    grade_report_[newreport]&lt;br /&gt;
&lt;br /&gt;
=== Grade_report class variables ===&lt;br /&gt;
The grade_report class makes the following variables available to your new class, if you use its constructor in your child class&#039; constructor:&lt;br /&gt;
    &lt;br /&gt;
; courseid       : Required by constructor&lt;br /&gt;
; gpr            : Grade plugin return tracking object, required by constructor&lt;br /&gt;
; context        : Required by constructor&lt;br /&gt;
; gtree          : The grade_tree must be instantiated in child classes: not all reports need the whole tree&lt;br /&gt;
; prefs          : Array of user preferences related to this report. Methods are given to get and set these easily&lt;br /&gt;
; gradebookroles : The roles for this report, pulled out of $CFG-&amp;gt;gradebookroles&lt;br /&gt;
; baseurl        : Base url for sorting by first/last name (not needed by all reports)&lt;br /&gt;
; pbarurl        : Base url for paging&lt;br /&gt;
; page           : Current page (for paging). Must be given to constructor if paging is required.&lt;br /&gt;
; lang_strings   : Array of cached language strings (using get_string() all the time                           takes a long time!). A method is provided to replace get_string() and use this cache    &lt;br /&gt;
; currentgroup   : The current group being displayed.&lt;br /&gt;
; group_selector : A HTML select element used to select the current group.&lt;br /&gt;
; groupsql       : An SQL fragment used to add linking information to the group tables.&lt;br /&gt;
; groupwheresql  : An SQL constraint to append to the queries used by this object to build the report.&lt;br /&gt;
&lt;br /&gt;
=== Grade_report class methods === &lt;br /&gt;
&lt;br /&gt;
The grade_report class has the following methods which you can use, provided the right steps have been taken to initialise the object first:&lt;br /&gt;
; get_pref()            : Given the name of a user preference (without grade_report_ prefix), locally saves then returns the value of that preference. If the preference has already been fetched before, the saved value is returned. If the preference is not set at the User level, the $CFG equivalent is given (site default).&lt;br /&gt;
; set_pref()            : Uses set_user_preferences() to update the value of a user preference. If &#039;default&#039; is given as the value, the preference will be removed in favour of a higher-level preference ($CFG-&amp;gt;$pref_name usually)&lt;br /&gt;
; process_data()        : Abstract method, needs to be implemented by child classes if they want to handle user form submissions on the report they want to handle user actions on the report                                  &lt;br /&gt;
; process_action()      : Abstract method, needs to be implemented by child classes if they want to handle user actions on the report&lt;br /&gt;
; get_grade_clean()     : format grade using lang specific decimal point and thousand separator the result is suitable for printing on html page&lt;br /&gt;
; format_grade()        : Given a user input grade, format it to standard format i.e. no thousand separator, and . as decimal point&lt;br /&gt;
; get_lang_string()     : First checks the cached language strings, then returns match if found, or uses get_string(). Use this for any lang_strings in the grades.php file.&lt;br /&gt;
; grade_to_percentage() : Computes then returns the percentage value of the grade value within the given range.&lt;br /&gt;
; get_grade_letters()   : Fetches and returns an array of grade letters indexed by their grade boundaries, as stored in preferences.&lt;br /&gt;
; get_numusers()        : Fetches and returns a count of all the users that will be shown on this page.&lt;br /&gt;
; setup_groups()        : Sets up this object&#039;s group variables, mainly to restrict the selection of users to display.&lt;br /&gt;
; get_sort_arrow()      : Returns an arrow icon inside an &amp;lt;a&amp;gt; tag, for the purpose of sorting a column.&lt;br /&gt;
; get_module_link()     : Builds and returns a HTML link to the grade or view page of the module given. If no itemmodule is given, only the name of the category/item is returned, no link.&lt;br /&gt;
&lt;br /&gt;
=== Report child class ===&lt;br /&gt;
&lt;br /&gt;
Assuming you are using flexitable, your child class needs the following variable and methods:&lt;br /&gt;
    $table : The flexitable that will hold the data&lt;br /&gt;
    &lt;br /&gt;
*grade_report_[newreport]() : Constructor. You can set up anything here, but you must call the parent constructor with the 3 required params:&lt;br /&gt;
        parent::grade_report($COURSE-&amp;gt;id, $gpr, $context);&lt;br /&gt;
        The $gpr and $context variables are normally set up in grade/report/[newreport]/index.php&lt;br /&gt;
    &lt;br /&gt;
*setup_table() : Prepares the headers and attributes of the flexitable. Example used for the very simple overview report:&lt;br /&gt;
        // setting up table headers&lt;br /&gt;
        $tablecolumns = array(&#039;coursename&#039;, &#039;grade&#039;, &#039;rank&#039;);&lt;br /&gt;
        $tableheaders = array($this-&amp;gt;get_lang_string(&#039;coursename&#039;, &#039;grades&#039;),&lt;br /&gt;
                              $this-&amp;gt;get_lang_string(&#039;grade&#039;),&lt;br /&gt;
                              $this-&amp;gt;get_lang_string(&#039;rank&#039;, &#039;grades&#039;));&lt;br /&gt;
 &lt;br /&gt;
        $this-&amp;gt;table = new flexible_table(&#039;grade-report-overview-&#039;.$this-&amp;gt;user-&amp;gt;id);&lt;br /&gt;
 &lt;br /&gt;
        $this-&amp;gt;table-&amp;gt;define_columns($tablecolumns);&lt;br /&gt;
        $this-&amp;gt;table-&amp;gt;define_headers($tableheaders);&lt;br /&gt;
        $this-&amp;gt;table-&amp;gt;define_baseurl($this-&amp;gt;baseurl);&lt;br /&gt;
 &lt;br /&gt;
        $this-&amp;gt;table-&amp;gt;set_attribute(&#039;cellspacing&#039;, &#039;0&#039;);&lt;br /&gt;
        $this-&amp;gt;table-&amp;gt;set_attribute(&#039;id&#039;, &#039;overview-grade&#039;);&lt;br /&gt;
        $this-&amp;gt;table-&amp;gt;set_attribute(&#039;class&#039;, &#039;boxaligncenter generaltable&#039;);&lt;br /&gt;
 &lt;br /&gt;
        $this-&amp;gt;table-&amp;gt;setup();&lt;br /&gt;
     &lt;br /&gt;
*fill_table() : After setup_table(), gathers and enters the data in the table. Again, from the overview report:&lt;br /&gt;
        global $CFG;&lt;br /&gt;
        $numusers = $this-&amp;gt;get_numusers();&lt;br /&gt;
 &lt;br /&gt;
        if ($courses = get_courses(&#039;all&#039;, null, &#039;c.id, c.shortname&#039;)) {&lt;br /&gt;
            foreach ($courses as $course) {&lt;br /&gt;
                // Get course grade_item&lt;br /&gt;
                $grade_item_id = get_field(&#039;grade_items&#039;, &#039;id&#039;, &#039;itemtype&#039;, &lt;br /&gt;
                                           &#039;course&#039;, &#039;courseid&#039;, $course-&amp;gt;id);&lt;br /&gt;
 &lt;br /&gt;
                // Get the grade&lt;br /&gt;
                $finalgrade = get_field(&#039;grade_grades&#039;, &#039;finalgrade&#039;, &#039;itemid&#039;, &lt;br /&gt;
                                        $grade_item_id, &#039;userid&#039;, $this-&amp;gt;user-&amp;gt;id);&lt;br /&gt;
 &lt;br /&gt;
                /// prints rank&lt;br /&gt;
                if ($finalgrade) {&lt;br /&gt;
                    /// find the number of users with a higher grade&lt;br /&gt;
                    $sql = &amp;quot;SELECT COUNT(DISTINCT(userid))&lt;br /&gt;
                            FROM {$CFG-&amp;gt;prefix}grade_grades&lt;br /&gt;
                            WHERE finalgrade &amp;gt; $finalgrade&lt;br /&gt;
                            AND itemid = $grade_item_id&amp;quot;;&lt;br /&gt;
                    $rank = count_records_sql($sql) + 1;&lt;br /&gt;
 &lt;br /&gt;
                    $rankdata = &amp;quot;$rank/$numusers&amp;quot;;&lt;br /&gt;
                } else {&lt;br /&gt;
                    // no grade, no rank&lt;br /&gt;
                    $rankdata = &amp;quot;-&amp;quot;;&lt;br /&gt;
                }&lt;br /&gt;
 &lt;br /&gt;
                $this-&amp;gt;table-&amp;gt;add_data(array($course-&amp;gt;shortname, $finalgrade, $rankdata));&lt;br /&gt;
            }&lt;br /&gt;
 &lt;br /&gt;
            return true;&lt;br /&gt;
        } else {&lt;br /&gt;
            notify(get_string(&#039;nocourses&#039;, &#039;grades&#039;));&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
*print_table() : Just does what its name says...&lt;br /&gt;
        ob_start();&lt;br /&gt;
        $this-&amp;gt;table-&amp;gt;print_html();&lt;br /&gt;
        $html = ob_get_clean();&lt;br /&gt;
        if ($return) {&lt;br /&gt;
            return $html;&lt;br /&gt;
        } else {&lt;br /&gt;
            echo $html;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
*process_data() and process_action() : You can implement these two methods if you need to handle data and actions.&lt;br /&gt;
&lt;br /&gt;
=== Set up the index.php file ===&lt;br /&gt;
Here is the simple example from the overview report (grade/report/overview).&lt;br /&gt;
    &lt;br /&gt;
    require_once &#039;../../../config.php&#039;;&lt;br /&gt;
    require_once $CFG-&amp;gt;libdir.&#039;/gradelib.php&#039;;&lt;br /&gt;
    require_once $CFG-&amp;gt;dirroot.&#039;/grade/lib.php&#039;;&lt;br /&gt;
    require_once $CFG-&amp;gt;dirroot.&#039;/grade/report/overview/lib.php&#039;;&lt;br /&gt;
 &lt;br /&gt;
    $courseid = optional_param(&#039;id&#039;, $COURSE-&amp;gt;id, PARAM_INT);&lt;br /&gt;
    $userid   = optional_param(&#039;userid&#039;, $USER-&amp;gt;id, PARAM_INT);&lt;br /&gt;
 &lt;br /&gt;
    /// basic access checks&lt;br /&gt;
    if (!$course = get_record(&#039;course&#039;, &#039;id&#039;, $courseid)) {&lt;br /&gt;
        print_error(&#039;nocourseid&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    require_login($course);&lt;br /&gt;
 &lt;br /&gt;
    if (!$user = get_complete_user_data(&#039;id&#039;, $userid)) {&lt;br /&gt;
        error(&amp;quot;Incorrect userid&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    $context     = get_context_instance(CONTEXT_COURSE, $course-&amp;gt;id);&lt;br /&gt;
    $usercontext = get_context_instance(CONTEXT_USER, $user-&amp;gt;id);&lt;br /&gt;
    require_capability(&#039;gradereport/overview:view&#039;, $context);&lt;br /&gt;
 &lt;br /&gt;
    $access = true;&lt;br /&gt;
    if (has_capability(&#039;moodle/grade:viewall&#039;, $context)) {&lt;br /&gt;
        //ok - can view all course grades&lt;br /&gt;
 &lt;br /&gt;
    } else if ($user-&amp;gt;id == $USER-&amp;gt;id and has_capability(&#039;moodle/grade:view&#039;, $context) and $course-&amp;gt;showgrades) {&lt;br /&gt;
        //ok - can view own grades&lt;br /&gt;
 &lt;br /&gt;
    } else if (has_capability(&#039;moodle/grade:viewall&#039;, $usercontext) and $course-&amp;gt;showgrades) {&lt;br /&gt;
        // ok - can view grades of this user- parent most probably&lt;br /&gt;
 &lt;br /&gt;
    } else {&lt;br /&gt;
        $acces = false;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    /// return tracking object&lt;br /&gt;
    $gpr = new grade_plugin_return(array(&#039;type&#039;=&amp;gt;&#039;report&#039;, &#039;plugin&#039;=&amp;gt;&#039;overview&#039;, &#039;courseid&#039;=&amp;gt;$course-&amp;gt;id, &#039;userid&#039;=&amp;gt;$userid));&lt;br /&gt;
 &lt;br /&gt;
    /// last selected report session tracking&lt;br /&gt;
    if (!isset($USER-&amp;gt;grade_last_report)) {&lt;br /&gt;
        $USER-&amp;gt;grade_last_report = array();&lt;br /&gt;
    }&lt;br /&gt;
    $USER-&amp;gt;grade_last_report[$course-&amp;gt;id] = &#039;overview&#039;;&lt;br /&gt;
 &lt;br /&gt;
    /// Build navigation&lt;br /&gt;
    $strgrades  = get_string(&#039;grades&#039;);&lt;br /&gt;
    $reportname = get_string(&#039;modulename&#039;, &#039;gradereport_overview&#039;);&lt;br /&gt;
 &lt;br /&gt;
    $navigation = grade_build_nav(__FILE__, $reportname, $course-&amp;gt;id);&lt;br /&gt;
 &lt;br /&gt;
    /// Print header&lt;br /&gt;
    print_header_simple($strgrades.&#039;: &#039;.$reportname, &#039;: &#039;.$strgrades, $navigation,&lt;br /&gt;
                        &#039;&#039;, &#039;&#039;, true, &#039;&#039;, navmenu($course));&lt;br /&gt;
 &lt;br /&gt;
    /// Print the plugin selector at the top&lt;br /&gt;
    print_grade_plugin_selector($course-&amp;gt;id, &#039;report&#039;, &#039;overview&#039;);&lt;br /&gt;
 &lt;br /&gt;
    if ($access) {&lt;br /&gt;
 &lt;br /&gt;
        //first make sure we have proper final grades - this must be done before constructing of the grade tree&lt;br /&gt;
        grade_regrade_final_grades($course-&amp;gt;id);&lt;br /&gt;
 &lt;br /&gt;
        // Create a report instance&lt;br /&gt;
        $report = new grade_report_overview($userid, $gpr, $context);&lt;br /&gt;
 &lt;br /&gt;
        $gradetotal = 0;&lt;br /&gt;
        $gradesum = 0;&lt;br /&gt;
 &lt;br /&gt;
        // print the page&lt;br /&gt;
        print_heading(get_string(&#039;modulename&#039;, &#039;gradereport_overview&#039;). &#039; - &#039;.fullname($report-&amp;gt;user));&lt;br /&gt;
 &lt;br /&gt;
        if ($report-&amp;gt;fill_table()) {&lt;br /&gt;
            echo $report-&amp;gt;print_table(true);&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
    } else {&lt;br /&gt;
        // no access to grades!&lt;br /&gt;
        echo &amp;quot;Can not view grades.&amp;quot;; //TODO: localize&lt;br /&gt;
    }&lt;br /&gt;
    print_footer($course);&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
This short tutorial doesn&#039;t explain how to actually create a &#039;&#039;useful&#039;&#039; report. That part is essentially up to you, and there are no hard rules about how to do it. Instead, this tutorial explains how to setup a &amp;quot;stub&amp;quot; report, a basic framework with a set of tools and variables you can use to create a fully functional and essential report for your Moodle needs. Please share your report-building experiences and tribulations with the Moodle community through the forum.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=69223&amp;amp;mode=3 Gradebook Development ideas] forum discussion&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=51107 New gradebook for Moodle] forum discussion&lt;br /&gt;
* [[Grades]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Grades]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Plugins]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[ja:開発:評定表レポートチュートリアル]]&lt;/div&gt;</summary>
		<author><name>Sadaf3d</name></author>
	</entry>
</feed>