Moodle is an open source Learning Management System (LMS). It can be used to deliver online learning in a variety of settings. These settings include virtual schools, K12, higher education, corporate universities, charter schools, and commercial training, to name but a few. Moodle is designed to be used primarily as an asynchronous learning tool, where learners study at different times. However, it also includes synchronous tools. Moodle is used both as the primary delivery vehicle for courses as well as a supplemental tool for face-to-face learning. To put it simply, Moodle is a teacher's toolkit to help improve learning. Moodle is designed in a community with teachers interacting directly with programmers. Moodle's intuitive and simple interface is the result of this collaboration.
Moodle originally stood for Modular Object-Oriented Dynamic Learning Environment. From a programmer's perspective, the "M" in Moodle is a very important concept. Modularity is designed throughout Moodle. This lets a developer make significant modifications to Moodle without having to modify its code. This is a very important capability in terms of reducing the amount of time taken to make modifications when new versions of Moodle are released. Writing modular plugins for Moodle will be a large focus of this book.
You can learn more about general Moodle functionality and history on the Moodle Documentation site at http://docs.moodle.org/en/About_Moodle.
This chapter introduces some of the important concepts of Moodle architecture; how Moodle is structured and how Moodle works. This chapter introduces the following concepts:
Components of the system (operating system, web server, PHP interpreter, database, and browser)
Directory and system structure (Moodle code, database, and file storage)
Installation (how to install, what happens during installation, and how to upgrade)
Program execution (the major calling structure, included libraries, execution paths, and separation of function/display/data)
Configuration (from the interface, from the
config
file, and from the database)Application Programming Interface (a brief description of what the major libraries do)
Other common libraries (PEAR, ADOdb, YUI, and XMLDB)
Access control for users, courses, and other security objects
As you can see from the list, we will be covering a lot of ground in this chapter. Let's get started with a discussion of the technology stack that drives Moodle.
Moodle is an example of a "LAMP" application. LAMP originally stood for Linux, Apache, MySQL, and Perl. Over time, the various components of the acronym have shifted. For example, PHP has become the predominate language for "LAMP" applications. In truth, any of the components can be exchanged for another. However, the title has stuck to refer to applications written in web scripting languages, using an SQL database to store information. With the increasing popularity of running open source web applications on both Windows and Mac OS X, two new terms have been coined, respectively: WAMP and MAMP. See the following figure, which illustrates components of the system in Moodle:

