<?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=Vaibspidy</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=Vaibspidy"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Vaibspidy"/>
	<updated>2026-08-12T07:46:01Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Page_API&amp;diff=49987</id>
		<title>Page API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Page_API&amp;diff=49987"/>
		<updated>2016-05-09T20:37:54Z</updated>

		<summary type="html">&lt;p&gt;Vaibspidy: /* Page layout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Page API is used to set up the current page, add JavaScript, and configure how things will be displayed to the user.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
The Page API is an integral part of any Moodle page. It allows the developer to set things up the way they envisage it. Through the Page API you can set things like the title, initial heading, where the user is for the navigation, and which layout you think the page should use.&lt;br /&gt;
&lt;br /&gt;
This document starts off with a simple example, and then proceeds to provide a more complete description of how to set up a page for display.&lt;br /&gt;
&lt;br /&gt;
==A simple example==&lt;br /&gt;
This example covers how to set up a basic page for use within an activity plugin and is undoubtedly the simplest example as much of the work is done behind the scenes for you.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// File: /mod/mymodulename/view.php&lt;br /&gt;
require_once(&#039;../../config.php&#039;);&lt;br /&gt;
$cmid = required_param(&#039;id&#039;, PARAM_INT);&lt;br /&gt;
$cm = get_coursemodule_from_id(&#039;mymodulename&#039;, $cmid, 0, false, MUST_EXIST);&lt;br /&gt;
$course = $DB-&amp;gt;get_record(&#039;course&#039;, array(&#039;id&#039; =&amp;gt; $cm-&amp;gt;course), &#039;*&#039;, MUST_EXIST);&lt;br /&gt;
&lt;br /&gt;
require_login($course, true, $cm);&lt;br /&gt;
$PAGE-&amp;gt;set_url(&#039;/mod/mymodulename/view.php&#039;, array(&#039;id&#039; =&amp;gt; $cm-&amp;gt;id));&lt;br /&gt;
$PAGE-&amp;gt;set_title(&#039;My modules page title&#039;);&lt;br /&gt;
$PAGE-&amp;gt;set_heading(&#039;My modules page heading&#039;);&lt;br /&gt;
&lt;br /&gt;
// The rest of your code goes below this.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
I&#039;m going to assume you know what the first four lines are doing, if not you are starting in the wrong place.&lt;br /&gt;
&lt;br /&gt;
So lets start at require_login and assume you already have the course and course module objects ready to use. When you call require_login part of the magic it does for you is set up the basic for the current page.&amp;lt;br /&amp;gt;&lt;br /&gt;
In the case of the example above because require_login is given a course and course module it is already setting up much of the page for you. It is giving the course and course module objects to the page, setting the context for the page to the course modules context, and setting the page layout to &#039;&#039;incourse&#039;&#039; so that you get the standard look of a course module.&lt;br /&gt;
&lt;br /&gt;
The set up that we are having to do is as follows:&lt;br /&gt;
# Set the URL for the page. This MUST be done.&lt;br /&gt;
# Set a title for the page. Most likely will be shown in the &amp;lt;title&amp;gt; tag.&lt;br /&gt;
# Set the heading for the page. Most likely used in the pages header.&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to mention that this has to be done before output starts. That means you must set up the page before the header is printed and before you instantiate any moodleform instances.&lt;br /&gt;
&lt;br /&gt;
And that is it, if you were to add a bit of simple output there you would get a page that already looks like other module pages you would have seen. Simple as.&lt;br /&gt;
&lt;br /&gt;
==$PAGE The Moodle page global==&lt;br /&gt;
For every page request Moodle sets up a couple of global structures that you will likely need. $DB the database object, and $CFG which stores configuration are two that you are likely already aware of. $PAGE is the focus of this article, it is a moodle_page instance that stores all of the information and is used by the output library $OUTPUT when displaying the page.&amp;lt;br /&amp;gt;&lt;br /&gt;
It&#039;s important to note the difference between $PAGE and $OUTPUT, $PAGE is for setting up the page and $OUTPUT is for displaying the page. $PAGE contains lots of logic and magic, $OUTPUT is purely about display and does little more than produce HTML.&lt;br /&gt;
&lt;br /&gt;
==Setting up the page==&lt;br /&gt;
When creating a page in Moodle there are a couple of things that you must set, and a couple of things that get set for you in many cases but not all of the time.&lt;br /&gt;
&lt;br /&gt;
===URL===&lt;br /&gt;
This is an absolute must, failing to set this will lead Moodle to display an error that it has not been set.&amp;lt;br /&amp;gt;&lt;br /&gt;
It can be set in the following manner:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_url(new moodle_url(&#039;/path/to/your/file.php&#039;, array(&#039;key&#039; =&amp;gt; &#039;value&#039;, &#039;id&#039; =&amp;gt; 3)));&lt;br /&gt;
$PAGE-&amp;gt;set_url(&#039;/path/to/your/file.php&#039;, array(&#039;key&#039; =&amp;gt; &#039;value&#039;, &#039;id&#039; =&amp;gt; 3));&lt;br /&gt;
$PAGE-&amp;gt;set_url(&#039;/path/to/your/file.php?key=value&amp;amp;id=3&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code sets the page URL 3 times, and highlights the 3 different ways you can set the URL. Either of the first two methods are the preferred way as it provides 100% accuracy when processing the URL. Internally set_url() converts what ever you give it to a moodle_url object.&lt;br /&gt;
&lt;br /&gt;
The URL that you give to the page is going to be used by many Moodle core API&#039;s. Most importantly it is going to be used to create the navigation for your page so it&#039;s very important you set it accurately.&lt;br /&gt;
&lt;br /&gt;
===Context===&lt;br /&gt;
This is an absolute must as well, however in many cases it will be set for you magically by Moodle.&lt;br /&gt;
&lt;br /&gt;
In order to set the context for the page you must provide a context object, in Moodle 2.2 and greater this will look as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Moodle 2.2 and greater&lt;br /&gt;
$PAGE-&amp;gt;set_context(context_system::instance());&lt;br /&gt;
$PAGE-&amp;gt;set_context(context_coursecat::instance($categoryid));&lt;br /&gt;
$PAGE-&amp;gt;set_context(context_course::instance($courseid));&lt;br /&gt;
$PAGE-&amp;gt;set_context(context_module::instance($moduleid));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0+, and Moodle 2.1+ the following is the equivalent code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Moodle 2.0 and 2.1&lt;br /&gt;
$PAGE-&amp;gt;set_context(get_system_context());&lt;br /&gt;
$PAGE-&amp;gt;set_context(get_context_instance(CONTEXT_COURSECAT, $categoryid));&lt;br /&gt;
$PAGE-&amp;gt;set_context(get_context_instance(CONTEXT_COURSE, $courseid));&lt;br /&gt;
$PAGE-&amp;gt;set_context(get_context_instance(CONTEXT_MODULE, $moduleid));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In both examples above setting different types of contexts has been illustrated however you should only ever call set_context() once with the context that is most appropriate to the page you are creating.&amp;lt;br /&amp;gt;&lt;br /&gt;
If it is a plugin then the context to use would be the context you are using for your capability checks.&lt;br /&gt;
&lt;br /&gt;
As mentioned above the other thing to be aware of is that in some circumstances this gets automatically set for you.&amp;lt;br /&amp;gt;&lt;br /&gt;
If your script calls require_login (and most scripts have to) and you are providing a course, or a module to your require login call then you will not need to call set_context().&amp;lt;br /&amp;gt;&lt;br /&gt;
This is because require_login handles it for you.&lt;br /&gt;
&lt;br /&gt;
If your script doesn&#039;t call require_login, or you don&#039;t call it with a course and/or module then you will need to manually set the context as shown.&lt;br /&gt;
&lt;br /&gt;
===Optional set up===&lt;br /&gt;
The following are optional extras you can set up against the PAGE object that you are likely to encounter throughout Moodle core, and are likely to want to use yourself.&lt;br /&gt;
====Page layout====&lt;br /&gt;
The following code sets the pages layout to the standard layout, the most generic layout in the arsenal.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_pagelayout(&#039;standard&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
When setting the page layout you should use the layout that is the closest match to the page you are creating. Layouts are used by themes to determine what is  shown on the page. The most prominent difference between layouts is the block regions they support. The default layout `&#039;&#039;base&#039;&#039;` for example doesn&#039;t normally have any block regions at all, where as normally `&#039;&#039;standard&#039;&#039;` has the most generic layout and several block regions.&lt;br /&gt;
&lt;br /&gt;
There are dozens of different layouts that can be, and are used throughout Moodle core that you can use within your code. For a full list of common layouts you are best too look at theme/base/config.php or refer to the list below.&lt;br /&gt;
&lt;br /&gt;
Note: It&#039;s important to know that the theme determines what layouts are available and how each looks. If you select a layout that the theme doesn&#039;t support then it will revert to the default layout while using that theme.&amp;lt;br /&amp;gt;Themes are also able to specify additional layouts, however its important to spot them and know that while they may work with one theme they are unlikely to work as you expect with other themes.&lt;br /&gt;
&lt;br /&gt;
====Base theme page layouts====&lt;br /&gt;
The following is a list of the layouts defined by the base theme. Theme designers are encouraged to make the base theme a parent of their custom theme so you can be sure that in 99% of cases these layouts will be available.&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Layout&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| base&lt;br /&gt;
| Most backwards compatible layout without the blocks. This is the layout used by default.&lt;br /&gt;
|-&lt;br /&gt;
| standard&lt;br /&gt;
| Standard layout with blocks, this is recommended for most pages with general information&lt;br /&gt;
|-&lt;br /&gt;
| course&lt;br /&gt;
| The course main page uses this layout.&lt;br /&gt;
|-&lt;br /&gt;
| coursecategory&lt;br /&gt;
| Category course listings.&lt;br /&gt;
|-&lt;br /&gt;
| incourse&lt;br /&gt;
| Used for areas within a course, typical for modules. Default page layout if $cm specified in require_login().&lt;br /&gt;
|-&lt;br /&gt;
| frontpage&lt;br /&gt;
| The site home page uses this.&lt;br /&gt;
|-&lt;br /&gt;
| admin&lt;br /&gt;
| Admin and settings pages as well as server administration scripts.&lt;br /&gt;
|-&lt;br /&gt;
| mydashboard&lt;br /&gt;
| The users dashboard.&lt;br /&gt;
|-&lt;br /&gt;
| mypublic&lt;br /&gt;
| A users public profile uses this layout.&lt;br /&gt;
|-&lt;br /&gt;
| login&lt;br /&gt;
| The login screen.&lt;br /&gt;
|-&lt;br /&gt;
| popup&lt;br /&gt;
| Pages that appear in popup windows, usually no navigation, blocks, or header.&lt;br /&gt;
|-&lt;br /&gt;
| frametop&lt;br /&gt;
| Used for the outermost content of a page constructed with frames. Usually no blocks and minimal footer.&lt;br /&gt;
|-&lt;br /&gt;
| embedded&lt;br /&gt;
| Embedded pages such as content for iframes/objects. Needs as much space as possible usually no blocks, header, or footer.&lt;br /&gt;
|-&lt;br /&gt;
| maintenance&lt;br /&gt;
| Used during upgrade, installation, and when maintenance mode is enabled.&lt;br /&gt;
|-&lt;br /&gt;
| print&lt;br /&gt;
| Gets used when printing a page. Normally just a simple header and no blocks.&lt;br /&gt;
|-&lt;br /&gt;
| redirect&lt;br /&gt;
| A special layout used during a redirect. Normally with content only.&lt;br /&gt;
|-&lt;br /&gt;
| report&lt;br /&gt;
| Used for reports within Moodle. Special layout designed to handle horizontal scrolling in a nice way.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Title====&lt;br /&gt;
Setting an appropriate title is certainly a must for any properly designed page. While it is optional it is highly recommended that you set the title.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_title(&#039;This is my title&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
When setting the title for the page you need to provide just the string you want to use for the title. It should be a basic string and contain no HTML. Any HTML will be stripped out as the title is used within the &amp;lt;title&amp;gt; tag in the HTML head.&lt;br /&gt;
&lt;br /&gt;
====Heading====&lt;br /&gt;
Like title it is highly recommended that you set a meaningful heading for the page, although it is optional.&amp;lt;br /&amp;gt;The heading is normally displayed at the top of the page before the rest of the content starts. However it is up to the layout defined by the theme as to where it is displayed. Not all layouts will display a heading but I encourage you to always set one even if you are using a layout that doesn&#039;t support headings. This way if you are using a theme that uses a heading on every page regardless of layout things still look consistent.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_heading(get_string(&#039;pluginname&#039;, &#039;local_myplugin&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When setting a heading there is just one argument, the string to use for the heading. It should be a basic string and contain no HTML.&lt;br /&gt;
&lt;br /&gt;
=== Advanced set up ===&lt;br /&gt;
The following are advanced optional methods you can call to further set up your page. In most cases you will never need to use these.&lt;br /&gt;
&lt;br /&gt;
; set_activity_record : If you have called require_login with a course module, or you have manually set a course module on $PAGE then one other thing you may want to do is set the activity module record on $PAGE as well.&amp;lt;br /&amp;gt;This is best done when you have already fetched the activity record yourself in which case manually setting the activity record may reduce the number of queries for the page by 1.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_activity_record($activityrecord);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; set_blocks_editing_capability : Using this method you can set an additional capability that users must posses before being able to edit blocks on this page.&amp;lt;br /&amp;gt;By default &#039;moodle/site:manageblocks&#039; is used however there are sometimes reasons to use a different capability.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_blocks_editing_capability($strcapability);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; set_button : This allows you to set some HTML that will be shown in the navigation bar where the `Turn on editing` button normally lives.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_button($htmlstring);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; set_cacheable : By setting this to false the page will be sent with headers to prevent the client from caching the page. Defaults to true.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_cacheable(true/false);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; set_category_by_id : Allows you to set a category that this page is displaying. Calling this will force the $PAGE-&amp;gt;course to be set to the front page course.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_category_by_id($categoryid);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; set_cm : Like set page above, sometimes you need to manually set the course module for $PAGE. Again you must set the context to the context of the course module if you call this.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_cm($coursemodulerecord);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; set_course : This allows you to set the course the page belongs to. Normally when you call require_login the course you give it automatically gets sent to $PAGE for you.&amp;lt;br /&amp;gt;However if you don&#039;t want to require login for the course, but you need it in $PAGE then you can call set_course and provide it.&amp;lt;br /&amp;gt;Note that if you do this then you MUST use the context of the course when calling set_context().&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_course($courserecord);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; set_docs_path : Normally this gets automatically constructed for you, however in some circumstances you may want to manually set it.&amp;lt;br /&amp;gt;This allows you to have several pages that all point to the same docs page rather than requiring a docs page for each.&amp;lt;br /&amp;gt;The docs page link is normally shown by a theme in the footer.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_docs_path($strpath);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; set_focuscontrol : If you pass this method an element id when the page loads on the client focus will be shifted to the element with the corresponding id.&amp;lt;br /&amp;gt;Using this function is a REALLY bad idea in most situations because changing focus automatically in a browser is a nightmare for the vision impaired and those using screen readers.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_focuscontrol($controlid);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; set_headingmenu : This allows you to set some HTML that will be shown next to the pages main heading where the language select box normally lives.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_headingmenu($htmlstring);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; set_other_editing_capability : Can be used to set an additional capability that the user must posses before they can turn editing on for this page.&amp;lt;br /&amp;gt;This is useful if you can an editing more for your page that is more than just editing blocks.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_other_editing_capability($strcapability);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; set_pagetype : This gets automatically set up for by default to the path of your file e.g. mod/mymod/index.php will set up as mod-mymod-index.&amp;lt;br /&amp;gt;This is absolutely fine in 99% of cases however every now and again there is a reason to override it.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_pagetype($strpagetype);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; set_periodic_refresh_delay : If set a meta tag gets added to the page header causing it to refresh intermittently.&amp;lt;br /&amp;gt;This is rarely needed but can be useful if you need to automatically refresh the likes of a chat page, or news feed.&amp;lt;br /&amp;gt;Today it is not recommended to use this, but instead to create a means of getting additional content via AJAX.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_periodic_refresh_delay($intdelay);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; set_popup_notification_allowed : Allow or disallow popup notifications on this page. Things like messaging can cause messages to popup at the bottom of the screen sometimes.&amp;lt;br /&amp;gt;On some pages this functionality is not desired and can be stopped by calling this method and using false as the first argument.&amp;lt;br /&amp;gt;Popups are allowed by default.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_popup_notification_allowed(true/false);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; set_subpage : If context-&amp;gt;id and pagetype are not enough to uniquely identify this page and you need to include another string to make it more unique you can do it by calling this method setting a custom sub page type.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;set_subpage($strsubpage);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; add_body_class : Adds a CSS class to the body tag that will be printed by the Output API as part of the header.&amp;lt;br /&amp;gt;This is useful for adding classes to the body tag that describe the content of the page and may be required for styling the whole page, or for including indicator classes that may be useful to look for in JavaScript.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;add_body_class($strcssclass);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; add_body_classes : Adds an array of CSS classes to the body tag. Have a look at the above comment for &#039;&#039;&#039;add_body_class&#039;&#039;&#039; for more details.&lt;br /&gt;
&amp;lt;code php&amp;gt;$PAGE-&amp;gt;add_body_classes($arrayofclasses);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Getting information about the page==&lt;br /&gt;
As well of setting up the page you can of course get information back from it about the page it has been set up to display.&amp;lt;br /&amp;gt;&lt;br /&gt;
Anything you set against the page can be retrieved as can any information that was set magically for you by other methods.&lt;br /&gt;
&lt;br /&gt;
The following are the most interesting and likely useful things you can get back from the page.&lt;br /&gt;
&lt;br /&gt;
; activityrecord : The activityrecord will be the record from the database that relates to the cm that was set by require_login, or manually by your code.&amp;lt;br /&amp;gt;For example if you provided a $cm instance that related to a forum this will be a row from the forum table.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;activityrecord;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; blockmanager : This is the block manager responsible for loading the all of the blocks that will be shown on the page.&amp;lt;br /&amp;gt;For more information see the [[Blocks API]].&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;blockmanager;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; bodyid : The id that will be given to the body tag when the page is displayed.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;bodyid;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; categories : An array of all the categories the page course belongs to, starting with the immediately containing category.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;categories;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; category : The category that the page course belongs to.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;category;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; cm : The course module that has been set for the page.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;cm;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; course : The course that has been set for the page.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;course;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; devicetypeinuse : The device the user is using browse the page.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;devicetypeinuse;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; headerprinted : Is true if the page header has already been printed. &lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;headerprinted;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; heading : The page heading.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;heading;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; navbar : Gets a reference to the pages navigation bar so that you can interact with that. See the [[Navigation API]] for more information.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;navbar;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; navigation : Gets a reference to the navigation for the page. See the [[Navigation API]] for more information.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;navigation;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; requires : Gets the page requirements manager that handles any JavaScript and special CSS requirements for the page.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;requires;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; settingsnav : Gets the settings navigation for the page. See the [[Navigation API]] for more information.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;settingsnav;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; theme : Gets the theme that is being used for the page. Is a theme_config object.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;theme;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; title : Gets the title for the page.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;title;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; url : Gets the URL that was set for the page. Is a moodle_url object.&lt;br /&gt;
&amp;lt;code php&amp;gt;$var = $PAGE-&amp;gt;url;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==FAQs==&lt;br /&gt;
&lt;br /&gt;
; I don&#039;t have any blocks on my page? : This has happened because you have not set a page layout that uses blocks OR you have set it after output has started. Once output has started you cannot change integral aspects of that page that are used for the initial output. Included is the page title, heading, url and layout.&lt;br /&gt;
&lt;br /&gt;
; I am getting a notice about not having set the page URL but I have set it? : As above you must set up the page before output starts, trying to do so will lead to notices and developer warnings about having things in the wrong order.&lt;br /&gt;
&lt;br /&gt;
; What starts output? : Output starts when either the script calls echo $OUTPUT-&amp;gt;header OR a moodleform is instantiated.&lt;br /&gt;
&lt;br /&gt;
==Related API&#039;s==&lt;br /&gt;
There are a couple of API&#039;s that are closely related to the Page API that you should be aware of as well.&lt;br /&gt;
&lt;br /&gt;
===Output API===&lt;br /&gt;
The output API is an immediate relation of the page API. The page API is about setting things up, whereas the output API is all about displaying things.&lt;br /&gt;
It&#039;s through the output API that content is actually produced, and much of the information you set up through the page is used to customise what is produced, and fill in the general blanks of any page (such as title and heading.&lt;br /&gt;
&lt;br /&gt;
See the [[Output API]] documentation for more information.&lt;br /&gt;
&lt;br /&gt;
===Page requirements API===&lt;br /&gt;
The page requirements API allows you the developer to include additional CSS, and JavaScript resources that should be included with the page, and to include JavaScript calls within the page through a variety of means.&lt;br /&gt;
Technically this API is part of the Output API mentioned above, however it deserves special mention. If you are going to be using any JavaScript or CSS within your page you will need to know about this.&lt;br /&gt;
&lt;br /&gt;
See the [[Output API]] documentation for more information on the page requirements API.&lt;br /&gt;
&lt;br /&gt;
===Navigation API===&lt;br /&gt;
The final API to mention is the navigation API. This again is integral to both the page and output API and is used to recognise the context of the content being displayed and ensure that the correct blocks and navigaiton structure are loaded for the context.&lt;br /&gt;
There is a good chance that you will encounter a need to customise the navigation early on in plugin page development and it&#039;s important to be aware of this important API.&lt;br /&gt;
&lt;br /&gt;
See the [[Navigation API]] documentation for more information on the page requirements API.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Core APIs]] : A list of all the core API&#039;s in Moodle.&lt;br /&gt;
* [[Output API]] : The Output API.&lt;br /&gt;
* [[Navigation API]] : The Navigation API.&lt;br /&gt;
* [http://moodle.org/mod/forum/view.php?id=55 General developer forum] : The place to ask question you may have about the Page API.&lt;br /&gt;
* MDL-30977 : The issue to see the Page API properly documented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:API]]&lt;/div&gt;</summary>
		<author><name>Vaibspidy</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Access_API&amp;diff=49986</id>
		<title>Access API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Access_API&amp;diff=49986"/>
		<updated>2016-05-09T19:29:35Z</updated>

		<summary type="html">&lt;p&gt;Vaibspidy: /* Enrollment functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.2}}The Access API gives you functions so you can determine what the current user is allowed to do. It also allows modules to extend Moodle with new capabilities. &lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Moodle is using a role based access control model. Most entities in Moodle (system, users, course categories, courses, modules and blocks) are represented by contexts that are arranged in a tree like hierarchy called context tree. Role is a set of capability definitions, each capability usually represents an ability of user to do something. Roles are defined at the top most system context level. Role definitions can be overridden at lower context levels. User access control is calculated from the definitions of roles assigned to users.&lt;br /&gt;
&lt;br /&gt;
All users that did not log-in yet automatically get the default role defined in $CFG-&amp;gt;notloggedinroleid, it is not possible to assign any other role to this non-existent user id. There is one special guest user account that is used when user logs in using the guest login button or when guest autologin is enabled. Again you can not assign any roles to the guest account directly, this account gets the $CFG-&amp;gt;guestroleid automatically. All other authenticated users get the default user role specified in $CFG-&amp;gt;defaultuserroleid and in the frontpage context the role specified in $CFG-&amp;gt;defaultfrontpageroleid.&lt;br /&gt;
&lt;br /&gt;
==How to define new capabilities in plugins==&lt;br /&gt;
&lt;br /&gt;
Capabilities are defined by $capabilities array defined in db/access.php files. The name of the capability consists of &amp;quot;plugintype/pluginname:capabilityname&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $capabilities = array(&lt;br /&gt;
    &#039;mod/folder:managefiles&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;riskbitmask&#039; =&amp;gt; RISK_SPAM,&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;editingteacher&#039; =&amp;gt; CAP_ALLOW&lt;br /&gt;
        )&lt;br /&gt;
    ),&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where the meaning of array keys is:&lt;br /&gt;
* riskbitmask - associated risks. These are explained on [[Hardening new Roles system]].&lt;br /&gt;
* captype - &#039;&#039;read&#039;&#039; or &#039;&#039;write&#039;&#039; capability type, for security reasons system prevents all write capabilities for guest account and not-logged-in users&lt;br /&gt;
* contextlevel - specified as context level constant. Declares the typical context level where this capability is checked. It is the lowest level where this capability can be tweaked (overridden) via the permissions UI.&lt;br /&gt;
* archetypes - specifies defaults for roles with standard archetypes, this is used in installs, upgrades and when resetting roles (it is recommended to use only CAP_ALLOW here).  Archetypes are defined in mdl_role table.  See also [[Role archetypes]].&lt;br /&gt;
* clonepermissionsfrom - when you are adding a new capability, you can tell Moodle to copy the permissions for each role from the current settings for another capabilty. This may give better defaults than just using archetypes for administrators who have heavily customised their roles configuration. The full syntax is: &amp;lt;tt&amp;gt;&#039;clonepermissionsfrom&#039; =&amp;gt; &#039;moodle/quiz:attempt&#039;,&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &#039;&#039;In releases before May 2012 clonepermissionsfrom works only inside individual plugins or only in core, in later releases plugins may also clone permissions from core, success of other cloning operations depends on upgrade order.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It is necessary to bump up plugin version number after any change in db/access.php, so that the upgrade scripts can make the necessary changes to the database.  To run the upgrade scripts, log in to Moodle as administrator, navigate to the site home page, and follow the instructions.  (If you need to test the upgrade script without changing the plugin version, it is also possible to set back the version number in the mdl_block or mdl_modules table in the database.)&lt;br /&gt;
&lt;br /&gt;
The capability names are defined in plugin language files, the name of the string consists of &amp;quot;pluginname:capabilityname&amp;quot;, in the example above it would be:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;folder:managefiles&#039;] = &#039;Manage files in folder module&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Useful functions and classes==&lt;br /&gt;
&lt;br /&gt;
===Context fetching===&lt;br /&gt;
&lt;br /&gt;
In plugins context instances are usually only instantiated because they are instantiated and deleted automatically by the system.&lt;br /&gt;
&lt;br /&gt;
Fetching by object id:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$systemcontext = context_system::instance();&lt;br /&gt;
$usercontext = context_user::instance($user-&amp;gt;id);&lt;br /&gt;
$categorycontext = context_coursecat::instance($category-&amp;gt;id);&lt;br /&gt;
$coursecontext = context_course::instance($course-&amp;gt;id);&lt;br /&gt;
$contextmodule = context_module::instance($cm-&amp;gt;id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetching by context id:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$context = context::instance_by_id($contextid);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
* by default exception is thrown if context can not be created&lt;br /&gt;
* deleted users do not have contexts any more&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are multiple deprecated context related functions since 2.2, it is not necessary to replace them immediately. The following two functions are equivalent to the context fetching examples above:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_context_instance($contextlevel, $instance = 0, $strictness = IGNORE_MISSING)&lt;br /&gt;
function get_context_instance_by_id($id, $strictness = IGNORE_MISSING)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Determining that a user has a given capability===&lt;br /&gt;
&lt;br /&gt;
When implementing access control always ask &amp;quot;Does the user have capability to do something?&amp;quot;. It is incorrect to ask &amp;quot;Does the user have a role somewhere?&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
====has_capability()====&lt;br /&gt;
has_capability() is the most important function:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 function has_capability($capability, context $context, $user = null, $doanything = true)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check whether a user has a particular capability in a given context. For example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$context = context_module::instance($cm-&amp;gt;id);&lt;br /&gt;
has_capability(&#039;mod/folder:managefiles&#039;, $context)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default checks the capabilities of the current user, but you can pass a different userid. By default will return true for admin users, it is not recommended to use false here.&lt;br /&gt;
&lt;br /&gt;
====require_capability()====&lt;br /&gt;
Function require_capability() is very similar, it is throwing access control exception if user does not have the capability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function require_capability($capability, context $context, $userid = null, $doanything = true, $errormessage = &#039;nopermissions&#039;, $stringfile = &#039;&#039;) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Enrollment functions===&lt;br /&gt;
&lt;br /&gt;
See [[Enrolment API]].&lt;br /&gt;
&lt;br /&gt;
===Other related functions===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false)&lt;br /&gt;
 function require_course_login($courseorid, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false)&lt;br /&gt;
 function get_users_by_capability(context $context, $capability, $fields = &#039;&#039;, $sort = &#039;&#039;, $limitfrom = &#039;&#039;, $limitnum = &#039;&#039;,&lt;br /&gt;
                                  $groups = &#039;&#039;, $exceptions = &#039;&#039;, $doanything_ignored = null, $view_ignored = null, $useviewallgroups = false)&lt;br /&gt;
 function isguestuser($user = null)&lt;br /&gt;
 function isloggedin()&lt;br /&gt;
 function is_siteadmin($user_or_id = null)&lt;br /&gt;
 function is_guest(context $context, $user = null)&lt;br /&gt;
 function is_viewing(context $context, $user = null, $withcapability = &#039;&#039;)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====require_login()====&lt;br /&gt;
&lt;br /&gt;
Each plugin script should include require_login() or require_course_login() after setting up PAGE-&amp;gt;url.&lt;br /&gt;
&lt;br /&gt;
This function does following:&lt;br /&gt;
* it verifies that user is logged in before accessing any course or activities (not-logged-in users can not enter any courses).&lt;br /&gt;
* user is logged in as gu&lt;br /&gt;
* verify access to hidden courses and activities&lt;br /&gt;
* verify experimental groupmembersonly access&lt;br /&gt;
* verify that user is either enrolled or has capability &#039;moodle/course:view&#039; or some enrol plugin gives them temporary guest access&lt;br /&gt;
* logs access to courses&lt;br /&gt;
&lt;br /&gt;
====require_course_login()====&lt;br /&gt;
&lt;br /&gt;
This function is supposed to be used only in activities that want to allow read access to content on the frontpage without logging-in. For example view resource files, reading of glossary  entries, etc.&lt;br /&gt;
&lt;br /&gt;
====isguestuser(), isloggedin() and is_siteadmin()====&lt;br /&gt;
&lt;br /&gt;
These functions were previously needed for limiting of access of special accounts. It is usually not necessary anymore, because any &#039;&#039;&#039;write&#039;&#039;&#039; or &#039;&#039;&#039;risky&#039;&#039;&#039; capabilities are now automatically prevented in has_capability().&lt;br /&gt;
&lt;br /&gt;
It is strongly discouraged to use is_siteadmin() in activity modules, please use standard capabilities and enrollment status instead.&lt;br /&gt;
&lt;br /&gt;
====is_guest(), is_viewing() and is_enrolled()====&lt;br /&gt;
&lt;br /&gt;
In order to access course data one of these functions must return true for user:&lt;br /&gt;
* is_enrolled() - user has active record in user_enrollments table&lt;br /&gt;
* is_viewing() - user has &#039;moodle/course:view&#039; capability (may access course, but is not considered to be participant)&lt;br /&gt;
* is_guest() - user was given temporary guest access by some enrollment plugin&lt;br /&gt;
&lt;br /&gt;
====get_users_by_capability()====&lt;br /&gt;
&lt;br /&gt;
This method returns list of users with given capability, it ignores enrollment status and should be used only above the course context.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Core APIs]]&lt;br /&gt;
* [[Roles]]&lt;br /&gt;
* [[Role archetypes]]&lt;br /&gt;
* [[Hardening new Roles system]]&lt;br /&gt;
* [[Roles and modules]]&lt;br /&gt;
* [[NEWMODULE Adding capabilities]]&lt;br /&gt;
* [[New permissions evaluation in 2.0]]&lt;br /&gt;
&lt;br /&gt;
[[Category:API]]&lt;/div&gt;</summary>
		<author><name>Vaibspidy</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Access_API&amp;diff=49985</id>
		<title>Access API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Access_API&amp;diff=49985"/>
		<updated>2016-05-09T19:05:19Z</updated>

		<summary type="html">&lt;p&gt;Vaibspidy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.2}}The Access API gives you functions so you can determine what the current user is allowed to do. It also allows modules to extend Moodle with new capabilities. &lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Moodle is using a role based access control model. Most entities in Moodle (system, users, course categories, courses, modules and blocks) are represented by contexts that are arranged in a tree like hierarchy called context tree. Role is a set of capability definitions, each capability usually represents an ability of user to do something. Roles are defined at the top most system context level. Role definitions can be overridden at lower context levels. User access control is calculated from the definitions of roles assigned to users.&lt;br /&gt;
&lt;br /&gt;
All users that did not log-in yet automatically get the default role defined in $CFG-&amp;gt;notloggedinroleid, it is not possible to assign any other role to this non-existent user id. There is one special guest user account that is used when user logs in using the guest login button or when guest autologin is enabled. Again you can not assign any roles to the guest account directly, this account gets the $CFG-&amp;gt;guestroleid automatically. All other authenticated users get the default user role specified in $CFG-&amp;gt;defaultuserroleid and in the frontpage context the role specified in $CFG-&amp;gt;defaultfrontpageroleid.&lt;br /&gt;
&lt;br /&gt;
==How to define new capabilities in plugins==&lt;br /&gt;
&lt;br /&gt;
Capabilities are defined by $capabilities array defined in db/access.php files. The name of the capability consists of &amp;quot;plugintype/pluginname:capabilityname&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $capabilities = array(&lt;br /&gt;
    &#039;mod/folder:managefiles&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;riskbitmask&#039; =&amp;gt; RISK_SPAM,&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;editingteacher&#039; =&amp;gt; CAP_ALLOW&lt;br /&gt;
        )&lt;br /&gt;
    ),&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where the meaning of array keys is:&lt;br /&gt;
* riskbitmask - associated risks. These are explained on [[Hardening new Roles system]].&lt;br /&gt;
* captype - &#039;&#039;read&#039;&#039; or &#039;&#039;write&#039;&#039; capability type, for security reasons system prevents all write capabilities for guest account and not-logged-in users&lt;br /&gt;
* contextlevel - specified as context level constant. Declares the typical context level where this capability is checked. It is the lowest level where this capability can be tweaked (overridden) via the permissions UI.&lt;br /&gt;
* archetypes - specifies defaults for roles with standard archetypes, this is used in installs, upgrades and when resetting roles (it is recommended to use only CAP_ALLOW here).  Archetypes are defined in mdl_role table.  See also [[Role archetypes]].&lt;br /&gt;
* clonepermissionsfrom - when you are adding a new capability, you can tell Moodle to copy the permissions for each role from the current settings for another capabilty. This may give better defaults than just using archetypes for administrators who have heavily customised their roles configuration. The full syntax is: &amp;lt;tt&amp;gt;&#039;clonepermissionsfrom&#039; =&amp;gt; &#039;moodle/quiz:attempt&#039;,&amp;lt;/tt&amp;gt;&lt;br /&gt;
* &#039;&#039;In releases before May 2012 clonepermissionsfrom works only inside individual plugins or only in core, in later releases plugins may also clone permissions from core, success of other cloning operations depends on upgrade order.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It is necessary to bump up plugin version number after any change in db/access.php, so that the upgrade scripts can make the necessary changes to the database.  To run the upgrade scripts, log in to Moodle as administrator, navigate to the site home page, and follow the instructions.  (If you need to test the upgrade script without changing the plugin version, it is also possible to set back the version number in the mdl_block or mdl_modules table in the database.)&lt;br /&gt;
&lt;br /&gt;
The capability names are defined in plugin language files, the name of the string consists of &amp;quot;pluginname:capabilityname&amp;quot;, in the example above it would be:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;folder:managefiles&#039;] = &#039;Manage files in folder module&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Useful functions and classes==&lt;br /&gt;
&lt;br /&gt;
===Context fetching===&lt;br /&gt;
&lt;br /&gt;
In plugins context instances are usually only instantiated because they are instantiated and deleted automatically by the system.&lt;br /&gt;
&lt;br /&gt;
Fetching by object id:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$systemcontext = context_system::instance();&lt;br /&gt;
$usercontext = context_user::instance($user-&amp;gt;id);&lt;br /&gt;
$categorycontext = context_coursecat::instance($category-&amp;gt;id);&lt;br /&gt;
$coursecontext = context_course::instance($course-&amp;gt;id);&lt;br /&gt;
$contextmodule = context_module::instance($cm-&amp;gt;id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fetching by context id:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$context = context::instance_by_id($contextid);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
* by default exception is thrown if context can not be created&lt;br /&gt;
* deleted users do not have contexts any more&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are multiple deprecated context related functions since 2.2, it is not necessary to replace them immediately. The following two functions are equivalent to the context fetching examples above:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_context_instance($contextlevel, $instance = 0, $strictness = IGNORE_MISSING)&lt;br /&gt;
function get_context_instance_by_id($id, $strictness = IGNORE_MISSING)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Determining that a user has a given capability===&lt;br /&gt;
&lt;br /&gt;
When implementing access control always ask &amp;quot;Does the user have capability to do something?&amp;quot;. It is incorrect to ask &amp;quot;Does the user have a role somewhere?&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
====has_capability()====&lt;br /&gt;
has_capability() is the most important function:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 function has_capability($capability, context $context, $user = null, $doanything = true)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check whether a user has a particular capability in a given context. For example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$context = context_module::instance($cm-&amp;gt;id);&lt;br /&gt;
has_capability(&#039;mod/folder:managefiles&#039;, $context)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default checks the capabilities of the current user, but you can pass a different userid. By default will return true for admin users, it is not recommended to use false here.&lt;br /&gt;
&lt;br /&gt;
====require_capability()====&lt;br /&gt;
Function require_capability() is very similar, it is throwing access control exception if user does not have the capability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function require_capability($capability, context $context, $userid = null, $doanything = true, $errormessage = &#039;nopermissions&#039;, $stringfile = &#039;&#039;) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Enrollment functions===&lt;br /&gt;
&lt;br /&gt;
See [[Enrollment API]].&lt;br /&gt;
&lt;br /&gt;
===Other related functions===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false)&lt;br /&gt;
 function require_course_login($courseorid, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false)&lt;br /&gt;
 function get_users_by_capability(context $context, $capability, $fields = &#039;&#039;, $sort = &#039;&#039;, $limitfrom = &#039;&#039;, $limitnum = &#039;&#039;,&lt;br /&gt;
                                  $groups = &#039;&#039;, $exceptions = &#039;&#039;, $doanything_ignored = null, $view_ignored = null, $useviewallgroups = false)&lt;br /&gt;
 function isguestuser($user = null)&lt;br /&gt;
 function isloggedin()&lt;br /&gt;
 function is_siteadmin($user_or_id = null)&lt;br /&gt;
 function is_guest(context $context, $user = null)&lt;br /&gt;
 function is_viewing(context $context, $user = null, $withcapability = &#039;&#039;)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====require_login()====&lt;br /&gt;
&lt;br /&gt;
Each plugin script should include require_login() or require_course_login() after setting up PAGE-&amp;gt;url.&lt;br /&gt;
&lt;br /&gt;
This function does following:&lt;br /&gt;
* it verifies that user is logged in before accessing any course or activities (not-logged-in users can not enter any courses).&lt;br /&gt;
* user is logged in as gu&lt;br /&gt;
* verify access to hidden courses and activities&lt;br /&gt;
* verify experimental groupmembersonly access&lt;br /&gt;
* verify that user is either enrolled or has capability &#039;moodle/course:view&#039; or some enrol plugin gives them temporary guest access&lt;br /&gt;
* logs access to courses&lt;br /&gt;
&lt;br /&gt;
====require_course_login()====&lt;br /&gt;
&lt;br /&gt;
This function is supposed to be used only in activities that want to allow read access to content on the frontpage without logging-in. For example view resource files, reading of glossary  entries, etc.&lt;br /&gt;
&lt;br /&gt;
====isguestuser(), isloggedin() and is_siteadmin()====&lt;br /&gt;
&lt;br /&gt;
These functions were previously needed for limiting of access of special accounts. It is usually not necessary anymore, because any &#039;&#039;&#039;write&#039;&#039;&#039; or &#039;&#039;&#039;risky&#039;&#039;&#039; capabilities are now automatically prevented in has_capability().&lt;br /&gt;
&lt;br /&gt;
It is strongly discouraged to use is_siteadmin() in activity modules, please use standard capabilities and enrollment status instead.&lt;br /&gt;
&lt;br /&gt;
====is_guest(), is_viewing() and is_enrolled()====&lt;br /&gt;
&lt;br /&gt;
In order to access course data one of these functions must return true for user:&lt;br /&gt;
* is_enrolled() - user has active record in user_enrollments table&lt;br /&gt;
* is_viewing() - user has &#039;moodle/course:view&#039; capability (may access course, but is not considered to be participant)&lt;br /&gt;
* is_guest() - user was given temporary guest access by some enrollment plugin&lt;br /&gt;
&lt;br /&gt;
====get_users_by_capability()====&lt;br /&gt;
&lt;br /&gt;
This method returns list of users with given capability, it ignores enrollment status and should be used only above the course context.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Core APIs]]&lt;br /&gt;
* [[Roles]]&lt;br /&gt;
* [[Role archetypes]]&lt;br /&gt;
* [[Hardening new Roles system]]&lt;br /&gt;
* [[Roles and modules]]&lt;br /&gt;
* [[NEWMODULE Adding capabilities]]&lt;br /&gt;
* [[New permissions evaluation in 2.0]]&lt;br /&gt;
&lt;br /&gt;
[[Category:API]]&lt;/div&gt;</summary>
		<author><name>Vaibspidy</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Git_for_developers&amp;diff=49791</id>
		<title>Git for developers</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Git_for_developers&amp;diff=49791"/>
		<updated>2016-04-11T08:53:30Z</updated>

		<summary type="html">&lt;p&gt;Vaibspidy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is for helping you get started on Moodle development with Git. For further details of Git, see [[:Category:Git]].&lt;br /&gt;
&lt;br /&gt;
== General workflow ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;A reasonable knowledge of the Git basics is a good idea before you start to use it for development. If you are new to Git, you are encouraged to go to &#039;See also&#039; for some more general reading.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[image:git-pushpull-model.png|right|thumb|400px|Moodle development workflow with Git]]&lt;br /&gt;
Detailed explanation of the workflow can be found in the [[Process]] page. In short, the Moodle development with Git looks like this:&lt;br /&gt;
&lt;br /&gt;
* You as the contributor commit changes into your personal repository at your computer&lt;br /&gt;
* You push the changes into your public repository and publish links to your changes in the Moodle Tracker&lt;br /&gt;
* You request a peer review of your code from another developer&lt;br /&gt;
* When peer reviewer is happy they submit issue for integration&lt;br /&gt;
* Moodle integrators pull the changes from your public repository and if they like them, they put them into Moodle integration repository&lt;br /&gt;
* The integrated change is tested and finally pushed into Moodle production repository&lt;br /&gt;
* You update your local repository with all changes from the production repository and the next cycle may start again&lt;br /&gt;
&lt;br /&gt;
This workflow runs in roughly weekly cycles. The integration happens on Monday and Tuesday and the testing on Wednesday. On Thursday (or Friday if testing takes too long), the production repository moodle.git is usually updated with changes from the last development week.&lt;br /&gt;
&lt;br /&gt;
Most Moodle developers have their public repositories hosted at [http://github.com/ Github]. Alternatively you may want to try [http://gitorious.org Gitorious] or the legendary [http://repo.or.cz repo.or.cz]. In the examples in this guide we assume you&#039;ll set up your public repository at Github.&lt;br /&gt;
&lt;br /&gt;
When you first register on tracker you can not assign issues to yourself or send them for peer review. You will be added to the developers group after your first bug fix is integrated. Before that just comment on the issue with a link to your branch and component lead or another developer will send issue for peer review for you.&lt;br /&gt;
&lt;br /&gt;
== Installing Git on your computer ==&lt;br /&gt;
&lt;br /&gt;
Install Git on your computer. Most Linux distributions have Git available as a package to install. On Debian/Ubuntu, type &#039;&#039;&#039;&#039;sudo apt-get install git&#039;&#039;&#039;&#039; on the terminal. If you are on Mac, [http://code.google.com/p/git-osx-installer/ git-osx-installer] installs it in a few clicks. &lt;br /&gt;
&lt;br /&gt;
Immediately after the installation, set your name and contact e-mail. The name and e-mail will become part of your commits and they can&#039;t be changed later once your commits are accepted into the Moodle code. Therefore we ask contributors to use their real names written in capital letters, eg &amp;quot;John Smith&amp;quot; and not &amp;quot;john smith&amp;quot; or even &amp;quot;john5677&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
    git config --global user.name &amp;quot;Your Name&amp;quot;&lt;br /&gt;
    git config --global user.email yourmail@domain.tld&lt;br /&gt;
&lt;br /&gt;
Unless you are the repository maintainer, it is wise to set your Git to not push changes in file permissions:&lt;br /&gt;
&lt;br /&gt;
    git config --global core.filemode false&lt;br /&gt;
&lt;br /&gt;
Also, it&#039;s recommended to verify that the your git installation is not performing any transformation between LFs and CRLFs. All Moodle &#039;&#039;&#039;uses only LFs&#039;&#039;&#039; and you should &#039;&#039;&#039;fetch/edit and push&#039;&#039;&#039; it that way (may need to configure your editor/IDE too). Note that having any &amp;quot;magic&amp;quot; enabled is known to cause [[Common unit test problems#The_test_file_.22evolution.test.22_should_not_contain_section_named_.22.5Blots_of_content.5D.22|problems with unit tests]] execution. So we recommend you to set:&lt;br /&gt;
&lt;br /&gt;
    git config --global core.autocrlf false&lt;br /&gt;
&lt;br /&gt;
== Setting-up the public repository ==&lt;br /&gt;
&lt;br /&gt;
1. Go to [http://github.com/ Github] and create an account.&lt;br /&gt;
&lt;br /&gt;
2. Go to the [http://github.com/moodle/moodle official Moodle Github repository] and click on the Fork button. You now have your own Github Moodle repository.&lt;br /&gt;
&lt;br /&gt;
3. Now you need to set up your SSH public key, so you can push to your Github Moodle repository from your local Moodle repository. On Mac you can go on this [http://help.github.com/mac-key-setup/ Github help page]. If you are on another system, go to your Github administration page, to the section SSH Public Keys, and you should see a link to a help page. Done? Good! That was the most difficult part!&lt;br /&gt;
&lt;br /&gt;
== Setting-up the local repository at your computer  ==&lt;br /&gt;
&lt;br /&gt;
Create a local clone repository of your Github repository. In a terminal:&lt;br /&gt;
&lt;br /&gt;
    git clone git://github.com/YOUR_GITHUB_USERNAME/moodle.git LOCALDIR&lt;br /&gt;
&lt;br /&gt;
    (or:  git clone git@github.com:YOUR_GITHUB_USERNAME/moodle.git LOCALDIR)&lt;br /&gt;
&lt;br /&gt;
This command does several jobs for you. It creates a new folder, initializes an empty Git repository in it, sets your Github repository as the remote repository called &#039;origin&#039; and makes a local checkout of the branch &#039;master&#039; from it. The important point to remember now is that your Github repository is aliased as &#039;origin&#039; for your local clone.&lt;br /&gt;
&lt;br /&gt;
Note that the format of the URL here is important. In the first example, the URL starts &amp;quot;git://github.com&amp;quot; and this will give read-only access to the repository at github.com. If you use this URL, the &amp;quot;git push origin&amp;quot; command that appears later in this document will not work. Therefore, if you want to be able to update the &amp;quot;origin&amp;quot; repository, you should use the URL that starts &amp;quot;git@github.com&amp;quot;, i.e. the second of the two &amp;quot;git clone&amp;quot; commands given above. This will give you read and write access to the repository on github.com.&lt;br /&gt;
&lt;br /&gt;
== Keeping your public repository up-to-date ==&lt;br /&gt;
&lt;br /&gt;
[[image:git-sync-github.png|right|thumb|400px|Fetching changes from upstream and pushing them to github]]&lt;br /&gt;
Your fork at Github is not updated automatically. To keep it synced with the upstream Moodle repository, you have to fetch the recent changes from the official moodle.git and push them to your public repository. To avoid problems with this it is strongly recommended that you never modify the standard Moodle branches. &#039;&#039;Remember: never commit directly into master and MOODLE_xx_STABLE branches.&#039;&#039; In other words, always create topic branches to work on. In Gitspeak, the master branch and MOODLE_xx_STABLE branches should be always fast-forwardable.&lt;br /&gt;
&lt;br /&gt;
To keep your public repository up-to-date, we will register remote repository git://git.moodle.org/moodle.git under &#039;upstream&#039; alias. Then we create a script to be run regularly that fetches changes from the upstream repository and pushes them to your public repository. Note that this procedure will not affect your local working directory.&lt;br /&gt;
&lt;br /&gt;
To register the upstream remote:&lt;br /&gt;
&lt;br /&gt;
    cd moodle&lt;br /&gt;
    git remote add upstream git://git.moodle.org/moodle.git&lt;br /&gt;
&lt;br /&gt;
The following commands can be used to keep the standard Moodle branches at your Github repository synced with the upstream repository. You may wish to store them in a script so that you can run it every week after the upstream repository is updated.&lt;br /&gt;
&lt;br /&gt;
    #!/bin/sh&lt;br /&gt;
    git fetch upstream&lt;br /&gt;
    for BRANCH in MOODLE_{19..27}_STABLE master; do&lt;br /&gt;
        git push origin refs/remotes/upstream/$BRANCH:$BRANCH&lt;br /&gt;
    done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How it works ===&lt;br /&gt;
&lt;br /&gt;
The git-fetch command does not modify your current working dir (your checkout). It just downloads all recent changes from a remote repository and stores them into so called remote-tracking branches. The git-push command takes these remote-tracking branches from upstream and pushes them to Github under the same name. Understanding this fully requires a bit knowledge of Git internals - see gitrevisions(7) man page.&lt;br /&gt;
&lt;br /&gt;
Note there is no need to switch the local branch during this. You can even execute this via cron at your machine. Just note that the upstream repository updates typically just once a week.&lt;br /&gt;
&lt;br /&gt;
=== New branches ===&lt;br /&gt;
&lt;br /&gt;
Occasionally, moodle.org will create a new branch that does not exist in your public (e.g. Github.com) repository. If you try to push this new branch, you will see an error such as the following:&lt;br /&gt;
&lt;br /&gt;
    error: unable to push to unqualified destination: MOODLE_99_STABLE&lt;br /&gt;
    The destination refspec neither matches an existing ref on the remote&lt;br /&gt;
    nor begins with refs/, and we are unable to guess a prefix based on the source ref.&lt;br /&gt;
    error: failed to push some refs to &#039;git@github.com:YOUR_GITHUB_USERNAME/moodle.git&#039;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;quot;MOODLE_99_STABLE&amp;quot;, is the name of the new branch that does not exist in your public repository. To fix the error, you need to create the new branch on your public repository, using the following commands, replacing &amp;quot;MOODLE_99_STABLE&amp;quot; with the name of the new branch you wish to create:&lt;br /&gt;
&lt;br /&gt;
    git checkout MOODLE_99_STABLE&lt;br /&gt;
    git push origin MOODLE_99_STABLE:MOODLE_99_STABLE&lt;br /&gt;
&lt;br /&gt;
The above code will create a new copy of the &amp;quot;MOODLE_99_STABLE&amp;quot; branch in your local repository. If you do not need to keep a local copy of the new branch - and probably you do not need it, you then can remove it from your local repository as follows:&lt;br /&gt;
&lt;br /&gt;
    git checkout master&lt;br /&gt;
    git branch -D MOODLE_99_STABLE&lt;br /&gt;
&lt;br /&gt;
== Preparing a patch ==&lt;br /&gt;
&lt;br /&gt;
As said earlier at this page, you never work on standard Moodle branches directly. Every time you are going to edit something, switch to a local branch. Fork the local branch off the standard branch you think it should be merged to. So if you are working on a patch for 1.9 or 2.0, fork the branch off MOODLE_19_STABLE or MOODLE_20_STABLE, respectively. Patches for the next [[Moodle versions|major version]] should be based on the master branch.&lt;br /&gt;
&lt;br /&gt;
    git checkout -b MDL-xxxxx-nasty-bug origin/master&lt;br /&gt;
&lt;br /&gt;
Note that if you forget to specify the starting point, the branch is based on the currently checked-out branch. It may not be what you want. It is recommended to always specify the starting point.&lt;br /&gt;
&lt;br /&gt;
To check the current branch, run&lt;br /&gt;
&lt;br /&gt;
    git branch&lt;br /&gt;
&lt;br /&gt;
The current branch is highlighted.&lt;br /&gt;
&lt;br /&gt;
Now go and fix the issue with your favorite IDE. Check the status of the files, view the change to be committed and finally commit the change:&lt;br /&gt;
&lt;br /&gt;
    vim filename.php&lt;br /&gt;
    git status&lt;br /&gt;
    git diff&lt;br /&gt;
    git commit -a&lt;br /&gt;
&lt;br /&gt;
Note that this is safe as the commit is recorded just locally, nothing is sent to any server yet (as it would in CVS). To see history of the commits, use&lt;br /&gt;
&lt;br /&gt;
    git log&lt;br /&gt;
&lt;br /&gt;
Once your local branch contains the change (note that it may consists of several patches) and you are happy with it, publish the branch at your public repository:&lt;br /&gt;
&lt;br /&gt;
    git push MDL-xxxxx-nasty-bug&lt;br /&gt;
&lt;br /&gt;
Because we did not specify explicit remote repository, the &#039;origin&#039; is used. Because we did not specify the branch to push, the Git will use the current branch and push it to the remote repository under the same name (by default, this is a subject of your configuration. See push.default config variable).&lt;br /&gt;
&lt;br /&gt;
Now as your branch is published, you can ask Moodle core developers to review it and eventually integrate it into the standard Moodle repository.&lt;br /&gt;
&lt;br /&gt;
=== Changing commit message, reordering and squashing commits ===&lt;br /&gt;
&lt;br /&gt;
It often happens that you made a mistake in your patch or in the commit message and helpful CiBot pointed it out for you. You can &amp;quot;rewrite the history&amp;quot; and change the existing commits.&lt;br /&gt;
&lt;br /&gt;
Option 1. Reset all the changes in the branch and commit again. &lt;br /&gt;
&lt;br /&gt;
    git reset --mixed origin/master&lt;br /&gt;
&lt;br /&gt;
Now all your changes are still present but all commits on top of &amp;quot;master&amp;quot; branch are gone. You can create a new commit&lt;br /&gt;
&lt;br /&gt;
Option 2. Discover &#039;&#039;&#039;git rebase&#039;&#039;&#039; - this is a powerful tool to change the sequence of commit, change the commit messages, squash commits, etc. We will not cover it here, there are many articles in the Internet about it.&lt;br /&gt;
&lt;br /&gt;
Whatever option you chose, you have &amp;quot;rewritten the history&amp;quot; and you can not simply push the changes to github again because they would need to overwrite the commits that were already pushed. If you try &amp;quot;git push MDL-xxxxx-nasty-bug&amp;quot; you will get an error message suggesting you to force push. To force push the changed commits use:&lt;br /&gt;
&lt;br /&gt;
    git push -f MDL-xxxxx-nasty-bug&lt;br /&gt;
&lt;br /&gt;
=== Checking if a branch has already been merged ===&lt;br /&gt;
&lt;br /&gt;
After some time contributing to Moodle you would have a lot of branches both in your local repository and in your public repository. To prune their list and delete those that were accepted by upstream, use the following&lt;br /&gt;
&lt;br /&gt;
    git fetch upstream                                      (1)&lt;br /&gt;
    git branch --merged upstream/master                     (2)&lt;br /&gt;
    git branch --merged upstream/MOODLE_20_STABLE           (3)&lt;br /&gt;
&lt;br /&gt;
The command (1) fetches the changes from your upstream repository at git.moodle.org (remember that git-fetch does not modify your working dir so it is safe to run it whenever). Command (2) and (3) print all branches that are merged into the upstream master branch and MOODLE_20_STABLE branch, respectively. To delete these local branches, use&lt;br /&gt;
&lt;br /&gt;
    git branch -d MDL-xxxxx-accepted-branch&lt;br /&gt;
&lt;br /&gt;
The similar approach can be used to check the branches published at your origin repository at github.com&lt;br /&gt;
&lt;br /&gt;
    git fetch origin                                        (1)&lt;br /&gt;
    git fetch upstream&lt;br /&gt;
    git branch -r --merged upstream/master                  (2)&lt;br /&gt;
    git branch -r --merged upstream/MOODLE_20_STABLE        (3)&lt;br /&gt;
&lt;br /&gt;
The command (1) makes sure that you have all your branches from github.com recorded as the remote tracking branch locally. Commands (2) and (3) work the same as in the previous example but they list remote tracking branches only ([http://www.kernel.org/pub/software/scm/git/docs/git-branch.html see -r param]). To delete a branch at github.com, use&lt;br /&gt;
&lt;br /&gt;
    git push origin :MDL-xxxx-branch-to-delete&lt;br /&gt;
&lt;br /&gt;
This syntax may look weird to you. However it is pretty logical. The general syntax of the git-push command is&lt;br /&gt;
&lt;br /&gt;
    git push &amp;lt;repository&amp;gt; &amp;lt;source ref&amp;gt;:&amp;lt;target ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
so deleting a remote branch can be understood as pushing an &amp;quot;empty (null) reference&amp;quot; to it.&lt;br /&gt;
&lt;br /&gt;
== Peer-reviewing someone else&#039;s code ==&lt;br /&gt;
&lt;br /&gt;
To review a branch that someone else pushed into their public repository, you do not need to register a new remote (unless you work with such repository frequently, of course). Let us imagine your friend Alice pushed a work-in-progress branch called &#039;wip-feature&#039; into her Github repository and asked you to review it. You need to know the read-only address of the repository and the name of the branch.&lt;br /&gt;
&lt;br /&gt;
    git fetch git://github.com/alice/moodle.git wip-feature&lt;br /&gt;
&lt;br /&gt;
This will download all required data and will keep the pointer to the tip of the wip-feature branch in a local symbolic reference FETCH_HEAD. To see what&#039;s there on that branch, use&lt;br /&gt;
&lt;br /&gt;
    git log -p FETCH_HEAD&lt;br /&gt;
&lt;br /&gt;
To see how a particular file looks at Alice&#039;s branch&lt;br /&gt;
&lt;br /&gt;
    git show FETCH_HEAD:admin/blocks.php&lt;br /&gt;
&lt;br /&gt;
To create a new local branch called &#039;alice-wip-feature&#039; containing the work by Alice, use&lt;br /&gt;
&lt;br /&gt;
    git checkout -b alice-wip-feature FETCH_HEAD&lt;br /&gt;
&lt;br /&gt;
To merge Alice&#039;s work into your current branch:&lt;br /&gt;
&lt;br /&gt;
    git merge FETCH_HEAD&lt;br /&gt;
&lt;br /&gt;
To see what would be merged into the current branch without actually modifying anything:&lt;br /&gt;
&lt;br /&gt;
    git diff ...FETCH_HEAD&lt;br /&gt;
&lt;br /&gt;
Once you are all set and reviewing code, this [[Peer_reviewing_checklist|checklist]] should prove to be useful.&lt;br /&gt;
&lt;br /&gt;
== Rebasing a branch ==&lt;br /&gt;
&lt;br /&gt;
Rebasing is a process when you cut off the branch from its current start point and transplant it to another point. Let us assume the following history exists:&lt;br /&gt;
&lt;br /&gt;
          A---B---C topic&lt;br /&gt;
         /&lt;br /&gt;
    D---E---F---G master&lt;br /&gt;
&lt;br /&gt;
From this point, the result of the command:&lt;br /&gt;
&lt;br /&gt;
    git rebase master topic&lt;br /&gt;
&lt;br /&gt;
would be:&lt;br /&gt;
&lt;br /&gt;
                  A&#039;--B&#039;--C&#039; topic&lt;br /&gt;
                 /&lt;br /&gt;
    D---E---F---G master&lt;br /&gt;
&lt;br /&gt;
and would end with &#039;topic&#039; being your current branch.&lt;br /&gt;
&lt;br /&gt;
You may be asked to rebase your branch submitted for the integration if the submitted branch was based on an outdated commit. The typical case is if you create a new branch as a fork off the upstream master branch on Tuesday. Then on Wednesday, the upstream master branch grows as all changes from the last integration cycle are merged to it. To make diff easy on Github for next weekly pull request review, you want to rebase your branch against the updated master.&lt;br /&gt;
&lt;br /&gt;
    git rebase master MDL-xxxxx-topic-branch&lt;br /&gt;
&lt;br /&gt;
Note that rebasing effectively rewrites the history of the branch. &#039;&#039;&#039;Do not rebase the branch if there is a chance that somebody has already forked it and based their own branch on it.&#039;&#039;&#039; For this reason, many Git tutorials discourage from rebasing any branch that has been published. However in Moodle, all branches submitted for integration are potential subject of rebase (even though we try to not to do it often) and you should not base your own branches on them.&lt;br /&gt;
&lt;br /&gt;
=== Conflicts during rebase ===&lt;br /&gt;
&lt;br /&gt;
During the rebase procedure, conflicts may appear. git-status commands reports the conflicted files. Explore them carefully and fix them in your editor (like you would do with CVS). Then add the files with &#039;git add&#039; command and continue.&lt;br /&gt;
&lt;br /&gt;
    vim conflicted.php&lt;br /&gt;
    git add conflicted.php&lt;br /&gt;
    git rebase --continue&lt;br /&gt;
&lt;br /&gt;
== Applying changes from one branch to another ==&lt;br /&gt;
&lt;br /&gt;
Most bugs are fixed at a stable branch (like MOODLE_20_STABLE) and the fix must be prepared for other branches, too (like MOODLE_21_STABLE and the main development branch - master). In Moodle, we do not merge stable branches into the master one. So usually the contributor prepares at least two branches - with the fix for the stable branch(es) and with the fix for the master branch.&lt;br /&gt;
&lt;br /&gt;
If you have a patch prepared on a local branch (let us say MDL-xxxx-topic_20_STABLE), it is possible to re-apply it to another branch.&lt;br /&gt;
&lt;br /&gt;
=== Cherry-picking a single commit ===&lt;br /&gt;
&lt;br /&gt;
Let us have two local Git repositories ~/public_html/moodle21 containing local installation of Moodle 2.1 and ~/public_html/moodledev with the local installation of most recent development version of Moodle. They both use your public repository at github.com as the origin. You have a branch in moodle21 called MDL-xxxx-topic_21_STABLE that was forked off MOODLE_21_STABLE. It contains one commit. Now you want to re-apply this commit to a branch MDL-xxxx-topic in moodledev.&lt;br /&gt;
&lt;br /&gt;
    cd ~/public_html/moodledev&lt;br /&gt;
    git checkout -b MDL-xxxx-topic origin/master            (1)&lt;br /&gt;
    git fetch ../moodle21 MDL-xxxx-topic_21_STABLE          (2)&lt;br /&gt;
    git cherry-pick FETCH_HEAD                              (3)&lt;br /&gt;
&lt;br /&gt;
The command (1) creates new local branch forked off the CONTHERE The command (1) fetches all data needed to re-apply the topic branch and stores the pointer to the tip of that branch to FETCH_HEAD symbolic reference. The command (2) picks the tip of the branch (the top-most commit on it) and tries to apply it on the current branch.&lt;br /&gt;
There is also a variant of the cherry-pick command that supports multiple commits, shortly (see its man page for details): &amp;lt;code bash&amp;gt;$ git cherry-pick A^..B&amp;lt;/code&amp;gt; if you want to include from A - see &#039;&#039;&#039;^&#039;&#039;&#039; - to B, A should be older than B. We will use another approach for cherry-picking multiple commits.&lt;br /&gt;
&lt;br /&gt;
=== Applying a set of patches ===&lt;br /&gt;
&lt;br /&gt;
If the branch MDL-xxxx-topic_21_STABLE from the previous example consists of several commits, it may be easier to use git-format-patch and git-am combo to re-apply the whole set of patches (aka patchset). Firstly you will export all commits from the topic branch to files.&lt;br /&gt;
&lt;br /&gt;
    cd ~/public_html/moodle21&lt;br /&gt;
    mkdir .patches&lt;br /&gt;
    git format-patch -o .patches MOODLE_21_STABLE..MDL-xxxx-topic_21_STABLE         (1)&lt;br /&gt;
&lt;br /&gt;
The command (1) takes all commits from the topic branch that are not in MOODLE_21_STABLE and exports them one by one to the output directory .patches. Look at the generated files. They contain the patch itself (in diff format) and additional information about the commit. You could eg send these files by email to a friend of yours for peer-review. We will use them in another repository.&lt;br /&gt;
&lt;br /&gt;
    cd ~/public_html/moodledev&lt;br /&gt;
    git checkout -b MDL-xxxx-topic origin/master&lt;br /&gt;
    git am -3 ../moodle21/.patches/*                        (1)&lt;br /&gt;
&lt;br /&gt;
The command (1) applies all the files from the .patches directory. When a patch does not apply cleanly, the command tries fall back on 3-way merge (see the -3 parameter). If conflicts occur during the procedure, you can either deal with them and then use `git am --continue` or abort the whole procedure with `git am --abort`.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
; Moodle forum discussions&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=168094 GIT help needed]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=165236 Best way to manage CONTRIB code with GIT]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=167063 Handy Git tip for tracking 3rd-party modules and plugins]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=167730 Moodle Git repositories]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=183409 Git help!! I don&#039;t understand rebase enough...]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=217617 add MOODLE_24_STABLE to github.com repository]&lt;br /&gt;
&lt;br /&gt;
; External resources &lt;br /&gt;
* [http://www.kernel.org/pub/software/scm/git/docs/everyday.html Everyday GIT With 20 Commands Or So]&lt;br /&gt;
* [http://gitref.org/ Git Reference]&lt;br /&gt;
* [http://progit.org/book/ Pro Git book]&lt;br /&gt;
* [http://vimeo.com/14629850 Getting git by Scott Chacon] - an recording of an excellent 1-hour presentation that introducing git, including a simple introduction to what is going on under the hood.&lt;br /&gt;
* [http://tjhunt.blogspot.co.uk/2012/03/fixing-bug-in-moodle-core-mechanics.html Tim Hunt&#039;s blog: Fixing a bug in Moodle core: the mechanics]&lt;br /&gt;
&lt;br /&gt;
[[Category:Git]]&lt;br /&gt;
&lt;br /&gt;
[[ja:開発者用Git]]&lt;/div&gt;</summary>
		<author><name>Vaibspidy</name></author>
	</entry>
</feed>