<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/21/en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Libertymoodle</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/21/en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Libertymoodle"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/Special:Contributions/Libertymoodle"/>
	<updated>2026-04-17T12:13:09Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Verify_Database_Schema&amp;diff=96203</id>
		<title>Verify Database Schema</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Verify_Database_Schema&amp;diff=96203"/>
		<updated>2013-05-23T13:13:37Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Typo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Installing Moodle}}&lt;br /&gt;
If you have been upgrading your Moodle site over several versions, it is possible (likely even) that some differences may have crept in between the database table definitions (the &amp;quot;schema&amp;quot;) in your database and the version you would get creating a new empty site. This happens because of small errors or oversights in the upgrade scripts. Most of these differences are not harmful, but some may cause strange or unexpected errors. For example, if a default value has been added to a field and this was not reflected in an upgrade script code that assumes the presence of the default may fail to work as expected. &lt;br /&gt;
&lt;br /&gt;
The solution is after doing an upgrade (or, if your problem is that the upgrade fails, before) to compare the database schema of the &amp;quot;production&amp;quot; site to that of a newly created site (where no upgrades have been performed) using &#039;&#039;&#039;exactly&#039;&#039;&#039; the same code base. There are a number of ways of doing this, but this article outlines a simple way using the Unix command line.&lt;br /&gt;
&lt;br /&gt;
* Complete the upgrade&lt;br /&gt;
* Generate the database schema from your recently upgraded site using the following command:&lt;br /&gt;
    mysqldump -d -u root -p &#039;&#039;myproductiondb&#039;&#039; &amp;gt;production.schema&lt;br /&gt;
* Copy the code  of your production database to a new (web accessible) location (this is important, it *must* be the same version)&lt;br /&gt;
* Create a new, empty database and moodledata area for the new site as per the [[Installation]] instructions&lt;br /&gt;
* Edit the config.php file to point at the new database and locations, or delete it and use the install script&lt;br /&gt;
* Run the install script to generate the (if applicable) config.php file and the database (admin and site values are not important)&lt;br /&gt;
* Generate the database schema from your new site using the following command:&lt;br /&gt;
    mysqldump -d -u root -p &#039;&#039;mycleandb&#039;&#039; &amp;gt;clean.schema&lt;br /&gt;
* Run the following command to detect the differences&lt;br /&gt;
    diff -u production.schema clean.schema &amp;gt;db.diff&lt;br /&gt;
&lt;br /&gt;
You can now look at &#039;&#039;db.diff&#039;&#039; with your favorite editor to see the differences.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; The above obviously applies to MySQL databases. Other databases are likely to have a similar function to dump only the schema. For example PostgreSQL has the &#039;&#039;&#039;pg_dump&#039;&#039;&#039; command. The remainder of the discussion still applies. &lt;br /&gt;
&lt;br /&gt;
==Interpreting the diff file==&lt;br /&gt;
&lt;br /&gt;
Firstly here&#039;s a (real) example:&lt;br /&gt;
&lt;br /&gt;
     --&lt;br /&gt;
     -- Table structure for table `mdl_backup_config`&lt;br /&gt;
        @@ -129,11 +93,11 @@&lt;br /&gt;
         DROP TABLE IF EXISTS `mdl_backup_config`;&lt;br /&gt;
         CREATE TABLE `mdl_backup_config` (&lt;br /&gt;
    -  `id` int(10) unsigned NOT NULL auto_increment,&lt;br /&gt;
    +  `id` bigint(10) unsigned NOT NULL auto_increment,&lt;br /&gt;
       `name` varchar(255) NOT NULL default &#039;&#039;,&lt;br /&gt;
       `value` varchar(255) NOT NULL default &#039;&#039;,&lt;br /&gt;
        PRIMARY KEY  (`id`),&lt;br /&gt;
    -  UNIQUE KEY `name` (`name`)&lt;br /&gt;
    +  UNIQUE KEY `mdl_backconf_nam_uix` (`name`)&lt;br /&gt;
         ) ENGINE=MyISAM AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 COMMENT=&#039;To store backup configuration variables&#039;;&lt;br /&gt;
&lt;br /&gt;
The file may have lots of blocks of changes. The - lines show lines to be taken out and the + lines the ones to replace them (from the production to the clean). So here, the int has been replaced with a bigint and the key name changed. Both of these, technically, should have been changed at some point by upgrade scripts but have been missed. In this case they are unlikely to affect the operation of Moodle. &lt;br /&gt;
&lt;br /&gt;
===Too many changes to track manually?===&lt;br /&gt;
&lt;br /&gt;
You can also use database management programs to synchronize old and new Moodle databases.&lt;br /&gt;
&lt;br /&gt;
For example [http://wb.mysql.com/ MySQL Workbench] for MySQL databases.&lt;br /&gt;
&lt;br /&gt;
This is very useful, if you have a lot of changes.&lt;br /&gt;
&lt;br /&gt;
If you can work a Unix/Linux command line the Python script [http://schemasync.org/ Schema Sync] provides a quick and simple way to generate all the commands to update your database.&lt;br /&gt;
&lt;br /&gt;
==Should I worry?==&lt;br /&gt;
&lt;br /&gt;
Changes in field types (as long as they are compatible) and key name changes seem to be the common issues but &#039;&#039;&#039;should&#039;&#039;&#039; not cause problems. Things to look out for would be along the lines of missing fields and changes to default values.&lt;br /&gt;
&lt;br /&gt;
If you are about to upgrade to Moodle 2.0 you should be more concerned. In order for the upgrade to proceed smoothly it is a very good idea to correct these problems.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* The missing indexes report in &#039;&#039;SiteAdmin-&amp;gt;Misc-&amp;gt;XMLDB editor-&amp;gt;Check Indexes&#039;&#039;&lt;br /&gt;
* [http://moodle.org/mod/forum/view.php?id=45 Moodle Databases Forum]&lt;br /&gt;
&lt;br /&gt;
[[de:Datenbank-Schema prüfen]]&lt;br /&gt;
[[fr:Vérification du schéma de la base de données]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Moodle_migration&amp;diff=96193</id>
		<title>Moodle migration</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Moodle_migration&amp;diff=96193"/>
		<updated>2013-05-15T07:21:34Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* See also link */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Installing Moodle}}&lt;br /&gt;
There may be times when you need to move your Moodle site from one server to another. For example, moving a Moodle site from shared hosting service&#039;s server to a dedicated server.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;Tip:&#039;&#039; One common migration mistake is to forget to update the details in the migrated Moodle&#039;s &#039;&#039;[[Configuration file|config.php]]&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
==Migrating a complete Moodle site - method 1==&lt;br /&gt;
&lt;br /&gt;
This involves moving a whole site from one server to another. If you are changing the domain/IP address to the new server you need to do these steps:&lt;br /&gt;
* &#039;&#039;&#039;Maintenance mode&#039;&#039;&#039;. Place your current Moodle site in maintenance mode to prevent any further additions to the Moodle database. Don&#039;t let administrators login during the migration as they are not affected by the maintenance mode setting.&lt;br /&gt;
* &#039;&#039;&#039;Backup your current Moodle database&#039;&#039;&#039;. Do this by following the instructions in the [[Upgrading | upgrading Moodle]] or [[Site backup]] page. This will give you a text file containing the mysql dump.&lt;br /&gt;
* &#039;&#039;&#039;Copy the Moodle software&#039;&#039;&#039;. You will need to copy the Moodle code itself to the new server - upgrade the code to the latest version if you can.&lt;br /&gt;
* &#039;&#039;&#039;Change &amp;lt;code&amp;gt;$CFG-&amp;gt;wwwroot&amp;lt;/code&amp;gt;&#039;&#039;&#039;. In your (possibly new) Moodle directory, change the &amp;lt;code&amp;gt;$CFG-&amp;gt;wwwroot&amp;lt;/code&amp;gt; variable in the &#039;&#039;config.php&#039;&#039; file for the new server.&lt;br /&gt;
* &#039;&#039;&#039;Copy data directory contents (moodledata)&#039;&#039;&#039;. Copy the contents of your data directory (check for the value in &amp;lt;code&amp;gt;$CFG-&amp;gt;dataroot&amp;lt;/code&amp;gt;) to the new server.&lt;br /&gt;
* &#039;&#039;&#039;Review moodledata permissions&#039;&#039;&#039;. Check also that permissions remain the same on the new dataroot folder and change the value if you have changed its location on the new server.&lt;br /&gt;
* &#039;&#039;&#039;Change your Moodle URL&#039;&#039;&#039;. If you have a new URL, you&#039;ll need to change this in the Moodle database to the new server. This is needed as links to pictures, files, etc are stored as absolute links and will reference the old &amp;lt;code&amp;gt;$CFG-&amp;gt;wwwroot&amp;lt;/code&amp;gt; value. So when loading a mysql backup dump of the Moodle server into mysql on another server the absolute referenced links will be broken. There are two methods of doing this:&lt;br /&gt;
:(a) The first method changes the Moodle URL using the Moodle script &#039;&#039;replace.php&#039;&#039; while your site is currently running just before you backup the Moodle database. Point your browser to &amp;lt;nowiki&amp;gt;http://yourserver.com/admin/replace.php&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Enter the url for your old server (&amp;lt;nowiki&amp;gt;http://oldserver.com/&amp;lt;/nowiki&amp;gt;) and new server (&amp;lt;nowiki&amp;gt;http://newserver.com/&amp;lt;/nowiki&amp;gt;) and it will fix the mysql tables. You will also need to clear out any cached links by restarting your webserver. Now, take another backup of the Moodle database - this one will have the correct URLs.&lt;br /&gt;
&lt;br /&gt;
:(b) The second method is to backup the Moodle database first, then use the search and replace feature of your text editor (or use a unix tool like sed) to replace the old URL with the new one in the mysql backup file. Here is an example sed command:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;#sed -e &#039;s/oldserver.com/newserver.com/g&#039; oldmysqldump.sql &amp;gt; newmysqldump.sql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;TIP:&#039;&#039; You may want to check the mysqldump file to see how the old server was referenced.&lt;br /&gt;
:After changing the URL, restore the mysql database&lt;br /&gt;
* &#039;&#039;&#039;Test the migration&#039;&#039;&#039;. To test the new install, access Moodle using your browser and the new server&#039;s URL. When you have tested that a number of links in the courses work, take the new Moodle site out of maintenance mode.&lt;br /&gt;
&#039;&#039;&#039;See also&#039;&#039;&#039;: Forum discussion on [http://moodle.org/mod/forum/discuss.php?d=85812 migrating Moodle&#039;s data directory on a Windows system].&lt;br /&gt;
&lt;br /&gt;
==Migrating a complete Moodle site - method 2==&lt;br /&gt;
&lt;br /&gt;
Do you have shell access on both servers? If so, the following method is a very quick and efficient method to migrate a Unix based site.&lt;br /&gt;
&lt;br /&gt;
It is also useful for creating snapshots or test sites.&lt;br /&gt;
*Set up a new empty database on the &#039;&#039;&#039;new&#039;&#039;&#039; server.&lt;br /&gt;
&lt;br /&gt;
It mean that that you must not open the&lt;br /&gt;
 http://example.domain/moodle/admin&lt;br /&gt;
webpage yet.&lt;br /&gt;
*Place your Moodle site into maintenance mode.&lt;br /&gt;
*Login to shell on the &#039;&#039;&#039;old&#039;&#039;&#039; server.&lt;br /&gt;
*Use rsync to copy &#039;&#039;&#039;moodledata&#039;&#039;&#039; and &#039;&#039;&#039;public_html&#039;&#039;&#039; (or whatever directory your Moodle install is in) to the new server - execute (replacing caps with your details; SOURCE = the directory you want to copy) for each directory:&lt;br /&gt;
::&amp;lt;code&amp;gt;rsync -av -e ssh SOURCE/ USERNAME@NEW_SERVER.COM:/PATH/TO/DESTINATION/&amp;lt;/code&amp;gt;&lt;br /&gt;
On the new server you must to setup permissions on &#039;&#039;&#039;moodledata&#039;&#039;&#039; directory and it&#039;s subdirectories and files.&lt;br /&gt;
&lt;br /&gt;
Say, on a Debian operating system one can run the command:&lt;br /&gt;
::&amp;lt;code&amp;gt;hostname:/var/lib# chown www-data:www-data -R moodle/&amp;lt;/code&amp;gt;&lt;br /&gt;
*Dump existing database and move and import into database on new server by executing:&lt;br /&gt;
::&amp;lt;code&amp;gt;mysqldump --allow-keywords --opt -uMySQL_USERNAME -pPASSWORD DATABASE | ssh USER@DOMAIN &amp;quot;mysql -uMySQL_USERNAME -pPASSWORD DATABASE&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
*On the &#039;&#039;&#039;new server&#039;&#039;&#039;, update &#039;&#039;&#039;config.php&#039;&#039;&#039; with relevant details.&lt;br /&gt;
*To fix any internal Moodle links, login to your &amp;quot;new&amp;quot; Moodle install on your new server and use &#039;&#039;&#039;admin/replace.php&#039;&#039;&#039; to search and replace the old uri for the new.&lt;br /&gt;
Say:&lt;br /&gt;
::&amp;lt;code&amp;gt;&lt;br /&gt;
Search and replace text throughout the whole database&lt;br /&gt;
&lt;br /&gt;
Search whole database for: the.old.moodle.uri&lt;br /&gt;
&lt;br /&gt;
Replace with this string: the.new.moodle.uri&lt;br /&gt;
&lt;br /&gt;
*Make sure everything is working.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Takes about 15 minutes.&lt;br /&gt;
&lt;br /&gt;
When you are happy all has gone well, set up redirects/make DNS changes if required, take new site out of maintenance mode and &amp;quot;switch off&amp;quot; old site.&lt;br /&gt;
&lt;br /&gt;
==Other points to consider==&lt;br /&gt;
===Changed URL image links set to old site===&lt;br /&gt;
So you built your Moodle Server with a &amp;lt;nowiki&amp;gt;http//192.168.0.1/Moodle address.  Then you changed the URL for your site to http://OurMoodle.org/Moodle .   You changed the Moodle config file so the CFGs point to the new paths.  But your images point to the old url. &amp;lt;/nowiki&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;One simple, quick solution.  Login as admin and put http://OurMoodle.org/Moodle/admin/replace.php in your browser address bar.  Use the two form boxes to change http://192.168.0.1/  to  http://OurMoodle.org/ .&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Upgrade Moodle===&lt;br /&gt;
&lt;br /&gt;
When migrating Moodle it is often a good idea to take the opportunity to upgrade Moodle to the latest version. If you manage your own server, follow the instructions in [[Upgrading | upgrading moodle]], otherwise check if your host can upgrade for you.&lt;br /&gt;
&lt;br /&gt;
===Restoring a single course across servers===&lt;br /&gt;
&lt;br /&gt;
You may need to restore a single course from an old site to a new one, especially if you are testing the migration. When restoring a Moodle backup file to Moodle on a different server than the one used to create the backup, the absolute referenced links to files maybe broken. To fix this problem open the &#039;&#039;backup-coursename.zip&#039;&#039; file and edit the &#039;&#039;moodle.xml&#039;&#039; file replacing links with &amp;lt;code&amp;gt;$@FILEPHP@$&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, replace &amp;lt;nowiki&amp;gt;http://yourserver.com/file.php/243/&amp;lt;/nowiki&amp;gt; with &amp;lt;code&amp;gt;$@FILEPHP@$&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
When the file is restored it will use the correct file path for the new course.&lt;br /&gt;
&lt;br /&gt;
===DNS &amp;amp; Masquerading changes===&lt;br /&gt;
&lt;br /&gt;
You may have had to change the DNS entries for the new Moodle site. If you have done so, it will take some time for the changes to replicate, so be patient. If your server is located behind a firewall, you may also have to change your firewall rules to allow access to the new server. See the [[Masquerading | masquerading docs]].&lt;br /&gt;
&lt;br /&gt;
===Internal and external access===&lt;br /&gt;
&lt;br /&gt;
If you have a set up where your Moodle site can be accessed via a network and via the internet, ensure you check that the new site can be accessed internally and externally.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
Moodle Docs:&lt;br /&gt;
* [[Site backup]]&lt;br /&gt;
* [[Site restore]]&lt;br /&gt;
* [[Backup and restore FAQ]]&lt;br /&gt;
* [http://www.youtube.com/watch?v=sFCXvRx20Bs Moving Moodle to a new server video]&lt;br /&gt;
&lt;br /&gt;
Using Moodle forum discussions:&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=62959 Changing Moodle URL] &lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=57477 Changing site address] &lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=76704 Upgrading whilst migrating] &lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=65450 Internal and external access] &lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=111807 Migrated Moodle to New Server But Can&#039;t Login]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=228436 Replace script returns &amp;quot;Service Unavailable&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
[[fr:Migration de Moodle]]&lt;br /&gt;
[[nl:Moodle verhuizen]]&lt;br /&gt;
[[ja:Moodle移行]]&lt;br /&gt;
[[de:Moodle-Migration]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=error/moodle/invalidrecordunknown&amp;diff=96071</id>
		<title>error/moodle/invalidrecordunknown</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=error/moodle/invalidrecordunknown&amp;diff=96071"/>
		<updated>2012-08-08T11:45:04Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* invalidrecordunknown description and possible cause */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This error can occur when Moodle tries to access a record in the Moodle database that does not exist. This can happen when you try to view your student profile in Moodle by manually entering the URL in the address bar of your browser. Example if you type http://yourschool.com/user/profile.php?id=12345 into your browser and the 12345 id does not correspond to the id of your Moodle profile you will get this error.&lt;br /&gt;
&lt;br /&gt;
You should always avoid typing a url directly in the address bar of your browser when you are navigating through your Moodle site. Always use the nagigation that is part of Moodle to get around the site.&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Active_Directory&amp;diff=94196</id>
		<title>Active Directory</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Active_Directory&amp;diff=94196"/>
		<updated>2011-11-30T08:00:12Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* See also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Microsoft&#039;s Active Directory (AD) provides a variety of network directory services including Lightweight Directory Access Protocol (LDAP) like functions.  It is included in Windows 2000 Server and later versions of their operating system.   The focus of this page will be with the [[LDAP authentication]] functions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Trouble shooting AD and LDAP authentication==&lt;br /&gt;
===Warning: The PHP LDAP module does not seem to be present. Please ensure it is installed and enabled.===&lt;br /&gt;
This usually means that the main ldap dll or one of the supporting dlls are missing.&lt;br /&gt;
Let&#039;s start with the main one itself. &lt;br /&gt;
Browse to &amp;lt;nowiki&amp;gt;http://(moodleserver)/admin/phpinfo.php&amp;lt;/nowiki&amp;gt; and examine the &amp;quot;Configuration File (php.ini) Path&amp;quot; field to determine which php.ini is being used and open it with an editor. Find the line &#039;extension=php_ldap.dll&#039; and take out the semi-colon if it is there. That semi-colon will stop it loading the module all together! &lt;br /&gt;
While you have that file open, search for &#039;extension_dir&#039; and note which folder it is set to. Open that folder and ensure the php_ldap.dll file is in there. If it isn&#039;t then put it in there.&lt;br /&gt;
If that still hasn&#039;t fixed it you are missing a supporting dll, but you don&#039;t get told that. To see what dlls are missing open the Command Prompt and navigate to the php directory and execute the following line &#039;php -m&#039;. You should get some error messages now. Ugly, but at least they give you information! Find the dlls listed and copy them to the php directory. You may now need to restart the apache/httpd service. Run &#039;php -m&#039; again and you should be error free and the message in Moodle should be gone now.&lt;br /&gt;
&lt;br /&gt;
===LDAP-module cannot connect any LDAP servers===&lt;br /&gt;
 LDAP-module cannot connect any LDAP servers: &lt;br /&gt;
 Server: &#039;ldap://my.ldap.server/&#039; &lt;br /&gt;
 Connection: &#039;Resource id #26&#039; Bind result: &#039;&#039;&lt;br /&gt;
Getting this message when you are trying to log in is a result of incorrect details for the Bind user, or the user account having insufficient permissions in Active Directory. The best way to test and resolve this is use ldp.exe to test binding until it suceeds. There are instructions on installing ldp.exe below.&lt;br /&gt;
Open the program and Connect to AD, giving the server name, then from the Connection menu choose Bind. Enter the details you think are correct and you will probably find that an error is returned. Try adjusting the accounts priveleges or another account until you are returned an &amp;quot;Authenticated as&amp;quot; message.&lt;br /&gt;
Once you are sure your account can be used to bind to AD, check that the DN of that users name is correct. Expand the tree on the left until you find the user you used to bind. Right click on that item and choose Copy DN. Go to the User Authentication page in Moodle and paste the value into the ldap_bind_dn field. Add the password and you can now feel safe your user is binding sucessfully.&lt;br /&gt;
&lt;br /&gt;
===Getting correct CNs for Contexts and Creators===&lt;br /&gt;
For those not familiar with AD this could be very confusing, and not that easy for some who are familiar with it. Again, ldp.exe is your friend. There are instructions on installing ldp.exe below.&lt;br /&gt;
Open it up and expand the tree on the left until you find the group or user you want to use and right click on it and select Copy DN. Go back to the Moodle User Authentication page and paste that value into either ldap_contexts or ldap_creators.&lt;br /&gt;
&lt;br /&gt;
===Getting the right user_attribute===&lt;br /&gt;
By default, Moodle uses an accounts cn (full name) to verify against, but most networks don&#039;t use a full given name for logon as it&#039;s too easy to guess and you can easily have two people with the same name. If this is the case for you too you need to tell Moodle to look at another field for the logon id.&lt;br /&gt;
In ldp.exe navigate the tree on the left to find a user account, preferably your own. Double-click the item in the tree and full-details will be loaded into the screen on the right. Look down the details until you find your logon id and note the item listed against it. For me, and a lot of people, it is sAMAccountName. Copy this name and paste it into the ldap_user_attribute on the Moodle User Authentication page.&lt;br /&gt;
There are instructions on installing ldp.exe below.&lt;br /&gt;
&lt;br /&gt;
===Installing ldp.exe Server Tool===&lt;br /&gt;
ldp.exe comes as part of the Server Tools on most versions of Windows Server. Find your Windows Server installation disc and find a folder on it called Support\Tools. In there will be a SupTools.msi which will install the server tools if run. You should now have a folder under Program Files called Support Tools, in which will be ldp.exe. ldp.exe is also available in the Windows XP Support Tools, which you can download from Microsoft [http://www.microsoft.com/downloads/details.aspx?FamilyId=49AE8576-9BB9-4126-9761-BA8011FABF38&amp;amp;displaylang=en here]. Alternatively, a single download of ldp.exe is available [http://www.computerperformance.co.uk/w2k3/utilities/ldp.htm here].&lt;br /&gt;
&lt;br /&gt;
===Example Active Directory Configuration===&lt;br /&gt;
Below is an example configuration for Active Directory. As detailed above, the values may vary based on your local Active Directory configuration, but should provide a good starting point for most cases.&lt;br /&gt;
&lt;br /&gt;
 ldap_host_url = ldap://ads.example.com&lt;br /&gt;
 ldap_version = 3&lt;br /&gt;
 ldap_preventpassindb = yes&lt;br /&gt;
 ldap_bind_dn = bind-user@example.com&lt;br /&gt;
 ldap_bind_pw = bind-password&lt;br /&gt;
 ldap_user_type = MS ActiveDirectory&lt;br /&gt;
 ldap_contexts = ou=moodleusers,dc=example,dc=com&lt;br /&gt;
 ldap_user_attribute = sAMAccountName&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that the ldap_bind_dn value should work in either the CN=bin-user,CN=Users,DC=example,DC=com format as shown in the main instructions or the bind-user@example.com format shown in this example.&lt;br /&gt;
&lt;br /&gt;
==Global Catalogs==&lt;br /&gt;
Moodle currently only has limited support for multiple domain controllers; specifically it expects each of the LDAP servers listed to contain identical sets of information. If you have users in multiple domains this presents an issue. One solution when working with MS-AD is to use the Global Catalog. The Global Catalog is designed to be a read-only, partial representation of an entire MS-AD forest, designed for searching the entire directory when the domain of the required object is not known.&lt;br /&gt;
&lt;br /&gt;
===Enabling the Global Catalog===&lt;br /&gt;
&lt;br /&gt;
The Global Catalog is available on Windows 2000 and Windows 2003 Active Directory servers. To enable, open the ‘Active Directory Sites and Services’ MMC (Microsoft Management Console) snap-in. Extend ‘Sites’ and then the name of the Site containing the active directory forest you wish to use. Expand the server you wish to enable the Global Catalog on, right click ‘NTDS settings’ and select the ‘Properties’ tab. To enable, simply click the ‘Global Catalog’ checkbox. Under a Windows 2000 server it is necessary to restart the server (although it won’t prompt you to); under Windows 2003 server it is not necessary to restart the server. In either case you will generally have to wait for the AD forest to replicate before the Global Catalog offers a representation of the entire AD forest. Changes made in Active Directory will also be subject to a short delay due to the latency involved with replication. If your AD servers are firewalled port 3268 will need to be opened for Global Catalog servers.&lt;br /&gt;
If your organisation uses Microsoft Exchange then it its highly likely that at least one Domain Controller will already have Global Catalog enabled – Exchange 2000 and 2003 rely on the Global Catalog for address information, users also access the Global Catalog when using the GAL (Global Address List)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Child Domains===&lt;br /&gt;
If your organisation has a main domain example.org, staff and students are contained in two child domains staff.example.org and students.example.org. The 3 domains (example.org, staff.example.org and students.example.org) each have a domain controller (dc01, dc02 and dc03 respectively.) Each domain controller contains a full, writable, representation of only the objects that belong to its domain. However, assuming that the Global Catalog has been enabled (see below) on one of the domain controllers (for example dc01) a query to the Global Catalog would reveal matching objects from all three domains. The Global Catalog is automatically maintained through replication across the active directory forest, it can also be enabled on multiple servers (if, for example, you need redundancy / load balancing.)&lt;br /&gt;
&lt;br /&gt;
To make use of this in Moodle to allow logins from multiple domains is simple. The Global Catalog runs on port 3268 as opposed to 389 for standard LDAP queries. As a result, still assuming the Global Catalog is running on dc01, the &#039;&#039;&#039;&#039;ldap_host_url&#039;&#039;&#039;&#039; would be &#039;&#039;ldap://dc01.example.org:3268&#039;&#039;. The rest of the settings are the same as for other MS-AS Auth setups.&lt;br /&gt;
&lt;br /&gt;
You should use the &#039;&#039;&#039;&#039;ldap_contexts&#039;&#039;&#039;&#039; setting to indicate the locations of individuals you wish to grant access. To extend the example above a little: In the example.org domain users are all in the&#039;&#039; &#039;Users&#039; &#039;&#039;OU, in the staff.example.org domain users are in two OUs at the root of the domain,&#039;&#039; &#039;Support Staff&#039; &#039;&#039;and&#039;&#039; &#039;Teaching Staff&#039; &#039;&#039;, and in the students.example.org domain students are in an OU indicating the year that they enrolled, all of which are under the&#039;&#039; &#039;Students&#039; &#039;&#039;OU. As a result our &#039;&#039;&#039;&#039;ldap_contexts&#039;&#039;&#039;&#039; setting may look a little like this:&#039;&#039; &#039;OU=Users,DC=example,DC=org; OU=Support Staff,DC=staff,DC=example,DC=org; OU=Teaching Staff,DC=staff,DC=example,DC=org; OU=Students,DC=students,DC=example,DC=org&#039;&#039;.&#039; The &#039;&#039;&#039;&#039;ldap_search_sub&#039;&#039;&#039;&#039; option should be set to&#039;&#039; &#039;Yes&#039; &#039;&#039;to allow moodle to search within the child OUs.&lt;br /&gt;
&lt;br /&gt;
Its worth noting that the Global Catalog only contains a partial representation of the attributes of each object, as defined in the Partial Attribute Set supplied by Microsoft. However common information likely to be of use to a general Moodle installation (Forename, Surname, Email Address, sAMAccountName etc) is included in the set. For specific needs the schema can be altered to remove or add various attributes - see Microsoft [http://support.microsoft.com/kb/248717 KB248717] for more information.&lt;br /&gt;
&lt;br /&gt;
In most cases the Global Catalog is read-only, update queries must be made over the standard LDAP ports to the domain controller that holds the object in question (in our example, updating a student&#039;s details would require an LDAP query to the students.example.org domain controller - dc03, it would not be possible to update details by querying the Global Catalog.) The exception to this would be in an environment where there is only a single domain in the active directory forest; in this case the Global Catalog holds a writable full set of attributes for each object in the domain. However, for the purposes of Moodle authorisation, there would be no need to use the Global Catalog in this case.&lt;br /&gt;
&lt;br /&gt;
===MaxPageSize setting===&lt;br /&gt;
Modifying the number of Active Directory objects to search: &lt;br /&gt;
&lt;br /&gt;
By default Active Directory only allows searches returning a limited number of objects per search. Since there is currently no Page control support in PHP 5.2.x which would enable smaller page searches you may need to modify your MaxPageSize setting to make sure LDAP Client searches can return enough user objects to support the number of authenticating users. &lt;br /&gt;
&lt;br /&gt;
If you find that the script is not running through all of your users properly and you have MS Active Directory + over 1000 users, follow the instructions [http://support.microsoft.com/kb/315071 here] to set the MaxPageSize setting to a number higher than your total number of users (both now and in future) to fix it.  This is a forest-wide setting.&lt;br /&gt;
&lt;br /&gt;
==MS Active Directory + SSL ==&lt;br /&gt;
&lt;br /&gt;
If the Certificate Authority is not installed you&#039;ll have to install it first as follows:&lt;br /&gt;
# Click &#039;&#039;&#039;Start&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Control Panel&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Add or Remove programs.&#039;&#039;&#039;&lt;br /&gt;
# Click &#039;&#039;&#039;Add/Remove Windows Components&#039;&#039;&#039; and select &#039;&#039;&#039;Certificate Services.&#039;&#039;&#039;&lt;br /&gt;
# Follow the procedure provided to install the &#039;&#039;&#039;Certificate Authority&#039;&#039;&#039;. Enterprise level is a good choice.&lt;br /&gt;
&lt;br /&gt;
Verify that SSL has been enabled on the server by installing suptools.msi from Windows installation cd&#039;s \Support\tools directory. After support tools installation:&lt;br /&gt;
# Select &#039;&#039;&#039;Start&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Run&#039;&#039;&#039;, write &#039;&#039;&#039;ldp&#039;&#039;&#039; in the Open field.&lt;br /&gt;
# From the ldp window select &#039;&#039;&#039;Connection&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Connect&#039;&#039;&#039; and supply valid hostname and port number &#039;&#039;&#039;636&#039;&#039;&#039;. Also select the SSL check box.&lt;br /&gt;
&lt;br /&gt;
If successful, you should get information about the connection.&lt;br /&gt;
&lt;br /&gt;
See [[LDAP_authentication#Enabling_LDAPS_on_the_client_side_.28Moodle_server.29|Enabling LDAPS on the client side (Moodle server)]] for details on the client side configuration.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[[LDAP authentication]] in Moodle&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Directory_service Directory services] overview in Wikipedia&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol LDAP] in Wikipedia&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=17198 Using multiple LDAP servers - Our students are on separate domain] forum discussion&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=74279 How to use multiple LDAP servers with Moodle 1.8] forum discussion&lt;br /&gt;
&lt;br /&gt;
[[ja:Active Directory]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Active_Directory&amp;diff=94195</id>
		<title>Active Directory</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Active_Directory&amp;diff=94195"/>
		<updated>2011-11-30T07:58:45Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* See also link */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Microsoft&#039;s Active Directory (AD) provides a variety of network directory services including Lightweight Directory Access Protocol (LDAP) like functions.  It is included in Windows 2000 Server and later versions of their operating system.   The focus of this page will be with the [[LDAP authentication]] functions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Trouble shooting AD and LDAP authentication==&lt;br /&gt;
===Warning: The PHP LDAP module does not seem to be present. Please ensure it is installed and enabled.===&lt;br /&gt;
This usually means that the main ldap dll or one of the supporting dlls are missing.&lt;br /&gt;
Let&#039;s start with the main one itself. &lt;br /&gt;
Browse to &amp;lt;nowiki&amp;gt;http://(moodleserver)/admin/phpinfo.php&amp;lt;/nowiki&amp;gt; and examine the &amp;quot;Configuration File (php.ini) Path&amp;quot; field to determine which php.ini is being used and open it with an editor. Find the line &#039;extension=php_ldap.dll&#039; and take out the semi-colon if it is there. That semi-colon will stop it loading the module all together! &lt;br /&gt;
While you have that file open, search for &#039;extension_dir&#039; and note which folder it is set to. Open that folder and ensure the php_ldap.dll file is in there. If it isn&#039;t then put it in there.&lt;br /&gt;
If that still hasn&#039;t fixed it you are missing a supporting dll, but you don&#039;t get told that. To see what dlls are missing open the Command Prompt and navigate to the php directory and execute the following line &#039;php -m&#039;. You should get some error messages now. Ugly, but at least they give you information! Find the dlls listed and copy them to the php directory. You may now need to restart the apache/httpd service. Run &#039;php -m&#039; again and you should be error free and the message in Moodle should be gone now.&lt;br /&gt;
&lt;br /&gt;
===LDAP-module cannot connect any LDAP servers===&lt;br /&gt;
 LDAP-module cannot connect any LDAP servers: &lt;br /&gt;
 Server: &#039;ldap://my.ldap.server/&#039; &lt;br /&gt;
 Connection: &#039;Resource id #26&#039; Bind result: &#039;&#039;&lt;br /&gt;
Getting this message when you are trying to log in is a result of incorrect details for the Bind user, or the user account having insufficient permissions in Active Directory. The best way to test and resolve this is use ldp.exe to test binding until it suceeds. There are instructions on installing ldp.exe below.&lt;br /&gt;
Open the program and Connect to AD, giving the server name, then from the Connection menu choose Bind. Enter the details you think are correct and you will probably find that an error is returned. Try adjusting the accounts priveleges or another account until you are returned an &amp;quot;Authenticated as&amp;quot; message.&lt;br /&gt;
Once you are sure your account can be used to bind to AD, check that the DN of that users name is correct. Expand the tree on the left until you find the user you used to bind. Right click on that item and choose Copy DN. Go to the User Authentication page in Moodle and paste the value into the ldap_bind_dn field. Add the password and you can now feel safe your user is binding sucessfully.&lt;br /&gt;
&lt;br /&gt;
===Getting correct CNs for Contexts and Creators===&lt;br /&gt;
For those not familiar with AD this could be very confusing, and not that easy for some who are familiar with it. Again, ldp.exe is your friend. There are instructions on installing ldp.exe below.&lt;br /&gt;
Open it up and expand the tree on the left until you find the group or user you want to use and right click on it and select Copy DN. Go back to the Moodle User Authentication page and paste that value into either ldap_contexts or ldap_creators.&lt;br /&gt;
&lt;br /&gt;
===Getting the right user_attribute===&lt;br /&gt;
By default, Moodle uses an accounts cn (full name) to verify against, but most networks don&#039;t use a full given name for logon as it&#039;s too easy to guess and you can easily have two people with the same name. If this is the case for you too you need to tell Moodle to look at another field for the logon id.&lt;br /&gt;
In ldp.exe navigate the tree on the left to find a user account, preferably your own. Double-click the item in the tree and full-details will be loaded into the screen on the right. Look down the details until you find your logon id and note the item listed against it. For me, and a lot of people, it is sAMAccountName. Copy this name and paste it into the ldap_user_attribute on the Moodle User Authentication page.&lt;br /&gt;
There are instructions on installing ldp.exe below.&lt;br /&gt;
&lt;br /&gt;
===Installing ldp.exe Server Tool===&lt;br /&gt;
ldp.exe comes as part of the Server Tools on most versions of Windows Server. Find your Windows Server installation disc and find a folder on it called Support\Tools. In there will be a SupTools.msi which will install the server tools if run. You should now have a folder under Program Files called Support Tools, in which will be ldp.exe. ldp.exe is also available in the Windows XP Support Tools, which you can download from Microsoft [http://www.microsoft.com/downloads/details.aspx?FamilyId=49AE8576-9BB9-4126-9761-BA8011FABF38&amp;amp;displaylang=en here]. Alternatively, a single download of ldp.exe is available [http://www.computerperformance.co.uk/w2k3/utilities/ldp.htm here].&lt;br /&gt;
&lt;br /&gt;
===Example Active Directory Configuration===&lt;br /&gt;
Below is an example configuration for Active Directory. As detailed above, the values may vary based on your local Active Directory configuration, but should provide a good starting point for most cases.&lt;br /&gt;
&lt;br /&gt;
 ldap_host_url = ldap://ads.example.com&lt;br /&gt;
 ldap_version = 3&lt;br /&gt;
 ldap_preventpassindb = yes&lt;br /&gt;
 ldap_bind_dn = bind-user@example.com&lt;br /&gt;
 ldap_bind_pw = bind-password&lt;br /&gt;
 ldap_user_type = MS ActiveDirectory&lt;br /&gt;
 ldap_contexts = ou=moodleusers,dc=example,dc=com&lt;br /&gt;
 ldap_user_attribute = sAMAccountName&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that the ldap_bind_dn value should work in either the CN=bin-user,CN=Users,DC=example,DC=com format as shown in the main instructions or the bind-user@example.com format shown in this example.&lt;br /&gt;
&lt;br /&gt;
==Global Catalogs==&lt;br /&gt;
Moodle currently only has limited support for multiple domain controllers; specifically it expects each of the LDAP servers listed to contain identical sets of information. If you have users in multiple domains this presents an issue. One solution when working with MS-AD is to use the Global Catalog. The Global Catalog is designed to be a read-only, partial representation of an entire MS-AD forest, designed for searching the entire directory when the domain of the required object is not known.&lt;br /&gt;
&lt;br /&gt;
===Enabling the Global Catalog===&lt;br /&gt;
&lt;br /&gt;
The Global Catalog is available on Windows 2000 and Windows 2003 Active Directory servers. To enable, open the ‘Active Directory Sites and Services’ MMC (Microsoft Management Console) snap-in. Extend ‘Sites’ and then the name of the Site containing the active directory forest you wish to use. Expand the server you wish to enable the Global Catalog on, right click ‘NTDS settings’ and select the ‘Properties’ tab. To enable, simply click the ‘Global Catalog’ checkbox. Under a Windows 2000 server it is necessary to restart the server (although it won’t prompt you to); under Windows 2003 server it is not necessary to restart the server. In either case you will generally have to wait for the AD forest to replicate before the Global Catalog offers a representation of the entire AD forest. Changes made in Active Directory will also be subject to a short delay due to the latency involved with replication. If your AD servers are firewalled port 3268 will need to be opened for Global Catalog servers.&lt;br /&gt;
If your organisation uses Microsoft Exchange then it its highly likely that at least one Domain Controller will already have Global Catalog enabled – Exchange 2000 and 2003 rely on the Global Catalog for address information, users also access the Global Catalog when using the GAL (Global Address List)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Child Domains===&lt;br /&gt;
If your organisation has a main domain example.org, staff and students are contained in two child domains staff.example.org and students.example.org. The 3 domains (example.org, staff.example.org and students.example.org) each have a domain controller (dc01, dc02 and dc03 respectively.) Each domain controller contains a full, writable, representation of only the objects that belong to its domain. However, assuming that the Global Catalog has been enabled (see below) on one of the domain controllers (for example dc01) a query to the Global Catalog would reveal matching objects from all three domains. The Global Catalog is automatically maintained through replication across the active directory forest, it can also be enabled on multiple servers (if, for example, you need redundancy / load balancing.)&lt;br /&gt;
&lt;br /&gt;
To make use of this in Moodle to allow logins from multiple domains is simple. The Global Catalog runs on port 3268 as opposed to 389 for standard LDAP queries. As a result, still assuming the Global Catalog is running on dc01, the &#039;&#039;&#039;&#039;ldap_host_url&#039;&#039;&#039;&#039; would be &#039;&#039;ldap://dc01.example.org:3268&#039;&#039;. The rest of the settings are the same as for other MS-AS Auth setups.&lt;br /&gt;
&lt;br /&gt;
You should use the &#039;&#039;&#039;&#039;ldap_contexts&#039;&#039;&#039;&#039; setting to indicate the locations of individuals you wish to grant access. To extend the example above a little: In the example.org domain users are all in the&#039;&#039; &#039;Users&#039; &#039;&#039;OU, in the staff.example.org domain users are in two OUs at the root of the domain,&#039;&#039; &#039;Support Staff&#039; &#039;&#039;and&#039;&#039; &#039;Teaching Staff&#039; &#039;&#039;, and in the students.example.org domain students are in an OU indicating the year that they enrolled, all of which are under the&#039;&#039; &#039;Students&#039; &#039;&#039;OU. As a result our &#039;&#039;&#039;&#039;ldap_contexts&#039;&#039;&#039;&#039; setting may look a little like this:&#039;&#039; &#039;OU=Users,DC=example,DC=org; OU=Support Staff,DC=staff,DC=example,DC=org; OU=Teaching Staff,DC=staff,DC=example,DC=org; OU=Students,DC=students,DC=example,DC=org&#039;&#039;.&#039; The &#039;&#039;&#039;&#039;ldap_search_sub&#039;&#039;&#039;&#039; option should be set to&#039;&#039; &#039;Yes&#039; &#039;&#039;to allow moodle to search within the child OUs.&lt;br /&gt;
&lt;br /&gt;
Its worth noting that the Global Catalog only contains a partial representation of the attributes of each object, as defined in the Partial Attribute Set supplied by Microsoft. However common information likely to be of use to a general Moodle installation (Forename, Surname, Email Address, sAMAccountName etc) is included in the set. For specific needs the schema can be altered to remove or add various attributes - see Microsoft [http://support.microsoft.com/kb/248717 KB248717] for more information.&lt;br /&gt;
&lt;br /&gt;
In most cases the Global Catalog is read-only, update queries must be made over the standard LDAP ports to the domain controller that holds the object in question (in our example, updating a student&#039;s details would require an LDAP query to the students.example.org domain controller - dc03, it would not be possible to update details by querying the Global Catalog.) The exception to this would be in an environment where there is only a single domain in the active directory forest; in this case the Global Catalog holds a writable full set of attributes for each object in the domain. However, for the purposes of Moodle authorisation, there would be no need to use the Global Catalog in this case.&lt;br /&gt;
&lt;br /&gt;
===MaxPageSize setting===&lt;br /&gt;
Modifying the number of Active Directory objects to search: &lt;br /&gt;
&lt;br /&gt;
By default Active Directory only allows searches returning a limited number of objects per search. Since there is currently no Page control support in PHP 5.2.x which would enable smaller page searches you may need to modify your MaxPageSize setting to make sure LDAP Client searches can return enough user objects to support the number of authenticating users. &lt;br /&gt;
&lt;br /&gt;
If you find that the script is not running through all of your users properly and you have MS Active Directory + over 1000 users, follow the instructions [http://support.microsoft.com/kb/315071 here] to set the MaxPageSize setting to a number higher than your total number of users (both now and in future) to fix it.  This is a forest-wide setting.&lt;br /&gt;
&lt;br /&gt;
==MS Active Directory + SSL ==&lt;br /&gt;
&lt;br /&gt;
If the Certificate Authority is not installed you&#039;ll have to install it first as follows:&lt;br /&gt;
# Click &#039;&#039;&#039;Start&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Control Panel&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Add or Remove programs.&#039;&#039;&#039;&lt;br /&gt;
# Click &#039;&#039;&#039;Add/Remove Windows Components&#039;&#039;&#039; and select &#039;&#039;&#039;Certificate Services.&#039;&#039;&#039;&lt;br /&gt;
# Follow the procedure provided to install the &#039;&#039;&#039;Certificate Authority&#039;&#039;&#039;. Enterprise level is a good choice.&lt;br /&gt;
&lt;br /&gt;
Verify that SSL has been enabled on the server by installing suptools.msi from Windows installation cd&#039;s \Support\tools directory. After support tools installation:&lt;br /&gt;
# Select &#039;&#039;&#039;Start&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Run&#039;&#039;&#039;, write &#039;&#039;&#039;ldp&#039;&#039;&#039; in the Open field.&lt;br /&gt;
# From the ldp window select &#039;&#039;&#039;Connection&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Connect&#039;&#039;&#039; and supply valid hostname and port number &#039;&#039;&#039;636&#039;&#039;&#039;. Also select the SSL check box.&lt;br /&gt;
&lt;br /&gt;
If successful, you should get information about the connection.&lt;br /&gt;
&lt;br /&gt;
See [[LDAP_authentication#Enabling_LDAPS_on_the_client_side_.28Moodle_server.29|Enabling LDAPS on the client side (Moodle server)]] for details on the client side configuration.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[[LDAP authentication]] in Moodle&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Directory_service Directory services] overview in Wikipedia&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol LDAP] in Wikipedia&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=17198 Using multiple LDAP servers - Our students are on separate domain] Using Moodle forum discussion&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=74279 How to use multiple LDAP servers with Moodle 1.8] Using Moodle forum discussion&lt;br /&gt;
&lt;br /&gt;
[[ja:Active Directory]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=93757</id>
		<title>Using the Microsoft SQL Server Driver for PHP</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=93757"/>
		<updated>2011-11-13T16:16:19Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: Updated driver link. Removed ref to &amp;quot;minimum version required is v1.1&amp;quot; V1.1 of th driver is deprecated.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Using the SQL Server Driver for PHP from Microsoft ==&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This short manual is for running Moodle 2.0 (and upwards) using the Microsoft SQL Server (MSSQL) RDBMS. The steps detailed below must be performed &#039;&#039;&#039;before&#039;&#039;&#039; installing Moodle itself.&lt;br /&gt;
&lt;br /&gt;
First of all, the minimum required version of MSSQL has been stabilized to MSSQL 2005 (v.9).&lt;br /&gt;
&lt;br /&gt;
== Installation overview ==&lt;br /&gt;
1. Install Microsoft SQL Server including SQL Server Management Studio. ([http://www.microsoft.com/sql/editions/express/default.mspx A free version, SQL Server Express Edition] is available for testing.)&lt;br /&gt;
:Make sure to choose mixed authentication (Windows and local accounts) to keep things simpler later.  Define the &amp;quot;sa&amp;quot; account password when requested (it&#039;s the default System Administrator account which has full access to all databases by default).&lt;br /&gt;
&lt;br /&gt;
2. Configure Windows for MSSQL.&lt;br /&gt;
:By default, MSSQL listens to port 1433 for incoming TCP/IP connections and this port needs to be opened in the firewall. This is explicitly configured in the firewall installed (either Windows Firewall in the Control Panel or the configuration interface for other firewalls). If the port was changed when MSSQL was installed, then specify the correct port number to open in the firewall.&lt;br /&gt;
:Confirm the TCP/IP protocol is enabled in: &#039;&#039;&#039;SQL Server Configuration Manager&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Network Configuration&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Protocols&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;TCP/IP enabled&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
3. Create and configure a new database.&lt;br /&gt;
:Open &amp;quot;SQL Server Management Studio&amp;quot; and create a new empty database.&lt;br /&gt;
*Execute the following command to enable Row Versioning:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 USE MASTER&lt;br /&gt;
 GO&lt;br /&gt;
 ALTER DATABASE &amp;amp;lt;your-database-name&amp;amp;gt; SET READ_COMMITTED_SNAPSHOT ON&lt;br /&gt;
 GO&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Install PHP and a web server.&lt;br /&gt;
*PHP can be downloaded from [http://www.php.net/downloads.php www.php.net]&lt;br /&gt;
*If IIS is used as the web server, IIS 7.0 or later is recommended with [http://www.iis.net/download FastCGI and WinCache]. &lt;br /&gt;
&lt;br /&gt;
5. Install the SQL Server Driver for PHP.&lt;br /&gt;
:On the web server, install [http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;amp;id=20098 SQL Server Driver for PHP] including all the pre-requisites listed on the download page. Note: it is critical to install the SQL Server Native Access Client version documented on the download page of the SQL Server Driver for PHP.&lt;br /&gt;
:Configure PHP to use the appropriate SQLSRV driver. In php.ini, set the following:&lt;br /&gt;
&lt;br /&gt;
For PHP 5.2.4 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 [PHP_SQLSRV]&lt;br /&gt;
 extension=php_sqlsrv_52_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For PHP 5.3.2 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 [PHP_SQLSRV]&lt;br /&gt;
 extension=php_sqlsrv_53_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Microsoft documentation for the SQL Server Driver for PHP is available at: http://msdn.microsoft.com/en-us/library/ee229548(v=SQL.10).aspx &lt;br /&gt;
&lt;br /&gt;
6. Install and configure Moodle.&lt;br /&gt;
:Continue with the [[Installing Moodle|standard Moodle installation]].&lt;br /&gt;
&lt;br /&gt;
7. The Moodle &#039;&#039;&#039;config.php&#039;&#039;&#039; should include lines like these:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;sqlsrv&#039;;         // Required&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;localhost&#039;;      // Assuming that MSSQL is on the same server, otherwise &lt;br /&gt;
                                    // use the actual name or IP address of your database server&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;moodle&#039;;         // The name of the newly created Moodle database&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // Usually the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  true;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;           // The prefix can be changed per individual preferences, &lt;br /&gt;
                                    // but NEVER leave this blank!&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:If the config.php file doesn&#039;t exist, it will be generated as normal from the Moodle installer. Alternatively, use the config-dist.php file that comes with the Moodle package to create a custom config.php file.&lt;br /&gt;
&lt;br /&gt;
8. Restart or start your web server.&lt;br /&gt;
:If Moodle still cannot communicate with the database server, turn &#039;&#039;&#039;display_startup_errors&#039;&#039;&#039; to &amp;quot;On&amp;quot; in the /PHP/php.ini file, then restart the web server and check for any errors that may indicate incorrect DLL versions or missing dependencies.  These error reports, turned off by default in PHP, can be vital in locating a problem with new extension installations.&lt;br /&gt;
&lt;br /&gt;
9. Test the database connection.&lt;br /&gt;
:Try this PHP script, just add a text file called test.php from the example below and change (&#039;localhost&#039;, &#039;db_user&#039;, &#039;db_password&#039;) to align with the config.php settings, and load from local host (http://localhost/test.php).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$link = sqlsrv_connect($this-&amp;gt;dbhost, array(&#039;UID&#039; =&amp;gt; &#039;db_user&#039;, &#039;PWD&#039; =&amp;gt; &#039;db_password&#039;));&lt;br /&gt;
if($link === FALSE) {&lt;br /&gt;
    echo &#039;Could not connect&#039;;&lt;br /&gt;
    die(&#039;Could not connect: &#039; . sqlsrv_errors(SQLSRV_ERR_ALL));&lt;br /&gt;
}&lt;br /&gt;
echo &#039;Successful connection&#039;;&lt;br /&gt;
sqlsrv_close($link);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
10. Complete the rest of the Moodle installation as usual.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Installing Moodle]]&lt;br /&gt;
* [[Errors FAQ]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum]&lt;br /&gt;
* [[Beginning Administration FAQ]]&lt;br /&gt;
* [[Installing Postgres for PHP]]&lt;br /&gt;
* [[Installing MSSQL for PHP]]&lt;br /&gt;
* [[Installing Oracle for PHP]]&lt;br /&gt;
* Microsoft SQL Server Driver for PHP solves major Moodle performance problems. See: [http://moodle.org/mod/forum/discuss.php?d=183987 Hardware and Performance Forum]&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:XMLDB]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Performance_recommendations&amp;diff=92459</id>
		<title>Performance recommendations</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Performance_recommendations&amp;diff=92459"/>
		<updated>2011-10-21T08:55:21Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* PHP performance - WinCache */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Performance}}&lt;br /&gt;
Moodle can be made to perform very well, at small usage levels or scaling up to many thousands of users. The factors involved in performance are basically the same as for any PHP-based database-driven system. When trying to optimize your server, try to focus on the factor which will make the most difference to the user. For example, if you have relatively more users browsing than accessing the database, look to improve the webserver performance.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Obtain a baseline benchmark==&lt;br /&gt;
&lt;br /&gt;
Before attempting any optimization, you should obtain a baseline benchmark of the component of the system you are trying to improve. For Linux try [http://lbs.sourceforge.net/ LBS] and for Windows use the Performance Monitor. Once you have quantitative data about how your system is performing currently, you&#039;ll be able to determine if the change you have made has had any real impact.&lt;br /&gt;
&lt;br /&gt;
The overall aim of adjustments to improve performance is to use RAM (cacheing) and to reduce disk-based activity. It is especially important to try to eliminate swap file usage as much as you can. If your system starts swapping, this is a sign that you need more RAM. &lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;optimization order preference&#039;&#039;&#039; is usually: primary storage (more RAM), secondary storage (faster hard disks/improved hard disk configuration), processor (more and faster).&lt;br /&gt;
&lt;br /&gt;
==Scalability==&lt;br /&gt;
&lt;br /&gt;
Moodle&#039;s design (with clear separation of application layers) allows for strongly scalable setups. (Please check the list of [[Large installations|large Moodle installations]].)&lt;br /&gt;
&lt;br /&gt;
Large sites usually separate the web server and database onto separate servers, although for smaller installations this is typically not necessary.&lt;br /&gt;
&lt;br /&gt;
It is possible to load-balance a Moodle installation, for example by using more than one webserver. The separate webservers should query the same database and refer to the same filestore area, but otherwise the separation of the application layers is complete enough to make this kind of clustering feasible. Similarly, the database could be a cluster of servers (e.g. a MySQL cluster), but this is not an easy task and you should seek expert support, e.g. from a Moodle Partner.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;See also&#039;&#039;&#039;: &lt;br /&gt;
*[[Server cluster]]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=4801 Scalability] forum discussion.&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=57202 Moodle clustering] forum discussion.&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=44470 Software load balancing] forum discussion.&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=49986 TCP load balancing] forum dicsussion.&lt;br /&gt;
&lt;br /&gt;
==Hardware configuration==&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: The fastest and most effective change that you can make to improve performance is to &#039;&#039;&#039;increase the amount of RAM on your web server&#039;&#039;&#039; - get as much as possible (eg 4GB). Increasing primary memory will reduce the need for processes to swap to disk and will enable your server to handle more users.&lt;br /&gt;
* Better performance is gained by obtaining the best &#039;&#039;&#039;processor capability&#039;&#039;&#039; you can, i.e. dual or dual core processors. A modern BIOS should allow you to enable hyperthreading, but check if this makes a difference to the overall performance of the processors by using a [http://en.wikipedia.org/wiki/Super_PI CPU benchmarking tool].&lt;br /&gt;
* If you can afford them, use &#039;&#039;&#039;SCSI hard disks&#039;&#039;&#039; instead of SATA drives. SATA drives will increase your system&#039;s CPU utilization, whereas SCSI drives have their own integrated processors and come into their own when you have multiple drives. If you must have SATA drives, check that your motherboard and the drives themselves support NCQ (Native Command Queuing).&lt;br /&gt;
* Purchase hard disks with a &#039;&#039;&#039;low seek time&#039;&#039;&#039;. This will improve the overall speed of your system, especially when accessing Moodle&#039;s reports.&lt;br /&gt;
* Size your &#039;&#039;&#039;swap file&#039;&#039;&#039; correctly. The general advice is to set it to 4 x physical RAM.&lt;br /&gt;
* Use a &#039;&#039;&#039;RAID disk system&#039;&#039;&#039;. Although there are many different RAID configurations you can create, the following generally works best:&lt;br /&gt;
** install a hardware RAID controller (if you can)&lt;br /&gt;
** the operating system and swap drive on one set of disks configured as RAID-1.&lt;br /&gt;
** Moodle, Web server and Database server on another set of disks configured as RAID-5.&lt;br /&gt;
* Use &#039;&#039;&#039;gigabit ethernet&#039;&#039;&#039; for improved latency and throughput. This is especially important when you have your webserver and database server separated out on different hosts.&lt;br /&gt;
* Check the settings on your &#039;&#039;&#039;network card&#039;&#039;&#039;. You may get an improvement in performance by increasing the use of buffers and transmit/receive descriptors (balance this with processor and memory overheads) and off-loading TCP checksum calculation onto the card instead of the OS.&lt;br /&gt;
*  Read this [http://moodle.org/mod/forum/discuss.php?d=68579 Case Study] on a server stress test with 300 users.  &lt;br /&gt;
* See this [http://elearning.sgu.ac.jp/doc/PT/ accompanying report] on network traffic and server loads.&lt;br /&gt;
* See the [[Moodle.org configuration]]&lt;br /&gt;
* Also see this SFSU presentation at Educause (using VMWare): [http://www.educause.edu/Resources/AnOpenSourceLMSforaMissionCrit/162843]&lt;br /&gt;
&lt;br /&gt;
==Operating System==&lt;br /&gt;
* You can use [http://en.wikipedia.org/wiki/Linux Linux](recommended), Unix-based, Windows or Mac OS X for the server &#039;&#039;&#039;operating system&#039;&#039;&#039;. *nix operating systems generally require less memory than Mac OS X or Windows servers for doing the same task as the server is configured with just a shell interface. Additionally Linux does not have licensing fees attached, but can have a big learning curve if you&#039;re used to another operating system. If you have a large number of processors running SMP, you may also want to consider using a highly tuned OS such as [http://en.wikipedia.org/wiki/Solaris_Operating_Environment Solaris].&lt;br /&gt;
* Check your own OS and &#039;&#039;&#039;vendor specific instructions&#039;&#039;&#039; for optimization steps.&lt;br /&gt;
** For Linux look at the [http://linuxperf.sourceforge.net/ Linux Performance Team] site. &lt;br /&gt;
** For Linux investigate the hdparm command, e.g. hdparm -m16 -d1 can be used to enable read/write on multiple sectors and DMA. Mount disks with the async and noatime options.&lt;br /&gt;
** For Windows set the sever to be optimized for network applications (Control Panel, Network Connections, LAN connection, Properties, File &amp;amp; Printer Sharing for Microsoft Networks, Properties, Optimization). You can also search the [http://technet.microsoft.com/ Microsoft TechNet site] for optimization documents.&lt;br /&gt;
&lt;br /&gt;
==Web server performance==&lt;br /&gt;
&lt;br /&gt;
Installing [http://www.mozilla.com/en-US/ Firefox] and the [https://addons.mozilla.org/en-US/firefox/addon/1843 firebug] extension will allow you to watch the time it takes for each page component to load. Also, the [https://addons.mozilla.org/en-US/firefox/addon/5369 Yslow] extension will evaluate your page against Yahoo&#039;s [http://www.skrenta.com/2007/05/14_rules_for_fast_web_pages_by_1.html 14 rules], full text [http://developer.yahoo.com/performance/rules.html Best Practices for Speeding Up Your Web Site], &amp;lt;strike&amp;gt;([http://video.yahoo.com/video/play?vid=1040890 video])&amp;lt;/strike&amp;gt; for fast loading websites.&lt;br /&gt;
&lt;br /&gt;
===PHP performance===&lt;br /&gt;
* You are strongly recommended to use a &#039;&#039;&#039;PHP accelerator&#039;&#039;&#039; to ease CPU load, such as [http://pecl.php.net/apc APC], [http://www.php-accelerator.co.uk/ PHPA], [http://trac.lighttpd.net/xcache/ Xcache], [http://sourceforge.net/projects/wincache WinCache] or [http://eaccelerator.net/ eAccelerator]. (Take care to choose a PHP accelerator that is known to work well with your version of PHP and note that Turck MMCache is [http://turckmmcache.exeprod.com/TheManifestoEnglish no longer maintained] and can cause failures with PHP 5). &lt;br /&gt;
* Improvements in read/write performance can be improved by putting the cached PHP pages on a [[TMPFS]] filesystem - but remember that you&#039;ll lose the cache contents when there is a power failure or the server is rebooted.&lt;br /&gt;
* Performance of PHP is better when installed as an &#039;&#039;&#039;Apache/IIS ISAPI module&#039;&#039;&#039; (rather than a CGI).&lt;br /&gt;
* Also check the &#039;&#039;&#039;memory_limit&#039;&#039;&#039; in php.ini, reduce it to 16M for Moodle version earlier than 1.7 ([http://moodle.org/mod/forum/discuss.php?d=39656 See this forum discussion]). For Moodle 1.7 or later, it is recommended that the value of memory_limit should be 40M. As of [http://www.php.net/ChangeLog-5.php PHP 5.2.1] the default value for the memory_limit directive is 128M.&lt;br /&gt;
* Also see [[PHP_settings_by_Moodle_version]]&lt;br /&gt;
&lt;br /&gt;
===Install HowTo===&lt;br /&gt;
* [http://2bits.com/articles/installing-php-apc-gnulinux-centos-5.html APC on CentOS 5.x (linux)]&lt;br /&gt;
* [http://fplanque.com/dev/linux/install-apc-php-cache-debian-lenny APC on Debian (linux)]&lt;br /&gt;
* [http://www.linuxtuts.net/211-installing-memcached-php5-memcache-module-debian-apache2.html MemCache module on Debian (Apache2 and PHP5) ]&lt;br /&gt;
* [http://noveckg.blogspot.com/2010/03/installing-memcached-on-centos-5x.html Installing Memcache on CentOS 5.x (linux)]&lt;br /&gt;
* [http://noveckg.blogspot.com/2010/02/installing-eaccelerator-cache-for-php.html Installing eAccelerator on CentOS 5.x (linux)]&lt;br /&gt;
* [https://docs.moodle.org/en/Installing_eAccelerator_In_Ubuntu_Server/ Installing eAccelerator on Ubuntu Server (linux)]&lt;br /&gt;
&lt;br /&gt;
===Apache performance===&lt;br /&gt;
* If you are using Apache on a Windows server, use the build from [http://www.apachelounge.com Apache Lounge] which is reported to have [http://moodle.org/mod/forum/discuss.php?d=93358 performance and stability improvements] compared to the official Apache download. Note that this is an unofficial build, so may not keep up with official releases.&lt;br /&gt;
* Set the &#039;&#039;&#039;MaxClients&#039;&#039;&#039; directive correctly. Use this formula to help (which uses 80% of available memory to leave room for spare):&lt;br /&gt;
 MaxClients = Total available memory * 80% / Max memory usage of apache process&lt;br /&gt;
:Memory usage of apache process is usually 10MB, so a general rule of thumb is to divide your available memory in megabytes by 10 to get the value of MaxClients. To find the max memory usage of apache processes read the value from the shell command:&lt;br /&gt;
 #ps -ylC httpd --sort:rss&lt;br /&gt;
&lt;br /&gt;
:If you need to increase the value of &#039;&#039;&#039;MaxClients&#039;&#039;&#039; beyond 256, you will also need to set the &#039;&#039;&#039;ServerLimit&#039;&#039;&#039; directive. &lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Warning&#039;&#039;&#039;: Do not be tempted to set the value of MaxClients higher than your available memory as your server will consume more RAM than available and start to swap to disk. &lt;br /&gt;
* Consider reducing the &#039;&#039;&#039;number of modules&#039;&#039;&#039; that Apache loads in the httpd.conf file to the minumum necessary to reduce the memory needed. &lt;br /&gt;
* Use the &#039;&#039;&#039;latest version of Apache&#039;&#039;&#039; - Apache 2 has an improved memory model which reduces memory usage further.&lt;br /&gt;
* For Unix/Linux systems, consider lowering &#039;&#039;&#039;MaxRequestsPerChild&#039;&#039;&#039; in httpd.conf to as low as 20-30 (if you set it any lower the overhead of forking begins to outweigh the benefits). &lt;br /&gt;
* For a heavily loaded server, consider setting &#039;&#039;&#039;KeepAlive Off&#039;&#039;&#039; (do this only if your Moodle pages do not contain links to resources or uploaded images) or lowering the &#039;&#039;&#039;KeepAliveTimeout&#039;&#039;&#039; to between 2 and 5. The default is 15 (seconds) - the higher the value the more server processes will be kept waiting for possibly idle connections. A more accurate value for KeepAliveTimeout is obtained by observing how long it takes your users to download a page. After altering any of the KeepAlive variables, monitor your CPU utilization as there may be an additional overhead in initiating more worker processes/threads.&lt;br /&gt;
* As an alternative to using KeepAlive Off, consider setting-up a &#039;&#039;&#039;Reverse Proxy server&#039;&#039;&#039; infront of the Moodle server to cache HTML files with images. You can then return Apache to using keep-alives on the Moodle server.&lt;br /&gt;
* If you do not use a .htaccess file, set the &#039;&#039;&#039;AllowOverride&#039;&#039;&#039; variable to AllowOverride None to prevent .htaccess lookups.&lt;br /&gt;
* Set &#039;&#039;&#039;DirectoryIndex&#039;&#039;&#039; correctly so as to avoid content-negotiation. Here&#039;s an example from a production server:&lt;br /&gt;
 DirectoryIndex index.php index.html index.htm&lt;br /&gt;
* Unless you are doing development work on the server, set &#039;&#039;&#039;ExtendedStatus Off&#039;&#039;&#039; and disable mod_info as well as mod_status.&lt;br /&gt;
* Leave &#039;&#039;&#039;HostnameLookups Off&#039;&#039;&#039; (as default) to reduce DNS latency.&lt;br /&gt;
* Consider reducing the value of &#039;&#039;&#039;TimeOut&#039;&#039;&#039; to between 30 to 60 (seconds). &lt;br /&gt;
* For the &#039;&#039;&#039;Options directive&#039;&#039;&#039;, avoid Options Multiviews as this performs a directory scan. To reduce disk I/O further use&lt;br /&gt;
 Options -Indexes FollowSymLinks&lt;br /&gt;
*&#039;&#039;&#039;Caching (unsupported)&#039;&#039;&#039; - &#039;&#039;Please note that this kind of caching may create major problems during upgrades.&#039;&#039; Apache can be told to make pages load a lot faster by specifying that the browser should cache some various page elements such as images and reuse them from local memory rather than ask for them again every time a page is requested. How to do this varies slightly between OSes but there are two basic steps:&lt;br /&gt;
&lt;br /&gt;
# Install and enable mod_expires - refer to documentation or man pages&lt;br /&gt;
# Add this code to the virtual server config file within the &amp;lt;directory&amp;gt; section for the root directory (or within the .htaccess file if AllowOverrides is On):&lt;br /&gt;
 &amp;lt;IfModule mod_expires.c&amp;gt;&lt;br /&gt;
  ExpiresActive On&lt;br /&gt;
  ExpiresDefault &amp;quot;access plus 1 seconds&amp;quot;&lt;br /&gt;
  ExpiresByType text/html &amp;quot;access plus 1 seconds&amp;quot;&lt;br /&gt;
  ExpiresByType image/gif &amp;quot;access plus 1 week&amp;quot;&lt;br /&gt;
  ExpiresByType image/jpeg &amp;quot;access plus 1 week&amp;quot;&lt;br /&gt;
  ExpiresByType image/png &amp;quot;access plus 1 week&amp;quot;&lt;br /&gt;
  ExpiresByType text/css &amp;quot;access plus 1 week&amp;quot;&lt;br /&gt;
  ExpiresByType text/javascript &amp;quot;access plus 1 week&amp;quot;&lt;br /&gt;
  ExpiresByType application/x-javascript &amp;quot;access plus 1 week&amp;quot;&lt;br /&gt;
  ExpiresByType text/xml &amp;quot;access plus 1 seconds&amp;quot;&lt;br /&gt;
 &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The effect is to make everything stay in the cache except HTML and XML, which change dynamically. It&#039;s possible to gain a several hundred percent decrease in load times this way. Adjust the cache times according to how often your images etc change.&lt;br /&gt;
&lt;br /&gt;
* Compression reduces response times by reducing the size of the HTTP response&lt;br /&gt;
# Install and enable mod_deflate - refer to documentation or man pages&lt;br /&gt;
# Add this code to the virtual server config file within the &amp;lt;directory&amp;gt; section for the root directory (or within the .htaccess file if AllowOverrides is On):&lt;br /&gt;
 &amp;lt;ifModule mod_deflate.c&amp;gt;&lt;br /&gt;
   AddOutputFilterByType DEFLATE text/html text/plain text/xml&lt;br /&gt;
 &amp;lt;/ifmodule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: [http://www.metaskills.net/blog/heuristics/sysadmin/how-to-control-browser-caching-with-apache-2 www.metaskills.net]&lt;br /&gt;
&lt;br /&gt;
===IIS performance===&lt;br /&gt;
All alter this location in the registry:&lt;br /&gt;
 HKLM\SYSTEM\CurrentControlSet\Services\Inetinfo\Parameters\&lt;br /&gt;
* The equivalent to KeepAliveTimeout is &#039;&#039;&#039;ListenBackLog&#039;&#039;&#039; (IIS - registry location is HKLM\ SYSTEM\ CurrentControlSet\ Services\ Inetinfo\ Parameters). Set this to between 2 to 5.&lt;br /&gt;
*Change the &#039;&#039;&#039;MemCacheSize&#039;&#039;&#039; value to adjust the amount of memory (Mb) that IIS will use for its file cache (50% of available memory by default).&lt;br /&gt;
*Change the &#039;&#039;&#039;MaxCachedFileSize&#039;&#039;&#039; to adjust the maximum size of a file cached in the file cache in bytes. Default is 262,144 (256K).&lt;br /&gt;
*Create a new DWORD called &#039;&#039;&#039;ObjectCacheTTL&#039;&#039;&#039; to change the length of time (in milliseconds) that objects in the cache are held in memory. Default is 30,000 milliseconds (30 seconds).&lt;br /&gt;
&lt;br /&gt;
===Lighttpd, NginX and Cherokee performance===&lt;br /&gt;
You can increase server performance by using a &#039;&#039;&#039;light-weight&#039;&#039;&#039; webserver like [http://www.lighttpd.net/ lighttpd],  [http://nginx.net/ nginx] or [http://www.cherokee-project.com/ cherokee] in combination with PHP in FastCGI-mode. Lighttpd was originally created as a proof-of-concept[http://www.lighttpd.net/story] to address the [http://www.kegel.com/c10k.html C10k problem] and while primarily recommended for memory-limited servers, its design origins and asynchronous-IO model make it a suitable and proven[http://blog.lighttpd.net/articles/2006/12/28/lighttpd-powers-5-alexa-top-250-sites] alternative HTTP server for high-load websites and web apps, including Moodle. See the [[lighttpd | MoodleDocs Lighttpd page]] for additional information, configuration example and links.&lt;br /&gt;
&lt;br /&gt;
Alternatively, both [http://www.lighttpd.net/ lighttpd] and [http://nginx.net/ nginx] are capable of performing as a load-balancer and/or reverse-proxy to alleviate load on back-end servers[http://www.linuxjournal.com/article/10108], providing benefit without requiring an actual software change on existing servers.&lt;br /&gt;
&lt;br /&gt;
Do note that these are likely to be the least tested server environments of all particularly if you are using advanced features such as web services and/or Moodle Networking. They are probably best considered for heavily used Moodle sites with relatively simple configurations.&lt;br /&gt;
&lt;br /&gt;
==Database performance==&lt;br /&gt;
&lt;br /&gt;
Moodle contains a script which will display some key database performance statistics from the [http://phplens.com/lens/adodb/docs-perf.htm ADOdb performance monitor]. Run the script in your browser as in the following example:&lt;br /&gt;
&lt;br /&gt;
 http://www.mymoodle.com/admin/dbperformance.php&lt;br /&gt;
&lt;br /&gt;
Use the data displayed as a guide to tune and improve the performance of your database server.&lt;br /&gt;
&lt;br /&gt;
===MySQL performance===&lt;br /&gt;
&lt;br /&gt;
The following are MySQL specific settings which can be adjusted for better performance in your my.cnf (my.ini in Windows). The file contains a list of settings and their values. To see the current values use these commands&lt;br /&gt;
 SHOW STATUS;&lt;br /&gt;
 SHOW VARIABLES; &lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039;: You must make backups of your database before attempting to change any MySQL server configuration. After any change to the my.cnf, restart mysqld.&lt;br /&gt;
&lt;br /&gt;
If you are able, the [http://mysqltuner.com/ MySQLTuner] tool can be run against your MySQL server and will calculate appropriate configuration values for most of the following settings based on your current load, status and variables automatically.&lt;br /&gt;
&lt;br /&gt;
* Enable the &#039;&#039;&#039;query cache&#039;&#039;&#039; with &lt;br /&gt;
 query_cache_type = 1. &lt;br /&gt;
For most Moodle installs, set the following:&lt;br /&gt;
 query_cache_size = 36M &lt;br /&gt;
 query_cache_min_res_unit = 2K. &lt;br /&gt;
The query cache will improve performance if you are doing few updates on the database. &lt;br /&gt;
* Set the &#039;&#039;&#039;table cache&#039;&#039;&#039; correctly. For Moodle 1.6 set &lt;br /&gt;
 table_cache = 256 #(table_open_cache in MySQL &amp;gt; 5.1.2)&lt;br /&gt;
(min), and for Moodle 1.7 set &lt;br /&gt;
 table_cache = 512 #(table_open_cache in MySQL &amp;gt; 5.1.2)&lt;br /&gt;
(min). The table cache is used by all threads (connections), so monitor the value of opened_tables to further adjust - if opened_tables &amp;gt; 3 * table_cache(table_open_cache in MySQL &amp;gt; 5.1.2) then increase table_cache upto your OS limit. Note also that the figure for table_cache will also change depending on the number of modules and plugins you have installed. Find the number for your server by executing the mysql statement below. Look at the number returned and set table_cache to this value.&lt;br /&gt;
 mysql&amp;gt;SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema=&#039;yourmoodledbname&#039;;&lt;br /&gt;
* Set the &#039;&#039;&#039;thread cache&#039;&#039;&#039; correctly. Adjust the value so that your thread cache utilization is as close to 100% as possible by this formula:&lt;br /&gt;
 thread cache utilization (%) = (threads_created / connections) * 100&lt;br /&gt;
* The &#039;&#039;&#039;key buffer&#039;&#039;&#039; can improve the access speed to Moodle&#039;s SELECT queries. The correct size depends on the size of the index files (.myi) and in Moodle 1.6 or later (without any additional modules and plugins), the recommendation for this value is key_buffer_size = 32M. Ideally you want the database to be reading once from the disk for every 100 requests so monitor that the value is suitable for your install by adjusting the value of key_buffer_size so that the following formulas are true:&lt;br /&gt;
 key_read / key_read_requests &amp;lt; 0.01&lt;br /&gt;
 key_write / key_write_requests &amp;lt;= 1.0&lt;br /&gt;
* Set the &#039;&#039;&#039;maximum number of connections&#039;&#039;&#039; so that your users will not see a &amp;quot;Too many connections&amp;quot; message. Be careful that this may have an impact on the total memory used. MySQL connections usually last for milliseconds, so it is unusual even for a heavily loaded server for this value to be over 200.&lt;br /&gt;
* Manage &#039;&#039;&#039;high burst activity&#039;&#039;&#039;. If your Moodle install uses a lot of quizzes and you are experiencing performance problems (check by monitoring the value of threads_connected - it should not be rising) consider increasing the value of back_log.&lt;br /&gt;
* &#039;&#039;&#039;Optimize your tables weekly and after upgrading Moodle&#039;&#039;&#039;. It is good practice to also optimize your tables after performing a large data deletion exercise, e.g. at the end of your semester or academic year. This will ensure that index files are up to date. Backup your database first and then use:&lt;br /&gt;
 mysql&amp;gt;CHECK TABLE mdl_tablename;&lt;br /&gt;
 mysql&amp;gt;OPTIMIZE TABLE mdl_tablename;&lt;br /&gt;
:The common tables in Moodle to check are mdl_course_sections, mdl_forum_posts, mdl_log and mdl_sessions (if using dbsessions). Any errors need to be corrected using REPAIR TABLE (see the [http://dev.mysql.com/doc/refman/5.0/en/repair-table.html MySQL manual] and this [http://moodle.org/mod/forum/discuss.php?d=58208#p279638 forum script]).&lt;br /&gt;
* &#039;&#039;&#039;Maintain the key distribution&#039;&#039;&#039;. Every month or so it is a good idea to stop the mysql server and run these myisamchk commands.&lt;br /&gt;
 #myisamchk -a -S /pathtomysql/data/moodledir/*.MYI&lt;br /&gt;
:&#039;&#039;&#039;Warning&#039;&#039;&#039;: You must stop the mysql database process (mysqld) before running any myisamchk command. If you do not, you risk data loss.&lt;br /&gt;
* Reduce the number of &#039;&#039;&#039;temporary tables saved to disk&#039;&#039;&#039;. Check this with the created_tmp_disk_tables value. If this is relatively large (&amp;gt;5%) increase tmp_table_size until you see a reduction. Note that this will have an impact on RAM usage.&lt;br /&gt;
&lt;br /&gt;
===PostgreSQL performance===&lt;br /&gt;
&lt;br /&gt;
There are some good papers around on tuning PostgreSQL, and Moodle&#039;s case does not seem to be different to the general case.&lt;br /&gt;
&lt;br /&gt;
The first thing to recognise is that if you really need to worry about tuning you should be using a separate machine for the database server. If you are not using a separate machine then the answers to many performance questions are substantially muddied by the memory requirements of the rest of the application.&lt;br /&gt;
&lt;br /&gt;
You should probably &#039;&#039;&#039;enable autovacuum&#039;&#039;&#039;, unless you know what you are doing. Many e-learning sites have predictable periods of low use, so disabling autovacuum and running a specific vacuum at those times can be a good option. Or perhaps leave autovacuum running but do a full vacuum weekly in a quiet period.&lt;br /&gt;
&lt;br /&gt;
Set &#039;&#039;&#039;shared_buffers&#039;&#039;&#039; to something reasonable. For versions up to 8.1 my testing has shown that peak performance is almost always obtained with buffers &amp;lt; 10000, so if you are using such a version, and have more than 512M of RAM just set shared_buffers to 10,000 (8MB).&lt;br /&gt;
&lt;br /&gt;
The buffer management had a big overhaul in 8.2 and &amp;quot;reasonable&amp;quot; is now a much larger number. I have not conducted performance tests with 8.2, but the recommendations from others are generally that you should now scale shared_buffers much more with memory and may continue to reap benefits even up to values like 100,000 (80MB). Consider using 1-2% of system RAM.&lt;br /&gt;
&lt;br /&gt;
PostgreSQL will also assume that the operating system is caching its files, so setting &#039;&#039;&#039;effective_cache_size&#039;&#039;&#039; to a reasonable value is also a good idea. A reasonable value will usually be (total RAM - RAM in use by programs). If you are running Linux and leave the system running for a day or two you can look at &#039;free&#039; and under the &#039;cached&#039; column you will see what it currently is. Consider taking that number (which is kB) and dividing it by 10 (i.e. allow 20% for other programs cache needs and then divide by 8 to get pages). If you are not using a dedicated database server you will need to decrease that value to account for usage by other programs.&lt;br /&gt;
&lt;br /&gt;
Some other useful parameters that can have positive effects, and the values I would typically set them to on a machine with 4G RAM, are:&lt;br /&gt;
&lt;br /&gt;
 work_mem = 10240&lt;br /&gt;
&lt;br /&gt;
That&#039;s 10M of RAM to use instead of on-disk sorting and so forth. That can give a big speed increase, but it is per connection and 200 connections * 10M is 2G, so it can theoretically chew up a lot of RAM.&lt;br /&gt;
&lt;br /&gt;
 maintenance_work_mem = 163840&lt;br /&gt;
&lt;br /&gt;
That&#039;s 160M of RAM which will be used by (e.g.) VACUUM, index rebuild, cluster and so forth. This should only be used periodically and should be freed when those processes exit, so I believe it is well worth while.&lt;br /&gt;
&lt;br /&gt;
 max_fsm_pages = 100000&lt;br /&gt;
 max_fsm_relations = 5000&lt;br /&gt;
&lt;br /&gt;
These are used to hold the free-space map, and if they are too small you will see performance degradation after the database has been operating for some time. The exact numbers to set can be gleaned from the output of VACUUM VERBOSE, which prints the required FSM pages at the end of it&#039;s run. The 5x increase seems to be useful for a Moodle installation, from experience.&lt;br /&gt;
&lt;br /&gt;
 wal_buffers = 64&lt;br /&gt;
&lt;br /&gt;
These buffers are used for the write-ahead log, and there have been a number of reports on the PostgreSQL mailing lists of improvement from this level of increase.&lt;br /&gt;
&lt;br /&gt;
This is a little out of date now (version 8.0) but still worth a read: http://www.powerpostgresql.com/Docs&lt;br /&gt;
&lt;br /&gt;
And there is lots of good stuff here as well: http://www.varlena.com/GeneralBits/Tidbits/index.php&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Based on Andrew McMillan&#039;s post at [http://moodle.org/mod/forum/discuss.php?d=68558 Tuning PostgreSQL] forum thread.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Other database performance links===&lt;br /&gt;
* Consider using a &#039;&#039;&#039;distributed cacheing system&#039;&#039;&#039; like [http://en.wikipedia.org/wiki/Memcached memcached] but note that memcached does not have any security features so it should be used behind a firewall.&lt;br /&gt;
* Consider using PostgreSQL. See [[Arguments in favour of PostgreSQL]] and [http://moodle.org/mod/forum/discuss.php?d=49195 how to migrate from MySQL to PostgreSQL] (forum discussion).&lt;br /&gt;
* [[Increasing the database connection lifetime | Try increasing the database connection lifetime]]&lt;br /&gt;
* [http://dev.mysql.com/doc/refman/5.0/en/server-parameters.html General advice on tuning MySQL parameters] (advice from the MySQL manual)&lt;br /&gt;
* [http://www.mysqlperformanceblog.com/2007/11/01/innodb-performance-optimization-basics/ InnoDB performance optimization] taken from the [http://www.mysqlperformanceblog.com/ MySQL performance blog] site.&lt;br /&gt;
&lt;br /&gt;
==Performance of different Moodle modules==&lt;br /&gt;
&lt;br /&gt;
Moodle&#039;s activity modules, filters, and other plugins can be activated/deactivated. If necessary, you may wish to deactivate some features (such as chat) if not required - but this isn&#039;t necessary. Some notes on the performance of certain modules:&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;Chat&#039;&#039;&#039; module is [http://moodle.org/mod/forum/discuss.php?d=37979&amp;amp;parent=175079 said] to be a hog in terms of frequent HTTP requests to the main server. This can be reduced by setting the module to use &#039;&#039;Streamed&#039;&#039; updates, or, if you&#039;re using a Unix-based webserver, by running the chat in daemon mode. When using the Chat module use the configuration settings to tune for your expected load. Pay particular attention to the &#039;&#039;chat_old_ping&#039;&#039; and &#039;&#039;chat_refresh&#039;&#039; parameters as these can have greatest impact on server load.&lt;br /&gt;
* The &#039;&#039;&#039;Quiz&#039;&#039;&#039; module is known to stretch database performance. Try to optimise your database server by tuning. See [http://moodle.org/mod/forum/discuss.php?d=25616&amp;amp;parent=120770 for a brief report on performance for 55 students simultaneously using quizzes]&lt;br /&gt;
** See this Case Study for an extensive server stress test with 300 quiz users.[http://moodle.org/mod/forum/discuss.php?d=68579]  And this accompanying report on network traffic and server loads. [http://elearning.sgu.ac.jp/doc/PT/]&lt;br /&gt;
* The Moodle &#039;&#039;&#039;Cron&#039;&#039;&#039; task is triggered by calling the script &#039;&#039;cron.php&#039;&#039;. If this is called over HTTP (e.g. using wget or curl) it can take a large amount of memory on large installations. If it is called by directly invoking the php command (e.g. &#039;&#039;php -f /path/to/moodle/directory/admin/cron.php&#039;&#039;) efficiency can be much improved.&lt;br /&gt;
* The &#039;&#039;&#039;Recent activities&#039;&#039;&#039; block is consuming to much resources if you have huge number of records &amp;lt;code&amp;gt;mdl_log&amp;lt;/code&amp;gt;. this is being tested to optimize the SQL query.&lt;br /&gt;
&lt;br /&gt;
==Moodle Image Optimization==&lt;br /&gt;
&lt;br /&gt;
The base images delivered in the original Moodle distribution package provide unoptimized graphics, most of which can benefit from lossless recompression utilizing [http://optipng.sourceforge.net/ optipng] for PNGs, [http://www.lcdf.org/gifsicle/ gifsicle] for GIFs and [http://www.kokkonen.net/tjko/projects.html jpegoptim] for JPGs.  Optimized graphics transfer faster and provide a faster perceived response for clients[http://www.websiteoptimization.com/speed/12/], especially distance learners.  The following example will recursively optimize (without any loss of quality) all the graphics and image files included in a base Moodle installation directory on a server with the above commands installed and available.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
find /example/directory/moodle-1.9 -iname *.png -exec optipng -o7 {} \;&lt;br /&gt;
find /example/directory/moodle-1.9 -iname *.gif -exec gifsicle -O2 -b {} \;&lt;br /&gt;
find /example/directory/moodle-1.9 -iname *.jpg -exec jpegoptim -p {} \;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both [http://optipng.sourceforge.net/ optipng] and [http://www.lcdf.org/gifsicle/ gifsicle] are provided in the base repositories of most newer Linux distributions; [http://www.kokkonen.net/tjko/projects.html jpegoptim] must be downloaded and installed manually.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*Using Moodle: [http://moodle.org/mod/forum/view.php?f=94 Hardware and Performance] forum&lt;br /&gt;
&lt;br /&gt;
There have been a lot of discussions on moodle.org about performance, here are some of the more interesting and (potentially) useful ones:&lt;br /&gt;
&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=83057 Performance woes!]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=57028 Performance perspectives - a little script]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=88927 Comments on planned server hardware]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=102978#p461624 Moodle performance in a pil by Martin Langhoff]&lt;br /&gt;
&lt;br /&gt;
[[es:Rendimiento]]&lt;br /&gt;
[[fr:Performance]]&lt;br /&gt;
[[ja:パフォーマンス]]&lt;br /&gt;
[[pl:Wydajnosc]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=error/auth_ldap/ntlmsso_iwamagicnotenabled&amp;diff=91229</id>
		<title>error/auth ldap/ntlmsso iwamagicnotenabled</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=error/auth_ldap/ntlmsso_iwamagicnotenabled&amp;diff=91229"/>
		<updated>2011-10-05T07:25:11Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Fix See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See the [http://moodle.org/mod/forum/discuss.php?d=117343#p517037 Error ntlmsso_iwamagicnotenabled using NTLM SSO] discussion in the Using Moodle forum for a way to troubleshoot this error.&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=error/auth_ldap/ntlmsso_iwamagicnotenabled&amp;diff=91228</id>
		<title>error/auth ldap/ntlmsso iwamagicnotenabled</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=error/auth_ldap/ntlmsso_iwamagicnotenabled&amp;diff=91228"/>
		<updated>2011-10-05T07:18:42Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* See also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See the [http://moodle.org/mod/forum/discuss.php?d=117343#p517037 Error ntlmsso_iwamagicnotenabled using NTLM SSO] Using Moodle forum discussion for more information about this error.&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=NTLM_authentication&amp;diff=90678</id>
		<title>NTLM authentication</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=NTLM_authentication&amp;diff=90678"/>
		<updated>2011-09-29T07:40:19Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* How to Turn Integrated Authentication on */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document describes how to set up &#039;&#039;&#039;NTLM/Windows Integrated Authentication&#039;&#039;&#039; in Moodle. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
Integrated Windows Authentication uses the security features of Windows clients and servers. It does not prompt users for a user name and password. The current Windows user information on the client computer is supplied by the browser through a challenge/response authentication process with the Web server for the Moodle site. &lt;br /&gt;
&lt;br /&gt;
==Assumptions==&lt;br /&gt;
&lt;br /&gt;
#You are running MS [[Active Directory]] for Authentication.&lt;br /&gt;
#The Server hosting your website is a member of the Active Directory Domain that your users are also members of.&lt;br /&gt;
#You are able to define people inside your Network (and authenticated to the Domain) from an IP range of computers.&lt;br /&gt;
#You are familar with or have read the LDAP authentication documentation.&lt;br /&gt;
#The Active Directory domain credentials of your users are returned as &#039;&#039;&#039;DOMAINNAME\username&#039;&#039;&#039; from your authentication service. If you are using the Winbind service from the Samba project, this can be untrue, depending on your Winbind configuration settings.&lt;br /&gt;
&lt;br /&gt;
If you can not modify your settings to satisfy this last assumption, then you will need to remove or comment out the line that reads:&lt;br /&gt;
    $username = substr(strrchr($username, &#039;\\&#039;), 1); //strip domain info&lt;br /&gt;
and add the relevant lines of code to extract the username part from the domain user credentials and store it in $username.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;VERY IMPORTANT&#039;&#039;&#039;: NTLM authentication depends on [[LDAP authentication]], and NTLM configuration is specified in the LDAP authentication settings page (Site Administration &amp;gt;&amp;gt; Plugins &amp;gt;&amp;gt; Authentication &amp;gt;&amp;gt; LDAP Server). So before trying to configure NTLM, make sure you have LDAP_authentication properly setup and working.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
&lt;br /&gt;
No installation needed. See Site Administration &amp;gt;&amp;gt; Plugins &amp;gt;&amp;gt; Authentication &amp;gt;&amp;gt; LDAP Server for the NTLM config options. You only have to&lt;br /&gt;
&lt;br /&gt;
*Enable NTLM SSO&lt;br /&gt;
*Set the IP/Subnet mask for the clients (see below)&lt;br /&gt;
*On IIS: turn on Windows Authentication&lt;br /&gt;
*On Apache - use one of the 3 methods outlined below&lt;br /&gt;
*On the client pc&#039;s, you might need to set the moodle server ip/moodle url as being in &amp;quot;local intranet&amp;quot; (From IE, tools -&amp;gt; options -&amp;gt; security -&amp;gt; local intranet)&lt;br /&gt;
&lt;br /&gt;
It is important to note the following conditions must be satisfied to let NTLM SSO happens:&lt;br /&gt;
*you&#039;ve arrived to the login page with one GET request&lt;br /&gt;
*you&#039;ve ldap-&amp;gt;ntlmsso_enabled&lt;br /&gt;
*you&#039;ve ldap-&amp;gt;ntlmsso_subnet&lt;br /&gt;
*you aren&#039;t logged&lt;br /&gt;
*the IP of the client is in ntlmsso_subnet&lt;br /&gt;
&lt;br /&gt;
Thus it is needed to set the IP subnet.&lt;br /&gt;
&lt;br /&gt;
If you have used previous versions of NTLM (from 1.8 and below) in your Moodle database you will need to make two further changes. &lt;br /&gt;
&lt;br /&gt;
#The type of authentication held against each user now needs to be LDAP, as NTLM will not be recognised. To edit the fields open up a SQL query for your Moodle server and use the following query &amp;quot;update mdl_user set auth = &#039;ldap&#039; where auth = &#039;ntlm&#039; &amp;quot;&lt;br /&gt;
#If you had a previous .htaccess file in the auth/ntlm directory, you will need to move it to the auth/ldap directory. Regardless of whether it is in a .htaccess file of the httpd.conf, the &amp;lt;Files&amp;gt; line now needs to refer to ntlmsso_magic.php. If it is in the httpd.conf, the &amp;lt;Directory&amp;gt; will need to change too. This is covered later on for new installs, but is one of the fundamental changes that needs to be made for those upgrading.&lt;br /&gt;
&lt;br /&gt;
==How to Turn Integrated Authentication on==&lt;br /&gt;
The auth/ldap/ntlmsso_magic.php file MUST have NTLM/Integrated Authentication enabled on the server or the authentication will not work.&lt;br /&gt;
&lt;br /&gt;
===IIS Configuration===&lt;br /&gt;
Open the IIS Management Console and navigate to the auth/ldap/ntlmsso_magic.php file.&lt;br /&gt;
&lt;br /&gt;
====IIS 6.0====&lt;br /&gt;
#right click on the file, choose properties&lt;br /&gt;
#under the &amp;quot;file security&amp;quot; tab, click on the Authentication and Access control &amp;quot;edit&amp;quot; button&lt;br /&gt;
#untick &amp;quot;Enable Anonymous Access&amp;quot; and tick &amp;quot;Integrated Windows Authentication&amp;quot;&lt;br /&gt;
&lt;br /&gt;
====IIS 7.x====&lt;br /&gt;
#After navigating to the &#039;auth/ldap&#039; folder, switch to Content View&lt;br /&gt;
#right click on the file, choose &amp;quot;Switch to Features View&amp;quot;&lt;br /&gt;
#click on the Authentication icon on the right&lt;br /&gt;
#select &#039;Anonymous Authentication&#039; and click the &#039;Disable&#039; button&lt;br /&gt;
#select &#039;Windows Authentication&#039; and click the &#039;Enable&#039; button&lt;br /&gt;
&lt;br /&gt;
*According to [http://moodle.org/mod/forum/discuss.php?d=145171#p634027 this post], if you are using IIS 7.5 (it comes with Windows Server 2008 R2), you have to select &#039;Windows Authentication&#039; and click on &#039;Providers&#039;. This shows a list of enabled providers (Negotiate and NTLM, by default). Change the order so that NTLM is at the top of the list.&lt;br /&gt;
*If &#039;Windows Authentication&#039; is not available, then you need to install it as a separate authentication provider (in Control Panel).&lt;br /&gt;
&lt;br /&gt;
===APACHE Configuration===&lt;br /&gt;
There are currently 3 possible methods for this:&lt;br /&gt;
&lt;br /&gt;
====Using the NTLM part of Samba for Apache on Linux====&lt;br /&gt;
&lt;br /&gt;
* Get the plugin here: http://samba.org/ftp/unpacked/lorikeet/mod_auth_ntlm_winbind/ . You need to download all the files from the link, but not the &amp;lt;code&amp;gt;contrib&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;debian&amp;lt;/code&amp;gt; directories. Then follow the instructions given inside the &amp;lt;code&amp;gt;README&amp;lt;/code&amp;gt; file. If you are using Debian/Ubuntu, you can follow these [[#Compiling_mod_auth_ntlm_winbind_on_Debian.2FUbuntu|compilation instructions]].&lt;br /&gt;
* Once you have compiled it, put it inside Apache&#039;s modules subdirectory (this location depends on a number of factors, like compiling Apache yourself, using different Linux distributions packages, an so on), and load and enable the module in Apache&#039;s configuration. For example, if your Apache modules are under &amp;lt;tt&amp;gt;/usr/lib/apache2/modules&amp;lt;/tt&amp;gt;, you&#039;ll need something like this in your Apache configuration file (usually called &amp;lt;tt&amp;gt;apache2.conf&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;http2.conf&amp;lt;/tt&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;IfModule !mod_auth_ntlm_winbind.c&amp;gt;&lt;br /&gt;
       LoadModule auth_ntlm_winbind_module /usr/lib/apache2/modules/mod_auth_ntlm_winbind.so&lt;br /&gt;
   &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Install the Samba &amp;lt;tt&amp;gt;winbind&amp;lt;/tt&amp;gt; daemon package. This packages relies on Samba&#039;s configuration file to get some important settings (like the Windows domain name, uid and gid range mappings, and so on). In addition to that, you&#039;ll need to make your Linux/Unix machine part of the domain. Otherwise winbind won&#039;t be able to pull user and groups informationi from the domain controllers. You should read the Samba documentation to perform this step, but the most important part is having something like the following lines in your &amp;lt;code&amp;gt;smb.conf&amp;lt;/code&amp;gt; file (in addition to what you already have there):&lt;br /&gt;
&lt;br /&gt;
  workgroup = DOMAINNAME&lt;br /&gt;
  password server = *&lt;br /&gt;
  security = domain&lt;br /&gt;
  encrypt passwords = true&lt;br /&gt;
  idmap uid = 10000-20000&lt;br /&gt;
  idmap gid = 10000-20000&lt;br /&gt;
&lt;br /&gt;
: and executing the command (as root):&lt;br /&gt;
&lt;br /&gt;
  # net join DOMAINNAME -U Administrator&lt;br /&gt;
&lt;br /&gt;
: where &#039;&#039;&#039;DOMAINNAME&#039;&#039;&#039; is the NetBIOS windows domain name, and &#039;&#039;&#039;Administrator&#039;&#039;&#039; an account with enough privileges to add new machines to the domain.&amp;lt;br/&amp;gt; You&#039;ll need to type this account&#039;s password for the command to succeed.&lt;br /&gt;
&lt;br /&gt;
: In Windows environments you could also try executing the command (as root):&lt;br /&gt;
&lt;br /&gt;
  # net join DOMAINNAME -S DCSERVER -U Administrator&lt;br /&gt;
&lt;br /&gt;
: where DCSERVER is the Domain Controller server&lt;br /&gt;
&lt;br /&gt;
: Also, make sure you have disabled &amp;quot;Microsoft Network Server: digitally sign communications (always)&amp;quot; in your Domain Controllers Security Policy, unless you are using a version of Samba that can sign SMB packets.&lt;br /&gt;
&lt;br /&gt;
* Restart the &amp;lt;tt&amp;gt;winbind&amp;lt;/tt&amp;gt; service to apply the changes and test that it&#039;s running ok by executing:&lt;br /&gt;
&lt;br /&gt;
  $ wbinfo -u&lt;br /&gt;
&lt;br /&gt;
: You should get the full list of Windows domain users. If you use &#039;&#039;&#039;&amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt;&#039;&#039;&#039; instead, you&#039;ll get the domain groups list.&lt;br /&gt;
&lt;br /&gt;
* Check that your &amp;lt;tt&amp;gt;winbind&amp;lt;/tt&amp;gt; package installed the authentication helper command &amp;lt;tt&amp;gt;ntlm_auth&amp;lt;/tt&amp;gt;, as we&#039;ll need it later. We&#039;ll assume the helper is located at &amp;lt;tt&amp;gt;/usr/bin/ntlm_auth&amp;lt;/tt&amp;gt;. If yours is at a different location, make sure you adjust the path in the example below.&lt;br /&gt;
&lt;br /&gt;
* Add something like this to your Apache configuration file (usually called &amp;lt;tt&amp;gt;apache2.conf&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;http2.conf&amp;lt;/tt&amp;gt;). We&#039;ll assume that your Moodle &amp;lt;tt&amp;gt;$CFG-&amp;gt;dirroot&amp;lt;/tt&amp;gt; directory is located at &amp;lt;tt&amp;gt;/var/www/moodle&amp;lt;/tt&amp;gt; in the example:&lt;br /&gt;
: &#039;&#039;&#039;For 1.9 or above use&#039;&#039;&#039;:&lt;br /&gt;
    &amp;lt;Directory &amp;quot;/var/www/moodle/auth/ldap/&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;Files ntlmsso_magic.php&amp;gt;&lt;br /&gt;
            NTLMAuth on&lt;br /&gt;
            AuthType NTLM&lt;br /&gt;
            AuthName &amp;quot;Moodle NTLM Authentication&amp;quot;&lt;br /&gt;
            NTLMAuthHelper &amp;quot;/usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp&amp;quot;&lt;br /&gt;
            NTLMBasicAuthoritative on&lt;br /&gt;
            require valid-user&lt;br /&gt;
        &amp;lt;/Files&amp;gt;&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
: &#039;&#039;&#039;For 1.8 or below use&#039;&#039;&#039;:&lt;br /&gt;
    &amp;lt;Directory &amp;quot;/var/www/moodle/auth/ntlm/&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;Files oncampuslogin.php&amp;gt;&lt;br /&gt;
            NTLMAuth on&lt;br /&gt;
            AuthType NTLM&lt;br /&gt;
            AuthName &amp;quot;Moodle NTLM Authentication&amp;quot;&lt;br /&gt;
            NTLMAuthHelper &amp;quot;/usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp&amp;quot;&lt;br /&gt;
            NTLMBasicAuthoritative on&lt;br /&gt;
            require valid-user&lt;br /&gt;
        &amp;lt;/Files&amp;gt;&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
* Check the permissions of the Winbind pipe directory (Ubuntu places it under &amp;lt;tt&amp;gt;/var/run/samba/winbindd_privileged&amp;lt;/tt&amp;gt;, yours may be placed at a different location). Apache will need to be able to enter that directory, so we need to make sure it has the right permissions. So have a look at the permissions of that directory and note the name of the group assigned to it. The following example is from a Ubuntu 7.10 machine:&lt;br /&gt;
&lt;br /&gt;
  $ ls -ald /var/run/samba/winbindd_privileged&lt;br /&gt;
  drwxr-x--- 2 root winbindd_priv 60 2007-11-17 16:18 /var/run/samba/winbindd_privileged/&lt;br /&gt;
&lt;br /&gt;
:so we see the group is &amp;lt;tt&amp;gt;winbindd_priv&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Instead of modifying the directory permissions (which could break other services that use winbind) we are going to make the Apache user (&amp;lt;tt&amp;gt;www-data&amp;lt;/tt&amp;gt; in our example, but could be &amp;lt;tt&amp;gt;httpd&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;nobody&amp;lt;/tt&amp;gt;, etc.) is part of the appropiate group. Execute the following as root:&lt;br /&gt;
&lt;br /&gt;
  # adduser www-data winbindd_priv&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tt&amp;gt;adduser&amp;lt;/tt&amp;gt; is available in Debian and Ubuntu at least. If your distribution doesn&#039;t have &amp;lt;tt&amp;gt;adduser&amp;lt;/tt&amp;gt;, you can edit &amp;lt;tt&amp;gt;/etc/group&amp;lt;/tt&amp;gt; manually to achive the same effect.&lt;br /&gt;
&lt;br /&gt;
* Stop and start the Apache service to apply the changes. Have a look at Apache&#039;s error log to see that everything is ok.&lt;br /&gt;
&lt;br /&gt;
* Couple of gotchas - in Fedora Core (and also in Redhat/Centos), keep alive is turned OFF by default in the httpd.conf - see this bug for further info: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=188138&amp;lt;br /&amp;gt;&lt;br /&gt;
simply change the line to that was:&lt;br /&gt;
 KeepAlive Off&lt;br /&gt;
to:&lt;br /&gt;
 KeepAlive On&lt;br /&gt;
and restart apache (/etc/init.d/http restart)&lt;br /&gt;
* Email Dan if you get this working - I&#039;m keen to hear how people go using the samba winbind option!&lt;br /&gt;
::-- Hi Dan! I made it work using Ubuntu 7.04. That&#039;s what I&#039;ve used to update the documentation. [[User:Iñaki Arenaza|Iñaki Arenaza]] 10:43, 30 September 2007 (CDT)&lt;br /&gt;
::-- Hi Dan! I have this working on Ubuntu 8.04 LTS in an RM CC4 Active Directory Domain. [[User:munk3h|Ian]] 16:31 15 December 2009 (GMT)&lt;br /&gt;
&lt;br /&gt;
====Using the NTLM Auth Module for Apache on Linux====&lt;br /&gt;
The NTLM Auth module is a bit stale and even its authors suggest that you use the [[#Using_the_NTLM_part_of_Samba_for_Apache_on_Linux|NTLM part of Samba with Apache on Linux]]&lt;br /&gt;
&lt;br /&gt;
Get it from here &lt;br /&gt;
# get the Module from: http://modntlm.sourceforge.net/&lt;br /&gt;
# follow the instructions given there and inside the README that comes with the package.&lt;br /&gt;
&lt;br /&gt;
I (Iñaki Arenaza) strongly recommend using the [[#Using_the_NTLM_part_of_Samba_for_Apache_on_Linux|NTLM part of Samba with Apache on Linux]] over this module. It&#039;s better maintained, more robust and has more features.&lt;br /&gt;
&lt;br /&gt;
====Using the mod_auth_sspi Module for Apache 2 on Windows====&lt;br /&gt;
NOTE: This setup is currently being used in a live production environment, and is therefore suitable for such use provided it is correctly configured and tested.&lt;br /&gt;
&lt;br /&gt;
This is the recommended method for Apache 2 on Windows, however it will &#039;&#039;&#039;not&#039;&#039;&#039; work on Linux/UNIX systems.&lt;br /&gt;
It provides better stability and higher performance than other NTLM modules.&lt;br /&gt;
&lt;br /&gt;
* Download the mod_auth_sspi Module from: http://sourceforge.net/projects/mod-auth-sspi/. At the moment of writing this (2007.09.30), the current version is mod_auth_sspi 1.0.4, which has two different ZIP files to download:&lt;br /&gt;
&lt;br /&gt;
::* mod_auth_sspi-1.0.4-2.0.58.zip :   Use this file if you are using Apache 2.0.x.&lt;br /&gt;
::* mod_auth_sspi-1.0.4-2.2.2.zip :   Use this file if you are using Apache 2.2.x.&lt;br /&gt;
&lt;br /&gt;
* Unzip the right file and copy mod_auth_sspi.so (it&#039;s inside &#039;&#039;&#039;bin&#039;&#039;&#039; subdirectory) to your Apache modules directory.&lt;br /&gt;
* Edit your Apache 2 configuration file (httpd.conf) to load the module.&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;IfModule !mod_auth_sspi.c&amp;gt;&lt;br /&gt;
        LoadModule sspi_auth_module modules/mod_auth_sspi.so&lt;br /&gt;
    &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Choose one of the two methods below&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&#039;Method 1&#039;&#039;&#039;: This method is recommended for servers that will host a single Moodle instance. Configure NTLM from the main configuration file, add the following to httpd.conf (substitute &amp;quot;C:\moodle&amp;quot; with the path to your Moodle installation e.g. &amp;quot;C:\my-moodle&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:: &#039;&#039;&#039;For 1.9 or above use&#039;&#039;&#039;:&lt;br /&gt;
    &amp;lt;Directory &amp;quot;C:\moodle\auth\ldap&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;Files ntlmsso_magic.php&amp;gt;&lt;br /&gt;
            AuthName &amp;quot;Moodle at My College&amp;quot;&lt;br /&gt;
            AuthType SSPI&lt;br /&gt;
            SSPIAuth On&lt;br /&gt;
            SSPIOfferBasic Off&lt;br /&gt;
            SSPIAuthoritative On&lt;br /&gt;
            SSPIDomain mycollege.ac.uk&lt;br /&gt;
            require valid-user&lt;br /&gt;
        &amp;lt;/Files&amp;gt;&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
:: &#039;&#039;&#039;For 1.8 or below use&#039;&#039;&#039;:&lt;br /&gt;
    &amp;lt;Directory &amp;quot;C:\moodle\auth\ntlm&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;Files oncampuslogin.php&amp;gt;&lt;br /&gt;
            AuthName &amp;quot;Moodle at My College&amp;quot;&lt;br /&gt;
            AuthType SSPI&lt;br /&gt;
            SSPIAuth On&lt;br /&gt;
            SSPIOfferBasic Off&lt;br /&gt;
            SSPIAuthoritative On&lt;br /&gt;
            SSPIDomain mycollege.ac.uk&lt;br /&gt;
            require valid-user&lt;br /&gt;
        &amp;lt;/Files&amp;gt;&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&#039;Method 2&#039;&#039;&#039;: The alternative method is to use a .htaccess file&lt;br /&gt;
:This method is recommended for servers that will host multiple Moodle instances. It allows additional Moodle instances to be configured without restarting apache, and also makes the solution a little more portable. We need to add a directive to the main httpd.conf to allow configuration of authentication within .htaccess files.&lt;br /&gt;
    &amp;lt;Directory C:\moodle&amp;gt;&lt;br /&gt;
        AllowOverride AuthConfig&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:::Create a new text file named &#039;.htaccess&#039; in the directory &#039;C:\moodle\moodle\auth\ldap&#039; and add the following directives:&lt;br /&gt;
    &amp;lt;Files ntlmsso_magic.php&amp;gt;&lt;br /&gt;
        AuthName &amp;quot;Moodle at My College&amp;quot;&lt;br /&gt;
        AuthType SSPI&lt;br /&gt;
        SSPIAuth On&lt;br /&gt;
        SSPIOfferBasic Off&lt;br /&gt;
        SSPIAuthoritative On&lt;br /&gt;
        SSPIDomain mycollege.ac.uk&lt;br /&gt;
        require valid-user&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:This enables the Moodle folder to be moved to any apache webserver that is configured to allow authentication configuration through .htaccess&lt;br /&gt;
&lt;br /&gt;
For further help and discussion: http://moodle.org/mod/forum/discuss.php?d=56565&lt;br /&gt;
&lt;br /&gt;
====Using the Kerberos Auth Module for Apache on Linux/UNIX (mod_auth_kerb)====&lt;br /&gt;
*Install and configure http://modauthkerb.sourceforge.net/&lt;br /&gt;
*Configuration of mod_auth_kerb in a Microsoft Windows Active Directory environment (AD 2003 and above) (http://grolmsnet.de/kerbtut/)&lt;br /&gt;
&lt;br /&gt;
Environment details in this example:&lt;br /&gt;
#&#039;&#039;&#039;Active Directory Domain:&#039;&#039;&#039; EXAMPLE.AC.UK&lt;br /&gt;
#&#039;&#039;&#039;Active Directory Domain Controller:&#039;&#039;&#039; dc.example.ac.uk&lt;br /&gt;
#&#039;&#039;&#039;Linux/UNIX web server:&#039;&#039;&#039; moodle.example.ac.uk&lt;br /&gt;
#&#039;&#039;&#039;Active Directory user account for web server service principal:&#039;&#039;&#039; moodlekerb&lt;br /&gt;
&lt;br /&gt;
Install kerberos on moodle.example.ac.uk and enter the following in krb5.conf (by default: /etc/krb5.conf)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[libdefaults]&lt;br /&gt;
    default_realm = EXAMPLE.AC.UK&lt;br /&gt;
[domain_realm]&lt;br /&gt;
    example.ac.uk = EXAMPLE.AC.UK&lt;br /&gt;
[realms]&lt;br /&gt;
     EXAMPLE.AC.UK = {&lt;br /&gt;
                      admin_server = dc.example.ac.uk&lt;br /&gt;
                      kdc          = dc.example.ac.uk&lt;br /&gt;
                    }:&lt;br /&gt;
* Test kerberos&lt;br /&gt;
Issue the following command at the shell prompt:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$&amp;gt; kinit user@EXAMPLE.AC.UK&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &#039;user&#039; is an Active Directory account for which you know the password.&lt;br /&gt;
&lt;br /&gt;
Next, issue the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;$&amp;gt;klist&amp;lt;/pre&amp;gt;&lt;br /&gt;
If all is OK it will list the Kerberos ticket you were granted from the domain controller (KDC)&lt;br /&gt;
&lt;br /&gt;
* Create HTTP service principal for moodle.example.ac.uk&lt;br /&gt;
#Create the &#039;moodlekerb&#039; &#039;&#039;&#039;user&#039;&#039;&#039; account in Active Directory (NOT a machine account) to map to the web server service principal (HTTP/moodle.example.ac.uk@EXAMPLE.AC.UK)&lt;br /&gt;
NOTE: moodle.example.ac.uk MUST be the canonical DNS name of the server i.e. an A record (NOT a CNAME). Additionally a valid PTR (reverse DNS) record must exist and match the corresponding A record.&lt;br /&gt;
&lt;br /&gt;
#Use the ktpass.exe utility to map the service principal and create a keytab file&lt;br /&gt;
Apache requires a keytab file, which is generated with ktpass.exe on the Windows Active Directory Domain Controller.&lt;br /&gt;
Shockingly, this component of Windows Server 2003 SP1 does not function correctly so one must obtain a hot fix: http://support.microsoft.com/kb/919557&lt;br /&gt;
&lt;br /&gt;
Run the following command on the domain controller:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\path\to\hotfix\ktpass.exe -princ HTTP/moodle.example.ac.uk@EXAMPLE.AC.UK -mapuser EXAMPLE\moodlekerb -crypto DES-CBC-MD5 +DesOnly +setPass +rndPass -ptype KRB5_NT_PRINCIPAL -out moodle.example.ac.uk.keytab&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy C:\path\to\hotfix\moodle.example.ac.uk.keytab to the moodle web server and remember the location (/etc/httpd/moodle.example.ac.uk.keytab or similar)&lt;br /&gt;
&lt;br /&gt;
* Configure Apache / mod_auth_kerb&lt;br /&gt;
Edit the Apache configuration for the moodle host and add the following directives:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        &amp;lt;Directory /path/to/moodle/docs/auth/ldap/&amp;gt;&lt;br /&gt;
                &amp;lt;Files ntlmsso_magic.php&amp;gt;&lt;br /&gt;
                        AuthName &amp;quot;Moodle&amp;quot;&lt;br /&gt;
                        AuthType Kerberos&lt;br /&gt;
                        KrbAuthRealms EXAMPLE.AC.UK&lt;br /&gt;
                        KrbServiceName HTTP&lt;br /&gt;
                        Krb5Keytab /etc/httpd/moodle.example.ac.uk.keytab&lt;br /&gt;
                        KrbMethodNegotiate on&lt;br /&gt;
                        KrbMethodK5Passwd on&lt;br /&gt;
                        KrbAuthoritative on&lt;br /&gt;
                        require valid-user&lt;br /&gt;
                &amp;lt;/Files&amp;gt;&lt;br /&gt;
        &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Replace the &#039;&#039;&#039;ntlmsso_magic&#039;&#039;&#039; function in &#039;&#039;&#039;/auth/ldap/auth.php&#039;&#039;&#039; (1.9 only, as 2.x already support Kerberos format out of the box) with the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function ntlmsso_magic($sesskey) {&lt;br /&gt;
        if (isset($_SERVER[&#039;REMOTE_USER&#039;]) &amp;amp;&amp;amp; !empty($_SERVER[&#039;REMOTE_USER&#039;])) {&lt;br /&gt;
&lt;br /&gt;
            // HTTP __headers__ seem to be sent in ISO-8859-1 encoding&lt;br /&gt;
            // (according to my reading of RFC-1945, RFC-2616 and RFC-2617 and&lt;br /&gt;
            // my local tests), so we need to convert the REMOTE_USER value&lt;br /&gt;
            // (i.e., what we got from the HTTP WWW-Authenticate header) into UTF-8&lt;br /&gt;
            $textlib = textlib_get_instance();&lt;br /&gt;
            $username = $textlib-&amp;gt;convert($_SERVER[&#039;REMOTE_USER&#039;], &#039;iso-8859-1&#039;, &#039;utf-8&#039;);&lt;br /&gt;
            &lt;br /&gt;
            /**&lt;br /&gt;
             * begin kerberos - afhole@wortech.ac.uk 21-04-2009&lt;br /&gt;
             */&lt;br /&gt;
            if ($pos = strpos($username, &amp;quot;@&amp;quot;)) {&lt;br /&gt;
                $username = substr($username, 0, $pos);&lt;br /&gt;
            } else {&lt;br /&gt;
                $username = substr(strrchr($username, &#039;\\&#039;), 1); //strip domain info&lt;br /&gt;
            }&lt;br /&gt;
            /**&lt;br /&gt;
             * end kerberos&lt;br /&gt;
             */&lt;br /&gt;
&lt;br /&gt;
            $username = moodle_strtolower($username); //compatibility hack&lt;br /&gt;
            set_cache_flag(&#039;auth/ldap/ntlmsess&#039;, $sesskey, $username, AUTH_NTLMTIMEOUT);&lt;br /&gt;
            return true;&lt;br /&gt;
        }&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code change will account for the fact that Kerberos presents the username to REMOTE_USER in the format user@DOMAIN, rather than NTLM&#039;s DOMAIN\user&lt;br /&gt;
&lt;br /&gt;
==Configuring IP/Subnet Mask==&lt;br /&gt;
Subnet masks are based on binary patterns so need a bit of knowledge to understand. The best way to find out what IP/Subnet masks to use is to ask your Network Admin. &lt;br /&gt;
&lt;br /&gt;
* The new way of specifiying subnets is even easier/more flexible than before 1.9. Just type them one after the other, separated by commas. You can use several syntaxes:&lt;br /&gt;
** Type the network-number/prefix-length combination. E.g. 192.168.1.0/24&lt;br /&gt;
** Type the network &#039;prefix&#039;, ending in a period character. E.g. 192.168.1.&lt;br /&gt;
** Type the network address range (&#039;&#039;&#039;this only works for the last address octect&#039;&#039;&#039;). E.g. 192.168.1.1-254&lt;br /&gt;
:All the three examples refer to the same subnetwork. So assuming you need to specify the following subnetworks:&lt;br /&gt;
::* 10.1.0/255.255.0.0&lt;br /&gt;
::* 10.2.0.0/255.255.0.0&lt;br /&gt;
::* 172.16.0.0/255.255.0.0&lt;br /&gt;
::* 192.168.100.0/255.255.255.240&lt;br /&gt;
:You can type:&lt;br /&gt;
 10.1.0.0/16, 10.2.0.0/16, 172.16.0.0/16, 192.168.100.0/28&lt;br /&gt;
: or:&lt;br /&gt;
  10.1.0.0/16, 10.2.0.0/16, 172.16.0.0/16, 192.168.100.240-255&lt;br /&gt;
:or even:&lt;br /&gt;
  10.1., 10.2., 172.16., 192.168.100.0/28&lt;br /&gt;
:(the last one cannot be expressed as a network &#039;prefix&#039; as the netmask does not fall on an octect boundary).&lt;br /&gt;
&lt;br /&gt;
==Notes/Tips==&lt;br /&gt;
&lt;br /&gt;
#If you are using Firefox, you will need to follow these steps:&lt;br /&gt;
:*Load Firefox and type about:config in the address box. The configuration settings page should be displayed.&lt;br /&gt;
:*In the Filter box, type the word &amp;quot;ntlm&amp;quot; to filter the NTLM strings. You should see three settings displayed.&lt;br /&gt;
:*Double-click on &amp;quot;network.automatic-ntlm-auth.trusted-uris&amp;quot;.&lt;br /&gt;
:*In the box, enter the full URL of your Moodle server. For example &amp;lt;pre&amp;gt;http://moodle.mydomain.com, (the comma is important)&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Close Firefox and restart.&lt;br /&gt;
# NTLM seems to not work at all when BASIC authentication is enabled. (this was using the Kerberos method, other ways may work)&lt;br /&gt;
# If the account in your AD management console shows like &amp;quot;First Last&amp;quot;, you better change the ldap settings parameter &#039;User Attribute&#039; from its default of {blank} / &#039;cn&#039; to &#039;sAMAccountName&#039; as indicated in [http://moodle.org/mod/forum/discuss.php?d=132364#p682173 this post]. The reason is that the cn name generally looks like &amp;quot;First Last&amp;quot;, once you done the ldap sync, the user name in moodle will be &amp;quot;first last&amp;quot;, but IE passes the account of &amp;quot;domain\first.last&amp;quot; to moodle which does not exist in moodle.&lt;br /&gt;
&lt;br /&gt;
== To get a domain name for Moodle working on IIS7.5 Windows 2008 R2 ==&lt;br /&gt;
Refer to http://support.microsoft.com/kb/896861. Key section listed below.&lt;br /&gt;
Click Start, click Run, type regedit, and then click OK.&amp;lt;br /&amp;gt;&lt;br /&gt;
In Registry Editor, locate and then click the following registry key: &lt;br /&gt;
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0&amp;lt;br /&amp;gt;&lt;br /&gt;
Right-click MSV1_0, point to New, and then click Multi-String Value.&amp;lt;br /&amp;gt;&lt;br /&gt;
Type BackConnectionHostNames, and then press ENTER.&amp;lt;br /&amp;gt;&lt;br /&gt;
Right-click BackConnectionHostNames, and then click Modify.&amp;lt;br /&amp;gt;&lt;br /&gt;
In the Value data box, type the host name or the host names for the sites that are on the local computer, and then click OK.&amp;lt;br /&amp;gt;&lt;br /&gt;
Quit Registry Editor, and then restart the IISAdmin service.&lt;br /&gt;
&lt;br /&gt;
==Compiling mod_auth_ntlm_winbind on Debian/Ubuntu==&lt;br /&gt;
You need to install the following packages (and all of their dependencies) by using aptitude, synaptic, etc.:&lt;br /&gt;
&lt;br /&gt;
  autoconf apache2-threaded-dev debian-builder&lt;br /&gt;
&lt;br /&gt;
Once you have them installed, open up a text console, go to the directory where you downloaded the mod_auth_ntlm_winbind files an execute the following commands (as a normal user):&lt;br /&gt;
&lt;br /&gt;
  autoconf&lt;br /&gt;
  ./configure --with-apxs=/usr/bin/apxs2 --with-apache=/usr/sbin/apache2&lt;br /&gt;
  make&lt;br /&gt;
&lt;br /&gt;
That should compile it without errors. Then as a user that can run commands as root via sudo, execute the following command from the same directory:&lt;br /&gt;
&lt;br /&gt;
  sudo make install&lt;br /&gt;
&lt;br /&gt;
This will create the final mod_auth_ntlm_winbind.so file and install it under /usr/lib/apache2/modules, with the rest of the Apache 2 modules (the size of the file and last modification time shown below may differ from your install):&lt;br /&gt;
&lt;br /&gt;
  ls -l /usr/lib/apache2/modules/mod_auth_ntlm_winbind.so&lt;br /&gt;
  -rw-r--r-- 1 root root 20921 2009-02-17 04:27 /usr/lib/apache2/modules/mod_auth_ntlm_winbind.so&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://moodle.org/mod/forum/view.php?id=42 Using Moodle: User authentication] forum&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=45887 NTLM Authentication] forum discussion&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=80104 Merging AD NTLM SSO into auth/ldap] forum discussion&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=186661 Moodle in a DMZ with NTLM] forum discussion&lt;br /&gt;
*[http://moodle.org/mod/data/view.php?d=13&amp;amp;rid=314 Download the NTLM Authentication Module]&lt;br /&gt;
&lt;br /&gt;
[[Category:Contributed code]]&lt;br /&gt;
[[Category:Authentication]]&lt;br /&gt;
&lt;br /&gt;
[[fr:Authentification NTLM]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=NTLM_authentication&amp;diff=90676</id>
		<title>NTLM authentication</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=NTLM_authentication&amp;diff=90676"/>
		<updated>2011-09-29T07:18:42Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* New See also link */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document describes how to set up &#039;&#039;&#039;NTLM/Windows Integrated Authentication&#039;&#039;&#039; in Moodle. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
Integrated Windows Authentication uses the security features of Windows clients and servers. It does not prompt users for a user name and password. The current Windows user information on the client computer is supplied by the browser through a challenge/response authentication process with the Web server for the Moodle site. &lt;br /&gt;
&lt;br /&gt;
==Assumptions==&lt;br /&gt;
&lt;br /&gt;
#You are running MS [[Active Directory]] for Authentication.&lt;br /&gt;
#The Server hosting your website is a member of the Active Directory Domain that your users are also members of.&lt;br /&gt;
#You are able to define people inside your Network (and authenticated to the Domain) from an IP range of computers.&lt;br /&gt;
#You are familar with or have read the LDAP authentication documentation.&lt;br /&gt;
#The Active Directory domain credentials of your users are returned as &#039;&#039;&#039;DOMAINNAME\username&#039;&#039;&#039; from your authentication service. If you are using the Winbind service from the Samba project, this can be untrue, depending on your Winbind configuration settings.&lt;br /&gt;
&lt;br /&gt;
If you can not modify your settings to satisfy this last assumption, then you will need to remove or comment out the line that reads:&lt;br /&gt;
    $username = substr(strrchr($username, &#039;\\&#039;), 1); //strip domain info&lt;br /&gt;
and add the relevant lines of code to extract the username part from the domain user credentials and store it in $username.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;VERY IMPORTANT&#039;&#039;&#039;: NTLM authentication depends on [[LDAP authentication]], and NTLM configuration is specified in the LDAP authentication settings page (Site Administration &amp;gt;&amp;gt; Plugins &amp;gt;&amp;gt; Authentication &amp;gt;&amp;gt; LDAP Server). So before trying to configure NTLM, make sure you have LDAP_authentication properly setup and working.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
&lt;br /&gt;
No installation needed. See Site Administration &amp;gt;&amp;gt; Plugins &amp;gt;&amp;gt; Authentication &amp;gt;&amp;gt; LDAP Server for the NTLM config options. You only have to&lt;br /&gt;
&lt;br /&gt;
*Enable NTLM SSO&lt;br /&gt;
*Set the IP/Subnet mask for the clients (see below)&lt;br /&gt;
*On IIS: turn on Windows Authentication&lt;br /&gt;
*On Apache - use one of the 3 methods outlined below&lt;br /&gt;
*On the client pc&#039;s, you might need to set the moodle server ip/moodle url as being in &amp;quot;local intranet&amp;quot; (From IE, tools -&amp;gt; options -&amp;gt; security -&amp;gt; local intranet)&lt;br /&gt;
&lt;br /&gt;
It is important to note the following conditions must be satisfied to let NTLM SSO happens:&lt;br /&gt;
*you&#039;ve arrived to the login page with one GET request&lt;br /&gt;
*you&#039;ve ldap-&amp;gt;ntlmsso_enabled&lt;br /&gt;
*you&#039;ve ldap-&amp;gt;ntlmsso_subnet&lt;br /&gt;
*you aren&#039;t logged&lt;br /&gt;
*the IP of the client is in ntlmsso_subnet&lt;br /&gt;
&lt;br /&gt;
Thus it is needed to set the IP subnet.&lt;br /&gt;
&lt;br /&gt;
If you have used previous versions of NTLM (from 1.8 and below) in your Moodle database you will need to make two further changes. &lt;br /&gt;
&lt;br /&gt;
#The type of authentication held against each user now needs to be LDAP, as NTLM will not be recognised. To edit the fields open up a SQL query for your Moodle server and use the following query &amp;quot;update mdl_user set auth = &#039;ldap&#039; where auth = &#039;ntlm&#039; &amp;quot;&lt;br /&gt;
#If you had a previous .htaccess file in the auth/ntlm directory, you will need to move it to the auth/ldap directory. Regardless of whether it is in a .htaccess file of the httpd.conf, the &amp;lt;Files&amp;gt; line now needs to refer to ntlmsso_magic.php. If it is in the httpd.conf, the &amp;lt;Directory&amp;gt; will need to change too. This is covered later on for new installs, but is one of the fundamental changes that needs to be made for those upgrading.&lt;br /&gt;
&lt;br /&gt;
==How to Turn Integrated Authentication on==&lt;br /&gt;
The File ntlmsso_magic.php MUST have NTLM/Integrated Authentication enabled at the server or the page will not work.&lt;br /&gt;
&lt;br /&gt;
===IIS Configuration===&lt;br /&gt;
Open up IIS, and find the auth/ldap/ntlmsso_magic.php file, &lt;br /&gt;
&lt;br /&gt;
====IIS 6.0====&lt;br /&gt;
#right click on the file, choose properties&lt;br /&gt;
#under the &amp;quot;file security&amp;quot; tab, click on the Authentication and Access control &amp;quot;edit&amp;quot; button&lt;br /&gt;
#untick &amp;quot;Enable Anonymous Access&amp;quot; and tick &amp;quot;Integrated Windows Authentication&amp;quot;&lt;br /&gt;
&lt;br /&gt;
====IIS 7.x====&lt;br /&gt;
#After navigating to the &#039;auth/ldap&#039; folder, switch to Content View&lt;br /&gt;
#right click on the file, choose &amp;quot;Switch to Features View&amp;quot;&lt;br /&gt;
#click on the Authentication icon on the right&lt;br /&gt;
#select &#039;Anonymous Authentication&#039; and click the &#039;Disable&#039; button&lt;br /&gt;
#select &#039;Windows Authentication&#039; and click the &#039;Enable&#039; button&lt;br /&gt;
&lt;br /&gt;
*According to [http://moodle.org/mod/forum/discuss.php?d=145171#p634027 this post], if you are using IIS 7.5 (it comes with Windows Server 2008 R2), you have to select &#039;Windows Authentication&#039; and click on &#039;Providers&#039;. This shows a list of enabled providers (Negotiate and NTLM, by default). Change the order so that NTLM is at the top of the list.&lt;br /&gt;
*If &#039;Windows Authentication&#039; is not available, then you need to install it as a separate authentication provider (in Control Panel).&lt;br /&gt;
&lt;br /&gt;
===APACHE Configuration===&lt;br /&gt;
There are currently 3 possible methods for this:&lt;br /&gt;
&lt;br /&gt;
====Using the NTLM part of Samba for Apache on Linux====&lt;br /&gt;
&lt;br /&gt;
* Get the plugin here: http://samba.org/ftp/unpacked/lorikeet/mod_auth_ntlm_winbind/ . You need to download all the files from the link, but not the &amp;lt;code&amp;gt;contrib&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;debian&amp;lt;/code&amp;gt; directories. Then follow the instructions given inside the &amp;lt;code&amp;gt;README&amp;lt;/code&amp;gt; file. If you are using Debian/Ubuntu, you can follow these [[#Compiling_mod_auth_ntlm_winbind_on_Debian.2FUbuntu|compilation instructions]].&lt;br /&gt;
* Once you have compiled it, put it inside Apache&#039;s modules subdirectory (this location depends on a number of factors, like compiling Apache yourself, using different Linux distributions packages, an so on), and load and enable the module in Apache&#039;s configuration. For example, if your Apache modules are under &amp;lt;tt&amp;gt;/usr/lib/apache2/modules&amp;lt;/tt&amp;gt;, you&#039;ll need something like this in your Apache configuration file (usually called &amp;lt;tt&amp;gt;apache2.conf&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;http2.conf&amp;lt;/tt&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;IfModule !mod_auth_ntlm_winbind.c&amp;gt;&lt;br /&gt;
       LoadModule auth_ntlm_winbind_module /usr/lib/apache2/modules/mod_auth_ntlm_winbind.so&lt;br /&gt;
   &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Install the Samba &amp;lt;tt&amp;gt;winbind&amp;lt;/tt&amp;gt; daemon package. This packages relies on Samba&#039;s configuration file to get some important settings (like the Windows domain name, uid and gid range mappings, and so on). In addition to that, you&#039;ll need to make your Linux/Unix machine part of the domain. Otherwise winbind won&#039;t be able to pull user and groups informationi from the domain controllers. You should read the Samba documentation to perform this step, but the most important part is having something like the following lines in your &amp;lt;code&amp;gt;smb.conf&amp;lt;/code&amp;gt; file (in addition to what you already have there):&lt;br /&gt;
&lt;br /&gt;
  workgroup = DOMAINNAME&lt;br /&gt;
  password server = *&lt;br /&gt;
  security = domain&lt;br /&gt;
  encrypt passwords = true&lt;br /&gt;
  idmap uid = 10000-20000&lt;br /&gt;
  idmap gid = 10000-20000&lt;br /&gt;
&lt;br /&gt;
: and executing the command (as root):&lt;br /&gt;
&lt;br /&gt;
  # net join DOMAINNAME -U Administrator&lt;br /&gt;
&lt;br /&gt;
: where &#039;&#039;&#039;DOMAINNAME&#039;&#039;&#039; is the NetBIOS windows domain name, and &#039;&#039;&#039;Administrator&#039;&#039;&#039; an account with enough privileges to add new machines to the domain.&amp;lt;br/&amp;gt; You&#039;ll need to type this account&#039;s password for the command to succeed.&lt;br /&gt;
&lt;br /&gt;
: In Windows environments you could also try executing the command (as root):&lt;br /&gt;
&lt;br /&gt;
  # net join DOMAINNAME -S DCSERVER -U Administrator&lt;br /&gt;
&lt;br /&gt;
: where DCSERVER is the Domain Controller server&lt;br /&gt;
&lt;br /&gt;
: Also, make sure you have disabled &amp;quot;Microsoft Network Server: digitally sign communications (always)&amp;quot; in your Domain Controllers Security Policy, unless you are using a version of Samba that can sign SMB packets.&lt;br /&gt;
&lt;br /&gt;
* Restart the &amp;lt;tt&amp;gt;winbind&amp;lt;/tt&amp;gt; service to apply the changes and test that it&#039;s running ok by executing:&lt;br /&gt;
&lt;br /&gt;
  $ wbinfo -u&lt;br /&gt;
&lt;br /&gt;
: You should get the full list of Windows domain users. If you use &#039;&#039;&#039;&amp;lt;tt&amp;gt;-g&amp;lt;/tt&amp;gt;&#039;&#039;&#039; instead, you&#039;ll get the domain groups list.&lt;br /&gt;
&lt;br /&gt;
* Check that your &amp;lt;tt&amp;gt;winbind&amp;lt;/tt&amp;gt; package installed the authentication helper command &amp;lt;tt&amp;gt;ntlm_auth&amp;lt;/tt&amp;gt;, as we&#039;ll need it later. We&#039;ll assume the helper is located at &amp;lt;tt&amp;gt;/usr/bin/ntlm_auth&amp;lt;/tt&amp;gt;. If yours is at a different location, make sure you adjust the path in the example below.&lt;br /&gt;
&lt;br /&gt;
* Add something like this to your Apache configuration file (usually called &amp;lt;tt&amp;gt;apache2.conf&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;http2.conf&amp;lt;/tt&amp;gt;). We&#039;ll assume that your Moodle &amp;lt;tt&amp;gt;$CFG-&amp;gt;dirroot&amp;lt;/tt&amp;gt; directory is located at &amp;lt;tt&amp;gt;/var/www/moodle&amp;lt;/tt&amp;gt; in the example:&lt;br /&gt;
: &#039;&#039;&#039;For 1.9 or above use&#039;&#039;&#039;:&lt;br /&gt;
    &amp;lt;Directory &amp;quot;/var/www/moodle/auth/ldap/&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;Files ntlmsso_magic.php&amp;gt;&lt;br /&gt;
            NTLMAuth on&lt;br /&gt;
            AuthType NTLM&lt;br /&gt;
            AuthName &amp;quot;Moodle NTLM Authentication&amp;quot;&lt;br /&gt;
            NTLMAuthHelper &amp;quot;/usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp&amp;quot;&lt;br /&gt;
            NTLMBasicAuthoritative on&lt;br /&gt;
            require valid-user&lt;br /&gt;
        &amp;lt;/Files&amp;gt;&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
: &#039;&#039;&#039;For 1.8 or below use&#039;&#039;&#039;:&lt;br /&gt;
    &amp;lt;Directory &amp;quot;/var/www/moodle/auth/ntlm/&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;Files oncampuslogin.php&amp;gt;&lt;br /&gt;
            NTLMAuth on&lt;br /&gt;
            AuthType NTLM&lt;br /&gt;
            AuthName &amp;quot;Moodle NTLM Authentication&amp;quot;&lt;br /&gt;
            NTLMAuthHelper &amp;quot;/usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp&amp;quot;&lt;br /&gt;
            NTLMBasicAuthoritative on&lt;br /&gt;
            require valid-user&lt;br /&gt;
        &amp;lt;/Files&amp;gt;&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
* Check the permissions of the Winbind pipe directory (Ubuntu places it under &amp;lt;tt&amp;gt;/var/run/samba/winbindd_privileged&amp;lt;/tt&amp;gt;, yours may be placed at a different location). Apache will need to be able to enter that directory, so we need to make sure it has the right permissions. So have a look at the permissions of that directory and note the name of the group assigned to it. The following example is from a Ubuntu 7.10 machine:&lt;br /&gt;
&lt;br /&gt;
  $ ls -ald /var/run/samba/winbindd_privileged&lt;br /&gt;
  drwxr-x--- 2 root winbindd_priv 60 2007-11-17 16:18 /var/run/samba/winbindd_privileged/&lt;br /&gt;
&lt;br /&gt;
:so we see the group is &amp;lt;tt&amp;gt;winbindd_priv&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Instead of modifying the directory permissions (which could break other services that use winbind) we are going to make the Apache user (&amp;lt;tt&amp;gt;www-data&amp;lt;/tt&amp;gt; in our example, but could be &amp;lt;tt&amp;gt;httpd&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;nobody&amp;lt;/tt&amp;gt;, etc.) is part of the appropiate group. Execute the following as root:&lt;br /&gt;
&lt;br /&gt;
  # adduser www-data winbindd_priv&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tt&amp;gt;adduser&amp;lt;/tt&amp;gt; is available in Debian and Ubuntu at least. If your distribution doesn&#039;t have &amp;lt;tt&amp;gt;adduser&amp;lt;/tt&amp;gt;, you can edit &amp;lt;tt&amp;gt;/etc/group&amp;lt;/tt&amp;gt; manually to achive the same effect.&lt;br /&gt;
&lt;br /&gt;
* Stop and start the Apache service to apply the changes. Have a look at Apache&#039;s error log to see that everything is ok.&lt;br /&gt;
&lt;br /&gt;
* Couple of gotchas - in Fedora Core (and also in Redhat/Centos), keep alive is turned OFF by default in the httpd.conf - see this bug for further info: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=188138&amp;lt;br /&amp;gt;&lt;br /&gt;
simply change the line to that was:&lt;br /&gt;
 KeepAlive Off&lt;br /&gt;
to:&lt;br /&gt;
 KeepAlive On&lt;br /&gt;
and restart apache (/etc/init.d/http restart)&lt;br /&gt;
* Email Dan if you get this working - I&#039;m keen to hear how people go using the samba winbind option!&lt;br /&gt;
::-- Hi Dan! I made it work using Ubuntu 7.04. That&#039;s what I&#039;ve used to update the documentation. [[User:Iñaki Arenaza|Iñaki Arenaza]] 10:43, 30 September 2007 (CDT)&lt;br /&gt;
::-- Hi Dan! I have this working on Ubuntu 8.04 LTS in an RM CC4 Active Directory Domain. [[User:munk3h|Ian]] 16:31 15 December 2009 (GMT)&lt;br /&gt;
&lt;br /&gt;
====Using the NTLM Auth Module for Apache on Linux====&lt;br /&gt;
The NTLM Auth module is a bit stale and even its authors suggest that you use the [[#Using_the_NTLM_part_of_Samba_for_Apache_on_Linux|NTLM part of Samba with Apache on Linux]]&lt;br /&gt;
&lt;br /&gt;
Get it from here &lt;br /&gt;
# get the Module from: http://modntlm.sourceforge.net/&lt;br /&gt;
# follow the instructions given there and inside the README that comes with the package.&lt;br /&gt;
&lt;br /&gt;
I (Iñaki Arenaza) strongly recommend using the [[#Using_the_NTLM_part_of_Samba_for_Apache_on_Linux|NTLM part of Samba with Apache on Linux]] over this module. It&#039;s better maintained, more robust and has more features.&lt;br /&gt;
&lt;br /&gt;
====Using the mod_auth_sspi Module for Apache 2 on Windows====&lt;br /&gt;
NOTE: This setup is currently being used in a live production environment, and is therefore suitable for such use provided it is correctly configured and tested.&lt;br /&gt;
&lt;br /&gt;
This is the recommended method for Apache 2 on Windows, however it will &#039;&#039;&#039;not&#039;&#039;&#039; work on Linux/UNIX systems.&lt;br /&gt;
It provides better stability and higher performance than other NTLM modules.&lt;br /&gt;
&lt;br /&gt;
* Download the mod_auth_sspi Module from: http://sourceforge.net/projects/mod-auth-sspi/. At the moment of writing this (2007.09.30), the current version is mod_auth_sspi 1.0.4, which has two different ZIP files to download:&lt;br /&gt;
&lt;br /&gt;
::* mod_auth_sspi-1.0.4-2.0.58.zip :   Use this file if you are using Apache 2.0.x.&lt;br /&gt;
::* mod_auth_sspi-1.0.4-2.2.2.zip :   Use this file if you are using Apache 2.2.x.&lt;br /&gt;
&lt;br /&gt;
* Unzip the right file and copy mod_auth_sspi.so (it&#039;s inside &#039;&#039;&#039;bin&#039;&#039;&#039; subdirectory) to your Apache modules directory.&lt;br /&gt;
* Edit your Apache 2 configuration file (httpd.conf) to load the module.&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;IfModule !mod_auth_sspi.c&amp;gt;&lt;br /&gt;
        LoadModule sspi_auth_module modules/mod_auth_sspi.so&lt;br /&gt;
    &amp;lt;/IfModule&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Choose one of the two methods below&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&#039;Method 1&#039;&#039;&#039;: This method is recommended for servers that will host a single Moodle instance. Configure NTLM from the main configuration file, add the following to httpd.conf (substitute &amp;quot;C:\moodle&amp;quot; with the path to your Moodle installation e.g. &amp;quot;C:\my-moodle&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:: &#039;&#039;&#039;For 1.9 or above use&#039;&#039;&#039;:&lt;br /&gt;
    &amp;lt;Directory &amp;quot;C:\moodle\auth\ldap&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;Files ntlmsso_magic.php&amp;gt;&lt;br /&gt;
            AuthName &amp;quot;Moodle at My College&amp;quot;&lt;br /&gt;
            AuthType SSPI&lt;br /&gt;
            SSPIAuth On&lt;br /&gt;
            SSPIOfferBasic Off&lt;br /&gt;
            SSPIAuthoritative On&lt;br /&gt;
            SSPIDomain mycollege.ac.uk&lt;br /&gt;
            require valid-user&lt;br /&gt;
        &amp;lt;/Files&amp;gt;&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
:: &#039;&#039;&#039;For 1.8 or below use&#039;&#039;&#039;:&lt;br /&gt;
    &amp;lt;Directory &amp;quot;C:\moodle\auth\ntlm&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;Files oncampuslogin.php&amp;gt;&lt;br /&gt;
            AuthName &amp;quot;Moodle at My College&amp;quot;&lt;br /&gt;
            AuthType SSPI&lt;br /&gt;
            SSPIAuth On&lt;br /&gt;
            SSPIOfferBasic Off&lt;br /&gt;
            SSPIAuthoritative On&lt;br /&gt;
            SSPIDomain mycollege.ac.uk&lt;br /&gt;
            require valid-user&lt;br /&gt;
        &amp;lt;/Files&amp;gt;&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&#039;Method 2&#039;&#039;&#039;: The alternative method is to use a .htaccess file&lt;br /&gt;
:This method is recommended for servers that will host multiple Moodle instances. It allows additional Moodle instances to be configured without restarting apache, and also makes the solution a little more portable. We need to add a directive to the main httpd.conf to allow configuration of authentication within .htaccess files.&lt;br /&gt;
    &amp;lt;Directory C:\moodle&amp;gt;&lt;br /&gt;
        AllowOverride AuthConfig&lt;br /&gt;
    &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:::Create a new text file named &#039;.htaccess&#039; in the directory &#039;C:\moodle\moodle\auth\ldap&#039; and add the following directives:&lt;br /&gt;
    &amp;lt;Files ntlmsso_magic.php&amp;gt;&lt;br /&gt;
        AuthName &amp;quot;Moodle at My College&amp;quot;&lt;br /&gt;
        AuthType SSPI&lt;br /&gt;
        SSPIAuth On&lt;br /&gt;
        SSPIOfferBasic Off&lt;br /&gt;
        SSPIAuthoritative On&lt;br /&gt;
        SSPIDomain mycollege.ac.uk&lt;br /&gt;
        require valid-user&lt;br /&gt;
    &amp;lt;/Files&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:This enables the Moodle folder to be moved to any apache webserver that is configured to allow authentication configuration through .htaccess&lt;br /&gt;
&lt;br /&gt;
For further help and discussion: http://moodle.org/mod/forum/discuss.php?d=56565&lt;br /&gt;
&lt;br /&gt;
====Using the Kerberos Auth Module for Apache on Linux/UNIX (mod_auth_kerb)====&lt;br /&gt;
*Install and configure http://modauthkerb.sourceforge.net/&lt;br /&gt;
*Configuration of mod_auth_kerb in a Microsoft Windows Active Directory environment (AD 2003 and above) (http://grolmsnet.de/kerbtut/)&lt;br /&gt;
&lt;br /&gt;
Environment details in this example:&lt;br /&gt;
#&#039;&#039;&#039;Active Directory Domain:&#039;&#039;&#039; EXAMPLE.AC.UK&lt;br /&gt;
#&#039;&#039;&#039;Active Directory Domain Controller:&#039;&#039;&#039; dc.example.ac.uk&lt;br /&gt;
#&#039;&#039;&#039;Linux/UNIX web server:&#039;&#039;&#039; moodle.example.ac.uk&lt;br /&gt;
#&#039;&#039;&#039;Active Directory user account for web server service principal:&#039;&#039;&#039; moodlekerb&lt;br /&gt;
&lt;br /&gt;
Install kerberos on moodle.example.ac.uk and enter the following in krb5.conf (by default: /etc/krb5.conf)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[libdefaults]&lt;br /&gt;
    default_realm = EXAMPLE.AC.UK&lt;br /&gt;
[domain_realm]&lt;br /&gt;
    example.ac.uk = EXAMPLE.AC.UK&lt;br /&gt;
[realms]&lt;br /&gt;
     EXAMPLE.AC.UK = {&lt;br /&gt;
                      admin_server = dc.example.ac.uk&lt;br /&gt;
                      kdc          = dc.example.ac.uk&lt;br /&gt;
                    }:&lt;br /&gt;
* Test kerberos&lt;br /&gt;
Issue the following command at the shell prompt:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$&amp;gt; kinit user@EXAMPLE.AC.UK&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &#039;user&#039; is an Active Directory account for which you know the password.&lt;br /&gt;
&lt;br /&gt;
Next, issue the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;$&amp;gt;klist&amp;lt;/pre&amp;gt;&lt;br /&gt;
If all is OK it will list the Kerberos ticket you were granted from the domain controller (KDC)&lt;br /&gt;
&lt;br /&gt;
* Create HTTP service principal for moodle.example.ac.uk&lt;br /&gt;
#Create the &#039;moodlekerb&#039; &#039;&#039;&#039;user&#039;&#039;&#039; account in Active Directory (NOT a machine account) to map to the web server service principal (HTTP/moodle.example.ac.uk@EXAMPLE.AC.UK)&lt;br /&gt;
NOTE: moodle.example.ac.uk MUST be the canonical DNS name of the server i.e. an A record (NOT a CNAME). Additionally a valid PTR (reverse DNS) record must exist and match the corresponding A record.&lt;br /&gt;
&lt;br /&gt;
#Use the ktpass.exe utility to map the service principal and create a keytab file&lt;br /&gt;
Apache requires a keytab file, which is generated with ktpass.exe on the Windows Active Directory Domain Controller.&lt;br /&gt;
Shockingly, this component of Windows Server 2003 SP1 does not function correctly so one must obtain a hot fix: http://support.microsoft.com/kb/919557&lt;br /&gt;
&lt;br /&gt;
Run the following command on the domain controller:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
C:\path\to\hotfix\ktpass.exe -princ HTTP/moodle.example.ac.uk@EXAMPLE.AC.UK -mapuser EXAMPLE\moodlekerb -crypto DES-CBC-MD5 +DesOnly +setPass +rndPass -ptype KRB5_NT_PRINCIPAL -out moodle.example.ac.uk.keytab&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy C:\path\to\hotfix\moodle.example.ac.uk.keytab to the moodle web server and remember the location (/etc/httpd/moodle.example.ac.uk.keytab or similar)&lt;br /&gt;
&lt;br /&gt;
* Configure Apache / mod_auth_kerb&lt;br /&gt;
Edit the Apache configuration for the moodle host and add the following directives:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        &amp;lt;Directory /path/to/moodle/docs/auth/ldap/&amp;gt;&lt;br /&gt;
                &amp;lt;Files ntlmsso_magic.php&amp;gt;&lt;br /&gt;
                        AuthName &amp;quot;Moodle&amp;quot;&lt;br /&gt;
                        AuthType Kerberos&lt;br /&gt;
                        KrbAuthRealms EXAMPLE.AC.UK&lt;br /&gt;
                        KrbServiceName HTTP&lt;br /&gt;
                        Krb5Keytab /etc/httpd/moodle.example.ac.uk.keytab&lt;br /&gt;
                        KrbMethodNegotiate on&lt;br /&gt;
                        KrbMethodK5Passwd on&lt;br /&gt;
                        KrbAuthoritative on&lt;br /&gt;
                        require valid-user&lt;br /&gt;
                &amp;lt;/Files&amp;gt;&lt;br /&gt;
        &amp;lt;/Directory&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Replace the &#039;&#039;&#039;ntlmsso_magic&#039;&#039;&#039; function in &#039;&#039;&#039;/auth/ldap/auth.php&#039;&#039;&#039; (1.9 only, as 2.x already support Kerberos format out of the box) with the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function ntlmsso_magic($sesskey) {&lt;br /&gt;
        if (isset($_SERVER[&#039;REMOTE_USER&#039;]) &amp;amp;&amp;amp; !empty($_SERVER[&#039;REMOTE_USER&#039;])) {&lt;br /&gt;
&lt;br /&gt;
            // HTTP __headers__ seem to be sent in ISO-8859-1 encoding&lt;br /&gt;
            // (according to my reading of RFC-1945, RFC-2616 and RFC-2617 and&lt;br /&gt;
            // my local tests), so we need to convert the REMOTE_USER value&lt;br /&gt;
            // (i.e., what we got from the HTTP WWW-Authenticate header) into UTF-8&lt;br /&gt;
            $textlib = textlib_get_instance();&lt;br /&gt;
            $username = $textlib-&amp;gt;convert($_SERVER[&#039;REMOTE_USER&#039;], &#039;iso-8859-1&#039;, &#039;utf-8&#039;);&lt;br /&gt;
            &lt;br /&gt;
            /**&lt;br /&gt;
             * begin kerberos - afhole@wortech.ac.uk 21-04-2009&lt;br /&gt;
             */&lt;br /&gt;
            if ($pos = strpos($username, &amp;quot;@&amp;quot;)) {&lt;br /&gt;
                $username = substr($username, 0, $pos);&lt;br /&gt;
            } else {&lt;br /&gt;
                $username = substr(strrchr($username, &#039;\\&#039;), 1); //strip domain info&lt;br /&gt;
            }&lt;br /&gt;
            /**&lt;br /&gt;
             * end kerberos&lt;br /&gt;
             */&lt;br /&gt;
&lt;br /&gt;
            $username = moodle_strtolower($username); //compatibility hack&lt;br /&gt;
            set_cache_flag(&#039;auth/ldap/ntlmsess&#039;, $sesskey, $username, AUTH_NTLMTIMEOUT);&lt;br /&gt;
            return true;&lt;br /&gt;
        }&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code change will account for the fact that Kerberos presents the username to REMOTE_USER in the format user@DOMAIN, rather than NTLM&#039;s DOMAIN\user&lt;br /&gt;
&lt;br /&gt;
==Configuring IP/Subnet Mask==&lt;br /&gt;
Subnet masks are based on binary patterns so need a bit of knowledge to understand. The best way to find out what IP/Subnet masks to use is to ask your Network Admin. &lt;br /&gt;
&lt;br /&gt;
* The new way of specifiying subnets is even easier/more flexible than before 1.9. Just type them one after the other, separated by commas. You can use several syntaxes:&lt;br /&gt;
** Type the network-number/prefix-length combination. E.g. 192.168.1.0/24&lt;br /&gt;
** Type the network &#039;prefix&#039;, ending in a period character. E.g. 192.168.1.&lt;br /&gt;
** Type the network address range (&#039;&#039;&#039;this only works for the last address octect&#039;&#039;&#039;). E.g. 192.168.1.1-254&lt;br /&gt;
:All the three examples refer to the same subnetwork. So assuming you need to specify the following subnetworks:&lt;br /&gt;
::* 10.1.0/255.255.0.0&lt;br /&gt;
::* 10.2.0.0/255.255.0.0&lt;br /&gt;
::* 172.16.0.0/255.255.0.0&lt;br /&gt;
::* 192.168.100.0/255.255.255.240&lt;br /&gt;
:You can type:&lt;br /&gt;
 10.1.0.0/16, 10.2.0.0/16, 172.16.0.0/16, 192.168.100.0/28&lt;br /&gt;
: or:&lt;br /&gt;
  10.1.0.0/16, 10.2.0.0/16, 172.16.0.0/16, 192.168.100.240-255&lt;br /&gt;
:or even:&lt;br /&gt;
  10.1., 10.2., 172.16., 192.168.100.0/28&lt;br /&gt;
:(the last one cannot be expressed as a network &#039;prefix&#039; as the netmask does not fall on an octect boundary).&lt;br /&gt;
&lt;br /&gt;
==Notes/Tips==&lt;br /&gt;
&lt;br /&gt;
#If you are using Firefox, you will need to follow these steps:&lt;br /&gt;
:*Load Firefox and type about:config in the address box. The configuration settings page should be displayed.&lt;br /&gt;
:*In the Filter box, type the word &amp;quot;ntlm&amp;quot; to filter the NTLM strings. You should see three settings displayed.&lt;br /&gt;
:*Double-click on &amp;quot;network.automatic-ntlm-auth.trusted-uris&amp;quot;.&lt;br /&gt;
:*In the box, enter the full URL of your Moodle server. For example &amp;lt;pre&amp;gt;http://moodle.mydomain.com, (the comma is important)&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Close Firefox and restart.&lt;br /&gt;
# NTLM seems to not work at all when BASIC authentication is enabled. (this was using the Kerberos method, other ways may work)&lt;br /&gt;
# If the account in your AD management console shows like &amp;quot;First Last&amp;quot;, you better change the ldap settings parameter &#039;User Attribute&#039; from its default of {blank} / &#039;cn&#039; to &#039;sAMAccountName&#039; as indicated in [http://moodle.org/mod/forum/discuss.php?d=132364#p682173 this post]. The reason is that the cn name generally looks like &amp;quot;First Last&amp;quot;, once you done the ldap sync, the user name in moodle will be &amp;quot;first last&amp;quot;, but IE passes the account of &amp;quot;domain\first.last&amp;quot; to moodle which does not exist in moodle.&lt;br /&gt;
&lt;br /&gt;
== To get a domain name for Moodle working on IIS7.5 Windows 2008 R2 ==&lt;br /&gt;
Refer to http://support.microsoft.com/kb/896861. Key section listed below.&lt;br /&gt;
Click Start, click Run, type regedit, and then click OK.&amp;lt;br /&amp;gt;&lt;br /&gt;
In Registry Editor, locate and then click the following registry key: &lt;br /&gt;
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0&amp;lt;br /&amp;gt;&lt;br /&gt;
Right-click MSV1_0, point to New, and then click Multi-String Value.&amp;lt;br /&amp;gt;&lt;br /&gt;
Type BackConnectionHostNames, and then press ENTER.&amp;lt;br /&amp;gt;&lt;br /&gt;
Right-click BackConnectionHostNames, and then click Modify.&amp;lt;br /&amp;gt;&lt;br /&gt;
In the Value data box, type the host name or the host names for the sites that are on the local computer, and then click OK.&amp;lt;br /&amp;gt;&lt;br /&gt;
Quit Registry Editor, and then restart the IISAdmin service.&lt;br /&gt;
&lt;br /&gt;
==Compiling mod_auth_ntlm_winbind on Debian/Ubuntu==&lt;br /&gt;
You need to install the following packages (and all of their dependencies) by using aptitude, synaptic, etc.:&lt;br /&gt;
&lt;br /&gt;
  autoconf apache2-threaded-dev debian-builder&lt;br /&gt;
&lt;br /&gt;
Once you have them installed, open up a text console, go to the directory where you downloaded the mod_auth_ntlm_winbind files an execute the following commands (as a normal user):&lt;br /&gt;
&lt;br /&gt;
  autoconf&lt;br /&gt;
  ./configure --with-apxs=/usr/bin/apxs2 --with-apache=/usr/sbin/apache2&lt;br /&gt;
  make&lt;br /&gt;
&lt;br /&gt;
That should compile it without errors. Then as a user that can run commands as root via sudo, execute the following command from the same directory:&lt;br /&gt;
&lt;br /&gt;
  sudo make install&lt;br /&gt;
&lt;br /&gt;
This will create the final mod_auth_ntlm_winbind.so file and install it under /usr/lib/apache2/modules, with the rest of the Apache 2 modules (the size of the file and last modification time shown below may differ from your install):&lt;br /&gt;
&lt;br /&gt;
  ls -l /usr/lib/apache2/modules/mod_auth_ntlm_winbind.so&lt;br /&gt;
  -rw-r--r-- 1 root root 20921 2009-02-17 04:27 /usr/lib/apache2/modules/mod_auth_ntlm_winbind.so&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://moodle.org/mod/forum/view.php?id=42 Using Moodle: User authentication] forum&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=45887 NTLM Authentication] forum discussion&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=80104 Merging AD NTLM SSO into auth/ldap] forum discussion&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=186661 Moodle in a DMZ with NTLM] forum discussion&lt;br /&gt;
*[http://moodle.org/mod/data/view.php?d=13&amp;amp;rid=314 Download the NTLM Authentication Module]&lt;br /&gt;
&lt;br /&gt;
[[Category:Contributed code]]&lt;br /&gt;
[[Category:Authentication]]&lt;br /&gt;
&lt;br /&gt;
[[fr:Authentification NTLM]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Flat_file&amp;diff=88430</id>
		<title>Flat file</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Flat_file&amp;diff=88430"/>
		<updated>2011-08-25T17:34:20Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* See also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Location: Flat file edit settings link in &#039;&#039;Site administration &amp;gt; Plugins &amp;gt; Enrolments &amp;gt; Manage enrol plugins&#039;&#039; in 2.0 onwards or &#039;&#039;Administration &amp;gt; Courses &amp;gt; Enrolments&#039;&#039; pre-2.0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A flat file allows bulk enrolment management (enrol or unenrol) of existing users in existing course. The file is read one time by Moodle then erased. The file is located in the moodle file structure as a text file and [[Cron]] provides the timing when it is read.  &lt;br /&gt;
&lt;br /&gt;
==Options==&lt;br /&gt;
The site administrator should edit the settings for a flat file if it is enabled. &lt;br /&gt;
[[Image:Enrolment Flat file options.png|thumb|center|Options for flat file enrolment]] &lt;br /&gt;
&lt;br /&gt;
Version 2.0&lt;br /&gt;
&lt;br /&gt;
[[Image:EnrolSettngsFlatFile 2.0.png]]&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
:You should specify an absolute path for the upload file (eg /var/moodledata/enrolments.txt) where it can be read and modified by the webserver process.&lt;br /&gt;
&lt;br /&gt;
You can choose to have an email sent to notify the Administrator, Teachers and/or students when the file has been processed.&lt;br /&gt;
&lt;br /&gt;
==Flat file structure==&lt;br /&gt;
The file should be structured with the action, role, user id, and course ID number.  Optionally a start time and end time can be added as additional fields.&lt;br /&gt;
&lt;br /&gt;
The edit field link will give details on how to format the flat file on the Administration &amp;gt; Courses &amp;gt; Enrolments&#039;&#039; page.&lt;br /&gt;
&lt;br /&gt;
[[Image:Enrolment Flat file data.png|thumb|center|Flat file instructions for fields and records]]&lt;br /&gt;
 &lt;br /&gt;
==See also==&lt;br /&gt;
*[[Upload users]]&lt;br /&gt;
*[[Bulk user actions]] how to download site user information (including userIDs)&lt;br /&gt;
Using Moodle forum discussions:&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=13289 How does flat file work?]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=144997 Flat file enrolments - how is this typically used by organisations?]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=45514 un-enroll a user from a course]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=79250 flat file unenroll]&lt;br /&gt;
&lt;br /&gt;
[[Category:Enrolment]]&lt;br /&gt;
&lt;br /&gt;
[[fr:Inscription par fichier plat]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Upload_users&amp;diff=86100</id>
		<title>Upload users</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Upload_users&amp;diff=86100"/>
		<updated>2011-07-16T15:44:50Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* See also link: Stanmdardise usernames */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Accounts}}&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&#039;&#039;&#039;Please refer to [[TOC_with_notes#Accounts|these notes]] before editing this page.&#039;&#039;&#039;&amp;lt;/p&amp;gt;&lt;br /&gt;
Location: &#039;&#039;Administration &amp;gt; Users &amp;gt; Accounts &amp;gt; Upload users&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Image:Upload users preview.png|thumb|Upload users preview in Moodle 1.9]]&lt;br /&gt;
Firstly, note that it is usually not necessary to import users in bulk - to keep maintenance work down you should first explore forms of authentication that do not require manual maintenance, such as [[External database authentication|connecting to existing external databases]] or letting the [[Internal enrolment|users create their own accounts]]. See [[Manage authentication]] for more information.&lt;br /&gt;
&lt;br /&gt;
If you are sure you want to import multiple user accounts from a text file, then you need to format your text file as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Upload users file format==&lt;br /&gt;
&lt;br /&gt;
* Each line contains fields &#039;&#039;&#039;separated&#039;&#039;&#039; by commas (or other delimiters) without quotes (&amp;quot;) and no trailing delimiter&lt;br /&gt;
* The first line is special, and contains fieldnames defining the format for the rest of the file.&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Required fields&#039;&#039;&#039;:  In any order&lt;br /&gt;
:&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;username, firstname, lastname, email&amp;lt;/code&amp;gt;&lt;br /&gt;
:Validity checks are performed for:&lt;br /&gt;
#&amp;lt;code&amp;gt;username&amp;lt;/code&amp;gt; can only contain alphabetical &#039;&#039;&#039;lowercase&#039;&#039;&#039; letters , numbers, hypen &#039;-&#039;, underscore &#039;_&#039;, period &#039;.&#039;, or at-sign &#039;@&#039; &lt;br /&gt;
#&amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; is in the form: &#039;&#039;name@example.com&#039;&#039; .&amp;lt;/p&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Password field&#039;&#039;&#039;: &amp;quot;password&amp;quot; field is optional if &amp;quot;Create password if needed&amp;quot; setting is chosen (default). &lt;br /&gt;
**If included, values should meet the requirements for the site&#039;s [[Site_policies#Password_policy|Password policy]]. To force password change for a particular user, set the password field to &amp;lt;code&amp;gt;changeme&amp;lt;/code&amp;gt;. &lt;br /&gt;
**If omitted, a password will be generated for each user (during the next Cron job) and welcome e-mails sent out (not working in v2.0.2?).&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Optional fields&#039;&#039;&#039;: To provide values other than the default include one or more of these&lt;br /&gt;
:&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;institution, department, city, country, lang, auth, ajax, timezone, idnumber, icq, phone1, phone2, address, url, description, mailformat, maildisplay, htmleditor, autosubscribe, emailstop&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Custom profile field names&#039;&#039;&#039;: (Optional). xxxxx is the real custom user profile field name (i.e. the unique shortname)&lt;br /&gt;
:&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;profile_field_xxxxx&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
: Create the custom fields BEFORE importing. Use the standard header. The &amp;quot;shortname&amp;quot; for your custom field is xxxxx (NB: as at v2.0.2, the shortname must be all lowercase, otherwise won&#039;t be recognised). The first record must include &amp;quot;profile_field_xxxxx&amp;quot;.&lt;br /&gt;
:&#039;&#039;&#039;Example&#039;&#039;&#039;: To create a custom field &amp;quot;genre&amp;quot;, you must write a shortname &amp;quot;genre&amp;quot; in the new field, and write &amp;quot;profile_field_genre&amp;quot; in the header of the .csv file.&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Special fields&#039;&#039;&#039;: Used for changing of usernames or deleting of users&lt;br /&gt;
:&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;oldusername&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;deleted&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
*&#039;&#039;&#039;Enrolment fields&#039;&#039;&#039;: (Optional):&lt;br /&gt;
:&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;course1, type1, role1, group1, enrolperiod1, course2, type2, role2, group2, enrolperiod2&amp;lt;/code&amp;gt; etc.&lt;br /&gt;
**&amp;lt;code&amp;gt;course&amp;lt;/code&amp;gt; is the &amp;quot;shortname&amp;quot;  if present the user will be enrolled in those courses.&lt;br /&gt;
** &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; refers to the role to be used for associated course enrolment. Value 1 is default course role, 2 is legacy Teacher role and 3 is legacy Non-editing Teacher.&lt;br /&gt;
** You can use role field instead to specify roles directly - use either role short name or id (numeric names of roles are not supported).&lt;br /&gt;
** Users may be also assigned to groups in course (group1 in course1, group2 in course2, etc.).&lt;br /&gt;
*** A group is identified by name or id (numeric group names are not supported).&lt;br /&gt;
** From Moodle 2.0, you can set the enrolment duration, in days, for each course (&amp;lt;code&amp;gt;enrolperiod1&amp;lt;/code&amp;gt; for &amp;lt;code&amp;gt;course1&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;enrolperiod2&amp;lt;/code&amp;gt; for &amp;lt;code&amp;gt;course2&amp;lt;/code&amp;gt;, etc.).&lt;br /&gt;
&lt;br /&gt;
Commas within  a field must be encoded as &amp;amp;#44 - the script will decode these back to commas.&lt;br /&gt;
&lt;br /&gt;
For Boolean fields, use &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; for false and &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; for true.&lt;br /&gt;
&lt;br /&gt;
Turn email off: &amp;lt;code&amp;gt;emailstop&amp;lt;/code&amp;gt; set to &amp;lt;CODE&amp;gt;1&amp;lt;/CODE&amp;gt; if the email address should be disabled (default: email is enabled):&lt;br /&gt;
&lt;br /&gt;
To prevent users from receiving a large number of emails from courses or forced subscription forums use the &#039;&#039;&#039;maildigest&#039;&#039;&#039;.  The options for this field are 0 = No digest, 1 = Complete digest and 2 = Digest with just subjects.&lt;br /&gt;
&lt;br /&gt;
Here is an example of a valid upload file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;username, password, firstname, lastname, email, course1, group1&amp;lt;br /&amp;gt;&lt;br /&gt;
jonest, verysecret, Tom, Jones, jonest@someplace.edu, math102, Section 1&amp;lt;br /&amp;gt;&lt;br /&gt;
reznort, somesecret, Trent, Reznor, reznort@someplace.edu,math102, Section 3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Updating existing accounts==&lt;br /&gt;
By default Moodle  creates new user accounts, and skips lines where the &amp;lt;code&amp;gt;username&amp;lt;/code&amp;gt; matches an existing account. Set &amp;quot;Upload Type&amp;quot; to &#039;&#039;&#039;Add  new and update existing accounts&#039;&#039;&#039;, and existing user account will be updated.&lt;br /&gt;
&lt;br /&gt;
Include  fieldname &amp;lt;code&amp;gt;oldusername&amp;lt;/code&amp;gt; to updating existing accounts and change usernames.  In the preview options, Set &amp;quot;Allow renames&amp;quot; to &#039;&#039;&#039;Yes&#039;&#039;. &lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: errors updating existing accounts can affect your users badly. Be careful when using the options to update.&lt;br /&gt;
&lt;br /&gt;
==After preview==&lt;br /&gt;
After the preprocessing, depending on the contents of the upload, the following may be available before final user creation&lt;br /&gt;
*Settings&lt;br /&gt;
** New user password &lt;br /&gt;
** Existing user details&lt;br /&gt;
** Existing user password&lt;br /&gt;
** Allow renames&lt;br /&gt;
** Allow deletes&lt;br /&gt;
** Prevent email addess duplicates&lt;br /&gt;
** Select for bulk operations&lt;br /&gt;
&lt;br /&gt;
* Default values&lt;br /&gt;
** Authentication method: Manual account |no login | EMail-based self-registration&lt;br /&gt;
** Email display: Allow only other course members to see my email address | hide .. from everyone | allow anyone ...&lt;br /&gt;
** Email format Pretty HTML | plain text&lt;br /&gt;
** Email digest type: none|complete subjects&lt;br /&gt;
** Forum auto-subscribe: no |yes when  I post&lt;br /&gt;
** When editing text: use HTML| standard web forms&lt;br /&gt;
** AJAX and Javascript: yes|no&lt;br /&gt;
** city/town&lt;br /&gt;
** country&lt;br /&gt;
** timezone&lt;br /&gt;
** Preferred language&lt;br /&gt;
** Description&lt;br /&gt;
** Web page&lt;br /&gt;
** ID number&lt;br /&gt;
** Institution&lt;br /&gt;
** Department&lt;br /&gt;
** Phone&lt;br /&gt;
** Mobile Phone&lt;br /&gt;
** Address&lt;br /&gt;
&lt;br /&gt;
==After results ==&lt;br /&gt;
Users which were not added, will NOT be auto-enrolled in courses&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Open another moodle browser and &lt;br /&gt;
* Site administration&lt;br /&gt;
** Courses&lt;br /&gt;
*** Add/edit courses; select the category, and the course&lt;br /&gt;
* Course administration&lt;br /&gt;
** Users&lt;br /&gt;
*** Enrolled Users&lt;br /&gt;
**** Enrol users and select the users flagged from other window&lt;br /&gt;
&lt;br /&gt;
==Templates==&lt;br /&gt;
&lt;br /&gt;
The default values are processed as templates in which the following codes are allowed:&lt;br /&gt;
&lt;br /&gt;
* %l - will be replaced by the lastname&lt;br /&gt;
* %f - will be replaced by the firstname&lt;br /&gt;
* %u - will be replaced by the username&lt;br /&gt;
* %% - will be replaced by the %&lt;br /&gt;
&lt;br /&gt;
Between the percent sign (%) and any code letter (l, f or u) the following modifiers are allowed:&lt;br /&gt;
&lt;br /&gt;
* (-) minus sign - the information specified by the code letter will be converted to lowercase&lt;br /&gt;
* (+) plus sign - the information specified by the code letter will be converted to UPPERCASE&lt;br /&gt;
* (~) tilde sign - the information specified by the code letter will be converted to Title Case&lt;br /&gt;
* a decimal number - the information specified by the code letter will be truncated to that many characters&lt;br /&gt;
&lt;br /&gt;
For example, if the firstname is John and the lastname is Doe, the following values will be obtained with the specified templates:&lt;br /&gt;
&lt;br /&gt;
* %l%f = DoeJohn&lt;br /&gt;
* %l%1f = DoeJ&lt;br /&gt;
* %-l%+f = doeJOHN&lt;br /&gt;
* %-f_%-l = john_doe&lt;br /&gt;
* http://www.example.com/~%u/ = http://www.example.com/~jdoe/ (if the username is jdoe or %-1f%-l)&lt;br /&gt;
&lt;br /&gt;
Template processing is done only on default values, and not on the values retrieved from the CSV file.&lt;br /&gt;
&lt;br /&gt;
In order to create correct Moodle usernames, the username is always converted to lowercase. Moreover, if the &amp;quot;Allow extended characters in usernames&amp;quot; option in the Site policies page is off, characters different to letters, digits, dash (-) and dot (.) are removed. For example if the firstname is John Jr. and the lastname is Doe, the username %-f_%-l will produce john jr._doe when Allow extended characters in usernames is on, and johnjr.doe when off.&lt;br /&gt;
&lt;br /&gt;
When the &amp;quot;New username duplicate handling&amp;quot; setting is set to Append counter, an auto-increment counter will be append to duplicate usernames produced by the template. For example, if the CSV file contains the users named John Doe, Jane Doe and Jenny Doe without explicit usernames, the default username is %-1f%-l and New username duplicate handling is set to Append counter, then the usernames produced will be jdoe, jdoe2 and jdoe3. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Deleting accounts==&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;deleted&amp;lt;/code&amp;gt; field is present, users with value 1 for it will be deleted. In this case, all the fields may be omitted, except for &amp;lt;code&amp;gt;username&amp;lt;/code&amp;gt;. After uploading the file, be sure to change the &amp;quot;Upload type&amp;quot; to &amp;quot;Update existing users only&amp;quot; and the &amp;quot;Allow deletes&amp;quot; option to &amp;quot;Yes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Deleting and uploading accounts could be done with a single CSV file. For example, the following file will add the user Tom Jones and delete the user reznort:&lt;br /&gt;
&lt;br /&gt;
 username, firstname, lastname, deleted&lt;br /&gt;
 jonest, Tom, Jones, 0&lt;br /&gt;
 reznort, , , 1 &lt;br /&gt;
&lt;br /&gt;
==Encoding==&lt;br /&gt;
&lt;br /&gt;
In Moodle 1.8 the file must be UTF-8. In Moodle 1.9 onwards, the encoding may be selected from a large list, including ISO-8859-1.&lt;br /&gt;
&lt;br /&gt;
==Hints==&lt;br /&gt;
&lt;br /&gt;
===Spreadsheet===&lt;br /&gt;
&lt;br /&gt;
If you use a spreadsheet program such as Excel to create your .csv file, check the resulting output in a text editor before you upload it.  It is possible to get trailing commas on each line from an empty field if you have added and deleted columns of information prior to saving the final file. Also check the character encoding. A csv file is a simple text file (ASCII or Unicode) that can be used to upload user accounts.&lt;br /&gt;
&lt;br /&gt;
Excel translates passwords that begin with - (minus) or + (plus) as zero. Even when saving as .csv and saying &amp;quot;Yes&amp;quot; to &amp;quot;Keep this format, and leave out any incompatible features.&amp;quot; Check for this before uploading, as a zero halts the upload process.&lt;br /&gt;
&lt;br /&gt;
If you use a formula in Excel to create fields (for example, the concatenate function to create a user name), then remember to copy the cells with the formula and use special paste with values checked to make them into an acceptable data for a csv file.&lt;br /&gt;
&lt;br /&gt;
===Country===&lt;br /&gt;
The country should be written as a two letter code, in capitals. For example, use BE for Belgium or NL for the Netherlands.  Using &amp;quot;be&amp;quot; or &amp;quot;nl&amp;quot; as a country code will result in a database error.&lt;br /&gt;
:&#039;&#039;Tip:&#039;&#039;  If you are having trouble working out the two-letter code for a country, you can consult this Moodle source code file /moodle/lang/en_utf8/countries.php [http://cvs.moodle.org/moodle/lang/en_utf8/countries.php?view=markup&amp;amp;pathrev=MOODLE_19_STABLE or click here for a 1.9 STABLE list].&lt;br /&gt;
ISO Website: [http://www.iso.org/iso/country_codes/iso_3166_code_lists/english_country_names_and_code_elements.htm]&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
Moodle Docs:&lt;br /&gt;
*[[Flat file]]&lt;br /&gt;
&lt;br /&gt;
Using Moodle forum discussions:&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=36851 Can I auto enroll from Excel?]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=58215 Making Email Optional]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=97903 Uploading users to custom roles]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=181259 User upload option: standardise usernames]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=144569 Matriculacion con flat file csv] - discussion in Spanish&lt;br /&gt;
&lt;br /&gt;
[[Category:Authentication]]&lt;br /&gt;
[[Category:Enrolment]]&lt;br /&gt;
[[Category:Groups]]&lt;br /&gt;
&lt;br /&gt;
[[fr:Importer des utilisateurs]]&lt;br /&gt;
[[ja:ユーザのアップロード]]&lt;br /&gt;
[[zh:上传用户]]&lt;br /&gt;
[[ru:Загрузка пользователей]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Development:Weekly_Code_Review&amp;diff=83084</id>
		<title>Development:Weekly Code Review</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Development:Weekly_Code_Review&amp;diff=83084"/>
		<updated>2011-04-28T11:52:14Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* See also link */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Moodle has a weekly process of code review in the stable branches to help improve the quality of stable packages and to help detect any regressions that may have occurred in stable code.&lt;br /&gt;
&lt;br /&gt;
Here is the process for testers and developers:&lt;br /&gt;
&lt;br /&gt;
==Every Tuesday==&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t check any new fixes into CVS===&lt;br /&gt;
&lt;br /&gt;
HEAD is OK, but please avoid new fixes in all STABLE branches unless they are definitely definitely not going to cause new bugs  ;-)&lt;br /&gt;
&lt;br /&gt;
===Find bugs to test===&lt;br /&gt;
&lt;br /&gt;
All developers and testers should be looking at:&lt;br /&gt;
&lt;br /&gt;
 Moodle 1.9 stable:  [http://tracker.moodle.org/secure/IssueNavigator.jspa?mode=hide&amp;amp;requestId=10565 1.9.x Needs QA review]&lt;br /&gt;
&lt;br /&gt;
(Make sure you can see the QA Assigned column)&lt;br /&gt;
&lt;br /&gt;
Grab any bug that:&lt;br /&gt;
&lt;br /&gt;
* Is from the last week&lt;br /&gt;
* You did not fix&lt;br /&gt;
* Does not have a QA assignee yet &lt;br /&gt;
&lt;br /&gt;
and claim it by editing the bug to add your name as QA Assignee.&lt;br /&gt;
&lt;br /&gt;
===Test the fix===&lt;br /&gt;
&lt;br /&gt;
* Read the comments &lt;br /&gt;
* Look at the patch attached to the tracker&lt;br /&gt;
* Try the feature out to make sure it works as advertised &lt;br /&gt;
** Ensure you have debugging set to the DEBUG_DEVELOPER &amp;amp; look for new errors&lt;br /&gt;
** Test for potential regressions in other areas the fix may affect&lt;br /&gt;
* Post new comments (or talk on Moodle HQ) if you need clarification&lt;br /&gt;
&lt;br /&gt;
===Deal with any problems===&lt;br /&gt;
&lt;br /&gt;
* Post a comment on the bug with details (preferably including patch!)&lt;br /&gt;
* Reopen the bug&lt;br /&gt;
* If it looks like the original developer isn&#039;t seeing it, reassign to Eloy Lafuente for [[Development:Bug triage|triage]]&lt;br /&gt;
* If the fix is obvious and you have CVS access, fix it yourself&lt;br /&gt;
&lt;br /&gt;
===Mark the fix as reviewed===&lt;br /&gt;
&lt;br /&gt;
* When you are satisfied the bug is correctly fixed, simply change the status from Resolved to Closed&lt;br /&gt;
* If you committed any fix, let somebody else review it again - do not Close it yourself&lt;br /&gt;
&lt;br /&gt;
==Every Wednesday==&lt;br /&gt;
&lt;br /&gt;
* The download site will automatically tag the whole current stable codebase (e.g. MOODLE_19_WEEKLY) at 1:00 GMT on Wednesday morning and then build download packages&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=93474 Tuesday Code Reviews] forum discussion&lt;br /&gt;
*[[Development:Process]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Weekly Code Review]]&lt;br /&gt;
[[Category:Quality Assurance]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Development_talk:Git_for_developers&amp;diff=82544</id>
		<title>Development talk:Git for developers</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Development_talk:Git_for_developers&amp;diff=82544"/>
		<updated>2011-04-04T08:29:32Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Windows Git links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installing Git on your computer ==&lt;br /&gt;
Is this really the place for childish comments about the Windows OS? Some people don&#039;t have the luxury of choice when it comes to choosing their operating systems in their work environments... --[[User:Luis de Vasconcelos|Luis de Vasconcelos]] 06:02, 4 April 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
:Luis, apologies for the comment which has now been removed. Unfortunately I don&#039;t know how to install Git on a Windows computer - it would be great if you could help. --[[User:Helen Foster|Helen Foster]] 07:48, 4 April 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
:: ;-&amp;gt;   I&#039;m still not very familiar with Git so I haven&#039;t added anything to the docs. However, there do seem to be quite a few guides on the internet that explain Git on Windows, example: [http://nathanj.github.com/gitguide/tour.html An Illustrated Guide to Git on Windows] and [http://help.github.com/win-set-up-git/ Set Up Git (Windows)]. But we probably want something less &amp;quot;generic&amp;quot; and more Moodle specific. I&#039;ll make some notes once I&#039;ve figured it all out... --[[User:Luis de Vasconcelos|Luis de Vasconcelos]] 08:29, 4 April 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Development_talk:Git_for_developers&amp;diff=82511</id>
		<title>Development talk:Git for developers</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Development_talk:Git_for_developers&amp;diff=82511"/>
		<updated>2011-04-04T06:02:15Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Signature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installing Git on your computer ==&lt;br /&gt;
Is this really the place for childish comments about the Windows OS? Some people don&#039;t have the luxury of choice when it comes to choosing their operating systems in their work environments... --[[User:Luis de Vasconcelos|Luis de Vasconcelos]] 06:02, 4 April 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Development_talk:Git_for_developers&amp;diff=82510</id>
		<title>Development talk:Git for developers</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Development_talk:Git_for_developers&amp;diff=82510"/>
		<updated>2011-04-04T06:00:08Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Comments */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installing Git on your computer ==&lt;br /&gt;
Is this really the place for childish comments about the Windows OS? Some people don&#039;t have the luxury of choice when it comes to choosing their operating systems in their work environments...&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Development_talk:Themes_2.0_adding_a_settings_page&amp;diff=82382</id>
		<title>Development talk:Themes 2.0 adding a settings page</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Development_talk:Themes_2.0_adding_a_settings_page&amp;diff=82382"/>
		<updated>2011-03-29T14:12:33Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Printing problem */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Print Problem ==&lt;br /&gt;
&lt;br /&gt;
The code segments on this page contain tags like &amp;lt;nowiki&amp;gt;&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt; which adds scrollbars to the code blocks when viewed on the computer screen. This is fine on the screen as it reduces the size of the overall page, but when you print the document the content in those scrolling blocks (divs) is chopped off. Can we remove these divs or make them bigger so that the docs can be printed without data loss? --[[User:Luis de Vasconcelos|Luis de Vasconcelos]] 14:12, 29 March 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Development_talk:Themes_2.0_adding_a_settings_page&amp;diff=82381</id>
		<title>Development talk:Themes 2.0 adding a settings page</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Development_talk:Themes_2.0_adding_a_settings_page&amp;diff=82381"/>
		<updated>2011-03-29T14:09:00Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Printing problem */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The code segments on this page contain tags like &amp;lt;nowiki&amp;gt;&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt; which adds scrollbars to the code blocks when viewed on the computer screen. No problem. But when you print the document the content in those scrolling blocks (divs) is chopped off. Can we remove these divs or make them bigger so that the docs can be printed without data loss?&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Migration_from_MyISAM_to_InnoDB&amp;diff=82281</id>
		<title>Migration from MyISAM to InnoDB</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Migration_from_MyISAM_to_InnoDB&amp;diff=82281"/>
		<updated>2011-03-25T20:47:13Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* See also link */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{stub}}&lt;br /&gt;
This page only applies to administrators using Moodle with a MySQL database.&lt;br /&gt;
It&#039;s about migrating [http://dev.mysql.com/doc/refman/5.1/en/storage-engines.html MySQL storage engine].&lt;br /&gt;
&lt;br /&gt;
See [http://moodle.org/mod/forum/discuss.php?d=162871 Documentation for migration from MyISAM to InnoDB] for the current discussion which prompted the creation of this page. --[[User:Frank Ralf|Frank Ralf]] 11:41, 24 November 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Difference between MyISAM and InnoDB ==&lt;br /&gt;
* read [http://tag1consulting.com/MySQL_Engines_MyISAM_vs_InnoDB]&lt;br /&gt;
* InnoDB is best for data integrity, not so good for searching large files, and uses up more CPU cycles and storage space than MyISAM equivalent &lt;br /&gt;
* InnoDB is much younger than MyISAM but is becoming increasingly attractive ... but because it is more complex, some utilities written for MyISAM like mysqlhotcopy may not work&lt;br /&gt;
* It is perfectly OK to select InnoDB for certain tables, and MyISAM for others (based on above criteria)&lt;br /&gt;
&lt;br /&gt;
== MySQL Configuration ==&lt;br /&gt;
Before attempting to change the table type, you should:&lt;br /&gt;
* &#039;&#039;&#039;check InnoDB is enabled&#039;&#039;&#039;. Log in to MySQL and run the command [http://dev.mysql.com/doc/refman/5.1/en/show-engines.html SHOW ENGINES]. Make sure that support for InnoDB shows either &amp;quot;YES&amp;quot; or &amp;quot;DEFAULT&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;set innodb_file_per_table if required&#039;&#039;&#039;. [http://dev.mysql.com/doc/refman/5.1/en/innodb-multiple-tablespaces.html This setting] can be useful for large installations, but it only affects newly created tables and can&#039;t be applied retrospectively.&lt;br /&gt;
&lt;br /&gt;
== Various Methods described in Moodle Forums (choose one)==&lt;br /&gt;
* run the innodb script as a webpage http://www.YOUR_MOODLE_SITE/admin/innodb.php  (there might be timeout issues on large databases)&lt;br /&gt;
* use the CLI script in admin/cli/mysql_engine.php  (requires access to shell, and the config.php must only have one moodle instance, but has no timeout issues) &lt;br /&gt;
* use PHPMyAdmin entering Structure view of a table and clicking Operations tab. Look for Storage Engine parameter. This is a tedious task due to the number of tables [http://moodle.org/mod/forum/discuss.php?d=162002]&lt;br /&gt;
* perform a database dump (e.g. mysqldump moodle_database &amp;gt; dump.SQL), use an editor or sed/perl/awk command to find/replace , replacing MyISAM with InnoDB.  Finally, restore back in the server. (e.g. mysql &amp;lt; dump.SQL or equivalent)&lt;br /&gt;
* Follow the process detailed here - https://sites.google.com/site/moodlemayhem/tcea2011-moodle-server-setup-basics/moodleacidtrip&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=117913 New moodle.org] forum discussion&lt;br /&gt;
&lt;br /&gt;
* [http://tag1consulting.com/MySQL_Engines_MyISAM_vs_InnoDB MySQL Engines: MyISAM vs. InnoDB] article by Tag1 Consulting&lt;br /&gt;
&lt;br /&gt;
[[fr:Migration de MyISAM vers InnoDB]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Development_talk:Overview&amp;diff=81203</id>
		<title>Development talk:Overview</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Development_talk:Overview&amp;diff=81203"/>
		<updated>2011-02-09T12:48:52Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Comment */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hm, I find the quality control section rather short. Seems to me that a link to a more thorough introduction about who the testers are, what do testers do exactly (what is the core process) and whom to contact to learn more would be appropriate? --[[User:Olli Savolainen|Olli Savolainen]] 07:30, 22 June 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
It would be valuable to have information on this page about the concepts of &amp;quot;pulls&amp;quot; and &amp;quot;sprints&amp;quot; and all those new concepts. Or is this the wrong place? --[[User:Luis de Vasconcelos|Luis de Vasconcelos]] 12:48, 9 February 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=error/moodle/ddlexecuteerror&amp;diff=81103</id>
		<title>error/moodle/ddlexecuteerror</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=error/moodle/ddlexecuteerror&amp;diff=81103"/>
		<updated>2011-02-07T08:20:34Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Fix bullets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}&lt;br /&gt;
&lt;br /&gt;
This error indicates that an error occurred when the Moodle installer tried to run a SQL statement that makes changes to the Moodle database structure. This error will normally only occur during a Moodle installation or upgrade.&lt;br /&gt;
&lt;br /&gt;
To get more information about the error that caused this message you can enable the [[Debugging]] option in Moodle and then reattempt the Moodle installation. If the problem does occur again you will get a more detailed description of the problem. You can then use this information to report the problem to the Moodle developers via the Moodle [[Tracker]], which is the database for recording and managing Moodle bugs, improvements and feature requests.&lt;br /&gt;
&lt;br /&gt;
==Technical Information==&lt;br /&gt;
This error message is constructed by the &#039;&#039;ddl_change_structure_exception&#039;&#039; class in \lib\ddllib.php. This is a function that is used to trap errors that occur during Moodle database changes.&lt;br /&gt;
&lt;br /&gt;
The error can be triggered from one of two places in Moodle: &lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;execute_sql()&#039;&#039; function in \lib\ddl\database_manager.php. This function is part of the database_manager class and is responsible for all database structure modifications.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;query_end()&#039;&#039; function in \lib\dml\moodle_database.php which is called immediately after each database query. It is a &amp;quot;cleanup&amp;quot; routine that forms part of the the Moodle database interface.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Development:DDL functions]]&lt;br /&gt;
* Tracker issue: MDL-21874&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=error/moodle/ddlexecuteerror&amp;diff=81101</id>
		<title>error/moodle/ddlexecuteerror</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=error/moodle/ddlexecuteerror&amp;diff=81101"/>
		<updated>2011-02-07T07:48:08Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Description fix */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}&lt;br /&gt;
&lt;br /&gt;
This error indicates that an error occurred when the Moodle installer tried to run a SQL statement that makes changes to the Moodle database structure. This error will normally only occur during a Moodle installation or upgrade.&lt;br /&gt;
&lt;br /&gt;
To get more information about the error that caused this message you can enable the [[Debugging]] option in Moodle and then reattempt the Moodle installation. If the problem does occur again you will get a more detailed description of the problem. You can then use this information to report the problem to the Moodle developers via the Moodle [[Tracker]], which is the database for recording and managing Moodle bugs, improvements and feature requests.&lt;br /&gt;
&lt;br /&gt;
==Technical Information==&lt;br /&gt;
This error message is constructed by the &#039;&#039;ddl_change_structure_exception&#039;&#039; class in \lib\ddllib.php. This is a function that is used to trap errors that occur during Moodle database changes.&lt;br /&gt;
&lt;br /&gt;
The error can be triggered from one of two places in Moodle: &lt;br /&gt;
&lt;br /&gt;
- The &#039;&#039;execute_sql()&#039;&#039; function in \lib\ddl\database_manager.php. This function is part of the database_manager class and is responsible for all database structure modifications.&lt;br /&gt;
&lt;br /&gt;
- The &#039;&#039;query_end()&#039;&#039; function in \lib\dml\moodle_database.php which is called immediately after each database query. It is a &amp;quot;cleanup&amp;quot; routine that forms part of the the Moodle database interface.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Development:DDL functions]]&lt;br /&gt;
* Tracker issue: MDL-21874&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=error/moodle/ddlexecuteerror&amp;diff=81100</id>
		<title>error/moodle/ddlexecuteerror</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=error/moodle/ddlexecuteerror&amp;diff=81100"/>
		<updated>2011-02-07T07:44:43Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Added error description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}&lt;br /&gt;
&lt;br /&gt;
This error indicates that an error occurred when the Moodle installer tried to run a SQL statement that makes changes to the Moodle database structure. This error will normally only occur during a Moodle installation or upgrade.&lt;br /&gt;
&lt;br /&gt;
To get more information about the error that caused this message you can enable the [[Debugging]] option in Moodle and then reattempt the Moodle installation. If the problem does occur again you will get a more detailed description of the problem. You can then use this information to report the problem to the Moodle developers via the Moodle [[Tracker]], which is the database for recording and managing Moodle bugs, improvements and feature requests.&lt;br /&gt;
&lt;br /&gt;
==Technical Information==&lt;br /&gt;
This error message is constructed by the &#039;&#039;ddl_change_structure_exception&#039;&#039; class in \lib\ddllib.php. This is a PHP class used to trap errors that occur during database changes.&lt;br /&gt;
&lt;br /&gt;
The error can be triggered from one of two places in Moodle: &lt;br /&gt;
&lt;br /&gt;
- The &#039;&#039;execute_sql()&#039;&#039; function in \lib\ddl\database_manager.php. This function is part of the database_manager class and is responsible for all database structure modifications.&lt;br /&gt;
&lt;br /&gt;
- The &#039;&#039;query_end()&#039;&#039; function in \lib\dml\moodle_database.php which is called immediately after each database query. It is a &amp;quot;cleanup&amp;quot; routine that forms part of the the Moodle database interface.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Development:DDL functions]]&lt;br /&gt;
* Tracker issue: MDL-21874&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Course_files&amp;diff=80965</id>
		<title>Course files</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Course_files&amp;diff=80965"/>
		<updated>2011-01-31T14:38:33Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* See Also link */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}This page explains the legacy &amp;quot;Course files&amp;quot; area in Moodle 2, and related topics.&lt;br /&gt;
&lt;br /&gt;
It&#039;s useful for any teacher who wants to know how to add files to a Moodle 2.0 course (especially if you previously used Moodle 1.9 or earlier).&lt;br /&gt;
&lt;br /&gt;
==Files in Moodle 1.9==&lt;br /&gt;
&lt;br /&gt;
In versions of Moodle before 2.0 all the files uploaded into Moodle were stored in a physical directory on disk known as the &amp;quot;Course files&amp;quot; area.  &lt;br /&gt;
&lt;br /&gt;
This is where a teacher might upload files to be part of the course content, but this area also included everything students uploaded, such as assignments and forum attachments.  These &amp;quot;activity files&amp;quot; were stored in a special folder called &#039;&#039;moddata&#039;&#039; in a certain structure that helped modules keep track of their own files.&lt;br /&gt;
&lt;br /&gt;
===Typical Moodle 1.x workflows===&lt;br /&gt;
&lt;br /&gt;
The course files area was accessed in two ways through the Moodle interface by teachers.&lt;br /&gt;
&lt;br /&gt;
# Through the &amp;quot;Files&amp;quot; link in the Course Administration block, or&lt;br /&gt;
# When a file was required in other places, such as a resource, or attachment.&lt;br /&gt;
&lt;br /&gt;
When publishing a file as a resource, say a PDF file, a teacher might:&lt;br /&gt;
&lt;br /&gt;
# Upload it to their course files area along with all the other files they intend to use in the course&lt;br /&gt;
# Add a resource to the course&lt;br /&gt;
# Select the PDF from the course files&lt;br /&gt;
&lt;br /&gt;
Students did not have direct access to read the course files area. All they could do was upload files from their desktop computer straight into activities.&lt;br /&gt;
&lt;br /&gt;
===A less typical workflow===&lt;br /&gt;
&lt;br /&gt;
# Use [[wikipedia:FTP|FTP]] to push files straight into the course files area&lt;br /&gt;
# Add resources to the course by selecting these files&lt;br /&gt;
# Update the resources later by updating the files directly via FTP&lt;br /&gt;
&lt;br /&gt;
This meant expert users could update course content with files or HTML mini-sites without having to change anything in Moodle.&lt;br /&gt;
&lt;br /&gt;
===Problems with the Moodle 1.x model===&lt;br /&gt;
&lt;br /&gt;
* If the original file was deleted from course files area, or renamed, it would result in broken links everywhere where it was previously used&lt;br /&gt;
* Storing files on disk meant file names were restricted (eg file names in Japanese would break on some operating systems)&lt;br /&gt;
* All course files had to be readable by students (if they knew the URL) because Moodle had no way of telling what context you were viewing a file in (eg the same file might be in a HTML text in a forum and also in a resource).  This meant that files stored in the course files area were not as secret as teachers thought they were.&lt;br /&gt;
* Files could not be reused in several courses - that had to be uploaded to each course files area&lt;br /&gt;
* Backups had to include ALL course files, just in case they were required, even if the backup only contained one activity&lt;br /&gt;
* Images and other media might look fine for teachers, but others would not see it (eg in course descriptions)&lt;br /&gt;
* When importing activities from one course to another, ALL course files were imported, as it was impossible to tell which files were needed&lt;br /&gt;
&lt;br /&gt;
==Files in Moodle 2.0==&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 the files work a lot more like Web 2.0 systems, such as Facebook and Google Docs.&lt;br /&gt;
&lt;br /&gt;
Each activity and each text has its own file area, and files are associated directly with the place it is used.  For example, a file attached to a forum post is stored &amp;quot;with&amp;quot; the forum post, and becomes subject to exactly the same access restrictions.&lt;br /&gt;
&lt;br /&gt;
The Files system is intimately connected with the Repository system, and a file picker which makes it easy to browse external and internal repositories for files, and then copy them into Moodle.  Certain repositories also allow you to link directly to their media files.  Repositories in general are the way of the future for content - most Web 2.0 systems are really repositories of data with various management interfaces.&lt;br /&gt;
&lt;br /&gt;
A private files area is provided for each user to store a collection of files for their own use.  This is useful for students as well as teachers, and makes it easy to re-use media across the Moodle site.  Only you can access your own private files.&lt;br /&gt;
&lt;br /&gt;
The course files area in Moodle 2.0 is [[wikipedia:Deprecation|deprecated]] and is not available by default due to the problems described above. When a site is upgraded from 1.9, all course files are migrated into new file areas and the old course files area is hidden from view.&lt;br /&gt;
&lt;br /&gt;
Internally, files are stored in a &amp;quot;file pool&amp;quot; of blobs on disk with numbers for names.  All the actual names and metadata are stored in a database.&lt;br /&gt;
&lt;br /&gt;
===Typical Moodle 2.0 workflow===&lt;br /&gt;
&lt;br /&gt;
# Edit a text or activity &lt;br /&gt;
# Use the filepicker to easily select the file from any local or remote repository&lt;br /&gt;
&lt;br /&gt;
The file is then copied to Moodle and stored securely with the text or activity.&lt;br /&gt;
&lt;br /&gt;
===More advanced Moodle 2.0 workflow===&lt;br /&gt;
&lt;br /&gt;
# Edit a text or url resource&lt;br /&gt;
# Use the filepicker to easily select the file from any local or remote repository and select &amp;quot;link&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The file URL is then embedded into the text and when viewed, the media comes directly from the open repository.&lt;br /&gt;
&lt;br /&gt;
===Why is it better?===&lt;br /&gt;
&lt;br /&gt;
====Integrity====&lt;br /&gt;
&lt;br /&gt;
If a forum post with attached files (eg images) is imported into another course, then the files move with it.  Anyone in the new course will also see the files.   This makes activities more portable and re-usable.&lt;br /&gt;
&lt;br /&gt;
If two activities use the same file and one is deleted, then the other one is not affected.&lt;br /&gt;
&lt;br /&gt;
There should be less problems with everything looking fine for teachers and not appearing for students.&lt;br /&gt;
&lt;br /&gt;
====Security====&lt;br /&gt;
&lt;br /&gt;
Access to files is governed the same way as the items that they attached to, which is what people expect.  All files are now controlled by the settings in the Moodle interface, including roles and permissions.&lt;br /&gt;
&lt;br /&gt;
====Re-usability====&lt;br /&gt;
&lt;br /&gt;
It is now fast and easy to re-use files across Moodle.  Using the file picker, a recently-used file may easily be chosen, or a file from any course a user has access to.&lt;br /&gt;
&lt;br /&gt;
====Backups====&lt;br /&gt;
&lt;br /&gt;
Backups of activities are small and accurate, because Moodle knows exactly what files to include.  This is important for things like [[Community hubs]], where sharing of courses and parts of courses will become more common, and sharing every file in a course may be unacceptable.&lt;br /&gt;
&lt;br /&gt;
====Internationalization====&lt;br /&gt;
&lt;br /&gt;
There are no restrictions on file names - even files with names in Japanese may be used.&lt;br /&gt;
&lt;br /&gt;
====Repositories====&lt;br /&gt;
&lt;br /&gt;
The world is turning towards better management of files and less &amp;quot;dumping&amp;quot; of files into disks.  There are many repository solutions out there that focus on better management of files, with versioning, workflow, metadata and other features.&lt;br /&gt;
&lt;br /&gt;
===How to duplicate Moodle 1.x functionality in 2.0===&lt;br /&gt;
&lt;br /&gt;
If you really want to mimic older workflows in 2.0 then there are some solutions, although none of them are exactly the same.&lt;br /&gt;
&lt;br /&gt;
====FTP files into Moodle====&lt;br /&gt;
&lt;br /&gt;
# One way to do this is via the [[admin/repository/filesystem|File system repository]].  This allows you to turn a directory on the server into a repository of files within the Moodle file picker.  You can then use any server technology to access that directory from a desktop, such as FTP, [[wikipedia:Samba (software)|Samba]], [[wikipedia:AppleShare|Appleshare]] or [[wikipedia:WebDAV|WebDAV]].&lt;br /&gt;
# See the direct WebDAV plans below.&lt;br /&gt;
&lt;br /&gt;
====Change a file once, have it update in many places====&lt;br /&gt;
&lt;br /&gt;
# If you use an external repository that supports linking (such as Alfresco) then you get this behaviour for free.  Files in the repository can not have exactly the same access control as Moodle, but they can implement their own access control, especially if you use some sort of single sign-on.&lt;br /&gt;
# If you enable the [[Legacy course files]] feature in Moodle 2.0 then you can also link directly to files there using the Course files repository in the file picker.  Even HTML mini-sites work.  The caveat is that it only works in places where you can &#039;&#039;&#039;link&#039;&#039;&#039; to files.  So, for example, it won&#039;t work for a forum attachment or the &#039;resource&#039; module.  But it will work for the url module (new in 2.0) and any media embedded in HTML via the editor.&lt;br /&gt;
&lt;br /&gt;
==Roadmap for future improvements==&lt;br /&gt;
&lt;br /&gt;
Based on recent feedback, there are plans to improve the model in 2.0 with new features.&lt;br /&gt;
&lt;br /&gt;
===File synchronization===&lt;br /&gt;
&lt;br /&gt;
Instead of having to choose between linking to a course file or copying it to the current file area, we could add the option to &#039;Always use the latest version&#039; of the file.  This would re-copy the file to the destination whenever the source file changed.  Initially this would be implemented just for the internal repositories but could also be used later for some external repositories as well (those not requiring the Moodle site to authenticate as the user).&lt;br /&gt;
&lt;br /&gt;
This feature has the potential to maintain all the benefits of the 1.0 model without compromising the 2.0 model.&lt;br /&gt;
&lt;br /&gt;
However this feature is complex to implement because:&lt;br /&gt;
&lt;br /&gt;
* We need to cope with changing permissions in source and destination. &lt;br /&gt;
* We need to cope with cases like Assignment submissions (students shouldn&#039;t be able to update files after the due date, for example)&lt;br /&gt;
* We need some GUI solution to synchronize whole folders at once, such as a HTML mini-site.&lt;br /&gt;
* We need some in-GUI solution to report what the source file is for any given destination file.&lt;br /&gt;
&lt;br /&gt;
===Linking ability to File system repository===&lt;br /&gt;
&lt;br /&gt;
The File system repository currently does not allow linking to files.  This is because the files are in a directory inside moodledata and are not exposed by any direct URL from the web.&lt;br /&gt;
&lt;br /&gt;
To serve them to the web we&#039;d have to have some script like &#039;&#039;/repository/filesystem/file.php&#039;&#039; to serve them as links, which would allow relative links like HTML mini-sites to work.  &lt;br /&gt;
&lt;br /&gt;
The problem with this is that we are back to the same issues as 1.9 course files (or even worse), with no access control on the files at all.  Some people may not care about this, but the solution needs to make this very clear to users.&lt;br /&gt;
&lt;br /&gt;
===WebDAV support for course files and user files===&lt;br /&gt;
&lt;br /&gt;
This would effectively replace direct FTP access to the file system with WebDAV access to the &amp;quot;virtual&amp;quot; file system inside these file areas in Moodle.  It would allow people to update files without going near the web GUI.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* MDL-23306 META: Improve usability of new files structure&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=167471 Where is the Moodle 2.0 Course Backup Filearea] Using Moodle forum dicussion&lt;br /&gt;
 &lt;br /&gt;
[[Category:Teacher]] [[Category:Files]] [[fr:Fichiers de cours]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=80910</id>
		<title>Using the Microsoft SQL Server Driver for PHP</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=80910"/>
		<updated>2011-01-28T09:13:06Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Page formatting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
== Using the SQL Server Driver for PHP from Microsoft ==&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This short manual is for running Moodle 2.0 (and upwards) using the Microsoft SQL Server (MSSQL) RDBMS. The steps detailed below must be performed &#039;&#039;&#039;before&#039;&#039;&#039; installing Moodle itself.&lt;br /&gt;
&lt;br /&gt;
First of all, the minimum required version of MSSQL has been stabilized to MSSQL 2005 (v.9).&lt;br /&gt;
&lt;br /&gt;
== Installation overview ==&lt;br /&gt;
1. Install Microsoft SQL Server including SQL Server Management Studio. ([http://www.microsoft.com/sql/editions/express/default.mspx A free version, SQL Server Express Edition] is available for testing.)&lt;br /&gt;
:Make sure to choose mixed authentication (Windows and local accounts) to keep things simpler later.  Define the &amp;quot;sa&amp;quot; account password when requested (it&#039;s the default System Administrator account which has full access to all databases by default).&lt;br /&gt;
&lt;br /&gt;
2. Configure Windows for MSSQL.&lt;br /&gt;
:By default, MSSQL listens to port 1433 for incoming TCP/IP connections and this port needs to be opened in the firewall. This is explicitly configured in the firewall installed (either Windows Firewall in the Control Panel or the configuration interface for other firewalls). If the port was changed when MSSQL was installed, then specify the correct port number to open in the firewall.&lt;br /&gt;
:Confirm the TCP/IP protocol is enabled in: &#039;&#039;&#039;SQL Server Configuration Manager&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Network Configuration&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Protocols&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;TCP/IP enabled&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
3. Create and configure a new database.&lt;br /&gt;
:Open &amp;quot;SQL Server Management Studio&amp;quot; and create a new empty database.&lt;br /&gt;
*Execute the following command to enable Row Versioning:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 USE MASTER&lt;br /&gt;
 GO&lt;br /&gt;
 ALTER DATABASE &amp;amp;lt;your-database-name&amp;amp;gt; SET READ_COMMITTED_SNAPSHOT ON&lt;br /&gt;
 GO&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Install PHP and a web server.&lt;br /&gt;
*PHP can be downloaded from [http://www.php.net/downloads.php www.php.net]&lt;br /&gt;
*If IIS is used as the web server, IIS 7.0 or later is recommended with [http://www.iis.net/download FastCGI and WinCache]. &lt;br /&gt;
&lt;br /&gt;
5. Install the SQL Server Driver for PHP.&lt;br /&gt;
:On the web server, install [http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=ccdf728b-1ea0-48a8-a84a-5052214caad9 SQL Server Driver for PHP] including all the pre-requisites listed on the download page. Note: it is critical to install the SQL Server Native Access Client version documented on the download page of the SQL Server Driver for PHP.&lt;br /&gt;
:Configure PHP to use the appropriate SQLSRV driver. In php.ini, set the following:&lt;br /&gt;
&lt;br /&gt;
For PHP 5.2.4 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 [PHP_SQLSRV]&lt;br /&gt;
 extension=php_sqlsrv_52_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For PHP 5.3.2 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 [PHP_SQLSRV]&lt;br /&gt;
 extension=php_sqlsrv_53_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Microsoft documentation for the SQL Server Driver for PHP is available at: http://msdn.microsoft.com/en-us/library/ee229548(v=SQL.10).aspx &lt;br /&gt;
&lt;br /&gt;
6. Install and configure Moodle.&lt;br /&gt;
:Continue with the [[Installing Moodle|standard Moodle installation]].&lt;br /&gt;
&lt;br /&gt;
7. The Moodle &#039;&#039;&#039;config.php&#039;&#039;&#039; should include lines like these:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;sqlsrv&#039;;         // Required&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;localhost&#039;;      // Assuming that MSSQL is on the same server, otherwise &lt;br /&gt;
                                    // use the actual name or IP address of your database server&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;moodle&#039;;         // The name of the newly created Moodle database&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // Usually the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  true;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;           // The prefix can be changed per individual preferences, &lt;br /&gt;
                                    // but NEVER leave this blank!&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:If the config.php file doesn&#039;t exist, it will be generated as normal from the Moodle installer. Alternatively, use the config-dist.php file that comes with the Moodle package to create a custom config.php file.&lt;br /&gt;
&lt;br /&gt;
8. Restart or start your web server.&lt;br /&gt;
:If Moodle still cannot communicate with the database server, turn &#039;&#039;&#039;display_startup_errors&#039;&#039;&#039; to &amp;quot;On&amp;quot; in the /PHP/php.ini file, then restart the web server and check for any errors that may indicate incorrect DLL versions or missing dependencies.  These error reports, turned off by default in PHP, can be vital in locating a problem with new extension installations.&lt;br /&gt;
&lt;br /&gt;
9. Test the database connection.&lt;br /&gt;
:Try this PHP script, just add a text file called test.php from the example below and change (&#039;localhost&#039;, &#039;db_user&#039;, &#039;db_password&#039;) to align with the config.php settings, and load from local host (http://localhost/test.php).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$link = sqlsrv_connect($this-&amp;gt;dbhost, array(&#039;UID&#039; =&amp;gt; &#039;db_user&#039;, &#039;PWD&#039; =&amp;gt; &#039;db_password&#039;));&lt;br /&gt;
if($link === FALSE) {&lt;br /&gt;
    echo &#039;Could not connect&#039;;&lt;br /&gt;
    die(&#039;Could not connect: &#039; . sqlsrv_errors(SQLSRV_ERR_ALL));&lt;br /&gt;
}&lt;br /&gt;
echo &#039;Successful connection&#039;;&lt;br /&gt;
sqlsrv_close($link);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
10. Complete the rest of the Moodle installation as usual.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Installing Moodle]]&lt;br /&gt;
* [[Errors FAQ]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum]&lt;br /&gt;
* [[Beginning Administration FAQ]]&lt;br /&gt;
* [[Installing Oracle for PHP]]&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Installing_MSSQL_for_PHP&amp;diff=80841</id>
		<title>Installing MSSQL for PHP</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Installing_MSSQL_for_PHP&amp;diff=80841"/>
		<updated>2011-01-26T15:01:58Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Using the SQL Server 2005 Driver for PHP update */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 1.7}}{{Moodle 1.9}}{{Moodle 2.0}}&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This short manual is suitable if you are trying to run Moodle 1.7 (and upwards) using the SQL*Server (MSSQL) RDBMS. Steps detailed below must be performed &#039;&#039;&#039;before&#039;&#039;&#039; installing Moodle itself.&lt;br /&gt;
&lt;br /&gt;
Some of this may also apply if you wish to access an MSSQL server for external db authentication/enrollment. &lt;br /&gt;
&lt;br /&gt;
First of all, minimum required version of MSSQL has been stabilised to MSSQL 2005 (v.9), although it &#039;&#039;&#039;might work with MSSQL 2000 (v.8) or newer&#039;&#039;&#039;. All the development process has been performed using MSSQL 2005 and there could be some &#039;&#039;&#039;unknown problems&#039;&#039;&#039; with previous releases.&lt;br /&gt;
&lt;br /&gt;
While PHP comes with one, more or less, standard extension (mssql) that provides access to MSSQL databases, early we found some hard limits on it. Basically such default extension has some limits that prevent us to use it at all (you can find more info about these problems [[Development:XMLDB problems#MSSQL, PHP, UTF-8 and UCS-2|here]]).&lt;br /&gt;
&lt;br /&gt;
So, in order to allow PHP (i.e. Moodle) to access to MSSQL DBs properly we have to install a &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039; to save us from the problems related above. See the sections below for details about the various options.&lt;br /&gt;
&lt;br /&gt;
== Installation overview ==&lt;br /&gt;
&lt;br /&gt;
1. Get MSSQL Server installed and running. ([http://www.microsoft.com/sql/editions/express/default.mspx A free limited version, SQL Server Express Edition] is available for testing.)&lt;br /&gt;
:Make sure that you choose mixed authentication (Windows and local accounts) to keep things simpler later.  You&#039;ll be asked to define the  &amp;quot;sa&amp;quot; account password (it&#039;s the default System Administrator account which has full access to all databases by default).&lt;br /&gt;
&lt;br /&gt;
2. Make sure MS SQL Server can accept incoming TCP/IP connections on port 1433 (the standard one).&lt;br /&gt;
:You might need to explicitly allow this in your Windows firewall (see the Control Panel).  You may also need to edit options in the :&#039;&#039;&#039;SQL Server Configuration Manager&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Network Configuration&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Protocols&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;TCP/IP enabled&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
3. Open the &amp;quot;SQL Server Management Studio&amp;quot; and create a new empty database.  If you are using the &amp;quot;sa&amp;quot; account then you don&#039;t need to do anything else here.&lt;br /&gt;
&lt;br /&gt;
4. Configure these settings in your created (and still empty) database:&lt;br /&gt;
&lt;br /&gt;
:* ANSI NULLS Enabled = true (ALTER DATABASE xxxx SET ANSI_NULLS ON)&lt;br /&gt;
:* Quoted Identifiers Enabled = true (ALTER DATABASE xxxx SET QUOTED_IDENTIFIER ON)&lt;br /&gt;
:* Moodle 2.0 only: Row Versioning Enabled (ALTER DATABASE xxxx SET READ_COMMITTED_SNAPSHOT ON)&lt;br /&gt;
&lt;br /&gt;
5. Get PHP installed with a web server.   Unless you want to do it under IIS or some other way, the packages on the [http://download.moodle.org Moodle download page] are a good solution.&lt;br /&gt;
&lt;br /&gt;
6. Choose one of the following specific sections for your server to install the &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039; installed and running properly on your PHP box.&lt;br /&gt;
&lt;br /&gt;
7. Set the following settings in your php.ini file&lt;br /&gt;
:* mssql.textlimit = 20971520&lt;br /&gt;
:* mssql.textsize = 20971520&lt;br /&gt;
:Also, don&#039;t forget to set one of the following &#039;&#039;&#039;alternatives&#039;&#039;&#039;, in order to get all the data properly &amp;quot;slashed&amp;quot;:&lt;br /&gt;
:* magic_quotes_gpc = Off  &#039;&#039;&#039;or&#039;&#039;&#039;&lt;br /&gt;
:* magic_quotes_gpc = On &#039;&#039;&#039;and&#039;&#039;&#039; magic_quotes_sybase = On &lt;br /&gt;
&lt;br /&gt;
8. With all this properly configured, you can continue with a [[Installing Moodle|standard Moodle installation]].&lt;br /&gt;
&lt;br /&gt;
== Using the SQL Server 2005 Driver for PHP from Microsoft on Windows ==&lt;br /&gt;
In July 2008 Microsoft [http://social.msdn.microsoft.com/forums/en-US/sqldriverforphp/thread/a10e5202-9e41-4ff8-a33e-fbcc7b951be2/ released] a new SQL Server 2005 Driver for PHP. This is a PHP extension that allows PHP scripts to read and write data on Microsoft SQL Server databases and it overcomes the problems with the native SQL Server extension that was previously bundled with PHP.&lt;br /&gt;
&lt;br /&gt;
This Microsoft driver is the standard database layer for running Moodle 2 under Microsoft SQL Server databases. See [[Using the Microsoft SQL Server Driver for PHP]] the installation and configuration details.&lt;br /&gt;
&lt;br /&gt;
This driver is only supported in Moodle 2.0 and up. You should use [https://docs.moodle.org/en/Installing_MSSQL_for_PHP#Using_FreeTDS_on_Windows FreeTDS] if you are installing an older version of Moodle.&lt;br /&gt;
&lt;br /&gt;
See MDL-16497 and MDL-15093 for more background information.&lt;br /&gt;
&lt;br /&gt;
== Using FreeTDS on Windows ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&#039;&#039;&#039;Important Note 1:&#039;&#039;&#039; Due to some previous bugs it&#039;s highly recommendable to use PHP &amp;gt;= 5.2.6 and FreeTDS 0.82 + post-release patches ([http://tracker.moodle.org/browse/MDL-14725 more info]).&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If your web server is on Windows, use &#039;&#039;&#039;php_dblib.dll&#039;&#039;&#039;. Despite the name, it&#039;s FreeTDS compiled for Windows. (Go to this page for information on [https://docs.moodle.org/en/FreeTDS Using FreeTDS for Unix].) &lt;br /&gt;
&lt;br /&gt;
Originally we were using the DLLs available at [http://kromann.info/article.php?Id=11062598797760000 Frank Kromann&#039;s site], but they are outdated (using old versions of FreeTDS) and that has caused [http://tracker.moodle.org/browse/MDL-14725 some problems] in the past.&lt;br /&gt;
&lt;br /&gt;
So, right now, the recommended way to use FreeTDS under Windows is to use PHP 5.2.x following the following instructions:&lt;br /&gt;
&lt;br /&gt;
1. Download the appropriate copy of php_dblib.dll from the list below, and save it into your /PHP/ext directory.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; cellpadding=&amp;quot;5&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PHP version !! [http://www.iis-aid.com/articles/my_word/difference_between_php_thread_safe_and_non_thread_safe_binaries Thread Safe]  !! FreeTDS version !! Download URL&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | PHP 5.2.x (vc6) || Yes || 0.82 + 20090302 patches || [http://download.moodle.org/download.php/dblib/php52/DBLIB_TS.zip Download!]&lt;br /&gt;
|-&lt;br /&gt;
| No || 0.82 + 20090302 patches || [http://download.moodle.org/download.php/dblib/php52/DBLIB_NOTS.zip Download!]&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | PHP 5.3.x (vc9) || Yes || 0.82 + 20090904 patches || [http://download.moodle.org/download.php/dblib/php53/DBLIB_TS.zip Download!]&lt;br /&gt;
|-&lt;br /&gt;
| No || 0.82 + 20090904 patches || [http://download.moodle.org/download.php/dblib/php53/DBLIB_NOTS.zip Download!]&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; |  Thanks to [http://remote-learner.net/ Remote-Learner]] (Moodle [http://moodle.com/partners/ Partner]) and specially to Bryan Williams, donating one Visual C++ 6.0 Pro license to Moodle. Thanks to Trevor Johnson and his builds of the dblib extensions. Thanks to Daniele, Doug, Luis, Sean and many others by their collaboration in MDL-14725. Thanks to Frediano Ziglio and James K. Lowden from [http://freetds.org freetds.org] by their support. Thanks to Alastair Hole by providing the PHP 5.3 builds of the libraries. Thanks!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(alternatively here you can find some [[Development:Compiling FreeTDS under Windows|instructions to build those freetds extensions under win32]] yourself)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. FreeTDS requires the .NET Framework v1.1 to be installed.  You can [http://www.microsoft.com/downloads/details.aspx?FamilyID=262d25e3-f589-4842-8157-034d1e7cf3a3&amp;amp;DisplayLang=en download it from the Microsoft website] along with its [http://www.microsoft.com/downloads/details.aspx?FamilyID=a8f5654f-088e-40b2-bbdb-a83353618b38&amp;amp;DisplayLang=en service pack].  Alternatively, if you do not wish to install this framework, you can [http://kromann.info/ms-libs/msvcr71.dll download the required DLL] from Frank&#039;s site, and save it into your /PHP root directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. Edit your /PHP/php.ini file and add this line:&lt;br /&gt;
&lt;br /&gt;
  extension=php_dblib.dll &lt;br /&gt;
&lt;br /&gt;
Make sure that any lines referring to the php_mssql.dll extension are DISABLED (commented out).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4. When the PHP engine loads the FreeTDS extension it needs to be passed certain infiormation in order to be able to connect to your Moodle database. To retrieve this information FreeTDS looks for a file called &#039;&#039;&#039;freetds.conf&#039;&#039;&#039; in the root folder of the server that PHP installed on (e.g. C:\).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;freetds.conf&#039;&#039;&#039; should have the following structure:&lt;br /&gt;
&lt;br /&gt;
  [global]&lt;br /&gt;
      host = xxx.xxx.xxx.xxx (host name or ip of the MSSQL server)&lt;br /&gt;
      port = 1433&lt;br /&gt;
      client charset = UTF-8&lt;br /&gt;
      tds version = 8.0&lt;br /&gt;
      text size = 20971520&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to connect to a particular [http://msdn.microsoft.com/en-us/library/aa174516(SQL.80).aspx instance] of MSSQL you should specify the instance name:&lt;br /&gt;
&lt;br /&gt;
  [global]&lt;br /&gt;
      host = xxx.xxx.xxx.xxx (host name or ip of the MSSQL server)&lt;br /&gt;
      instance = xxx (instance name, e.g. INST2)&lt;br /&gt;
      port = 1433&lt;br /&gt;
      client charset = UTF-8&lt;br /&gt;
      tds version = 8.0&lt;br /&gt;
      text size = 20971520&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
*You can configure FreeTDS to look for the freetds.conf file in any directory that you want - you don&#039;t have to use C:\. To do this create a SYSTEM environment variable called &#039;&#039;&#039;FREETDS&#039;&#039;&#039; and point it to the directory where you have installed the freetds.conf file. If you do not set this environment variable FreeTDS will look for the freetds.conf file in the C:\ folder, which is the default. One possible benefit of setting the FREETDS environment variable and using a different installation directory for freetds.conf is that C:\ is very predictable to a hacker that knows anything about FreeTDS and that is the first place that he would look if he wanted to compromise your system. So, using a different installation directory would just make your system stronger. See the FreeTDS [http://www.freetds.org/userguide/envvar.htm Setting the environment variables] documentation for more information about this FREETDS environment variable.&lt;br /&gt;
&lt;br /&gt;
*Alternatively, you can [[Development:Compiling FreeTDS under Windows|recompile]] the FreeTDS extension yourself and change the default location to your preferred location at compile time. Then it is not necessary to create any environment variable. You must just ensure that freetds.conf is in the same folder that you specify when you compile php_dblib.dll.&lt;br /&gt;
&lt;br /&gt;
*MSSQL is usually installed with port 1433 as the default. However, if the port was changed on your server when you installed MSSQL then you need to specify the correct port number.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
5. Your Moodle &#039;&#039;&#039;config.php&#039;&#039;&#039; should include lines like these:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;mssql_n&#039;;        // Required&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;localhost&#039;;      // assuming MS SQL is on the same server, otherwise use an IP&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;moodle&#039;;         // or whatever you called the database you created&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // I usually use the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  false;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;            //Prefix, you can change it, but NEVER leave it blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have a config.php file yet, it can be generated as normal from the Moodle installer. Alternatively you can use the config-dist.php file that comes with the Moodle package to create your own config.php file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
6. Restart or start your web server.  If Moodle still cannot communicate with the database server, please turn display_startup_errors to &amp;quot;On&amp;quot; in your /PHP/php.ini file, then restart the web server and check for any errors that may indicate incorrect DLL versions or missing dependencies.  These error reports, turned off by default in PHP, can be vital in locating a problem with new extension installations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
7. Database conection test, try this PHP script, just put in a text file called test.php change (&#039;localhost&#039;, &#039;db_user&#039;, &#039;db_password&#039;) to suite your setup, and load from local host (http://localhost/test.php)...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
	$link = mssql_connect(&#039;localhost&#039;, &#039;db_user&#039;, &#039;db_password&#039;);&lt;br /&gt;
	if(!$link) {&lt;br /&gt;
		echo&#039;Could not connect&#039;;&lt;br /&gt;
		die(&#039;Could not connect: &#039; . mssql_error());&lt;br /&gt;
	}&lt;br /&gt;
	echo&#039;Successful connection&#039;;&lt;br /&gt;
	mssql_close($link);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
8. Install Moodle as usual.  Good luck!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
If you encounter some problems you can try:&lt;br /&gt;
*check that you have DotNet framework 1.1 installed (later version are installed on Vista, but you could need this specific one)&amp;lt;br /&amp;gt;&lt;br /&gt;
*enable TCP/IP for MSSQL: SQL Server 2005 Network Configuration -&amp;gt; Protocols for MSSQLSERVER -&amp;gt; TCP/IP (Enable) -&amp;gt; Properties -&amp;gt; Ip Addresses -&amp;gt; 127.0.0.1 (Active+Enable)&amp;lt;br /&amp;gt;&lt;br /&gt;
*if you are using SQL Server 2005 and you have the error &#039;&#039;4004: Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier&#039;&#039;, try the ODBTP method (next chapter). The SQL Server complaining that it doesn&#039;t support pure Unicode via TDS or older versions of ODBC. Microsoft has deprecated DB-Library a long ago, in favor of ODBC, OLE DB, or SQL Native Client. Many new features of SQL 2005 aren&#039;t accessible via DB-Library so if you need them, you could have to switch away from tools based on TDS and DB-Library :(&lt;br /&gt;
&lt;br /&gt;
== Using FreeTDS on Ubuntu by compiling an mssql.so extension ==&lt;br /&gt;
This is a good read to [http://www.robert-gonzalez.com/2009/02/18/building-the-php-ms-sql-server-extension-from-source-on-ubuntu-810/ building a FreeTDS based mssql extension for apache on Ubuntu].&lt;br /&gt;
&lt;br /&gt;
== Using FreeTDS on Debian Lenny ==&lt;br /&gt;
I found the following solution using:&lt;br /&gt;
* PHP Version 5.2.6-1+lenny9&lt;br /&gt;
* Microsoft SQL Server Enterprise Edition, version: 9.00.4053.00&lt;br /&gt;
&amp;lt;pre&amp;gt;apt-get install libsybdb5 freetds-common php5-sybase&lt;br /&gt;
/etc/init.d/apache2 restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
At the end of the process, if all goes fine, you will find in the mssql section of phpinfo();&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! MSSQL Support&lt;br /&gt;
! enabled&lt;br /&gt;
|-&lt;br /&gt;
| Library version &lt;br /&gt;
| FreeTDS &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Once FreeTDS is correctly installed, don not forget to set it up following explanations in https://docs.moodle.org/en/FreeTDS&lt;br /&gt;
&lt;br /&gt;
== Using ODBTP on Unix or Windows ==&lt;br /&gt;
&lt;br /&gt;
You can download ODBTP from http://odbtp.sourceforge.net/. Also you will access to the documentation from the same page.&lt;br /&gt;
&lt;br /&gt;
The downloaded package includes both the source code and some binaries to be installed in the server and some ready-to-use &#039;&#039;&#039;mssql extension alternatives&#039;&#039;&#039; for some platforms/PHP versions (so you won&#039;t need to compile it if your PHP server/version binary package is present).&lt;br /&gt;
&lt;br /&gt;
First of all, we have to install the Win32 service that comes with the package. Let&#039;s assume that it&#039;s going to run in the same Win32 machine where your MSSQL server is running (although it can run in any other Win32 server in your network).&lt;br /&gt;
&lt;br /&gt;
To do do, following the instructions present in http://odbtp.sourceforge.net/install.html, you must:&lt;br /&gt;
&lt;br /&gt;
Do the following on the MSSQL server:&lt;br /&gt;
# Create a directory on the Windows host where the service program files will reside, i.e., md odbtp.&lt;br /&gt;
# Copy the files odbtpctl.exe, odbtpsrv.exe and odbtpsrv.ini files from the winservice directory into the directory created in step 1.&lt;br /&gt;
# Edit the file odbtpsrv.ini of the previous step and this line: &amp;lt;pre&amp;gt;MaxRequestSize=20971520&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Open a command prompt (cmd) window on the Windows host.&lt;br /&gt;
# Change to the directory to which the service program files were copied, i.e., cd odbtp.&lt;br /&gt;
# Run the following commands to install and start the service:&lt;br /&gt;
#*   odbtpctl install&lt;br /&gt;
#*   odbtpctl start&lt;br /&gt;
# With these steps you should have one new service running in your host called &amp;quot;odbtp&amp;quot;. Verify it&#039;s present and running in the &amp;quot;Services&amp;quot; control panel.&lt;br /&gt;
# Don&#039;t forget to enable TCP/IP incoming connections to port 2799 in the host you have installed the service!&lt;br /&gt;
&lt;br /&gt;
Now it&#039;s time to build the &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039;. First of all, verify if, in the downloaded package, under the &amp;quot;php&amp;quot; dir, there is one extension suitable for your PHP server/version. If it&#039;s present, you can simply copy it to the php/extensions dir in your PHP server and skip next points about compiling it from source. It&#039;s important to point that, inside each directory, you&#039;ll find &#039;&#039;&#039;two different&#039;&#039;&#039; libraries/dll files. The one that must be copied to the extensions dir is the one called &#039;&#039;&#039;&amp;quot;php_odbtp_mssql.xxx&amp;quot;&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
If in the downloaded package isn&#039;t present the extension matching your PHP platform/version, you should build if from source files. To do that, just &#039;&#039;&#039;&amp;quot;configure, make, make install&amp;quot;&#039;&#039;&#039;. That will create some stuff under &amp;quot;/usr/local&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve successfully built ODBTP is time to create the &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039; that will provide us with the capacity of handling MSSQL DBs from within Moodle. To do so, just configure your PHP server adding this new option to the usual ones:&lt;br /&gt;
&lt;br /&gt;
  --with-odbtp-mssql&lt;br /&gt;
&lt;br /&gt;
then, after the standard &amp;quot;make and make install&amp;quot; steps, your PHP server will be built with MSSQL support provided by ODBTP.&lt;br /&gt;
&lt;br /&gt;
Do the following on the moodle webserver:&lt;br /&gt;
Finally, independently if we are using the binary extension provided in the download or if you have built it from source files, it&#039;s time to configure the extension. &lt;br /&gt;
1. To do so, add this lines, if no present, to your php.ini file:&lt;br /&gt;
&lt;br /&gt;
  extension=php_odbtp_mssql.dll&lt;br /&gt;
&lt;br /&gt;
(only for Win32 PHP servers!)&lt;br /&gt;
&lt;br /&gt;
2. And, for all the server platforms: &lt;br /&gt;
&lt;br /&gt;
  [odbtp]&lt;br /&gt;
  odbtp.interface_file = &amp;quot;/path/to/your/odbtp.conf&amp;quot;&lt;br /&gt;
  odbtp.datetime_format = mdyhmsf&lt;br /&gt;
  odbtp.detach_default_queries = yes&lt;br /&gt;
&lt;br /&gt;
(where &#039;&#039;&amp;quot;/path/to/your/odbtp.conf&amp;quot;&#039;&#039; is usually &#039;&#039;&#039;&amp;quot;/usr/local/etc/odbtp.conf&amp;quot;&#039;&#039;&#039; for Unix systems and &#039;&#039;&#039;&amp;quot;C:\odbtp\odbtp.conf&amp;quot;&#039;&#039;&#039; for Windows systems)&lt;br /&gt;
&lt;br /&gt;
Then, edit such &amp;quot;odbtp.conf&amp;quot; file and put there these contents:&lt;br /&gt;
&lt;br /&gt;
  [global]&lt;br /&gt;
  odbtp host = xxx.xxx.xxx (ip or hostname of the Win32 box running the ODBTP service i.e MSSQL server)&lt;br /&gt;
  type = mssql&lt;br /&gt;
  unicode sql = yes&lt;br /&gt;
  use row cache = yes&lt;br /&gt;
  right trim text = yes&lt;br /&gt;
  var data size = 20971520&lt;br /&gt;
&lt;br /&gt;
With this, your PHP server will be able to connect with the MSSQL DB server using ODBTP. From here, just continue with the installation.&lt;br /&gt;
&lt;br /&gt;
Finally, if you find the ODBTP executables and &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039; in binary formats, it only will be necessary to install them in your server (binary packages...) without the need to recompile anything (just the php.ini and odbtp.conf edition steps above will be necessary). Of course, it will be really welcome to have all those binary alternatives documented here.&lt;br /&gt;
&lt;br /&gt;
Once ODBTP is working, Moodle config.php should include lines like these:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;mssql_n&#039;;        // Required&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;localhost&#039;;      // assuming MS SQL is on the same server, otherwise use an IP&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;moodle&#039;;         // or whatever you called the database you created&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // I usually use the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  false;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;            //Prefix, you can change it, but NEVER leave it blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have a config.php file yet, it can be generated as normal from the Moodle installer.&lt;br /&gt;
&lt;br /&gt;
== Using ODBC on Windows ==&lt;br /&gt;
[[ODBC]] allows communication with an SQL database.&lt;br /&gt;
{{Not for production sites}}&lt;br /&gt;
&lt;br /&gt;
1. Go to the &#039;&#039;&#039;Administrative Tools&#039;&#039;&#039;  control panel, then the &#039;&#039;&#039;Data Sources (ODBC)&#039;&#039;&#039; panel.&lt;br /&gt;
&lt;br /&gt;
2. Configure one new System/User DSN (call it, for example &amp;quot;moodle&amp;quot;). Dont forget to enable these options if the driver asks for them:&lt;br /&gt;
&lt;br /&gt;
:* ANSI NULLS Enabled = true&lt;br /&gt;
:* Quoted Identifiers Enabled = true&lt;br /&gt;
&lt;br /&gt;
3. Your Moodle config.php should include lines like these:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;odbc_mssql&#039;;     // Note this is different to all the other configs on this page!&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;moodle&#039;;         // Where this matches the Data source name you chose above&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;&#039;;               // Keep it blank!!&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // I usually use the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  false;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;            //Prefix, you can change it, but NEVER leave it blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Install Moodle as usual.  Good luck!&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Installing Moodle]]&lt;br /&gt;
* [[Errors FAQ]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum]&lt;br /&gt;
* [[Beginning Administration FAQ]]&lt;br /&gt;
* [[Installing Oracle for PHP]]&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Installing_MSSQL_for_PHP&amp;diff=80840</id>
		<title>Installing MSSQL for PHP</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Installing_MSSQL_for_PHP&amp;diff=80840"/>
		<updated>2011-01-26T14:54:08Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* MS SQL Server Driver update */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 1.7}}{{Moodle 1.9}}{{Moodle 2.0}}&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This short manual is suitable if you are trying to run Moodle 1.7 (and upwards) using the SQL*Server (MSSQL) RDBMS. Steps detailed below must be performed &#039;&#039;&#039;before&#039;&#039;&#039; installing Moodle itself.&lt;br /&gt;
&lt;br /&gt;
Some of this may also apply if you wish to access an MSSQL server for external db authentication/enrollment. &lt;br /&gt;
&lt;br /&gt;
First of all, minimum required version of MSSQL has been stabilised to MSSQL 2005 (v.9), although it &#039;&#039;&#039;might work with MSSQL 2000 (v.8) or newer&#039;&#039;&#039;. All the development process has been performed using MSSQL 2005 and there could be some &#039;&#039;&#039;unknown problems&#039;&#039;&#039; with previous releases.&lt;br /&gt;
&lt;br /&gt;
While PHP comes with one, more or less, standard extension (mssql) that provides access to MSSQL databases, early we found some hard limits on it. Basically such default extension has some limits that prevent us to use it at all (you can find more info about these problems [[Development:XMLDB problems#MSSQL, PHP, UTF-8 and UCS-2|here]]).&lt;br /&gt;
&lt;br /&gt;
So, in order to allow PHP (i.e. Moodle) to access to MSSQL DBs properly we have to install a &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039; to save us from the problems related above. See the sections below for details about the various options.&lt;br /&gt;
&lt;br /&gt;
== Installation overview ==&lt;br /&gt;
&lt;br /&gt;
1. Get MSSQL Server installed and running. ([http://www.microsoft.com/sql/editions/express/default.mspx A free limited version, SQL Server Express Edition] is available for testing.)&lt;br /&gt;
:Make sure that you choose mixed authentication (Windows and local accounts) to keep things simpler later.  You&#039;ll be asked to define the  &amp;quot;sa&amp;quot; account password (it&#039;s the default System Administrator account which has full access to all databases by default).&lt;br /&gt;
&lt;br /&gt;
2. Make sure MS SQL Server can accept incoming TCP/IP connections on port 1433 (the standard one).&lt;br /&gt;
:You might need to explicitly allow this in your Windows firewall (see the Control Panel).  You may also need to edit options in the :&#039;&#039;&#039;SQL Server Configuration Manager&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Network Configuration&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Protocols&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;TCP/IP enabled&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
3. Open the &amp;quot;SQL Server Management Studio&amp;quot; and create a new empty database.  If you are using the &amp;quot;sa&amp;quot; account then you don&#039;t need to do anything else here.&lt;br /&gt;
&lt;br /&gt;
4. Configure these settings in your created (and still empty) database:&lt;br /&gt;
&lt;br /&gt;
:* ANSI NULLS Enabled = true (ALTER DATABASE xxxx SET ANSI_NULLS ON)&lt;br /&gt;
:* Quoted Identifiers Enabled = true (ALTER DATABASE xxxx SET QUOTED_IDENTIFIER ON)&lt;br /&gt;
:* Moodle 2.0 only: Row Versioning Enabled (ALTER DATABASE xxxx SET READ_COMMITTED_SNAPSHOT ON)&lt;br /&gt;
&lt;br /&gt;
5. Get PHP installed with a web server.   Unless you want to do it under IIS or some other way, the packages on the [http://download.moodle.org Moodle download page] are a good solution.&lt;br /&gt;
&lt;br /&gt;
6. Choose one of the following specific sections for your server to install the &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039; installed and running properly on your PHP box.&lt;br /&gt;
&lt;br /&gt;
7. Set the following settings in your php.ini file&lt;br /&gt;
:* mssql.textlimit = 20971520&lt;br /&gt;
:* mssql.textsize = 20971520&lt;br /&gt;
:Also, don&#039;t forget to set one of the following &#039;&#039;&#039;alternatives&#039;&#039;&#039;, in order to get all the data properly &amp;quot;slashed&amp;quot;:&lt;br /&gt;
:* magic_quotes_gpc = Off  &#039;&#039;&#039;or&#039;&#039;&#039;&lt;br /&gt;
:* magic_quotes_gpc = On &#039;&#039;&#039;and&#039;&#039;&#039; magic_quotes_sybase = On &lt;br /&gt;
&lt;br /&gt;
8. With all this properly configured, you can continue with a [[Installing Moodle|standard Moodle installation]].&lt;br /&gt;
&lt;br /&gt;
== Using the SQL Server 2005 Driver for PHP from Microsoft on Windows ==&lt;br /&gt;
In July 2008 Microsoft [http://social.msdn.microsoft.com/forums/en-US/sqldriverforphp/thread/a10e5202-9e41-4ff8-a33e-fbcc7b951be2/ released] a new SQL Server 2005 Driver for PHP. This is a PHP extension that allows for the reading and writing of SQL Server data from within PHP scripts and it overcomes the problems with the native SQL Server extension that was previously included with PHP.&lt;br /&gt;
&lt;br /&gt;
This driver is the standard database layer for running Moodle 2 under Microsoft SQL Server databases. See [[Using the Microsoft SQL Server Driver for PHP]] the installation and configuration details.&lt;br /&gt;
&lt;br /&gt;
This driver is only supported in Moodle 2.0 and up. You should use FreeTDS if you are installing an older version of Moodle.&lt;br /&gt;
&lt;br /&gt;
See MDL-16497 and MDL-15093 for more details.&lt;br /&gt;
&lt;br /&gt;
== Using FreeTDS on Windows ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&#039;&#039;&#039;Important Note 1:&#039;&#039;&#039; Due to some previous bugs it&#039;s highly recommendable to use PHP &amp;gt;= 5.2.6 and FreeTDS 0.82 + post-release patches ([http://tracker.moodle.org/browse/MDL-14725 more info]).&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If your web server is on Windows, use &#039;&#039;&#039;php_dblib.dll&#039;&#039;&#039;. Despite the name, it&#039;s FreeTDS compiled for Windows. (Go to this page for information on [https://docs.moodle.org/en/FreeTDS Using FreeTDS for Unix].) &lt;br /&gt;
&lt;br /&gt;
Originally we were using the DLLs available at [http://kromann.info/article.php?Id=11062598797760000 Frank Kromann&#039;s site], but they are outdated (using old versions of FreeTDS) and that has caused [http://tracker.moodle.org/browse/MDL-14725 some problems] in the past.&lt;br /&gt;
&lt;br /&gt;
So, right now, the recommended way to use FreeTDS under Windows is to use PHP 5.2.x following the following instructions:&lt;br /&gt;
&lt;br /&gt;
1. Download the appropriate copy of php_dblib.dll from the list below, and save it into your /PHP/ext directory.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; cellpadding=&amp;quot;5&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PHP version !! [http://www.iis-aid.com/articles/my_word/difference_between_php_thread_safe_and_non_thread_safe_binaries Thread Safe]  !! FreeTDS version !! Download URL&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | PHP 5.2.x (vc6) || Yes || 0.82 + 20090302 patches || [http://download.moodle.org/download.php/dblib/php52/DBLIB_TS.zip Download!]&lt;br /&gt;
|-&lt;br /&gt;
| No || 0.82 + 20090302 patches || [http://download.moodle.org/download.php/dblib/php52/DBLIB_NOTS.zip Download!]&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | PHP 5.3.x (vc9) || Yes || 0.82 + 20090904 patches || [http://download.moodle.org/download.php/dblib/php53/DBLIB_TS.zip Download!]&lt;br /&gt;
|-&lt;br /&gt;
| No || 0.82 + 20090904 patches || [http://download.moodle.org/download.php/dblib/php53/DBLIB_NOTS.zip Download!]&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; |  Thanks to [http://remote-learner.net/ Remote-Learner]] (Moodle [http://moodle.com/partners/ Partner]) and specially to Bryan Williams, donating one Visual C++ 6.0 Pro license to Moodle. Thanks to Trevor Johnson and his builds of the dblib extensions. Thanks to Daniele, Doug, Luis, Sean and many others by their collaboration in MDL-14725. Thanks to Frediano Ziglio and James K. Lowden from [http://freetds.org freetds.org] by their support. Thanks to Alastair Hole by providing the PHP 5.3 builds of the libraries. Thanks!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(alternatively here you can find some [[Development:Compiling FreeTDS under Windows|instructions to build those freetds extensions under win32]] yourself)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. FreeTDS requires the .NET Framework v1.1 to be installed.  You can [http://www.microsoft.com/downloads/details.aspx?FamilyID=262d25e3-f589-4842-8157-034d1e7cf3a3&amp;amp;DisplayLang=en download it from the Microsoft website] along with its [http://www.microsoft.com/downloads/details.aspx?FamilyID=a8f5654f-088e-40b2-bbdb-a83353618b38&amp;amp;DisplayLang=en service pack].  Alternatively, if you do not wish to install this framework, you can [http://kromann.info/ms-libs/msvcr71.dll download the required DLL] from Frank&#039;s site, and save it into your /PHP root directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. Edit your /PHP/php.ini file and add this line:&lt;br /&gt;
&lt;br /&gt;
  extension=php_dblib.dll &lt;br /&gt;
&lt;br /&gt;
Make sure that any lines referring to the php_mssql.dll extension are DISABLED (commented out).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4. When the PHP engine loads the FreeTDS extension it needs to be passed certain infiormation in order to be able to connect to your Moodle database. To retrieve this information FreeTDS looks for a file called &#039;&#039;&#039;freetds.conf&#039;&#039;&#039; in the root folder of the server that PHP installed on (e.g. C:\).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;freetds.conf&#039;&#039;&#039; should have the following structure:&lt;br /&gt;
&lt;br /&gt;
  [global]&lt;br /&gt;
      host = xxx.xxx.xxx.xxx (host name or ip of the MSSQL server)&lt;br /&gt;
      port = 1433&lt;br /&gt;
      client charset = UTF-8&lt;br /&gt;
      tds version = 8.0&lt;br /&gt;
      text size = 20971520&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to connect to a particular [http://msdn.microsoft.com/en-us/library/aa174516(SQL.80).aspx instance] of MSSQL you should specify the instance name:&lt;br /&gt;
&lt;br /&gt;
  [global]&lt;br /&gt;
      host = xxx.xxx.xxx.xxx (host name or ip of the MSSQL server)&lt;br /&gt;
      instance = xxx (instance name, e.g. INST2)&lt;br /&gt;
      port = 1433&lt;br /&gt;
      client charset = UTF-8&lt;br /&gt;
      tds version = 8.0&lt;br /&gt;
      text size = 20971520&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
*You can configure FreeTDS to look for the freetds.conf file in any directory that you want - you don&#039;t have to use C:\. To do this create a SYSTEM environment variable called &#039;&#039;&#039;FREETDS&#039;&#039;&#039; and point it to the directory where you have installed the freetds.conf file. If you do not set this environment variable FreeTDS will look for the freetds.conf file in the C:\ folder, which is the default. One possible benefit of setting the FREETDS environment variable and using a different installation directory for freetds.conf is that C:\ is very predictable to a hacker that knows anything about FreeTDS and that is the first place that he would look if he wanted to compromise your system. So, using a different installation directory would just make your system stronger. See the FreeTDS [http://www.freetds.org/userguide/envvar.htm Setting the environment variables] documentation for more information about this FREETDS environment variable.&lt;br /&gt;
&lt;br /&gt;
*Alternatively, you can [[Development:Compiling FreeTDS under Windows|recompile]] the FreeTDS extension yourself and change the default location to your preferred location at compile time. Then it is not necessary to create any environment variable. You must just ensure that freetds.conf is in the same folder that you specify when you compile php_dblib.dll.&lt;br /&gt;
&lt;br /&gt;
*MSSQL is usually installed with port 1433 as the default. However, if the port was changed on your server when you installed MSSQL then you need to specify the correct port number.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
5. Your Moodle &#039;&#039;&#039;config.php&#039;&#039;&#039; should include lines like these:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;mssql_n&#039;;        // Required&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;localhost&#039;;      // assuming MS SQL is on the same server, otherwise use an IP&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;moodle&#039;;         // or whatever you called the database you created&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // I usually use the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  false;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;            //Prefix, you can change it, but NEVER leave it blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have a config.php file yet, it can be generated as normal from the Moodle installer. Alternatively you can use the config-dist.php file that comes with the Moodle package to create your own config.php file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
6. Restart or start your web server.  If Moodle still cannot communicate with the database server, please turn display_startup_errors to &amp;quot;On&amp;quot; in your /PHP/php.ini file, then restart the web server and check for any errors that may indicate incorrect DLL versions or missing dependencies.  These error reports, turned off by default in PHP, can be vital in locating a problem with new extension installations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
7. Database conection test, try this PHP script, just put in a text file called test.php change (&#039;localhost&#039;, &#039;db_user&#039;, &#039;db_password&#039;) to suite your setup, and load from local host (http://localhost/test.php)...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
	$link = mssql_connect(&#039;localhost&#039;, &#039;db_user&#039;, &#039;db_password&#039;);&lt;br /&gt;
	if(!$link) {&lt;br /&gt;
		echo&#039;Could not connect&#039;;&lt;br /&gt;
		die(&#039;Could not connect: &#039; . mssql_error());&lt;br /&gt;
	}&lt;br /&gt;
	echo&#039;Successful connection&#039;;&lt;br /&gt;
	mssql_close($link);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
8. Install Moodle as usual.  Good luck!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
If you encounter some problems you can try:&lt;br /&gt;
*check that you have DotNet framework 1.1 installed (later version are installed on Vista, but you could need this specific one)&amp;lt;br /&amp;gt;&lt;br /&gt;
*enable TCP/IP for MSSQL: SQL Server 2005 Network Configuration -&amp;gt; Protocols for MSSQLSERVER -&amp;gt; TCP/IP (Enable) -&amp;gt; Properties -&amp;gt; Ip Addresses -&amp;gt; 127.0.0.1 (Active+Enable)&amp;lt;br /&amp;gt;&lt;br /&gt;
*if you are using SQL Server 2005 and you have the error &#039;&#039;4004: Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier&#039;&#039;, try the ODBTP method (next chapter). The SQL Server complaining that it doesn&#039;t support pure Unicode via TDS or older versions of ODBC. Microsoft has deprecated DB-Library a long ago, in favor of ODBC, OLE DB, or SQL Native Client. Many new features of SQL 2005 aren&#039;t accessible via DB-Library so if you need them, you could have to switch away from tools based on TDS and DB-Library :(&lt;br /&gt;
&lt;br /&gt;
== Using FreeTDS on Ubuntu by compiling an mssql.so extension ==&lt;br /&gt;
This is a good read to [http://www.robert-gonzalez.com/2009/02/18/building-the-php-ms-sql-server-extension-from-source-on-ubuntu-810/ building a FreeTDS based mssql extension for apache on Ubuntu].&lt;br /&gt;
&lt;br /&gt;
== Using FreeTDS on Debian Lenny ==&lt;br /&gt;
I found the following solution using:&lt;br /&gt;
* PHP Version 5.2.6-1+lenny9&lt;br /&gt;
* Microsoft SQL Server Enterprise Edition, version: 9.00.4053.00&lt;br /&gt;
&amp;lt;pre&amp;gt;apt-get install libsybdb5 freetds-common php5-sybase&lt;br /&gt;
/etc/init.d/apache2 restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
At the end of the process, if all goes fine, you will find in the mssql section of phpinfo();&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! MSSQL Support&lt;br /&gt;
! enabled&lt;br /&gt;
|-&lt;br /&gt;
| Library version &lt;br /&gt;
| FreeTDS &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Once FreeTDS is correctly installed, don not forget to set it up following explanations in https://docs.moodle.org/en/FreeTDS&lt;br /&gt;
&lt;br /&gt;
== Using ODBTP on Unix or Windows ==&lt;br /&gt;
&lt;br /&gt;
You can download ODBTP from http://odbtp.sourceforge.net/. Also you will access to the documentation from the same page.&lt;br /&gt;
&lt;br /&gt;
The downloaded package includes both the source code and some binaries to be installed in the server and some ready-to-use &#039;&#039;&#039;mssql extension alternatives&#039;&#039;&#039; for some platforms/PHP versions (so you won&#039;t need to compile it if your PHP server/version binary package is present).&lt;br /&gt;
&lt;br /&gt;
First of all, we have to install the Win32 service that comes with the package. Let&#039;s assume that it&#039;s going to run in the same Win32 machine where your MSSQL server is running (although it can run in any other Win32 server in your network).&lt;br /&gt;
&lt;br /&gt;
To do do, following the instructions present in http://odbtp.sourceforge.net/install.html, you must:&lt;br /&gt;
&lt;br /&gt;
Do the following on the MSSQL server:&lt;br /&gt;
# Create a directory on the Windows host where the service program files will reside, i.e., md odbtp.&lt;br /&gt;
# Copy the files odbtpctl.exe, odbtpsrv.exe and odbtpsrv.ini files from the winservice directory into the directory created in step 1.&lt;br /&gt;
# Edit the file odbtpsrv.ini of the previous step and this line: &amp;lt;pre&amp;gt;MaxRequestSize=20971520&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Open a command prompt (cmd) window on the Windows host.&lt;br /&gt;
# Change to the directory to which the service program files were copied, i.e., cd odbtp.&lt;br /&gt;
# Run the following commands to install and start the service:&lt;br /&gt;
#*   odbtpctl install&lt;br /&gt;
#*   odbtpctl start&lt;br /&gt;
# With these steps you should have one new service running in your host called &amp;quot;odbtp&amp;quot;. Verify it&#039;s present and running in the &amp;quot;Services&amp;quot; control panel.&lt;br /&gt;
# Don&#039;t forget to enable TCP/IP incoming connections to port 2799 in the host you have installed the service!&lt;br /&gt;
&lt;br /&gt;
Now it&#039;s time to build the &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039;. First of all, verify if, in the downloaded package, under the &amp;quot;php&amp;quot; dir, there is one extension suitable for your PHP server/version. If it&#039;s present, you can simply copy it to the php/extensions dir in your PHP server and skip next points about compiling it from source. It&#039;s important to point that, inside each directory, you&#039;ll find &#039;&#039;&#039;two different&#039;&#039;&#039; libraries/dll files. The one that must be copied to the extensions dir is the one called &#039;&#039;&#039;&amp;quot;php_odbtp_mssql.xxx&amp;quot;&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
If in the downloaded package isn&#039;t present the extension matching your PHP platform/version, you should build if from source files. To do that, just &#039;&#039;&#039;&amp;quot;configure, make, make install&amp;quot;&#039;&#039;&#039;. That will create some stuff under &amp;quot;/usr/local&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve successfully built ODBTP is time to create the &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039; that will provide us with the capacity of handling MSSQL DBs from within Moodle. To do so, just configure your PHP server adding this new option to the usual ones:&lt;br /&gt;
&lt;br /&gt;
  --with-odbtp-mssql&lt;br /&gt;
&lt;br /&gt;
then, after the standard &amp;quot;make and make install&amp;quot; steps, your PHP server will be built with MSSQL support provided by ODBTP.&lt;br /&gt;
&lt;br /&gt;
Do the following on the moodle webserver:&lt;br /&gt;
Finally, independently if we are using the binary extension provided in the download or if you have built it from source files, it&#039;s time to configure the extension. &lt;br /&gt;
1. To do so, add this lines, if no present, to your php.ini file:&lt;br /&gt;
&lt;br /&gt;
  extension=php_odbtp_mssql.dll&lt;br /&gt;
&lt;br /&gt;
(only for Win32 PHP servers!)&lt;br /&gt;
&lt;br /&gt;
2. And, for all the server platforms: &lt;br /&gt;
&lt;br /&gt;
  [odbtp]&lt;br /&gt;
  odbtp.interface_file = &amp;quot;/path/to/your/odbtp.conf&amp;quot;&lt;br /&gt;
  odbtp.datetime_format = mdyhmsf&lt;br /&gt;
  odbtp.detach_default_queries = yes&lt;br /&gt;
&lt;br /&gt;
(where &#039;&#039;&amp;quot;/path/to/your/odbtp.conf&amp;quot;&#039;&#039; is usually &#039;&#039;&#039;&amp;quot;/usr/local/etc/odbtp.conf&amp;quot;&#039;&#039;&#039; for Unix systems and &#039;&#039;&#039;&amp;quot;C:\odbtp\odbtp.conf&amp;quot;&#039;&#039;&#039; for Windows systems)&lt;br /&gt;
&lt;br /&gt;
Then, edit such &amp;quot;odbtp.conf&amp;quot; file and put there these contents:&lt;br /&gt;
&lt;br /&gt;
  [global]&lt;br /&gt;
  odbtp host = xxx.xxx.xxx (ip or hostname of the Win32 box running the ODBTP service i.e MSSQL server)&lt;br /&gt;
  type = mssql&lt;br /&gt;
  unicode sql = yes&lt;br /&gt;
  use row cache = yes&lt;br /&gt;
  right trim text = yes&lt;br /&gt;
  var data size = 20971520&lt;br /&gt;
&lt;br /&gt;
With this, your PHP server will be able to connect with the MSSQL DB server using ODBTP. From here, just continue with the installation.&lt;br /&gt;
&lt;br /&gt;
Finally, if you find the ODBTP executables and &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039; in binary formats, it only will be necessary to install them in your server (binary packages...) without the need to recompile anything (just the php.ini and odbtp.conf edition steps above will be necessary). Of course, it will be really welcome to have all those binary alternatives documented here.&lt;br /&gt;
&lt;br /&gt;
Once ODBTP is working, Moodle config.php should include lines like these:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;mssql_n&#039;;        // Required&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;localhost&#039;;      // assuming MS SQL is on the same server, otherwise use an IP&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;moodle&#039;;         // or whatever you called the database you created&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // I usually use the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  false;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;            //Prefix, you can change it, but NEVER leave it blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have a config.php file yet, it can be generated as normal from the Moodle installer.&lt;br /&gt;
&lt;br /&gt;
== Using ODBC on Windows ==&lt;br /&gt;
[[ODBC]] allows communication with an SQL database.&lt;br /&gt;
{{Not for production sites}}&lt;br /&gt;
&lt;br /&gt;
1. Go to the &#039;&#039;&#039;Administrative Tools&#039;&#039;&#039;  control panel, then the &#039;&#039;&#039;Data Sources (ODBC)&#039;&#039;&#039; panel.&lt;br /&gt;
&lt;br /&gt;
2. Configure one new System/User DSN (call it, for example &amp;quot;moodle&amp;quot;). Dont forget to enable these options if the driver asks for them:&lt;br /&gt;
&lt;br /&gt;
:* ANSI NULLS Enabled = true&lt;br /&gt;
:* Quoted Identifiers Enabled = true&lt;br /&gt;
&lt;br /&gt;
3. Your Moodle config.php should include lines like these:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;odbc_mssql&#039;;     // Note this is different to all the other configs on this page!&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;moodle&#039;;         // Where this matches the Data source name you chose above&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;&#039;;               // Keep it blank!!&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // I usually use the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  false;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;            //Prefix, you can change it, but NEVER leave it blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Install Moodle as usual.  Good luck!&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Installing Moodle]]&lt;br /&gt;
* [[Errors FAQ]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum]&lt;br /&gt;
* [[Beginning Administration FAQ]]&lt;br /&gt;
* [[Installing Oracle for PHP]]&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Installing_MSSQL_for_PHP&amp;diff=80838</id>
		<title>Installing MSSQL for PHP</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Installing_MSSQL_for_PHP&amp;diff=80838"/>
		<updated>2011-01-26T13:51:22Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Using the SQL Server 2005 Driver for PHP from Microsoft */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 1.7}}{{Moodle 1.9}}{{Moodle 2.0}}&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This short manual is suitable if you are trying to run Moodle 1.7 (and upwards) using the SQL*Server (MSSQL) RDBMS. Steps detailed below must be performed &#039;&#039;&#039;before&#039;&#039;&#039; installing Moodle itself.&lt;br /&gt;
&lt;br /&gt;
Some of this may also apply if you wish to access an MSSQL server for external db authentication/enrollment. &lt;br /&gt;
&lt;br /&gt;
First of all, minimum required version of MSSQL has been stabilised to MSSQL 2005 (v.9), although it &#039;&#039;&#039;might work with MSSQL 2000 (v.8) or newer&#039;&#039;&#039;. All the development process has been performed using MSSQL 2005 and there could be some &#039;&#039;&#039;unknown problems&#039;&#039;&#039; with previous releases.&lt;br /&gt;
&lt;br /&gt;
While PHP comes with one, more or less, standard extension (mssql) that provides access to MSSQL databases, early we found some hard limits on it. Basically such default extension has some limits that prevent us to use it at all (you can find more info about these problems [[Development:XMLDB problems#MSSQL, PHP, UTF-8 and UCS-2|here]]).&lt;br /&gt;
&lt;br /&gt;
So, in order to allow PHP (i.e. Moodle) to access to MSSQL DBs properly we have to install a &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039; to save us from the problems related above. See the sections below for details about the various options.&lt;br /&gt;
&lt;br /&gt;
== Installation overview ==&lt;br /&gt;
&lt;br /&gt;
1. Get MSSQL Server installed and running. ([http://www.microsoft.com/sql/editions/express/default.mspx A free limited version, SQL Server Express Edition] is available for testing.)&lt;br /&gt;
:Make sure that you choose mixed authentication (Windows and local accounts) to keep things simpler later.  You&#039;ll be asked to define the  &amp;quot;sa&amp;quot; account password (it&#039;s the default System Administrator account which has full access to all databases by default).&lt;br /&gt;
&lt;br /&gt;
2. Make sure MS SQL Server can accept incoming TCP/IP connections on port 1433 (the standard one).&lt;br /&gt;
:You might need to explicitly allow this in your Windows firewall (see the Control Panel).  You may also need to edit options in the :&#039;&#039;&#039;SQL Server Configuration Manager&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Network Configuration&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Protocols&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;TCP/IP enabled&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
3. Open the &amp;quot;SQL Server Management Studio&amp;quot; and create a new empty database.  If you are using the &amp;quot;sa&amp;quot; account then you don&#039;t need to do anything else here.&lt;br /&gt;
&lt;br /&gt;
4. Configure these settings in your created (and still empty) database:&lt;br /&gt;
&lt;br /&gt;
:* ANSI NULLS Enabled = true (ALTER DATABASE xxxx SET ANSI_NULLS ON)&lt;br /&gt;
:* Quoted Identifiers Enabled = true (ALTER DATABASE xxxx SET QUOTED_IDENTIFIER ON)&lt;br /&gt;
:* Moodle 2.0 only: Row Versioning Enabled (ALTER DATABASE xxxx SET READ_COMMITTED_SNAPSHOT ON)&lt;br /&gt;
&lt;br /&gt;
5. Get PHP installed with a web server.   Unless you want to do it under IIS or some other way, the packages on the [http://download.moodle.org Moodle download page] are a good solution.&lt;br /&gt;
&lt;br /&gt;
6. Choose one of the following specific sections for your server to install the &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039; installed and running properly on your PHP box.&lt;br /&gt;
&lt;br /&gt;
7. Set the following settings in your php.ini file&lt;br /&gt;
:* mssql.textlimit = 20971520&lt;br /&gt;
:* mssql.textsize = 20971520&lt;br /&gt;
:Also, don&#039;t forget to set one of the following &#039;&#039;&#039;alternatives&#039;&#039;&#039;, in order to get all the data properly &amp;quot;slashed&amp;quot;:&lt;br /&gt;
:* magic_quotes_gpc = Off  &#039;&#039;&#039;or&#039;&#039;&#039;&lt;br /&gt;
:* magic_quotes_gpc = On &#039;&#039;&#039;and&#039;&#039;&#039; magic_quotes_sybase = On &lt;br /&gt;
&lt;br /&gt;
8. With all this properly configured, you can continue with a [[Installing Moodle|standard Moodle installation]].&lt;br /&gt;
&lt;br /&gt;
== Using FreeTDS on Windows ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&#039;&#039;&#039;Important Note 1:&#039;&#039;&#039; Due to some previous bugs it&#039;s highly recommendable to use PHP &amp;gt;= 5.2.6 and FreeTDS 0.82 + post-release patches ([http://tracker.moodle.org/browse/MDL-14725 more info]).&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If your web server is on Windows, use &#039;&#039;&#039;php_dblib.dll&#039;&#039;&#039;. Despite the name, it&#039;s FreeTDS compiled for Windows. (Go to this page for information on [https://docs.moodle.org/en/FreeTDS Using FreeTDS for Unix].) &lt;br /&gt;
&lt;br /&gt;
Originally we were using the DLLs available at [http://kromann.info/article.php?Id=11062598797760000 Frank Kromann&#039;s site], but they are outdated (using old versions of FreeTDS) and that has caused [http://tracker.moodle.org/browse/MDL-14725 some problems] in the past.&lt;br /&gt;
&lt;br /&gt;
So, right now, the recommended way to use FreeTDS under Windows is to use PHP 5.2.x following the following instructions:&lt;br /&gt;
&lt;br /&gt;
1. Download the appropriate copy of php_dblib.dll from the list below, and save it into your /PHP/ext directory.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; cellpadding=&amp;quot;5&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! PHP version !! [http://www.iis-aid.com/articles/my_word/difference_between_php_thread_safe_and_non_thread_safe_binaries Thread Safe]  !! FreeTDS version !! Download URL&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | PHP 5.2.x (vc6) || Yes || 0.82 + 20090302 patches || [http://download.moodle.org/download.php/dblib/php52/DBLIB_TS.zip Download!]&lt;br /&gt;
|-&lt;br /&gt;
| No || 0.82 + 20090302 patches || [http://download.moodle.org/download.php/dblib/php52/DBLIB_NOTS.zip Download!]&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | PHP 5.3.x (vc9) || Yes || 0.82 + 20090904 patches || [http://download.moodle.org/download.php/dblib/php53/DBLIB_TS.zip Download!]&lt;br /&gt;
|-&lt;br /&gt;
| No || 0.82 + 20090904 patches || [http://download.moodle.org/download.php/dblib/php53/DBLIB_NOTS.zip Download!]&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; |  Thanks to [http://remote-learner.net/ Remote-Learner]] (Moodle [http://moodle.com/partners/ Partner]) and specially to Bryan Williams, donating one Visual C++ 6.0 Pro license to Moodle. Thanks to Trevor Johnson and his builds of the dblib extensions. Thanks to Daniele, Doug, Luis, Sean and many others by their collaboration in MDL-14725. Thanks to Frediano Ziglio and James K. Lowden from [http://freetds.org freetds.org] by their support. Thanks to Alastair Hole by providing the PHP 5.3 builds of the libraries. Thanks!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(alternatively here you can find some [[Development:Compiling FreeTDS under Windows|instructions to build those freetds extensions under win32]] yourself)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. FreeTDS requires the .NET Framework v1.1 to be installed.  You can [http://www.microsoft.com/downloads/details.aspx?FamilyID=262d25e3-f589-4842-8157-034d1e7cf3a3&amp;amp;DisplayLang=en download it from the Microsoft website] along with its [http://www.microsoft.com/downloads/details.aspx?FamilyID=a8f5654f-088e-40b2-bbdb-a83353618b38&amp;amp;DisplayLang=en service pack].  Alternatively, if you do not wish to install this framework, you can [http://kromann.info/ms-libs/msvcr71.dll download the required DLL] from Frank&#039;s site, and save it into your /PHP root directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. Edit your /PHP/php.ini file and add this line:&lt;br /&gt;
&lt;br /&gt;
  extension=php_dblib.dll &lt;br /&gt;
&lt;br /&gt;
Make sure that any lines referring to the php_mssql.dll extension are DISABLED (commented out).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4. When the PHP engine loads the FreeTDS extension it needs to be passed certain infiormation in order to be able to connect to your Moodle database. To retrieve this information FreeTDS looks for a file called &#039;&#039;&#039;freetds.conf&#039;&#039;&#039; in the root folder of the server that PHP installed on (e.g. C:\).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;freetds.conf&#039;&#039;&#039; should have the following structure:&lt;br /&gt;
&lt;br /&gt;
  [global]&lt;br /&gt;
      host = xxx.xxx.xxx.xxx (host name or ip of the MSSQL server)&lt;br /&gt;
      port = 1433&lt;br /&gt;
      client charset = UTF-8&lt;br /&gt;
      tds version = 8.0&lt;br /&gt;
      text size = 20971520&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to connect to a particular [http://msdn.microsoft.com/en-us/library/aa174516(SQL.80).aspx instance] of MSSQL you should specify the instance name:&lt;br /&gt;
&lt;br /&gt;
  [global]&lt;br /&gt;
      host = xxx.xxx.xxx.xxx (host name or ip of the MSSQL server)&lt;br /&gt;
      instance = xxx (instance name, e.g. INST2)&lt;br /&gt;
      port = 1433&lt;br /&gt;
      client charset = UTF-8&lt;br /&gt;
      tds version = 8.0&lt;br /&gt;
      text size = 20971520&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
*You can configure FreeTDS to look for the freetds.conf file in any directory that you want - you don&#039;t have to use C:\. To do this create a SYSTEM environment variable called &#039;&#039;&#039;FREETDS&#039;&#039;&#039; and point it to the directory where you have installed the freetds.conf file. If you do not set this environment variable FreeTDS will look for the freetds.conf file in the C:\ folder, which is the default. One possible benefit of setting the FREETDS environment variable and using a different installation directory for freetds.conf is that C:\ is very predictable to a hacker that knows anything about FreeTDS and that is the first place that he would look if he wanted to compromise your system. So, using a different installation directory would just make your system stronger. See the FreeTDS [http://www.freetds.org/userguide/envvar.htm Setting the environment variables] documentation for more information about this FREETDS environment variable.&lt;br /&gt;
&lt;br /&gt;
*Alternatively, you can [[Development:Compiling FreeTDS under Windows|recompile]] the FreeTDS extension yourself and change the default location to your preferred location at compile time. Then it is not necessary to create any environment variable. You must just ensure that freetds.conf is in the same folder that you specify when you compile php_dblib.dll.&lt;br /&gt;
&lt;br /&gt;
*MSSQL is usually installed with port 1433 as the default. However, if the port was changed on your server when you installed MSSQL then you need to specify the correct port number.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
5. Your Moodle &#039;&#039;&#039;config.php&#039;&#039;&#039; should include lines like these:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;mssql_n&#039;;        // Required&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;localhost&#039;;      // assuming MS SQL is on the same server, otherwise use an IP&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;moodle&#039;;         // or whatever you called the database you created&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // I usually use the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  false;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;            //Prefix, you can change it, but NEVER leave it blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have a config.php file yet, it can be generated as normal from the Moodle installer. Alternatively you can use the config-dist.php file that comes with the Moodle package to create your own config.php file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
6. Restart or start your web server.  If Moodle still cannot communicate with the database server, please turn display_startup_errors to &amp;quot;On&amp;quot; in your /PHP/php.ini file, then restart the web server and check for any errors that may indicate incorrect DLL versions or missing dependencies.  These error reports, turned off by default in PHP, can be vital in locating a problem with new extension installations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
7. Database conection test, try this PHP script, just put in a text file called test.php change (&#039;localhost&#039;, &#039;db_user&#039;, &#039;db_password&#039;) to suite your setup, and load from local host (http://localhost/test.php)...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
	$link = mssql_connect(&#039;localhost&#039;, &#039;db_user&#039;, &#039;db_password&#039;);&lt;br /&gt;
	if(!$link) {&lt;br /&gt;
		echo&#039;Could not connect&#039;;&lt;br /&gt;
		die(&#039;Could not connect: &#039; . mssql_error());&lt;br /&gt;
	}&lt;br /&gt;
	echo&#039;Successful connection&#039;;&lt;br /&gt;
	mssql_close($link);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
8. Install Moodle as usual.  Good luck!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
If you encounter some problems you can try:&lt;br /&gt;
*check that you have DotNet framework 1.1 installed (later version are installed on Vista, but you could need this specific one)&amp;lt;br /&amp;gt;&lt;br /&gt;
*enable TCP/IP for MSSQL: SQL Server 2005 Network Configuration -&amp;gt; Protocols for MSSQLSERVER -&amp;gt; TCP/IP (Enable) -&amp;gt; Properties -&amp;gt; Ip Addresses -&amp;gt; 127.0.0.1 (Active+Enable)&amp;lt;br /&amp;gt;&lt;br /&gt;
*if you are using SQL Server 2005 and you have the error &#039;&#039;4004: Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier&#039;&#039;, try the ODBTP method (next chapter). The SQL Server complaining that it doesn&#039;t support pure Unicode via TDS or older versions of ODBC. Microsoft has deprecated DB-Library a long ago, in favor of ODBC, OLE DB, or SQL Native Client. Many new features of SQL 2005 aren&#039;t accessible via DB-Library so if you need them, you could have to switch away from tools based on TDS and DB-Library :(&lt;br /&gt;
&lt;br /&gt;
== Using FreeTDS on Ubuntu by compiling an mssql.so extension ==&lt;br /&gt;
This is a good read to [http://www.robert-gonzalez.com/2009/02/18/building-the-php-ms-sql-server-extension-from-source-on-ubuntu-810/ building a FreeTDS based mssql extension for apache on Ubuntu].&lt;br /&gt;
&lt;br /&gt;
== Using FreeTDS on Debian Lenny ==&lt;br /&gt;
I found the following solution using:&lt;br /&gt;
* PHP Version 5.2.6-1+lenny9&lt;br /&gt;
* Microsoft SQL Server Enterprise Edition, version: 9.00.4053.00&lt;br /&gt;
&amp;lt;pre&amp;gt;apt-get install libsybdb5 freetds-common php5-sybase&lt;br /&gt;
/etc/init.d/apache2 restart&amp;lt;/pre&amp;gt;&lt;br /&gt;
At the end of the process, if all goes fine, you will find in the mssql section of phpinfo();&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! MSSQL Support&lt;br /&gt;
! enabled&lt;br /&gt;
|-&lt;br /&gt;
| Library version &lt;br /&gt;
| FreeTDS &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Using ODBTP on Unix or Windows ==&lt;br /&gt;
&lt;br /&gt;
You can download ODBTP from http://odbtp.sourceforge.net/. Also you will access to the documentation from the same page.&lt;br /&gt;
&lt;br /&gt;
The downloaded package includes both the source code and some binaries to be installed in the server and some ready-to-use &#039;&#039;&#039;mssql extension alternatives&#039;&#039;&#039; for some platforms/PHP versions (so you won&#039;t need to compile it if your PHP server/version binary package is present).&lt;br /&gt;
&lt;br /&gt;
First of all, we have to install the Win32 service that comes with the package. Let&#039;s assume that it&#039;s going to run in the same Win32 machine where your MSSQL server is running (although it can run in any other Win32 server in your network).&lt;br /&gt;
&lt;br /&gt;
To do do, following the instructions present in http://odbtp.sourceforge.net/install.html, you must:&lt;br /&gt;
&lt;br /&gt;
Do the following on the MSSQL server:&lt;br /&gt;
# Create a directory on the Windows host where the service program files will reside, i.e., md odbtp.&lt;br /&gt;
# Copy the files odbtpctl.exe, odbtpsrv.exe and odbtpsrv.ini files from the winservice directory into the directory created in step 1.&lt;br /&gt;
# Edit the file odbtpsrv.ini of the previous step and this line: &amp;lt;pre&amp;gt;MaxRequestSize=20971520&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Open a command prompt (cmd) window on the Windows host.&lt;br /&gt;
# Change to the directory to which the service program files were copied, i.e., cd odbtp.&lt;br /&gt;
# Run the following commands to install and start the service:&lt;br /&gt;
#*   odbtpctl install&lt;br /&gt;
#*   odbtpctl start&lt;br /&gt;
# With these steps you should have one new service running in your host called &amp;quot;odbtp&amp;quot;. Verify it&#039;s present and running in the &amp;quot;Services&amp;quot; control panel.&lt;br /&gt;
# Don&#039;t forget to enable TCP/IP incoming connections to port 2799 in the host you have installed the service!&lt;br /&gt;
&lt;br /&gt;
Now it&#039;s time to build the &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039;. First of all, verify if, in the downloaded package, under the &amp;quot;php&amp;quot; dir, there is one extension suitable for your PHP server/version. If it&#039;s present, you can simply copy it to the php/extensions dir in your PHP server and skip next points about compiling it from source. It&#039;s important to point that, inside each directory, you&#039;ll find &#039;&#039;&#039;two different&#039;&#039;&#039; libraries/dll files. The one that must be copied to the extensions dir is the one called &#039;&#039;&#039;&amp;quot;php_odbtp_mssql.xxx&amp;quot;&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
If in the downloaded package isn&#039;t present the extension matching your PHP platform/version, you should build if from source files. To do that, just &#039;&#039;&#039;&amp;quot;configure, make, make install&amp;quot;&#039;&#039;&#039;. That will create some stuff under &amp;quot;/usr/local&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve successfully built ODBTP is time to create the &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039; that will provide us with the capacity of handling MSSQL DBs from within Moodle. To do so, just configure your PHP server adding this new option to the usual ones:&lt;br /&gt;
&lt;br /&gt;
  --with-odbtp-mssql&lt;br /&gt;
&lt;br /&gt;
then, after the standard &amp;quot;make and make install&amp;quot; steps, your PHP server will be built with MSSQL support provided by ODBTP.&lt;br /&gt;
&lt;br /&gt;
Do the following on the moodle webserver:&lt;br /&gt;
Finally, independently if we are using the binary extension provided in the download or if you have built it from source files, it&#039;s time to configure the extension. &lt;br /&gt;
1. To do so, add this lines, if no present, to your php.ini file:&lt;br /&gt;
&lt;br /&gt;
  extension=php_odbtp_mssql.dll&lt;br /&gt;
&lt;br /&gt;
(only for Win32 PHP servers!)&lt;br /&gt;
&lt;br /&gt;
2. And, for all the server platforms: &lt;br /&gt;
&lt;br /&gt;
  [odbtp]&lt;br /&gt;
  odbtp.interface_file = &amp;quot;/path/to/your/odbtp.conf&amp;quot;&lt;br /&gt;
  odbtp.datetime_format = mdyhmsf&lt;br /&gt;
  odbtp.detach_default_queries = yes&lt;br /&gt;
&lt;br /&gt;
(where &#039;&#039;&amp;quot;/path/to/your/odbtp.conf&amp;quot;&#039;&#039; is usually &#039;&#039;&#039;&amp;quot;/usr/local/etc/odbtp.conf&amp;quot;&#039;&#039;&#039; for Unix systems and &#039;&#039;&#039;&amp;quot;C:\odbtp\odbtp.conf&amp;quot;&#039;&#039;&#039; for Windows systems)&lt;br /&gt;
&lt;br /&gt;
Then, edit such &amp;quot;odbtp.conf&amp;quot; file and put there these contents:&lt;br /&gt;
&lt;br /&gt;
  [global]&lt;br /&gt;
  odbtp host = xxx.xxx.xxx (ip or hostname of the Win32 box running the ODBTP service i.e MSSQL server)&lt;br /&gt;
  type = mssql&lt;br /&gt;
  unicode sql = yes&lt;br /&gt;
  use row cache = yes&lt;br /&gt;
  right trim text = yes&lt;br /&gt;
  var data size = 20971520&lt;br /&gt;
&lt;br /&gt;
With this, your PHP server will be able to connect with the MSSQL DB server using ODBTP. From here, just continue with the installation.&lt;br /&gt;
&lt;br /&gt;
Finally, if you find the ODBTP executables and &#039;&#039;&#039;mssql extension alternative&#039;&#039;&#039; in binary formats, it only will be necessary to install them in your server (binary packages...) without the need to recompile anything (just the php.ini and odbtp.conf edition steps above will be necessary). Of course, it will be really welcome to have all those binary alternatives documented here.&lt;br /&gt;
&lt;br /&gt;
Once ODBTP is working, Moodle config.php should include lines like these:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;mssql_n&#039;;        // Required&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;localhost&#039;;      // assuming MS SQL is on the same server, otherwise use an IP&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;moodle&#039;;         // or whatever you called the database you created&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // I usually use the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  false;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;            //Prefix, you can change it, but NEVER leave it blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have a config.php file yet, it can be generated as normal from the Moodle installer.&lt;br /&gt;
&lt;br /&gt;
== Using ODBC on Windows ==&lt;br /&gt;
[[ODBC]] allows communication with an SQL database.&lt;br /&gt;
{{Not for production sites}}&lt;br /&gt;
&lt;br /&gt;
1. Go to the &#039;&#039;&#039;Administrative Tools&#039;&#039;&#039;  control panel, then the &#039;&#039;&#039;Data Sources (ODBC)&#039;&#039;&#039; panel.&lt;br /&gt;
&lt;br /&gt;
2. Configure one new System/User DSN (call it, for example &amp;quot;moodle&amp;quot;). Dont forget to enable these options if the driver asks for them:&lt;br /&gt;
&lt;br /&gt;
:* ANSI NULLS Enabled = true&lt;br /&gt;
:* Quoted Identifiers Enabled = true&lt;br /&gt;
&lt;br /&gt;
3. Your Moodle config.php should include lines like these:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;odbc_mssql&#039;;     // Note this is different to all the other configs on this page!&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;moodle&#039;;         // Where this matches the Data source name you chose above&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;&#039;;               // Keep it blank!!&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // I usually use the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  false;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;            //Prefix, you can change it, but NEVER leave it blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Install Moodle as usual.  Good luck!&lt;br /&gt;
&lt;br /&gt;
== Using the SQL Server 2005 Driver for PHP from Microsoft ==&lt;br /&gt;
In July 2008 Microsoft [http://social.msdn.microsoft.com/forums/en-US/sqldriverforphp/thread/a10e5202-9e41-4ff8-a33e-fbcc7b951be2/ released] a new SQL Server 2005 Driver for PHP. This is a PHP extension that allows for the reading and writing of SQL Server data from within PHP scripts and it overcomes the problems with the native SQL Server extension that was previously included with PHP.&lt;br /&gt;
&lt;br /&gt;
This driver is the standard database layer for running Moodle 2 under Microsoft SQL Server databases. See [[Using the Microsoft SQL Server Driver for PHP]] the installation and configuration details.&lt;br /&gt;
&lt;br /&gt;
This driver is only supported in Moodle 2.0 and up. You should use FreeTDS if you are installing an older version of Moodle.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
MDL-16497&lt;br /&gt;
&lt;br /&gt;
MDL-15093&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Installing Moodle]]&lt;br /&gt;
* [[Errors FAQ]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum]&lt;br /&gt;
* [[Beginning Administration FAQ]]&lt;br /&gt;
* [[Installing Oracle for PHP]]&lt;br /&gt;
&lt;br /&gt;
* [[Category:FAQ]]&lt;br /&gt;
* [[Category:Installation]]&lt;br /&gt;
* [[Category:Developer]]&lt;br /&gt;
* [[Category:XMLDB]]&lt;br /&gt;
* [[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=78549</id>
		<title>Using the Microsoft SQL Server Driver for PHP</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=78549"/>
		<updated>2010-12-01T14:21:21Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Typos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
== Using the SQL Server Driver for PHP from Microsoft ==&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This short manual is for running Moodle 2.0 (and upwards) using the Microsoft SQL Server (MSSQL) RDBMS. The steps detailed below must be performed &#039;&#039;&#039;before&#039;&#039;&#039; installing Moodle itself.&lt;br /&gt;
&lt;br /&gt;
First of all, the minimum required version of MSSQL has been stabilized to MSSQL 2005 (v.9).&lt;br /&gt;
&lt;br /&gt;
== Installation overview ==&lt;br /&gt;
1. Install Microsoft SQL Server including SQL Server Management Studio. ([http://www.microsoft.com/sql/editions/express/default.mspx A free version, SQL Server Express Edition] is available for testing.)&lt;br /&gt;
:Make sure to choose mixed authentication (Windows and local accounts) to keep things simpler later.  Define the &amp;quot;sa&amp;quot; account password when requested (it&#039;s the default System Administrator account which has full access to all databases by default).&lt;br /&gt;
&lt;br /&gt;
2. Configure Windows for MSSQL.&lt;br /&gt;
:By default, MSSQL listens to port 1433 for incoming TCP/IP connections and this port needs to be opened in the firewall. This is explicitly configured in the firewall installed (either Windows Firewall in the Control Panel or the configuration interface for other firewalls). If the port was changed when MSSQL was installed, then specify the correct port number to open in the firewall.&lt;br /&gt;
:Confirm the TCP/IP protocol is enabled in: &#039;&#039;&#039;SQL Server Configuration Manager&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Network Configuration&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Protocols&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;TCP/IP enabled&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
3. Create and configure a new database.&lt;br /&gt;
:Open &amp;quot;SQL Server Management Studio&amp;quot; and create a new empty database.&lt;br /&gt;
*Execute the following command to enable Row Versioning:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 USE MASTER&lt;br /&gt;
 GO&lt;br /&gt;
 ALTER DATABASE &amp;amp;lt;your-database-name&amp;amp;gt; SET READ_COMMITTED_SNAPSHOT ON&lt;br /&gt;
 GO&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Install PHP and a web server.&lt;br /&gt;
*PHP can be downloaded from [http://www.php.net/downloads.php www.php.net]&lt;br /&gt;
*If IIS is used as the web server, IIS 7.0 or later is recommended with [http://www.iis.net/download FastCGI and WinCache]. &lt;br /&gt;
&lt;br /&gt;
5. Install the SQL Server Driver for PHP.&lt;br /&gt;
:On the web server, install [http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=ccdf728b-1ea0-48a8-a84a-5052214caad9 SQL Server Driver for PHP] including all the pre-requisites listed on the download page. Note: it is critical to install the SQL Server Native Access Client version documented on the download page of the SQL Server Driver for PHP.&lt;br /&gt;
:Configure PHP to use the appropriate SQLSRV driver. In php.ini, set the following:&lt;br /&gt;
&lt;br /&gt;
For PHP 5.2.4 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 [PHP_SQLSRV]&lt;br /&gt;
 extension=php_sqlsrv_52_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For PHP 5.3.2 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 [PHP_SQLSRV]&lt;br /&gt;
 extension=php_sqlsrv_53_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Microsoft documentation for the SQL Server Driver for PHP is available at: http://msdn.microsoft.com/en-us/library/ee229548(v=SQL.10).aspx &lt;br /&gt;
&lt;br /&gt;
6. Install and configure Moodle.&lt;br /&gt;
:Continue with the [[Installing Moodle|standard Moodle installation]].&lt;br /&gt;
&lt;br /&gt;
7. The Moodle &#039;&#039;&#039;config.php&#039;&#039;&#039; should include lines like these:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;sqlsrv&#039;;         // Required&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;localhost&#039;;      // Assuming MSSQL is on the same server, otherwise use an IP address&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;moodle&#039;;         // The name of the newly created Moodle database&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // Usually the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  true;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;           // The prefix can be changed per individual preferences, but NEVER leave this blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:If the config.php file doesn&#039;t exist, it will be generated as normal from the Moodle installer. Alternatively, use the config-dist.php file that comes with the Moodle package to create a custom config.php file.&lt;br /&gt;
&lt;br /&gt;
8. Restart or start your web server.&lt;br /&gt;
:If Moodle still cannot communicate with the database server, turn &#039;&#039;&#039;display_startup_errors&#039;&#039;&#039; to &amp;quot;On&amp;quot; in the /PHP/php.ini file, then restart the web server and check for any errors that may indicate incorrect DLL versions or missing dependencies.  These error reports, turned off by default in PHP, can be vital in locating a problem with new extension installations.&lt;br /&gt;
&lt;br /&gt;
9. Test the database connection.&lt;br /&gt;
:Try this PHP script, just add a text file called test.php from the example below and change (&#039;localhost&#039;, &#039;db_user&#039;, &#039;db_password&#039;) to align with the config.php settings, and load from local host (http://localhost/test.php).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$link = sqlsrv_connect($this-&amp;gt;dbhost, array(&#039;UID&#039; =&amp;gt; &#039;db_user&#039;, &#039;PWD&#039; =&amp;gt; &#039;db_password&#039;));&lt;br /&gt;
if($link === FALSE) {&lt;br /&gt;
    echo &#039;Could not connect&#039;;&lt;br /&gt;
    die(&#039;Could not connect: &#039; . sqlsrv_errors(SQLSRV_ERR_ALL));&lt;br /&gt;
}&lt;br /&gt;
echo &#039;Successful connection&#039;;&lt;br /&gt;
sqlsrv_close($link);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
10. Complete the rest of the Moodle installation as usual.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Installing Moodle]]&lt;br /&gt;
* [[Errors FAQ]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum]&lt;br /&gt;
* [[Beginning Administration FAQ]]&lt;br /&gt;
* [[Installing Oracle for PHP]]&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=78547</id>
		<title>Using the Microsoft SQL Server Driver for PHP</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=78547"/>
		<updated>2010-12-01T14:03:14Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Typos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
== Using the SQL Server Driver for PHP from Microsoft ==&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This short manual is for running Moodle 2.0 (and upwards) using Microsoft SQL Server (MSSQL) RDBMS. Steps detailed below must be performed &#039;&#039;&#039;before&#039;&#039;&#039; installing Moodle itself.&lt;br /&gt;
&lt;br /&gt;
First of all, minimum required version of MSSQL has been stabilized to MSSQL 2005 (v.9).&lt;br /&gt;
== Installation overview ==&lt;br /&gt;
1. Install Microsoft SQL Server including SQL Server Management Studio. ([http://www.microsoft.com/sql/editions/express/default.mspx A free version, SQL Server Express Edition] is available for testing.)&lt;br /&gt;
:Make sure to choose mixed authentication (Windows and local accounts) to keep things simpler later.  Define the &amp;quot;sa&amp;quot; account password when requested (it&#039;s the default System Administrator account which has full access to all databases by default).&lt;br /&gt;
&lt;br /&gt;
2. Configure Windows for MSSQL.&lt;br /&gt;
:By default, MSSQL listens to port 1433 for incoming TCP/IP connections and this port needs to be opened in the firewall. This is explicitly configured in the firewall installed (either Windows Firewall in the Control Panel or the configuration interface for other firewalls). If the port was changed when MSSQL was installed, then specify the correct port number to open in the firewall.&lt;br /&gt;
:Confirm the TCP/IP protocol is enabled in: &#039;&#039;&#039;SQL Server Configuration Manager&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Network Configuration&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Protocols&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;TCP/IP enabled&#039;&#039;&#039;&lt;br /&gt;
*MSSQL is usually installed with port 1433 as the default.&lt;br /&gt;
&lt;br /&gt;
3. Create and configure a new database.&lt;br /&gt;
:Open &amp;quot;SQL Server Management Studio&amp;quot; and create a new empty database.&lt;br /&gt;
*Execute the following command to enable Row Versioning:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 USE MASTER&lt;br /&gt;
 GO&lt;br /&gt;
 ALTER DATABASE &amp;amp;lt;your-database-name&amp;amp;gt; SET READ_COMMITTED_SNAPSHOT ON&lt;br /&gt;
 GO&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Install PHP and a web server.&lt;br /&gt;
*PHP can be downloaded from [http://www.php.net/downloads.php www.php.net]&lt;br /&gt;
*If IIS is used as the web server, IIS 7.0 or later is recommended with [http://www.iis.net/download FastCGI and WinCache]. &lt;br /&gt;
&lt;br /&gt;
5. Install the SQL Server Driver for PHP.&lt;br /&gt;
:On the web server, install [http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=ccdf728b-1ea0-48a8-a84a-5052214caad9 SQL Server Driver for PHP] including all the pre-requisites listed on the download page. Note: it is critical to install the SQL Server Native Access Client version documented on the download page of the SQL Server Driver for PHP.&lt;br /&gt;
:Configure PHP to use the appropriate SQLSRV driver. In php.ini, set the following:&lt;br /&gt;
&lt;br /&gt;
For PHP 5.2.4 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 [PHP_SQLSRV]&lt;br /&gt;
 extension=php_sqlsrv_52_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For PHP 5.3.2 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 [PHP_SQLSRV]&lt;br /&gt;
 extension=php_sqlsrv_53_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Microsoft documentation for the SQL Server Driver for PHP is available at: http://msdn.microsoft.com/en-us/library/ee229548(v=SQL.10).aspx &lt;br /&gt;
&lt;br /&gt;
6. Install and configure Moodle.&lt;br /&gt;
:Continue with the [[Installing Moodle|standard Moodle installation]].&lt;br /&gt;
&lt;br /&gt;
7. The Moodle &#039;&#039;&#039;config.php&#039;&#039;&#039; should include lines like these:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;sqlsrv&#039;;         // Required&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;localhost&#039;;      // Assuming MSSQL is on the same server, otherwise use an IP address&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;moodle&#039;;         // The name of the newly created Moodle database&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // Usually the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  true;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;           // The prefix can be changed per individual preferences, but NEVER leave this blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:If the config.php file doesn&#039;t exist, it will be generated as normal from the Moodle installer. Alternatively, use the config-dist.php file that comes with the Moodle package to create a custom config.php file.&lt;br /&gt;
&lt;br /&gt;
8. Restart or start your web server.&lt;br /&gt;
:If Moodle still cannot communicate with the database server, turn &#039;&#039;&#039;display_startup_errors&#039;&#039;&#039; to &amp;quot;On&amp;quot; in the /PHP/php.ini file, then restart the web server and check for any errors that may indicate incorrect DLL versions or missing dependencies.  These error reports, turned off by default in PHP, can be vital in locating a problem with new extension installations.&lt;br /&gt;
&lt;br /&gt;
9. Test the database connection.&lt;br /&gt;
:Try this PHP script, just add a text file called test.php from the example below and change (&#039;localhost&#039;, &#039;db_user&#039;, &#039;db_password&#039;) to align with the config.php settings, and load from local host (http://localhost/test.php).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$link = sqlsrv_connect($this-&amp;gt;dbhost, array(&#039;UID&#039; =&amp;gt; &#039;db_user&#039;, &#039;PWD&#039; =&amp;gt; &#039;db_password&#039;));&lt;br /&gt;
if($link === FALSE) {&lt;br /&gt;
    echo &#039;Could not connect&#039;;&lt;br /&gt;
    die(&#039;Could not connect: &#039; . sqlsrv_errors(SQLSRV_ERR_ALL));&lt;br /&gt;
}&lt;br /&gt;
echo &#039;Successful connection&#039;;&lt;br /&gt;
sqlsrv_close($link);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
10. Complete the rest of the Moodle installation as usual.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Installing Moodle]]&lt;br /&gt;
* [[Errors FAQ]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum]&lt;br /&gt;
* [[Beginning Administration FAQ]]&lt;br /&gt;
* [[Installing Oracle for PHP]]&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=78546</id>
		<title>Using the Microsoft SQL Server Driver for PHP</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=78546"/>
		<updated>2010-12-01T13:58:59Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Typos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
== Using the SQL Server Driver for PHP from Microsoft ==&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This short manual is for running Moodle 2.0 (and upwards) using Microsoft SQL Server (MSSQL) RDBMS. Steps detailed below must be performed &#039;&#039;&#039;before&#039;&#039;&#039; installing Moodle itself.&lt;br /&gt;
&lt;br /&gt;
First of all, minimum required version of MSSQL has been stabilized to MSSQL 2005 (v.9).&lt;br /&gt;
== Installation overview ==&lt;br /&gt;
1. Install Microsoft SQL Server including SQL Server Management Studio. ([http://www.microsoft.com/sql/editions/express/default.mspx A free version, SQL Server Express Edition] is available for testing.)&lt;br /&gt;
:Make sure to choose mixed authentication (Windows and local accounts) to keep things simpler later.  Define the &amp;quot;sa&amp;quot; account password when requested (it&#039;s the default System Administrator account which has full access to all databases by default).&lt;br /&gt;
&lt;br /&gt;
2. Configure Windows for MSSQL.&lt;br /&gt;
:By default, MSSQL listens to port 1433 for incoming TCP/IP connections and this port needs to be opened in the firewall. This is explicitly configured in the firewall installed (either Windows Firewall in the Control Panel or the configuration interface for other firewalls). If the port was changed when MSSQL was installed, then specify the correct port number to open in the firewall.&lt;br /&gt;
:Confirm the TCP/IP protocol is enabled in: &#039;&#039;&#039;SQL Server Configuration Manager&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Network Configuration&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Protocols&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;TCP/IP enabled&#039;&#039;&#039;&lt;br /&gt;
*MSSQL is usually installed with port 1433 as the default.&lt;br /&gt;
&lt;br /&gt;
3. Create and configure a new database.&lt;br /&gt;
:Open &amp;quot;SQL Server Management Studio&amp;quot; and create a new empty database.&lt;br /&gt;
*Execute the following command to enable Row Versioning:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 USE MASTER&lt;br /&gt;
 GO&lt;br /&gt;
 ALTER DATABASE &amp;amp;lt;your-database-name&amp;amp;gt; SET READ_COMMITTED_SNAPSHOT ON&lt;br /&gt;
 GO&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Install PHP and a web server.&lt;br /&gt;
*PHP can be downloaded from [http://www.php.net/downloads.php www.php.net]&lt;br /&gt;
*If IIS is used as the web server, IIS 7.0 or later is recommended with [http://www.iis.net/download FastCGI and WinCache]. &lt;br /&gt;
&lt;br /&gt;
5. Install the SQL Server Driver for PHP.&lt;br /&gt;
:On the web server, install [http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=ccdf728b-1ea0-48a8-a84a-5052214caad9 SQL Server Driver for PHP] including all the pre-requisites listed on the download page. Note: it is critical to install the SQL Server Native Access Client version documented on the download page of the SQL Server Driver for PHP.&lt;br /&gt;
:Configure PHP to use the appropriate SQLSRV driver. In php.ini, set the following:&lt;br /&gt;
&lt;br /&gt;
For PHP 5.2.4 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[PHP_SQLSRV]&lt;br /&gt;
extension=php_sqlsrv_52_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For PHP 5.3.2 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[PHP_SQLSRV]&lt;br /&gt;
extension=php_sqlsrv_53_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Microsoft documentation for the SQL Server Driver for PHP is available at: http://msdn.microsoft.com/en-us/library/ee229548(v=SQL.10).aspx &lt;br /&gt;
&lt;br /&gt;
6. Install and configure Moodle.&lt;br /&gt;
:Continue with the [[Installing Moodle|standard Moodle installation]].&lt;br /&gt;
&lt;br /&gt;
7. The Moodle &#039;&#039;&#039;config.php&#039;&#039;&#039; should include lines like these:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;sqlsrv&#039;;         // Required&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;localhost&#039;;      // Assuming MSSQL is on the same server, otherwise use an IP address&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;moodle&#039;;         // The name of the newly created Moodle database&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // Usually the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  true;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;           // The prefix can be changed per individual preferences, but NEVER leave this blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:If the config.php file doesn&#039;t exist, it will be generated as normal from the Moodle installer. Alternatively, use the config-dist.php file that comes with the Moodle package to create a custom config.php file.&lt;br /&gt;
&lt;br /&gt;
8. Restart or start your web server.&lt;br /&gt;
:If Moodle still cannot communicate with the database server, please turn display_startup_errors to &amp;quot;On&amp;quot; in the /PHP/php.ini file, then restart the web server and check for any errors that may indicate incorrect DLL versions or missing dependencies.  These error reports, turned off by default in PHP, can be vital in locating a problem with new extension installations.&lt;br /&gt;
&lt;br /&gt;
9. Test the database connection.&lt;br /&gt;
:Try this PHP script, just add a text file called test.php from the example below and change (&#039;localhost&#039;, &#039;db_user&#039;, &#039;db_password&#039;) to align with the config.php settings, and load from local host (http://localhost/test.php).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$link = sqlsrv_connect($this-&amp;gt;dbhost, array(&#039;UID&#039; =&amp;gt; &#039;db_user&#039;, &#039;PWD&#039; =&amp;gt; &#039;db_password&#039;));&lt;br /&gt;
if($link === FALSE) {&lt;br /&gt;
    echo &#039;Could not connect&#039;;&lt;br /&gt;
    die(&#039;Could not connect: &#039; . sqlsrv_errors(SQLSRV_ERR_ALL));&lt;br /&gt;
}&lt;br /&gt;
echo &#039;Successful connection&#039;;&lt;br /&gt;
sqlsrv_close($link);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
10. Complete the rest of the Moodle installation as usual.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Installing Moodle]]&lt;br /&gt;
* [[Errors FAQ]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum]&lt;br /&gt;
* [[Beginning Administration FAQ]]&lt;br /&gt;
* [[Installing Oracle for PHP]]&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=78545</id>
		<title>Using the Microsoft SQL Server Driver for PHP</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=78545"/>
		<updated>2010-12-01T13:55:16Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Typos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
== Using the SQL Server Driver for PHP from Microsoft ==&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This short manual is for running Moodle 2.0 (and upwards) using Microsoft SQL Server (MSSQL) RDBMS. Steps detailed below must be performed &#039;&#039;&#039;before&#039;&#039;&#039; installing Moodle itself.&lt;br /&gt;
&lt;br /&gt;
First of all, minimum required version of MSSQL has been stabilized to MSSQL 2005 (v.9).&lt;br /&gt;
== Installation overview ==&lt;br /&gt;
1. Install Microsoft SQL Server including SQL Server Management Studio. ([http://www.microsoft.com/sql/editions/express/default.mspx A free version, SQL Server Express Edition] is available for testing.)&lt;br /&gt;
:Make sure to choose mixed authentication (Windows and local accounts) to keep things simpler later.  Define the &amp;quot;sa&amp;quot; account password when requested (it&#039;s the default System Administrator account which has full access to all databases by default).&lt;br /&gt;
&lt;br /&gt;
2. Configure Windows for MSSQL.&lt;br /&gt;
:By default, MSSQL listens to port 1433 for incoming TCP/IP connections and this port needs to be opened in the firewall. This is explicitly configured in the firewall installed (either Windows Firewall in the Control Panel or the configuration interface for other firewalls). If the port was changed when MSSQL was installed, then specify the correct port number to open in the firewall.&lt;br /&gt;
:Confirm the TCP/IP protocol is enabled in: &#039;&#039;&#039;SQL Server Configuration Manager&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Network Configuration&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Protocols&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;TCP/IP enabled&#039;&#039;&#039;&lt;br /&gt;
*MSSQL is usually installed with port 1433 as the default.&lt;br /&gt;
&lt;br /&gt;
3. Create and configure a new database.&lt;br /&gt;
:Open &amp;quot;SQL Server Management Studio&amp;quot; and create a new empty database.&lt;br /&gt;
*Execute the following command to enable Row Versioning:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 USE MASTER&lt;br /&gt;
 GO&lt;br /&gt;
 ALTER DATABASE &amp;amp;lt;your-database-name&amp;amp;gt; SET READ_COMMITTED_SNAPSHOT ON&lt;br /&gt;
 GO&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Install PHP and a web server.&lt;br /&gt;
*PHP can be downloaded from [http://www.php.net/downloads.php www.php.net]&lt;br /&gt;
*If IIS is used as the web server, IIS 7.0 or later is recommended with [http://www.iis.net/download FastCGI and WinCache]. &lt;br /&gt;
&lt;br /&gt;
5. Install the SQL Server Driver for PHP.&lt;br /&gt;
:On the web server, install [http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=ccdf728b-1ea0-48a8-a84a-5052214caad9 SQL Server Driver for PHP] including all the pre-requisites listed on the download page. Note: it is critical to install the SQL Server Native Access Client version documented on the download page of the SQL Server Driver for PHP.&lt;br /&gt;
:Configure PHP to use the appropriate SQLSRV driver. In php.ini, set the following:&lt;br /&gt;
&lt;br /&gt;
For PHP 5.2.4 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[PHP_SQLSRV]&lt;br /&gt;
&lt;br /&gt;
extension=php_sqlsrv_52_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For PHP 5.3.2 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[PHP_SQLSRV]&lt;br /&gt;
&lt;br /&gt;
extension=php_sqlsrv_53_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Microsoft documentation for the SQL Server Driver for PHP is available at: http://msdn.microsoft.com/en-us/library/ee229548(v=SQL.10).aspx &lt;br /&gt;
&lt;br /&gt;
6. Install and configure Moodle.&lt;br /&gt;
:Continue with the [[Installing Moodle|standard Moodle installation]].&lt;br /&gt;
&lt;br /&gt;
7. The Moodle &#039;&#039;&#039;config.php&#039;&#039;&#039; should include lines like these:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;sqlsrv&#039;;         // Required&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;localhost&#039;;      // Assuming MSSQL is on the same server, otherwise use an IP address&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;moodle&#039;;         // The name of the newly created Moodle database&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // Usually the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  true;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;           // The prefix can be changed per individual preferences, but NEVER leave this blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:If the config.php file doesn&#039;t exist, it will be generated as normal from the Moodle installer. Alternatively, use the config-dist.php file that comes with the Moodle package to create a custom config.php file.&lt;br /&gt;
&lt;br /&gt;
8. Restart or start your web server.&lt;br /&gt;
:If Moodle still cannot communicate with the database server, please turn display_startup_errors to &amp;quot;On&amp;quot; in the /PHP/php.ini file, then restart the web server and check for any errors that may indicate incorrect DLL versions or missing dependencies.  These error reports, turned off by default in PHP, can be vital in locating a problem with new extension installations.&lt;br /&gt;
&lt;br /&gt;
9. Test the database connection.&lt;br /&gt;
:Try this PHP script, just add a text file called test.php from the example below and change (&#039;localhost&#039;, &#039;db_user&#039;, &#039;db_password&#039;) to align with the config.php settings, and load from local host (http://localhost/test.php).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$link = sqlsrv_connect($this-&amp;gt;dbhost, array(&#039;UID&#039; =&amp;gt; &#039;db_user&#039;, &#039;PWD&#039; =&amp;gt; &#039;db_password&#039;));&lt;br /&gt;
if($link === FALSE) {&lt;br /&gt;
    echo &#039;Could not connect&#039;;&lt;br /&gt;
    die(&#039;Could not connect: &#039; . sqlsrv_errors(SQLSRV_ERR_ALL));&lt;br /&gt;
}&lt;br /&gt;
echo &#039;Successful connection&#039;;&lt;br /&gt;
sqlsrv_close($link);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
10. Complete the rest of the Moodle installation as usual.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Installing Moodle]]&lt;br /&gt;
* [[Errors FAQ]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum]&lt;br /&gt;
* [[Beginning Administration FAQ]]&lt;br /&gt;
* [[Installing Oracle for PHP]]&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=78544</id>
		<title>Using the Microsoft SQL Server Driver for PHP</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=78544"/>
		<updated>2010-12-01T13:51:12Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* SQL Server driver instructions from Microsoft */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
== Using the SQL Server Driver for PHP from Microsoft ==&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This short manual is for running Moodle 2.0 (and upwards) using Microsoft SQL Server (MSSQL) RDBMS. Steps detailed below must be performed &#039;&#039;&#039;before&#039;&#039;&#039; installing Moodle itself.&lt;br /&gt;
&lt;br /&gt;
First of all, minimum required version of MSSQL has been stabilized to MSSQL 2005 (v.9).&lt;br /&gt;
== Installation overview ==&lt;br /&gt;
1. Install Microsoft SQL Server including SQL Server Management Studio. ([http://www.microsoft.com/sql/editions/express/default.mspx A free version, SQL Server Express Edition] is available for testing.)&lt;br /&gt;
:Make sure to choose mixed authentication (Windows and local accounts) to keep things simpler later.  Define the &amp;quot;sa&amp;quot; account password when requested (it&#039;s the default System Administrator account which has full access to all databases by default).&lt;br /&gt;
&lt;br /&gt;
2. Configure Windows for MSSQL.&lt;br /&gt;
:By default, MSSQL listens to port 1433 for incoming TCP/IP connections and this port needs to be opened in the firewall. This is explicitly configured in the firewall installed (either Windows Firewall in the Control Panel or the configuration interface for other firewalls). If the port was changed when MSSQL was installed, then specify the correct port number to open in the firewall.&lt;br /&gt;
:Confirm the TCP/IP protocol is enabled in: &#039;&#039;&#039;SQL Server Configuration Manager&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Network Configuration&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Protocols&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;TCP/IP enabled&#039;&#039;&#039;&lt;br /&gt;
*MSSQL is usually installed with port 1433 as the default.&lt;br /&gt;
&lt;br /&gt;
3. Create and configure a new database.&lt;br /&gt;
:Open &amp;quot;SQL Server Management Studio&amp;quot; and create a new empty database.&lt;br /&gt;
*Execute the following command to enable Row Versioning:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 USE MASTER&lt;br /&gt;
 GO&lt;br /&gt;
 ALTER DATABASE &amp;amp;lt;your-database-name&amp;amp;gt; SET READ_COMMITTED_SNAPSHOT ON&lt;br /&gt;
 GO&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Install PHP and a web server.&lt;br /&gt;
*PHP can be downloaded from [http://www.php.net/downloads.php www.php.net]&lt;br /&gt;
*If IIS is used as the web server, IIS 7.0 or later is recommended with [http://www.iis.net/download FastCGI and WinCache]. &lt;br /&gt;
&lt;br /&gt;
5. Install the SQL Server Driver for PHP.&lt;br /&gt;
:On the web server, install [http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=ccdf728b-1ea0-48a8-a84a-5052214caad9 SQL Server Driver for PHP] including all the pre-requisites listed on the download page. Note: it is critical to install the SQL Server Native Access Client version documented on the download page of the SQL Server Driver for PHP.&lt;br /&gt;
:Configure PHP to use the appropriate SQLSRV driver. In php.ini, set the following:&lt;br /&gt;
&lt;br /&gt;
For PHP 5.2.4 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[PHP_SQLSRV] &lt;br /&gt;
extension=php_sqlsrv_52_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For PHP 5.3.2 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[PHP_SQLSRV] &lt;br /&gt;
extension=php_sqlsrv_53_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Microsoft documentation for the SQL Server Driver for PHP is available at: http://msdn.microsoft.com/en-us/library/ee229548(v=SQL.10).aspx &lt;br /&gt;
&lt;br /&gt;
6. Install and configure Moodle.&lt;br /&gt;
:Continue with the [[Installing Moodle|standard Moodle installation]].&lt;br /&gt;
&lt;br /&gt;
7. The Moodle &#039;&#039;&#039;config.php&#039;&#039;&#039; should include lines like these:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;sqlsrv&#039;;         // Required&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;localhost&#039;;      // Assuming MSSQL is on the same server, otherwise use an IP address&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;moodle&#039;;         // The name of the newly created Moodle database&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // Usually the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  true;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;           // The prefix can be changed per individual preferences, but NEVER leave this blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:If the config.php file doesn&#039;t exist, it will be generated as normal from the Moodle installer. Alternatively, use the config-dist.php file that comes with the Moodle package to create a custom config.php file.&lt;br /&gt;
&lt;br /&gt;
8. Restart or start your web server.&lt;br /&gt;
:If Moodle still cannot communicate with the database server, please turn display_startup_errors to &amp;quot;On&amp;quot; in the /PHP/php.ini file, then restart the web server and check for any errors that may indicate incorrect DLL versions or missing dependencies.  These error reports, turned off by default in PHP, can be vital in locating a problem with new extension installations.&lt;br /&gt;
&lt;br /&gt;
9. Test the database connection.&lt;br /&gt;
:Try this PHP script, just add a text file called test.php from the example below and change (&#039;localhost&#039;, &#039;db_user&#039;, &#039;db_password&#039;) to align with the config.php settings, and load from local host (http://localhost/test.php).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$link = sqlsrv_connect($this-&amp;gt;dbhost, array(&#039;UID&#039; =&amp;gt; &#039;db_user&#039;, &#039;PWD&#039; =&amp;gt; &#039;db_password&#039;));&lt;br /&gt;
if($link === FALSE) {&lt;br /&gt;
    echo &#039;Could not connect&#039;;&lt;br /&gt;
    die(&#039;Could not connect: &#039; . sqlsrv_errors(SQLSRV_ERR_ALL));&lt;br /&gt;
}&lt;br /&gt;
echo &#039;Successful connection&#039;;&lt;br /&gt;
sqlsrv_close($link);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
10. Complete the rest of the Moodle installation as usual.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Installing Moodle]]&lt;br /&gt;
* [[Errors FAQ]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum]&lt;br /&gt;
* [[Beginning Administration FAQ]]&lt;br /&gt;
* [[Installing Oracle for PHP]]&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=78543</id>
		<title>Using the Microsoft SQL Server Driver for PHP</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Using_the_Microsoft_SQL_Server_Driver_for_PHP&amp;diff=78543"/>
		<updated>2010-12-01T13:50:53Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* SQL Server driver instructions from Microsoft */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
== Using the SQL Server Driver for PHP from Microsoft ==&lt;br /&gt;
&lt;br /&gt;
=1=&lt;br /&gt;
==2==&lt;br /&gt;
===3===&lt;br /&gt;
====4====&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This short manual is for running Moodle 2.0 (and upwards) using Microsoft SQL Server (MSSQL) RDBMS. Steps detailed below must be performed &#039;&#039;&#039;before&#039;&#039;&#039; installing Moodle itself.&lt;br /&gt;
&lt;br /&gt;
First of all, minimum required version of MSSQL has been stabilized to MSSQL 2005 (v.9).&lt;br /&gt;
== Installation overview ==&lt;br /&gt;
1. Install Microsoft SQL Server including SQL Server Management Studio. ([http://www.microsoft.com/sql/editions/express/default.mspx A free version, SQL Server Express Edition] is available for testing.)&lt;br /&gt;
:Make sure to choose mixed authentication (Windows and local accounts) to keep things simpler later.  Define the &amp;quot;sa&amp;quot; account password when requested (it&#039;s the default System Administrator account which has full access to all databases by default).&lt;br /&gt;
&lt;br /&gt;
2. Configure Windows for MSSQL.&lt;br /&gt;
:By default, MSSQL listens to port 1433 for incoming TCP/IP connections and this port needs to be opened in the firewall. This is explicitly configured in the firewall installed (either Windows Firewall in the Control Panel or the configuration interface for other firewalls). If the port was changed when MSSQL was installed, then specify the correct port number to open in the firewall.&lt;br /&gt;
:Confirm the TCP/IP protocol is enabled in: &#039;&#039;&#039;SQL Server Configuration Manager&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Network Configuration&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Protocols&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;TCP/IP enabled&#039;&#039;&#039;&lt;br /&gt;
*MSSQL is usually installed with port 1433 as the default.&lt;br /&gt;
&lt;br /&gt;
3. Create and configure a new database.&lt;br /&gt;
:Open &amp;quot;SQL Server Management Studio&amp;quot; and create a new empty database.&lt;br /&gt;
*Execute the following command to enable Row Versioning:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 USE MASTER&lt;br /&gt;
 GO&lt;br /&gt;
 ALTER DATABASE &amp;amp;lt;your-database-name&amp;amp;gt; SET READ_COMMITTED_SNAPSHOT ON&lt;br /&gt;
 GO&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Install PHP and a web server.&lt;br /&gt;
*PHP can be downloaded from [http://www.php.net/downloads.php www.php.net]&lt;br /&gt;
*If IIS is used as the web server, IIS 7.0 or later is recommended with [http://www.iis.net/download FastCGI and WinCache]. &lt;br /&gt;
&lt;br /&gt;
5. Install the SQL Server Driver for PHP.&lt;br /&gt;
:On the web server, install [http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=ccdf728b-1ea0-48a8-a84a-5052214caad9 SQL Server Driver for PHP] including all the pre-requisites listed on the download page. Note: it is critical to install the SQL Server Native Access Client version documented on the download page of the SQL Server Driver for PHP.&lt;br /&gt;
:Configure PHP to use the appropriate SQLSRV driver. In php.ini, set the following:&lt;br /&gt;
&lt;br /&gt;
For PHP 5.2.4 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[PHP_SQLSRV] &lt;br /&gt;
extension=php_sqlsrv_52_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For PHP 5.3.2 (or later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[PHP_SQLSRV] &lt;br /&gt;
extension=php_sqlsrv_53_nts_vc9.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Microsoft documentation for the SQL Server Driver for PHP is available at: http://msdn.microsoft.com/en-us/library/ee229548(v=SQL.10).aspx &lt;br /&gt;
&lt;br /&gt;
6. Install and configure Moodle.&lt;br /&gt;
:Continue with the [[Installing Moodle|standard Moodle installation]].&lt;br /&gt;
&lt;br /&gt;
7. The Moodle &#039;&#039;&#039;config.php&#039;&#039;&#039; should include lines like these:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;dbtype    = &#039;sqlsrv&#039;;         // Required&lt;br /&gt;
$CFG-&amp;gt;dbhost    = &#039;localhost&#039;;      // Assuming MSSQL is on the same server, otherwise use an IP address&lt;br /&gt;
$CFG-&amp;gt;dbname    = &#039;moodle&#039;;         // The name of the newly created Moodle database&lt;br /&gt;
$CFG-&amp;gt;dbuser    = &#039;yourusername&#039;;   // Usually the &#039;sa&#039; account (dbowner perms are enough)&lt;br /&gt;
$CFG-&amp;gt;dbpass    = &#039;yourpassword&#039;;&lt;br /&gt;
$CFG-&amp;gt;dbpersist =  true;&lt;br /&gt;
$CFG-&amp;gt;prefix    = &#039;mdl_&#039;;           // The prefix can be changed per individual preferences, but NEVER leave this blank.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:If the config.php file doesn&#039;t exist, it will be generated as normal from the Moodle installer. Alternatively, use the config-dist.php file that comes with the Moodle package to create a custom config.php file.&lt;br /&gt;
&lt;br /&gt;
8. Restart or start your web server.&lt;br /&gt;
:If Moodle still cannot communicate with the database server, please turn display_startup_errors to &amp;quot;On&amp;quot; in the /PHP/php.ini file, then restart the web server and check for any errors that may indicate incorrect DLL versions or missing dependencies.  These error reports, turned off by default in PHP, can be vital in locating a problem with new extension installations.&lt;br /&gt;
&lt;br /&gt;
9. Test the database connection.&lt;br /&gt;
:Try this PHP script, just add a text file called test.php from the example below and change (&#039;localhost&#039;, &#039;db_user&#039;, &#039;db_password&#039;) to align with the config.php settings, and load from local host (http://localhost/test.php).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$link = sqlsrv_connect($this-&amp;gt;dbhost, array(&#039;UID&#039; =&amp;gt; &#039;db_user&#039;, &#039;PWD&#039; =&amp;gt; &#039;db_password&#039;));&lt;br /&gt;
if($link === FALSE) {&lt;br /&gt;
    echo &#039;Could not connect&#039;;&lt;br /&gt;
    die(&#039;Could not connect: &#039; . sqlsrv_errors(SQLSRV_ERR_ALL));&lt;br /&gt;
}&lt;br /&gt;
echo &#039;Successful connection&#039;;&lt;br /&gt;
sqlsrv_close($link);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
10. Complete the rest of the Moodle installation as usual.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Installing Moodle]]&lt;br /&gt;
* [[Errors FAQ]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum]&lt;br /&gt;
* [[Beginning Administration FAQ]]&lt;br /&gt;
* [[Installing Oracle for PHP]]&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Backup_and_restore_FAQ&amp;diff=78378</id>
		<title>Backup and restore FAQ</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Backup_and_restore_FAQ&amp;diff=78378"/>
		<updated>2010-11-28T12:08:59Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Why are some courses being skipped update */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==How do I backup a course?==&lt;br /&gt;
&lt;br /&gt;
See [[Course backup]] and [[Automated course backup]].&lt;br /&gt;
&lt;br /&gt;
==How do I restore a course?==&lt;br /&gt;
&lt;br /&gt;
See [[Restore]].&lt;br /&gt;
&lt;br /&gt;
==How do I backup my site?==&lt;br /&gt;
&lt;br /&gt;
See [[Site backup]].&lt;br /&gt;
&lt;br /&gt;
==What is new in backup and restore in Moodle 2.0?==&lt;br /&gt;
&lt;br /&gt;
See [[Backup 2.0]].&lt;br /&gt;
&lt;br /&gt;
==Backup stops at Zipping backup==&lt;br /&gt;
Moodle 1.9 and lower use a PHP library to zip files that isn&#039;t very efficient and struggles to zip/unzip large files. You can use an external Zip binary to use a different process to handle your files - you can set this in &#039;&#039;Admin &amp;gt; Server &amp;gt; System Paths&#039;&#039; Moodle 2.0 uses new PHP zip functions so that specifying an external Zip binary isn&#039;t necessary see [[System_paths#Path_to_zip]] for help configuring an external zip binary.&lt;br /&gt;
&lt;br /&gt;
==What are the pros and cons of course versus site backups?==&lt;br /&gt;
&lt;br /&gt;
[[Site backup|Site backups]] are recommended in order to have all data saved with the best confidence and the shortest recovery time.&lt;br /&gt;
&lt;br /&gt;
For a site administrator, [[Automated course backup|automated course backups]] are more expensive in terms of time, CPU usage and storage. The recovery time to have a site running again takes longer than a site backup. However,  teachers and site administrators might find a course backups as a way to create a &amp;quot;fresh&amp;quot; copy of a course that can be re-used (in older versions of Moodle, in newer versions see [[Import course data]]) or as a method to distribute a course(s) to other Moodle sites.&lt;br /&gt;
&lt;br /&gt;
==What data is not contained in course backups?==&lt;br /&gt;
&lt;br /&gt;
By selecting all the options when setting up the backup you can include almost all the data in the course. However you should be aware of the fact that some things are not backed up:&lt;br /&gt;
* Quiz questions are only backed up if at least one question from their category has been added to a quiz.&lt;br /&gt;
* Scales are only backed up if they are used by at least one activity.&lt;br /&gt;
&lt;br /&gt;
==The process ends with: &amp;quot;Error: An error occurred deleting old backup data&amp;quot;. What should I do?==&lt;br /&gt;
&lt;br /&gt;
This part of the backup (or restore) procedure tries to delete old info, used in previous executions, performing the following tasks:&lt;br /&gt;
&lt;br /&gt;
# Delete old records from &amp;quot;backup_ids&amp;quot; table: Check the table exists, repair it and try again.&lt;br /&gt;
# Delete old records from &amp;quot;backup_files&amp;quot; table: Check the table exists, repair it and try again.&lt;br /&gt;
# Delete old files from &amp;quot;moodledata/temp/backup&amp;quot;: Delete the dir completely and try again.&lt;br /&gt;
&lt;br /&gt;
[[Image:BackupProblem.gif|thumb|Backup error message]]For points 1 &amp;amp; 2, there are various ways of repairing tables, including using MySQL Admin.&lt;br /&gt;
For point 3 see below:&lt;br /&gt;
&lt;br /&gt;
The error message states that the &amp;quot;directory not empty&amp;quot; and gives the path to that directory. If you go there with an FTP program you can see what is there and clean up. It could be just some empty subfolders that were leftover. Deleting these has been able to help. One can also delete the dir &amp;quot;moodledata/temp/backup&amp;quot; completely. That can take a bit longer but may solve several problems at once.&lt;br /&gt;
&lt;br /&gt;
==The process ends with: &amp;quot;XML error: not well-formed (invalid token) at line YYYY&amp;quot;. What can I do?==&lt;br /&gt;
&lt;br /&gt;
This problem can appear at any point in the restore process. It&#039;s caused when the XML parser detects something incorrect in the backup file that prevent correct operation. Usually, it&#039;s caused by some &amp;quot;illegal&amp;quot; characters added in the original course due to some copy/paste of text containing them (control characters, or invalid sequences...).&lt;br /&gt;
&lt;br /&gt;
The best method to handle this issue is:&lt;br /&gt;
&lt;br /&gt;
* Unzip the problematic backup file under one empty folder.&lt;br /&gt;
&lt;br /&gt;
* Open the moodle.xml with Firefox. It will show you where (exact char) the problem is happening.&lt;br /&gt;
&lt;br /&gt;
* Edit the moodle.xml file with some UTF8-compatible editor and delete such characters. Save changes.&lt;br /&gt;
&lt;br /&gt;
* Test the moodle.xml file again with Firefox until no error was displayed.&lt;br /&gt;
&lt;br /&gt;
* Zip everything again (all the folder contents but not the folder itself!).&lt;br /&gt;
&lt;br /&gt;
* Restore the course. It should work now.&lt;br /&gt;
&lt;br /&gt;
* Restore still not working? See the next question.&lt;br /&gt;
&lt;br /&gt;
Also, if possible, it&#039;s highly recommended to solve those problems in the original course too from Moodle itself. Once &amp;quot;repaired&amp;quot; there, problems will be out if you create new backup files in the future.&lt;br /&gt;
&lt;br /&gt;
==The process ends with: &amp;quot;moodle xml not found at root level of zip file&amp;quot;. What can I do?==&lt;br /&gt;
If you are restoring from a zip file backup make sure the moodle.xml file is at the root level. To ensure this:&lt;br /&gt;
#Unzip the backup file of the course (example: mycourse.zip)&lt;br /&gt;
#Once the file is unzipped, open the folder (example: mycourse).&lt;br /&gt;
#Select the folders within the mycourse folder AND the moodle.xml file and create a zip of those item (example: mycourse_new.zip)&lt;br /&gt;
#Upload the new zip file (example: mycourse_new.zip) and restore from that.&lt;br /&gt;
&lt;br /&gt;
If the backup file is guaranteed to be correct, check paths to external files (zip, unzip). Incorrect settings also lead to this error message (see the Using Moodle forum discussion [http://moodle.org/mod/forum/discuss.php?d=140355 moodle.xml not found in root...] and MDL-14812).&lt;br /&gt;
&lt;br /&gt;
==The process ends with: &amp;quot;An error occurred while copying the zip file...&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
This problem is most likely caused by a permissions issue in the destination directory. Backup files are copied to &amp;quot;XXX/backupdata&amp;quot; under your dataroot directory (where XXX is the id of the course being backed up).&lt;br /&gt;
&lt;br /&gt;
On Windows systems, if you have configured Moodle to use an external zip program then the IIS IUSR_computername user needs to have Execute access to cmd.exe so that it can run the zip program. See the Note in [https://docs.moodle.org/en/System_paths#Path_to_zip Path to zip] for more details.  &lt;br /&gt;
&lt;br /&gt;
The problem could also be caused by a disk being full, though this is far less likely.&lt;br /&gt;
&lt;br /&gt;
To obtain precise information about what&#039;s happening, you can enable debug messages in &#039;&#039;Administration &amp;gt; Server &amp;gt; [[Debugging]]&#039;&#039; (select the maximum level - DEVELOPER) and/or check the web server error logs.&lt;br /&gt;
&lt;br /&gt;
==I Still get an XML error. How can I clean the borked XML file?==&lt;br /&gt;
&lt;br /&gt;
In some cases XML backup files may contain characters causing the restore process to abort, even after the steps described in the previous question. In such cases you may want to try the following:&lt;br /&gt;
&lt;br /&gt;
* Download the [http://repository.atlassian.com/atlassian-xml-cleaner/jars/atlassian-xml-cleaner-0.1.jar Atlassian XML Cleaner Utility] from the [http://confluence.atlassian.com/display/JIRA/Removing+invalid+characters+from+XML+backups JIRA Atlassian site].&lt;br /&gt;
&lt;br /&gt;
* Unzip the problematic Moodle backup file under one empty folder. Moodle will create the course file folders as long as the unclean moodle.xml file. Please unzip using the Moodle unzip feature.&lt;br /&gt;
&lt;br /&gt;
* Rename the unclean moodle.xml file to moodle-unclean.xml. &lt;br /&gt;
&lt;br /&gt;
* If you don&#039;t have access to your Moodle server&#039;s command prompt, using the Moodle zip feature, zip the moodle-unclean.xml file only, download the zip file locally and unzip it. It is very important to download the xml file in zipped format to avoid unwanted character encoding when transferring from an operating system to another.&lt;br /&gt;
&lt;br /&gt;
* Move the downloaded Atlassian XML Cleaner Utility in the same folder where is your moodle-unclean.xml file.&lt;br /&gt;
&lt;br /&gt;
* Issue the following command from the command prompt: &lt;br /&gt;
&lt;br /&gt;
 java -jar atlassian-xml-cleaner-0.1.jar moodle-unclean.xml &amp;gt; moodle.xml&lt;br /&gt;
&lt;br /&gt;
* If you launched the utility on your local computer, zip the just created (and hopefully cleaned) moodle.xml file and upload it in the same place from where you downloaded the moodle-unclean.xml file. Once uploaded, unzip it using the Moodle unzip feature.&lt;br /&gt;
&lt;br /&gt;
* Zip everything again (all the folder contents but the folder itself!).&lt;br /&gt;
&lt;br /&gt;
* Restore the course. It should work now.&lt;br /&gt;
&lt;br /&gt;
==What does &amp;quot;Some of your courses weren&#039;t saved!!&amp;quot; mean?==&lt;br /&gt;
&lt;br /&gt;
There are three possible causes of this problem:&lt;br /&gt;
# Error - this happens when the backup procedure has found an error and so hasn&#039;t finished the backup of a particular course. These are &amp;quot;controlled&amp;quot; errors and the scheduled backup continues with the next course.&lt;br /&gt;
# Unfinished - this happens when the backup procedure dies without knowing why. When the cron is next executed it detects that the last execution went wrong, and continues skipping the problematic course. A possible solution would be to raise the PHP/Apache limit in your installation (memory, time of execution...). By taking a look to your log tables you should be able to see if the &amp;quot;crash&amp;quot; is happening at exact time intervals (usually a problem with the max_execution_time php&#039;s variable), or if there is some exact point were all the courses are breaking (generally internal zip libraries, try to switch to external executables instead).&lt;br /&gt;
# Skipped - this happens when a course is unavailable to students and has not been changed in the last month (31 days). This isn&#039;t an error situation - it&#039;s a feature, especially useful for sites with many unavailable old courses, saving process time.&lt;br /&gt;
&lt;br /&gt;
==How can I restore pre 1.6 non-ISO-8859-1 backups to Moodle 1.6 (Unicode)?==&lt;br /&gt;
&lt;br /&gt;
Any backup files with contents which are not 100% ISO-8859-1 will be a problem to restore to Moodle 1.6 (and upwards) running under Unicode. Instead, please try the following:&lt;br /&gt;
&lt;br /&gt;
# Make a clean install of Moodle 1.5.x (the latest version available)&lt;br /&gt;
# Restore all your courses there (they should work if they were working originally)&lt;br /&gt;
# Upgrade your site to Moodle 1.6 and run the UTF-8 migration script&lt;br /&gt;
# Backup your courses again&lt;br /&gt;
&lt;br /&gt;
This will produce a new set of backup files that will be 100% UTF-8 and you will be able to use them with Moodle 1.6 without any problems.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;broken_html&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
==Restoring a course results in broken HTML tags. What can I do?==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Summary:&#039;&#039;&#039; Upgrade your libxml2 and PHP and you should be fine. It has been confirmed that the recent versions of libxml2 (2.7.3) and PHP (5.2.10) no longer have this problem.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Background:&#039;&#039;&#039; (may be obsoleted) This problem is due to a [http://bugs.php.net/bug.php?id=45996 PHP bug in libxml2 2.7.1] (the same bug reported with version 2.7.2 and 2.7.3). All HTML entities, such as &amp;amp;gt;, &amp;amp;lt; and &amp;amp;quot; are removed when a course is restored.&lt;br /&gt;
&lt;br /&gt;
To resolve the problem, you should use a different version of libxml2 such as 2.7.0 or 2.6.32 or compile PHP against libexpat instead of libxml2 or finally use PHP version &amp;gt;= 5.2.9 that solves this compatibility issue over the newer libxml2.&lt;br /&gt;
&lt;br /&gt;
At Gentoo servers, you can use&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;&amp;gt;dev-libs/libxml2-2.6.32&amp;quot; &amp;gt;&amp;gt; /etc/portage/package.mask&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Update:&#039;&#039;&#039; This was fixed for libxml2 version 2.7.3 in PHP snapshot on 11/01/2009. You can use the following patch:&lt;br /&gt;
&lt;br /&gt;
 --- php-5.2.8/ext/xml/compat.c 2008/12/31 11:12:38 1.52&lt;br /&gt;
 +++ php-5.2.8/ext/xml/compat.c 2009/01/11 12:00:30 1.53&lt;br /&gt;
 @@ -482,6 +482,10 @@&lt;br /&gt;
 parser-&amp;gt;parser-&amp;gt;charset = XML_CHAR_ENCODING_NONE;&lt;br /&gt;
 #endif&lt;br /&gt;
 &lt;br /&gt;
 +#if LIBXML_VERSION &amp;gt;= 20703&lt;br /&gt;
 + xmlCtxtUseOptions(parser-&amp;gt;parser, XML_PARSE_OLDSAX);&lt;br /&gt;
 +#endif&lt;br /&gt;
 +&lt;br /&gt;
 parser-&amp;gt;parser-&amp;gt;replaceEntities = 1;&lt;br /&gt;
 parser-&amp;gt;parser-&amp;gt;wellFormed = 0;&lt;br /&gt;
 if (sep != NULL) {&lt;br /&gt;
&lt;br /&gt;
See the discussion [http://moodle.org/mod/forum/discuss.php?d=111321 Restoring makes webpages and labels in code] for further information.&lt;br /&gt;
&lt;br /&gt;
==Why are some courses being skipped?==&lt;br /&gt;
&lt;br /&gt;
From 1.6 onwards, course backups automatically skip courses which are unavailable to students and have not been changed in the last month.&lt;br /&gt;
&lt;br /&gt;
The [http://moodle.org/mod/forum/discuss.php?d=80367#p714733 Hide courses excluded from automatic backup] discussion in the Using Moodle forum describes a way that you can disable or override this thirty day check. This could be useful if, for example, you wanted to change the period from thirty days to six months.&lt;br /&gt;
&lt;br /&gt;
==Why does restore stop, rather than completing?==&lt;br /&gt;
&lt;br /&gt;
Attempting to restore a course to an older version of Moodle than the one the course was backed up on can result in the restore process failing to complete. To ensure a successful restore, make sure that the version of Moodle you are restoring the course to is the same, or newer, than the one the course was backed up on.&lt;br /&gt;
&lt;br /&gt;
If it stop unexpectedly with no errors shown try again with [[Debugging]] switched on. Any errors you now see can help experts in the support forums diagnose your problem. You can also check the discussion links in the See also section below for further advice.&lt;br /&gt;
&lt;br /&gt;
==How can I improve restore robustness and execution times?==&lt;br /&gt;
&lt;br /&gt;
{{Moodle 1.9}}To improve restore robustness and execution times, particularly for medium to large course backups, try enabling the setting &#039;&#039;experimentalsplitrestore&#039;&#039; in &#039;&#039;Administration &amp;gt; Miscellaneous &amp;gt; [[Experimental]]&#039;&#039;. (This setting is available in Moodle 1.9.5 onwards.)&lt;br /&gt;
&lt;br /&gt;
MDL-18468 contains information about this Experimental Split Restore functionality and the improvements to course restore robustness and execution times that it introduced, particularly for medium to large course backups. It also explains why this is an &#039;Experimental&#039; feature in Moodle 1.9.&lt;br /&gt;
&lt;br /&gt;
==How can I backup and restore a course from a 1.9 site to a 2.0 site?==&lt;br /&gt;
&lt;br /&gt;
The backup and restore process has been completely rewritten for Moodle 2.0. It is not currently possible to backup a course on a 1.9 site and restore it to a 2.0 site, however the functionality will be available in a forthcoming 2.0.x release (after the release of 2.0).&lt;br /&gt;
&lt;br /&gt;
In the meantime, a workaround is to upgrade the 1.9 site to 2.0.  PLEASE NOTE that Moodle 2 has yet to be released. There is a reason that it is yet to be released. For testing purposes, one could clone one&#039;s 1.9.x Moodle (leaving your production Moodle at 1.9.x) and then upgrade your clone to Moodle 2.&lt;br /&gt;
&lt;br /&gt;
==Restore stops with the message &amp;quot;Trying to restore user xxxx from backup file will cause conflict&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
[[Image:Moodle 2.0 Restore breaks.png|thumb|Error message in Moodle 2.0]]&lt;br /&gt;
&lt;br /&gt;
This message is displayed when:&lt;br /&gt;
&lt;br /&gt;
# Your target site has one xxxx user (xxxx being the username)&lt;br /&gt;
# The backup being restored also has one xxxx user&lt;br /&gt;
# After various comparisons, Moodle has detected that the xxxx user in 1. and the xxxx user in 2. aren&#039;t the same user.&lt;br /&gt;
&lt;br /&gt;
If 1, 2 and 3 above happens, restore stops before performing any action as far as restoring that user will end associating &amp;quot;things&amp;quot; (create activities, posts, attempts... whatever...) to the xxxx user in the target site, when those &amp;quot;things&amp;quot; weren&#039;t performed by the same user at all.&lt;br /&gt;
&lt;br /&gt;
Those checks and behaviour were introduced in Moodle 1.9.x and continue being valid under 2.0. Usually the xxxx user in the messages is the &amp;quot;admin&amp;quot; user (that exists in practically all Moodle installations).&lt;br /&gt;
&lt;br /&gt;
There are two possible solutions to make both xxxx users in 1 and 2 to match (and avoid the conflict):&lt;br /&gt;
&lt;br /&gt;
a) Modify the backup&#039;s &#039;&#039;&#039;users.xml&#039;&#039;&#039; file and make the &#039;&#039;email&#039;&#039; or &#039;&#039;firstaccess&#039;&#039; fields match with the ones in target site.&amp;lt;br /&amp;gt;&lt;br /&gt;
b) Modify the &#039;&#039;&#039;target site&#039;&#039;&#039; and set the user &#039;&#039;email&#039;&#039; or &#039;&#039;firstaccess&#039;&#039; fields to match with the ones in backup&#039;s user.xml file.&lt;br /&gt;
&lt;br /&gt;
Method a) is recommended so the restore process will match both xxxx users and every &amp;quot;thing&amp;quot; in the backup file belonging to xxxx will be associated to the already existing xxxx user in the target site.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/view.php?f=128 Backup and Restore forum]&lt;br /&gt;
*[http://www.databasejournal.com/features/mysql/article.php/10897_3300511_2 databasejournal.com article on repairing database corruption in MySQL]&lt;br /&gt;
&lt;br /&gt;
Moodle Docs:&lt;br /&gt;
* [[Site backup]]&lt;br /&gt;
* [[Moodle migration]]&lt;br /&gt;
* [[Beginning Administration FAQ]]&lt;br /&gt;
&lt;br /&gt;
Using Moodle forum discussions:&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=66708 Scheduled backup fails] including possible solution to &amp;quot;An error occurred while copying files&amp;quot;.&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=99338 Restore stops]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=125663 Major Backup and Restore Problem in 1.9.5] with ideas for solving &amp;quot;Course ID was incorrect (can&#039;t find it)&amp;quot; problem&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=137203 Restore does not continue]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=142720 Trying to restore user &#039;admin&#039; from backup file will cause conflict]&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Backup]]&lt;br /&gt;
&lt;br /&gt;
[[es:FAQ Backup]]&lt;br /&gt;
[[pl:Backup FAQ]]&lt;br /&gt;
[[fr:FAQ de sauvegarde]]&lt;br /&gt;
[[ja:バックアップFAQ]]&lt;br /&gt;
[[pt:FAQ sobre cópias de segurança]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Development:Themes_2.0_creating_your_first_theme&amp;diff=77427</id>
		<title>Development:Themes 2.0 creating your first theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Development:Themes_2.0_creating_your_first_theme&amp;diff=77427"/>
		<updated>2010-11-02T16:12:51Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Using images within CSS - changed DIV height to allow for printing. Still not perfect though */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}This document describes how to create a theme for Moodle 2.0. It assumes you have some understanding of how themes within Moodle work as well as a good understanding of HTML and CSS.&lt;br /&gt;
&lt;br /&gt;
===Theme designer mode===&lt;br /&gt;
&lt;br /&gt;
Under normal operation Moodle does several things in the name of performance, one of these is to combine all of the CSS into one file, minimize it, cache it on the server, and then serve it. After the first request the cached version is served to greatly improve page performance. &lt;br /&gt;
&lt;br /&gt;
What this means for you as a themer? When you make changes they will not be seen immediately. In fact you will need to tell Moodle to rebuild the cache that it is serving.&lt;br /&gt;
This isn&#039;t practical for designing themes of course so the &#039;&#039;&#039;theme designer mode&#039;&#039;&#039; was added. When enabled it tells Moodle not to combine or cache the CSS that gets delivered. This has the downside that page load times will take significantly longer, however you will see your changes immediately every time.&lt;br /&gt;
&lt;br /&gt;
Theme designer mode may be enabled via &#039;&#039;Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; [[Theme settings]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: Internet Explorer versions 6 and 7 have BIG problems when a site attempts to link to more than 31 stylesheets, in which case either a limited number or no styles get applied. Because Moodle sends up all of the CSS all of the time with theme designer mode turned on there is a very high chance you will get more than 31 stylesheets being included. This will, of course, cause major problems for Internet Explorer until theme designer mode is turned off.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
The first thing you need to do is create the directories and files you will be using, the first thing to create is the actual directory for your theme. This should be the name of your theme, in my case it&#039;s &#039;excitement&#039;. The directory should be located within the theme directory of Moodle, ./moodle/theme/excitement/ will be the directory I create.&lt;br /&gt;
&lt;br /&gt;
Now within that directory we can immediately create several files that we know we are going to need. &lt;br /&gt;
&lt;br /&gt;
So the files that we want to create are:&lt;br /&gt;
; config.php :  All of our settings will go here.&lt;br /&gt;
; /style/ : This directory will contain all of our stylesheets.&lt;br /&gt;
; /style/excitement.css : All of our css will go in here.&lt;br /&gt;
; /pix/ : Into this directory we&#039;ll put a screen shot of our theme as well as our favicon and any images we use in CSS.&lt;br /&gt;
; /layout/ : Our layout files will end up in this directory.&lt;br /&gt;
; /layout/standard.php : This will be our one basic layout file.&lt;br /&gt;
&lt;br /&gt;
So after this setup step you should have a directory structure similar to what is shown below.&lt;br /&gt;
&lt;br /&gt;
[[image:Learn_to_theme_01.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Configuring our theme==&lt;br /&gt;
&lt;br /&gt;
Open config.php in your favourite editor and start by adding the opening PHP tags &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;?php&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now we need to add the settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;excitement&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Very simply this tells Moodle the name of your theme, and if you ever have several config.php files open this will help you identify which one you are looking at.&lt;br /&gt;
&lt;br /&gt;
Next, the parents for this theme.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells Moodle that my new theme &#039;&#039;`excitement`&#039; wants to extend the base theme. &lt;br /&gt;
&lt;br /&gt;
A theme can extend any number of themes. Rather than creating an entirely new theme and copying all of the CSS, you can simply create a new theme, extend the theme you like and just add the changes you want to your theme. &lt;br /&gt;
&lt;br /&gt;
Also worth noting is the purpose of the base theme: it provides us with a basic layout and just enough CSS to make everything fall into place.&lt;br /&gt;
&lt;br /&gt;
Now we will tell Moodle about our stylesheets:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;excitement&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final thing we need to add into our theme&#039;s config.php file is the definition of the layouts for our theme:&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:1780px;overflow:auto;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;standard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;print&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;false),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
/** List of javascript files that need to be included on each page */&lt;br /&gt;
$THEME-&amp;gt;javascripts = array();&lt;br /&gt;
$THEME-&amp;gt;javascripts_footer = array();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you are looking at is the different layouts for our theme. Why are there so many? Because, that is how many there are in Moodle. There is one for every general type of page. With my &#039;&#039;`excitement`&#039;&#039; theme I have chosen to use my own layout. Unless there was a specific reason to do so, normally you would not need to create your own layouts, you could extend the base theme, and use its layouts, meaning you would only have to write CSS to achieve your desired look.&lt;br /&gt;
&lt;br /&gt;
For each layout above, you will notice the following four things are being set:&lt;br /&gt;
; file : This is the name of the layout file we want to use, it should always be located in the above themes layout directory. For us this is of course standard.php as we only have one layout file.&lt;br /&gt;
; regions : This is an array of block regions that our theme has. Each entry in here can be used to put blocks in when that layout is being used.&lt;br /&gt;
; defaultregion : If a layout has regions it should have a default region, this is where blocks get put when first added.&lt;br /&gt;
; options : These are special settings, anything that gets put into the options array is available later on when we are writing our layout file.&lt;br /&gt;
&lt;br /&gt;
There are additional settings that can be defined in the config.php file - see [[Development:Themes 2.0|Themes 2.0]] for the full list.&lt;br /&gt;
&lt;br /&gt;
==Writing the layout file==&lt;br /&gt;
&lt;br /&gt;
The excitement theme has just one layout file.&lt;br /&gt;
&lt;br /&gt;
The downside of this is that I have to make the layout file do everything I want which means I need to make use of some options (as defined in the layouts in config.php). &lt;br /&gt;
&lt;br /&gt;
The upside is that I only need to maintain one file. &lt;br /&gt;
&lt;br /&gt;
Other than maintenance, using multiple layout files provides many advantages to real world themes in that you can easily tweak and customise specific layouts to achieve the goals of the organisation using the theme.&lt;br /&gt;
&lt;br /&gt;
So lets start writing standard.php, the layout file for my &#039;&#039;`excitement`&#039;&#039; theme.&lt;br /&gt;
&lt;br /&gt;
===The top of the layout file===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hassidepre = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;, $OUTPUT);&lt;br /&gt;
$hassidepost = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-post&#039;, $OUTPUT);&lt;br /&gt;
echo $OUTPUT-&amp;gt;doctype(); ?&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lets look at the code that goes into this section:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo $OUTPUT-&amp;gt;doctype(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is very important and is required to go at the very top of the page. This tells Moodle to print out the document type tag that is determined by the settings within Moodle.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we open the HTML tag and then ask Moodle to print the attributes that should go inside it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Simply creates the title tag and asks Moodle to fill it in.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are asking Moodle to print all of the other tags and content that need to go into the head. This includes stylesheets, script tags, and inline JavaScript code.&lt;br /&gt;
&lt;br /&gt;
===The page header===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyid; ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-header&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&amp;gt;&lt;br /&gt;
            &amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
                echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
                if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
                    echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
                }&lt;br /&gt;
                echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
            ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;navbar clearfix&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;breadcrumb&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;navbar(); ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;navbutton&amp;quot;&amp;gt; &amp;lt;?php echo $PAGE-&amp;gt;button; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So there is a bit more going on here obviously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyid; ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again much like what we did for the opening HTML tag in the head we have started writing the opening body tag and are then asking Moodle to give us the ID we should use for the body tag as well as the classes we should use.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This very important call writes some critical bits of JavaScript into the page. It should always be located after the body tag as soon as possible.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are checking whether or not we need to print the header for the page. There are three checks we need to make here:&lt;br /&gt;
# &#039;&#039;&#039;$PAGE-&amp;gt;heading&#039;&#039;&#039; : This checks to make sure that there is a heading for the page. This will have been set by the script and normally describes the page in a couple of words.&lt;br /&gt;
# &#039;&#039;&#039;empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;])&#039;&#039;&#039; : Now this check is looking at the layout options that we set in our config.php file. It is looking to see if the layout set &#039;nonavbar&#039; =&amp;gt; true.&lt;br /&gt;
# &#039;&#039;&#039;$PAGE-&amp;gt;has_navbar()&#039;&#039;&#039; The third check is to check with the page whether it has a navigation bar to display.&lt;br /&gt;
If either there is a heading for this page or there is a navigation bar to display then we will display a heading.&lt;br /&gt;
&lt;br /&gt;
Leading on from this lets assume that there is a header to print.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
    .....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This line is simply saying if the page has a heading print it. In this case we run the first check above again just to make sute there is a heading, we then open a heading tag that we choose and ask the page to print the heading.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
    echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
    if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
        echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
    }&lt;br /&gt;
    echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are looking to print the menu and content that you see at the top of the page (usually to the right). We start by getting Moodle to print the login information for the current user. If the user is logged in this will be their name and a link to their profile, if not then it will be a link to login.&lt;br /&gt;
&lt;br /&gt;
Next we check our page options to see whether a language menu should be printed. If in the layout definition within config.php it sets &#039;&#039;&#039;langmenu =&amp;gt; true&#039;&#039;&#039; then we will print the language menu, a drop down box that lets the user change the language that Moodle displays in.&lt;br /&gt;
&lt;br /&gt;
Finally the page also has a heading menu that can be printed. This heading menu is special HTML that the page you are viewing wants to add. It can be anything from drop down boxes to buttons and any number of each.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;navbar clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;breadcrumb&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;navbar(); ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;navbutton&amp;quot;&amp;gt; &amp;lt;?php echo $PAGE-&amp;gt;button; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The final part of the header.&lt;br /&gt;
&lt;br /&gt;
Here we want to print the navigation bar for the page if there is one. To find out if there is one we run checks number 2 and 3 again and proceed if they pass.&lt;br /&gt;
&lt;br /&gt;
Assuming there is a header then there are two things that we need to print. The first is the navigation bar. This is a component that the OUTPUT library knows about. The second is a button to shown on the page.&lt;br /&gt;
&lt;br /&gt;
In both cases we can choose to wrap them in a div to make our life as a themer easier.&lt;br /&gt;
&lt;br /&gt;
Well that is it for the header. There is a lot of PHP compared to the other sections of the layout file but it does not change and can be copied and pasted between themes.&lt;br /&gt;
&lt;br /&gt;
===The page content===&lt;br /&gt;
&lt;br /&gt;
I am going with the default two block regions plus the main content.&lt;br /&gt;
&lt;br /&gt;
Because I have based this theme and layout file on the base theme the HTML looks a little intense. This is because it is a floating div layout where the content comes first and then we get the columns (even though one column will be to the left of the content.) Don&#039;t worry too much about it. When it comes to writing your own theme you can go about it as you choose.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-content&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;region-main-box&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;region-post-box&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;region-main-wrap&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-main&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-pre&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
                &amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-post&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In regards to PHP this section is very easy. There are only three lines for the whole section one to get the main content and one for each block region.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This line prints the main content for the page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These lines of code check the variables we created earlier on to decide whether we should show the pre block region. If you try to display a block region that isn&#039;t there or has no content then Moodle will give you an error message so these lines are very important.&lt;br /&gt;
&lt;br /&gt;
For those who get an error message if it is &amp;quot;unknown block region side-pre&amp;quot; or &amp;quot;unknown block region side-post&amp;quot; then this is the issue you are experiencing. Simply add the following lines and all will be fine.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This line gets all of the blocks and more particularly the content for the block region &#039;&#039;&#039;side-pre&#039;&#039;&#039;. This block region will be displayed to the left of the content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again we should make this check for every block region as there are some pages that have no blocks what-so-ever.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are getting the other block region &#039;&#039;&#039;side-post&#039;&#039;&#039; which will be displayed to the right of the content.&lt;br /&gt;
&lt;br /&gt;
===The page footer===&lt;br /&gt;
Here we want to print the footer for the page, any content required by Moodle, and then close the last tags.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
        &amp;lt;?php&lt;br /&gt;
        echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
        ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The section of code is responsible for printing the footer for the page.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
        &amp;lt;?php&lt;br /&gt;
        echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
        ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing we do before printing the footer is check that we actually want to print it. This is done by checking the options for the layout as defined in the config.php file. If &#039;&#039;&#039;nofooter =&amp;gt; true&#039;&#039;&#039; is set the we don&#039;t want to print the footer and should skip over this body of code.&lt;br /&gt;
&lt;br /&gt;
Assuming we want to print a footer we proceed to create a div to house its content and then print the bits of the content that will make it up.&lt;br /&gt;
There are four things that the typical page footer will want to print:&lt;br /&gt;
; echo page_doc_link(get_string(&#039;moodledocslink&#039;)) : This will print a link to the Moodle.org help page for this particular page.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;login_info(); : This is the same as at the top of the page and will print the login information for the current user.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;home_link(); : This prints a link back to the Moodle home page for this site.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;standard_footer_html(); : This prints special HTML that is determined by the settings for the site. Things such as performance information or debugging will be printed by this line if they are turned on.&lt;br /&gt;
&lt;br /&gt;
And the final line of code for our layout file is:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is one of the most important lines of code in the layout file. It asks Moodle to print any required content into the page, and there will likely be a lot although most of it will not be visual.&lt;br /&gt;
&lt;br /&gt;
It will instead be things such as inline scripts and JavaScript files required to go at the bottom of the page. If you forget this line its likely no JavaScript will work!&lt;br /&gt;
&lt;br /&gt;
We&#039;ve now written our layout file and it is all set to go. The complete source is below for reference. Remember if you want more practical examples simply look at the layout files located within the layout directory of other themes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:1850px;overflow:auto;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hassidepre = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;, $OUTPUT);&lt;br /&gt;
$hassidepost = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-post&#039;, $OUTPUT);&lt;br /&gt;
echo $OUTPUT-&amp;gt;doctype() ?&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;title; ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;shortcut icon&amp;quot; href=&amp;quot;&amp;lt;?php echo $OUTPUT-&amp;gt;pix_url(&#039;favicon&#039;, &#039;theme&#039;)?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyid; ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-header&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&amp;gt;&lt;br /&gt;
        &amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
            echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
            if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
                echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
            }&lt;br /&gt;
            echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
        ?&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;navbar clearfix&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;breadcrumb&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;navbar(); ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;navbutton&amp;quot;&amp;gt; &amp;lt;?php echo $PAGE-&amp;gt;button; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-content&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;region-main-box&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;region-post-box&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-main-wrap&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div id=&amp;quot;region-main&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                            &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-pre&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
                &amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-post&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
        &amp;lt;?php&lt;br /&gt;
        echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
        ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adding some CSS==&lt;br /&gt;
With config.php and standard.php both complete the theme is now usable and starting to look like a real theme, however if you change to it using the theme selector you will notice that it still lacks any style.&lt;br /&gt;
&lt;br /&gt;
This of course is where CSS comes in. When writing code Moodle developers are strongly encouraged to not use inline styles anywhere. This is fantastic for us as themers because there is nothing (or at least very little) in Moodle that cannot be styled using CSS.&lt;br /&gt;
&lt;br /&gt;
===Moodle CSS basics===&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 all of the CSS for the whole of Moodle is delivered all of the time! This was done for performance reasons. Moodle now reads in all of the CSS, combines it into one file, shrinks it removing any white space, caches it, and then delivers it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What this means for you as a themer?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You will need to write good CSS that won&#039;t clash with any other CSS within Moodle.&lt;br /&gt;
&lt;br /&gt;
Moodle is so big and complex,there is no way to ensure that classes don&#039;t get reused. What we can control however is the classes and id that get added to the body tag for every page. When writing CSS it is highly encouraged to make full use of these body classes, using them will help ensure the CSS you write has the least chance of causing conflicts.&lt;br /&gt;
&lt;br /&gt;
You should also take the time to look at how the Moodle themes use CSS. Look at their use of the body classes and how they separate the CSS for the theme into separate files based on the region of Moodle it applies to.&lt;br /&gt;
&lt;br /&gt;
Check out [[Development:Themes 2.0|Themes 2.0]] for more information about writing good CSS.&lt;br /&gt;
&lt;br /&gt;
===Starting to write excitement.css===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
a {text-decoration: none;}&lt;br /&gt;
.addcoursebutton .singlebutton {text-align: center;}&lt;br /&gt;
&lt;br /&gt;
h1.headermain {color: #fff;}&lt;br /&gt;
h2.main {border-bottom: 3px solid #013D6A;color: #013D6A;text-align: center;}&lt;br /&gt;
h2.headingblock {font-size: 18pt;margin-top: 0;background-color: #013D6A;color: #FFF;text-align: center;}&lt;br /&gt;
#page-header {background-color: #013D6A;}&lt;br /&gt;
#page-header .headermenu  {color: #FFF;}&lt;br /&gt;
#page-header .headermenu a {color: #FDFF2A;}&lt;br /&gt;
&lt;br /&gt;
.navbar {padding-left: 1em;}&lt;br /&gt;
.breadcrumb li {color: #FFF;}&lt;br /&gt;
.breadcrumb li a {color: #FFF;}&lt;br /&gt;
&lt;br /&gt;
.block {background-color: #013D6A;}&lt;br /&gt;
.block .header .title {color: #FFF;}&lt;br /&gt;
.block .header .title .block_action input {background-color: #FFF;}&lt;br /&gt;
.block .content {border: 1px solid #000;padding: 5px;background-color: #FFF;}&lt;br /&gt;
.block .content .block_tree p {font-size: 80%;}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer {text-align: center;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform {margin-left: 5%;width: 90%;font-size: 9pt;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform #adminsearchquery {width: 95%;}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .calendar-controls a {color: #013D6A;font-weight: bold;}&lt;br /&gt;
.block_calendar_month .content .minicalendar td {border-color: #FFF;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {color: #FFF;background-color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day a {color: #FFF000;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays th {border-width: 0;font-weight: bold;color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays abbr {border-width: 0;text-decoration: none;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
[[image:Learn_to_theme_02.jpg|400px|thumb|Excitement theme screenshot]]&lt;br /&gt;
This isn&#039;t all of the CSS for the theme, but just enough to style the front page when the user is not logged in.&lt;br /&gt;
Remember this theme extends the base theme so there is already CSS for layout as well.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* The CSS is laid out in a single line format. This is done within the core themes for Moodle. It makes it quicker to read the selectors and see what is being styled.&lt;br /&gt;
* I have written my selectors to take into account the structure of the HTML (more than just the one tag I want to style). This helps further to reduce the conflicts that I may encounter.&lt;br /&gt;
* I use generic classes like &#039;&#039;.sideblock&#039;&#039; only where I want to be generic, as soon as I want to be specific I use the unique classes such as &#039;&#039;.block_calendar_month&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using images within CSS===&lt;br /&gt;
&lt;br /&gt;
I will add two image files to the pix directory of my theme:&lt;br /&gt;
; /theme/excitement/pix/background.png : This will be the background image for my theme.&lt;br /&gt;
; /theme/excitement/pix/gradient.jpg : This will be a gradient I use for the header and headings.&lt;br /&gt;
I quickly created both of these images using gimp and simply saved them to the pix directory.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-image:url([[pix:theme|background]]);}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock,&lt;br /&gt;
#page-header,&lt;br /&gt;
.sideblock,&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {background-image:url([[pix:theme|gradient]]);background-repeat:repeat-x;background-color: #0273C8;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
[[image:Learn_to_theme_03.jpg‎|400px|thumb|Excitement theme screenshot]]&lt;br /&gt;
The CSS above is the two new rules that I had to write to use my images within CSS.&lt;br /&gt;
&lt;br /&gt;
The first rule sets the background image for the page to background.png&lt;br /&gt;
&lt;br /&gt;
The second rule sets the background for headings, and the sideblocks to use gradient.jpg&lt;br /&gt;
&lt;br /&gt;
You will notice that I did not need to write a path to the image. This is because Moodle has this special syntax that can be used and will be replaced when the CSS is parsed before delivery.&lt;br /&gt;
The advantage of using this syntax over writing the path in is that the path may change depending on where you are or what theme is being used.&lt;br /&gt;
&lt;br /&gt;
Other themers may choose to extend your theme with their own; if you use this syntax then all they need to do to override the image is to create one with the same name in their themes directory.&lt;br /&gt;
&lt;br /&gt;
You will also notice that I don&#039;t need to add the image files extension. This is because Moodle is smart enough to work out what extension the file uses. It also allows themers to override images with different formats.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right&amp;quot; /&amp;gt;&lt;br /&gt;
The following is the complete CSS for my theme:&lt;br /&gt;
&amp;lt;div style=&amp;quot;overflow:auto;height:860px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
a {text-decoration: none;}&lt;br /&gt;
.addcoursebutton .singlebutton {text-align: center;}&lt;br /&gt;
&lt;br /&gt;
h1.headermain {color: #fff;}&lt;br /&gt;
h2.main {border-bottom: 3px solid #013D6A;color: #013D6A;text-align: center;}&lt;br /&gt;
h2.headingblock {font-size: 18pt;margin-top: 0;background-color: #013D6A;color: #FFF;text-align: center;}&lt;br /&gt;
#page-header {background-color: #013D6A;border-bottom:5px solid #013D6A;}&lt;br /&gt;
#page-header .headermenu  {color: #FFF;}&lt;br /&gt;
#page-header .headermenu a {color: #FDFF2A;}&lt;br /&gt;
&lt;br /&gt;
.sideblock {background-color: #013D6A;}&lt;br /&gt;
.sideblock .header .title {color: #FFF;}&lt;br /&gt;
.sideblock .header .title .block_action input {background-color: #FFF;}&lt;br /&gt;
.sideblock .content {border: 1px solid #000;padding: 5px;background-color: #FFF;}&lt;br /&gt;
.sideblock .content .block_tree p {font-size: 80%;}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer {text-align: center;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform {margin-left: 5%;width: 90%;font-size: 9pt;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform #adminsearchquery {width: 95%;}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .calendar-controls a {color: #013D6A;font-weight: bold;}&lt;br /&gt;
.block_calendar_month .content .minicalendar td {border-color: #FFF;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {color: #FFF;background-color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day a {color: #FFF000;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays th {border-width: 0;font-weight: bold;color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays abbr {border-width: 0;text-decoration: none;}&lt;br /&gt;
&lt;br /&gt;
html {background-image:url([[pix:theme|background]]);}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock,&lt;br /&gt;
#page-header,&lt;br /&gt;
.sideblock,&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {background-image:url([[pix:theme|gradient]]);&lt;br /&gt;
   background-repeat:repeat-x;background-color: #0273C8;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adding a screenshot and favicon==&lt;br /&gt;
The final thing to do at this point is add both a screenshot for this theme as well as a favicon for it.&lt;br /&gt;
The screenshot will be shown in the theme selector screen and should be named &#039;&#039;screenshot.jpg&#039;&#039;.&lt;br /&gt;
The favicon will be used when someone bookmarks this page.&lt;br /&gt;
Both images should be located in your themes pix directory as follows:&lt;br /&gt;
* /theme/excitement/pix/screenshot.jpg&lt;br /&gt;
* /theme/excitement/pix/favicon.ico&lt;br /&gt;
&lt;br /&gt;
In the case of my theme I have taken a screenshot and added it to that directory, and because I don&#039;t really want to do anything special with the favicon I have copied it from /theme/base/pix/favicon.ico so that at least it will be recognisable as Moodle.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Themes]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Development:Themes_2.0_creating_your_first_theme&amp;diff=77426</id>
		<title>Development:Themes 2.0 creating your first theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Development:Themes_2.0_creating_your_first_theme&amp;diff=77426"/>
		<updated>2010-11-02T16:05:32Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* The page footer - changed DIV height to allow printing of this doc */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}This document describes how to create a theme for Moodle 2.0. It assumes you have some understanding of how themes within Moodle work as well as a good understanding of HTML and CSS.&lt;br /&gt;
&lt;br /&gt;
===Theme designer mode===&lt;br /&gt;
&lt;br /&gt;
Under normal operation Moodle does several things in the name of performance, one of these is to combine all of the CSS into one file, minimize it, cache it on the server, and then serve it. After the first request the cached version is served to greatly improve page performance. &lt;br /&gt;
&lt;br /&gt;
What this means for you as a themer? When you make changes they will not be seen immediately. In fact you will need to tell Moodle to rebuild the cache that it is serving.&lt;br /&gt;
This isn&#039;t practical for designing themes of course so the &#039;&#039;&#039;theme designer mode&#039;&#039;&#039; was added. When enabled it tells Moodle not to combine or cache the CSS that gets delivered. This has the downside that page load times will take significantly longer, however you will see your changes immediately every time.&lt;br /&gt;
&lt;br /&gt;
Theme designer mode may be enabled via &#039;&#039;Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; [[Theme settings]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: Internet Explorer versions 6 and 7 have BIG problems when a site attempts to link to more than 31 stylesheets, in which case either a limited number or no styles get applied. Because Moodle sends up all of the CSS all of the time with theme designer mode turned on there is a very high chance you will get more than 31 stylesheets being included. This will, of course, cause major problems for Internet Explorer until theme designer mode is turned off.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
The first thing you need to do is create the directories and files you will be using, the first thing to create is the actual directory for your theme. This should be the name of your theme, in my case it&#039;s &#039;excitement&#039;. The directory should be located within the theme directory of Moodle, ./moodle/theme/excitement/ will be the directory I create.&lt;br /&gt;
&lt;br /&gt;
Now within that directory we can immediately create several files that we know we are going to need. &lt;br /&gt;
&lt;br /&gt;
So the files that we want to create are:&lt;br /&gt;
; config.php :  All of our settings will go here.&lt;br /&gt;
; /style/ : This directory will contain all of our stylesheets.&lt;br /&gt;
; /style/excitement.css : All of our css will go in here.&lt;br /&gt;
; /pix/ : Into this directory we&#039;ll put a screen shot of our theme as well as our favicon and any images we use in CSS.&lt;br /&gt;
; /layout/ : Our layout files will end up in this directory.&lt;br /&gt;
; /layout/standard.php : This will be our one basic layout file.&lt;br /&gt;
&lt;br /&gt;
So after this setup step you should have a directory structure similar to what is shown below.&lt;br /&gt;
&lt;br /&gt;
[[image:Learn_to_theme_01.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Configuring our theme==&lt;br /&gt;
&lt;br /&gt;
Open config.php in your favourite editor and start by adding the opening PHP tags &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;?php&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now we need to add the settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;excitement&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Very simply this tells Moodle the name of your theme, and if you ever have several config.php files open this will help you identify which one you are looking at.&lt;br /&gt;
&lt;br /&gt;
Next, the parents for this theme.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells Moodle that my new theme &#039;&#039;`excitement`&#039; wants to extend the base theme. &lt;br /&gt;
&lt;br /&gt;
A theme can extend any number of themes. Rather than creating an entirely new theme and copying all of the CSS, you can simply create a new theme, extend the theme you like and just add the changes you want to your theme. &lt;br /&gt;
&lt;br /&gt;
Also worth noting is the purpose of the base theme: it provides us with a basic layout and just enough CSS to make everything fall into place.&lt;br /&gt;
&lt;br /&gt;
Now we will tell Moodle about our stylesheets:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;excitement&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final thing we need to add into our theme&#039;s config.php file is the definition of the layouts for our theme:&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:1780px;overflow:auto;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;standard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;print&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;false),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
/** List of javascript files that need to be included on each page */&lt;br /&gt;
$THEME-&amp;gt;javascripts = array();&lt;br /&gt;
$THEME-&amp;gt;javascripts_footer = array();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you are looking at is the different layouts for our theme. Why are there so many? Because, that is how many there are in Moodle. There is one for every general type of page. With my &#039;&#039;`excitement`&#039;&#039; theme I have chosen to use my own layout. Unless there was a specific reason to do so, normally you would not need to create your own layouts, you could extend the base theme, and use its layouts, meaning you would only have to write CSS to achieve your desired look.&lt;br /&gt;
&lt;br /&gt;
For each layout above, you will notice the following four things are being set:&lt;br /&gt;
; file : This is the name of the layout file we want to use, it should always be located in the above themes layout directory. For us this is of course standard.php as we only have one layout file.&lt;br /&gt;
; regions : This is an array of block regions that our theme has. Each entry in here can be used to put blocks in when that layout is being used.&lt;br /&gt;
; defaultregion : If a layout has regions it should have a default region, this is where blocks get put when first added.&lt;br /&gt;
; options : These are special settings, anything that gets put into the options array is available later on when we are writing our layout file.&lt;br /&gt;
&lt;br /&gt;
There are additional settings that can be defined in the config.php file - see [[Development:Themes 2.0|Themes 2.0]] for the full list.&lt;br /&gt;
&lt;br /&gt;
==Writing the layout file==&lt;br /&gt;
&lt;br /&gt;
The excitement theme has just one layout file.&lt;br /&gt;
&lt;br /&gt;
The downside of this is that I have to make the layout file do everything I want which means I need to make use of some options (as defined in the layouts in config.php). &lt;br /&gt;
&lt;br /&gt;
The upside is that I only need to maintain one file. &lt;br /&gt;
&lt;br /&gt;
Other than maintenance, using multiple layout files provides many advantages to real world themes in that you can easily tweak and customise specific layouts to achieve the goals of the organisation using the theme.&lt;br /&gt;
&lt;br /&gt;
So lets start writing standard.php, the layout file for my &#039;&#039;`excitement`&#039;&#039; theme.&lt;br /&gt;
&lt;br /&gt;
===The top of the layout file===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hassidepre = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;, $OUTPUT);&lt;br /&gt;
$hassidepost = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-post&#039;, $OUTPUT);&lt;br /&gt;
echo $OUTPUT-&amp;gt;doctype(); ?&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lets look at the code that goes into this section:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo $OUTPUT-&amp;gt;doctype(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is very important and is required to go at the very top of the page. This tells Moodle to print out the document type tag that is determined by the settings within Moodle.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we open the HTML tag and then ask Moodle to print the attributes that should go inside it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Simply creates the title tag and asks Moodle to fill it in.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are asking Moodle to print all of the other tags and content that need to go into the head. This includes stylesheets, script tags, and inline JavaScript code.&lt;br /&gt;
&lt;br /&gt;
===The page header===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyid; ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-header&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&amp;gt;&lt;br /&gt;
            &amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
                echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
                if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
                    echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
                }&lt;br /&gt;
                echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
            ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;navbar clearfix&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;breadcrumb&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;navbar(); ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;navbutton&amp;quot;&amp;gt; &amp;lt;?php echo $PAGE-&amp;gt;button; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So there is a bit more going on here obviously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyid; ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again much like what we did for the opening HTML tag in the head we have started writing the opening body tag and are then asking Moodle to give us the ID we should use for the body tag as well as the classes we should use.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This very important call writes some critical bits of JavaScript into the page. It should always be located after the body tag as soon as possible.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are checking whether or not we need to print the header for the page. There are three checks we need to make here:&lt;br /&gt;
# &#039;&#039;&#039;$PAGE-&amp;gt;heading&#039;&#039;&#039; : This checks to make sure that there is a heading for the page. This will have been set by the script and normally describes the page in a couple of words.&lt;br /&gt;
# &#039;&#039;&#039;empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;])&#039;&#039;&#039; : Now this check is looking at the layout options that we set in our config.php file. It is looking to see if the layout set &#039;nonavbar&#039; =&amp;gt; true.&lt;br /&gt;
# &#039;&#039;&#039;$PAGE-&amp;gt;has_navbar()&#039;&#039;&#039; The third check is to check with the page whether it has a navigation bar to display.&lt;br /&gt;
If either there is a heading for this page or there is a navigation bar to display then we will display a heading.&lt;br /&gt;
&lt;br /&gt;
Leading on from this lets assume that there is a header to print.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
    .....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This line is simply saying if the page has a heading print it. In this case we run the first check above again just to make sute there is a heading, we then open a heading tag that we choose and ask the page to print the heading.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
    echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
    if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
        echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
    }&lt;br /&gt;
    echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are looking to print the menu and content that you see at the top of the page (usually to the right). We start by getting Moodle to print the login information for the current user. If the user is logged in this will be their name and a link to their profile, if not then it will be a link to login.&lt;br /&gt;
&lt;br /&gt;
Next we check our page options to see whether a language menu should be printed. If in the layout definition within config.php it sets &#039;&#039;&#039;langmenu =&amp;gt; true&#039;&#039;&#039; then we will print the language menu, a drop down box that lets the user change the language that Moodle displays in.&lt;br /&gt;
&lt;br /&gt;
Finally the page also has a heading menu that can be printed. This heading menu is special HTML that the page you are viewing wants to add. It can be anything from drop down boxes to buttons and any number of each.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;navbar clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;breadcrumb&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;navbar(); ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;navbutton&amp;quot;&amp;gt; &amp;lt;?php echo $PAGE-&amp;gt;button; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The final part of the header.&lt;br /&gt;
&lt;br /&gt;
Here we want to print the navigation bar for the page if there is one. To find out if there is one we run checks number 2 and 3 again and proceed if they pass.&lt;br /&gt;
&lt;br /&gt;
Assuming there is a header then there are two things that we need to print. The first is the navigation bar. This is a component that the OUTPUT library knows about. The second is a button to shown on the page.&lt;br /&gt;
&lt;br /&gt;
In both cases we can choose to wrap them in a div to make our life as a themer easier.&lt;br /&gt;
&lt;br /&gt;
Well that is it for the header. There is a lot of PHP compared to the other sections of the layout file but it does not change and can be copied and pasted between themes.&lt;br /&gt;
&lt;br /&gt;
===The page content===&lt;br /&gt;
&lt;br /&gt;
I am going with the default two block regions plus the main content.&lt;br /&gt;
&lt;br /&gt;
Because I have based this theme and layout file on the base theme the HTML looks a little intense. This is because it is a floating div layout where the content comes first and then we get the columns (even though one column will be to the left of the content.) Don&#039;t worry too much about it. When it comes to writing your own theme you can go about it as you choose.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-content&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;region-main-box&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;region-post-box&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;region-main-wrap&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-main&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-pre&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
                &amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-post&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In regards to PHP this section is very easy. There are only three lines for the whole section one to get the main content and one for each block region.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This line prints the main content for the page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These lines of code check the variables we created earlier on to decide whether we should show the pre block region. If you try to display a block region that isn&#039;t there or has no content then Moodle will give you an error message so these lines are very important.&lt;br /&gt;
&lt;br /&gt;
For those who get an error message if it is &amp;quot;unknown block region side-pre&amp;quot; or &amp;quot;unknown block region side-post&amp;quot; then this is the issue you are experiencing. Simply add the following lines and all will be fine.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This line gets all of the blocks and more particularly the content for the block region &#039;&#039;&#039;side-pre&#039;&#039;&#039;. This block region will be displayed to the left of the content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again we should make this check for every block region as there are some pages that have no blocks what-so-ever.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are getting the other block region &#039;&#039;&#039;side-post&#039;&#039;&#039; which will be displayed to the right of the content.&lt;br /&gt;
&lt;br /&gt;
===The page footer===&lt;br /&gt;
Here we want to print the footer for the page, any content required by Moodle, and then close the last tags.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
        &amp;lt;?php&lt;br /&gt;
        echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
        ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The section of code is responsible for printing the footer for the page.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
        &amp;lt;?php&lt;br /&gt;
        echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
        ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing we do before printing the footer is check that we actually want to print it. This is done by checking the options for the layout as defined in the config.php file. If &#039;&#039;&#039;nofooter =&amp;gt; true&#039;&#039;&#039; is set the we don&#039;t want to print the footer and should skip over this body of code.&lt;br /&gt;
&lt;br /&gt;
Assuming we want to print a footer we proceed to create a div to house its content and then print the bits of the content that will make it up.&lt;br /&gt;
There are four things that the typical page footer will want to print:&lt;br /&gt;
; echo page_doc_link(get_string(&#039;moodledocslink&#039;)) : This will print a link to the Moodle.org help page for this particular page.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;login_info(); : This is the same as at the top of the page and will print the login information for the current user.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;home_link(); : This prints a link back to the Moodle home page for this site.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;standard_footer_html(); : This prints special HTML that is determined by the settings for the site. Things such as performance information or debugging will be printed by this line if they are turned on.&lt;br /&gt;
&lt;br /&gt;
And the final line of code for our layout file is:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is one of the most important lines of code in the layout file. It asks Moodle to print any required content into the page, and there will likely be a lot although most of it will not be visual.&lt;br /&gt;
&lt;br /&gt;
It will instead be things such as inline scripts and JavaScript files required to go at the bottom of the page. If you forget this line its likely no JavaScript will work!&lt;br /&gt;
&lt;br /&gt;
We&#039;ve now written our layout file and it is all set to go. The complete source is below for reference. Remember if you want more practical examples simply look at the layout files located within the layout directory of other themes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:1850px;overflow:auto;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hassidepre = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;, $OUTPUT);&lt;br /&gt;
$hassidepost = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-post&#039;, $OUTPUT);&lt;br /&gt;
echo $OUTPUT-&amp;gt;doctype() ?&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;title; ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;shortcut icon&amp;quot; href=&amp;quot;&amp;lt;?php echo $OUTPUT-&amp;gt;pix_url(&#039;favicon&#039;, &#039;theme&#039;)?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyid; ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-header&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&amp;gt;&lt;br /&gt;
        &amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
            echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
            if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
                echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
            }&lt;br /&gt;
            echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
        ?&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;navbar clearfix&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;breadcrumb&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;navbar(); ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;navbutton&amp;quot;&amp;gt; &amp;lt;?php echo $PAGE-&amp;gt;button; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-content&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;region-main-box&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;region-post-box&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-main-wrap&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div id=&amp;quot;region-main&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                            &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-pre&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
                &amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-post&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
        &amp;lt;?php&lt;br /&gt;
        echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
        ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adding some CSS==&lt;br /&gt;
With config.php and standard.php both complete the theme is now usable and starting to look like a real theme, however if you change to it using the theme selector you will notice that it still lacks any style.&lt;br /&gt;
&lt;br /&gt;
This of course is where CSS comes in. When writing code Moodle developers are strongly encouraged to not use inline styles anywhere. This is fantastic for us as themers because there is nothing (or at least very little) in Moodle that cannot be styled using CSS.&lt;br /&gt;
&lt;br /&gt;
===Moodle CSS basics===&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 all of the CSS for the whole of Moodle is delivered all of the time! This was done for performance reasons. Moodle now reads in all of the CSS, combines it into one file, shrinks it removing any white space, caches it, and then delivers it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What this means for you as a themer?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You will need to write good CSS that won&#039;t clash with any other CSS within Moodle.&lt;br /&gt;
&lt;br /&gt;
Moodle is so big and complex,there is no way to ensure that classes don&#039;t get reused. What we can control however is the classes and id that get added to the body tag for every page. When writing CSS it is highly encouraged to make full use of these body classes, using them will help ensure the CSS you write has the least chance of causing conflicts.&lt;br /&gt;
&lt;br /&gt;
You should also take the time to look at how the Moodle themes use CSS. Look at their use of the body classes and how they separate the CSS for the theme into separate files based on the region of Moodle it applies to.&lt;br /&gt;
&lt;br /&gt;
Check out [[Development:Themes 2.0|Themes 2.0]] for more information about writing good CSS.&lt;br /&gt;
&lt;br /&gt;
===Starting to write excitement.css===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
a {text-decoration: none;}&lt;br /&gt;
.addcoursebutton .singlebutton {text-align: center;}&lt;br /&gt;
&lt;br /&gt;
h1.headermain {color: #fff;}&lt;br /&gt;
h2.main {border-bottom: 3px solid #013D6A;color: #013D6A;text-align: center;}&lt;br /&gt;
h2.headingblock {font-size: 18pt;margin-top: 0;background-color: #013D6A;color: #FFF;text-align: center;}&lt;br /&gt;
#page-header {background-color: #013D6A;}&lt;br /&gt;
#page-header .headermenu  {color: #FFF;}&lt;br /&gt;
#page-header .headermenu a {color: #FDFF2A;}&lt;br /&gt;
&lt;br /&gt;
.navbar {padding-left: 1em;}&lt;br /&gt;
.breadcrumb li {color: #FFF;}&lt;br /&gt;
.breadcrumb li a {color: #FFF;}&lt;br /&gt;
&lt;br /&gt;
.block {background-color: #013D6A;}&lt;br /&gt;
.block .header .title {color: #FFF;}&lt;br /&gt;
.block .header .title .block_action input {background-color: #FFF;}&lt;br /&gt;
.block .content {border: 1px solid #000;padding: 5px;background-color: #FFF;}&lt;br /&gt;
.block .content .block_tree p {font-size: 80%;}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer {text-align: center;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform {margin-left: 5%;width: 90%;font-size: 9pt;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform #adminsearchquery {width: 95%;}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .calendar-controls a {color: #013D6A;font-weight: bold;}&lt;br /&gt;
.block_calendar_month .content .minicalendar td {border-color: #FFF;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {color: #FFF;background-color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day a {color: #FFF000;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays th {border-width: 0;font-weight: bold;color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays abbr {border-width: 0;text-decoration: none;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
[[image:Learn_to_theme_02.jpg|400px|thumb|Excitement theme screenshot]]&lt;br /&gt;
This isn&#039;t all of the CSS for the theme, but just enough to style the front page when the user is not logged in.&lt;br /&gt;
Remember this theme extends the base theme so there is already CSS for layout as well.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* The CSS is laid out in a single line format. This is done within the core themes for Moodle. It makes it quicker to read the selectors and see what is being styled.&lt;br /&gt;
* I have written my selectors to take into account the structure of the HTML (more than just the one tag I want to style). This helps further to reduce the conflicts that I may encounter.&lt;br /&gt;
* I use generic classes like &#039;&#039;.sideblock&#039;&#039; only where I want to be generic, as soon as I want to be specific I use the unique classes such as &#039;&#039;.block_calendar_month&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using images within CSS===&lt;br /&gt;
&lt;br /&gt;
I will add two image files to the pix directory of my theme:&lt;br /&gt;
; /theme/excitement/pix/background.png : This will be the background image for my theme.&lt;br /&gt;
; /theme/excitement/pix/gradient.jpg : This will be a gradient I use for the header and headings.&lt;br /&gt;
I quickly created both of these images using gimp and simply saved them to the pix directory.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-image:url([[pix:theme|background]]);}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock,&lt;br /&gt;
#page-header,&lt;br /&gt;
.sideblock,&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {background-image:url([[pix:theme|gradient]]);background-repeat:repeat-x;background-color: #0273C8;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
[[image:Learn_to_theme_03.jpg‎|400px|thumb|Excitement theme screenshot]]&lt;br /&gt;
The CSS above is the two new rules that I had to write to use my images within CSS.&lt;br /&gt;
&lt;br /&gt;
The first rule sets the background image for the page to background.png&lt;br /&gt;
&lt;br /&gt;
The second rule sets the background for headings, and the sideblocks to use gradient.jpg&lt;br /&gt;
&lt;br /&gt;
You will notice that I did not need to write a path to the image. This is because Moodle has this special syntax that can be used and will be replaced when the CSS is parsed before delivery.&lt;br /&gt;
The advantage of using this syntax over writing the path in is that the path may change depending on where you are or what theme is being used.&lt;br /&gt;
&lt;br /&gt;
Other themers may choose to extend your theme with their own; if you use this syntax then all they need to do to override the image is to create one with the same name in their themes directory.&lt;br /&gt;
&lt;br /&gt;
You will also notice that I don&#039;t need to add the image files extension. This is because Moodle is smart enough to work out what extension the file uses. It also allows themers to override images with different formats.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right&amp;quot; /&amp;gt;&lt;br /&gt;
The following is the complete CSS for my theme:&lt;br /&gt;
&amp;lt;div style=&amp;quot;overflow:auto;height:400px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
a {text-decoration: none;}&lt;br /&gt;
.addcoursebutton .singlebutton {text-align: center;}&lt;br /&gt;
&lt;br /&gt;
h1.headermain {color: #fff;}&lt;br /&gt;
h2.main {border-bottom: 3px solid #013D6A;color: #013D6A;text-align: center;}&lt;br /&gt;
h2.headingblock {font-size: 18pt;margin-top: 0;background-color: #013D6A;color: #FFF;text-align: center;}&lt;br /&gt;
#page-header {background-color: #013D6A;border-bottom:5px solid #013D6A;}&lt;br /&gt;
#page-header .headermenu  {color: #FFF;}&lt;br /&gt;
#page-header .headermenu a {color: #FDFF2A;}&lt;br /&gt;
&lt;br /&gt;
.sideblock {background-color: #013D6A;}&lt;br /&gt;
.sideblock .header .title {color: #FFF;}&lt;br /&gt;
.sideblock .header .title .block_action input {background-color: #FFF;}&lt;br /&gt;
.sideblock .content {border: 1px solid #000;padding: 5px;background-color: #FFF;}&lt;br /&gt;
.sideblock .content .block_tree p {font-size: 80%;}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer {text-align: center;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform {margin-left: 5%;width: 90%;font-size: 9pt;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform #adminsearchquery {width: 95%;}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .calendar-controls a {color: #013D6A;font-weight: bold;}&lt;br /&gt;
.block_calendar_month .content .minicalendar td {border-color: #FFF;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {color: #FFF;background-color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day a {color: #FFF000;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays th {border-width: 0;font-weight: bold;color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays abbr {border-width: 0;text-decoration: none;}&lt;br /&gt;
&lt;br /&gt;
html {background-image:url([[pix:theme|background]]);}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock,&lt;br /&gt;
#page-header,&lt;br /&gt;
.sideblock,&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {background-image:url([[pix:theme|gradient]]);background-repeat:repeat-x;background-color: #0273C8;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adding a screenshot and favicon==&lt;br /&gt;
The final thing to do at this point is add both a screenshot for this theme as well as a favicon for it.&lt;br /&gt;
The screenshot will be shown in the theme selector screen and should be named &#039;&#039;screenshot.jpg&#039;&#039;.&lt;br /&gt;
The favicon will be used when someone bookmarks this page.&lt;br /&gt;
Both images should be located in your themes pix directory as follows:&lt;br /&gt;
* /theme/excitement/pix/screenshot.jpg&lt;br /&gt;
* /theme/excitement/pix/favicon.ico&lt;br /&gt;
&lt;br /&gt;
In the case of my theme I have taken a screenshot and added it to that directory, and because I don&#039;t really want to do anything special with the favicon I have copied it from /theme/base/pix/favicon.ico so that at least it will be recognisable as Moodle.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Themes]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Development:Themes_2.0_creating_your_first_theme&amp;diff=77425</id>
		<title>Development:Themes 2.0 creating your first theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Development:Themes_2.0_creating_your_first_theme&amp;diff=77425"/>
		<updated>2010-11-02T15:55:33Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Configuring our theme - increased DIV height to allow printing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}This document describes how to create a theme for Moodle 2.0. It assumes you have some understanding of how themes within Moodle work as well as a good understanding of HTML and CSS.&lt;br /&gt;
&lt;br /&gt;
===Theme designer mode===&lt;br /&gt;
&lt;br /&gt;
Under normal operation Moodle does several things in the name of performance, one of these is to combine all of the CSS into one file, minimize it, cache it on the server, and then serve it. After the first request the cached version is served to greatly improve page performance. &lt;br /&gt;
&lt;br /&gt;
What this means for you as a themer? When you make changes they will not be seen immediately. In fact you will need to tell Moodle to rebuild the cache that it is serving.&lt;br /&gt;
This isn&#039;t practical for designing themes of course so the &#039;&#039;&#039;theme designer mode&#039;&#039;&#039; was added. When enabled it tells Moodle not to combine or cache the CSS that gets delivered. This has the downside that page load times will take significantly longer, however you will see your changes immediately every time.&lt;br /&gt;
&lt;br /&gt;
Theme designer mode may be enabled via &#039;&#039;Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; [[Theme settings]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: Internet Explorer versions 6 and 7 have BIG problems when a site attempts to link to more than 31 stylesheets, in which case either a limited number or no styles get applied. Because Moodle sends up all of the CSS all of the time with theme designer mode turned on there is a very high chance you will get more than 31 stylesheets being included. This will, of course, cause major problems for Internet Explorer until theme designer mode is turned off.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
The first thing you need to do is create the directories and files you will be using, the first thing to create is the actual directory for your theme. This should be the name of your theme, in my case it&#039;s &#039;excitement&#039;. The directory should be located within the theme directory of Moodle, ./moodle/theme/excitement/ will be the directory I create.&lt;br /&gt;
&lt;br /&gt;
Now within that directory we can immediately create several files that we know we are going to need. &lt;br /&gt;
&lt;br /&gt;
So the files that we want to create are:&lt;br /&gt;
; config.php :  All of our settings will go here.&lt;br /&gt;
; /style/ : This directory will contain all of our stylesheets.&lt;br /&gt;
; /style/excitement.css : All of our css will go in here.&lt;br /&gt;
; /pix/ : Into this directory we&#039;ll put a screen shot of our theme as well as our favicon and any images we use in CSS.&lt;br /&gt;
; /layout/ : Our layout files will end up in this directory.&lt;br /&gt;
; /layout/standard.php : This will be our one basic layout file.&lt;br /&gt;
&lt;br /&gt;
So after this setup step you should have a directory structure similar to what is shown below.&lt;br /&gt;
&lt;br /&gt;
[[image:Learn_to_theme_01.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Configuring our theme==&lt;br /&gt;
&lt;br /&gt;
Open config.php in your favourite editor and start by adding the opening PHP tags &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;?php&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now we need to add the settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;excitement&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Very simply this tells Moodle the name of your theme, and if you ever have several config.php files open this will help you identify which one you are looking at.&lt;br /&gt;
&lt;br /&gt;
Next, the parents for this theme.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells Moodle that my new theme &#039;&#039;`excitement`&#039; wants to extend the base theme. &lt;br /&gt;
&lt;br /&gt;
A theme can extend any number of themes. Rather than creating an entirely new theme and copying all of the CSS, you can simply create a new theme, extend the theme you like and just add the changes you want to your theme. &lt;br /&gt;
&lt;br /&gt;
Also worth noting is the purpose of the base theme: it provides us with a basic layout and just enough CSS to make everything fall into place.&lt;br /&gt;
&lt;br /&gt;
Now we will tell Moodle about our stylesheets:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;excitement&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final thing we need to add into our theme&#039;s config.php file is the definition of the layouts for our theme:&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:1780px;overflow:auto;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;standard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;print&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;false),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
/** List of javascript files that need to be included on each page */&lt;br /&gt;
$THEME-&amp;gt;javascripts = array();&lt;br /&gt;
$THEME-&amp;gt;javascripts_footer = array();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you are looking at is the different layouts for our theme. Why are there so many? Because, that is how many there are in Moodle. There is one for every general type of page. With my &#039;&#039;`excitement`&#039;&#039; theme I have chosen to use my own layout. Unless there was a specific reason to do so, normally you would not need to create your own layouts, you could extend the base theme, and use its layouts, meaning you would only have to write CSS to achieve your desired look.&lt;br /&gt;
&lt;br /&gt;
For each layout above, you will notice the following four things are being set:&lt;br /&gt;
; file : This is the name of the layout file we want to use, it should always be located in the above themes layout directory. For us this is of course standard.php as we only have one layout file.&lt;br /&gt;
; regions : This is an array of block regions that our theme has. Each entry in here can be used to put blocks in when that layout is being used.&lt;br /&gt;
; defaultregion : If a layout has regions it should have a default region, this is where blocks get put when first added.&lt;br /&gt;
; options : These are special settings, anything that gets put into the options array is available later on when we are writing our layout file.&lt;br /&gt;
&lt;br /&gt;
There are additional settings that can be defined in the config.php file - see [[Development:Themes 2.0|Themes 2.0]] for the full list.&lt;br /&gt;
&lt;br /&gt;
==Writing the layout file==&lt;br /&gt;
&lt;br /&gt;
The excitement theme has just one layout file.&lt;br /&gt;
&lt;br /&gt;
The downside of this is that I have to make the layout file do everything I want which means I need to make use of some options (as defined in the layouts in config.php). &lt;br /&gt;
&lt;br /&gt;
The upside is that I only need to maintain one file. &lt;br /&gt;
&lt;br /&gt;
Other than maintenance, using multiple layout files provides many advantages to real world themes in that you can easily tweak and customise specific layouts to achieve the goals of the organisation using the theme.&lt;br /&gt;
&lt;br /&gt;
So lets start writing standard.php, the layout file for my &#039;&#039;`excitement`&#039;&#039; theme.&lt;br /&gt;
&lt;br /&gt;
===The top of the layout file===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hassidepre = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;, $OUTPUT);&lt;br /&gt;
$hassidepost = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-post&#039;, $OUTPUT);&lt;br /&gt;
echo $OUTPUT-&amp;gt;doctype(); ?&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lets look at the code that goes into this section:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo $OUTPUT-&amp;gt;doctype(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is very important and is required to go at the very top of the page. This tells Moodle to print out the document type tag that is determined by the settings within Moodle.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we open the HTML tag and then ask Moodle to print the attributes that should go inside it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Simply creates the title tag and asks Moodle to fill it in.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are asking Moodle to print all of the other tags and content that need to go into the head. This includes stylesheets, script tags, and inline JavaScript code.&lt;br /&gt;
&lt;br /&gt;
===The page header===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyid; ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-header&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&amp;gt;&lt;br /&gt;
            &amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
                echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
                if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
                    echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
                }&lt;br /&gt;
                echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
            ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;navbar clearfix&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;breadcrumb&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;navbar(); ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;navbutton&amp;quot;&amp;gt; &amp;lt;?php echo $PAGE-&amp;gt;button; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So there is a bit more going on here obviously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyid; ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again much like what we did for the opening HTML tag in the head we have started writing the opening body tag and are then asking Moodle to give us the ID we should use for the body tag as well as the classes we should use.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This very important call writes some critical bits of JavaScript into the page. It should always be located after the body tag as soon as possible.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are checking whether or not we need to print the header for the page. There are three checks we need to make here:&lt;br /&gt;
# &#039;&#039;&#039;$PAGE-&amp;gt;heading&#039;&#039;&#039; : This checks to make sure that there is a heading for the page. This will have been set by the script and normally describes the page in a couple of words.&lt;br /&gt;
# &#039;&#039;&#039;empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;])&#039;&#039;&#039; : Now this check is looking at the layout options that we set in our config.php file. It is looking to see if the layout set &#039;nonavbar&#039; =&amp;gt; true.&lt;br /&gt;
# &#039;&#039;&#039;$PAGE-&amp;gt;has_navbar()&#039;&#039;&#039; The third check is to check with the page whether it has a navigation bar to display.&lt;br /&gt;
If either there is a heading for this page or there is a navigation bar to display then we will display a heading.&lt;br /&gt;
&lt;br /&gt;
Leading on from this lets assume that there is a header to print.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
    .....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This line is simply saying if the page has a heading print it. In this case we run the first check above again just to make sute there is a heading, we then open a heading tag that we choose and ask the page to print the heading.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
    echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
    if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
        echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
    }&lt;br /&gt;
    echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are looking to print the menu and content that you see at the top of the page (usually to the right). We start by getting Moodle to print the login information for the current user. If the user is logged in this will be their name and a link to their profile, if not then it will be a link to login.&lt;br /&gt;
&lt;br /&gt;
Next we check our page options to see whether a language menu should be printed. If in the layout definition within config.php it sets &#039;&#039;&#039;langmenu =&amp;gt; true&#039;&#039;&#039; then we will print the language menu, a drop down box that lets the user change the language that Moodle displays in.&lt;br /&gt;
&lt;br /&gt;
Finally the page also has a heading menu that can be printed. This heading menu is special HTML that the page you are viewing wants to add. It can be anything from drop down boxes to buttons and any number of each.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;navbar clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;breadcrumb&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;navbar(); ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;navbutton&amp;quot;&amp;gt; &amp;lt;?php echo $PAGE-&amp;gt;button; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The final part of the header.&lt;br /&gt;
&lt;br /&gt;
Here we want to print the navigation bar for the page if there is one. To find out if there is one we run checks number 2 and 3 again and proceed if they pass.&lt;br /&gt;
&lt;br /&gt;
Assuming there is a header then there are two things that we need to print. The first is the navigation bar. This is a component that the OUTPUT library knows about. The second is a button to shown on the page.&lt;br /&gt;
&lt;br /&gt;
In both cases we can choose to wrap them in a div to make our life as a themer easier.&lt;br /&gt;
&lt;br /&gt;
Well that is it for the header. There is a lot of PHP compared to the other sections of the layout file but it does not change and can be copied and pasted between themes.&lt;br /&gt;
&lt;br /&gt;
===The page content===&lt;br /&gt;
&lt;br /&gt;
I am going with the default two block regions plus the main content.&lt;br /&gt;
&lt;br /&gt;
Because I have based this theme and layout file on the base theme the HTML looks a little intense. This is because it is a floating div layout where the content comes first and then we get the columns (even though one column will be to the left of the content.) Don&#039;t worry too much about it. When it comes to writing your own theme you can go about it as you choose.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-content&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;region-main-box&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;region-post-box&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;region-main-wrap&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-main&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-pre&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
                &amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-post&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In regards to PHP this section is very easy. There are only three lines for the whole section one to get the main content and one for each block region.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This line prints the main content for the page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These lines of code check the variables we created earlier on to decide whether we should show the pre block region. If you try to display a block region that isn&#039;t there or has no content then Moodle will give you an error message so these lines are very important.&lt;br /&gt;
&lt;br /&gt;
For those who get an error message if it is &amp;quot;unknown block region side-pre&amp;quot; or &amp;quot;unknown block region side-post&amp;quot; then this is the issue you are experiencing. Simply add the following lines and all will be fine.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This line gets all of the blocks and more particularly the content for the block region &#039;&#039;&#039;side-pre&#039;&#039;&#039;. This block region will be displayed to the left of the content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again we should make this check for every block region as there are some pages that have no blocks what-so-ever.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are getting the other block region &#039;&#039;&#039;side-post&#039;&#039;&#039; which will be displayed to the right of the content.&lt;br /&gt;
&lt;br /&gt;
===The page footer===&lt;br /&gt;
Here we want to print the footer for the page, any content required by Moodle, and then close the last tags.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
        &amp;lt;?php&lt;br /&gt;
        echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
        ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The section of code is responsible for printing the footer for the page.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
        &amp;lt;?php&lt;br /&gt;
        echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
        ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing we do before printing the footer is check that we actually want to print it. This is done by checking the options for the layout as defined in the config.php file. If &#039;&#039;&#039;nofooter =&amp;gt; true&#039;&#039;&#039; is set the we don&#039;t want to print the footer and should skip over this body of code.&lt;br /&gt;
&lt;br /&gt;
Assuming we want to print a footer we proceed to create a div to house its content and then print the bits of the content that will make it up.&lt;br /&gt;
There are four things that the typical page footer will want to print:&lt;br /&gt;
; echo page_doc_link(get_string(&#039;moodledocslink&#039;)) : This will print a link to the Moodle.org help page for this particular page.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;login_info(); : This is the same as at the top of the page and will print the login information for the current user.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;home_link(); : This prints a link back to the Moodle home page for this site.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;standard_footer_html(); : This prints special HTML that is determined by the settings for the site. Things such as performance information or debugging will be printed by this line if they are turned on.&lt;br /&gt;
&lt;br /&gt;
And the final line of code for our layout file is:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is one of the most important lines of code in the layout file. It asks Moodle to print any required content into the page, and there will likely be a lot although most of it will not be visual.&lt;br /&gt;
&lt;br /&gt;
It will instead be things such as inline scripts and JavaScript files required to go at the bottom of the page. If you forget this line its likely no JavaScript will work!&lt;br /&gt;
&lt;br /&gt;
We&#039;ve now written our layout file and it is all set to go. The complete source is below for reference. Remember if you want more practical examples simply look at the layout files located within the layout directory of other themes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:400px;overflow:auto;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hassidepre = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;, $OUTPUT);&lt;br /&gt;
$hassidepost = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-post&#039;, $OUTPUT);&lt;br /&gt;
echo $OUTPUT-&amp;gt;doctype() ?&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;title; ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;link rel=&amp;quot;shortcut icon&amp;quot; href=&amp;quot;&amp;lt;?php echo $OUTPUT-&amp;gt;pix_url(&#039;favicon&#039;, &#039;theme&#039;)?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyid; ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-header&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&amp;gt;&lt;br /&gt;
        &amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
            echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
            if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
                echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
            }&lt;br /&gt;
            echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
        ?&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;navbar clearfix&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;breadcrumb&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;navbar(); ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;navbutton&amp;quot;&amp;gt; &amp;lt;?php echo $PAGE-&amp;gt;button; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-content&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;region-main-box&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;region-post-box&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-main-wrap&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div id=&amp;quot;region-main&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                            &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-pre&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
                &amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-post&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
        &amp;lt;?php&lt;br /&gt;
        echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
        echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
        ?&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adding some CSS==&lt;br /&gt;
With config.php and standard.php both complete the theme is now usable and starting to look like a real theme, however if you change to it using the theme selector you will notice that it still lacks any style.&lt;br /&gt;
&lt;br /&gt;
This of course is where CSS comes in. When writing code Moodle developers are strongly encouraged to not use inline styles anywhere. This is fantastic for us as themers because there is nothing (or at least very little) in Moodle that cannot be styled using CSS.&lt;br /&gt;
&lt;br /&gt;
===Moodle CSS basics===&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 all of the CSS for the whole of Moodle is delivered all of the time! This was done for performance reasons. Moodle now reads in all of the CSS, combines it into one file, shrinks it removing any white space, caches it, and then delivers it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What this means for you as a themer?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You will need to write good CSS that won&#039;t clash with any other CSS within Moodle.&lt;br /&gt;
&lt;br /&gt;
Moodle is so big and complex,there is no way to ensure that classes don&#039;t get reused. What we can control however is the classes and id that get added to the body tag for every page. When writing CSS it is highly encouraged to make full use of these body classes, using them will help ensure the CSS you write has the least chance of causing conflicts.&lt;br /&gt;
&lt;br /&gt;
You should also take the time to look at how the Moodle themes use CSS. Look at their use of the body classes and how they separate the CSS for the theme into separate files based on the region of Moodle it applies to.&lt;br /&gt;
&lt;br /&gt;
Check out [[Development:Themes 2.0|Themes 2.0]] for more information about writing good CSS.&lt;br /&gt;
&lt;br /&gt;
===Starting to write excitement.css===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
a {text-decoration: none;}&lt;br /&gt;
.addcoursebutton .singlebutton {text-align: center;}&lt;br /&gt;
&lt;br /&gt;
h1.headermain {color: #fff;}&lt;br /&gt;
h2.main {border-bottom: 3px solid #013D6A;color: #013D6A;text-align: center;}&lt;br /&gt;
h2.headingblock {font-size: 18pt;margin-top: 0;background-color: #013D6A;color: #FFF;text-align: center;}&lt;br /&gt;
#page-header {background-color: #013D6A;}&lt;br /&gt;
#page-header .headermenu  {color: #FFF;}&lt;br /&gt;
#page-header .headermenu a {color: #FDFF2A;}&lt;br /&gt;
&lt;br /&gt;
.navbar {padding-left: 1em;}&lt;br /&gt;
.breadcrumb li {color: #FFF;}&lt;br /&gt;
.breadcrumb li a {color: #FFF;}&lt;br /&gt;
&lt;br /&gt;
.block {background-color: #013D6A;}&lt;br /&gt;
.block .header .title {color: #FFF;}&lt;br /&gt;
.block .header .title .block_action input {background-color: #FFF;}&lt;br /&gt;
.block .content {border: 1px solid #000;padding: 5px;background-color: #FFF;}&lt;br /&gt;
.block .content .block_tree p {font-size: 80%;}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer {text-align: center;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform {margin-left: 5%;width: 90%;font-size: 9pt;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform #adminsearchquery {width: 95%;}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .calendar-controls a {color: #013D6A;font-weight: bold;}&lt;br /&gt;
.block_calendar_month .content .minicalendar td {border-color: #FFF;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {color: #FFF;background-color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day a {color: #FFF000;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays th {border-width: 0;font-weight: bold;color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays abbr {border-width: 0;text-decoration: none;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
[[image:Learn_to_theme_02.jpg|400px|thumb|Excitement theme screenshot]]&lt;br /&gt;
This isn&#039;t all of the CSS for the theme, but just enough to style the front page when the user is not logged in.&lt;br /&gt;
Remember this theme extends the base theme so there is already CSS for layout as well.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* The CSS is laid out in a single line format. This is done within the core themes for Moodle. It makes it quicker to read the selectors and see what is being styled.&lt;br /&gt;
* I have written my selectors to take into account the structure of the HTML (more than just the one tag I want to style). This helps further to reduce the conflicts that I may encounter.&lt;br /&gt;
* I use generic classes like &#039;&#039;.sideblock&#039;&#039; only where I want to be generic, as soon as I want to be specific I use the unique classes such as &#039;&#039;.block_calendar_month&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using images within CSS===&lt;br /&gt;
&lt;br /&gt;
I will add two image files to the pix directory of my theme:&lt;br /&gt;
; /theme/excitement/pix/background.png : This will be the background image for my theme.&lt;br /&gt;
; /theme/excitement/pix/gradient.jpg : This will be a gradient I use for the header and headings.&lt;br /&gt;
I quickly created both of these images using gimp and simply saved them to the pix directory.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-image:url([[pix:theme|background]]);}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock,&lt;br /&gt;
#page-header,&lt;br /&gt;
.sideblock,&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {background-image:url([[pix:theme|gradient]]);background-repeat:repeat-x;background-color: #0273C8;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
[[image:Learn_to_theme_03.jpg‎|400px|thumb|Excitement theme screenshot]]&lt;br /&gt;
The CSS above is the two new rules that I had to write to use my images within CSS.&lt;br /&gt;
&lt;br /&gt;
The first rule sets the background image for the page to background.png&lt;br /&gt;
&lt;br /&gt;
The second rule sets the background for headings, and the sideblocks to use gradient.jpg&lt;br /&gt;
&lt;br /&gt;
You will notice that I did not need to write a path to the image. This is because Moodle has this special syntax that can be used and will be replaced when the CSS is parsed before delivery.&lt;br /&gt;
The advantage of using this syntax over writing the path in is that the path may change depending on where you are or what theme is being used.&lt;br /&gt;
&lt;br /&gt;
Other themers may choose to extend your theme with their own; if you use this syntax then all they need to do to override the image is to create one with the same name in their themes directory.&lt;br /&gt;
&lt;br /&gt;
You will also notice that I don&#039;t need to add the image files extension. This is because Moodle is smart enough to work out what extension the file uses. It also allows themers to override images with different formats.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right&amp;quot; /&amp;gt;&lt;br /&gt;
The following is the complete CSS for my theme:&lt;br /&gt;
&amp;lt;div style=&amp;quot;overflow:auto;height:400px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
a {text-decoration: none;}&lt;br /&gt;
.addcoursebutton .singlebutton {text-align: center;}&lt;br /&gt;
&lt;br /&gt;
h1.headermain {color: #fff;}&lt;br /&gt;
h2.main {border-bottom: 3px solid #013D6A;color: #013D6A;text-align: center;}&lt;br /&gt;
h2.headingblock {font-size: 18pt;margin-top: 0;background-color: #013D6A;color: #FFF;text-align: center;}&lt;br /&gt;
#page-header {background-color: #013D6A;border-bottom:5px solid #013D6A;}&lt;br /&gt;
#page-header .headermenu  {color: #FFF;}&lt;br /&gt;
#page-header .headermenu a {color: #FDFF2A;}&lt;br /&gt;
&lt;br /&gt;
.sideblock {background-color: #013D6A;}&lt;br /&gt;
.sideblock .header .title {color: #FFF;}&lt;br /&gt;
.sideblock .header .title .block_action input {background-color: #FFF;}&lt;br /&gt;
.sideblock .content {border: 1px solid #000;padding: 5px;background-color: #FFF;}&lt;br /&gt;
.sideblock .content .block_tree p {font-size: 80%;}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer {text-align: center;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform {margin-left: 5%;width: 90%;font-size: 9pt;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform #adminsearchquery {width: 95%;}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .calendar-controls a {color: #013D6A;font-weight: bold;}&lt;br /&gt;
.block_calendar_month .content .minicalendar td {border-color: #FFF;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {color: #FFF;background-color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day a {color: #FFF000;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays th {border-width: 0;font-weight: bold;color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays abbr {border-width: 0;text-decoration: none;}&lt;br /&gt;
&lt;br /&gt;
html {background-image:url([[pix:theme|background]]);}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock,&lt;br /&gt;
#page-header,&lt;br /&gt;
.sideblock,&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {background-image:url([[pix:theme|gradient]]);background-repeat:repeat-x;background-color: #0273C8;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adding a screenshot and favicon==&lt;br /&gt;
The final thing to do at this point is add both a screenshot for this theme as well as a favicon for it.&lt;br /&gt;
The screenshot will be shown in the theme selector screen and should be named &#039;&#039;screenshot.jpg&#039;&#039;.&lt;br /&gt;
The favicon will be used when someone bookmarks this page.&lt;br /&gt;
Both images should be located in your themes pix directory as follows:&lt;br /&gt;
* /theme/excitement/pix/screenshot.jpg&lt;br /&gt;
* /theme/excitement/pix/favicon.ico&lt;br /&gt;
&lt;br /&gt;
In the case of my theme I have taken a screenshot and added it to that directory, and because I don&#039;t really want to do anything special with the favicon I have copied it from /theme/base/pix/favicon.ico so that at least it will be recognisable as Moodle.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Themes]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Development_talk:Themes_2.0_creating_your_first_theme&amp;diff=77424</id>
		<title>Development talk:Themes 2.0 creating your first theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Development_talk:Themes_2.0_creating_your_first_theme&amp;diff=77424"/>
		<updated>2010-11-02T15:55:00Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Configuring Our Theme DIV height for printing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wow!  Is the code for this theme available in a file, say in Modules and Plugins?  Or did I miss it in my quick look.  I can see my next project at work. --[[User:chris collman|chris collman]] 12:07, 6 April 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
Hi Chris, the code in this tutorial isn&#039;t available anywhere the reason being that it is entirely based on the base theme :) check out &#039;&#039;theme/base/*&#039;&#039; you&#039;ll notice that what is in there is very close to the code I wrote for this tutorial. --[[User:Sam Hemelryk|Sam Hemelryk]] 01:33, 7 April 2010 (UTC)&lt;br /&gt;
::Hi Sam, I did not look, why get confused by reality and numb about :) I sort of got here by creating a 1.9.8 localhost that I could do screenshots for [[Standard themes]] and then tried my first complete install package of 2.0 in 3 months. My primary goal is to revamp the &#039;navigation&#039; and organization of Category:Themes pages, your instructions are going to help me. Thanks for all your time and efforts.   --[[User:chris collman|chris collman]] 11:26, 7 April 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
Good crisp documentation!! Thank you Sam for this :) You ve made our lives easier with 2.0 themes!! ;) &lt;br /&gt;
&lt;br /&gt;
Cheers!! --[[User:Navin Dutta|Navin Dutta]] 03:12, 13 April 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
==Question about instruction==&lt;br /&gt;
Sam, your instructions say there will only be one layout php file called standard.php.  What is the general.php file pointer doing in config.php under base?  If I understand things, it should be pointed to the theme base (which has a general.php) or the file should be called standard.php.  Is that correct?&lt;br /&gt;
&lt;br /&gt;
It is snowing, so I thought I would see if I could follow your instructions and do something like standardlogo in 1.9 for fun.  No doubt will crash and burn with this part time project over the next 2 years :) Thanks --[[User:chris collman|chris collman]] 13:12, 16 April 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Broken :-( ==&lt;br /&gt;
&lt;br /&gt;
Hello,&lt;br /&gt;
&lt;br /&gt;
Thanks for the tutorial, but with - Moodle 2.0 Preview 2 (Build: 20100531) - I get the error &#039;Coding error detected, it must be fixed by a programmer: Trying to reference an unknown block region side-post&#039; when trying to select the theme for modern browsers.&lt;br /&gt;
&lt;br /&gt;
Update: I&#039;ve made the changes required to solve the problem after reading: http://moodle.org/mod/forum/discuss.php?d=150190&lt;br /&gt;
&lt;br /&gt;
Cheers,&lt;br /&gt;
&lt;br /&gt;
Gareth&lt;br /&gt;
&lt;br /&gt;
== Layouts ==&lt;br /&gt;
&lt;br /&gt;
The need for the layout definitions is mentioned but not what they or what they do. This either needs explained or a link to where it is explained. It certainly isn&#039;t obvious --[[User:Howard Miller|Howard Miller]] 17:18, 12 July 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Is this what??? ==&lt;br /&gt;
&lt;br /&gt;
Sorry guys, I think this is confusing Please understand that I am not that technically literate so I need things said a lot clearer: &lt;br /&gt;
&lt;br /&gt;
config.php &lt;br /&gt;
    All of our settings will go here. &lt;br /&gt;
/style/ &lt;br /&gt;
    This directory will contain all of our stylesheets. &lt;br /&gt;
/style/excitement.css &lt;br /&gt;
    All of our css will go in here. &lt;br /&gt;
/pix/ &lt;br /&gt;
    Into this directory we&#039;ll put a screen shot of our theme as well as our favicon and any images we use in CSS. &lt;br /&gt;
/layout/ &lt;br /&gt;
    Our layout files will end up in this directory. &lt;br /&gt;
/layout/standard.php &lt;br /&gt;
    This will be our one basic layout file. &lt;br /&gt;
&lt;br /&gt;
There is a clear difference between a file and a directory - but the manner in which the above example is set up does not appear to make that distinction. Could it not be better put like:  &lt;br /&gt;
&lt;br /&gt;
Create the theme directory/folder, which we are calling &amp;quot;excitement&amp;quot;. Into that directory/folder we create a file: &lt;br /&gt;
  config.php &lt;br /&gt;
    All of our settings will go here.&lt;br /&gt;
Then we create the directories/folders   &lt;br /&gt;
  /style/  &lt;br /&gt;
      This directory/folder will contain all of our stylesheets. &lt;br /&gt;
  /pix/ &lt;br /&gt;
      Into this directory/folder we&#039;ll put a screen shot of our theme as well as our favicon and any images we use in CSS. &lt;br /&gt;
  /layout/ &lt;br /&gt;
      Our layout files will end up in this directory/folder. &lt;br /&gt;
&lt;br /&gt;
Into the style directory/folder we create a file: &lt;br /&gt;
 excitement.css &lt;br /&gt;
    Where we place All of our css rules. &lt;br /&gt;
And in the layout directory/folder we create a file: &lt;br /&gt;
  standard.php &lt;br /&gt;
    This will be our one basic layout file. &lt;br /&gt;
&lt;br /&gt;
For me, not being that smart, this is a far more easily understood structure than has been shown.&lt;br /&gt;
&lt;br /&gt;
== Configuring Our Theme ==&lt;br /&gt;
The DIV that contains the config.php code  had a vertical scrollbar. This is because the DIV around the code had a height of 400. This is fine when you are reading this document on the computer, but when you print it a large part of the php ($THEME-&amp;gt;layouts = array) is chopped off. I increased the DIV height to 1780 and it solves the printing problem. Is this ok?&lt;br /&gt;
&lt;br /&gt;
--[[User:Luis de Vasconcelos|Luis de Vasconcelos]] 15:54, 2 November 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=LDAP_authentication&amp;diff=76892</id>
		<title>LDAP authentication</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=LDAP_authentication&amp;diff=76892"/>
		<updated>2010-10-20T14:03:42Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Using multiple LDAP Servers link */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 1.9}}&lt;br /&gt;
Location: Settings link in &#039;&#039;Administration &amp;gt; Users &amp;gt; [[Authentication]] &amp;gt; LDAP Server&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This document describes how to set up Lightweight Directory Access Protocol (LDAP) authentication in Moodle.  We cover the basic, advanced and some trouble shooting sections to assist the user in the installation and administrating LDAP in Moodle.  &lt;br /&gt;
==Table of Contents==&lt;br /&gt;
__TOC__&lt;br /&gt;
==Basic Scenario==&lt;br /&gt;
The simple and straightforward approach  for most installations.&lt;br /&gt;
&lt;br /&gt;
===Assumptions===&lt;br /&gt;
&lt;br /&gt;
# Your Moodle site is located at &#039;&#039;&#039;http://your.moodle.site/&#039;&#039;&#039;&lt;br /&gt;
# You have configured your PHP installation with the LDAP extension. It is loaded and activated, and it shows when you go to &#039;&#039;&#039;http://your.moodle.site/admin/phpinfo.php&#039;&#039;&#039; (logged in as user &#039;admin&#039;).&lt;br /&gt;
# Your LDAP server has &#039;&#039;&#039;192.168.1.100&#039;&#039;&#039; as its IP address.&lt;br /&gt;
# You are not using LDAP with SSL (also known as LDAPS) in your settings. This might prevent certain operations from working (e.g., you cannot update data if you are using MS Active Directory -- MS-AD from here on --), but should be OK if you just want to authenticate your users.&lt;br /&gt;
# You don&#039;t want your users to change their passwords the first time they log in into Moodle.&lt;br /&gt;
# You are using a single domain as the source of your authentication data in case you are using MS-AD (more on this in the Appendices).&lt;br /&gt;
# You are using a top level distinguished name (DN) of &#039;&#039;&#039;dc=my,dc=organization,dc=domain&#039;&#039;&#039; as the root of your LDAP tree. &lt;br /&gt;
# You have a non-privileged LDAP user account you will use to bind to the LDAP server. This is not necessary with certain LDAP servers, but MS-AD requires this and it won&#039;t hurt if you use it even if your LDAP server doesn&#039;t need it. Make sure &#039;&#039;&#039;this account and its password don&#039;t expire&#039;&#039;&#039;, and make this password as strong as possible. Remember you only need to type this password once, when configuring Moodle, so don&#039;t be afraid of making it as hard to guess as possible. Let&#039;s say this user account has a DN of &#039;&#039;&#039;cn=ldap-user,dc=my,dc=organization,dc=domain&#039;&#039;&#039;, and password &#039;&#039;&#039;hardtoguesspassword&#039;&#039;&#039;.&lt;br /&gt;
# All of your Moodle users are in an organizational unit (OU) called &#039;&#039;&#039;moodleusers&#039;&#039;&#039;, which is right under your LDAP root. That OU has a DN of &#039;&#039;&#039;ou=moodleusers,dc=my,dc=organization,dc=domain&#039;&#039;&#039;.&lt;br /&gt;
# You &#039;&#039;&#039;don&#039;t&#039;&#039;&#039; want your LDAP users&#039; passwords to be stored in Moodle at all.&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
===Configuring Moodle authentication===&lt;br /&gt;
&lt;br /&gt;
Log in as an admin user and go to Administration &amp;gt;&amp;gt; Users &amp;gt;&amp;gt; Authentication &amp;gt;&amp;gt; Manage authentication. In the table that appears, enable the &amp;quot;LDAP Server&amp;quot; authentication option (click on the closed eye to make it open) and then click on the associated &#039;Settings&#039; link. You will get a page similar to this one:&lt;br /&gt;
&lt;br /&gt;
[[Image:auth_ldap_config_screenshot.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Now, you just have to fill in the values. Let&#039;s go step by step.&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====LDAP Server Settings====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Host URL&lt;br /&gt;
| As the IP of your LDAP server is 192.168.1.100, type &amp;quot;&#039;&#039;&#039;ldap://192.168.1.100&#039;&#039;&#039;&amp;quot; (without the quotes), or just &amp;quot;&#039;&#039;&#039;192.168.1.100&#039;&#039;&#039;&amp;quot; (some people have trouble connecting with the first syntax, specially on MS Windows servers).&lt;br /&gt;
|-&lt;br /&gt;
| Version&lt;br /&gt;
| Unless you are using a really old LDAP server, &#039;&#039;&#039;version 3&#039;&#039;&#039; is the one you should choose.&lt;br /&gt;
|-&lt;br /&gt;
| LDAP Encoding&lt;br /&gt;
| Specify encoding used by LDAP server. Most probably utf-8.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====Bind settings====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Hide passwords&lt;br /&gt;
| As you &#039;&#039;&#039;don&#039;t&#039;&#039;&#039; want to store the users&#039;s password in Moodle&#039;s database, choose &#039;&#039;&#039;Yes&#039;&#039;&#039; here.&lt;br /&gt;
|-&lt;br /&gt;
| Distinguished Name&lt;br /&gt;
| This is the distinguished name of the bind user defined above. Just type &amp;quot;&#039;&#039;&#039;cn=ldap-user,dc=my,dc=organization,dc=domain&#039;&#039;&#039;&amp;quot; (without the quotes).&lt;br /&gt;
|-&lt;br /&gt;
| Password&lt;br /&gt;
| This is the bind user password defined above. Type &amp;quot;&#039;&#039;&#039;hardtoguesspassword&#039;&#039;&#039;&amp;quot; (without the quotes).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====User lookup settings====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| User type&lt;br /&gt;
| Choose: &lt;br /&gt;
* &#039;&#039;&#039;Novel Edirectory&#039;&#039;&#039; if your LDAP server is running Novell&#039;s eDdirectory.&lt;br /&gt;
* &#039;&#039;&#039;posixAccount (rfc2307)&#039;&#039;&#039; if your LDAP server is running a RFC-2307 compatible LDAP server (choose this is your server is running OpenLDAP, including Mac OS X server).&lt;br /&gt;
* &#039;&#039;&#039;posixAccount (rfc2307bis)&#039;&#039;&#039; if your LDAP server is running a RFC-2307bis compatible LDAP server.&lt;br /&gt;
* &#039;&#039;&#039;sambaSamAccount (v.3.0.7)&#039;&#039;&#039; if your LDAP server is running with SAMBA&#039;s 3.x LDAP schema extension and you want to use it.&lt;br /&gt;
* &#039;&#039;&#039;MS ActiveDirectory&#039;&#039;&#039; if your LDAP server is running Microsoft&#039;s Active Directory (MS-AD)&lt;br /&gt;
|-&lt;br /&gt;
| Contexts&lt;br /&gt;
| The DN of the context (container) where all of your Moodle users are found. Type &#039;&#039;&#039;ou=moodleusers,dc=my,dc=organization,dc=domain&#039;&#039;&#039; here.  &lt;br /&gt;
&lt;br /&gt;
On a Mac OS X Server, this is usually &#039;&#039;&#039;cn=users,dc=my,dc=organization,dc=domain&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| Search subcontexts&lt;br /&gt;
| If you have any sub organizational units (subcontexts) hanging from &#039;&#039;&#039;ou=moodleusers,dc=my,dc=organization,dc=domain&#039;&#039;&#039; and you want Moodle to search there too, set this to &#039;&#039;&#039;yes&#039;&#039;&#039;. Otherwise, set this to &#039;&#039;&#039;no&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| Dereference aliases&lt;br /&gt;
| Sometimes your LDAP server will tell you that the real value you are searching for is in fact in another part of the LDAP tree (this is called an alias). If you want Moodle to &#039;dereference&#039; the alias and fetch the real value from the original location, set this to &#039;&#039;&#039;yes&#039;&#039;&#039;. If you don&#039;t want Moodle to dereference it, set this to &#039;&#039;&#039;no&#039;&#039;&#039;. If you are using MS-AD, set this to &#039;&#039;&#039;no&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| User attribute&lt;br /&gt;
| The attribute used to name/search users in your LDAP tree. This option takes a default value based on the &#039;&#039;User type&#039;&#039; value you chose above. &amp;lt;u&amp;gt;So unless you need something special, you don&#039;t need to fill this in&amp;lt;/u&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
By the way, it&#039;s usually &#039;&#039;&#039;cn&#039;&#039;&#039; (Novell eDirectory and MS-AD) or &#039;&#039;&#039;uid&#039;&#039;&#039; (RFC-2037, RFC-2037bis and SAMBA 3.x LDAP extension), but if you are using MS-AD you could use &#039;&#039;&#039;sAMAccountName&#039;&#039;&#039; (the pre-Windows 2000 logon account name) if you need too.&lt;br /&gt;
|-&lt;br /&gt;
| Member attribute&lt;br /&gt;
| The attribute used to list the members of a given group. This option takes a default value based on the &#039;&#039;User type&#039;&#039; value you choosed above. &amp;lt;u&amp;gt;So unless you need something special, you don&#039;t need to fill this in.&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By the way, the usual values are &#039;&#039;&#039;member&#039;&#039;&#039; and &#039;&#039;&#039;memberUid&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| Member attribute uses dn&lt;br /&gt;
| Whether the member attribute contains distinguished names (1) or not (0).This option takes a default value based on the &#039;&#039;User type&#039;&#039; value you choosed above. &amp;lt;u&amp;gt;So unless you need something special, you don&#039;t need to fill this in.&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Object class&lt;br /&gt;
| The type of LDAP object used to search for users. This option takes a default value based on the &#039;&#039;User type&#039;&#039; value you chose above. &amp;lt;u&amp;gt;So unless you need something special, you don&#039;t need to fill this in.&amp;lt;/u&amp;gt;&lt;br /&gt;
* If you leave it blank, the filter &amp;quot;(objectClass=*)&amp;quot; will be used.&lt;br /&gt;
* If you provide &amp;quot;objectClass=some-string&amp;quot;, then it will provide &amp;quot;(objectClass=some-string)&amp;quot; as the filter.&lt;br /&gt;
* If you provide a value that does not start with &amp;quot;(&amp;quot;, it is assumed to be a value that should be set to &amp;quot;objectClass&amp;quot;. So if you provide &amp;quot;some-string&amp;quot;, then it will provide &amp;quot;(objectClass=some-string)&amp;quot; as the filter.&lt;br /&gt;
* If you provide a string that starts with a &amp;quot;(&amp;quot;, then it will pass that as is. So if you provide &amp;quot;(&amp;amp;(objectClass=user)(enabledMoodleUser=1))&amp;quot;, then it will pass that as the filter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here are the default values for each of the &#039;&#039;ldap_user_type&#039;&#039; values:&lt;br /&gt;
* &#039;&#039;&#039;User&#039;&#039;&#039; for Novel eDirectory&lt;br /&gt;
* &#039;&#039;&#039;posixAccount&#039;&#039;&#039; for RFC-2037 and RFC-2037bis&lt;br /&gt;
* &#039;&#039;&#039;sambaSamAccount&#039;&#039;&#039; for SAMBA 3.0.x LDAP extension&lt;br /&gt;
* &#039;&#039;&#039;user&#039;&#039;&#039; for MS-AD&lt;br /&gt;
If you get an error about a problem with updating the ldap server (even if you have specified not to write changes back to the ldap server) try setting the ldap object class to * - see http://moodle.org/mod/forum/discuss.php?d=70566 for a discussion on this problem&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====Force change password====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Force change password&lt;br /&gt;
| Set this to &#039;&#039;Yes&#039;&#039; if you want to force your users to change their password on the first login into Moodle. Otherwise, set this to &#039;&#039;no&#039;&#039;. Bear in mind the password they are forced to change is the one stored in your LDAP server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;As you don&#039;t want your users to change their passwords in their first login, leave this set to &#039;&#039;No&#039;&#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Use standard Change Password Page&lt;br /&gt;
|&lt;br /&gt;
* Setting this to &#039;&#039;Yes&#039;&#039; makes Moodle use it&#039;s own standard password change page, everytime users want to change their passwords.&lt;br /&gt;
* Setting this to &#039;&#039;No&#039;&#039; makes Moodle use the the page specified in the field called &amp;quot;Password change URL&amp;quot; (see below).&lt;br /&gt;
&lt;br /&gt;
Bear in mind that changing your LDAP passwords from Moodle might require a LDAPS connection (this is actually a requirement for MS-AD). In addition to that, the bind user specified above must have the rights needed to change other users&#039; passwords.&lt;br /&gt;
&lt;br /&gt;
Also, code for changing passwords from Moodle for anything but Novell eDirectory and Active Directory is almost not tested, so this may or may not work for other LDAP servers.&lt;br /&gt;
|-&lt;br /&gt;
| Password Format&lt;br /&gt;
| Specify how the new password is encrypted before sending it to the LDAP server: Plain text, MD5 hash or SHA-1 hash. MS-AD uses plain text, for example.&lt;br /&gt;
|-&lt;br /&gt;
| Password change URL&lt;br /&gt;
| Here you can specify a location at which your users can recover or change their username/password if they&#039;ve forgotten it. This will be provided to users as a button on the login page and their user page. if you leave this blank the button will not be printed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====LDAP password expiration settings====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Expiration&lt;br /&gt;
| &lt;br /&gt;
* Setting this to &#039;&#039;No&#039;&#039; will make Moodle not to check if the password of the user has expired or not.&lt;br /&gt;
* Setting this to &#039;&#039;LDAP&#039;&#039; will make Moodle check if the LDAP password of the user has expired or not, and warn her a number of days before the password expires.&lt;br /&gt;
&lt;br /&gt;
Current code only deals with Novell eDirectory LDAP server and MS-AD.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;So unless you have Novell eDirectory server or MS-AD, choose &#039;&#039;No&#039;&#039; here.&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Expiration warning&lt;br /&gt;
| This value sets how many days in advance of password expiration the user is warned that her password is about to expire.&lt;br /&gt;
|-&lt;br /&gt;
| Expiration attribute.&lt;br /&gt;
| The LDAP user attribute used to check password expiration. This option takes a default value based on the &#039;&#039;User type&#039;&#039; value you choosed above. &amp;lt;u&amp;gt;So unless you need something special, you don&#039;t need to fill this in.&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Grace logins&lt;br /&gt;
| This setting is specific to Novell eDirectory. If set to &#039;&#039;Yes&#039;&#039;, enable LDAP gracelogin support. After password has expired the user can login until gracelogin count is 0.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;So unless you have Novell eDirectory server and want to allow gracelogin support, choose &#039;&#039;No&#039;&#039; here.&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Grace login attribute&lt;br /&gt;
| This setting is currently not used in the code (and is specific to Novell eDirectory). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;So you don&#039;t need to fill this in.&amp;lt;/u&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====Enable user creation====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Create users externally&lt;br /&gt;
| New (anonymous) users can self-create user accounts on the external LDAP server and confirm them via email. If you enable this, remember to also configure module-specific options for user creation and to fill in some instructions in &#039;&#039;auth_instructions&#039;&#039; field in Administration &amp;gt;&amp;gt; Users &amp;gt;&amp;gt; Authentication &amp;gt;&amp;gt; Manage authentication. Otherwise the new users won&#039;t be able to self-create new accounts.&lt;br /&gt;
&lt;br /&gt;
As of now, only Novell eDirectory and MS-AD can create users externally.&lt;br /&gt;
|-&lt;br /&gt;
| Context for new users&lt;br /&gt;
| Specify the context where users are created. This context should be different from other users&#039; contexts to prevent security issues. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====Course creation====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Creators&lt;br /&gt;
| The DN of the group that contains all of your Moodle creators. This is typically a posixGroup with a &amp;quot;memberUid&amp;quot; attribute for each user you want to be a creator.  If your group is called &#039;&#039;creators&#039;&#039;, type &#039;&#039;&#039;cn=creators,ou=moodleusers,dc=my,dc=organization,dc=domain&#039;&#039;&#039; here.  Each memberUid attribute contains the CN of a user who is authorized to be a creator.  Do not use the user&#039;s full DN (e.g.,  not &#039;&#039;&#039;memberUid: cn=JoeTeacher,ou=moodleusers,dc-my,dc=organizations,dc=domain&#039;&#039;&#039;, but rather &#039;&#039;&#039;memberUid: JoeTeacher&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
In eDirectory, the objectClass for a group is (by default) not &#039;&#039;&#039;posixGroup&#039;&#039;&#039; but &#039;&#039;&#039;groupOfNames,&#039;&#039;&#039; whose member attribute is &#039;&#039;&#039;member,&#039;&#039;&#039; not &#039;&#039;&#039;memberUid,&#039;&#039;&#039; and whose value is the full DN of the user in question.  Although you can probably modify Moodle&#039;s code to use this field, a better solution is just to add a new &#039;&#039;&#039;objectClass&#039;&#039;&#039; attribute of &#039;&#039;&#039;posixGroup&#039;&#039;&#039; to your creators group and put the CNs for each creator in a &#039;&#039;&#039;memberUid&#039;&#039;&#039; attribute.&lt;br /&gt;
&lt;br /&gt;
In MS Active Directory, you will need to create a security group for your creators to be part of and then add them all. If your ldap context above is &#039;ou=staff,dc=my,dc=org&#039; then your group should then be &#039;cn=creators,ou=staff,dc=my,dc=org&#039;. If some of the users are from other contexts and have been added to the same security group, you&#039;ll have to add these as separate contexts after the first one using the same format.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====Cron synchronization script====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Removed ext user&lt;br /&gt;
| Specify what to do with internal user account during mass synchronization when user was removed from external source. Only suspended users are automatically revived if they reappear in ext source.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====NTLM SSO====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Enable&lt;br /&gt;
| If you want to use NTLM SSO (see details at [[NTLM_authentication]]), choose &#039;&#039;Yes&#039;&#039; here. Otherwise, choose &#039;&#039;No&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| Subnet&lt;br /&gt;
| Specify the subnets of the clients that will use NTLM SSO (see details at [[NTLM_authentication]]).&lt;br /&gt;
|-&lt;br /&gt;
| MS IE Fast Path?&lt;br /&gt;
| If all of you clients (or most of them) are using MS Internet Explorer, you can set this option to bypasses certain steps of the SSO login and speed up login times. This only works with MS Internet Explorer, but deals with other browsers in a sensible way (they are automatically sent to the plain login page).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====Data Mapping====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| First name&lt;br /&gt;
| The name of the attribute that holds the first name of your users in your LDAP server. This is usually &#039;&#039;&#039;givenName&#039;&#039;&#039; or &#039;&#039;&#039;displayName&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Surname&lt;br /&gt;
| The name of the attribute that holds the surname of your users in your LDAP server. This is usually &#039;&#039;&#039;sn&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Email address&lt;br /&gt;
| The name of the attribute that holds the email address of your users in your LDAP server. This is usually &#039;&#039;&#039;mail&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| City/town&lt;br /&gt;
| The name of the attribute that holds the city/town of your users in your LDAP server. This is usully &#039;&#039;&#039;l&#039;&#039;&#039; (lowercase L) or &#039;&#039;&#039;localityName&#039;&#039;&#039; (not valid in MS-AD).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| Country&lt;br /&gt;
| The name of the attribute that holds the country of your users in your LDAP server. This is usully &#039;&#039;&#039;c&#039;&#039;&#039; or &#039;&#039;&#039;countryName&#039;&#039;&#039; (not valid in MS-AD).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Language&lt;br /&gt;
| &#039;&#039;&#039;preferredLanguage&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| &#039;&#039;&#039;description&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Webpage&lt;br /&gt;
| &amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| ID Number&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Institution&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Department&lt;br /&gt;
| The name of the attribute that holds the department name of your users in your LDAP server. This is usully &#039;&#039;&#039;departmentNumber&#039;&#039;&#039; (for posixAccount and maybe eDirectory) or &#039;&#039;&#039;department&#039;&#039;&#039; (for MS-AD).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Phone 1&lt;br /&gt;
| The name of the attribute that holds the telephone number of your users in your LDAP server. This is usually &#039;&#039;&#039;telephoneNumber&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Phone 2&lt;br /&gt;
|  The name of the attribute that holds an additional telephone number of your users in your LDAP server. This can be &#039;&#039;&#039;homePhone&#039;&#039;&#039;, &#039;&#039;&#039;mobile&#039;&#039;&#039;, &#039;&#039;&#039;pager&#039;&#039;&#039;, &#039;&#039;&#039;facsimileTelephoneNumber&#039;&#039;&#039; or even others.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Address&lt;br /&gt;
| The name of the attribute that holds the street address of your users in your LDAP server. This is usully &#039;&#039;&#039;streetAddress&#039;&#039;&#039; or &#039;&#039;&#039;street&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
===Setting up regular automatic synchronisation using cron===&lt;br /&gt;
There is a script located at /auth/ldap/auth_ldap_sync_users.php which will create or suspend/delete (see the setting above) all LDAP accounts automatically. Ideally, this is called from the command line once a day during a quiet time using exactly the same procedure as the standard [[Cron|cron]] job (so you will end up with two cron entries). It is important, however, to make sure that all of the above LDAP settings are working properly before you try this, as well as backing up your database and moodledata folders. Poor LDAP configuration could lead to users being wrongly deleted.&lt;br /&gt;
&lt;br /&gt;
If you find that the script is not running through all of your users properly and you have MS Active Directory + over 1000 users, this is because by default, MS AD only sends back 1000 users at a time. Follow the instructions [http://support.microsoft.com/kb/315071 here] to set the MaxPageSize setting to a number higher than your total number of users (both now and in future) to fix it. This is a forest-wide setting.&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
==Active Directory help==&lt;br /&gt;
[[Active Directory]] is Microsoft&#039;s directory service. It is included in Windows 2000 Server and later versions of their operating system. For more information about subjects below, &#039;&#039;&#039;[[Active Directory|please go here]]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
*Warning: The PHP LDAP module does not seem to be present&lt;br /&gt;
*LDAP-module cannot connect any LDAP servers &lt;br /&gt;
*Getting correct CNs for Contexts and Creators&lt;br /&gt;
*Getting the right user_attribute&lt;br /&gt;
*Installing ldp.exe Server Tool&lt;br /&gt;
*Example Active Directory Configuration&lt;br /&gt;
*Child Domains and the Global Catalog in MS Active Directory&lt;br /&gt;
*Enabling the Global Catalog&lt;br /&gt;
*Active Directory with Moodle 1.8&lt;br /&gt;
*MS Active Directory + SSL&lt;br /&gt;
&lt;br /&gt;
==Advanced Scenarios - Multiple servers or locations==&lt;br /&gt;
For larger installations with  multiple LDAP servers, or multiple locations (contexts) in a LDAP tree.&lt;br /&gt;
&lt;br /&gt;
===Using multiple LDAP Servers===&lt;br /&gt;
Entering more than one name in the ldap_host_url field can provide some sort of resilience to your system. Simply use the syntax :&lt;br /&gt;
ldap://my.first.server ; ldap://my.second.server ; ...&lt;br /&gt;
&lt;br /&gt;
Of course, this will only work if all the servers share the same directory information, using a replication or synchronization mecanism once introduced in eDirectory and now generalized to the main LDAP-compatible directories.&lt;br /&gt;
&lt;br /&gt;
There is one drawback in Moodle 1.5 - 1.6 implementation of LDAP authentication : the auth_ldap_connect() function processes the servers sequentially, not in a round robin mode. Thus, if the primary server fails, you will have to wait for the connection to time out before switching to the following one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See also: [http://moodle.org/mod/forum/discuss.php?d=17198 Using multiple LDAP servers - Our students are on separate domain] discussion on the Using Moodle forum.&lt;br /&gt;
&lt;br /&gt;
===Using multiple user locations (contexts) in your LDAP tree===&lt;br /&gt;
There is no need to use multiple user locations if your directory tree is flat, i.e. if all user accounts reside in a &#039;&#039;&#039;ou=people,dc=my,dc=organization,dc=domain&#039;&#039;&#039; or &#039;&#039;&#039;ou=people,o=myorg&#039;&#039;&#039; container. &lt;br /&gt;
&lt;br /&gt;
At the opposite, if you use the ACL mecanism to delegate user management, there are chances that your users will be stored in containers like &#039;&#039;&#039;ou=students,ou=dept1,o=myorg&#039;&#039;&#039; and &#039;&#039;&#039;ou=students,ou=dept2,o=myorg&#039;&#039;&#039; ...&lt;br /&gt;
&lt;br /&gt;
Then there is an alternative :&lt;br /&gt;
* Look at the &#039;&#039;&#039;o=myorg&#039;&#039;&#039; level with the ldap_search_sub attribute set to &#039;&#039;&#039;yes&#039;&#039;&#039;.&lt;br /&gt;
* Set the ldap_context to &#039;&#039;&#039;ou=students,ou=dept1,o=myorg ; ou=students,ou=dept2,o=myorg&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Choosing between these two solutions supposes some sort of benchmarking, as the result depends heavily on the structure of your directory tree &#039;&#039;&#039;and&#039;&#039;&#039; on your LDAP software indexing capabilities. Simply note that there is a probability in such deep trees that two users share the same &#039;&#039;common name&#039;&#039; (cn), while having different &#039;&#039;distinguished names&#039;&#039;. Then only the second solution will have a deterministic result (returning allways the same user).&lt;br /&gt;
&lt;br /&gt;
===Using LDAPS (LDAP + SSL)===&lt;br /&gt;
====Enabling LDAPS on the LDAP server side====&lt;br /&gt;
&lt;br /&gt;
* [[Active_Directory#MS_Active_Directory_.2B_SSL|Enabling LDAPS on MS Active Directory ]]&lt;br /&gt;
&lt;br /&gt;
====Enabling LDAPS on the client side (Moodle server)====&lt;br /&gt;
&lt;br /&gt;
* If you are running Moodle on MS Windows, you need to tell PHP&#039;s OpenLDAP extension to disable SSL server certificate checking. You must create a directory called &#039;&#039;C:\OpenLDAP\sysconf&#039;&#039;. In this directory, create a file called &#039;&#039;ldap.conf&#039;&#039; with the following content (If you are using certain versions of PHP 5.3.x you may need to place the file at other locations, [http://bugs.php.net/bug.php?id=48866 see PHP bug #48866]):&lt;br /&gt;
&lt;br /&gt;
 TLS_REQCERT never&lt;br /&gt;
&lt;br /&gt;
* If you are running Moodle on Linux or any other Unix-like operating system, and you want to disable SSL server certificate checking, you need to edit the OpenLDAP client configuration file (usually /etc/ldap.conf or /etc/ldap/ldap.conf or even /etc/openldap/ldap.conf) and make sure you have a line like the following one:&lt;br /&gt;
&lt;br /&gt;
 TLS_REQCERT never&lt;br /&gt;
&lt;br /&gt;
Now you should be able to use &#039;&#039;&#039;ldaps://&#039;&#039;&#039; when connecting to your LDAP server.&lt;br /&gt;
&lt;br /&gt;
If you have the certificate of the LDAPS server as a file and want to check the certificate for the connection, copy the certificate file to an arbitary directory (e.g. /etc/ldap/certificate.pem) on your client and change the content of the &#039;&#039;ldap.conf&#039;&#039; as follows:&lt;br /&gt;
&lt;br /&gt;
 TLS_REQCERT demand&lt;br /&gt;
 TLS_CACERT  /etc/ldap/certificate.pem&lt;br /&gt;
&lt;br /&gt;
When the requested server certificate is bad or not provided, the connection to the LDAPS server is immediately terminated.&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
==Appendices==&lt;br /&gt;
===ldap auth_user_create() only suports Novell===&lt;br /&gt;
&lt;br /&gt;
After configuring user authentication with ldap I realized ldap only support edir (Novell) when combining ldap an email user confirmation. For example in my case (I use openldap) I have the following error after filling the user form:&lt;br /&gt;
&lt;br /&gt;
auth: ldap auth_user_create() does not support selected usertype:&amp;quot;rfc2307&amp;quot; (..yet)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Setting Resource Limits RedHat Directory Server ===&lt;br /&gt;
&lt;br /&gt;
Operational attributes can be set for the bind user DN using the command-line. &lt;br /&gt;
One can simply use ldapmodify to add the following attributes:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Attribute Name &lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| nsLookThroughLimit&lt;br /&gt;
| Specifies how many entries are examined for a search operation. Giving this attribute a value of -1 indicates that there is no limit.&lt;br /&gt;
|-&lt;br /&gt;
| nsSizeLimit &lt;br /&gt;
| Specifies the maximum number of entries the server returns to a client application in response to a search operation. Giving this attribute a value of -1 indicates that there is no limit.&lt;br /&gt;
|-&lt;br /&gt;
| nsTimeLimit &lt;br /&gt;
| Specifies the maximum time the server spends processing a search operation. Giving this attribute a value of -1 indicates that there is no time limit.&lt;br /&gt;
|-&lt;br /&gt;
| nsIdleTimeout 	        &lt;br /&gt;
| Specifies the time a connection to the server can be idle before the connection is dropped. The value is given in seconds. Giving this attribute a value of -1 indicates that there is no limit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt; LDAP Console Command-Line&lt;br /&gt;
&lt;br /&gt;
 ldapmodify -h redhat_dir_server -p 389 -D &amp;quot;cn=directory manager&amp;quot; -w secretpwd&lt;br /&gt;
&lt;br /&gt;
 dn: uid=MoodleAdmin,ou=system,dc=myschool,dc=edu&lt;br /&gt;
 changetype: modify&lt;br /&gt;
 add:nsSizeLimit&lt;br /&gt;
 nsSizeLimit: 1000&lt;br /&gt;
 &amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[NTLM_authentication]]&lt;br /&gt;
* [[Active_Directory]]&lt;br /&gt;
* [[LDAP enrolment]]&lt;br /&gt;
* [http://download.moodle.org/download.php/docs/en/how-to_guides/ldap_auth_and_enrolment_set-up.pdf LDAP auth and enrolment set-up guide] (PDF 227KB)&lt;br /&gt;
&lt;br /&gt;
Using Moodle:&lt;br /&gt;
* [http://moodle.org/mod/forum/view.php?id=42 User authentication forum]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=32168 PHP LDAP module does not seem to be present] forum discussion&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=140901 Syncronisation with AUTH_LDAP_SYNC_USERS.PHP produces fewer accounts than it should] forum discussion&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=17198 Using multiple LDAP servers] forum discussion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Authentication]]&lt;br /&gt;
&lt;br /&gt;
[[es:LDAP_authentication]]&lt;br /&gt;
[[fr:Utiliser un serveur LDAP]]&lt;br /&gt;
[[ja:LDAP認証]]&lt;br /&gt;
[[zh:LDAP认证]]&lt;br /&gt;
[[de:Authentifizierung über LDAP]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Active_Directory&amp;diff=76891</id>
		<title>Active Directory</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Active_Directory&amp;diff=76891"/>
		<updated>2010-10-20T14:02:35Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* See also: Using multiple LDAP servers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Microsoft&#039;s Active Directory (AD) provides a variety of network directory services including Lightweight Directory Access Protocol (LDAP) like functions.  It is included in Windows 2000 Server and later versions of their operating system.   The focus of this page will be with the [[LDAP authentication]] functions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Trouble shooting AD and LDAP authentication==&lt;br /&gt;
===Warning: The PHP LDAP module does not seem to be present. Please ensure it is installed and enabled.===&lt;br /&gt;
This usually means that the main ldap dll or one of the supporting dlls are missing.&lt;br /&gt;
Let&#039;s start with the main one itself. &lt;br /&gt;
Browse to &amp;lt;nowiki&amp;gt;http://(moodleserver)/admin/phpinfo.php&amp;lt;/nowiki&amp;gt; and examine the &amp;quot;Configuration File (php.ini) Path&amp;quot; field to determine which php.ini is being used and open it with an editor. Find the line &#039;extension=php_ldap.dll&#039; and take out the semi-colon if it is there. That semi-colon will stop it loading the module all together! &lt;br /&gt;
While you have that file open, search for &#039;extension_dir&#039; and note which folder it is set to. Open that folder and ensure the php_ldap.dll file is in there. If it isn&#039;t then put it in there.&lt;br /&gt;
If that still hasn&#039;t fixed it you are missing a supporting dll, but you don&#039;t get told that. To see what dlls are missing open the Command Prompt and navigate to the php directory and execute the following line &#039;php -m&#039;. You should get some error messages now. Ugly, but at least they give you information! Find the dlls listed and copy them to the php directory. You may now need to restart the apache/httpd service. Run &#039;php -m&#039; again and you should be error free and the message in Moodle should be gone now.&lt;br /&gt;
&lt;br /&gt;
===LDAP-module cannot connect any LDAP servers===&lt;br /&gt;
 LDAP-module cannot connect any LDAP servers: &lt;br /&gt;
 Server: &#039;ldap://my.ldap.server/&#039; &lt;br /&gt;
 Connection: &#039;Resource id #26&#039; Bind result: &#039;&#039;&lt;br /&gt;
Getting this message when you are trying to log in is a result of incorrect details for the Bind user, or the user account having insufficient permissions in Active Directory. The best way to test and resolve this is use ldp.exe to test binding until it suceeds. There are instructions on installing ldp.exe below.&lt;br /&gt;
Open the program and Connect to AD, giving the server name, then from the Connection menu choose Bind. Enter the details you think are correct and you will probably find that an error is returned. Try adjusting the accounts priveleges or another account until you are returned an &amp;quot;Authenticated as&amp;quot; message.&lt;br /&gt;
Once you are sure your account can be used to bind to AD, check that the DN of that users name is correct. Expand the tree on the left until you find the user you used to bind. Right click on that item and choose Copy DN. Go to the User Authentication page in Moodle and paste the value into the ldap_bind_dn field. Add the password and you can now feel safe your user is binding sucessfully.&lt;br /&gt;
&lt;br /&gt;
===Getting correct CNs for Contexts and Creators===&lt;br /&gt;
For those not familiar with AD this could be very confusing, and not that easy for some who are familiar with it. Again, ldp.exe is your friend. There are instructions on installing ldp.exe below.&lt;br /&gt;
Open it up and expand the tree on the left until you find the group or user you want to use and right click on it and select Copy DN. Go back to the Moodle User Authentication page and paste that value into either ldap_contexts or ldap_creators.&lt;br /&gt;
&lt;br /&gt;
===Getting the right user_attribute===&lt;br /&gt;
By default, Moodle uses an accounts cn (full name) to verify against, but most networks don&#039;t use a full given name for logon as it&#039;s too easy to guess and you can easily have two people with the same name. If this is the case for you too you need to tell Moodle to look at another field for the logon id.&lt;br /&gt;
In ldp.exe navigate the tree on the left to find a user account, preferably your own. Double-click the item in the tree and full-details will be loaded into the screen on the right. Look down the details until you find your logon id and note the item listed against it. For me, and a lot of people, it is sAMAccountName. Copy this name and paste it into the ldap_user_attribute on the Moodle User Authentication page.&lt;br /&gt;
There are instructions on installing ldp.exe below.&lt;br /&gt;
&lt;br /&gt;
===Installing ldp.exe Server Tool===&lt;br /&gt;
ldp.exe comes as part of the Server Tools on most versions of Windows Server. Find your Windows Server installation disc and find a folder on it called Support\Tools. In there will be a SupTools.msi which will install the server tools if run. You should now have a folder under Program Files called Support Tools, in which will be ldp.exe. ldp.exe is also available in the Windows XP Support Tools, which you can download from Microsoft [http://www.microsoft.com/downloads/details.aspx?FamilyId=49AE8576-9BB9-4126-9761-BA8011FABF38&amp;amp;displaylang=en here]. Alternatively, a single download of ldp.exe is available [http://www.computerperformance.co.uk/w2k3/utilities/ldp.htm here].&lt;br /&gt;
&lt;br /&gt;
===Example Active Directory Configuration===&lt;br /&gt;
Below is an example configuration for Active Directory. As detailed above, the values may vary based on your local Active Directory configuration, but should provide a good starting point for most cases.&lt;br /&gt;
&lt;br /&gt;
 ldap_host_url = ldap://ads.example.com&lt;br /&gt;
 ldap_version = 3&lt;br /&gt;
 ldap_preventpassindb = yes&lt;br /&gt;
 ldap_bind_dn = bind-user@example.com&lt;br /&gt;
 ldap_bind_pw = bind-password&lt;br /&gt;
 ldap_user_type = MS ActiveDirectory&lt;br /&gt;
 ldap_contexts = ou=moodleusers,dc=example,dc=com&lt;br /&gt;
 ldap_user_attribute = sAMAccountName&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that the ldap_bind_dn value should work in either the CN=bin-user,CN=Users,DC=example,DC=com format as shown in the main instructions or the bind-user@example.com format shown in this example.&lt;br /&gt;
&lt;br /&gt;
==Global Catalogs==&lt;br /&gt;
Moodle currently only has limited support for multiple domain controllers; specifically it expects each of the LDAP servers listed to contain identical sets of information. If you have users in multiple domains this presents an issue. One solution when working with MS-AD is to use the Global Catalog. The Global Catalog is designed to be a read-only, partial representation of an entire MS-AD forest, designed for searching the entire directory when the domain of the required object is not known.&lt;br /&gt;
&lt;br /&gt;
===Enabling the Global Catalog===&lt;br /&gt;
&lt;br /&gt;
The Global Catalog is available on Windows 2000 and Windows 2003 Active Directory servers. To enable, open the ‘Active Directory Sites and Services’ MMC (Microsoft Management Console) snap-in. Extend ‘Sites’ and then the name of the Site containing the active directory forest you wish to use. Expand the server you wish to enable the Global Catalog on, right click ‘NTDS settings’ and select the ‘Properties’ tab. To enable, simply click the ‘Global Catalog’ checkbox. Under a Windows 2000 server it is necessary to restart the server (although it won’t prompt you to); under Windows 2003 server it is not necessary to restart the server. In either case you will generally have to wait for the AD forest to replicate before the Global Catalog offers a representation of the entire AD forest. Changes made in Active Directory will also be subject to a short delay due to the latency involved with replication. If your AD servers are firewalled port 3268 will need to be opened for Global Catalog servers.&lt;br /&gt;
If your organisation uses Microsoft Exchange then it its highly likely that at least one Domain Controller will already have Global Catalog enabled – Exchange 2000 and 2003 rely on the Global Catalog for address information, users also access the Global Catalog when using the GAL (Global Address List)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Child Domains===&lt;br /&gt;
If your organisation has a main domain example.org, staff and students are contained in two child domains staff.example.org and students.example.org. The 3 domains (example.org, staff.example.org and students.example.org) each have a domain controller (dc01, dc02 and dc03 respectively.) Each domain controller contains a full, writable, representation of only the objects that belong to its domain. However, assuming that the Global Catalog has been enabled (see below) on one of the domain controllers (for example dc01) a query to the Global Catalog would reveal matching objects from all three domains. The Global Catalog is automatically maintained through replication across the active directory forest, it can also be enabled on multiple servers (if, for example, you need redundancy / load balancing.)&lt;br /&gt;
&lt;br /&gt;
To make use of this in Moodle to allow logins from multiple domains is simple. The Global Catalog runs on port 3268 as opposed to 389 for standard LDAP queries. As a result, still assuming the Global Catalog is running on dc01, the &#039;&#039;&#039;&#039;ldap_host_url&#039;&#039;&#039;&#039; would be &#039;&#039;ldap://dc01.example.org:3268&#039;&#039;. The rest of the settings are the same as for other MS-AS Auth setups.&lt;br /&gt;
&lt;br /&gt;
You should use the &#039;&#039;&#039;&#039;ldap_contexts&#039;&#039;&#039;&#039; setting to indicate the locations of individuals you wish to grant access. To extend the example above a little: In the example.org domain users are all in the&#039;&#039; &#039;Users&#039; &#039;&#039;OU, in the staff.example.org domain users are in two OUs at the root of the domain,&#039;&#039; &#039;Support Staff&#039; &#039;&#039;and&#039;&#039; &#039;Teaching Staff&#039; &#039;&#039;, and in the students.example.org domain students are in an OU indicating the year that they enrolled, all of which are under the&#039;&#039; &#039;Students&#039; &#039;&#039;OU. As a result our &#039;&#039;&#039;&#039;ldap_contexts&#039;&#039;&#039;&#039; setting may look a little like this:&#039;&#039; &#039;OU=Users,DC=example,DC=org; OU=Support Staff,DC=staff,DC=example,DC=org; OU=Teaching Staff,DC=staff,DC=example,DC=org; OU=Students,DC=students,DC=example,DC=org&#039;&#039;.&#039; The &#039;&#039;&#039;&#039;ldap_search_sub&#039;&#039;&#039;&#039; option should be set to&#039;&#039; &#039;Yes&#039; &#039;&#039;to allow moodle to search within the child OUs.&lt;br /&gt;
&lt;br /&gt;
Its worth noting that the Global Catalog only contains a partial representation of the attributes of each object, as defined in the Partial Attribute Set supplied by Microsoft. However common information likely to be of use to a general Moodle installation (Forename, Surname, Email Address, sAMAccountName etc) is included in the set. For specific needs the schema can be altered to remove or add various attributes - see Microsoft [http://support.microsoft.com/kb/248717 KB248717] for more information.&lt;br /&gt;
&lt;br /&gt;
In most cases the Global Catalog is read-only, update queries must be made over the standard LDAP ports to the domain controller that holds the object in question (in our example, updating a student&#039;s details would require an LDAP query to the students.example.org domain controller - dc03, it would not be possible to update details by querying the Global Catalog.) The exception to this would be in an environment where there is only a single domain in the active directory forest; in this case the Global Catalog holds a writable full set of attributes for each object in the domain. However, for the purposes of Moodle authorisation, there would be no need to use the Global Catalog in this case.&lt;br /&gt;
&lt;br /&gt;
===MaxPageSize setting===&lt;br /&gt;
Modifying the number of Active Directory objects to search: &lt;br /&gt;
&lt;br /&gt;
By default Active Directory only allows searches returning a limited number of objects per search. Since there is currently no Page control support in PHP 5.2.x which would enable smaller page searches you may need to modify your MaxPageSize setting to make sure LDAP Client searches can return enough user objects to support the number of authenticating users. &lt;br /&gt;
&lt;br /&gt;
If you find that the script is not running through all of your users properly and you have MS Active Directory + over 1000 users, follow the instructions [http://support.microsoft.com/kb/315071 here] to set the MaxPageSize setting to a number higher than your total number of users (both now and in future) to fix it.  This is a forest-wide setting.&lt;br /&gt;
&lt;br /&gt;
== Active Directory with Moodle 1.8==&lt;br /&gt;
There is an issue with the PHP ldap options that are required for Active Directory access in version 1.8 of Moodle. &lt;br /&gt;
&lt;br /&gt;
Using moodle on a LAMP platform with authentication to Active Directory may give some errors. &lt;br /&gt;
&lt;br /&gt;
Check this bug [http://tracker.moodle.org/browse/MDL-10921 MDL-10921] or this post http://moodle.org/mod/forum/discuss.php?d=78316 for further information.&lt;br /&gt;
&lt;br /&gt;
==MS Active Directory + SSL ==&lt;br /&gt;
&lt;br /&gt;
If the Certificate Authority is not installed you&#039;ll have to install it first as follows:&lt;br /&gt;
# Click &#039;&#039;&#039;Start&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Control Panel&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Add or Remove programs.&#039;&#039;&#039;&lt;br /&gt;
# Click &#039;&#039;&#039;Add/Remove Windows Components&#039;&#039;&#039; and select &#039;&#039;&#039;Certificate Services.&#039;&#039;&#039;&lt;br /&gt;
# Follow the procedure provided to install the &#039;&#039;&#039;Certificate Authority&#039;&#039;&#039;. Enterprise level is a good choice.&lt;br /&gt;
&lt;br /&gt;
Verify that SSL has been enabled on the server by installing suptools.msi from Windows installation cd&#039;s \Support\tools directory. After support tools installation:&lt;br /&gt;
# Select &#039;&#039;&#039;Start&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Run&#039;&#039;&#039;, write &#039;&#039;&#039;ldp&#039;&#039;&#039; in the Open field.&lt;br /&gt;
# From the ldp window select &#039;&#039;&#039;Connection&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Connect&#039;&#039;&#039; and supply valid hostname and port number &#039;&#039;&#039;636&#039;&#039;&#039;. Also select the SSL check box.&lt;br /&gt;
&lt;br /&gt;
If successful, you should get information about the connection.&lt;br /&gt;
&lt;br /&gt;
See [[LDAP_authentication#Enabling_LDAPS_on_the_client_side_.28Moodle_server.29|Enabling LDAPS on the client side (Moodle server)]] for details on the client side configuration.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[[LDAP authentication]] in Moodle&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Directory_service Directory services] overview in Wikipedia&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol LDAP] in Wikipedia&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=17198 Using multiple LDAP servers - Our students are on separate domain] Using Moodle forum discussion&lt;br /&gt;
&lt;br /&gt;
[[ja:Active Directory]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=LDAP_authentication&amp;diff=76890</id>
		<title>LDAP authentication</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=LDAP_authentication&amp;diff=76890"/>
		<updated>2010-10-20T14:00:43Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Multiple LDAP servers See Also link */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 1.9}}&lt;br /&gt;
Location: Settings link in &#039;&#039;Administration &amp;gt; Users &amp;gt; [[Authentication]] &amp;gt; LDAP Server&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This document describes how to set up Lightweight Directory Access Protocol (LDAP) authentication in Moodle.  We cover the basic, advanced and some trouble shooting sections to assist the user in the installation and administrating LDAP in Moodle.  &lt;br /&gt;
==Table of Contents==&lt;br /&gt;
__TOC__&lt;br /&gt;
==Basic Scenario==&lt;br /&gt;
The simple and straightforward approach  for most installations.&lt;br /&gt;
&lt;br /&gt;
===Assumptions===&lt;br /&gt;
&lt;br /&gt;
# Your Moodle site is located at &#039;&#039;&#039;http://your.moodle.site/&#039;&#039;&#039;&lt;br /&gt;
# You have configured your PHP installation with the LDAP extension. It is loaded and activated, and it shows when you go to &#039;&#039;&#039;http://your.moodle.site/admin/phpinfo.php&#039;&#039;&#039; (logged in as user &#039;admin&#039;).&lt;br /&gt;
# Your LDAP server has &#039;&#039;&#039;192.168.1.100&#039;&#039;&#039; as its IP address.&lt;br /&gt;
# You are not using LDAP with SSL (also known as LDAPS) in your settings. This might prevent certain operations from working (e.g., you cannot update data if you are using MS Active Directory -- MS-AD from here on --), but should be OK if you just want to authenticate your users.&lt;br /&gt;
# You don&#039;t want your users to change their passwords the first time they log in into Moodle.&lt;br /&gt;
# You are using a single domain as the source of your authentication data in case you are using MS-AD (more on this in the Appendices).&lt;br /&gt;
# You are using a top level distinguished name (DN) of &#039;&#039;&#039;dc=my,dc=organization,dc=domain&#039;&#039;&#039; as the root of your LDAP tree. &lt;br /&gt;
# You have a non-privileged LDAP user account you will use to bind to the LDAP server. This is not necessary with certain LDAP servers, but MS-AD requires this and it won&#039;t hurt if you use it even if your LDAP server doesn&#039;t need it. Make sure &#039;&#039;&#039;this account and its password don&#039;t expire&#039;&#039;&#039;, and make this password as strong as possible. Remember you only need to type this password once, when configuring Moodle, so don&#039;t be afraid of making it as hard to guess as possible. Let&#039;s say this user account has a DN of &#039;&#039;&#039;cn=ldap-user,dc=my,dc=organization,dc=domain&#039;&#039;&#039;, and password &#039;&#039;&#039;hardtoguesspassword&#039;&#039;&#039;.&lt;br /&gt;
# All of your Moodle users are in an organizational unit (OU) called &#039;&#039;&#039;moodleusers&#039;&#039;&#039;, which is right under your LDAP root. That OU has a DN of &#039;&#039;&#039;ou=moodleusers,dc=my,dc=organization,dc=domain&#039;&#039;&#039;.&lt;br /&gt;
# You &#039;&#039;&#039;don&#039;t&#039;&#039;&#039; want your LDAP users&#039; passwords to be stored in Moodle at all.&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
===Configuring Moodle authentication===&lt;br /&gt;
&lt;br /&gt;
Log in as an admin user and go to Administration &amp;gt;&amp;gt; Users &amp;gt;&amp;gt; Authentication &amp;gt;&amp;gt; Manage authentication. In the table that appears, enable the &amp;quot;LDAP Server&amp;quot; authentication option (click on the closed eye to make it open) and then click on the associated &#039;Settings&#039; link. You will get a page similar to this one:&lt;br /&gt;
&lt;br /&gt;
[[Image:auth_ldap_config_screenshot.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Now, you just have to fill in the values. Let&#039;s go step by step.&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====LDAP Server Settings====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Host URL&lt;br /&gt;
| As the IP of your LDAP server is 192.168.1.100, type &amp;quot;&#039;&#039;&#039;ldap://192.168.1.100&#039;&#039;&#039;&amp;quot; (without the quotes), or just &amp;quot;&#039;&#039;&#039;192.168.1.100&#039;&#039;&#039;&amp;quot; (some people have trouble connecting with the first syntax, specially on MS Windows servers).&lt;br /&gt;
|-&lt;br /&gt;
| Version&lt;br /&gt;
| Unless you are using a really old LDAP server, &#039;&#039;&#039;version 3&#039;&#039;&#039; is the one you should choose.&lt;br /&gt;
|-&lt;br /&gt;
| LDAP Encoding&lt;br /&gt;
| Specify encoding used by LDAP server. Most probably utf-8.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====Bind settings====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Hide passwords&lt;br /&gt;
| As you &#039;&#039;&#039;don&#039;t&#039;&#039;&#039; want to store the users&#039;s password in Moodle&#039;s database, choose &#039;&#039;&#039;Yes&#039;&#039;&#039; here.&lt;br /&gt;
|-&lt;br /&gt;
| Distinguished Name&lt;br /&gt;
| This is the distinguished name of the bind user defined above. Just type &amp;quot;&#039;&#039;&#039;cn=ldap-user,dc=my,dc=organization,dc=domain&#039;&#039;&#039;&amp;quot; (without the quotes).&lt;br /&gt;
|-&lt;br /&gt;
| Password&lt;br /&gt;
| This is the bind user password defined above. Type &amp;quot;&#039;&#039;&#039;hardtoguesspassword&#039;&#039;&#039;&amp;quot; (without the quotes).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====User lookup settings====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| User type&lt;br /&gt;
| Choose: &lt;br /&gt;
* &#039;&#039;&#039;Novel Edirectory&#039;&#039;&#039; if your LDAP server is running Novell&#039;s eDdirectory.&lt;br /&gt;
* &#039;&#039;&#039;posixAccount (rfc2307)&#039;&#039;&#039; if your LDAP server is running a RFC-2307 compatible LDAP server (choose this is your server is running OpenLDAP, including Mac OS X server).&lt;br /&gt;
* &#039;&#039;&#039;posixAccount (rfc2307bis)&#039;&#039;&#039; if your LDAP server is running a RFC-2307bis compatible LDAP server.&lt;br /&gt;
* &#039;&#039;&#039;sambaSamAccount (v.3.0.7)&#039;&#039;&#039; if your LDAP server is running with SAMBA&#039;s 3.x LDAP schema extension and you want to use it.&lt;br /&gt;
* &#039;&#039;&#039;MS ActiveDirectory&#039;&#039;&#039; if your LDAP server is running Microsoft&#039;s Active Directory (MS-AD)&lt;br /&gt;
|-&lt;br /&gt;
| Contexts&lt;br /&gt;
| The DN of the context (container) where all of your Moodle users are found. Type &#039;&#039;&#039;ou=moodleusers,dc=my,dc=organization,dc=domain&#039;&#039;&#039; here.  &lt;br /&gt;
&lt;br /&gt;
On a Mac OS X Server, this is usually &#039;&#039;&#039;cn=users,dc=my,dc=organization,dc=domain&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| Search subcontexts&lt;br /&gt;
| If you have any sub organizational units (subcontexts) hanging from &#039;&#039;&#039;ou=moodleusers,dc=my,dc=organization,dc=domain&#039;&#039;&#039; and you want Moodle to search there too, set this to &#039;&#039;&#039;yes&#039;&#039;&#039;. Otherwise, set this to &#039;&#039;&#039;no&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| Dereference aliases&lt;br /&gt;
| Sometimes your LDAP server will tell you that the real value you are searching for is in fact in another part of the LDAP tree (this is called an alias). If you want Moodle to &#039;dereference&#039; the alias and fetch the real value from the original location, set this to &#039;&#039;&#039;yes&#039;&#039;&#039;. If you don&#039;t want Moodle to dereference it, set this to &#039;&#039;&#039;no&#039;&#039;&#039;. If you are using MS-AD, set this to &#039;&#039;&#039;no&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| User attribute&lt;br /&gt;
| The attribute used to name/search users in your LDAP tree. This option takes a default value based on the &#039;&#039;User type&#039;&#039; value you chose above. &amp;lt;u&amp;gt;So unless you need something special, you don&#039;t need to fill this in&amp;lt;/u&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
By the way, it&#039;s usually &#039;&#039;&#039;cn&#039;&#039;&#039; (Novell eDirectory and MS-AD) or &#039;&#039;&#039;uid&#039;&#039;&#039; (RFC-2037, RFC-2037bis and SAMBA 3.x LDAP extension), but if you are using MS-AD you could use &#039;&#039;&#039;sAMAccountName&#039;&#039;&#039; (the pre-Windows 2000 logon account name) if you need too.&lt;br /&gt;
|-&lt;br /&gt;
| Member attribute&lt;br /&gt;
| The attribute used to list the members of a given group. This option takes a default value based on the &#039;&#039;User type&#039;&#039; value you choosed above. &amp;lt;u&amp;gt;So unless you need something special, you don&#039;t need to fill this in.&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By the way, the usual values are &#039;&#039;&#039;member&#039;&#039;&#039; and &#039;&#039;&#039;memberUid&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| Member attribute uses dn&lt;br /&gt;
| Whether the member attribute contains distinguished names (1) or not (0).This option takes a default value based on the &#039;&#039;User type&#039;&#039; value you choosed above. &amp;lt;u&amp;gt;So unless you need something special, you don&#039;t need to fill this in.&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Object class&lt;br /&gt;
| The type of LDAP object used to search for users. This option takes a default value based on the &#039;&#039;User type&#039;&#039; value you chose above. &amp;lt;u&amp;gt;So unless you need something special, you don&#039;t need to fill this in.&amp;lt;/u&amp;gt;&lt;br /&gt;
* If you leave it blank, the filter &amp;quot;(objectClass=*)&amp;quot; will be used.&lt;br /&gt;
* If you provide &amp;quot;objectClass=some-string&amp;quot;, then it will provide &amp;quot;(objectClass=some-string)&amp;quot; as the filter.&lt;br /&gt;
* If you provide a value that does not start with &amp;quot;(&amp;quot;, it is assumed to be a value that should be set to &amp;quot;objectClass&amp;quot;. So if you provide &amp;quot;some-string&amp;quot;, then it will provide &amp;quot;(objectClass=some-string)&amp;quot; as the filter.&lt;br /&gt;
* If you provide a string that starts with a &amp;quot;(&amp;quot;, then it will pass that as is. So if you provide &amp;quot;(&amp;amp;(objectClass=user)(enabledMoodleUser=1))&amp;quot;, then it will pass that as the filter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here are the default values for each of the &#039;&#039;ldap_user_type&#039;&#039; values:&lt;br /&gt;
* &#039;&#039;&#039;User&#039;&#039;&#039; for Novel eDirectory&lt;br /&gt;
* &#039;&#039;&#039;posixAccount&#039;&#039;&#039; for RFC-2037 and RFC-2037bis&lt;br /&gt;
* &#039;&#039;&#039;sambaSamAccount&#039;&#039;&#039; for SAMBA 3.0.x LDAP extension&lt;br /&gt;
* &#039;&#039;&#039;user&#039;&#039;&#039; for MS-AD&lt;br /&gt;
If you get an error about a problem with updating the ldap server (even if you have specified not to write changes back to the ldap server) try setting the ldap object class to * - see http://moodle.org/mod/forum/discuss.php?d=70566 for a discussion on this problem&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====Force change password====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Force change password&lt;br /&gt;
| Set this to &#039;&#039;Yes&#039;&#039; if you want to force your users to change their password on the first login into Moodle. Otherwise, set this to &#039;&#039;no&#039;&#039;. Bear in mind the password they are forced to change is the one stored in your LDAP server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;As you don&#039;t want your users to change their passwords in their first login, leave this set to &#039;&#039;No&#039;&#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Use standard Change Password Page&lt;br /&gt;
|&lt;br /&gt;
* Setting this to &#039;&#039;Yes&#039;&#039; makes Moodle use it&#039;s own standard password change page, everytime users want to change their passwords.&lt;br /&gt;
* Setting this to &#039;&#039;No&#039;&#039; makes Moodle use the the page specified in the field called &amp;quot;Password change URL&amp;quot; (see below).&lt;br /&gt;
&lt;br /&gt;
Bear in mind that changing your LDAP passwords from Moodle might require a LDAPS connection (this is actually a requirement for MS-AD). In addition to that, the bind user specified above must have the rights needed to change other users&#039; passwords.&lt;br /&gt;
&lt;br /&gt;
Also, code for changing passwords from Moodle for anything but Novell eDirectory and Active Directory is almost not tested, so this may or may not work for other LDAP servers.&lt;br /&gt;
|-&lt;br /&gt;
| Password Format&lt;br /&gt;
| Specify how the new password is encrypted before sending it to the LDAP server: Plain text, MD5 hash or SHA-1 hash. MS-AD uses plain text, for example.&lt;br /&gt;
|-&lt;br /&gt;
| Password change URL&lt;br /&gt;
| Here you can specify a location at which your users can recover or change their username/password if they&#039;ve forgotten it. This will be provided to users as a button on the login page and their user page. if you leave this blank the button will not be printed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====LDAP password expiration settings====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Expiration&lt;br /&gt;
| &lt;br /&gt;
* Setting this to &#039;&#039;No&#039;&#039; will make Moodle not to check if the password of the user has expired or not.&lt;br /&gt;
* Setting this to &#039;&#039;LDAP&#039;&#039; will make Moodle check if the LDAP password of the user has expired or not, and warn her a number of days before the password expires.&lt;br /&gt;
&lt;br /&gt;
Current code only deals with Novell eDirectory LDAP server and MS-AD.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;So unless you have Novell eDirectory server or MS-AD, choose &#039;&#039;No&#039;&#039; here.&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Expiration warning&lt;br /&gt;
| This value sets how many days in advance of password expiration the user is warned that her password is about to expire.&lt;br /&gt;
|-&lt;br /&gt;
| Expiration attribute.&lt;br /&gt;
| The LDAP user attribute used to check password expiration. This option takes a default value based on the &#039;&#039;User type&#039;&#039; value you choosed above. &amp;lt;u&amp;gt;So unless you need something special, you don&#039;t need to fill this in.&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Grace logins&lt;br /&gt;
| This setting is specific to Novell eDirectory. If set to &#039;&#039;Yes&#039;&#039;, enable LDAP gracelogin support. After password has expired the user can login until gracelogin count is 0.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;So unless you have Novell eDirectory server and want to allow gracelogin support, choose &#039;&#039;No&#039;&#039; here.&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Grace login attribute&lt;br /&gt;
| This setting is currently not used in the code (and is specific to Novell eDirectory). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;So you don&#039;t need to fill this in.&amp;lt;/u&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====Enable user creation====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Create users externally&lt;br /&gt;
| New (anonymous) users can self-create user accounts on the external LDAP server and confirm them via email. If you enable this, remember to also configure module-specific options for user creation and to fill in some instructions in &#039;&#039;auth_instructions&#039;&#039; field in Administration &amp;gt;&amp;gt; Users &amp;gt;&amp;gt; Authentication &amp;gt;&amp;gt; Manage authentication. Otherwise the new users won&#039;t be able to self-create new accounts.&lt;br /&gt;
&lt;br /&gt;
As of now, only Novell eDirectory and MS-AD can create users externally.&lt;br /&gt;
|-&lt;br /&gt;
| Context for new users&lt;br /&gt;
| Specify the context where users are created. This context should be different from other users&#039; contexts to prevent security issues. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====Course creation====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Creators&lt;br /&gt;
| The DN of the group that contains all of your Moodle creators. This is typically a posixGroup with a &amp;quot;memberUid&amp;quot; attribute for each user you want to be a creator.  If your group is called &#039;&#039;creators&#039;&#039;, type &#039;&#039;&#039;cn=creators,ou=moodleusers,dc=my,dc=organization,dc=domain&#039;&#039;&#039; here.  Each memberUid attribute contains the CN of a user who is authorized to be a creator.  Do not use the user&#039;s full DN (e.g.,  not &#039;&#039;&#039;memberUid: cn=JoeTeacher,ou=moodleusers,dc-my,dc=organizations,dc=domain&#039;&#039;&#039;, but rather &#039;&#039;&#039;memberUid: JoeTeacher&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
In eDirectory, the objectClass for a group is (by default) not &#039;&#039;&#039;posixGroup&#039;&#039;&#039; but &#039;&#039;&#039;groupOfNames,&#039;&#039;&#039; whose member attribute is &#039;&#039;&#039;member,&#039;&#039;&#039; not &#039;&#039;&#039;memberUid,&#039;&#039;&#039; and whose value is the full DN of the user in question.  Although you can probably modify Moodle&#039;s code to use this field, a better solution is just to add a new &#039;&#039;&#039;objectClass&#039;&#039;&#039; attribute of &#039;&#039;&#039;posixGroup&#039;&#039;&#039; to your creators group and put the CNs for each creator in a &#039;&#039;&#039;memberUid&#039;&#039;&#039; attribute.&lt;br /&gt;
&lt;br /&gt;
In MS Active Directory, you will need to create a security group for your creators to be part of and then add them all. If your ldap context above is &#039;ou=staff,dc=my,dc=org&#039; then your group should then be &#039;cn=creators,ou=staff,dc=my,dc=org&#039;. If some of the users are from other contexts and have been added to the same security group, you&#039;ll have to add these as separate contexts after the first one using the same format.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====Cron synchronization script====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Removed ext user&lt;br /&gt;
| Specify what to do with internal user account during mass synchronization when user was removed from external source. Only suspended users are automatically revived if they reappear in ext source.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====NTLM SSO====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| Enable&lt;br /&gt;
| If you want to use NTLM SSO (see details at [[NTLM_authentication]]), choose &#039;&#039;Yes&#039;&#039; here. Otherwise, choose &#039;&#039;No&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| Subnet&lt;br /&gt;
| Specify the subnets of the clients that will use NTLM SSO (see details at [[NTLM_authentication]]).&lt;br /&gt;
|-&lt;br /&gt;
| MS IE Fast Path?&lt;br /&gt;
| If all of you clients (or most of them) are using MS Internet Explorer, you can set this option to bypasses certain steps of the SSO login and speed up login times. This only works with MS Internet Explorer, but deals with other browsers in a sensible way (they are automatically sent to the plain login page).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
====Data Mapping====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Field name&lt;br /&gt;
! Value to fill in&lt;br /&gt;
|-&lt;br /&gt;
| First name&lt;br /&gt;
| The name of the attribute that holds the first name of your users in your LDAP server. This is usually &#039;&#039;&#039;givenName&#039;&#039;&#039; or &#039;&#039;&#039;displayName&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Surname&lt;br /&gt;
| The name of the attribute that holds the surname of your users in your LDAP server. This is usually &#039;&#039;&#039;sn&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Email address&lt;br /&gt;
| The name of the attribute that holds the email address of your users in your LDAP server. This is usually &#039;&#039;&#039;mail&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| City/town&lt;br /&gt;
| The name of the attribute that holds the city/town of your users in your LDAP server. This is usully &#039;&#039;&#039;l&#039;&#039;&#039; (lowercase L) or &#039;&#039;&#039;localityName&#039;&#039;&#039; (not valid in MS-AD).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| Country&lt;br /&gt;
| The name of the attribute that holds the country of your users in your LDAP server. This is usully &#039;&#039;&#039;c&#039;&#039;&#039; or &#039;&#039;&#039;countryName&#039;&#039;&#039; (not valid in MS-AD).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Language&lt;br /&gt;
| &#039;&#039;&#039;preferredLanguage&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Description&lt;br /&gt;
| &#039;&#039;&#039;description&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Webpage&lt;br /&gt;
| &amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| ID Number&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Institution&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Department&lt;br /&gt;
| The name of the attribute that holds the department name of your users in your LDAP server. This is usully &#039;&#039;&#039;departmentNumber&#039;&#039;&#039; (for posixAccount and maybe eDirectory) or &#039;&#039;&#039;department&#039;&#039;&#039; (for MS-AD).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Phone 1&lt;br /&gt;
| The name of the attribute that holds the telephone number of your users in your LDAP server. This is usually &#039;&#039;&#039;telephoneNumber&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Phone 2&lt;br /&gt;
|  The name of the attribute that holds an additional telephone number of your users in your LDAP server. This can be &#039;&#039;&#039;homePhone&#039;&#039;&#039;, &#039;&#039;&#039;mobile&#039;&#039;&#039;, &#039;&#039;&#039;pager&#039;&#039;&#039;, &#039;&#039;&#039;facsimileTelephoneNumber&#039;&#039;&#039; or even others.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Address&lt;br /&gt;
| The name of the attribute that holds the street address of your users in your LDAP server. This is usully &#039;&#039;&#039;streetAddress&#039;&#039;&#039; or &#039;&#039;&#039;street&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;This setting is optional&amp;lt;/u&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
===Setting up regular automatic synchronisation using cron===&lt;br /&gt;
There is a script located at /auth/ldap/auth_ldap_sync_users.php which will create or suspend/delete (see the setting above) all LDAP accounts automatically. Ideally, this is called from the command line once a day during a quiet time using exactly the same procedure as the standard [[Cron|cron]] job (so you will end up with two cron entries). It is important, however, to make sure that all of the above LDAP settings are working properly before you try this, as well as backing up your database and moodledata folders. Poor LDAP configuration could lead to users being wrongly deleted.&lt;br /&gt;
&lt;br /&gt;
If you find that the script is not running through all of your users properly and you have MS Active Directory + over 1000 users, this is because by default, MS AD only sends back 1000 users at a time. Follow the instructions [http://support.microsoft.com/kb/315071 here] to set the MaxPageSize setting to a number higher than your total number of users (both now and in future) to fix it. This is a forest-wide setting.&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
==Active Directory help==&lt;br /&gt;
[[Active Directory]] is Microsoft&#039;s directory service. It is included in Windows 2000 Server and later versions of their operating system. For more information about subjects below, &#039;&#039;&#039;[[Active Directory|please go here]]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
*Warning: The PHP LDAP module does not seem to be present&lt;br /&gt;
*LDAP-module cannot connect any LDAP servers &lt;br /&gt;
*Getting correct CNs for Contexts and Creators&lt;br /&gt;
*Getting the right user_attribute&lt;br /&gt;
*Installing ldp.exe Server Tool&lt;br /&gt;
*Example Active Directory Configuration&lt;br /&gt;
*Child Domains and the Global Catalog in MS Active Directory&lt;br /&gt;
*Enabling the Global Catalog&lt;br /&gt;
*Active Directory with Moodle 1.8&lt;br /&gt;
*MS Active Directory + SSL&lt;br /&gt;
&lt;br /&gt;
==Advanced Scenarios - Multiple servers or locations==&lt;br /&gt;
For larger installations with  multiple LDAP servers, or multiple locations (contexts) in a LDAP tree.&lt;br /&gt;
&lt;br /&gt;
===Using multiple LDAP Servers===&lt;br /&gt;
Entering more than one name in the ldap_host_url field can provide some sort of resilience to your system. Simply use the syntax :&lt;br /&gt;
ldap://my.first.server ; ldap://my.second.server ; ...&lt;br /&gt;
&lt;br /&gt;
Of course, this will only work if all the servers share the same directory information, using a replication or synchronization mecanism once introduced in eDirectory and now generalized to the main LDAP-compatible directories.&lt;br /&gt;
&lt;br /&gt;
There is one drawback in Moodle 1.5 - 1.6 implementation of LDAP authentication : the auth_ldap_connect() function processes the servers sequentially, not in a round robin mode. Thus, if the primary server fails, you will have to wait for the connection to time out before switching to the following one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See also: [http://moodle.org/mod/forum/discuss.php?d=17198#p111090 Using multiple LDAP servers - Our students are on separate domain] discussion on the Using Moodle forum.&lt;br /&gt;
&lt;br /&gt;
===Using multiple user locations (contexts) in your LDAP tree===&lt;br /&gt;
There is no need to use multiple user locations if your directory tree is flat, i.e. if all user accounts reside in a &#039;&#039;&#039;ou=people,dc=my,dc=organization,dc=domain&#039;&#039;&#039; or &#039;&#039;&#039;ou=people,o=myorg&#039;&#039;&#039; container. &lt;br /&gt;
&lt;br /&gt;
At the opposite, if you use the ACL mecanism to delegate user management, there are chances that your users will be stored in containers like &#039;&#039;&#039;ou=students,ou=dept1,o=myorg&#039;&#039;&#039; and &#039;&#039;&#039;ou=students,ou=dept2,o=myorg&#039;&#039;&#039; ...&lt;br /&gt;
&lt;br /&gt;
Then there is an alternative :&lt;br /&gt;
* Look at the &#039;&#039;&#039;o=myorg&#039;&#039;&#039; level with the ldap_search_sub attribute set to &#039;&#039;&#039;yes&#039;&#039;&#039;.&lt;br /&gt;
* Set the ldap_context to &#039;&#039;&#039;ou=students,ou=dept1,o=myorg ; ou=students,ou=dept2,o=myorg&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Choosing between these two solutions supposes some sort of benchmarking, as the result depends heavily on the structure of your directory tree &#039;&#039;&#039;and&#039;&#039;&#039; on your LDAP software indexing capabilities. Simply note that there is a probability in such deep trees that two users share the same &#039;&#039;common name&#039;&#039; (cn), while having different &#039;&#039;distinguished names&#039;&#039;. Then only the second solution will have a deterministic result (returning allways the same user).&lt;br /&gt;
&lt;br /&gt;
===Using LDAPS (LDAP + SSL)===&lt;br /&gt;
====Enabling LDAPS on the LDAP server side====&lt;br /&gt;
&lt;br /&gt;
* [[Active_Directory#MS_Active_Directory_.2B_SSL|Enabling LDAPS on MS Active Directory ]]&lt;br /&gt;
&lt;br /&gt;
====Enabling LDAPS on the client side (Moodle server)====&lt;br /&gt;
&lt;br /&gt;
* If you are running Moodle on MS Windows, you need to tell PHP&#039;s OpenLDAP extension to disable SSL server certificate checking. You must create a directory called &#039;&#039;C:\OpenLDAP\sysconf&#039;&#039;. In this directory, create a file called &#039;&#039;ldap.conf&#039;&#039; with the following content (If you are using certain versions of PHP 5.3.x you may need to place the file at other locations, [http://bugs.php.net/bug.php?id=48866 see PHP bug #48866]):&lt;br /&gt;
&lt;br /&gt;
 TLS_REQCERT never&lt;br /&gt;
&lt;br /&gt;
* If you are running Moodle on Linux or any other Unix-like operating system, and you want to disable SSL server certificate checking, you need to edit the OpenLDAP client configuration file (usually /etc/ldap.conf or /etc/ldap/ldap.conf or even /etc/openldap/ldap.conf) and make sure you have a line like the following one:&lt;br /&gt;
&lt;br /&gt;
 TLS_REQCERT never&lt;br /&gt;
&lt;br /&gt;
Now you should be able to use &#039;&#039;&#039;ldaps://&#039;&#039;&#039; when connecting to your LDAP server.&lt;br /&gt;
&lt;br /&gt;
If you have the certificate of the LDAPS server as a file and want to check the certificate for the connection, copy the certificate file to an arbitary directory (e.g. /etc/ldap/certificate.pem) on your client and change the content of the &#039;&#039;ldap.conf&#039;&#039; as follows:&lt;br /&gt;
&lt;br /&gt;
 TLS_REQCERT demand&lt;br /&gt;
 TLS_CACERT  /etc/ldap/certificate.pem&lt;br /&gt;
&lt;br /&gt;
When the requested server certificate is bad or not provided, the connection to the LDAPS server is immediately terminated.&lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
==Appendices==&lt;br /&gt;
===ldap auth_user_create() only suports Novell===&lt;br /&gt;
&lt;br /&gt;
After configuring user authentication with ldap I realized ldap only support edir (Novell) when combining ldap an email user confirmation. For example in my case (I use openldap) I have the following error after filling the user form:&lt;br /&gt;
&lt;br /&gt;
auth: ldap auth_user_create() does not support selected usertype:&amp;quot;rfc2307&amp;quot; (..yet)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Setting Resource Limits RedHat Directory Server ===&lt;br /&gt;
&lt;br /&gt;
Operational attributes can be set for the bind user DN using the command-line. &lt;br /&gt;
One can simply use ldapmodify to add the following attributes:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! Attribute Name &lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| nsLookThroughLimit&lt;br /&gt;
| Specifies how many entries are examined for a search operation. Giving this attribute a value of -1 indicates that there is no limit.&lt;br /&gt;
|-&lt;br /&gt;
| nsSizeLimit &lt;br /&gt;
| Specifies the maximum number of entries the server returns to a client application in response to a search operation. Giving this attribute a value of -1 indicates that there is no limit.&lt;br /&gt;
|-&lt;br /&gt;
| nsTimeLimit &lt;br /&gt;
| Specifies the maximum time the server spends processing a search operation. Giving this attribute a value of -1 indicates that there is no time limit.&lt;br /&gt;
|-&lt;br /&gt;
| nsIdleTimeout 	        &lt;br /&gt;
| Specifies the time a connection to the server can be idle before the connection is dropped. The value is given in seconds. Giving this attribute a value of -1 indicates that there is no limit.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;pre&amp;gt; LDAP Console Command-Line&lt;br /&gt;
&lt;br /&gt;
 ldapmodify -h redhat_dir_server -p 389 -D &amp;quot;cn=directory manager&amp;quot; -w secretpwd&lt;br /&gt;
&lt;br /&gt;
 dn: uid=MoodleAdmin,ou=system,dc=myschool,dc=edu&lt;br /&gt;
 changetype: modify&lt;br /&gt;
 add:nsSizeLimit&lt;br /&gt;
 nsSizeLimit: 1000&lt;br /&gt;
 &amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
[[LDAP_authentication#Table of Contents|Table of Contents]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[NTLM_authentication]]&lt;br /&gt;
* [[Active_Directory]]&lt;br /&gt;
* [[LDAP enrolment]]&lt;br /&gt;
* [http://download.moodle.org/download.php/docs/en/how-to_guides/ldap_auth_and_enrolment_set-up.pdf LDAP auth and enrolment set-up guide] (PDF 227KB)&lt;br /&gt;
&lt;br /&gt;
Using Moodle:&lt;br /&gt;
* [http://moodle.org/mod/forum/view.php?id=42 User authentication forum]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=32168 PHP LDAP module does not seem to be present] forum discussion&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=140901 Syncronisation with AUTH_LDAP_SYNC_USERS.PHP produces fewer accounts than it should] forum discussion&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=17198 Using multiple LDAP servers] forum discussion&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Authentication]]&lt;br /&gt;
&lt;br /&gt;
[[es:LDAP_authentication]]&lt;br /&gt;
[[fr:Utiliser un serveur LDAP]]&lt;br /&gt;
[[ja:LDAP認証]]&lt;br /&gt;
[[zh:LDAP认证]]&lt;br /&gt;
[[de:Authentifizierung über LDAP]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=blocks/configurable_reports/&amp;diff=76828</id>
		<title>blocks/configurable reports/</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=blocks/configurable_reports/&amp;diff=76828"/>
		<updated>2010-10-18T06:08:45Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* See Also link */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
# Download the Configurable Reports installation file and unzip it to the &#039;&#039;&#039;\blocks&#039;&#039;&#039; directory in your Moodle folder.&lt;br /&gt;
# Login to Moodle as Administrator and click Notifications under Site Administration.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information see [[Installing contributed modules or plugins]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This block is a Moodle custom reports builder.&lt;br /&gt;
&lt;br /&gt;
It is designed in a modular way to allow developers to create new plugins in less than an hour.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Who can create custom reports?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Anyone with block, managereports or manageownreports permissions at SITE level or COURSE level.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What type of reports can I create?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Courses reports, with information regarding courses.&lt;br /&gt;
&lt;br /&gt;
- Users reports, with information regarding users and their activity in a course.&lt;br /&gt;
&lt;br /&gt;
- Custom SQL Reports, custom SQL queries. This block can use the same SQL queries that [http://moodle.org/mod/data/view.php?d=13&amp;amp;rid=2884 Tim Hunt&#039;s Custom SQL queries] plugin.&lt;br /&gt;
&lt;br /&gt;
Note for developers: You can create your own type of reports.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Who can view the reports?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
When you create a report you can select which users can view it.&lt;br /&gt;
&lt;br /&gt;
The reports are displayed in a block in the course or site frontpage.&lt;br /&gt;
&lt;br /&gt;
== Creating a report ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a very simple process.  &lt;br /&gt;
&lt;br /&gt;
If you are going to create a report for a course, you have to add the block in the course and click in the &amp;quot;Manage reports&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
On the other hand, for site reports, add the block in the frontpage and click in the &amp;quot;Manage reports&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
You must enter a name, an optional description, and you have to choose the type of report, pagination and exports formats.&lt;br /&gt;
&lt;br /&gt;
Depending on the report choosen, there will be more or less tabs. These are the tabs for the courses and users report:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Columns&#039;&#039;&#039;: Here you can choose the differents columns of your report depending on the type of report. (Course Name, User firstname, etc..)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conditions&#039;&#039;&#039;: Here you can define the conditions (i.e, only courses from this category, only users from Spain, etc.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ordering&#039;&#039;&#039;: Here you can choose how to order the report using fields and directions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Filters&#039;&#039;&#039;: Here you can choose which filters will be displayed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Template&#039;&#039;&#039;: You can modify the report&#039;s layout by creating a template.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Permissions&#039;&#039;&#039;: Here you can choose who can view a report.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Calculations&#039;&#039;&#039;: Here you can add calculations for columns, i.e: average of number of users enrolled in courses&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Plots&#039;&#039;&#039;: Here you can add graphs to your report based on the report columns and values.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;View report&#039;&#039;&#039;: Self explanatory&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
=== Creating a users&#039; report ===&lt;br /&gt;
&lt;br /&gt;
Requirements: &#039;&#039;Users from Spain, but no from Madrid, in this course. This report can be viewed only by users from Spain. A filter based on the user&#039;s city must be displayed. A pie plot showing the users&#039; cities is required. A calculation table showing the total forum post views is required. The report must be order by users&#039; lastname.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let&#039;s see how easy it is!&lt;br /&gt;
&lt;br /&gt;
First of all, install the block.&lt;br /&gt;
&lt;br /&gt;
Go to the course where the report will be created.&lt;br /&gt;
&lt;br /&gt;
Add an instance of the Custom Reports block.&lt;br /&gt;
&lt;br /&gt;
Click on &amp;quot;Manage reports&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Click on &amp;quot;Add report&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Enter a name, a description and choose &amp;quot;Users report&amp;quot; as Type of Report&lt;br /&gt;
&lt;br /&gt;
The report will be saved and you will be redirected to the first Tab named &amp;quot;Columns&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Columns&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Here you can define the report table properties, width, align, cell padding, cell spacing, etc..&lt;br /&gt;
Add a Column called &amp;quot;User profile field&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Choose the field &amp;quot;firstname&amp;quot; and enter a name for the column in the text field. You can leave blank the rest of elements.&lt;br /&gt;
&lt;br /&gt;
Repit the process above for the lastname and city fields.&lt;br /&gt;
&lt;br /&gt;
Add a Column called &amp;quot;User module actions&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose a module from the list, in this example, a forum.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;Adding Conditions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Conditions Tab.&lt;br /&gt;
&lt;br /&gt;
Add a Condition named &amp;quot;User field Condition&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;Country&amp;quot;, the Operator &amp;quot;=&amp;quot;, and enter the value &amp;quot;ES&amp;quot; (this is the international code for Spain as Moodle stores it).&lt;br /&gt;
&lt;br /&gt;
Add a Condition named &amp;quot;User field Condition&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;city&amp;quot;, the Operator &amp;quot;&amp;lt;&amp;gt;&amp;quot;, and enter the value &amp;quot;Madrid&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add a Condition named &amp;quot;Users in current report course&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
These are the main conditions of the reports. Note that at the bottom there is a text box called condition, with this text:&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;c2 and c1 and c3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Here you can define a logic condition, in this case, we don&#039;t need to edit this condition but you can create complex expressions like:&lt;br /&gt;
&lt;br /&gt;
 (c1 and c2) or (c4 and c3)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Ordering&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Ordering Tab.&lt;br /&gt;
&lt;br /&gt;
Add a ordering named &amp;quot;User field ordering&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;Lastname&amp;quot; and the ordering &amp;quot;ASC&amp;quot; (Ascending).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Filters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Filters Tab.&lt;br /&gt;
&lt;br /&gt;
Add a filter named &amp;quot;User field filter&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose city.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Permissions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Permissions Tab.&lt;br /&gt;
&lt;br /&gt;
Choose &amp;quot;User field Value&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;Country&amp;quot;, and enter the value &amp;quot;ES&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Here you can add more permissions and a logic condition to be achieved.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Calculations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Calculations tab.&lt;br /&gt;
&lt;br /&gt;
Choose Sum.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;User module actions&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Plots&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Plots tab.&lt;br /&gt;
&lt;br /&gt;
Choose &amp;quot;Pie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the colum &amp;quot;City&amp;quot; as Name and Value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finally, add a few users in Moodle with the country Spain, and different cities, Madrid, Barcelona, Seville etc. and test the report.&lt;br /&gt;
&lt;br /&gt;
You can download the report in differents formats (ods and xls), remember to check these options in the report page.&lt;br /&gt;
&lt;br /&gt;
[[blocks/custom_reports/#Users_report | See screenshot]]&lt;br /&gt;
&lt;br /&gt;
=== Creating a SQL Report ===&lt;br /&gt;
&lt;br /&gt;
You can find a lot of SQL Reports here: [[ad-hoc contributed reports]]&lt;br /&gt;
&lt;br /&gt;
Since this block supports Tim Hunt&#039;s CustomSQL Queries Reports, you can use any query.&lt;br /&gt;
&lt;br /&gt;
Remember to add a &amp;quot;Time filter&amp;quot; if you are going to use reports with time tokens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First of all, install the block.&lt;br /&gt;
&lt;br /&gt;
Go to the course where the report will be created.&lt;br /&gt;
&lt;br /&gt;
Add an instance of the Custom Reports block.&lt;br /&gt;
&lt;br /&gt;
Click on &amp;quot;Manage reports&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Click on &amp;quot;Add report&lt;br /&gt;
&lt;br /&gt;
Enter a name, description, choose &amp;quot;SQL&amp;quot; as Type of Report&lt;br /&gt;
&lt;br /&gt;
The report will be saved and you redirect to the firs Tab named &amp;quot;Custom SQL&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add this query (&#039;&#039;Courses activity&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
SELECT COUNT(l.id) hits, l.course courseId, c.fullname coursename&lt;br /&gt;
FROM prefix_log l INNER JOIN prefix_course c ON l.course = c.id&lt;br /&gt;
GROUP BY courseId&lt;br /&gt;
ORDER BY hits DESC&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Go to Calculations Tab&lt;br /&gt;
&lt;br /&gt;
Add a Sum calculation, choose the hits column&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Go to Plot&lt;br /&gt;
&lt;br /&gt;
Add a Pie graph, choosing coursename as Name and hits as value&lt;br /&gt;
&lt;br /&gt;
So, here you have, a report with a Graph and calculations based on a SQL Query.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can add a Course filter, is very easy:&lt;br /&gt;
&lt;br /&gt;
Go to filters, choose Courses&lt;br /&gt;
&lt;br /&gt;
Edit the Custom SQL query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
SELECT COUNT(l.id) hits, l.course courseId, c.fullname coursename&lt;br /&gt;
FROM prefix_log l INNER JOIN prefix_course c ON l.course = c.id &lt;br /&gt;
%%FILTER_COURSES:l.course%% &lt;br /&gt;
GROUP BY courseId&lt;br /&gt;
ORDER BY hits DESC&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we are adding a token called: %%FILTER_COURSES:l.courseid%% &lt;br /&gt;
&lt;br /&gt;
Go to View report, and you will see a Courses Filter, choose a Course and click on Add, here you have a report filtered.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You cand add also, and Starttime and endtime filter&lt;br /&gt;
&lt;br /&gt;
Go to filters, choose Stard / End date filter&lt;br /&gt;
&lt;br /&gt;
Go to Custom SQL tab, this is the new query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
SELECT COUNT(l.id) hits, l.course courseId, c.fullname coursename&lt;br /&gt;
FROM prefix_log l INNER JOIN prefix_course c ON l.course = c.id &lt;br /&gt;
%%FILTER_COURSES:l.course%% &lt;br /&gt;
%%FILTER_STARTTIME:l.time:&amp;gt;%% %%FILTER_ENDTIME:l.time:&amp;lt;%% &lt;br /&gt;
GROUP BY courseId&lt;br /&gt;
ORDER BY hits DESC&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Go to View report, now you can filter by time also&lt;br /&gt;
&lt;br /&gt;
[[blocks/custom_reports/#SQL_report | See screenshot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Advanced options ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Templates ===&lt;br /&gt;
&lt;br /&gt;
You can customize the report output using a template.&lt;br /&gt;
&lt;br /&gt;
Just enable the Template option in the same name tab.&lt;br /&gt;
&lt;br /&gt;
This is an example html code for displaying a list of users:&lt;br /&gt;
&lt;br /&gt;
Header:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;##reportname##&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;60%&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Record:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;http://yourmoodle.com/user/pix.php/[[id]]/f1.jpg&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;h2&amp;gt;[[Firstname]] [[Lastname]]&amp;lt;/h2&amp;gt;&lt;br /&gt;
City: [[City]]&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Footer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
##graphs## &lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
##exportoptions##&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded reports ===&lt;br /&gt;
&lt;br /&gt;
A embedded report consists in a report&#039;s set of columns that are embeeded in other report.&lt;br /&gt;
&lt;br /&gt;
You can embed a user report into a course report, in this case, the resulting rows will be expanded duplicating each row for each user.&lt;br /&gt;
&lt;br /&gt;
Imaging you have a courses report, you can embed a user report, every row of the course report will be cloned for each user.&lt;br /&gt;
&lt;br /&gt;
To embed a report just add a &amp;quot;Other report&amp;quot; column, a list of your reports will be showed.&lt;br /&gt;
&lt;br /&gt;
Inside a course report you can embed a user report and the other way.&lt;br /&gt;
&lt;br /&gt;
== Developers documentation ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s very easy to create new report types, components and plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Report&#039;&#039;&#039;: A report plugin is a folder located at /report. &lt;br /&gt;
This folder contains a .class.php file with the child - class of the report_base.&lt;br /&gt;
&lt;br /&gt;
You only need to modify a few methos to add a new report type.&lt;br /&gt;
Please, take a look to any of the current reports. The SQL report is an example of a non-typical report, &lt;br /&gt;
meanwhile the users and courses reports are standard reports.&lt;br /&gt;
&lt;br /&gt;
The best way to create a report is duplicate an existing one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Component&#039;&#039;&#039;: A component is part of a report, a component may be used by more than one report.&lt;br /&gt;
The main Component is the component Columns, that is used to add the columns of a report.&lt;br /&gt;
&lt;br /&gt;
Others components are filters, permissions, plot, calculations..&lt;br /&gt;
&lt;br /&gt;
The best way to create a component is duplicate an existing one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Plugin&#039;&#039;&#039;: A plugin is a component module. The component column has a few of plugins (coursefield, userfield, etc..)&lt;br /&gt;
A plugins works usually for an unique report, but there are plugins that works for more than one report.&lt;br /&gt;
The best way to create a plugin is duplicate an existing one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Credits ==&lt;br /&gt;
&lt;br /&gt;
Juan Leyva [http://moodle.org/user/view.php?id=49568&amp;amp;course=1 Moodle profile]&lt;br /&gt;
&lt;br /&gt;
[http://twitter.com/jleyvadelgado Follow me in Twitter]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Contributed code]]&lt;br /&gt;
&lt;br /&gt;
== Screenshots ==&lt;br /&gt;
&lt;br /&gt;
=== Users report ===&lt;br /&gt;
[[Image:block_custom_reports_sample_user_report.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== SQL report ===&lt;br /&gt;
[[Image:block_custom_reports_sample_sql_report.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
CONTRIB-2386&lt;br /&gt;
&lt;br /&gt;
[http://tracker.moodle.org/browse/CONTRIB/component/10753 Block: Configurable reports] Tracker component&lt;br /&gt;
&lt;br /&gt;
[http://moodle.org/mod/data/view.php?rid=4283 Modules &amp;amp; Plugins] database entry&lt;br /&gt;
&lt;br /&gt;
[[es:blocks/configurable_reports/]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=blocks/configurable_reports/&amp;diff=76827</id>
		<title>blocks/configurable reports/</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=blocks/configurable_reports/&amp;diff=76827"/>
		<updated>2010-10-18T06:04:22Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* See Also link */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
# Download the Configurable Reports installation file and unzip it to the &#039;&#039;&#039;\blocks&#039;&#039;&#039; directory in your Moodle folder.&lt;br /&gt;
# Login to Moodle as Administrator and click Notifications under Site Administration.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information see [[Installing contributed modules or plugins]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This block is a Moodle custom reports builder.&lt;br /&gt;
&lt;br /&gt;
It is designed in a modular way to allow developers to create new plugins in less than an hour.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Who can create custom reports?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Anyone with block, managereports or manageownreports permissions at SITE level or COURSE level.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What type of reports can I create?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Courses reports, with information regarding courses.&lt;br /&gt;
&lt;br /&gt;
- Users reports, with information regarding users and their activity in a course.&lt;br /&gt;
&lt;br /&gt;
- Custom SQL Reports, custom SQL queries. This block can use the same SQL queries that [http://moodle.org/mod/data/view.php?d=13&amp;amp;rid=2884 Tim Hunt&#039;s Custom SQL queries] plugin.&lt;br /&gt;
&lt;br /&gt;
Note for developers: You can create your own type of reports.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Who can view the reports?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
When you create a report you can select which users can view it.&lt;br /&gt;
&lt;br /&gt;
The reports are displayed in a block in the course or site frontpage.&lt;br /&gt;
&lt;br /&gt;
== Creating a report ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a very simple process.  &lt;br /&gt;
&lt;br /&gt;
If you are going to create a report for a course, you have to add the block in the course and click in the &amp;quot;Manage reports&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
On the other hand, for site reports, add the block in the frontpage and click in the &amp;quot;Manage reports&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
You must enter a name, an optional description, and you have to choose the type of report, pagination and exports formats.&lt;br /&gt;
&lt;br /&gt;
Depending on the report choosen, there will be more or less tabs. These are the tabs for the courses and users report:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Columns&#039;&#039;&#039;: Here you can choose the differents columns of your report depending on the type of report. (Course Name, User firstname, etc..)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conditions&#039;&#039;&#039;: Here you can define the conditions (i.e, only courses from this category, only users from Spain, etc.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ordering&#039;&#039;&#039;: Here you can choose how to order the report using fields and directions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Filters&#039;&#039;&#039;: Here you can choose which filters will be displayed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Template&#039;&#039;&#039;: You can modify the report&#039;s layout by creating a template.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Permissions&#039;&#039;&#039;: Here you can choose who can view a report.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Calculations&#039;&#039;&#039;: Here you can add calculations for columns, i.e: average of number of users enrolled in courses&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Plots&#039;&#039;&#039;: Here you can add graphs to your report based on the report columns and values.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;View report&#039;&#039;&#039;: Self explanatory&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
=== Creating a users&#039; report ===&lt;br /&gt;
&lt;br /&gt;
Requirements: &#039;&#039;Users from Spain, but no from Madrid, in this course. This report can be viewed only by users from Spain. A filter based on the user&#039;s city must be displayed. A pie plot showing the users&#039; cities is required. A calculation table showing the total forum post views is required. The report must be order by users&#039; lastname.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let&#039;s see how easy it is!&lt;br /&gt;
&lt;br /&gt;
First of all, install the block.&lt;br /&gt;
&lt;br /&gt;
Go to the course where the report will be created.&lt;br /&gt;
&lt;br /&gt;
Add an instance of the Custom Reports block.&lt;br /&gt;
&lt;br /&gt;
Click on &amp;quot;Manage reports&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Click on &amp;quot;Add report&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Enter a name, a description and choose &amp;quot;Users report&amp;quot; as Type of Report&lt;br /&gt;
&lt;br /&gt;
The report will be saved and you will be redirected to the first Tab named &amp;quot;Columns&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Columns&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Here you can define the report table properties, width, align, cell padding, cell spacing, etc..&lt;br /&gt;
Add a Column called &amp;quot;User profile field&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Choose the field &amp;quot;firstname&amp;quot; and enter a name for the column in the text field. You can leave blank the rest of elements.&lt;br /&gt;
&lt;br /&gt;
Repit the process above for the lastname and city fields.&lt;br /&gt;
&lt;br /&gt;
Add a Column called &amp;quot;User module actions&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose a module from the list, in this example, a forum.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;Adding Conditions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Conditions Tab.&lt;br /&gt;
&lt;br /&gt;
Add a Condition named &amp;quot;User field Condition&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;Country&amp;quot;, the Operator &amp;quot;=&amp;quot;, and enter the value &amp;quot;ES&amp;quot; (this is the international code for Spain as Moodle stores it).&lt;br /&gt;
&lt;br /&gt;
Add a Condition named &amp;quot;User field Condition&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;city&amp;quot;, the Operator &amp;quot;&amp;lt;&amp;gt;&amp;quot;, and enter the value &amp;quot;Madrid&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add a Condition named &amp;quot;Users in current report course&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
These are the main conditions of the reports. Note that at the bottom there is a text box called condition, with this text:&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;c2 and c1 and c3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Here you can define a logic condition, in this case, we don&#039;t need to edit this condition but you can create complex expressions like:&lt;br /&gt;
&lt;br /&gt;
 (c1 and c2) or (c4 and c3)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Ordering&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Ordering Tab.&lt;br /&gt;
&lt;br /&gt;
Add a ordering named &amp;quot;User field ordering&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;Lastname&amp;quot; and the ordering &amp;quot;ASC&amp;quot; (Ascending).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Filters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Filters Tab.&lt;br /&gt;
&lt;br /&gt;
Add a filter named &amp;quot;User field filter&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose city.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Permissions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Permissions Tab.&lt;br /&gt;
&lt;br /&gt;
Choose &amp;quot;User field Value&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;Country&amp;quot;, and enter the value &amp;quot;ES&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Here you can add more permissions and a logic condition to be achieved.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Calculations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Calculations tab.&lt;br /&gt;
&lt;br /&gt;
Choose Sum.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;User module actions&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Plots&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Plots tab.&lt;br /&gt;
&lt;br /&gt;
Choose &amp;quot;Pie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the colum &amp;quot;City&amp;quot; as Name and Value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finally, add a few users in Moodle with the country Spain, and different cities, Madrid, Barcelona, Seville etc. and test the report.&lt;br /&gt;
&lt;br /&gt;
You can download the report in differents formats (ods and xls), remember to check these options in the report page.&lt;br /&gt;
&lt;br /&gt;
[[blocks/custom_reports/#Users_report | See screenshot]]&lt;br /&gt;
&lt;br /&gt;
=== Creating a SQL Report ===&lt;br /&gt;
&lt;br /&gt;
You can find a lot of SQL Reports here: [[ad-hoc contributed reports]]&lt;br /&gt;
&lt;br /&gt;
Since this block supports Tim Hunt&#039;s CustomSQL Queries Reports, you can use any query.&lt;br /&gt;
&lt;br /&gt;
Remember to add a &amp;quot;Time filter&amp;quot; if you are going to use reports with time tokens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First of all, install the block.&lt;br /&gt;
&lt;br /&gt;
Go to the course where the report will be created.&lt;br /&gt;
&lt;br /&gt;
Add an instance of the Custom Reports block.&lt;br /&gt;
&lt;br /&gt;
Click on &amp;quot;Manage reports&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Click on &amp;quot;Add report&lt;br /&gt;
&lt;br /&gt;
Enter a name, description, choose &amp;quot;SQL&amp;quot; as Type of Report&lt;br /&gt;
&lt;br /&gt;
The report will be saved and you redirect to the firs Tab named &amp;quot;Custom SQL&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add this query (&#039;&#039;Courses activity&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
SELECT COUNT(l.id) hits, l.course courseId, c.fullname coursename&lt;br /&gt;
FROM prefix_log l INNER JOIN prefix_course c ON l.course = c.id&lt;br /&gt;
GROUP BY courseId&lt;br /&gt;
ORDER BY hits DESC&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Go to Calculations Tab&lt;br /&gt;
&lt;br /&gt;
Add a Sum calculation, choose the hits column&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Go to Plot&lt;br /&gt;
&lt;br /&gt;
Add a Pie graph, choosing coursename as Name and hits as value&lt;br /&gt;
&lt;br /&gt;
So, here you have, a report with a Graph and calculations based on a SQL Query.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can add a Course filter, is very easy:&lt;br /&gt;
&lt;br /&gt;
Go to filters, choose Courses&lt;br /&gt;
&lt;br /&gt;
Edit the Custom SQL query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
SELECT COUNT(l.id) hits, l.course courseId, c.fullname coursename&lt;br /&gt;
FROM prefix_log l INNER JOIN prefix_course c ON l.course = c.id &lt;br /&gt;
%%FILTER_COURSES:l.course%% &lt;br /&gt;
GROUP BY courseId&lt;br /&gt;
ORDER BY hits DESC&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we are adding a token called: %%FILTER_COURSES:l.courseid%% &lt;br /&gt;
&lt;br /&gt;
Go to View report, and you will see a Courses Filter, choose a Course and click on Add, here you have a report filtered.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You cand add also, and Starttime and endtime filter&lt;br /&gt;
&lt;br /&gt;
Go to filters, choose Stard / End date filter&lt;br /&gt;
&lt;br /&gt;
Go to Custom SQL tab, this is the new query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
SELECT COUNT(l.id) hits, l.course courseId, c.fullname coursename&lt;br /&gt;
FROM prefix_log l INNER JOIN prefix_course c ON l.course = c.id &lt;br /&gt;
%%FILTER_COURSES:l.course%% &lt;br /&gt;
%%FILTER_STARTTIME:l.time:&amp;gt;%% %%FILTER_ENDTIME:l.time:&amp;lt;%% &lt;br /&gt;
GROUP BY courseId&lt;br /&gt;
ORDER BY hits DESC&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Go to View report, now you can filter by time also&lt;br /&gt;
&lt;br /&gt;
[[blocks/custom_reports/#SQL_report | See screenshot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Advanced options ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Templates ===&lt;br /&gt;
&lt;br /&gt;
You can customize the report output using a template.&lt;br /&gt;
&lt;br /&gt;
Just enable the Template option in the same name tab.&lt;br /&gt;
&lt;br /&gt;
This is an example html code for displaying a list of users:&lt;br /&gt;
&lt;br /&gt;
Header:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;##reportname##&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;60%&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Record:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;http://yourmoodle.com/user/pix.php/[[id]]/f1.jpg&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;h2&amp;gt;[[Firstname]] [[Lastname]]&amp;lt;/h2&amp;gt;&lt;br /&gt;
City: [[City]]&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Footer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
##graphs## &lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
##exportoptions##&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded reports ===&lt;br /&gt;
&lt;br /&gt;
A embedded report consists in a report&#039;s set of columns that are embeeded in other report.&lt;br /&gt;
&lt;br /&gt;
You can embed a user report into a course report, in this case, the resulting rows will be expanded duplicating each row for each user.&lt;br /&gt;
&lt;br /&gt;
Imaging you have a courses report, you can embed a user report, every row of the course report will be cloned for each user.&lt;br /&gt;
&lt;br /&gt;
To embed a report just add a &amp;quot;Other report&amp;quot; column, a list of your reports will be showed.&lt;br /&gt;
&lt;br /&gt;
Inside a course report you can embed a user report and the other way.&lt;br /&gt;
&lt;br /&gt;
== Developers documentation ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s very easy to create new report types, components and plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Report&#039;&#039;&#039;: A report plugin is a folder located at /report. &lt;br /&gt;
This folder contains a .class.php file with the child - class of the report_base.&lt;br /&gt;
&lt;br /&gt;
You only need to modify a few methos to add a new report type.&lt;br /&gt;
Please, take a look to any of the current reports. The SQL report is an example of a non-typical report, &lt;br /&gt;
meanwhile the users and courses reports are standard reports.&lt;br /&gt;
&lt;br /&gt;
The best way to create a report is duplicate an existing one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Component&#039;&#039;&#039;: A component is part of a report, a component may be used by more than one report.&lt;br /&gt;
The main Component is the component Columns, that is used to add the columns of a report.&lt;br /&gt;
&lt;br /&gt;
Others components are filters, permissions, plot, calculations..&lt;br /&gt;
&lt;br /&gt;
The best way to create a component is duplicate an existing one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Plugin&#039;&#039;&#039;: A plugin is a component module. The component column has a few of plugins (coursefield, userfield, etc..)&lt;br /&gt;
A plugins works usually for an unique report, but there are plugins that works for more than one report.&lt;br /&gt;
The best way to create a plugin is duplicate an existing one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Credits ==&lt;br /&gt;
&lt;br /&gt;
Juan Leyva [http://moodle.org/user/view.php?id=49568&amp;amp;course=1 Moodle profile]&lt;br /&gt;
&lt;br /&gt;
[http://twitter.com/jleyvadelgado Follow me in Twitter]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Contributed code]]&lt;br /&gt;
&lt;br /&gt;
== Screenshots ==&lt;br /&gt;
&lt;br /&gt;
=== Users report ===&lt;br /&gt;
[[Image:block_custom_reports_sample_user_report.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== SQL report ===&lt;br /&gt;
[[Image:block_custom_reports_sample_sql_report.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
CONTRIB-2386&lt;br /&gt;
&lt;br /&gt;
[http://tracker.moodle.org/browse/CONTRIB/component/10753 Block: Configurable reports] Tracker component&lt;br /&gt;
&lt;br /&gt;
[http://moodle.org/mod/data/view.php?d=13&amp;amp;rid=4283&amp;amp;filter=1 Modules &amp;amp; Plugins] database entry&lt;br /&gt;
&lt;br /&gt;
[[es:blocks/configurable_reports/]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=blocks/configurable_reports/&amp;diff=76800</id>
		<title>blocks/configurable reports/</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=blocks/configurable_reports/&amp;diff=76800"/>
		<updated>2010-10-15T07:10:12Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Added See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
# Download the Configurable Reports installation file and unzip it to the &#039;&#039;&#039;\blocks&#039;&#039;&#039; directory in your Moodle folder.&lt;br /&gt;
# Login to Moodle as Administrator and click Notifications under Site Administration.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information see [[Installing contributed modules or plugins]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This block is a Moodle custom reports builder.&lt;br /&gt;
&lt;br /&gt;
It is designed in a modular way to allow developers to create new plugins in less than an hour.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Who can create custom reports?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Anyone with block, managereports or manageownreports permissions at SITE level or COURSE level.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What type of reports can I create?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Courses reports, with information regarding courses.&lt;br /&gt;
&lt;br /&gt;
- Users reports, with information regarding users and their activity in a course.&lt;br /&gt;
&lt;br /&gt;
- Custom SQL Reports, custom SQL queries. This block can use the same SQL queries that [http://moodle.org/mod/data/view.php?d=13&amp;amp;rid=2884 Tim Hunt&#039;s Custom SQL queries] plugin.&lt;br /&gt;
&lt;br /&gt;
Note for developers: You can create your own type of reports.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Who can view the reports?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
When you create a report you can select which users can view it.&lt;br /&gt;
&lt;br /&gt;
The reports are displayed in a block in the course or site frontpage.&lt;br /&gt;
&lt;br /&gt;
== Creating a report ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a very simple process.  &lt;br /&gt;
&lt;br /&gt;
If you are going to create a report for a course, you have to add the block in the course and click in the &amp;quot;Manage reports&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
On the other hand, for site reports, add the block in the frontpage and click in the &amp;quot;Manage reports&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
You must enter a name, an optional description, and you have to choose the type of report, pagination and exports formats.&lt;br /&gt;
&lt;br /&gt;
Depending on the report choosen, there will be more or less tabs. These are the tabs for the courses and users report:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Columns&#039;&#039;&#039;: Here you can choose the differents columns of your report depending on the type of report. (Course Name, User firstname, etc..)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conditions&#039;&#039;&#039;: Here you can define the conditions (i.e, only courses from this category, only users from Spain, etc.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ordering&#039;&#039;&#039;: Here you can choose how to order the report using fields and directions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Filters&#039;&#039;&#039;: Here you can choose which filters will be displayed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Template&#039;&#039;&#039;: You can modify the report&#039;s layout by creating a template.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Permissions&#039;&#039;&#039;: Here you can choose who can view a report.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Calculations&#039;&#039;&#039;: Here you can add calculations for columns, i.e: average of number of users enrolled in courses&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Plots&#039;&#039;&#039;: Here you can add graphs to your report based on the report columns and values.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;View report&#039;&#039;&#039;: Self explanatory&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
=== Creating a users&#039; report ===&lt;br /&gt;
&lt;br /&gt;
Requirements: &#039;&#039;Users from Spain, but no from Madrid, in this course. This report can be viewed only by users from Spain. A filter based on the user&#039;s city must be displayed. A pie plot showing the users&#039; cities is required. A calculation table showing the total forum post views is required. The report must be order by users&#039; lastname.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let&#039;s see how easy it is!&lt;br /&gt;
&lt;br /&gt;
First of all, install the block.&lt;br /&gt;
&lt;br /&gt;
Go to the course where the report will be created.&lt;br /&gt;
&lt;br /&gt;
Add an instance of the Custom Reports block.&lt;br /&gt;
&lt;br /&gt;
Click on &amp;quot;Manage reports&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Click on &amp;quot;Add report&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Enter a name, a description and choose &amp;quot;Users report&amp;quot; as Type of Report&lt;br /&gt;
&lt;br /&gt;
The report will be saved and you will be redirected to the first Tab named &amp;quot;Columns&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Columns&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Here you can define the report table properties, width, align, cell padding, cell spacing, etc..&lt;br /&gt;
Add a Column called &amp;quot;User profile field&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Choose the field &amp;quot;firstname&amp;quot; and enter a name for the column in the text field. You can leave blank the rest of elements.&lt;br /&gt;
&lt;br /&gt;
Repit the process above for the lastname and city fields.&lt;br /&gt;
&lt;br /&gt;
Add a Column called &amp;quot;User module actions&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose a module from the list, in this example, a forum.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;Adding Conditions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Conditions Tab.&lt;br /&gt;
&lt;br /&gt;
Add a Condition named &amp;quot;User field Condition&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;Country&amp;quot;, the Operator &amp;quot;=&amp;quot;, and enter the value &amp;quot;ES&amp;quot; (this is the international code for Spain as Moodle stores it).&lt;br /&gt;
&lt;br /&gt;
Add a Condition named &amp;quot;User field Condition&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;city&amp;quot;, the Operator &amp;quot;&amp;lt;&amp;gt;&amp;quot;, and enter the value &amp;quot;Madrid&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add a Condition named &amp;quot;Users in current report course&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
These are the main conditions of the reports. Note that at the bottom there is a text box called condition, with this text:&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;c2 and c1 and c3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Here you can define a logic condition, in this case, we don&#039;t need to edit this condition but you can create complex expressions like:&lt;br /&gt;
&lt;br /&gt;
 (c1 and c2) or (c4 and c3)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Ordering&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Ordering Tab.&lt;br /&gt;
&lt;br /&gt;
Add a ordering named &amp;quot;User field ordering&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;Lastname&amp;quot; and the ordering &amp;quot;ASC&amp;quot; (Ascending).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Filters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Filters Tab.&lt;br /&gt;
&lt;br /&gt;
Add a filter named &amp;quot;User field filter&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose city.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Permissions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Permissions Tab.&lt;br /&gt;
&lt;br /&gt;
Choose &amp;quot;User field Value&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;Country&amp;quot;, and enter the value &amp;quot;ES&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Here you can add more permissions and a logic condition to be achieved.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Calculations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Calculations tab.&lt;br /&gt;
&lt;br /&gt;
Choose Sum.&lt;br /&gt;
&lt;br /&gt;
Choose the column &amp;quot;User module actions&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Adding Plots&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Click on the Plots tab.&lt;br /&gt;
&lt;br /&gt;
Choose &amp;quot;Pie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Choose the colum &amp;quot;City&amp;quot; as Name and Value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finally, add a few users in Moodle with the country Spain, and different cities, Madrid, Barcelona, Seville etc. and test the report.&lt;br /&gt;
&lt;br /&gt;
You can download the report in differents formats (ods and xls), remember to check these options in the report page.&lt;br /&gt;
&lt;br /&gt;
[[blocks/custom_reports/#Users_report | See screenshot]]&lt;br /&gt;
&lt;br /&gt;
=== Creating a SQL Report ===&lt;br /&gt;
&lt;br /&gt;
You can find a lot of SQL Reports here: [[ad-hoc contributed reports]]&lt;br /&gt;
&lt;br /&gt;
Since this block supports Tim Hunt&#039;s CustomSQL Queries Reports, you can use any query.&lt;br /&gt;
&lt;br /&gt;
Remember to add a &amp;quot;Time filter&amp;quot; if you are going to use reports with time tokens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First of all, install the block.&lt;br /&gt;
&lt;br /&gt;
Go to the course where the report will be created.&lt;br /&gt;
&lt;br /&gt;
Add an instance of the Custom Reports block.&lt;br /&gt;
&lt;br /&gt;
Click on &amp;quot;Manage reports&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Click on &amp;quot;Add report&lt;br /&gt;
&lt;br /&gt;
Enter a name, description, choose &amp;quot;SQL&amp;quot; as Type of Report&lt;br /&gt;
&lt;br /&gt;
The report will be saved and you redirect to the firs Tab named &amp;quot;Custom SQL&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add this query (&#039;&#039;Courses activity&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
SELECT COUNT(l.id) hits, l.course courseId, c.fullname coursename&lt;br /&gt;
FROM prefix_log l INNER JOIN prefix_course c ON l.course = c.id&lt;br /&gt;
GROUP BY courseId&lt;br /&gt;
ORDER BY hits DESC&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Go to Calculations Tab&lt;br /&gt;
&lt;br /&gt;
Add a Sum calculation, choose the hits column&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Go to Plot&lt;br /&gt;
&lt;br /&gt;
Add a Pie graph, choosing coursename as Name and hits as value&lt;br /&gt;
&lt;br /&gt;
So, here you have, a report with a Graph and calculations based on a SQL Query.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can add a Course filter, is very easy:&lt;br /&gt;
&lt;br /&gt;
Go to filters, choose Courses&lt;br /&gt;
&lt;br /&gt;
Edit the Custom SQL query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
SELECT COUNT(l.id) hits, l.course courseId, c.fullname coursename&lt;br /&gt;
FROM prefix_log l INNER JOIN prefix_course c ON l.course = c.id &lt;br /&gt;
%%FILTER_COURSES:l.course%% &lt;br /&gt;
GROUP BY courseId&lt;br /&gt;
ORDER BY hits DESC&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we are adding a token called: %%FILTER_COURSES:l.courseid%% &lt;br /&gt;
&lt;br /&gt;
Go to View report, and you will see a Courses Filter, choose a Course and click on Add, here you have a report filtered.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You cand add also, and Starttime and endtime filter&lt;br /&gt;
&lt;br /&gt;
Go to filters, choose Stard / End date filter&lt;br /&gt;
&lt;br /&gt;
Go to Custom SQL tab, this is the new query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
SELECT COUNT(l.id) hits, l.course courseId, c.fullname coursename&lt;br /&gt;
FROM prefix_log l INNER JOIN prefix_course c ON l.course = c.id &lt;br /&gt;
%%FILTER_COURSES:l.course%% &lt;br /&gt;
%%FILTER_STARTTIME:l.time:&amp;gt;%% %%FILTER_ENDTIME:l.time:&amp;lt;%% &lt;br /&gt;
GROUP BY courseId&lt;br /&gt;
ORDER BY hits DESC&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Go to View report, now you can filter by time also&lt;br /&gt;
&lt;br /&gt;
[[blocks/custom_reports/#SQL_report | See screenshot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Advanced options ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Templates ===&lt;br /&gt;
&lt;br /&gt;
You can customize the report output using a template.&lt;br /&gt;
&lt;br /&gt;
Just enable the Template option in the same name tab.&lt;br /&gt;
&lt;br /&gt;
This is an example html code for displaying a list of users:&lt;br /&gt;
&lt;br /&gt;
Header:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;##reportname##&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;60%&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Record:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;img src=&amp;quot;http://yourmoodle.com/user/pix.php/[[id]]/f1.jpg&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;h2&amp;gt;[[Firstname]] [[Lastname]]&amp;lt;/h2&amp;gt;&lt;br /&gt;
City: [[City]]&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Footer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
##graphs## &lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
##exportoptions##&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Embedded reports ===&lt;br /&gt;
&lt;br /&gt;
A embedded report consists in a report&#039;s set of columns that are embeeded in other report.&lt;br /&gt;
&lt;br /&gt;
You can embed a user report into a course report, in this case, the resulting rows will be expanded duplicating each row for each user.&lt;br /&gt;
&lt;br /&gt;
Imaging you have a courses report, you can embed a user report, every row of the course report will be cloned for each user.&lt;br /&gt;
&lt;br /&gt;
To embed a report just add a &amp;quot;Other report&amp;quot; column, a list of your reports will be showed.&lt;br /&gt;
&lt;br /&gt;
Inside a course report you can embed a user report and the other way.&lt;br /&gt;
&lt;br /&gt;
== Developers documentation ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s very easy to create new report types, components and plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Report&#039;&#039;&#039;: A report plugin is a folder located at /report. &lt;br /&gt;
This folder contains a .class.php file with the child - class of the report_base.&lt;br /&gt;
&lt;br /&gt;
You only need to modify a few methos to add a new report type.&lt;br /&gt;
Please, take a look to any of the current reports. The SQL report is an example of a non-typical report, &lt;br /&gt;
meanwhile the users and courses reports are standard reports.&lt;br /&gt;
&lt;br /&gt;
The best way to create a report is duplicate an existing one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Component&#039;&#039;&#039;: A component is part of a report, a component may be used by more than one report.&lt;br /&gt;
The main Component is the component Columns, that is used to add the columns of a report.&lt;br /&gt;
&lt;br /&gt;
Others components are filters, permissions, plot, calculations..&lt;br /&gt;
&lt;br /&gt;
The best way to create a component is duplicate an existing one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Plugin&#039;&#039;&#039;: A plugin is a component module. The component column has a few of plugins (coursefield, userfield, etc..)&lt;br /&gt;
A plugins works usually for an unique report, but there are plugins that works for more than one report.&lt;br /&gt;
The best way to create a plugin is duplicate an existing one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Credits ==&lt;br /&gt;
&lt;br /&gt;
Juan Leyva [http://moodle.org/user/view.php?id=49568&amp;amp;course=1 Moodle profile]&lt;br /&gt;
&lt;br /&gt;
[http://twitter.com/jleyvadelgado Follow me in Twitter]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Contributed code]]&lt;br /&gt;
&lt;br /&gt;
== Screenshots ==&lt;br /&gt;
&lt;br /&gt;
=== Users report ===&lt;br /&gt;
[[Image:block_custom_reports_sample_user_report.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== SQL report ===&lt;br /&gt;
[[Image:block_custom_reports_sample_sql_report.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
CONTRIB-2386&lt;br /&gt;
&lt;br /&gt;
[http://tracker.moodle.org/browse/CONTRIB/component/10753 Block: Configurable report] Tracker component&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[es:blocks/configurable_reports/]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Development_talk:Developer_FAQ&amp;diff=76491</id>
		<title>Development talk:Developer FAQ</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Development_talk:Developer_FAQ&amp;diff=76491"/>
		<updated>2010-10-05T11:19:40Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Book question */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The link &amp;quot;the documentation for datalib.php&amp;quot; appears to be broken. I believe that it should link to http://phpdocs.moodle.org/moodlecore/_lib---datalib.php.html instead of http://moodle.sourceforge.net/dhawes-phpdoc/moodlecore/_lib_datalib_php.html I&#039;m not sure though because the file is empty. Hopefully someone else knows now to fix this.&lt;br /&gt;
&lt;br /&gt;
===Is there any information on creating a new module or plugin?===&lt;br /&gt;
This section contains a link to the &#039;Moodle 1.9 Extension Development&#039; book by Jonathan Moore and Michael Churchward. Is this book still relevant to Moodle 2 or does Moodle 2 make it out-of-date? In other words, can you use it to develop modules or plugins for Moodle 2, considering that Moodle 2 is such a big upgrade and so much of the Moodle 2 core code has changed significantly?&lt;br /&gt;
--[[User:Luis de Vasconcelos|Luis de Vasconcelos]] 11:19, 5 October 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=Installing_Oracle_for_PHP&amp;diff=76308</id>
		<title>Installing Oracle for PHP</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=Installing_Oracle_for_PHP&amp;diff=76308"/>
		<updated>2010-09-29T09:25:47Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* New Related links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* http://www.oracle.com/technology/pub/notes/technote_php_instant.html&lt;br /&gt;
* http://moodle.org/mod/forum/discuss.php?d=65488#p308002 (with attached html document)&lt;br /&gt;
* http://es.php.net/oci8&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important Note:&#039;&#039;&#039; Don&#039;t forget to enable this variable in your php.ini (or .htaccess)  file:&lt;br /&gt;
&lt;br /&gt;
(else, all your data will be escaped following MySQL rules, that are incorrect for Oracle)&lt;br /&gt;
&lt;br /&gt;
    magic_quotes_sybase = On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Broken versions of OCI8 driver ==&lt;br /&gt;
&lt;br /&gt;
PHP v5.2.4 (and perhaps v5.2.3 as well) have shipped with a bug in the OCI8 driver that leaks statement handles. The version of the OCI8 driver with the bug is v1.2.4. Possible workarounds:&lt;br /&gt;
&lt;br /&gt;
* Upgrade to PHP v5.2.5 or later&lt;br /&gt;
* Downgrade to PHP v5.2.1 (reported to work)&lt;br /&gt;
* Downgrade only the oci8 driver to the one included in PHP 5.2.1 (it worked for us -- iarenaza)&lt;br /&gt;
* If you are on linux and/or can compile PECL extensions, install an older OCI8 driver (v1.2.3 seems to work) from the PECL repository http://pecl.php.net/package/oci8&lt;br /&gt;
&lt;br /&gt;
More information at&lt;br /&gt;
* http://bugs.php.net/bug.php?id=42496 -- tracking the PHP OCI8 bug&lt;br /&gt;
* http://tracker.moodle.org/browse/MDL-11429 -- diagnostics on the Moodle side&lt;br /&gt;
&lt;br /&gt;
== Installing Moodle on Windows with Oracle Express Edition ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
This section explains how to install Moodle with Oracle Express Edition on Windows. I&#039;m using it for &#039;&#039;&#039;debugging&#039;&#039;&#039; purpose. It&#039;s definitively not a production environment. The goal is to setup easily and quickly a Moodle/Windows/Oracle environment.&lt;br /&gt;
&lt;br /&gt;
=== Install Oracle ===&lt;br /&gt;
Download Oracle Express Edition on [http://www.oracle.com/technology/products/database/xe/index.html Oracle web site].&amp;lt;br /&amp;gt;&lt;br /&gt;
You will also need the Instant client [http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/winsoft.html from here] (free account sign up needed). Copy everything from the unzipped folder into apache/bin. &amp;lt;br /&amp;gt;&lt;br /&gt;
Install both.&amp;lt;br /&amp;gt;&lt;br /&gt;
Access to the oracle console (http://127.0.0.1:8080/apex). Login: SYS Password: the_one_you_entered_during_the_installation&amp;lt;br /&amp;gt;&lt;br /&gt;
Create a new user and give it all rights (including DBA).&amp;lt;br /&amp;gt;&lt;br /&gt;
Note: Oracle Express Edition 10g is limited at one database called &#039;XE&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Set up your oracle extension ===&lt;br /&gt;
This document does not explain how to setup apache/php for Oracle. You can have more information on [http://www.oracle.com/technology/tech/php/htdocs/php-oracle-tutorial.html Oracle Documentation]. On my own machine I used my WAMP installation ([http://www.en.wampserver.com/ Wampserver 2.0]) which allowed me to activate all oracle extensions in few clicks (php_oci8, php_oracle, php_pdo_oci, php_pdo_oci8).&lt;br /&gt;
&lt;br /&gt;
=== Install Moodle ===&lt;br /&gt;
On the database setup page:&amp;lt;br /&amp;gt;&lt;br /&gt;
Driver: Oracle oci8&amp;lt;br /&amp;gt;&lt;br /&gt;
Host: empty the field&amp;lt;br /&amp;gt;&lt;br /&gt;
Database: //localhost:1521/XE&amp;lt;br /&amp;gt;&lt;br /&gt;
User: the user that you created&amp;lt;br /&amp;gt;&lt;br /&gt;
Password: the password you gave to the user&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Related links ==&lt;br /&gt;
* [http://lewiscarr.co.uk/node/4 Installing ORACLE drivers with PHP]&lt;br /&gt;
*[[Installing MSSQL for PHP]]&lt;br /&gt;
*[[PHP]]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=134729#p588963 Can i install Moodle with Oracle database]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=65488 Who uses Oracle]&lt;br /&gt;
*[https://docs.moodle.org/en/Step-by-step_Install_Guide_for_Solaris_10_with_Oracle_10 Step by step Install Guide for Solaris 10 with Oracle 10]&lt;br /&gt;
*[http://learningischange.com/2009/05/29/install-moodle-on-an-oracle-database-in-25-minutes-or-less/ Install Moodle on an Oracle Database (in 25 minutes or less)]. The related Using Moodle forum discussion is [http://moodle.org/mod/forum/discuss.php?d=124629 here].&lt;br /&gt;
*[http://www.mguhlin.org/2009/05/moodle-on-oracle-database.html Moodle on Oracle Database] discussion on Miguel Guhlin&#039;s blog &lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=admin/environment/php_extension/intl&amp;diff=75803</id>
		<title>admin/environment/php extension/intl</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=admin/environment/php_extension/intl&amp;diff=75803"/>
		<updated>2010-09-14T14:08:51Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Formatting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Internationalization extension (Intl) is a wrapper for the ICU library, a set of C/C++ and Java libraries that provide Unicode and Globalization support for software applications. It enables PHP programmers to perform UCA-conformant collation and date/time/number/currency formatting in their scripts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To enable this extension add the following line to your php.ini file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
extension=php_intl.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And then set the &#039;&#039;intl.default_locale&#039;&#039; and &#039;&#039;intl.error_level&#039;&#039; directives in your php.ini file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[intl]&lt;br /&gt;
&lt;br /&gt;
intl.default_locale = en_utf8&lt;br /&gt;
&lt;br /&gt;
intl.error_level = E_WARNING&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;intl.error_level&#039;&#039; directive is optional.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
[http://www.php.net/manual/en/intro.intl.php INTL Introduction]&lt;br /&gt;
&lt;br /&gt;
[http://www.php.net/manual/en/book.intl.php PHP Internationalization Functions]&lt;br /&gt;
&lt;br /&gt;
[https://docs.moodle.org/en/Table_of_locales Table of locales] lists the locales that you can use.&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/21/en/index.php?title=admin/environment/php_extension/intl&amp;diff=75802</id>
		<title>admin/environment/php extension/intl</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/21/en/index.php?title=admin/environment/php_extension/intl&amp;diff=75802"/>
		<updated>2010-09-14T14:03:31Z</updated>

		<summary type="html">&lt;p&gt;Libertymoodle: /* Typos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Internationalization extension (Intl) is a wrapper for the ICU library, a set of C/C++ and Java libraries that provide Unicode and Globalization support for software applications. It enables PHP programmers to perform UCA-conformant collation and date/time/number/currency formatting in their scripts.&lt;br /&gt;
&lt;br /&gt;
To enable this extension add the following line to your php.ini file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
extension=php_intl.dll&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And then set the &#039;&#039;intl.default_locale&#039;&#039; and &#039;&#039;intl.error_level&#039;&#039; directives in your php.ini file.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;intl.error_level&#039;&#039; directive is optional.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[intl]&lt;br /&gt;
&lt;br /&gt;
intl.default_locale = en_utf8&lt;br /&gt;
&lt;br /&gt;
intl.error_level = E_WARNING&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
[http://www.php.net/manual/en/intro.intl.php INTL Introduction]&lt;br /&gt;
&lt;br /&gt;
[http://www.php.net/manual/en/book.intl.php PHP Internationalization Functions]&lt;br /&gt;
&lt;br /&gt;
[https://docs.moodle.org/en/Table_of_locales Table of locales] lists the locales that you can use.&lt;/div&gt;</summary>
		<author><name>Libertymoodle</name></author>
	</entry>
</feed>