Moodle is written in PHP, and the current version as of this writing (Version 1.9) requires PHP Version 4.3.0 or higher. Version 2.0 of Moodle, which is currently in development, will require PHP Version 5.2.8 or higher.
Moodle's database layer is written using the PHP ADOdb library, which was created to provide a standardized method of accessing various database systems, using a consistent programming interface. PHP native database libraries are database specific and as a result are difficult to use to write a program that can support multiple database servers. Thanks to its use of ADOdb, Moodle provides support for a variety of databases including: MySQL, PostgreSQL, Microsoft SQL, and Oracle. Moodle supports a much longer list of databases for the purpose of external system integrations, by using its plugin architecture. While Moodle does enjoy broad database support, in practice, most systems are deployed using MySQL. As a practical result of this, more eyes are looking at MySQL installations; it has the fewest bugs, with the broadest set of third-party additions. PostgreSQL is the second most popular backend and has a strong following amongst performance enthusiasts and large deployments (tens of thousands or more users). Microsoft SQL and Oracle installations are primarily used by organizations with a pre-existing investment in one of these architectures. Because of their smaller user base, they are not as well tested. It is also more difficult to find good support for using these database types with Moodle. Many third-party add-on modules do not work under these systems without patching.
Database version requirements for Moodle 1.9:
Proposed database requirements for Moodle 2.0:
The latest version of these requirements can be viewed at the following URL: http://docs.moodle.org/en/Environment#Moodle_version_1.9.
Note that the specifications for the Moodle 2.0 database layer can be found at the following location: http://docs.moodle.org/en/Development:DB_layer_2.0.
Moodle can run on any operating system that supports the required version of PHP and the database. Moodle is generally installed on one of the three major operating systems: Windows, Mac OS X, or Linux (or Unix/Unix-like operating systems). As compared to Linux, both Mac OS X and Windows operating systems suffer from less efficient performance for large-scale deployments. For Windows, this is due to a less-optimized PHP stack, and for Mac OS X it is due to poor process forking performance, which both Apache and MySQL rely on for high concurrency. Windows Server 2008 is reported in press releases by both Microsoft and Zend, the creator of PHP, as having improved PHP performance. In a development environment, you can use any of these operating systems as an excellent platform. In a production environment, each operating system will have different performance characteristics.
Moodle will typically work with any web server that supports running the appropriate versions of PHP. In practice, the most used web server is Apache, which is available for most operating systems. Internet Information Services (IIS) is another popular web server for hosting Moodle. There are also a growing number of advocates for Lighthttpd as a web server, and this is reported in the Moodle community forums (http://moodle.org/forums/) as working well with Moodle. Lighthttpd has a growing number of advocates due to its low memory design. It is extremely popular for its use with virtual environments (VMware, Xen, and Amazon Elastic Compute Cloud), where memory footprint is more of a concern.
Moodle as a web application has support and development constraints that are different from the norm. This is due to the way in which Moodle is used. A user interacting with Moodle will have a higher than normal amount of clicks, and Moodle generates many SQL queries as it builds a page. Moodle is very efficient at what it does. However, what it does is fairly complex. This means, as developers, we need to be aware of the type of architectures that our modifications will likely be used within. It also means that we need to be aware of the performance implications of our coding. The following figure illustrates several common configurations used for Moodle in a production environment. Moodle is deployed in a broad range of settings—anywhere from a single teacher running it on his or her desktop all the way up to multi-machine clusters of high performance servers:

Moodle, as is common with the standard PHP application model, scales at particular points. The first scaling point is the database, which can easily be moved to a separate physical server. After that, we can bring in additional frontend web servers by using a load balancer. When using multiple web servers we will also need shared storage for our Moodle data. Session data can be stored in either Moodle data or in the database. The database server is the point where Moodle's scalability is most limited. To scale the database it is necessary to bring in a faster database server, replacing the older server. Currently, there is no standard method for scaling a single Moodle installation across multiple master database servers, as we do with the web application servers. It is also common practice to use Moodle with a PHP accelerator such as eAccelerator or APC. It's important to test your code in these environments to make sure that it functions correctly.
Moodle is an example of a "LAMP" application. LAMP originally stood for Linux, Apache, MySQL, and Perl. Over time, the various components of the acronym have shifted. For example, PHP has become the predominate language for "LAMP" applications. In truth, any of the components can be exchanged for another. However, the title has stuck to refer to applications written in web scripting languages, using an SQL database to store information. With the increasing popularity of running open source web applications on both Windows and Mac OS X, two new terms have been coined, respectively: WAMP and MAMP. See the following figure, which illustrates components of the system in Moodle:

Moodle is written in PHP, and the current version as of this writing (Version 1.9) requires PHP Version 4.3.0 or higher. Version 2.0 of Moodle, which is currently in development, will require PHP Version 5.2.8 or higher.
Moodle's database layer is written using the PHP ADOdb library, which was created to provide a standardized method of accessing various database systems, using a consistent programming interface. PHP native database libraries are database specific and as a result are difficult to use to write a program that can support multiple database servers. Thanks to its use of ADOdb, Moodle provides support for a variety of databases including: MySQL, PostgreSQL, Microsoft SQL, and Oracle. Moodle supports a much longer list of databases for the purpose of external system integrations, by using its plugin architecture. While Moodle does enjoy broad database support, in practice, most systems are deployed using MySQL. As a practical result of this, more eyes are looking at MySQL installations; it has the fewest bugs, with the broadest set of third-party additions. PostgreSQL is the second most popular backend and has a strong following amongst performance enthusiasts and large deployments (tens of thousands or more users). Microsoft SQL and Oracle installations are primarily used by organizations with a pre-existing investment in one of these architectures. Because of their smaller user base, they are not as well tested. It is also more difficult to find good support for using these database types with Moodle. Many third-party add-on modules do not work under these systems without patching.
Database version requirements for Moodle 1.9:
Proposed database requirements for Moodle 2.0:
The latest version of these requirements can be viewed at the following URL: http://docs.moodle.org/en/Environment#Moodle_version_1.9.
Note that the specifications for the Moodle 2.0 database layer can be found at the following location: http://docs.moodle.org/en/Development:DB_layer_2.0.
Moodle can run on any operating system that supports the required version of PHP and the database. Moodle is generally installed on one of the three major operating systems: Windows, Mac OS X, or Linux (or Unix/Unix-like operating systems). As compared to Linux, both Mac OS X and Windows operating systems suffer from less efficient performance for large-scale deployments. For Windows, this is due to a less-optimized PHP stack, and for Mac OS X it is due to poor process forking performance, which both Apache and MySQL rely on for high concurrency. Windows Server 2008 is reported in press releases by both Microsoft and Zend, the creator of PHP, as having improved PHP performance. In a development environment, you can use any of these operating systems as an excellent platform. In a production environment, each operating system will have different performance characteristics.
Moodle will typically work with any web server that supports running the appropriate versions of PHP. In practice, the most used web server is Apache, which is available for most operating systems. Internet Information Services (IIS) is another popular web server for hosting Moodle. There are also a growing number of advocates for Lighthttpd as a web server, and this is reported in the Moodle community forums (http://moodle.org/forums/) as working well with Moodle. Lighthttpd has a growing number of advocates due to its low memory design. It is extremely popular for its use with virtual environments (VMware, Xen, and Amazon Elastic Compute Cloud), where memory footprint is more of a concern.
Moodle as a web application has support and development constraints that are different from the norm. This is due to the way in which Moodle is used. A user interacting with Moodle will have a higher than normal amount of clicks, and Moodle generates many SQL queries as it builds a page. Moodle is very efficient at what it does. However, what it does is fairly complex. This means, as developers, we need to be aware of the type of architectures that our modifications will likely be used within. It also means that we need to be aware of the performance implications of our coding. The following figure illustrates several common configurations used for Moodle in a production environment. Moodle is deployed in a broad range of settings—anywhere from a single teacher running it on his or her desktop all the way up to multi-machine clusters of high performance servers:

Moodle, as is common with the standard PHP application model, scales at particular points. The first scaling point is the database, which can easily be moved to a separate physical server. After that, we can bring in additional frontend web servers by using a load balancer. When using multiple web servers we will also need shared storage for our Moodle data. Session data can be stored in either Moodle data or in the database. The database server is the point where Moodle's scalability is most limited. To scale the database it is necessary to bring in a faster database server, replacing the older server. Currently, there is no standard method for scaling a single Moodle installation across multiple master database servers, as we do with the web application servers. It is also common practice to use Moodle with a PHP accelerator such as eAccelerator or APC. It's important to test your code in these environments to make sure that it functions correctly.
As shown in the following figure, each working Moodle system can be divided into three separate areas: Moodle code, the Moodle database, and Moodle data.

Because PHP is an interpreted language, the Moodle code is stored as source code files on the web server. When a particular file is requested on the server, the PHP interpreter parses the code on the fly, and the resulting output is sent out via the web server software. As mentioned earlier, the "M" in Moodle stands for "Modular", and its directory structure reflects that. Each top-level folder represents a major component of Moodle. Many of the main components support plugin modules. Each plugin has its own folder inside the component's folder. In some cases, modules will also have support for additional plugins. An example of this is the quiz activity module, which supports modular question types. From the end user point of view, modules are installed by copying the module into the appropriate folder location on the server. Moodle detects the new module the next time that an administrator logs into the system, locates the module's SQL code, runs it, and finally displays the results.
Upgrades work in much the same way with Moodle, tracking the database version and automatically upgrading the database as needed. All of this easy interface for end users comes at the cost of some elbow grease for the developer.
The following screenshot is a directory listing of a recent Moodle 1.9 installation:

We will not cover all of the directories in the main folder at this time. However, we will explore the functions of some of the important folders used by developers who make modifications to Moodle. Moodle uses a simple nomenclature for modules, where all of the modules are enclosed in their own folder, and the name of the folder is the name that Moodle displays in its interface when referring to the module.
admin:
This folder stores the PHP files that control the administrative user's interface. They also contain the cron.php
file, which is run as a batch process to perform system maintenance tasks such as message delivery and course backups. We will often hook into the cron.php
process to perform batch operations.
auth:
The auth
folder contains all of the authentication modules for Moodle. Each module will have its own directory in this area. Authentication modules control the creation of users, user profile data, and user access to the system. Authentication modules are great for automating system administration, and as a result are a common customization project.
backup:
This folder contains the core course backup facilities for the system. These are not system-wide backup facilities but functions for the backup, restore, and import of courses. Each individual course module is responsible for its own backup code and makes use of these functions as needed. Each module is self-contained, allowing us, as developers, to add modules cleanly to Moodle without having to modify the core code.
blocks:
blocks
are used to display boxes of information in either the right-hand side or left-hand side column of the Moodle page. This is one of the simplest module types to make, and also tend to work across multiple versions of Moodle with little or no modifications.
course:
This component of Moodle has obvious importance, given that Moodle is organized around courses. As developers, we are most likely to modify or add course formats and reports. Custom course formats can be used to change the layout of courses.
enrol:
The enrol
folder contains all of the enrollment modules for Moodle. Enrollment modules control the creation and management of course-level role assignments (enrollments). Enrollment modules are another key automation hook.
files:
The files
component allows Moodle to incorporate files into the system. This includes file uploads, access control, and the viewing of files. files
will see a major rewrite in Moodle 2.0. Moodle 2.0 will allow storing and using files in external file repositories such as Alfresco, Box.net, and Google Docs.
filter:
The Moodle filtering system is a text/regular expression-based search-and-replace facility. The filter system is fed user-entered content from the database during page creation. Filters match and modify the page before it is displayed. For example, there is a math
filter that supports auto conversion of TEX markup language to equation graphics. The Multimedia Plugins filter finds references to common media types and wraps the text in the appropriate embed and/or object tags, in order to automatically embed the media, along with player controls, into the page. This is a very powerful capability. However, it needs to be carefully developed, with performance implications in mind.
lang:
The lang
folder stores the core system language strings. This is the foundation of Moodle's localization and language support. All of the strings displayed to the end user are mapped via this facility. Language string mappings are also stored in the Moodle data lang
folder. This structure allows for easy local customization of language files.
The following is a small section of the /lang/en_utf8/moodle.php
language file. Notice how each string that is displayed to the end user is mapped to a string hash by using a key value that is descriptive of the strings purpose (in English):
$string['abouttobeinstalled'] = 'about to be installed'; $string['action'] = 'Action'; $string['actions'] = 'Actions'; $string['active'] = 'Active'; $string['activeusers'] = 'Active users';
lib:
The lib
folder stores the core system library functions. As we develop modules and customizations, we will use classes and functions defined in this folder.
mod:
The mod
folder stores activity modules such as assignment, quiz, wiki, forum, and lesson modules. Learning activities are the core of any course delivered using Moodle. Activity modules are more challenging to create than blocks, because they back up, restore, and store grades. Oh, and of course, they have to teach something to the learner.
my:
my
is a light-weight portal area in Moodle. It provides a listing of courses a learner is assigned, including a summary of upcoming course activities. The user can also add and remove blocks on his or her portal page. my
provides a good location to display custom information with minimal core changes to Moodle. For example, we use my
as a dashboard location in many of our customization projects.
theme:
The theme
folder stores all of the built-in Moodle themes and any custom themes installed on the system. Themes are a combination of CSS, HTML, and PHP. Each theme has its own folder. The theme system is useful for defining the visual skin, header, and footer of the Moodle page. It is, however, limited in how much of the Moodle page it can modify. For example, certain components of the Moodle page are hardcoded to display in a certain way.
The Moodle database is organized into roughly 200 related tables. The default installation option prepends mdl_
in front of each table name. Each major component of the system typically has one or more tables, each starting with the component's name. For example, there are two tables related to the config
component: mdl_config
and mdl_config_plugins
. As programmers, we will have to manipulate the database on a regular basis. It's also important for us to be able to treat the entire database as an entity, copying and moving instances of an entire Moodle database for the creation of staging and testing areas as we develop our code. We generally do this by using command-line utilities such as mysqldump and MySQL.
Moodle data is the file storage location for user-uploaded content. Moodle data also stores the session data for users logged into the system, if file-based sessions are being used. Moodle data also stores optional language packs that can be downloaded from Moodle's administration interface. Moodle structures the data in this folder by either the user or by the course. Most of the data by file count and size will be in the courses. Each course has a folder, which is named with an integer value. The integer value is set to the internal database ID of the course in question. We can easily determine these values by navigating to a course via the Moodle web interface and inspecting its URL. For example, examine this URL for a course on my local test Moodle
http://localhost/workspace/moodle19/course/view.php?id=3.
Note the id=3
at the end of the URL. If we have uploaded any files to this course, there will be a folder path_to_moodledata/3
. Within a course folder, Moodle will store module data in the moddata
folder. When a module needs to store files, it saves them here in a folder with the same name as the module. For example, the wiki module will have a folder here named wiki
. Additionally, Moodle will create a folder called backupdata
if any course backups have been created. Any files that have been uploaded directly by a user using the course files interface will be loaded into the root of this folder. Users can also create their own folders and sub folders within the root folder.
Moodle 2.0 uses an entirely new organizational model for user-uploaded files, which is based on a hashing algorithm. The primary goal of this new method is to support efficient use of disk storage space and greater flexibility for using files across multiple courses.
There are many ways to install Moodle. One of the simplest ways is to download one of the all-in-one installers from http://moodle.org. These are labeled as Moodle for Windows and Moodle for Mac OS X under the Downloads menu at http://moodle.org. These all-in-one installers contain both Moodle and all of the necessary server software, including Apache, PHP, and MySQL. While these packages are not recommended for production use, they can provide a convenient starting point for a developer new to Moodle.
To manually install Moodle, download the Moodle source code files from http://moodle.org. You will find a variety of download packages. Each package is labeled with the version number. Major versions of Moodle are numbered in tenths: 1.6, 1.7, 1.8, and so on. Major versions focus on adding new features and bug fixes, which require major system changes to be implemented. Each major release has a number of minor point releases. For example: 1.9.1, 1.9.2, 1.9.3, and so on. Minor point releases focus on bug fixes and security updates. Finally, there are 'plus' releases that contain nightly or weekly fixes.
From a developer's perspective, it makes sense to use the official CVS feeds to get Moodle's source code. This allows for easier updates and code merges, as well as integrating with many popular development tools. See http://docs.moodle.org/en/CVS_for_Administrators.
Once you have the source code, it needs to be copied to your server's web root. You should then create a folder (outside of the web root) for Moodle data, which is writable by the web server software. From your SQL server, create an empty database for Moodle to use. Finally, once this is done, you should enter the server's address and path to Moodle into your web browser. This will initiate the Moodle web installer and walk you through the rest of the installation options. During the installation you will be asked to enter details for your database. Once these have been entered, Moodle will connect to the database and create all 200+ tables. At the end of the installation it will write a config.php
file to your Moodle directory with the values that you entered during installation. The following screenshot illustrates the first screen of the Moodle installer, where we select our default language:

Upgrades follow the same basic pattern. Download the new code, copy it on the server in place of the old code (note that in most cases, you can copy the new code over the top of the old folder contents), and then visit the Moodle site in your web browser. Moodle will detect a version change by comparing the version tags stored in its configuration database against the ones reported in the module code, and then initiate the upgrade. Each module is responsible for its own database upgrades.
The final consideration for our development environment is to have a development tool for writing our code. While it is perfectly possible to write PHP code in any text editor (and many do), a popular option is to use the PHP plugin for Eclipse, or NetBeans. Detailed instructions for optimizing this setup can be found at http://docs.moodle.org/en/Setting_up_Eclipse_for_Moodle_development.
Moodle has many entry points—scripts that are called for execution. These are the files that are called by the browser to execute Moodle's functions. While there are many, the main ones are:
Let's walk through a typical script, and follow the execution path. For the walkthrough, we will use the main course display script, /course/view.php
. For this example, let's assume that we are using http://localhost/course/view.php?id=23.
Before we jump in, let's analyze the URL a bit. The portion up to /course
will be the URL of your Moodle site. The /course/
portion is the directory in Moodle that contains the course-handling scripts. The meat of the URL is the portion view.php?id=23
. This script displays a course page. The course it displays is identified by the id=23
parameter, where 23
is the data ID of the course in question. If you look in the course
data table in the database for your Moodle site, you will find an entry with the 'id' field equal to 23. The very first executable line we see in the script is:
require_once('../config.php');
All of the entry scripts include the same important file: config.php
. This is the only file in Moodle that must be included by specifying the exact literal path. This file performs a number of initial parameter assignments in the global $CFG
variable. This provides the minimal amount of information to run the rest of the system; among this information are the database, web URL, script directory, and data storage directory definitions.
Lastly, and most importantly, config.php
includes /lib/setup.php
.
config.php
performs some basic, important variable assignment, whereas setup.php
performs all of the initial program execution required to complete the execution environment setup. This includes defining several other important global variables, including $SESSION, $COURSE, $THEME
, and $db
.
Next, it sets up and connects your database according to the settings defined in config.php
. Moodle uses the open source ADOdb libraries to manage database functions. These functions are loaded through the inclusion of /lib/adodb/adodb.inc.php
.
Next, some critical library files are included that will be used by pretty much every other function in Moodle. These libraries include the functions required to manage multibyte strings, HTML output, Moodle data, access controls, events, groups, and general purpose Moodle and PEAR libraries.
The remainder of the file sets up some other critical global variables, loads configuration variables from the database, sets up caching, sessions, environment variables, themes, language, and locales.
After including config.php
, our script includes some other library files:
require_once('lib.php'); require_once($CFG->libdir.'/blocklib.php'); ...
This uses the PHP construct require_once
, in case any of the files were included elsewhere first. Any file not located in the same directory is fully specified using directory definitions defined in config.php
. You will notice lib.php
has no directory specification, as it is located in the same directory as view.php
. Likewise, the remaining files have full paths using directory definitions set up by config.php
. You will notice the use of $CFG->libdir
and $CFG->dirroot
. The first is the defined file path to the main library directory (usually the lib
subdirectory of the Moodle file path), while the second is the defined Moodle file path. Next, our script checks for, and loads, any parameters that it expects to get from the URL:
$id = optional_param('id', 0, PARAM_INT); $name = optional_param('name', '', PARAM_RAW); ...
It does this by using the Moodle optional_param
function, which loads the specified variable with a named parameter value if one is present, or a default value if not. If the parameter is required for the script to work properly, then the function required_param
should be used instead. Both of these functions validate the data based on the specified arguments, and will generate errors or warnings if something other than what was expected is passed in. This is critical to securing user input in case of any additions to Moodle. SeeChapter 10, Writing Secure Code for more information.
Next, our script loads the specific records that it needs from the database:
if (! ($course = get_record('course', 'id', $id)) ) { error('Invalid course id'); }
This can be done with either a database call, as above, or a specific API call.
At this point, our script has enough information to check if the user has permissions to access its basic functions. This is done by loading contexts, checking the user login, and verifying capabilities:
preload_course_contexts($course->id); if (!$context = get_context_instance(CONTEXT_COURSE, $course->id)) { print_error('nocontext'); } require_login($course);
Much of the capability verification is performed by the require_login
function. It verifies that the user is logged in (if necessary—some courses may not require that) and redirects them to the login function if required. It also loads and checks specific capabilities, including whether or not the user has access to the course. It also verifies enrollment and redirects the user to the enrollment function if necessary.
Next, our script will perform the necessary programming required to carry out its functions. Once it has finished this, it will begin the display process. The main functions for display are the print_header
and print_header_simple
functions. The following script uses the print_header
function from the PAGE
object it set up:
$PAGE->print_header(get_string('course').': %fullname%', NULL, '', $bodytags);
This function starts the HTML output by writing the HTTP headers, the theme information, requested JavaScript files, and other header section information. Then it begins with the body section.
The body output is handled by the specific course format. Whatever format has been specified for the course in question in its settings, handles the body output. This is done as follows, by including the file format.php
from the subdirectory of the format in question:
require($CFG->dirroot .'/course/format/'. $course->format .'/ format.php');
If the course used the topics
format (for example), then the file would be /course/format/topics/format.php
. This file handles the specific course page output, including the blocks and main content. It uses library functions found in /course/lib.php
to output the section's content. Lastly, the script outputs the footer:
print_footer(NULL, $course);
This function closes the body and completes the output to the screen. In most cases, this will be the last function executed for a script.
Moodle is a highly-configurable application, with many complex settings in many areas of its functionality. These settings can be modified by Moodle administrators through:
Direct code in the main
config.php
fileThe
mdl_config
table via administrative code and interfacesThe
mdl_config_plugins
table via plugin administration
During program execution, all of the main configuration values are stored in the $CFG
global variable. $CFG
is a generic structure. Each configuration variable is an element of the $CFG
structure. For example, the $CFG->theme
contains the text name of your site's selected theme.
The elements of $CFG
are loaded by direct assignment, and from values stored in the database mdl_config
table. The primary point of direct assignment takes place in /config.php
. Here, the initial, necessary configuration settings are made.
There are minimal assignments that must be defined in this file. You are prompted for these values when you install Moodle, and you can change them afterwards by editing this file. The minimal settings are as follows:
$CFG->dbtype = 'mysql'; // mysql or postgres7 (for now) $CFG->dbhost = 'localhost'; // eg localhost or db.isp.com $CFG->dbname = 'moodle'; // database name, eg moodle $CFG->dbuser = 'username'; // your database username $CFG->dbpass = 'password'; // your database password $CFG->prefix = 'mdl_'; // Prefix to use for all table names $CFG->dbpersist = false; // Should database connections be // reused? $CFG->wwwroot = 'http://example.com/moodle'; $CFG->dirroot = '/home/example/public_html/moodle'; $CFG->dataroot = '/home/example/moodledata'; $CFG->directorypermissions = 02777; $CFG->admin = 'admin';
There are other optional settings that can be made in this file. Review your /config-dist.php
file to see all of these settings.
Historically, any configuration settings that did not have a UI available to set these were set via code statements in this file. These often include new, experimental features.
The remainder of the $CFG
elements are set from the database. This is done through a call to the library function get_config
(located in the /lib/moodlelib.php
library file) from /lib/setup.php
, which is included as the last action of config.php
. The important thing to know about the function get_config
is that it will not overwrite any $CFG
setting that has already been set. This means you can overrule any database setting by hardcoding it into config.php
. Also, config.php
clears out the $CFG
structure before it does anything else. This guarantees that nothing sets any configuration variables before config.php
and setup.php
.
As a developer, you can set and use configuration variables for your functionality. You can set a configuration variable through the set_config
function. The set_config
function takes a name, a value, and an optional plugin name as arguments. The name becomes the element of the $CFG
structure and the passed value becomes its value. Additionally, this will be stored into the database mdl_config
table, so that it can be loaded on every program execution from then on. You can also specifically request a configuration variable at any time, by using the get_config
function, but you won't need to, because it will be loaded into the $CFG
structure once it has been set.
The one issue that you need to consider when creating your own configuration variable is that the variable name you choose must be unique. Your variable becomes meaningless if you choose one that already exists. As most customizations you will be developing are likely to be plugins (modules, blocks, and so on), Moodle provides an alternate way to store configuration variables that are plugin specific.
Plugin configuration variables are loaded into the plugin structure itself, rather than into the $CFG
global structure. This means that the configuration variable name only needs to be unique to the plugin. Plugin configuration variables are stored in the mdl_config_plugin
table, with the name of the plugin. They can be set and retrieved by using the same set_config
and get_config
functions as before.
Generally, configuration variables are set by using administration interfaces. Most of the Moodle configuration variables are set through the various settings pages in the Site Administration menu block, which is visible on the home page of your Moodle site. In future sections, you will learn how the plugins add their interfaces to this structure. The following screenshot displays an example of Moodle's Site Administration block:

Moodle's API is a mix of library functions and classes. Moodle was originally based on the version 4 series of PHP, and as such, most of its API is built around functions defined in PHP library files. However, some of the newer constructs of Moodle use object-oriented structures and as such provide extensible classes.
Most of Moodle's main libraries are kept in the /lib/
directory. All of these files generally adhere to the naming convention [function]lib.php
. Some of the examples are textlib.php
and weblib.php
. These library files contain Moodle's API.
Almost all of the core libraries are included in the execution stream when you load config.php
via its inclusion of /lib/setup.php
. The setup.php
file includes these via the following lines:
require_once($CFG->libdir .'/textlib.class.php'); // Functions to handle multibyte strings require_once($CFG->libdir .'/weblib.php'); // Functions for producing HTML require_once($CFG->libdir .'/dmllib.php'); // Functions to handle DB data (DML) require_once($CFG->libdir .'/datalib.php'); // Legacy lib with a big-mix of functions. require_once($CFG->libdir .'/accesslib.php'); // Access control functions require_once($CFG->libdir .'/deprecatedlib.php'); // Deprecated functions included for backward compatibility require_once($CFG->libdir .'/moodlelib.php'); // Other general-purpose functions require_once($CFG->libdir .'/eventslib.php'); // Events functions require_once($CFG->libdir .'/grouplib.php'); // Groups functions
These by no means define all of the functions available in Moodle, and in fact each of these libraries may include other libraries. However, the core of the functions that you will need are contained within these libraries. In fact, the ones that you will need to look at the most are:
moodlelib.php
weblib.php
dmllib.php
accesslib.php
grouplib.php
There are many other libraries that you will use, as you start to carry out specific functions. Most of these are stored in the /lib/
directory. However, others may be in specific functional areas such as /course/
and /blocks/
.
Many of the specific libraries define classes that you can use. Libraries such as /lib/pagelib.php
and /lib/formslib.php
define classes that are designed to be extended in order to handle output to screen. pagelib.php
defines specific page types, with all of the functions necessary to manage page output and create your own page types. Likewise, formslib.php
defines Moodle's implementation of the PEAR QuickForm classes in order to handle web-based forms.
There is no single, all-encompassing document for all of Moodle's API. However, you can find out more about each specific area in the developer documentation at Moodle Docs. A good place to start is http://docs.moodle.org/en/Development:Developer_documentation#Core_components_that_affect_everything.
Another resource that can help is the Moodle code cross reference. This is an online resource that is generated from the code and inline comments in order to produce documentation. It is generated automatically by using PHPXref. The reference can be found at http://docs.moodle.org/en/Development:Code_Cross-Reference. Note that it may not be up-to-date and maintained. Still, it does provide an easy overview.
Moodle relies on a number of libraries, both internal and external. Several of these are explained below:
PEAR stands for PHP Extension and Application Repository. As such, it's not a single library but a set of tools for getting and updating PHP libraries and modules.
ADOdb is a database library that provides a unified programming interface for a large variety of databases. Although Moodle supports a limited core set of databases for its direct backend, ADOdb really shines through in the supported databases for both the external database authentication and the enrollment plugins.
The Yahoo! User Interface (YUI) library is written in JavaScript, and is used to create rich web interfaces using AJAX, DOM, and DHTML. The Moodle course editing interface relies on this library for drag-and-drop placement of course elements.
XMLDB was added to Moodle as part of the initiative to add Microsoft SQL and Oracle backend support for Moodle. XMLDB rationalized all of the database configuration files to XML schemas, so that the same files could be used across all four supported backends. This extended upon the capabilities available from ADOdb, providing a single code base for accessing all databases supported, while still providing appropriate performance.
As open as Moodle is, it is tight with its security. It goes to great efforts to make sure that anyone accessing the system is supposed to be accessing the system, and they are supposed to be accessing it the way they are trying to.
Moodle has a powerful access control and permission system. At the core of the access system is the user account. Although it is possible to grant access to any visitor to your site without authenticating them, it doesn't allow them to do many interesting things. We will assume that you want to know who your users are, and that you will want them to have their own accounts.
A user account provides individual access via a username and password combination. These accounts are created by using authentication plugins. The bare minimum authentication is manual, where a user is created using the administration interface. The next, most common authentication is the e-mail-based system that allows users to create their own accounts using e-mail verification. In either case, a unique username and e-mail address are required as well as a password. Passwords in Moodle are encoded with an MD5 hash function to make them unreadable and difficult to guess.
To get into the system, a user enters their username and password, and if correctly entered, they are granted access to the site. Logging in uses PHP's 'cookie' functions to set cookies into the current session and help identify the user throughout the site visit.
Permissions can be assigned within six contexts: site/global, course category, course, blocks and activities, user, and front page. There are seven built-in roles: administrator, teacher, non-editing teacher, student, course creator, authenticated user, and guest, all of which can be assigned in any one or more of the above contexts. Any number of customized roles can be created through the list of over 200 system capabilities. Each capability can be assigned one of four access levels: Not Set, Allow, Prohibit, and Prevent. Each user can have multiple roles that inherit permissions from all of the context levels applicable to a given access request from the user. The combination of these provides a powerful and flexible solution for administrators.
The standard system roles are:
An infinite number of custom roles can be generated by using the Moodle GUI and role definition screens.
To check and force a login from inside your code, a call to require_login
is used. This function allows you to check if the user is logged in, and forces them to log in if this is required by the element that they are trying to access. For example, you can create a specific activity in a course that requires the user to be logged in. If the user is not logged in, then they will be redirected to the correct login function. This function also remembers what the user was accessing, so they can be returned there once they have successfully logged in.
Contexts are elements in the system associated with the defined context levels. On the code-side, contexts are defined in /lib/accesslib.php
as follows:
define('CONTEXT_SYSTEM', 10); define('CONTEXT_USER', 30); define('CONTEXT_COURSECAT', 40); define('CONTEXT_COURSE', 50); define('CONTEXT_GROUP', 60); define('CONTEXT_MODULE', 70); define('CONTEXT_BLOCK', 80);
This means every instance of any of these levels is a context. There is only one 'SYSTEM', but there are many of the others, such as users, courses, and modules.
Capabilities are associated with context levels, and are specific access rules that can be granted to roles. Examples of capabilities are:
As developers, we can create capabilities to control access to our new functionality. Careful consideration should be given as to which context is the best location for a new capability. Capabilities should generally be placed at the lowest context level at which they can function. We will cover these topics in more detail as we work, in the chapters ahead.
Roles are specific identifiers that are associated with all contexts. Roles are primarily used to group capabilities for a context, so that these capabilities can be given to users. Capabilities are assigned to roles in specific contexts, either by default or by specific assignment (overriding).
Lastly, users can be assigned to roles in specific contexts. This assignment gives them the accesses defined by the capabilities in that role for that context.
So, to summarize:
Contexts are specific elements in Moodle
Roles are associated with all contexts
Capabilities are assigned to roles in a given context
Users are assigned roles in a given context
It is the role assignment at the context level being checked, and the capability that role has at that context, which determines whether a user can perform the requested action.
As you develop code for Moodle, you will need to keep this functionality in mind, so that you can design and build the access control that you want for your functions.
In this chapter, you have started the journey towards becoming a proficient Moodle developer, by studying Moodle's overall architecture. You should now be comfortable with the underlying system requirements to run Moodle, and the major elements that make up a Moodle installation. You have also looked into the process to install and upgrade Moodle with some discussion of our development environment. You have also gained some insights into the program execution for Moodle and the key PHP files that serve as entry points to the system. You have also understood the fundamentals of how Moodle stores its configuration. You now know a bit about both the core internal libraries of Moodle and some of the external library dependencies. Finally, you took a look at Moodle's security and access model.
In the next chapter, you will learn how to create and modify blocks.