0% found this document useful (0 votes)
444 views145 pages

Development Moodle

This section of Moodle Docs is aimed at developers who contribute to The Moodle code, plugins, themes, and so on. If you manage a Moodle site, Administrator documentation may suit your needs better. A page may be added to the developer category by adding the template CategoryDeveloper to the bottom of the page.

Uploaded by

Adry Calleja
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
444 views145 pages

Development Moodle

This section of Moodle Docs is aimed at developers who contribute to The Moodle code, plugins, themes, and so on. If you manage a Moodle site, Administrator documentation may suit your needs better. A page may be added to the developer category by adding the template CategoryDeveloper to the bottom of the page.

Uploaded by

Adry Calleja
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 145

Development:Developer documentation

(Redirected from Development)

This Developer section of Moodle Docs is aimed at developers who contribute to the Moodle code, plugins, themes, and so on. If you manage a Moodle site, Administrator documentation may suit your needs better. If you teach using Moodle, try Teacher documentation.

Note: New developer documentation pages should be added to the Development

Development: before the new page name i.e. [[Development:New page name]]. If you are a developer, you probably want
namespace by typing to change your preferences to include the Development namespace in searches. A page may be added to the Developer category by adding the template

{{CategoryDeveloper}} to the bottom of the page. - If required, you can use [[Category:Developer|Sort key]] to provide a sort key other than the
default page name.

Contents
[hide]

1 How Moodle development works 2 Guidelines 3 Documentation for core components 3.1 Core components that affect everything 3.2 Core libraries with a more specific uses 3.3 Modules included in the standard distribution 4 How you can contribute 4.1 Make a new plugin 4.2 Change core code 4.3 Ways to contribute that do not involve PHP programming 5 Plans for the future 6 Resources 7 Tools 7.1 IDEs 7.2 Browser add-ons

7.3 Miscellaneous 8 See also

How Moodle development works


The overview of the Moodle development process explains how Moodle development occurs and how people become Moodle developers. Current plans are listed on the Roadmap. You can also enrol in one of the Moodle Developer Courses.

Concepts
Overview | Unit 1 "To Do" List Welcome to this Introduction to Moodle Programming course developed and offered at Humboldt State University! Since 2004, staff at Humboldt State University have taken a leadership role in the international community in the support of Moodle. This leadership was recognized by the Andrew W. Mellon Foundation with a grant to support the development of this course to further expand our contributions. What is Moodle? Moodle is software that can be used to produce web-based courses and web sites to support collaborative projects. It is designed to support a social constructivist model of education. There are many ways to customize Moodle--both at a system level and at a course level. The Moodle interface consists of "sections" and "blocks." The content of "sections" is managed by the Teacher or course developer by adding text and/or activities."Blocks" are created by programmers and installed at the system level as options the Teacher can select from to customize the online classroom. Blocks typically appear in the right and left columns of the course main page, while sections appear down the center column. Some blocks are a "standard" part of the Moodle core and others are options available from third parties in the Moodle community. Examples of standard "blocks" selected to be used in this course include the "Calendar" and "People." Moodle's "modules" generally contain the code controlling instructional activities, such as a quiz or a discussion forum.

Moodle is provided freely as "open source" software. This distribution model has contributed to Moodle's growing popularity and made it an on-going development project with support from developers around the world. Because Moodle uses PHP coding, the developer community is quite large and even small organizations can support it by finding staff with modest object-oriented programming experience. This course will guide you to the introductory principles of creating a "block" that can be added to your own Moodle installation, or--when shared--others' Moodle sites around the world as an optional enhancement. Moodle developers have made significant and impressive progress to make Moodle a learning management system that is widely adopted around the world. One of the critical areas where it has compared favorably to commercial alternatives is its attention to universal accessibility. While commercial vendors have been slow to respond to accessibility concerns raised by users, the open source environment of Moodle allows adaptations to be made more quickly. Complying with principles of "universal accessibility" ensures that all users, regardless of their computer input and output devices, have equivalent access. Individuals with physical disabilities are particularly impacted when they use assistive technologies to access the World Wide Web. It is imperative that programmers adhere to principles of accessibility as they create enhancements and modifications to Moodle for their users or the Moodle community at large so that Moodle adoption and use doesn't fall off due to it failing to meet accessibility standards. Therefore, in this week's lesson, you'll find an introduction to web accessibility which will provide the foundation for references to accessibility that occur throughout this course. The Moodle community gathers for information exchange at Moodle.org. This first week, as part of our introductory activities, create an account for yourself at Moodle.org and login to explore for yourself the wealth of information there. Use this week to also review fundamentals of SQL and PHP to ready yourself for activities in the weeks ahead. Expect to see each unit in this course in the same format:

Overview "To Do" List summarizing all participant activities for the week, including reading assignments or supporting web sites to visit

Check the course schedule and course Calendar block for deadlines for assignments.

Be sure to post any questions you have in the "Questions?" forum in the top section of this course's main page.

"To Do" List


New browser windows open for each external resource. 1. Introduce yourself to other class participants in the designated discussion Forum. Greet others.

2.

Visit Moodle.org. Join the online community by creating a new account for yourself. Browse the site, including the Moodle Development section and the links in the Main Menu at the left margin for "Documentation," "Moodle Buzz," and "Issue Tracker." Take a look at the Tracker and locate an open ticket that interests you.

3.

Submit the URL of the open ticket you selected in Bug Tracker in the "Open Ticket" Assignment area of this course.

4.

What exactly is "open source" software? Read The Open Source Definition (Annotated) from the Open Source Initiative

5.

Read Introduction to Web Accessibility from the W3C Web Accessibility Initiative. Be sure to explore the related comprehensive information on ... Different Disabilities that Can Affect Web Accessibility.

6.

Carefully review the WebAIM Section 508 Checklist. These standards are widely adopted and significantly enhance accessibility. What is "Section 508?" "Section 508 (the 1998 Amendment to Section 508 of the [U.S.] Rehabilitation Act) requires the [U.S.] federal government to make all goods and servicesincluding Web pagesfully accessible. It identifies specific standards for Internet and Web accessibility, which are often used as a basis for evaluating whether or not Web sites meet accessibility requirements." University of Maryland University College Accessibility in Distance Education Glossary.

7.
8.

Review this description of Object-oriented programming from Wikipedia. Read the first six Moodle Coding Guidelines as well as the Coding Style section. Complete the tutorials for PHP (PHP Tutorial - from Refsnes Data) and SQL (SQL Course - Interactive Online SQL Training for Beginners). If you're already familar with the basics of PHP and SQL but can use a review to refresh your memory,

9.

practice with these online tutorials. Focus on the PHP Basic list to understand thoroughly, as well as Include, Sessions, and Date from the PHP Advanced list . Glance through other PHP Advanced topics also, like Email and File. 10. Review the important terminology included in the Glossary as well as the PHP and SQL tutorials before taking the quiz. 11. Take the quiz before the deadline noted on the course Calendar (top left corner of the course main page). Two attempts are allowed. 12. Post your response to the assigned discussion questions as early after beginning Unit 1 as possible. Watch for others' responses and respond to at least two classmates-beginning with those without replies already.

Unit 2: Creating and Working in the Development Environment


Overview | Unit 2 "To Do" List External resources open in new browser windows. In this unit, we will be examining a variety of tools to make the job of creating and editing Moodle code easier. As with any creative task, having the right tools will make the job easier. By making the mechanics more transparent, it allows us to focus our thoughts on the creative process (the actual code we want) instead of fumbling with the process of recording our thoughts. There are several developer tools that will be introduced this week along with practice exercises so you can explore the features of each. The two browser plug-ins introduced help when creating and debugging browser issues. Both are invaluable tools to help troubleshooting issues--especially CSS and Javascript problems.

You may be familiar with other tools that do similar tasks--please share those experiences in the discussion this week. Most development for Moodle starts with a programmer working on his or her local computer. In order to develop locally you will need to first configure your development environment. In this Unit we will install and configure the tools that you will need to develop for Moodle locally.

Local Web and Database Server


Moodle requires a web server that can interpret PHP code as well as a database server to which you can save content. XAMPP is a preconfigured web and database server for a specific set of operating systems. XAMPP has been preconfigured for four operating systems Windows, Mac OS X , Linux and Solaris. We will focus on Windows, Mac OS X and Linux as development environments. XAMPP, MAMP and LAMPP are acronyms for Windows, Mac or Linux, respectively, and Apache, MySQL, Perl and PHP.

Integrated Development Environment


Review Wikipedia's entry describing the Integrated Development Environment (IDE). After installing a web and database server, you will need to setup and configure your Integrated Development Environment (IDE). At Humboldt State University we use Eclipse, which is a free open source java-based IDE. Other Universities like San Francisco State University use PhpED, which is also a full featured commercial IDE with a PHP debugger. Other potential development environments for Moodle development are vim, Adobe's Dreamweaver, Nvu or any text editor. For the purposes of this course we will use Eclipse.

Alternative Development Environments

PhpED
PhpED is a Windows-only IDE developed by NuSphere. It has an integrated debugger and most of the same features as Eclipse.

VIM
Vim is a highly-configurable text editor built to enable efficient text editing. It is an improved version of the vi editor distributed with most UNIX systems. Vim is often called a "programmer's editor" and is so useful for programming that many consider it an entire IDE. It's not just for programmers, though. Vim is perfect for all kinds of text editing, from composing email to editing configuration files. Instructions on how to configure Vim for use with Moodle.

Adobe Dreamweaver
Dreamweaver is a commercial tool commonly used for web development that can also be used to develop PHP programs. It will work just as well for Moodle development but lacks some of the features of a full IDE like Eclipse or PhpED.

Developer's Browser Toolbars

Firebug for Firefox


Firebug is an indispensable Firefox browser plugin for dynamically viewing and editing the HTML, javascript and CSS source code for a web page.

Selenium for Firefox


Selenium is a test tool for web applications. Selenium tests run directly in a browser and act like a real user would. A Selenium test will run in Internet Explorer, Mozilla and Firefox on Windows, Linux, and Macintosh. Running Selenium for other web browsers involves downloading Selenium core and unzipping the core folder to the root web directory of your XAMPP install.

Molybdenum for Firefox


Molybdenum is another add-on for Firefox that can edit and run Selenium tests

Important Tip!

All of the validators' links to tests run on external websites, so the URL used to validate the sites must be publicly viewable. To use the validators on your localhost address you will need to open port 80 on your Windows firewall, which you should be asked to do the first time you start Apache through XAMPP. You will also need to use the IP address to your computer instead of localhost (e.g., http://69.57.234.89/test/test.php). If you are behind a firewall router you will need to forward port 80 to the computer you are using. If you are using DSL, your IP address will probably change on a daily basis, which means you will need to change localhost to your new IP address for the validators to work.

Web Developer for Firefox


The Web Developer extension is designed for Firefox, Flock, Mozilla and Seamonkey, and will run on any platform that these browsers support including Windows, Mac OS X and Linux. (Note the Help available if you need assistance with the installation).The Web Developer extension is an excellent tool for viewing forms variables, CSS and HTML inline as well as validating css, html and accessibility. Patrick Lauke does an excellent job of explaining how to use the Web Developer Extension for accessibility validation as well as explaining the different parts of 508 compliance--see the assigned reading in this Unit's "To Do" List.

Web Developer for Internet Explorer


The Web Developer Toolbar for Internet Explorer is similar to the Web Developer Extension for Firefox. It allows you to:

Explore and modify the document object model (DOM) of a Web page. Locate and select specific elements on a Web page through a variety of techniques. Selectively disable Internet Explorer settings. View HTML object class names, IDs, and details such as link paths, tab index values, and access keys.

Outline tables, table cells, images, or selected tags. Validate HTML, CSS, WAI, and RSS web feed links. Display image dimensions, file sizes, path information, and alternate (ALT) text. Immediately resize the browser window to a new resolution. Selectively clear the browser cache and saved cookies. Choose from all objects or those associated with a given domain.

Display a fully featured design ruler to help accurately align and measure objects on your pages.

Find the style rules used to set specific style values on an element. View the formatted and syntax colored source of HTML and CSS.

XMLDB Editor
XMLDB is a database abstraction layer that provides a common way to create and update database tables for Moodle. Each table's definition (fields, keys, and indexes) is saved in an XML format. This file is read when the Moodle database is first created and whenever a module or plugin is installed. This means developers create one definition of the table(s) used by their module or plugin and system administrators can choose to use any supported database system such as Oracle, MSSQL, MySQL or PostgreSQL. You'll use the XMLDB Editor in Unit 7 when editing Moodle's database. More detail will be provided in Unit 7.

Web Accessibility
Evaluating web sites for accessibility is made easier by a variety of accessibility checkers and validation tools. While manual checks are almost always necessary, software can streamline a site's evaluation and spot errors that might be overlooked by the designer in a manual evaluation. The assigned reading for this unit, Patrick Lauke's "Evaluating Web Sites for Accessibility with Firefox," illustrates how Firefox's Web Developer Toolbar can be valuable in detecting accessibility problems. There are certainly other software tools available to enhance productivity in the development environment and check for universal accessibility problems. If you have tried other tools that you prefer, please share your experiences in this Unit's discussion forum. top

"To Do" List


1. Install a Local Web and Database Server

Install XAMPP/MAMP/LAMPP
Follow the instructions below for your operating system to download and install XAMPP/MAMP/LAMPP:

Windows Mac OS X Linux

http://www.apachefriends.org/en/xamppwindows.html http://www.apachefriends.org/en/xamppmacosx.html http://www.apachefriends.org/en/xampp-linux.html

Start Apache and MySQL


To start Apache and MySQL locate the folder under which you installed XAMPP, MAMP or LAMPP and find the corresponding icon and double click it.

XAMPP View

MAMP View

Then either select "Start Servers" (MAMP) or "Start" for both Apache and MySQL (XAMPP). Test by going to http://localhost/ where you'll see a splash screen similar to:

Navigate to phpMyAdmin
Now that Apache and MySQL are started you should be able to visit phpMyAdmin, which was installed with XAMPP. In your web browser visit http://localhost/phpmyadmin .

Create a Database in phpMyAdmin


To create a database using phpMyAdmin: i. Type "moodle18" in the "Create new database" field

ii. iii.

Select "utf8_general_ci" in the dropdown below in the related text field Click on the "Create" button immediately below the dropdown menu.

Other MySQL GUI Applications


MySql Admnistrator/Query Browser Cocoa MySQL HeidiSQL SQLyog

Create a Directory for Moodle Source Code


To create a directory for Moodle you must first navigate to the root directory of the webserver. In XAMPP this is located in the folder you installed the application to--for Windows, usually C:\XAMPP and for Mac, usually /Applications/MAMP. In this directory locate the htdocs folder. In this directory create a new directory named "moodle". top

2. Install and Configure Eclipse


If you run into problems with Eclipse, refer to the detailed information in this Moodle Docs article: Development: Setting up Eclipse.

Download Eclipse Recommended (new Directory/Folder browser for Extraction and windows Installation will open) Eclipse for Windows Eclipse for Mac OS X Eclipse for Linux "Program Files" "Applications" Look for a package or rpm for your distribution.

PHP for Eclipse


After installing Eclipse configure it to edit PHP files. First install a plugin for Eclipse and then perform some configuration (refer to the "Installing the necessary plugins" section of the article.

SVN for Eclipse (Subclipse)


In later units of this course you might use Subversion for code management. Eclipse has a handy plugin for subversion that allows you to perform subversion commands without leaving Eclipse. Instructions for installing the subversion plugin.

Set Eclipse to PHP View


1. Choose Window-->Open Perspective-->Other 2. Select PHP and click OK.

top

2. Explore Toolbars

Web Accessibility
Read "Evaluating Web Sites for Accessibility with Firefox," an excellent summary by Patrick Lauke of the value of Firefox's Web Developer Toolbar in detecting accessibility problems. Download and install Firefox Web Developer. (Install the latest Firefox browser first, if you don't already have it!) Download and install the Internet Explorer Developer Toolbar. Select one or more web pages you commonly visit and evaluate their accessibility using one or more of these accessibility validators: o o o WebAIM's WAVE Web Accessibility Tool Watchfire's WebXACT HiSoftware's Cynthia Says Portal

Selenium

Step 1. Create a Selenium test case using the Selenium IDE for Firefox. First navigate to the Firefox tools menu and select Selenium IDE.

To start recording a test case navigate to Humboldt State University's home page at http://humboldt.edu and click the red circle in the top right corner of the Selenium IDE interface. The circle will change colors to pink in the middle to designate you are recording. Go back to your Firefox browser window and click on the "Admissions" link on the Humboldt State University main page. Next click on the "Apply" tab on the Admissions web page. Step 2. Return to the Selenium IDE and you should see that both actions were recorded. You can stop recording your actions by clicking again on the record button. Step 3. To execute a Selenium test case click on the green arrow next to "Step" in the Selenium IDE toolbar. You will see Firefox progress through the web pages in the same fashion you did, albeit faster, and you will see the log in the Selenium IDE record warnings and Info. We will discuss more about how to use Selenium in testing later in this course. top

2.

Create a Project and PHP File


Step 1. Using the Eclipse File menu, select New-->PHP Project. Step 2. In the Project name field, enter "Test." Uncheck "Use default location" box. Step 3. Click the Browse button to navigate to your XAMPP htdocs location or to your MAMP location. Create a new directory called "test". Step 4. The directory "Test" should show up in the Navigator screen. Step 5. To create a PHP file, from the File menu, choose New-->PHP File. Step 6. The container should be /Test and name the file "hello.php" in the "File name" field. Step 7. After the */ and before the ?> prompt, type

echo "Hello Moodle

world";

Step 8. Save the changes and view your creation with your browser at http://localhost/test/hello.php. Complete and submit the "Hello World" PHP Assignment before the deadline noted on the course Calendar.

Create a project using the editing tools of your choice, then write a simple "Hello World" php program--but use one of the development tools explored this week to prepare your project. Submit a screen shot of a working "Hello World" php program showing the file in a project in a development envrionment of your choice. The screen shot may be a .gif, .jpg or the screen shot inserted into a .doc (MS Word) or .rtf file.

3. Take the quiz before the deadline noted on the course Calendar (top left corner of
the course main page). Prepare for the quiz by practicing with the developer tools.

4. Post your responses to the assigned discussion questions in the designated forums.
Respond to classmates.

Unit 3: Source Code Management


Overview | Unit 3 "To Do" List External resources will open in new browser windows. Source management systems are essential for software development. "Not using one is like driving a car too fast: it's fun and you might get to your destination faster, but an accident is inevitable." M. Tim Jones in Version Control for Linux: Overview of architectures, models, and examples. Source management systems provide a reliable way to

Track changes Collaborate with other developers Provide management of files Revert back to old versions Versioning - grouping and tagging files together so that you can recover that exact configuration at a later point in time.

In this Unit we will cover basic concepts necessary to use source code management for software development.

For purposes of this course you will be using CVS exclusively, but in your everyday Moodle development there will be times when you will be using SVN, CVS, or both. top

"To Do" List


1. Read about using CVS for source code version control
Using Fluid Thoughts' CVS tutorial, read over the commonly used CVS commands. Make sure you cover

add, commit, update, and remove. Although these

commands are similar to SVN commands, some of them behave differently than their SVN counterparts.

2. Read about using SVN for source code version control


See the available options for installing SVN. After reviewing some of the available installation options, check to see if you have one of them already installed in your development environment. If you do not have one installed, choose an appropriate installation package and follow the instructions to install that package. Read the section, "Initial Checkout" in Chapter 2 of the online book, "Version Control with Subversion," which describes the steps that would apply to checking out a working copy of Moodle from a SVN server. Browse through the "Basic Work Cycle" section in Chapter 2 of the online book, "Version Control with Subversion," to study the commands that you are likely to need during a typical workday. Pay particular attention to the five commands you'll use most:

o o o o o

svn update svn status svn commit svn add svn delete

Review the other commands in this chapter's section so that you understand how and when they are used. Remember that

svn help <command> (e.g., svn help commit)


will show you want the command is used for and some of the valid options. If you will be using TortoiseSVN then take a look at the manual available either through the application or online at TortoiseSVN. Read Subversion Best Practices from Open Collabnet.

3. Obtain Moodle for your development environment.

Using CVS
CVS for Windows
a.
Find the Moodle directory in C:\XAMPP\htdocs.

b. Right-mouse-click on the moodle directory and choose "CVS Checkout" from


the menu. You should see a dialog box.

c. Enter this text into the CVSROOT field:

: pserver:[email protected]:/cvsroot/ moodle (for U.S.-based developers, replace the "SERVER" with "us"

d.

Under the "Module" field, type "moodle" to get the moodle directory.

e. Click on the "Revisions" tab. f. Select the "Choose branch or tag" radio button. g. Click the "Update list ..." button. h.

Important Tip!
If you ever want to check out a different version of Moodle (for example 1.9 or 2.0) or a specific release (for example 1.8.4 or 1.8.3) you will want to change the name in the branch or tag name field. After clicking on the "Update list button" you will see a listing in the drop down of all the possible Moodle branches to check out.

Later, to update your local copy of moodle to the most current 1.8 release version in CVS, just right-mouse-click the moodle directory and choose "CVS Update". Select MOODLE_18_STABLE from the list of all possible Moodle revisions.

i.

Press the button "OK" and everything should be checked out into the

moodle directory.

CVS for Mac and Linux


Make sure you have a CVS client installed and working in your environment. If you are working in a Linux or Unix environment you should already have CVS installed. If you are working in a Mac OS X environment you should also already have CVS installed that can be accessed via the command prompt. If you are working in a Windows environment download CVS from TortoiseCVS. Explore this documentation on checking out a copy of the Moodle CVS located at Moodle.org and CVS Quick Reference Card. To connect and login for the first time to the CVS server:

cvs -d:pserver:[email protected]:/cvsroot/moodl e login


There is no password; when asked for one, just hit Enter. To checkout (download) the entire Moodle code for the first time, use this command to get the latest STABLE version:

cvs -z3 -d:pserver:[email protected]:/cvsroot/moodl e co -r MOODLE_18_STABLE moodle


Or the latest development version:

cvs -z3 -d:pserver:[email protected]:/cvsroot/moodl e co moodle


top Later, to update your local copy of Moodle to the current version in CVS you just need to go into your local Moodle directory and type:

cvs update -dP


To update your local copy and to save the log of the process:

cvs update -dP -r MOODLE_18_STABLE | tee upgrade.log


To update your local copy of Moodle to a new version (e.g. from 1.7+ to 1.8), go into your local Moodle directory and type:

cvs update -dP -r MOODLE_18_STABLE


Then look at the upgrade.log, notably look for lines starting with "C" (conflict):

grep '^C' upgrade.log

Note!
Conflicts may appear if you have manually modified your source files. You have to resolve conflicts before using the site. See CVS for Developers for more details.

Other Alternatives to Get Moodle Code


Windows
Download from 'Moodle Packages for Windows' from Moodle.org. Choose the Moodle 1.8.x+ version (for Windows, usually it is named as 'MoodleWindowsInstaller-latest18.zip').

Mac OS X
You will find some information about CVS and Mac OS X in the documentation for the complete installation package Moodle4Mac. Please read How To Update Your Moodle4Mac. It works fine with the new CVS servers.

Use the information in this Unit to select the type of checkout that applies to you, then checkout a copy of Moodle to a directory in your local webroot of your development environment.

2. Take the quiz. 3. Contribute to the discussion topic.


Which method did you use to checkout Moodle for your development environment? What are the circumstances that influenced your decision to use SVN or CVS ?

SVN (Subversion) or CVS (Concurrent Versioning System) for Moodle Development?


Using Just CVS
The most common developer configuration for source code versioning with Moodle is to use CVS and checkout the latest version of the Moodle stable branch of the Moodle CVS repository. In this configuration the developer obtains all updates to Moodle through Moodle's CVS repository. The developer then makes changes locally and tests against the current CVS version of Moodle. The developer could also decide to checkout the CVS contribute branch of the Moodle repository in order to test and modify third-party Modules and Plugins. The developer may or may not have permissions to commit changes back to Moodle's CVS repository or branches. In this scenario the most common commands the developer will need to know are CVS update and, if they have commit privileges, CVS commit.

Who does Just CVS work for?


o o o o
Developers who just want to help out Moodle Developers who don't have a production environment Developers who feel comfortable developing in their production environment Developer groups who don't need to share their code with others in their group

Developers that want to version control their own source code but don't care about Moodle's version control top

Using Just SVN

This option is for people who would prefer to download Moodle in a zip format and need a way to version control the code they are creating. There can be many configurations for this, with the most likely that you download the Moodle sourcecode from www.moodle.org and merge it into your SVN repository. You manage all of your code through SVN. In this case you could use all the commands within SVN, but the most likely commands will be

svn update, svn commit and svn merge.

Who does Just SVN work for?


o
Someone who would like to version control their own code but don't care about the version control for Moodle

A group of developers who are in different locations but sharing a common code base

Using CVS and SVN Together


This option is the most common for an organization that has multiple developers and multiple servers. The developers generally checkout the most current version of Moodle from the CVS repository and then merge the changes into their SVN repository. This allows them to use all the power of SVN while minimizing the time it takes to get the most current bug and security fixes from moodle.org's developers. In this scenario you will use the CVS update command along with potentially all the SVN commands.

Who does CVS and SVN work for?


o o o
Multiple developer groups Organizations with multiple servers that use different modules or blocks Single developers who are interested in learning SVN

If you'll be developing in Moodle without using SVN for version control, then you only need to follow the steps for checking out Moodle from a CVS repository. If you'll be developing in Moodle in a shop that manages a code base in SVN, then you may only need to follow the steps for checking out Moodle from an SVN repository. In some cases, such as at Humboldt State University's Courseware Development Center, a SVN repository used by most developers is kept up to date via CVS updates from a Moodle CVS repository. In this case, the administrator/lead developer

must be knowledgeable with both systems. If this is your case, then follow the steps to checkout copies from both systems.

Unit 4: Configuring Moodle for Development


Overview | Unit 4 "To Do" List External resources will open in new browser windows. Now that you've configured your development environment, you're ready to begin your official "Moodling!" After installing the Moodle program, you'll be creating the fundamental elements of a Moodle environment so you can see the results of your programming efforts from a user perspective. Although it's possible with the most recent versions of Moodle to automatically populate the database with an institution's courses and students, you will be manually creating a course "shell," to contain the test course, as well as fictitious students. Each "user" you create will have a different set of roles and permissions. After creating the test course and a few users, you'll also begin customizing your Moodle installation by installing an existing block and an existing module shared by the Moodle community. Moodle "blocks" offer a Moodle course developer (usually the "Teacher") an array of opportunities to customize the features displayed in the online environment--usually to provide additional information or functionality to the learner. There are a set of standard blocks that come with Moodle but there are also many third-party blocks that a Moodle system administrator can choose to add. In general, "blocks" can be distinguished from modules because blocks affect layout and infrastructure of the course environment but do not contain content, activities, or interaction opportunities. Blocks typically may appear only once on a course main page in the left or right columns; activities (created by "modules") may be repeated many times throughout the course sections in the center column. "Modules" contain the code for creating the activities within the course for participant interaction and assessment. For example, Moodle "Modules" include the discussion forum or a quiz creation tools.

Basic Moodle Preparation


Be sure to read documentation carefully before and during the software installation. In particular, Installing Moodle from Moodle.org is an invaluable resource to read before beginning. During the install you'll find additional helpful information in the

readme_en.txt file unzipped in your C:\XAMPP directory..


The "contrib" branch is an area in the Moodle source repository where user contributed thirdparty modules, blocks, and customizations are contained. It's a way of keeping the development of those separate from core Moodle. This Unit gives considerable attention to the contrib branch.

Important Tip!
Beware of role assignments that don't make sense when the underlying functionality does not exist. The interface or facility must actually exist within the context that you have assigned that right. For example, you can assign a user the right to create new categories at the Category context. However, category creation is only available at the site level.

Roles and Permissions


There are six default roles: 1. 2. 3. 4. 5. 6. Administrator Course creator Teacher Non-editing teacher Student Guest

By assigning a role to a user in a certain context, you grant them the permissions contained in that role for the current context and all lower contexts. Contexts in hierarchical order are:

System (no parent) Site (parent = system) - Moodle 1.8 onwards Course category (parent = system) Course (parent = category or system) Module (parent = course or system/site(1.8 onwards)) Block (parent = course or system/site(1.8 onwards)) User (parent = system)

TRICK: Enabling teachers to assign teacher role


By default, teachers are only allowed to assign the roles of non-editing teacher, student and guest. To enable teachers to assign the role of teacher:

1.
2. 3. 4.

Access Administration > Users > Permissions > Define roles. Click the tab "Allow role assignments". Click the checkbox where the teacher row and column intersect. Click the "Save changes" button.

Inheritance will kick in if a role is assigned at a higher level . For example if a user is assigned a Teacher role in a particular course category then the user will have this role in ALL courses within the category. Roles only work if the role assignment is made in the correct context. For example, the Inspector role is an example of a role assigned in the system context, the Teacher role should be assigned in the course or course category context, the Forum moderator role is an example of a role assigned in the module context, and the Parent role is an example of a role assigned in the user context. As a system administrator, you could create additional roles (we will cover this in more detail later in this course). A significant part of the roles infrastructure is the ability to assign a user into multiple roles (at the same time). The capabilities of each role are merged to produce the effective set of capabilities. In particular it is perfectly possible for a user to be both a Teacher and Student in the same course. This differs from the behavior of Moodle prior to the introduction of roles. You should be careful to ensure that if you change a user's role that you remove them from any other roles as required as this will no longer be done automatically. See more information about managing roles as a system administrator. As a developer, it is also important to understand the implementation of the ROLES and PERMISSIONS system so that you could familiarize yourself for the debugging/programming later on.

Installing Third Party Blocks and Modules


Moodle developers around the world program blocks and modules to add features to the basic ("core") Moodle code. These enhancements are shared in the online Moodle community so others can use or modify the customizations. In the activities for this Unit, you'll install an existing block and an existing module from the Moodle.org site to customize your new Moodle installation.

Basically there are two ways to obtain third party blocks developed by other Moodle developers: Approach A. In Unit 3 we covered how to checkout Moodle source code using CVS . You could use CVS to checkout the contrib branch which contains a lot of third party patches, plugins, modules, and blocks. Using CVS to checkout the Moodle contrib branch is advised when you are planning to modify the code, or if you want to use CVS update to obtain new versions of third party modules or blocks. CVS allows you to incorporate the third party block or module owner's modifications with your own modifications to the third party block or module. CVS will also inform you if there is a conflict between your code and the third party owner's code. Approach B. Navigate to the Modules and Plugins area at the Moodle.org website. ("Plugins" is used interchangeably with "blocks.") This approach is advised if you don't plan to modify a third party block or module and are satisfied with navigating the Moodle website to download the latest code for a third party block or module.

Important Tip!
The PHP function echo or Moodle's print_object() function could be more useful for debugging than enabling the Moodle "debug modes."

Debugging Mode
You can find debugging mode in the Site Administration block. To prepare for the debugging activity later in this unit refer to this essential information about Debugging at the Moodle site. top

"To Do" List


1. Install Moodle
Install Moodle following the directions at http://docs.moodle.org/en/Installing_Moodle.

Previously in Unit 2 we learned how to setup XAMPP on PC (and Mac) and created the Moodle database; in Unit 3 we learned how to use CVS to check out Moodle source codes. Next you'll setup and configure your local Moodle installation for development.

Now carefully follow steps 5.5 through 7 in the installation directions.

2. Create the Moodle test environment (empty course, test students, assign roles, restore test case course).

Create an Empty Course


Login to Moodle as an administrator. Find the "Site Administration" block and click on the "Courses" link, then "Add/edit courses" link.

Three fields are required: "Full name," "Short name," and "Summary." (*) For now you could just put in something that you could remember and then click on the "Save changes" button. If you do not understand some of the options (such as "Format"), you could click on the help button right next to it (the yellow "question mark") for more information.

Create Students for Testing


Return to the System Administrator main menu (click on the "Administration" link in the breadcrumb area at the top left). Create two or more users now: click on "Users," then "Accounts," then "Add a new user."

Remember that the required fields must be entered before the user will be accepted by Moodle. In this case the required fields are "Username," "New password," "First name," "Surname," "Email address,"City/town," and "Select a country." Required fields are marked with asterisks.

The new user information is saved by pressing the "Update user" button near the bottom of the form. Other fields that are part of a user's profile can also be filled out when the user is created. Some of the profile fields can be revealed by pressing the "Show Advanced" button.

Assigning Roles
Now that you have created some new users, assign each with different roles. Return to the empty course that you created (click on "Courses" in the "Site Administration" block, then "Add/edit courses"). Once you get back to the course view, click on the "Assign roles" in your "Administration" block.

Choose the type of role you want to assign from the list. For example, for assigning a Student role to Martin, we'd first choose "Student" from the list of roles. After choosing a role, two lists appear: a list of users who currently have that role ("Student Demo" in this example) in the left pane, and a list of users who don't in the right pane. By selecting Martin in the right pane (clicking on his name) and using the left-pointing arrow button in the middle of the two panes, Martin would be added to the list of existing users on the left. Multiple users may be selected by holding down the Apple (Mac) or Ctrl (PC) key while clicking n the users' names. Removing someone from a role is done by moving the user from the left column to the right by selecting their name and clicking on the right-pointing arrow.

Restore Demo Course Content


Download the Moodle 1.9.3 Features Demo course backup then return to the course view to restore the course into the empty course you have already created (#2 above). Note that you can only restore the Moodle Features Demo course backup to a Moodle 1.9.3 site or newer. Click on "Restore" link in the "Administration" block.

You will then be able to upload the test case course to your Moodle development server and see it in your Files list.

Click on the "Restore" link to restore the course. Once you successfully restore the course you could start to explore all the features provided by Moodle. top 3.

Important Tip!
Some modules come with roles and capability settings. Pay close attention to the global settings.

Install New Blocks


There are two ways to obtain third party blocks: (A) through Moodle CVS "contrib" branch (requires using CVS checkout) and (B) to download it from http://download.moodle.org. These two different approaches are introduced below using the Windows platform and the "Quickmail" block as an example block to download and install.

Approach A: From Moodle CVS "contrib" Directory

i.

Find the contrib directory or create a new directory where you want to place downloaded third-party Moodle customizations (e.g., C:\XAMPP\moodle\contrib\). .

ii.

Right-mouse-click that directory and choose " CVS Checkout" from the menu. You should see a dialog box.

iii.

Enter this text into the CVSROOT field:

:pserver:[email protected]:/cvsroot /moodle
(for US-based developers, replace the "SERVER" with "us" ) iv. v. Under the "Module" field, type "contrib" to get contrib directory. Press the button: "OK" and everything should be downloaded. Move some of the language files into the language directory. For example, you need to copy the

vi.

block_quickmail.php that is included in the

\lang\en directory into your development Moodle installation \lang\en_utf8 directory. This will help define some of the strings that
this block uses.

vii.

Take care of the Help files too: Put the

/lang/en/help/*.html

into the /lang/en_utf8/help in your development Moodle


installation. These are the help button content of the quickmail block. Later, to update your local copy of contrib to the current version in CVS, just rightmouse-click the directory and choose "CVS Update". Note: The enclosing Moodle directory is self-contained - you can move it anywhere you like or even rename it.

Under your local contrib directory, you will find several directories.

Blocks are also referred to as "plugins," so to find the block called "quickmail," navigate into the "plugins" directory and click on "blocks." Here you should find the "quickmail" directory.

Copy the whole quickmail directory and place it under your Moodle directory (e.g., C:\XAMPP\moodle18\blocks\quickmail). Login as admin on your local development Moodle installation, then click on "notification" in your "Site Administration" block. You should now be all set. Sometimes for some of the blocks there might be some global settings or course level settings, so take care of these settings as well.

Approach B: Download from http://download.moodle.org


viii.
Download the quickmail.zip file from http://download.moodle.org. Moodle download site for plugins" alt="screen shot of Moodle download site for plugins"

src="http://dev.moodle.org/file.php/2/pictures/Unit4screenshots/pluginsdow nloadUnit4.jpg" /> ix. Unzip quickmail.zip to your local Moodle installation, putting it in the /block directory.

x.

Move some of the language files into the language directory. For example, you need to copy the

block_quickmail.php that is included in the

\lang\en directory into your development Moodle installation \lang\en_utf8 directory. This will help define some of the strings that
this block uses.

xi.

Take care of the Help files too: Put the

/lang/en/help/*.html

into the /lang/en_utf8/help in your development Moodle


installation. These are the help button content of the quickmail block. xii. After all these are done, login as the admin on your development Moodle installation, and click on the "Notification" link in your "Site Administration" block. You will be prompted that quickmail tables are created correctly and now the quickmail block is ready for your users to use!

4. Verify your block is installed properly.


Regardless of whether using Approach A or Approach B, verify your block is properly installed by adding the newly installed block to a course of your choice . First, while logged in as an administrator or teacher, "Turn editing on," then (1) select the name of your block from the Blocks drop down menu. (2) You should see your block appear in the column on the right below existing blocks on your course main page.

5. Install New Modules


To install a third party module called "Face-to-Face": i. Download the .zip file (or copy from your contrib directory--you can find it in /contrib/plugins/mod directory). ii. iii. Copy the "facetoface" directory to the /mod directory. Be sure to read the README file inside the facetoface directory for more upto-date instructions. Usually, if there IS a README file in the directory of a third party module (or block), it will also tell you which version of Moodle it is compatible with.

iv.

Login as admin on your Moodle development installation, then click on the "Notification" link in the "Site Administration" block. You will be prompted with several tables, then a "Continue" button at the end of the page.

v. vi.

Click on the "Continue" button and then you are done! Usually you also will want to check whether there is a "Global Setting" associated with the module. Click on the "Modules" link under "Site Administration" to see if there are global settings that need your attention. Refer to the example illustrated for the "Face-to-face" third party module.

vii.

After taking care of the global settings, try logging in as an administrator, an instructor, or a student to create an instance of this new module. With editing capabilities on the course, you can see the newly installed "Face-toface" module available from the dropdown menu.

6. Debugging Mode
After you login as Admin user, find the "Site Administration" block and click on the "Server" link, then the "Debugging" link.

Step 1. Take a close look at the options for "debug messages debug." The default setting is "NONE: Do not show any errors or warnings." You have the following five options: i. ii. iii. iv. v. NONE: Do not show any errors or warnings MINIMAL: Show only fatal errors NORMAL: Show errors, warnings and notices ALL: Show all reasonable PHP debug messages DEVELOPER: extra Moodle debug messages for developers

Experiment with these options. You might find out that if you set it to NORMAL (or above), sometimes Moodle will display a lot of undesired error/warning messages which might not be related to what you are looking for. Later in the course in "Quality Assurance Testing Techniques" we will cover this in more depth and you will be able to use functions such as Moodle's PhpED/Eclipse for debugging purposes.

print_object() or PHP's echo, or

Step 2. Enable the "Performance info perfdebug" check box. After you click on "Save changes", you will start to see on the bottom of each page (the footer) how many seconds it took to load the page, and how many files were included before PHP could render this page correctly. In

config.php you can enable other performance information, such as how

many database queries before displaying the page, etc.

For example, if you set Debug to "Yes" in the Configuration->Variables page, some performance profiling data will show up on your footer (in default theme). With these settings you get more granular control over the capture and printout of the data.

You could add these two lines right before the PHP closing ?> in config.php to enable database query information:

define('MDL_PERF', true);

// Capture performance profiling data // Capture additional data from DB

define('MDL_PERFDB', true);

This will allow you to actually see the performance data. You MUST check the "Performance info" (perfdebug) checkbox in Debugging so that adding these two lines in the 7.

config.php will work!

Following the steps in Approach A, above, pick a third party block to install on your own Moodle installation. For troubleshooting, please participate in the forum in Unit 4.

8.

Add to the discussion on your experience installing third-party materials.

Structure
Overview | Unit 5 "To Do" List External resources open in new browser windows. This Unit refers to the directory structure in Moodle version 1.8.

The /admin directory


Files under this directory handle all the features under the "Site Administration" block. As of November 2007, there are 635 files spread out in 137 directories under this /admin directory (in Moodle 1.8.3+ version). For purposes of this course, we will just focus on the most important file: /admin/cron.php Some of Moodle's modules require continual checks to perform tasks. For example, Moodle needs to check the discussion forums so it can mail out copies of posts to people who have subscribed. The script that performs these continual checks is located in the admin directory and is called cron.php. Usually we set up a mechanism where this script runs regularly by itself, although you could also manually run it directly from a Web browser, or from a command line. Cron.php provides a "heartbeat" to perform functions at intervals defined by each module. This kind of regular mechanism is typically implemented using a cron daemon/service via cron jobs.

The cron.php script: 1. Searches the mdl_modules table (assuming the default table prefix, of course) in the Moodle database for modules scheduled to have their cron functions run

2.
3.

In each such module directory locates any function called module-name_cron in the lib.php file and runs it Searches the mdl_block table for blocks scheduled for their cron methods (object functions) to be run

4.

for each such block, runs the cron method for a new object associated with that block

These files (the lib.php files and the files where the block classes are defined) can contain cleanup functions, email functions or anything that needs to be run on a regular basis. For example, cron will trigger the system to create the backups of courses at the time specified in the administration settings. It also triggers any messaging module or forum email notifications, but not all functions are called each time the cron runs. Some functions, such as unenrolling students who have not logged in or deleting old copies of log files, are only run occasionally. The cron.php file has a section which will randomly call these core tasks

approximately 1 in 5 times the cron runs.

Note that the machine performing the cron does not need to be the same machine that is running Moodle. For example, if you have a limited web hosting service that does not have a cron service, then you might choose to run cron on another server or on your home computer. All that matters is that the cron.php file is called regularly.

The load of this script is not very high, so 5 minutes is usually reasonable, but you can reduce the time period to 15 minutes or even 30 minutes. It's best not to make the time period too long, as delaying mail-outs can slow down activity within the course. Remember that mail-outs also wait for the editing time to expire before being queued for sending. As long as cron is run regularly and fairly frequently, the load is not very high. However, if it hasn't been run in a long time or the proceessing frequency is too far apart the loads can be considerable depending on site activity and any background batch processes such as enrolling or un-enrolling that may need to occur. top

The /blocks directory


By now you probably already know about 'blocks' in moodle. Moodle blocks typically appear in the left and right margins of a course's main page. They typically contain a function and differ from the "sections" that appear down the center column of a course's main page that contain the content and Activities or Resources added by the instructor.

When a Moodle course is created it automatically generates several 'blocks' that allow you to control how you navigate or find information in Moodle (examples of these include the "Site Administration" block for administrator, the "Search Forums" block or the "Calendar" block for all users, etc.). In addition to the blocks that automatically appear, you will notice that you have several options for further blocks of tools (from the Blocks drop down menu when editing is turned on) to add to your course. Examples include the "Remote RSS Feeds" block, the "Blog" block, etc.). Similarly, you can delete any of the existing blocks if you feel they are unnecessary to your course and you can also move the blocks so that they appear on a single side rather than on both sides of the middle content (this can only be achieved using the move or delete buttons with editing turned on). In a typical Moodle 1.8 installation, you will see a set of standard blocks available for each course creator.

If you look into your local Moodle installation and navigate to /blocks directory, you will find a matching directory for each block.

If you need to debug the "Blog Menu" block, for example, you go to the "blog_menu' directory. If you need to debug the "Search Forums" block, begin with the "search_forums" directory, etc. Later in this course we will introduce more about how to write a Moodle block from a programmer's perspective. Additional details about "Blocks administration" (usually from a system administrator's perspective).

Important Tip:
Localized strings should be in a separate language directory such as en_custom. The default is if a string is not found in one language it falls back to en_utf8. This way, your changes override the default, but you do not have to include every string or manage changing core language strings. You just have to manage your localized settings.

The /lang directory


This directory contains all the different language files, including their related help button content. The one to pay most attention to is the "en_utf8" directory. Under this directory you will be able to understand how Moodle defines all the strings in different modules or blocks. For example, all the strings that are related to the admin module defined in admin.php.

The /lib directory


For a Moodle developer, this is probably one of the most important directories that you will use. The /lib directory contains many library files (275 directories and 2179 files, as of Moodle 1.8.3+) ranging from ajax and adodb libraries, to xmldb and yui (Yahoo User Interface) libraries. The most important three library files are probably moodlelib.php, weblib.php, and accesslib.php. These three library files will be discussed in more depth in Part B of this Unit. However, this is a brief summary of these three library files: moodlelib.php is the Moodle "main" library. This file contains of miscellaneous generalpurpose Moodle functions (such as

set_user_preferences(),

get_user_timezone(), and so on).


weblib.php contains functions that help Moodle produce web output. For example, it has functions such as

format_text_email(), print_header(),

print_group_menu(), etc.

datalib.php contains functions that alllow moodle to access the database, it also has functions that deal with the role capabilities, such as

load_defaultuser_role(),

get_guest_role(), etc.

The /mod directory


This directory contains most of the Moodle key modules. Currently in moodle 1.8 there are 18 key modules under /mod directory.

top

"To Do" List


1.
Experiment with the cron script by running it directly from your browser (http://localhost/moodle/admin/cron.php). If cron is called from the command line by any user logged in to your Moodle it will create a temporary admin environment in order to run and then log the user out. You can disable command line running of cron by disabling the appropriate section in the cron.php file. See more details about how to set up automated execution of this script (cron.php) on (1) Windows, (2) Web hosting services, or (3) Using the crontab program on Unix. Usually this is a system

administrator's job to set up so it is beyond the scope of this introductory Moodle programmer's course. 2. Run admin/auth.php from your Web browser (http://localhost/moodle18/moodle/admin/auth.php) to see what it does. You could also access this file through the "Site Administration" menu (under Users -> Authentication).

Unit 5 Part B: Global Variables


Overview | Unit 5 "To Do" List External resources open in new browser windows. In Part B we will focus on Moodle's global variables. Later in Part C of this unit we will introduce Moodle API and some of the most important Moodle library files.

Moodle Globals
Most PHP programmers should know that in general, you want to avoid the use of global variables as much as possible. Regardless of this general guideline Moodle still uses a few global variables. As a Moodle programmer, you should not use any other global variables other than those listed in this lesson. In general when programming with Moodle you should not use PHP's built-in superglobals either--instead you should access data in these variables via Moodle's API functions.

$CFG
The $CFG object holds many of Moodle's configuration directives. In general when linking to items you want to use the variables in $CFG so that your code is portable to other sites, and the calling order of scripts is not critical. You can find most $CFG variables in the /config.php file. We will not cover all of the attributes of $CFG, but rather we will focus on those you are most likely to use while programming.

$CFG->wwwroot: This is the base address of the moodle installation. Use this
when constructing URL's so that it doesn't matter what other script includes your script. That is, since your script can potentially be included from an arbitrary directory you will not reliably be able to construct relative URLs. Take a look at your config.php and see how this variable was defined.

$CFG->dirroot: This is the base file path of the Moodle installation. This is the
directory where Moodle is installed. So you will find your blocks in " {$CFG-

>dirroot}/blocks"

$CFG->dataroot: This is the data directory for your Moodle site. $CFG->admin: This is the administrator username. $CFG->httpswwwroot: If https is enabled this is the secure wwwroot base
address. If https is not enabled this is the same as

$CFG->wwwroot.

$CFG->libdir: This is the location of the moodle library files. $CFG->textfilters: Is a comma separated list of the currently enabled text
filters.

$CFG->loginhttps: Is a boolean value indicating whether or not https is


enabled for login.

$CFG->noreplyaddress: The email address to use for email that should not
receive a reply.

$CFG->sesskey: The current sesskey. Use the sesskey() function to obtain


the current users session key for form and data processing. Using the function rather than the value in preferred as the

sesskey()

$USER->sesskey or $CFG->sesskey is
function allows the API to change and you will not

sesskey()

need to update your code.

$CFG->themedir: This is the location of the theme directory via the filesystem. $CFG->themewww: The web accessible base URL for the theme directory. $CFG->theme: Is the current site theme. $CFG->pixpath: The web accessible base URL of the pix directory. This is where
the moodle icons will come from.

$CFG->modpixpath: The web accessible base URL of the module icons. $CFG->mailsessiontime: This variable stores the number of hours email
sessions persist (default is 1 month). A cron function (cleanup function) written in admin/cron.php is used to prune the session table.

Additionally, if your code stores any information in the config table (usually named as mdl_config) then that information will be accessible via the $CFG variable as well. top

$USER
The

$USER object holds information pertaining to the currently logged in user. This global

variable was first declared in /lib/setup.php.We will not cover all of the attributes of this

object, but instead will focus on those attributes you are most likely to use. Most of these attributes come from the user profile.

$USER->id: The user's Moodle user id. $USER->auth: The user's authentication method. $USER->username: The user's username $USER->idnumber: The user's idnumber, this is typically used to uniquely
identify the user on an external system.

$USER->firstname: The user's firstname. $USER->lastname: The user's lastname $USER->email: The user's email address. $USER->emailstop: Indicates if the user has disabled their email. $USER->institution: The user's institution. $USER->department: The user's department. $USER->address: The user's address. $USER->city: The user's city. $USER->country: The user's country $USER->lang: The user's default language $USER->theme: The user's theme if user themes are allowed. $USER->lastlogin: The last time the user logged in. $USER->currentlogin: The user's current login time. $USER->lastIP: The last IP the user logged in from. $USER->picture: If the user has a picture set or not. $USER->timemodified: The last time the user profile was modified. $USER->student: An array of course id numbers the user is a student in. $USER->timeaccess: An array keyed by course id which lists the access time
for that particular course.

$USER->teacher: An array of course id numbers the user is a teacher for. $USER->teacheredit: An array of course id numbers the user is an editing
teach for.

$USER->sesskey: The user's current session key.


top

$COURSE
The

$COURSE object holds information pertaining to the currently viewing course. This

global variable was also declared in /lib/setup.php.We will not cover all of the attributes of this object, but instead will focus on those attributes you are most likely to use in the future.

$COURSE->id: The course's Moodle course id. $COURSE->category: The course's category. Usually moodle administrator
may have setup up several course categories, for example, "Science," "Humanities," "Public Health," etc. (or based on semester). When you create a new course manually, by default the category will be set to "Miscellaneous" for which the category id is 1.

$COURSE->fullname: The course's full name, such as "Computer Science Basic


Programming Logic"

$COURSE->shortname: The course's shortname, such as CS101. $COURSE->format: The "format" of the course is usually "site" (for the Moodle
root course), "weeks," or "topics" (based on the format the teacher chooses).

$COURSE->visible: This specifies whether the course is visible to the students


or not

$COURSE->groupmode: This specifies whether the course uses group mode or


not. 0 is no, and 1 is yes.

$COURSE->timecreated: The time that the course was created. This uses
Unix time stamp format so to really understand what the actual date is, you need some conversion (see the link below for more details)

$COURSE->timemodified: The time that the course was last modified. Again
it is using Unix time stamp format.

$COURSE->guest: Whether the course allows "guest access." If the value is set
to 0 then no, but if the value is set to 1 then yes.

$COURSE->startdate: The starting date of the Moodle course. Note that


Moodle uses "Unix timestamp" to convert the actual date/time to startdate. So for example, if you want to do a SQL query to list out all the courses that has starting date from 2007-08-01 to 2007-09-01 you could write the query like this using "unix_timestamp":

select fullname, shortname, cat.name from mdl_course, mdl_course_categories as cat where startdate > unix_timestamp('20070801 00:00:00') and

startdate < unix_timestamp('20070901 00:00:00') and category = cat.id order by cat.name


More information on the Unix timestamp. For other attributes under $COURSE object, browse the Moodle table mdl_course.

Name $COURSE id category sortorder password fullname shortname idnumber summary format showgrades modinfo newsitems teacher teachers student students Guest Startdate Enrolperiod Numsections Marker Maxbytes Showreports Visible

Default Value

Type Object(stdClass) (44 elements)

"1" "0" "1000" ""

String String String String

"Moodle 1.8.x +" String "mdl18x" "" "test" "site" "1" NULL "3" "Teacher" "Teachers" "Student" "Students" "0" "0" "0" "0" "0" "0" "0" "1" String String String String String Undefined String String String String String String String String String String String String String

Hiddensections Groupmode

"0" "0"

String String String String String String String String String String String String String String String String String String String String
top

Groupmodeforce '0' Lang Theme Cost Currency Timecreated Timemodified Metacourse Requested "" "" "" "USD" "0" "1197679457" "0" "0"

Restrictmodules "0" Expirynotify "0"

Expirythreshold "0" Notifystudents Enrollable Enrolstartdate Enrolenddate Enroll Defaultrole "0" "1" "0" "0" "" "0"

$SITE
Site variables are settings that determine how your entire Moodle site functions. The $site variables are the most technical settings. This is the only global variable that is not declared in the /lib/setup.php file. These are some commonly used attributes in Moodle 1.8:

$SITE->fullname: The Moodle site's full name. This is based on what you
described during the Moodle installation process.

$SITE->shortname: The Moodle site's short name. This is also based on what
you named it during the Moodle installation process.

$SITE->numsections: The Moodle site's number of sections. $SITE->id: The Moodle site ID number. By default it is assigned as "1".

$SITE->category: The Moodle site category number. By default it is assigned


as "0", which is the root category. Usually only the Moodle "root course"--the front page of Moodle, that is assigned to category 0. The "Miscellaneous" course category is category 1.

$SITE->password: This is the admin admin stite password, which is the super
admin (username: admin) password. Note: Don't confuse this one with the

$CFG-

>dbpass--these two are different. The $CFG->dbpass is usually defined in the


config.php and is the Moodle database password.

Name $SITE Visible Timemodified Timecreated Theme Teachers Teacher Summary Students Student Startdate Sortorder Showreports Showgrades Shortname

Default Value

Type Object(stdClass) (44 elements)

"1" "1182375379' "0" "" "teachers" "teacher" "test" "students" "student" "0" "1000" "0" "1" "moodle18p"

String String String String String String String String String String String String String String String String String String String String Undefined

Restrictmodules "0" Requested Password Numsections Notifystudents Newsitems Modinfo "0" "" '0' "0" "3" NULL

Metacourse Maxbytes Marker Lang Idnumber Id Hiddensections Guest

"0" "0" '0' "" "" "1" "0" "0"

String String String String String String String String String String

Groupmodeforce "0" Groupmode Fullname Format "0"

"Moodle 1.8.x+" String "site" String String String String String String String String String String String

Expirythreshold "0" Expirynotify Enrolstartdate Enrolperiod Enrolenddate Enroll Defaultrole Currency Cost Category "0" "0" "0" "0" "" "0" "USD" "" "0"

Note: Other global variables such as $THEME, $db, $MCACHE, and $HTTPSPAGEREQUIRED are found in the /lib/setup.php.

"To Do" List


1. 2.
Read additional Moodle Coding Guidelines: #10 in the General rules section; #6 under the Security issues section. Use

print_object() (defined in /lib/datalib.php at around line 1610),

print() (http://us2.php.net/print), or echo()

(http://us2.php.net/manual/en/function.echo.php) to print out some of the values of the global variables mentioned in this unit for debugging purposes. 3. Contribute your ideas to the discussions for this Unit on global variables.

Unit 5 Part C: Moodle Libraries


Overview | Unit 5 Part C "To Do" List External resources will open in new browser windows.

Important Tip:
Discuss with the Moodle core team (using moodle.org "General Developer" forum) when planning changes to any of these three files, and preferably (if you have write access to the Moodle CVS tree) after approved by the Moodle core team, you should commit your changes into the Moodle CVS In Part A of this Unit you were introduced to one of the most important directories for Moodle developers, the /lib directory. In Part C you will learn more about this directory, specifically the three major library files: moodlelib.php, weblib.php, and datalib.php. As you review code examples in Moodle and begin to prepare code as part of this lesson, refer to the "General Programming and Security Overview" Unit in this course. For a general overview, take some time to browse through the Moodle Core API, usually covered in these three files, so that you could get a rough idea the scale of these three library files. This page is automatically generated using PHPEdit (a PHP software tool) from the three main library files in moodle/lib. Very few Moodle programmers could master every single function or class among these three library files. Usually you look up these three major library files for what you need to know when you are troubleshooting a problem. There is a very useful website provided by Moodle, http://xref.moodle.org/ (referred to in this course as " xref"). Browse this site to get ideas how to use this site to look up specific functions, classes, or variables. As it might not be easy to master every single function inside of these three library files, it is probably better to explain with some examples. Here are three examples of how you can troubleshoot with these three files.

Case A - moodlelib.php
As we already learned from Part A, the moodlelib.php IS the main library file of miscellaneous general-purpose Moodle functions. This means that it also contains functions

related to login, etc. If we look at an example case MDL-10375 at Bug Tracker you will notice the problem was undefined mnethostid (which you might guess it means "mnet host id"). In the description of the bug report it mentions that the plan is to create one new create_guest_user() function under moodlelib.php with correct settings. This is the type of function that usually goes into moodlelib.php

Case B - weblib.php
This is the library of all general-purpose Moodle PHP functions and constants that produce HTML output. In Moodle 1.8 code, it defines one class (tabobject) and nine functions. See an example case using weblib.php with MDL-11506 at Bug Tracker.

Case C - datalib.php
This is the library that contains functions for database manipulation. In Moodle 1.8 code, datalib.php defines 43 functions. Some examples are object of the main admin user),

get_admin()

(returns $user

search_users() (search through course users),

get_users() (returns a subset of users), get_courses() (returns list of courses,


for whole site, or category),

get_logs(), etc.

The datalib.php sometimes can be confused with dmllib.php, which is another very important library that contains functions for database manipulation as well. However, dmllib.php in general deals with the record level (more micro level) type of database manipulation, while datalib.php deals with users, admins, courses, logs and other higher levels of database manipulations. See two examples using datalib.php at Bug Tracker: MDL11135 and MDL-8549. During major Moodle version upgrades, usually there will be more functions added to these three files (moodlelib.php, weblib.php, and datalib.php).

Other Important Libraries

Remember:
Assume a function exists before writing the functionality on your own. Moodle's API is rather robust, and functions can be broken down into several main categories. Understanding where portions of the API are located in Moodle's lib structure can be extremely helpful in determining where to check if a particular function exists or how to call a particular function. There are a few functions that are used often with which you should become familiar. As you become more familiar with Moodle through programming experience it will become obvious

which functions these are. We will wait until we begin writing some code before we cover the API in detail, but below is a brief overview of functionality and a good starting place to look:

lib/dmllib.php: inserting, updating, and retrieving data from the database. These are more micro-level functions, including

execute_sql(),

db_uppercase(), modify_database(), count_records(), get_record(), get_field(), delete_record(), insert_record(), update_record(), etc. As of moodle 1.8.3+, there
are around 69 functions defined in this library file (for more details please refer to the Moodle xref site). The most important (or most frequently used) functions in this library are:

get_record() Get a single records as an "object." This function is very


frequently used (i.e., referenced 1500+ times in Moodle 1.8 code).

get_records() Get a number of records as an array of objects. This


function is also frequently used (i.e., referenced 460+ times in Moodle 1.8. code). If the query succeeds and returns at least one record, the return value is an array of objects, one object for each record found. The array key is the value from the first column of the result set. The object associated with that key has a member variable for each column of the results.

get_record_sql() Get a single record as an object using an SQL


statement. The SQL statement should normally only returns one record. In debug mode you will get a warning if more records are returned (unless you set

$expectmultiple to true). In non-debug mode, it just returns the

first record.

Important Tip:

When accessing the database use the Moodle database API. The database API abstracts the database calls allowing system administrators to choose which relational database works best for this installation. Not using the database API forces the developer to create SQL queries for all of the relational databases Moodle supports (MySQL, Postgresql, MSSQL, and Oracle).


lib/ddlib.php: modifying, creating, or deleting database schema. In Moodle 1.8 it contains 27 functions. This library includes functions such as

table_column(),

table_exists(), field_exists(), index_exists(), find_index_name(), create_table(), rename_table(), add_field(), drop_field(), rename_field(), add_key(), drop_key(), etc. Some of the most important or most frequently used functions
in this library file are:

table_column() This function will add a new field to a table, or modify an existing one (if oldfield is defined). It was referenced 850+ times in Moodle codes. Warning: Please be careful on primary keys in different tables, as this function will eat auto_increments.

create_table() This function will create the table passed as an argument with all its fields/keys/indexes/sequences--everything based in the XMLDB object. As you would have guessed, there are also

drop_table(),

rename_table(), add_field(), drop_field(), rename_field(), and change_field_type() functions. All are


related to manipulating database schema.

lib/accesslib.php: This is a new library file created beginning in Moodle 1.7. It mainly covers context, roles, and permission related functions. In Moodle 1.8.x there are around 80 functions defined in this accesslib.php file. Frequently used functions are:

require_capability() Checks for a capability assertion being true.


If it isn't then the page is terminated neatly with a standard error message.

has_capability() You will see this function being referenced a lot (in
Moodle 1.8.3+, at least 915 times; see the Moodle xref site for more details). This function returns where the current user has the capability of performing a function. For example, we can do

has_capability(mod/forum:replypost',$context) in
forum. This is a recursive function, by the way.

get_context_instance() Get the context instance as an object.


This function is frequently used and will create the context instance if it does not exist yet.

create_role() and delete_role() Creates a role and deletes a


role (as well as cleaning it up after it)

lib/blocklib.php: In short, this library file includes all the necessary functions to use blocks in a typical course page. As of Moodle 1.8.3+, there are around 27 functions included in this file. Some of the most important (or frequently used) functions include:

block_instance() Loads the necessary class files for a block.


Whenever you want to load a block, use this function first.

blocks_have_content() This function will accept an array of block


instances and checks to see if any of them have content to display. Will return true or false. It is being referenced in /course/format/scorm/format.php, /admin/settings.php, and other places.

block_print_group() Prints one group of blocks in a page.


Parameters passed by reference for speed; they are not modified.

lib/formslib.php: This is a VERY important library file in Moodle 1.8. This is the library of classes for creating forms in Moodle, based on PEAR QuickForms. Want to know more about the features of formslib? Additional useful related resources are Formslib Usage, Formslib Form Definition, and Formslib Validation.

Information is also available on the most recent changes for the library files mentioned above.

Important Tip:
Knowing where to look and what functions to use will become easier with time and familiarity with the Moodle codebase. It may seem frustrating at first--but be patient!

Selecting Library Files to Include


When including Moodle core libraries it is best to follow the practice of less is more: including only the libraries that contain the functions that you require for the program to work. Always use the function

require_once()to avoid including files that may have already been

included in other portions of Moodle code. The most common file to include is config.php. This file sets up the global variable $CFG (more about $CFG to come in Unit 5 Part C), as well as includes other essential files. Another common practice is to store all common functions for a block or module in a library file called lib.php file. This is just a brief overview and the above library files cover more functionality than what is suggested by the above list. There are many other functions available via the API.

Example Code Snippets Using Functions from Three Main Library Files

Example 1
Objective: Implement an if statement to see if a user with username 'joe' exists in the user database. Step 1: Analyze the task. As the task is dealing with the user database,we look into the /lib/dmllib.php to look for useful functions that we could use to retrieve user data. We found the function "record_exists()". Step 2: Implement the code snippets:

global $CFG; require once ($CFG->dirroot . 'config.php'); require once ($CFG->dirroot . '/lib/dmllib.php'); if (record_exists('user', 'username', 'joe')) { print 'joe is an existing username'; } else { print 'joe is not an existing username'; }
Step 3: Test out the code to see if it works. Testing methods are covered in more depth in Unit 8. top

Example 2
Objective: Printing a yes/no combination box for an HTML form with the element name 'active', 'no' as selected. Step 1: Analyze the task. As the task is dealing with HTML output, we look into the /lib/weblib.php to look for useful functions that help us achieve our goal. We found the function 'choose_from_menu()' (at around line #642). Step 2: Implement the code snippets:

global $CFG; require once ($CFG->dirroot . 'config.php'); require once ($CFG->dirroot . '/lib/weblib.php');

$options = array(); $options[0] = get_string('no'); $options[1] = get_string('yes');


choose_from_menu($options,
Step 3: Test the code.

'active', 'no');

Example 3
Objective: Cleaning and sanitizing some data submitted from a form and inserting the data into the 'mdl_notes' table where 'mdl_' is the database prefix. Assuming that 'notes' is a textarea and 'url' is a text box. Step 1: Analyze the task. The task is dealing with (1) cleaning data submitted from a form, and (b) inserting data into a Moodle table. We realize that we probably have to look into the /lib/weblib.php (for data submitted from a form) and /lib/moodlelib.php (for cleaning data), and /lib/dmllib.php (for inserting data into the table. So we probably have to deal with three library files: weblib.php, moodlelib.php, and dmllib.php. We find the

data_submitted() function in weblib.php (at around line #285), and clean_param() function in moodlelib.php (at around line #336), and finally, the insert_record() function in dmllib.php. If we want to handle the code writing in a
more "Moodle" way, we could use

get_string() (returns a localized string), and

print_string() (print out a translated string) functions to display success/error


messages. This way it would allow the error message to be displayed in different languages (if the string is defined in a particular language pack). Step 2: Implement the code snippets:

global $CFG; require once ($CFG->dirroot . 'config.php'); require once ($CFG->dirroot . '/lib/dmllib.php'); require once ($CFG->dirroot . '/lib/weblib.php'); require once ($CFG->dirroot . '/lib/moodlelib.php'); if ($data = data_submitted()) { if (!empty($data->notes) && !empty($data->url)) { // build a new object to insert into the database $insert = new stdClass; $insert->notes = clean_param($data->notes, PARAM_CLEAN);

$insert->url = clean_param($data->url, PARAM_URL); if (insert_record('notes', $insert)) {


print_string('notesinserted');

} else { error(get_string('insertnoteserror')); } } else { error(get_string('missingrequireddata')); } } else { error(get_string('nodatasubmitted')); }


Step 3: Test the code. top

"To Do" List


1. Open your favorite PHP editor and browse through the moodlelib.php now.

Important Tip:
The "search" feature on the xref site is sometimes difficult to find and use. The search link is located on the upper-right corner of the site and when you "mouseover" the link, you will see a embedded pop-up window of options (class, function, variable, constant, and table).

2.

Go to xref (http://xref.moodle.org/) and browse through the same file (moodlelib.php). This time you will be able to click on functions or variables right away and know where they were defined or referenced. This site can be particularly useful when you try to skim through all major functions covered in moodlelib.php.

This "search feature" will also record your search history. If you click on the link "Search history +" link, you will see all of your search history on this site:

3.

Pick a file not covered in this Unit's discussion of the /lib directory and browse the code to determine what it does.

4.

Navigate weblib.php on xref.moodle.org to get a rough idea what functions are covered in this library file.

5.

Write a simple snippet that would list out all courses (with their id, shortname, and fullname) that were created between 2006-10-01 to 2007-12-01. (Hint: You may need to use a function in the moodlelib.php library to convert a date to a unix timestamp.) The output should be using the just using

get_string() function (instead of

echo or print

so that it complies with the Moodle standard (to make

it easier for other languages). Submit your snippet as a text file in the designated Assignment area. 6. 7. Share your comments on Moodle libraries in the designated discussion forum. Take the quiz. Two attempts are allowed.

8.

Add to the discussion on Moodle libraries.

Unit 6: Programming Practices Overview


Overview | Unit 6 "To Do" List External resources will open in new browser windows.

There are definite challenges to creating and maintaining code created by programmers around the world that may be accustomed to their own programming standards. So it should not be surprising that Moodle has developed coding guidelines to streamline the integration of code from many sources. In addition to the assigned reading on Moodle coding guidelines, as you prepare to write your own Moodle programs, remember these quick tips:

Use four spaces instead of the Tab key. This can be easily accomplished by properly configuring your editor as you did in Unit 2 for Eclipse.

Variable names should be descriptive and useful Write your code to be readable instead of writing comments to explain badly written code.

Any good security resource will first cover social engineering aspects because many security breaches are a result of lack of policy or following existing policy protocol. This Unit will only briefly cover social engineering aspects--not all possible aspects of security. There are many other quality resources out there that will do a much better job (reference appendix) than we could possibly do here. For this reason we will focus on how to manage risks involved with database driven web applications. Also we will briefly cover other security issues and include some security best practices. 'The big lie of computer security is that security improves by imposing complex passwords on users. In real life, people write down anything they can't remember. Security is increased by designing for the way humans actually behave.' --Jakob Nielsen How do most web-based security issues occur?

Errors in Programming
Giving too much permission to a user or not restricting user permission: This happens when we do not, or can not, properly check to see if a user has the appropriate authority to execute a command. This means that users should not be able to edit another

user's account unless they have administrative privileges. Or a user should not be able to change a course unless they are the teacher for that course or they are an admin or some other user that should have that privilege. General logic errors: There are general logic errors that appear to go through the proper steps, but maybe a boolean conditional is reversed or improperly negated. That is, we proceed down the wrong branch of execution.

Errors in Handling Data


Improperly handling data: Essentially no data coming from users should ever be trusted. What this means is that regardless of who our current user is we should treat the data coming in as though it may have malicious content. We should always appropriately clean and filter data coming from the user. Data stored in the database was probably initially submitted by a user so that data needs to be properly handled when redisplayed to users. Lack of casting/type checking: This is essentially an extension of improperly handling data. When we are expecting a number as input from the user we should ensure that a number is supplied. Wherever possible numeric data should be used because it is extremely easy to clean. However, we still need to do appropriate user level checks to ensure they have the rights to see or modify data. Exposing too much information: - Some systems have been referred to as "loose lipped" when they expose too much information. A common example is a login script that may respond with "Incorrect password for user 'Joe'" this system is loose lipped because it alerts the user that 'Joe' is a valid user account. A better message would be "Incorrect username or password" this provides a valid user with information as to what went wrong and a person trying to hack a login with essentially no information. Most often too much information is exposed via error messages; unfortunately it is frequently the case that too little information is returned. Your script should only return enough information, and no more, for the user to understand what happened so they can fix their error. When handling data from a user you want to apply the tightest filtering possible. You want to let only the data you want to get through. No more and no less. If you are expecting a number, ensure that the data provided is in fact a number. If you are expecting an alphanumeric string, ensure that is what is provided. A solid and robust API will have solid ways to handle incoming data. Unfortunately sometimes you may not be able to filter the data very strictly. This is where it becomes incredibly important that you treat the data appropriately before trying to do anything with

the database involving that data, or properly handle the data before redisplaying it in the users browser. Properly handling data involves not only handling incoming data, but also properly handling outgoing data.

Errors in Trust
Trusting data from a non-trusted user: As covered above you should not trust data coming from users. So the statement can more succinctly be "trusting data from a user." This may seem overly harsh or restrictive, but the reason for not trusting users is that an unintended person may gain access to a user account. That is, the person on the other end may not be who you think it is. Trusting data from the database: This has already been touched on as well. A common mistake is the assumption that user input was cleaned before it was put into the database so it is safe when it comes back from the database. This is an extremely dangerous assumption as the user may have posted malicious code that was not executed initially due to proper handling, but now if we assume it is safe the original exploit may still be possible. The reason for this is that when we initially handled the data we may have protected against the malicious code, but the malicious code is still present in the data. That is, rather than executing the malicious code we have stored it in the database. Now, if we later assume it is safe then we may inadvertently execute the malicious code.

Why you shouldn't trust users


This may sound like a harsh policy or procedure, but this is a fair assumption and is good practice.

Users make mistakes. Sometimes we do things that we don't intend to do A user may not be who you think they are. It may be that the user on the other end of the computer may not be who you think they are. This can happen for various reasons that are outside of the scope of this document.

A user may need to educate students about exploits.It is plausible that a user may need to educate their students about common security exploits. During this process they may need to post code that if not properly handled would be malicious or have unintended consequences. The instructor may post this code, so you do not want to trust that the information provided by the instructor is safe.

Trusting users leads to vulnerabilities: By trusting your users you are placing the security of your whole site into your entire userbase. If that doesn't make you nervous maybe you

should consider another profession, and certainly not system administration! When you trust users you are assuming they will not do anything dangerous or malicious either intentionally or accidentally. For instance, a flaw that allows elevated permissions is a vulnerability that might allow a student to gain teacher privileges and a teacher to gain administrator privileges. Once the system is penetrated, problems seem to escalate and security breaches will become increasingly serious. top

Cross-Site Scripting (XSS)


What is XSS?
Cross-Site Scripting exploits are typically the result of trusting data from one source and presenting it to another user without properly scanning and handling the initial data or properly filtering the data before sending it to a second user to be displayed.

Why should we protect against XSS, or what are some implications of a XSS exploit?
Many vendors downplay the seriousness of XSS exploits. This is rather unfortunate because as we will see XSS pose security issues for other websites as well as a user's personal information stored on their computer. Below are some potential results from employing XSS:

Cookie theft: Obtaining cookie data from websites in a different domain. This can expose personal information stored in a cookie issued by a website in a different domain. This is a direct circumvention of the DOM and can expose a user's personal information or give access to information stored in a cookie for another website.

Account hijacking: "Logging in" to a different user's account. This could potentially be accomplished by stealing the cookie information from another website that employs persistent connections. Or perhaps a user alters an account for a particular web application to make it trivially easy to login.

Alteration of web application settings: Changing a user's password or preferences for a particular website making it unavailable to or unusable by the correct user.

Exploit of a web browser security issue to access a user's underlying operating system: This is a double exploit issue here. By employing a known security issue for a particular web browser it is possible that a user employing an XSS attack may gain elevated privileges to the underlying operating system that the browser is running on.

How do we protect against XSS?


There are two key major points in protecting against XSS, and another which some may argue is not related to XSS per se, but does alleviate some of the potential security issues of someone exploiting a XSS vulnerability. The two major points are:

Input validation: By validating input we can try to recognize data that may have unintended consequences when retrieved from the database and sent to the browser or directly sent to a browser. There are several options to take when trying to handle user input. We can refuse to do anything for data that looks suspicious, or we can choose to filter the incoming data. Since XSS exploits are not a static target it is critical that there is a single function to handle identifying and cleaning potentially problematic data. (Moodle has created the function

clean_param()

for this

purpose.) This makes the code manageable as new exploits are invented there is one place to update to ensure that all of the code-base is safe. This of course assumes that everyone is properly coding and using the appropriate API functions for whatever application they are programming for.

Encoding data before sending to a user: by encoding data before it is sent to the user we can ensure that certain text that may be interpreted as valid JavaScript (or other scripting code) is properly escaped so that it is shown as text and not interpreted as valid markup to be executed. This prevents the user from inadvertently running some type of script. See the general rules of the Moodle Coding Guidelines.

The other method is verification of a private token, and really protects against "Cross-Site Request Forgery" (CSRF), but this is often lumped in with XSS. (Moodle uses

sesskey()

as its private token.) A Cross-Site Request Forgery is when one user crafts a URL that appears to do one thing, yet when another user clicks on it some command or procedure will be executed. For example Joe could create a controversial post in a forum or something that would likely cause users to click a crafted URL that takes advantage of a CSRF vulnerability in an application. Now let us assume that Mary is reading Joe's post and clicks on the URL. If an application is vulnerable to CSRF attacks, Mary may have just deleted a file or unknowingly altered her user preferences. To protect against CSRF attacks the application can generate private tokens that must be submitted along with requests to update, create, or delete data. The private token is generated for each session and is verified any time that the user attempts to alter data. See the Security Issues section of the Moodle Coding Guidelines.

How do we protect against XSS in Moodle?

Input validation: Review lib/moodlelib.php for appropriate PARAM_TYPE information

required_param($parameter, PARAM_TYPE);
Use this function when a parameter must be present. $parameter is expected to be a parameter name that will be obtained via POST or GET in that order.The Moodle API will throw an error and stop execution of the script if the parameter is not present. Use an appropriate PARAM_TYPE to filter the variable.

optional_param($parameter, $default, PARAM_TYPE);


Use this function when a parameter may be present. $parameter is expected to be a parameter name that will be obtained via POST or GET in that order. If the variable is not present then $default is returned. Use an appropriate PARAM_TYPE to filter the variable.

clean_param($variable, PARAM_TYPE);
Use this function to clean a variable that is already set in the code.

Encoding data: See Moodle Output Functions developer documentation. Private token:

sesskey()

Make sure that the

sesskey()

parameter is set in any form that

will result in the user making changes to data in the database. These forms should use the POST method rather than GET wherever possible.

echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />'; echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';

confirm_sesskey()

When processing form data and your script will change any data in the database always ensure to confirm that the session key parameter is present and the session key matches the current

session key. Use

confirm_sesskey()

which will throw an

error and stop execution if the values do not match.

SQL Injections
What are SQL injections?
SQL injections are a form of security exploit where arbitrary database commands can be executed. This usually occurs when user input is not properly filtered or when the data is not strongly typed. An example of SQL injection would be a credit card company's website using your username and password to look up your credit card number, social security number, and mailing address. If the programmer trusts the user to enter in the information without cleaning the username or password and decides to add the username and password directly to the php code that creates the SQL query, the SQL query code looks like:

$sql = "SELECT creditcardnum, ssn, address FROM userdata Where username = '".$username."' And password = '".$password".'";
Now assume that a malicious hacker sent the following information to the program: Username = test Password = blah' or '1' = '1 These parameters create an SQL query:

SELECT creditcardnum, ssn, address FROM userdata Where username = 'blah' And password = 'blah' or '1' = '1'
The "or" statement causes this to select all records in the user table--not just the one with the correct username and password. Looks like that malicious hacker has a lot of customer's credit card information now!

Why is it important to protect against SQL injections?


It is important to protect against SQL injections because a user may be able to execute any database command. Possible scenarios include catastrophic deletion of the whole database,

exposure of sensitive user information, or subtle hard to detect changes such as adding a few points to a graded assignment.

How do we protect against SQL injections?


To protect against SQL injections we must properly filter user text and be careful how we use user input to generate SQL queries. Additionally we can strongly type the queries so that parameters are appropriately handled. To filter text we need to properly handle escape characters so that they are not misinterpreted, allowing for a user to run modified or multiple SQL queries. Strongly typing data passed in by the user ensures that the data is of the type we expect it to be. That is, if we are expecting a number from the user then we can strongly type that variable to ensure it holds a number rather than a string.

How do we protect against SQL injections in Moodle?

Filter user input - appropriately filter user input using:

o o o

required_param() optional_param() clean_param()

Strongly type user input - Where possible, the PARAM_TYPE's for the above three functions will approximate this method. top

Moodle Data Cleaning Parameters


The following is an overview of the parameter cleaning types to be used with

required_param(), optional_param(), and clean_param().



PARAM_RAW: specifies a parameter that is not cleaned or processed in any way. PARAM_CLEAN: Obsolete, please try to use a more specific type of parameter. PARAM_INT: Integers only, use when expecting only numbers PARAM_INTEGER: Alias for PARAM_INT PARAM_ALPHA: Contains only english letters. PARAM_ACTION: Alias for PARAM_ALPHA, use for various actions in forms and URLs. PARAM_FORMAT: Alias for PARAM_ALPHA, use for names of plugins, formats, etc. PARAM_NOTAGS: All HTML tags are stripped from the text. Do not abuse this type. PARAM_MULTILANG: Alias of PARAM_TEXT. PARAM_TEXT: General plain text compatible with multilang filter, no other html tags.

PARAM_FILE: Safe file name, all dangerous chars are stripped, protects against XSS, SQL injections and directory traversals.

PARAM_PATH: Safe relative path name, all dangerous chars are stripped, protects against XSS, SQL injections and directory traversals

note: The leading slash is not removed, window drive letter is not allowed

PARAM_HOST: expected fully qualified domain name (FQDN) or an IPv4 dotted quad (IP address)

PARAM_URL: expected properly formatted URL. PARAM_LOCALURL: expected properly formatted URL as well as one that refers to the local server itself. NOT orthogonal to the others! Implies PARAM_URL!

PARAM_CLEANFILE: safe file name, all dangerous and regional chars are removed, PARAM_ALPHANUM: expected numbers and letters only. PARAM_BOOL: converts input into 0 or 1, use for switches in forms and urls. PARAM_CLEANHTML: cleans submitted HTML code and removes slashes

note: do not forget to

addslashes()

before storing into database!

PARAM_ALPHAEXT: the same contents as PARAM_ALPHA plus the chars in quotes: "/-_" allowed, suitable for

include() and require() include() and

PARAM_SAFEDIR: safe directory name, suitable for

require()

PARAM_SEQUENCE: expects a sequence of numbers like 8 to 1, 5, 6, 4, 6, 8, 9. Numbers and commas only. top

Security Aspects of Moodle's Roles and Capabilities System


Beginning with Moodle version 1.7 a system of roles and capabilities was introduced to replace the existing system of fixed roles (e.g., administrators, course creators, editing teachers, students, etc.). Of the errors in security described earlier, some errors in logic and some errors in trust are mitigated by this system of roles, capabilities, and permissions. A capability is usually some specific Moodle action that can be executed by a user. For example, the capability 'moodle/course:update' refers to the action of updating course settings. Another capability, 'moodle/course:viewhiddencourses', refers to the action of viewing courses that have been hidden. A role is a named set of all the capabilities with associated permissions (e.g., student, forum moderator, teacher, teacher assistant).

A permission describes the ability of a role to perform a certain capability. Permissions for a particular capability of a specific role are set within a context or "space" in Moodle. For example, a course would be considered one context. The four permissions available to be set for a capability of a role in a specified context are: 1. 2. 3. 4. CAP_INHERIT CAP_ALLOW CAP_PREVENT CAP_PROHIBIT

To understand how these four permissions work it is necessary to understand that contexts are hierarchical. From the broadest to the most specific, the contexts are: 1. 2. 3. 4. 5. 6. 7. CONTEXT_SYSTEM CONTEXT_PERSONAL CONETXT_USER CONEXT_COURSECAT CONTEXT_COURSE CONTEXT_MODULE CONTEXT_BLOCK

Permissions not set in a context for a role's capability are inherited (CAP_INHERIT) from a more general context. For example, if the student role has a CAP_ALLOW permission for the 'moodle/course:view' capability in a CONTEXT_COURSE context and the underlying contexts (CONTEXT_MODULE and CONTEXT_BLOCK) have not been "overridden" then the role will also have CAP_ALLOW for 'moodle/course:view' in those more specific contexts. The CAP_PREVENT permission will deny a user that capability in that context and more specific contexts unless overridden in those contexts. It is important to realize that CAP_PREVENT permissions can be overridden in more specific contexts. For example, a student role may have CAP_PREVENT on the capability 'mod/forum:rate' in a course context, but for a specific forum (module context) they have CAP_ALLOW. The permission in the specific context "wins." The CAP_PROHIBIT permission also denies a user that capability in the context in which it is set, but the permission in more specific contexts can not be overridden. top

Legacy Permissions
Legacy permissions in the Moodle roles system have been implemented for backwards compatibility. In versions of Moodle before 1.7 there were five static roles: 1. 2. 3. 4. 5. Administrators Course Creators Teachers Students Guests

In Moodle 1.7 and beyond those same roles exist in a default installation of Moodle. A Moodle administrator now has the capability to add, delete, or change any permission in their Moodle installation. When creating a new capability developers set the default value for each of these default roles in the legacy section in order to configure the default permissions for a Moodle installation. All non-default roles will need to be configured manually by the Moodle administrator when a block or module with a new capability is installed.

Moodle Functions for Roles and Capabilities


There are several important functions in Moodle in the roles and capabilities system. The first line of defense in a script is the

require_login()

function to restrict access

to logged-in users. This function first checks that the user is logged in and then optionally checks whether they are allowed to be in a particular course and/or view a particular course module. To check a user's permission for a capability in a certain context requires a couple of functions. The first,

get_context_instance(), returns a context instance as an

object. A context instance is a context level (e.g. CONTEXT_COURSE) and an instance id (e.g., a course id). Once you have the context instance you can require a capability in a script using the function

require_capability() or you can check to see if a user has a particular capability


before performing some action with the function these functions might look like this:

has_capability(). An application of

$context = get_context_instance(CONTEXT_COURSE, $courseid); $require_capability('moodle/course:view', $context); // some things that anyone with moodle/course:view can // do or see here // now check for a more restrictive capability

if (has_capability('moodle/course:update' $context) { // do some update to the course } else { error('You do not have the correct permissions'); }
top

Programming for Accessibility


As mentioned in the Introduction of this course, Moodle developers around the world have made progress toward universal accessibility--in large part because of commitment to making improvements in the code that improve usability. It is imperative that future developers of Moodle code not dismantle the significant strides made to date and continue to observe some key programming practices that impact users. Some quick tips to keep in mind when designing Moodle elements:

As much as possible avoid events that cause pop-up windows. Use meaningful link names and form element labels Functions must be executable from a keyboard Never use color alone to convey meaning Avoid blinking or animated elements Provide descriptive and relevant alternative text for any graphics or images, remembering that it will be read aloud to visually-impaired users

In-Development Documentation of Code


Moodle uses PHPDocumentor to generate online documentation about common classes and functions. It is recommended that you use PHPDocumentor format when documenting your functions and classes. This allows other developers to view information about the functions you create online without needing to search your code. PHPDocumentor's style also makes for clean, easy-to-read code that a developer can use to quickly understand what a function is supposed to do and what each parameter is without reading the entire function. See Moodle's PHP documentation. top

"To Do" List


1. 2. 3.
Carefully read the Coding Guidelines at Moodle.org--giving special attention to the Security Issues section. Review the WebAIM Section 508 Checklist for important suggestions to achieve universal accessibility. Read over Moodle resources for best security practices and which can sometimes be confusing. 4. 5. Complete the PHPDocumentor Tutorial Detect the security, accessibility, documentation, and coding guideline errors from the following example. Submit your corrections in the designated drop box in this Unit's section on the course main page. Copy your changed code into a text-only file and submit the file.

addslashes(),

<?php /* * Created on Dec 11, 2007 * * This script tests the user has the course view * capability and then verifies that the password entered * is correct. if the password is correct it prints out a webpage. */ require_once('http://www.somesite.com/abadfile.php'); required_param($id,PARAM_INTEGER); required_param($password,PARAM_TEXT); required_param($courseid, PARAM_INTEGER); optional_param($sitename, "HUMBOLDT", PARAM_TEXT); $file = get_file_contents($_GET['url']); $context = get_context_instance(CONTEXT_COURSE, $courseid); $require_capability('moodle/course:view', $context);

if($password != 'thisistherightpassword'){ error("<blink>Your Password is not correct</blink>"); } else { echo $file; //This function does some addition function block_addition($a, $b){ return($a+$b); } ?>
6. 7. Take the quiz. Two attempts are allowed. Add your thoughts to the discussion on accessibility.

Unit 7 - Part A - Block Basics


Part A - Block Basics
1. 2. 3. Create a simple block following Moodle's tutorial. The block will be named "simplehtml." Create a language file and directory. Create a database table into which our block will insert information.

Part B - Forms
1. Add a form using the Moodle forms library to insert information into the table

o o o o o o o o
2.

Define a new form. Display the new form. Add a header. Add access control. Add logging. Add form elements. Add state variables. Finalize the form.

Process the form.

Part C - Refine the User Interface


1. 2. 3. Add links to each page of the block. Add methods to view pages. Refactor display method.

o o
4. 5. 6.

Add page title. Display the date

Display text. Display link to file. Display the picture.

Part D - Add Editing Capabilities


Add editing capabilities that allow users to edit data, including 1. 2. 3. Delete a page Add a link to the delete.php file Create the delete.php file Clean up all data associated with the block with the

4.

instance_delete() function

Part E - Define a Role for the Block


1. 2. 3. 4. Add check to the block for the capability Add a role to the simplehtml form Add a role to edit Add a role to delete

Block Basics | Forms | Refine the User Interface | Add Editing Capabilities | Define a Role Hyperlinks will open in new browser windows. Now that we have covered the basics about Moodle libraries, secure programming, your development environment, and how to install and configure Moodle, we will get to the fun part--coding! As you learned in Unit 5, Moodle is modularized as much as possible to allow for third party programs to integrate with Moodle. The simplest way to integrate a program with Moodle or to develop new functionality is to create a self-contained block. In Unit 7 you will create a block called simplehtml. You'll begin with a Moodle.org tutorial that will teach you how to create a basic Moodle block with commonly-used functions. By completing the simplehtml block, you will:

Add a database table to Moodle

Create a Moodle form Add multiple HTML QuickForm elements to a Moodle form Process a Moodle form with multiple HTML QuickForm elements Insert, update and delete data from database table in Moodle using the form.

Some of the examples in this course may not seem logical or useful in the context they are used. In general this is intentional to illustrate different methods. Because of the amount of detail in this topic, it is broken into parts that should be completed in sequence, beginning with this Part A, "Block Basics."

Creating a Simple Block


Follow the tutorial in the Moodle site documentation to create a simple block. Test it to make sure it installs and works. If you need help, review "Unit 4 - Configuring Moodle for Development!" which covers installing blocks and modules. In order to fix some PHP warnings that will pop up from the code in the Moodle tutorial you will want to change your specialization function to the following.

function specialization() { if(!empty($this->config->title)){ $this->title = $this->config->title; } if(empty($this->config->text)){ $this->config->text = ''; } }


Notice that this code checks if the configuration variables were set; if either variable has not been set it assigns an empty string to that variable or does not use it. This reduces warnings and follows good coding practice of checking if a variable is instantiated before it is used.

Verify that the block you created using the tutorial works by installing it (see "Unit 4 Configuring Moodle for Development!") and adding the block to a test course.

Introduction to Moodle's Language and Internationalization


Now that the simple block has been created, it is time to expand it to do more things. As discussed in Unit 5, one of the most important directories for the

customization of Moodle is the lang directory. Each block can have its own language directory. In the block directory create a lang directory (right click on the simplehtml directory, then select New > Folder) . Next create a new directory within the lang directory called en_utf8 (English encoded using the utf8 character encoding). Now add a new PHP file with the name block_simplehtml.php to the simplehtml/lang/en_utf8 directory. This file will hold all the static strings that the simplehml block will use. Later if you want to translate your string to another language you can add another directory within lang for the language you are translating to. Example utf8 directories can be found in the site lang directory if you have installed other language packs. More about language translations. Now that the language file is created, a new string can be added to Moodle for the block using something like the sample code below--replacing the 'name of the string' with a valid PHP array key and the 'Text for the string' with a PHP string:

$string'name of the string' = 'Text for the string';


Practice by adding the line below to your block_simplehtml.php file.

$string'blockname' = 'Simple HTML Block';


To retrieve this string within the block you would use the Moodle function found in lib/moodlelib.php. To get the title string into a variable use:

get_string()

$this->title = get_string('blockname', 'block_simplehtml');


Replace the line in the class definition for block_simplehtml.php that assigns a value to

$this->title with the line of code above.

Create a Database Table for the Block


With the language file started it's time to move on to using the XMLDB Editor to design and create the database table that will hold the data from the form that you will create later. [If you want more detail on the XMLDB Editor, see Appendix B.] The user will input eight pieces of information to the simplehtml form: 1. 2. 3. 4. 5. 6. Text to be displayed with the link to the display of the form information Displayable HTML or text HTML area format A file name A "yes or no" question A picture choice

7. 8.

HTML or plain text from a text area A date and time stamp

Important Tip!
Avoid using enum because not all databases support this type. It is better to use an integer that is coded to a string value. Integers also scale better than enums. To begin, create the correct directory structure in Moodle. Add a file directory named db under your main block directory. Next login to Moodle and navigate to the XMLDB editor, located in the "Site administration" block > Miscellaneous > XMLDB Editor. The XMLDB editor is a graphical interface to help generate the xml files that Moodle uses to create and maintain database tables. When you get to the XMLDB editor you will see all the blocks, modules and other areas that have db directories. Those that show a link already have tables defined that can be loaded and modified. Find the blocks/simplehtml/db and click on Create.

Refresh the Eclipse navigator. Now the db directory has an install.xml file with some basic information about your block and one table called simplehtml. In Moodle you will now see the block/simplehtml/db highlighted in green and the Load and Delete commands will be linked. Click on Load. Now you will see the Edit and Unload text linked. Click on Edit. The simplehtml table must be modified to include the information entered from the form: click on the Edit link next to the simplehtml table to display the definition that is created by default for the table. Id field will be there and a primary key that links to the id field. Rename the table to block_simplehtml. Alter the comments for this table here as well. Any changes to the comments field requires a click on the Change button for the changes to be recorded. Now add the following fields: 1. 2. 3. 4. 5. 6. 7. 8. 9. blockid pagetitle displaytext format filename picture description displaypicture displaydate

top

blockid
The blockid is a foreign key that

references the block table. This will be used to join our data rows to the block table. The block table houses generic block information for installed block instances. To add the blockid field: 1. 2. 3. 4. 5. 6. 7. 8. 9. Click the "New Field" link Change the Name to blockid Enter a Comment about the field Set the Type to int Enter a Length of 10 Set Unsigned to unsigned Set Not Null to not null Set Sequence to No Enter 0 for the Default

10. Click the Change button.

pagetitle

The

pagetitle is simply text that will be used for links to this simplehtml page. Using default Moodle Themes, Moodle blocks cannot handle more than 25 characters without wrapping. To add the pagetitle field: 1. 2. 3. 4. 5. 6. 7. Click the "New Field" link Change the Name to pagetitle Enter a Comment about the field Set the Type to char Enter a Length of 25 Set Not Null to not null Click the Change button.

displaytext
The

displaytext field will be displayed as text on the simplehtml page, potentially as HTML. This will be an HTML text area where the user should be allowed to write as much text or HTML as

desired--which means it should be defined as a 'big' length text field. To add the dispaytext field: 1. 2. 3. 4. 5. 6. 7. Click the "New Field" link Change the Name to displaytext Enter a Comment about the field Set the Type to text Enter a Length of big Set Not Null to not null Click the Change button.

format
The format field will contain the integer value that

represents the format the text was entered in. To add the format field: 1. 2. 3. 4. 5. 6. 7. 8. 9. Click the "New Field" link Change the Name to format Enter a Comment about the field Set the Type to int Enter a Length of 3 Set Unsigned to unsigned Set Not Null to not null Enter 0 for the Default Click the Change button.

filename
The filename field stores the name of a file the

instructor posts on the simplehtml page, which students can then download or view. To add the filename field: 1. 2. 3. 4. 5. 6. 7. Click the "New Field" link Change the Name to filename Enter a Comment about the field Set the Type to char Enter a Length of 255 Set Not Null to not null Click the Change button.

picture
The URL for the user's chosen picture is in a

predefined static variable that associates a number to a picture. This will allow the addition of more pictures later if necessary, or for changing the current pictures' URLs without

updating the database. Because only the number is stored the database field should be created as an int rather than a char. To add the picture field: 1. 2. 3. 4. 5. 6. 7. 8. 9. Click the "New Field" link Change the Name to picture Enter a Comment about the field Set the Type to int Enter a Length of 2 Set Unsigned to unsigned Set Not Null to not null Set Sequence to No Enter 0 for the Default

10. Click the Change button. top

description
Add the

description field that will be displayed on the page. This will be an HTML text area where the user is allowed to write as much as desired so it is a 'big' text field. To add the description field: 1. 2. 3. 4. 5. 6. Click the "New Field" link Change the Name to description Enter a Comment about the field Set the Type to text Enter a Length of big Set Not Null to not null

7.

Click the Change button.

displaypicture
The

displaypicture field will be the "yes" or "no" question on the form. This is best represented as an 'int'. To add the displaypicture field: 1. 2. 3. 4. 5. 6. 7. 8. 9. Click the "New Field" link Change the Name to displaypicture Enter a Comment about the field Set the Type to int Enter a Length of 1 Set Unsigned to unsigned Set Not Null to not null Set Sequence to No Enter 0 for the Default

10. Click the Change button.

displaydate
The final field to add to the table is

the displaydate. It is a UNIX timestamp which is an integer value. To add the displaydate field: 1. 2. 3. 4. 5. 6. 7. 8. 9. Click the "New Field" link Change the Name to displaydate Enter a Comment about the field Set the Type to int Enter a Length of 10 Set Unsigned to unsigned Set Not Null to not null Set Sequence to No Enter 0 for the Default

10. Click the Change button. Now that the fields have been added to the table the install.xml needs to be saved. Click the "Back" link and the "Back to Main". Once on the main page click the "Save" link to save the changes to the install.xml. With the install.xml created anyone who installs the simplehtml block fresh will have the table setup when they check the notifications link (as discussed in Unit 4).

Unit 7 - Part B - Forms


Part A - Block Basics
1. 2. 3. Create a simple block following Moodle's tutorial. The block will be named "simplehtml." Create a language file and directory. Create a database table into which our block will insert information.

Part B - Forms
1. Add a form using the Moodle forms library to insert information into the table

o o o o o o

Define a new form. Display the new form. Add a header. Add access control. Add logging. Add form elements.

o o
2.

Add state variables. Finalize the form.

Process the form.

Part C - Refine the User Interface


1. 2. 3. Add links to each page of the block. Add methods to view pages. Refactor display method.

o o
4. 5. 6.

Add page title. Display the date

Display text. Display link to file. Display the picture.

Part D - Add Editing Capabilities


Add editing capabilities that allow users to edit data, including 1. 2. 3. Delete a page Add a link to the delete.php file Create the delete.php file Clean up all data associated with the block with the

4.

instance_delete() function

Part E - Define a Role for the Block


1. 2. 3. 4. Add check to the block for the capability Add a role to the simplehtml form Add a role to edit Add a role to delete

Block Basics | Forms | Refine the User Interface | Add Editing Capabilities | Define a Role Hyperlinks open in new browser windows. In Part A of this unit you learned how to create a basic block with all the standard functions that Moodle needs to display the block with some limited configuration. You learned how to create a database table using the XMLDB editor in Moodle, added a new language file for the block. Next you will work on creating a form to add information to the database table you created.

Add a Form to a Block Using the Forms Library


Read through Moodle's documentation on forms library usage and the definition of the forms library fields. After reading about how to create a form, create one for the block_simplehtml block that allows the user to: 1. Enter text to describe the html page the user will be going to when they click on a link in the block 2. 3. 4. 5. 6. 7. 8. 9. Display a link to a file in the course file directory Display the picture (answer a question Yes or No) Select between three pictures to display Enter text for the html area under the picture Display a date and time Place the fields created in #3, #4, and #5 (above) into a separate fieldset Add the field created in #6 (above) to the advanced features section of a form Require #1 (above) to be entered before the form can be submitted.

Define a New Form


The first step in creating a form is to create the form class which extends moodleform. Create a file called simplehtml_form.php (observing Moodle's naming conventions, see Appendix A) and add the following code:

<?php require_once("$CFG->libdir/formslib.php"); class simplehtml_form extends moodleform { function definition() { global $CFG;

$mform =& $this->_form; $mform->addElement('header', 'displayinfo', get_string('textfields', 'block_simplehtml')); } } ?>


The "definition" function is a function that will be overridden and adds the static elements to a form. This is the basic class definition for the form. Anytime you want to create a form you can copy the above code and replace "simplethml" with the name of the form you are

creating. The code adds an HTML header to the form, which means that the textfields string needs to be added to the language file for the block.

Display a Form
Now that the basic form definition has been created, the next step is to create the php program that will display the form. Create a new file in the blocks/simplehtml directory called view.php. To this file, add the following code:

<?php require_once('../../config.php'); require_once('simplehtml_form.php');

$simplehtml = new simplehtml_form();

$simplehtml->display();

?>

The code above will display and render the form. You can test it by clicking on the addpage link in the footer of the block. As you can see, the use of inheritance has made form display very straightforward. The base class does most of the heavy lifting, so all that's left to do is define a form class that extends the base class (moodleform) where the member function is defined. Although this code is functional, we have skipped many important steps. Now we will add in the missing pieces.

display()

Add a Header
If you visit the page now you will see a very basic non-themed form without any of the necessary navigational structure. Note that this happens because the form processing page, in this case view.php, is being accessed directly via the URL and not by being included in another page. This means that the necessary infrastructure must be added directly to the script. Add this by using the

print_header function, but a few pieces of data are

needed to build appropriate navigation. Make the following adjustments to view.php:

To have access to

$CFG

and

$USER add the following after

require_once('../../config.php');;

global $CFG, $USER;


A populated course object is needed which will contain various course details. Since passing in the courseid as a parameter, that can be used to build a course object. To do this, add the following code after

require_once('simplehtml_form.php'):
$courseid = required_param('courseid',PARAM_INT);

if (! $course = get_record('course', 'id', $courseid) { error(get_string('invalidcourse', 'block_simplehtml'). $courseid); }


Notice that getting a valid object or generating an error is ensured.

To display a proper header add the following before

$simplehtml-

>display();
print_header(strip_tags($site->fullname), $site->fullname, '<a href="'.$CFG->wwwroot.'/course/view.php?id='. $courseid.'">'.$course->shortname. '</a> ->'.get_string('formtitle', 'block_simplehtml'), '', '<meta name="description" content="'. s(strip_tags($site->summary)) .'">', true, '', '');
Just before

$simplehtml->display(); add:
'<a href="'.$CFG->wwwroot.'/course/view.php?

print_header(strip_tags($site->fullname), $site->fullname,

id='.$courseid.'">'.$course->shortname. '</a> ->'.get_string('formtitle', 'block_simplehtml'), '', '<meta name="description" content="'. s(strip_tags($site->summary)) .'">', true, '', '')

Add Access Control


Currently any user can visit this page. Right now this is not as big of a concern since the form does not do anything, but always ensure that users have access only to those portions of the application that they should. After loading the course object, add:

require_login($course);
This will ensure that only a logged in user with access to the course will be able to use the simplehtml form. See the Access Controls section of this Unit for more details. Your view.php file should now look similar to:

<?php require_once('../../config.php'); global $CFG, $USER;

require_once('simplehtml_form.php'); $courseid = required_param('courseid',PARAM_INT);

if (! $course = get_record('course', 'id', $courseid) ) { error(get_string('invalidcourse', 'block_simplehtml'). $courseid); }

require_login($course); $simplehtml = new simplehtml_form();

$site = get_site(); print_header(strip_tags($site->fullname), $site->fullname, '<a href="'.$CFG->wwwroot.'/course/view.php?id='. $courseid.'">'.$course->shortname. '</a> ->'.get_string('formtitle', 'block_simplehtml'), '', '<meta name="description" content="'. s(strip_tags($site->summary)) true, '', ''); $simplehtml->display(); print_footer(); .'">',

?>

Add Logging
Moodle uses the function

add_to_log() to log information about the user's actions. Add insert_record() in simplehtml.php:

this line of code after the if statement containing

add_to_log($id, 'block_simplehtml', 'insert page', $CFG>wwwroot.'blocks/simplehtml/view.php?courseid='. $courseid.'&blockid='.$blockid, '', 0, $USER->id);


The first parameter sent to

add_to_log is the course id, which is passed via the url or

form to simplehtml.php. The second parameter is the block or module name. The third paramater is the action taken, which is usually something simple. The fourth parameter is the url from the referring page. The fifth parameter is additional information if the string representing the action in the third parameter is not descriptive enough. The sixth parameter is the id of the course module. The final parameter is the user id.

Form State Control


Now to add some basic form state control: The first step is to setup the appropriate actions based on the form state, accounting for three scenarios: 1. 2. 3. to display a form for the first time to process submitted form data the user has canceled the form submission

To implement these three scenarios adjust the code a bit. The existing form display and header code will be used as the first time display code, and an if statement added after instantiating the simplehtml_form object will handle the logic behind the application flow:

if ($simplehtml->is_cancelled()) { // cancelled forms redirect to course main page redirect("$CFG->wwwroot/course/view.php?id=$id"); } else if ($fromform = $simplehtml->get_data()) { // we need to add code to appropriately act on and store the submitted data redirect("$CFG->wwwroot/course/view.php? id=$courseid"); } else { //form didn't validate or this is the first display $site = get_site(); print_header(strip_tags($site->fullname), $site->fullname,

'<a href="'.$CFG->wwwroot.'/course/view.php?id='. $courseid.'">'.$course->shortname. '</a> ->'.get_string('formtitle', 'block_simplehtml'), '', '<meta name="description" content="'. s(strip_tags($site->summary)) .'">', true, '', ''); $simplehtml->display(); print_footer(); }
Notice that the existing header and form display code have been moved into the third branch of the conditional. Also, there isn't any code to handle form processing. That code will be added shortly.

Final Steps
Reviewing the progress so far:

1. 2.

simplehtml_form.php is created which defines the class used later to display our form. view.php is created which:

loads base moodle API and any necessary third party modules or non-base API files

o o o

loads the necessary course object and globals performs necessary access control loads our form and branches execution appropriately based on our form state

So the form class is defined and the form is displayed in a separate file. Adding elements to the form and finishing the processing of our form will wrap it up!

Add Form Elements


Currently there are no form elements which can submit data. Editing the form class definition in simplehtml_form.php will change that by adding a wide set of form elements to the form for demonstrative purposes only. This will give an example of how to add and process various form elements. To add the link title text field and the displaytext HTML area to the form, paste the following text after the creation of the form object in the simplehtml_form.php file:

// add group for text areas $mform->addElement('header', 'displayinfo', get_string('textfields', 'block_simplehtml'));

// add page title element $mform>addElement('text','pagetitle',get_string('pagetitle','block_simplehtm l')); $mform->addRule('pagetitle', null, 'required', null, 'client');

// add display text field $mform->addElement('htmleditor', 'displaytext', get_string('displayedhtml', 'block_simplehtml')); $mform->setType('displaytexttext', PARAM_RAW); $mform->addRule('displaytext', null, 'required', null, 'client');
The page will now display:

For full details on review

addElement() review the moodle documentation on addElement. Also

addRule() in moodle's documentation and the PEAR web site. PEAR is an included

form processing library that moodle uses for form processing. Now add additional form elements to simplehtml_form.php:

File Upload
Add the file field to the form after the existing elements:

// add filename selection $mform->addElement('choosecoursefile', 'filename', get_string('displayfile', 'block_simplehtml'), array('courseid'=>$COURSE->id));


This field allows the user to choose a file in the course file directory. Notice that the name of the element in the form is the same name as the field in the database. This will make it easy to insert and update the database records later. Notice that the code uses this means that the to

$COURSE->id:

$COURSE variable needs to be added to the global variables line next

$CFG.

This next set of widgets allows optional display of a picture the user selects via a radio button, and adds alternate text that is displayed with the image. You would most likely do this directly via the HTML editor, but it's added to the form for illustration.

Fieldset Header
//add picturefields header $mform->addElement('header', 'pictureinfo', get_string('picturefields', 'block_simplehtml'));

Yes/No Select
// add display picture yes/no option $mform->addElement('selectyesno', 'displaypicture', get_string('displaypicture','block_simplehtml')); $mform->setDefault('displaypicture', 1);
Note the default value for the display pictures is set to "yes."

Radio Select
To control the available options, create a function that will return the list of available options as an array keyed by an integer. This is preferred for several reasons:

It keeps the database free from

enum field types by providing data key by integers.

This is database engine independent.

It makes it easy to add additional options at a later date by changing our function It avoids the use of global variables.

Create a file

lib.php and place the following code into it which will define the image

options via radio select.

<?php /** * Library functions for the simplehtml block **/ function block_simplehtml_images() { global $CFG; return array('<img src="' . $CFG->wwwroot . '/blocks/simplehtml/pix/picture0.jpg" alt="'.get_string('red', 'block_simplehtml').'">', '<img src="' . $CFG->wwwroot . '/blocks/simplehtml/pix/picture1.jpg" alt="'.get_string('blue', 'block_simplehtml').'">', '<img src="' . $CFG->wwwroot . '/blocks/simplehtml/pix/picture2.jpg" alt="'.get_string('green', 'block_simplehtml').'">'); }

?>
Now include the above file in any files that need to use the function, for now this is just

simplehtml_form.php. Add the following after require_once("$CFG>libdir/formslib.php"); in simplehtml_form.php


require_once($CFG->dirroot.'/blocks/simplehtml/lib.php');
Add the referenced pictures above to the appropriate directory. Create a directory called

pix in your simplehtml block directory, and extract the following archive there. Now add the
radio select to the form definition (simplethml_form.php)

// add image selector radio buttons $images = block_simplehtml_images(); $radioarray=array(); for($i = 0; $i < count($images); $i++){ $radioarray[] =&$mform->createElement('radio', 'picture', '', $images[$i],$i); }

$mform->addGroup($radioarray, 'radioar', get_string('pictureselect', 'block_simplehtml'), array(' '), false);


A group is also added to capture multiple form elements on one line. Another approach would be to just display each radio element on its own line.

Alt Text Input


Finally, to wrap-up the image display selection, allow the user to choose the alternate text that will be displayed with the selected image.

// add description field $attributes=array('size'=>'50', 'maxlength'=>'100'); $mform->addElement('text', 'description', get_string('picturedesc', 'block_simplehtml'), $attributes); $mform->setType('description', PARAM_TEXT); $mform->setType('description', PARAM_TEXT);
Note that there is an attributes variable added to the text field to limit its size and length. The

setAdvanced() function adds advanced options to a form. To use this function pass

in the name of the form element, group of elements, or header. The "Advanced Options" button appears in the upper right corner of the fieldset. In this example, there is a single element, but later you'll see an element within a header. Learn more about setAdvanced. The"Show/Hide Advanced" button won't be displayed until adding action buttons to the form during the next step of this tutorial.

Date Time Selector


Now add the date field as an optional element:

// add optional grouping $mform->addElement('header', 'optional', get_string('optional','form'), null, false);

// add date_time selector in optional area $mform->addElement('date_time_selector', 'displaydate', get_string('displaydate', 'block_simplehtml'), array('optional'=>true)); $mform->setAdvanced('optional');
The above code adds a form header and sets it to hide the date/time selector within the optional (advanced) form controls.

Add State Variables and Finalize the Form

Adding Form Buttons


Most moodle forms have a basic set of buttons. "Submit" and "Cancel" are added by calling the moodleform member function end of

add_action_buttons(). Add the following at the

simplehtml_form.php

$this->add_action_buttons();
Notice when calling because

add_action_buttons(), $this is used rather than $mform $mform.

add_action_buttons() is defined in the base class moodleform and

would be outside scope for

Add State Variables


Sometimes forms need to keep track of additional data that is not intended to be visible to users. These fields should be placed in hidden elements. For this form

blockid and the

courseid are needed. Before the call to add_action_buttons() add:


$mform->addElement('hidden','blockid'); $mform->addElement('hidden','courseid');
These elements will need to be populated by displaying code because these will be passed in via the URL initially. Before the display function in

view.php add:

$toform['blockid'] = $blockid; $toform['courseid'] = $courseid; $simplehtml->set_data($toform);


Add

$blockid as a required parameter in the form display file view.php. Add this $courseid = required_param('courseid',PARAM_INT);;

code after

$blockid = required_param('blockid', PARAM_INT);


One final note: language strings have not been added to the language file

lang/en_utf8/block_simplehtml.php.

Add the appropriate entries to the

language file. Remember the presence of a string surrounded by double square brackets (e.g., somestring) indicates that the string is missing from a language definition. After

adding your language strings your form should look something like:

Process Form Data


Important notes

Use add_to_log() sparingly. Each block, module and other PHP code will be adding data to the log table. The more information in the log table, the less useful it becomes and the slower the database queries on the table.

Always use add_to_log() when a user performs actions such as adding, editing, and deleting. Actions outside of add, edit, and delete should be used sparingly. For instance, it may be useful for an instructor to know when (or if) a student has accessed certain material in the course.

One of the more important administrative aspects wiithin Moodle is logging user actions. This helps site administrators diagnose problems, catch cheaters, and in general figure out what a user did to get to where they had a problem. This can also be invaluable to developers to determine where in your code someone was able to get to before they had a problem. Of course, the logs are also critical for teachers to monitor student activities in a course.

After creating the form, appropriate code must be added to process the submitted form data. Accomplish this by adding code to

view.php. Typically when processing form data it is

helpful to remove some of the final processing steps so that your script essentially terminates execution and does not redirect you to the course page or wherever makes sense. This is tremendously helpful while debugging. The processing code will be added to this block of code in

view.php :

else if ($fromform = $simplehtml->get_data()) { // we need to add code to appropriately act on and store the submitted data redirect("$CFG->wwwroot/course/view.php? id=$courseid"); }
For now comment out the redirect and add the following above it

print_object($fromform);

print_object() is a useful moodle function which prints out data from mixed data
types showing the keys and data for arrays and objects. Now visit the "Add Page" link for the block and submit some form data. You should see something similar to:

stdClass Object ( [MAX_FILE_SIZE] => 2097152 [pagetitle] => This is my first simplehthml page [displaytext] => Lorem ipsum dolor sit amet... [filename] => blockimage1.gif [displaypicture] => 1 [picture] => 0 [description] => Red is a great color

[displaydate] => 1222722600 [mform_showadvanced_last] => 1 [blockid] => 13 [courseid] => 2 [submitbutton] => Save changes )
The values in brackets are the keys and the portion after => is the data for that particular key. Since the form submission is verified as working as expected, save the submitted form data. The most direct way to save is with a call to

insert_record(). This function

takes the name of the table, 'block_simplehtml' in our case, and the object to be inserted. The object must have keys that map one-to-one with table column names. Choosing form element names that map directly to the database columns saves a bit of code. Save the submitted form data with the following code pasted above the commented out redirect:

if(!insert_record('block_simplehtml',$fromform)){ error(get_string('inserterror' , 'block_simplehtml')); }


Notice that upon checking for a call to

insert_record an okay status is returned; and if print_object() call and un-comment

not an error is produced. Now comment out the the call to

redirect(). Finally, test to see if the form submission and saving works

properly by submitting some data using the form. You can review that the data was stored in the proper table by viewing the table block_simplehtml via phpmyadmin. You should see something similar to the this:

Note if you receive an error, verify that your table exists in the database. Remember update code wasn't added to install the database table after the block has already been installed. When developing within a localized environment load the database by uninstalling the module and then reinstalling it. In normal circumstances where the block or module has been in production use you would need to do this with proper update code.

Unit 7 - Part C - Refine the User Interface


Part A - Block Basics
1. 2. 3. Create a simple block following Moodle's tutorial. The block will be named "simplehtml." Create a language file and directory. Create a database table into which our block will insert information.

Part B - Forms
1. Add a form using the Moodle forms library to insert information into the table

o o o o o o o o
2.

Define a new form. Display the new form. Add a header. Add access control. Add logging. Add form elements. Add state variables. Finalize the form.

Process the form.

Part C - Refine the User Interface


1. 2. 3. Add links to each page of the block. Add methods to view pages. Refactor display method.

o o
4. 5. 6.

Add page title. Display the date

Display text. Display link to file. Display the picture.

Part D - Add Editing Capabilities


Add editing capabilities that allow users to edit data, including 1. 2. Delete a page Add a link to the delete.php file

3.

Create the delete.php file Clean up all data associated with the block with the

4.

instance_delete() function

Part E - Define a Role for the Block


1. 2. 3. 4. Add check to the block for the capability Add a role to the simplehtml form Add a role to edit Add a role to delete

Block Basics | Forms | Refine the User Interface | Add Editing Capabilities | Define a Role After successfully submitting data to the database via the form it is now time to begin displaying that data so that users can interact with the data and view what has been submitted. Both steps will be contained within simplehtml/block_simplehtml.php.

Add Links to Each Page of the Block


To retrieve the relevant rows call 1. 2. the table name the name of the column or field to be queried the value of the queried field we want to match (note the use of

get_records(), which accepts three parameters::

3.

$this-

>instance->id, which is the same as blockid within this scope)


Add the following code after

$this->content->text = $this->config-

>text:
if($simplehtmlpages = get_records('block_simplehtml', 'blockid', $this->instance->id)){ $this->content->text .= '<ul class="block-simplehtml-pagelist">'; foreach($simplehtmlpages as $simplehtmlpage){ $this->content->text .= '<li><a href="'.$CFG->wwwroot. '/blocks/simplehtml/view.php?id='. $simplehtmlpage->id. '&courseid='.$COURSE->id.'">'. $simplehtmlpage->pagetitle.'</a></li>'; } $this->content->text .= '</ul>'; }

Add Methods to View Pages


Review the links created earlier to see that the file 1. 2. 3. 4.

view.php is needed that will:

Check for any required variables; id (references the simplehtml page id), courseid Verify the courseid given is a valid course Verify the user is logged in Verify thathte user has the appropriate permissions to view any output thescript may generate

5. 6. 7. 8.

Retrieve the database record for the simplehtml page requested Print the header for the page Display the information for the page requested Print the page footer

Many of these steps have previously been completed. Try to work through the list above, skipping over the "display information for the page requested". Your code should look similar to:

<?php // include moodle API and any supplementary files/API require_once('../../config.php'); require_once('simplehtml_form.php');

// declare any globals we need to use global $CFG, $USER;

// check for all required variables $id = required_param('id', PARAM_INT); $courseid = required_param('courseid',PARAM_INT);

// ensure we have a valid courseid and can load the associated course object if (! $course = get_record('course', 'id', $courseid) ) { error(get_string('invalidcourse', 'block_simplehtml', $courseid)); }

// ensure the user has access to this course require_login($course);

// ensure the user has appropriate permissions to access this area require_capability('block/simplehtml:viewpages', get_context_instance(CONTEXT_COURSE, $courseid));

// ensure we have a valid simplehtml page id and can load the associated page if(!$simplehtmlpage = get_record('block_simplehtml', 'id', $id)){ error(get_string('nopage','block_simplehtml', $id)); }

// print the header and associated data $site = get_site(); print_header(strip_tags($site->fullname), $site->fullname, '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$courseid.'">'. $course->shortname. '</a> ->'.$simplehtmlpage->pagetitle, '', '<meta name="description" content="'. s(strip_tags($site>summary)) .'">', true, '', '');

// display page information

// print the footer print_footer(); ?>


Note the use of a third parameter with

get_string(). The third parameter allows

Moodle's translation system to substitute variables in proper locations after being translated. Consider one example from the above code.

error(get_string('invalidcourse', 'block_simplehtml', $courseid));


This calls

get_string() searching for 'invalidcourse' in the 'block_simplehtml' language

file, and finally it passes in $courseid. Then in the language file for the block this string will have acess to the value passed in through the third paramter as $a.

$string['invalidcourse'] = 'The courseid $a does not exist';

Refactor Display Method


To avoid any code duplication and make it easy to reuse this functionality create a function in lib.php to handle the page display. A preloaded simplehtml page is passed in as a single parameter, and an optional parameter will control whether the data is returned or directly printed out. Most Moodle functions that print information can be passed a true value as the last parameter. This is the function's return value, which tells the function to return the HTML and not print or echo it to the user. For development, set the return value to false so that the data is printed out.

function block_simplehtml_print_page($simplehtml, $return = FALSE){}

Important Tip
The function block_simplehtml_print_page uses

block_simplehtml in the beginning of the function name to avoid any


namespace collisions. Namespace collisions are important to consider when naming variables and functions in Moodle beause Moodle has many hooks that call different functions at different times. It is generally considered good practice to preface a varable or function name with the name of the block or module to avoid problems with namespace collisions. Now consider what the function needs to do in order to display all of the necessary information from our page. Page Title Print this out as a centered header for the HTML PAGE Display Text Print this out in whatever format the user specified, centered in a box on the page Filename Display a link to the file in the course file directory so the user has the option to download it. This will be centered in the same box as the display text. Display Picture Display the picture with the description on the right of the picture in a box if the user has chosen for the picture to display Display date Display the date under the page title in a smaller font

Add Page Title


To display the page title use moodle's

print_heading() function. Add the following to

block_simplehtml_print_page() in lib.php

$output = print_heading($simplehtml->pagetitle, 'center', 2, 'main', TRUE);


The parameters in order are 'text', 'text-alignment', 'header size', 'css class', and finally whether to directly print the output or return it.

Display the Date


The requirements for date display call for displaying the date ni a smaller font under the page title. First, display the date. Moodle has a advantages over PHP's

userdate() function that has several

date() function. It displays the date in the user's preferred format

and adjusts the date for any timezone difference.

if ($simplehtml->displaydate) { $output .= userdate($simplehtml->displaydate); }


Notice that since the user had an option of choosing a date or not that you must check to ensure that it was set before trying to output it. Take a look at the displayed page: click on one of your page links from the block. There's no output. Add some additional code that handles the value of

$return. Add the following at the end of the function definition:

if ($return) { return $output; } else { print $output; }


Now try refreshing your page. You should see something like:

As mentioned earlier, the requirements for the date field were to be centered under the page title and smaller. This can be controlled with a stylesheet. First, add a div tag around the date, and give it a class to target with CSS later. Change the date output line:

$output .= '<div class="simplehtml displaydate">'.userdate($simplehtml->displaydate).'</div>';


There are two options for adding the stylesheet:

1. 2.

Add the CSS to the theme's CSS files in the theme directory Create a styles.php file in the block and add the CSS there

Choosing the second option, adding a

styles.php file, allows more flexibility and avoids

needing to create multiple entries if the site is using more than one theme. Create

styles.php and add this CSS:


.simplehtml.displaydate { font-size: .8em; text-align: center; }
Now refresh the page and the date should be displayed properly.

Display Text
Now the display text needs to be added to a box.

Within moodle there are two ways to display a box:

1. print_box() and 2.
a combination of

print_box_start() and print_box_end().

The output is the same; which one you choose is mostly a matter of preference. To add two different pieces of data to the box, display text and the file link, the example code uses

print_box_start() and print_box_end() for readability.


$output .= print_box_start('generalbox', '', TRUE); $output .= clean_text($simplehtml->displaytext); $output .= print_box_end(TRUE)

Display Link to File


To generate a file URL call the function

get_file_url(), but the function is defined in

lib/filelib.php and is not a part of the core moodle API. So ensure you have access
to this file by calling

include_once(). Add the following near the top of the function:

global $CFG, $COURSE; include_once($CFG->dirroot.'/lib/filelib.php');


Now add the following lines just before the call to

print_box_end()

$fileurl = get_file_url($COURSE->id.'/'.$simplehtml->filename); $output .= '<br /><a href="'.$fileurl.'">'.get_string('viewfile', 'block_simplehtml').'</a>';


Notice that providing more than just the filename of the file to create a proper URL is necessary. The course id for the course in question must also be provided.

Display the Picture


To selectively display the picture with its description text located to the right of it:

if ($simplehtml->displaypicture) { $images = block_simplehtml_images(); $output .= print_box_start('generalbox', '', TRUE); $output .= $images[$simplehtml->picture]; $output .= $simplehtml->description; $output .= print_box_end(TRUE); }
The page should now look like:

Unit 7 - Part D - Add Editing Capabilities


Part A - Block Basics
1. 2. 3. Create a simple block following Moodle's tutorial. The block will be named "simplehtml." Create a language file and directory. Create a database table into which our block will insert information.

Part B - Forms
1. Add a form using the Moodle forms library to insert information into the table

o o o o o

Define a new form. Display the new form. Add a header. Add access control. Add logging.

o o o
2.

Add form elements. Add state variables. Finalize the form.

Process the form.

Part C - Refine the User Interface


1. 2. 3. Add links to each page of the block. Add methods to view pages. Refactor display method.

o o
4. 5. 6.

Add page title. Display the date

Display text. Display link to file. Display the picture.

Part D - Add Editing Capabilities


Add editing capabilities that allow users to edit data, including 1. 2. 3. Delete a page Add a link to the delete.php file Create the delete.php file Clean up all data associated with the block with the

4.

instance_delete() function

Part E - Define a Role for the Block


1. 2. 3. 4. Add check to the block for the capability Add a role to the simplehtml form Add a role to edit Add a role to delete

Block Basics | Forms | Refine the User Interface | Add Editing Capabilities | Define a Role Students and teachers can view links and the teacher can create links, but what happens if they make a mistake? There is no way to edit anything that has previously been entered. Good developers want their blocks to be used, which means the block needs to include a way for the user to edit the existing data. A way to edit what a user entered must be added to the simplehtml block. The edit feature will use an image to link to the edit.php instead of text. This image will only appear when the instructor turns editing on.

Moodle stores pictures and icons in the pix directory under the base moodle directory. You can also use pictures that are custom to a theme. These are stored within the theme's pix directory. For this example, use the icons in the pix directory for moodle. The image should be encapsulated in an HTML link to simplehtml.php. The url should pass the block instance id, block id, and course id to simplehtml.php.

Before displaying the added edit image and link verify that editing has been turned on (checking that the user has appropriate permissions is covered in the last section, Access Controls). The function on for the course. The

isediting() is used to determine if the user has editing turned

isediting() function is passed the pageid for the block

instance, which in most cases is the same as courseid. Edit the block_simplehtml.php file, as follows:

if($simplehtmlpages = get_records('block_simplehtml', 'blockid', $this->instance->id)){ $this->content->text .= '<ul class="block-simplehtml-pagelist">'; foreach($simplehtmlpages as $simplehtmlpage){ if ($canmanage) { $edit = '<a href="'.$CFG>wwwroot.'/blocks/simplehtml/view.php?id=' .$simplehtmlpage->id.'&blockid='.$this>instance->id.'&courseid='. $COURSE->id.'"><img src="'.$CFG>pixpath.'/t/edit.gif" alt="'. get_string('editpage', 'block_simplehtml').'" /></a>'; } else { $edit = ''; } $this->content->text .= '<li><a href="'.$CFG->wwwroot. '/blocks/simplehtml/view.php?id='. $simplehtmlpage->id. '&courseid='.$COURSE->id.'">'. $simplehtmlpage->pagetitle.'</a>'.$edit.'</li>'; }

$this->content->text .= '</ul>'; }
Notice that there's a link to the same file few adjustments to

view.php that handled the page adding. Make a

view.php so that pages can also be updated.

First, modify the form to have a new hidden field called id to store the id of the record in the database to know which page to update. Add the following to

simplehtml_form.php :
$mform->addElement('hidden','id','0');
Second, add an optional parameter to the form to track the id in the event you update an existing page. Add the following code to

view.php

$id = optional_param('id',0, PARAM_INT);


Third, adjust the first time display or failed form validation display portion of load necessary data when

view.php to

$id is present:

//form didn't validate or this is the first display if ($id != 0) { if (!$toform = get_record('block_simplehtml', 'id', $id)) { error(get_string('nopage', 'block_simplehtml', $id)); } } else { $toform = new stdClass; } $toform->blockid = $blockid; $toform->courseid = $courseid; $site = get_site(); print_header(strip_tags($site->fullname), $site->fullname, '<a href="'.$CFG->wwwroot.'/course/view.php?id='. $courseid.'">'.$course->shortname. '</a> ->'.get_string('formtitle', 'block_simplehtml'), '', '<meta name="description" content="'. s(strip_tags($site>summary)) .'">', true, '', '');

$simplehtml->set_data($toform);

$simplehtml->display(); print_footer();
Notice that handling of the

$toform variable has been adjusted. It is now an object rather

than an array. This is to provide consistency regardless of whether we are adding a new page or updating an existing one. Finally, change the code to conditionally update or insert a new record. In the middle conditional block (elseif) adjust as follows to update records when the id field is non-zero

// add code to appropriately act on and store the submitted data if ($fromform->id != 0) { if (!update_record('block_simplehtml', $fromform)) { error(get_string('updateerror', 'block_simplehtml')); } add_to_log($blockid, 'block_simplehtml', 'update page', $CFG>wwwroot. 'blocks/simplehtml/view.php?blockid='. $blockid.'&courseid'. $courseid, '', $blockid, $USER->id); } else { if (!insert_record('block_simplehtml',$fromform)) { error(get_string('inserterror' , 'block_simplehtml')); } add_to_log($id, 'block_simplehtml', 'insert page', $CFG>wwwroot.'blocks/simplehtml/view.php?courseid='.$courseid.'&blockid='. $blockid, '', 0, $USER->id); } redirect("$CFG->wwwroot/course/view.php? id=$courseid");

Page Deletion
After being able to add a page and edit a page, what else would someone need to do with our html pages? Delete! Deleting is a simple operation; requiring a few simple steps:: 1. 2. 3. Add a link to a new delete.php file Create the delete.php file Print a verification form to the screen in case the user made a mistake

4.

Use

delete_record() to delete a record from the simplehtml table given an id

and a confirmation.

Add a Link to delete.php


Begin by editing

block_simplehtml.php and creating a link just after the edit link.

$delete = '<a href="'.$CFG->wwwroot.'/blocks/simplehtml/delete.php? id='. $simplehtmlpage->id.'&courseid='.$COURSE->id.'"><img src="'. $CFG->pixpath.'/t/delete.gif" alt="'. get_string('deletepage','block_simplehtml').'" /></a>';
Remember to set the links to a blank string if the user doesn't have the correct permissions:

if ($canmanage) { $edit = '<a href="'.$CFG->wwwroot.'/blocks/simplehtml/view.php? id=' .$simplehtmlpage->id.'&blockid='.$this->instance>id.'&courseid='. $COURSE->id.'"><img src="'.$CFG->pixpath.'/t/edit.gif" alt="'. get_string('editpage', 'block_simplehtml').'" /></a>';

$delete = '<a href="'.$CFG>wwwroot.'/blocks/simplehtml/delete.php?id='. $simplehtmlpage->id.'&courseid='.$COURSE->id.'"><img src="'. $CFG->pixpath.'/t/delete.gif" alt="'. get_string('deletepage','block_simplehtml').'" /></a>'; } else { $edit = ''; $delete = ''; } $this->content->text .= '<li><a href="'.$CFG->wwwroot. '/blocks/simplehtml/view.php?id='. $simplehtmlpage->id. '&courseid='.$COURSE->id.'">'.

$simplehtmlpage->pagetitle.'</a>'.$edit.$delete.'</li>'; }

Create delete.php
Refresh the course page and you should now see a black X icon next to each page after the edit icon (when editing is turned on). The purpose of delete.php is to print out a notice to the user with a verification that the user wants to delete the simplehtml page. The notice will either return the user to the course if they say No, or delete the page and return the user to the course if they say Yes. Moodle has a predefined core function in weblib.php that will create the Yes-No form for you and send the user on to the correct locations based on the answer to the question. The function is called

notice_yesno(). Before using this, setup

the basic file structure for delete.php (it's similar to what has been used for most of the other files like view.php and simplehtml.php).

<?php require_once('../../config.php'); global $CFG, $USER, $SITE;

$courseid = required_param('courseid',PARAM_INT); $id = optional_param('id',0, PARAM_INT); $confirm = optional_param('confirm',0,PARAM_INT);

if (! $course = get_record('course', 'id', $courseid) ) { error(get_string('invalidcourse', 'block_simplehtml'). $courseid); }

require_login($course); require_capability('block/simplehtml:managepages', get_context_instance(CONTEXT_COURSE, $courseid));

if(! $simplehtmlpage = get_record('block_simplehtml', 'id', $id)){ error(get_string('nopage','block_simplehtml',$id)); }

$site = get_site(); print_header(strip_tags($site->fullname), $site->fullname,'<a href="'. $CFG->wwwroot.

'/course/view.php?id='.$courseid.'">'.$course->shortname.'</a> ->'. $simplehtmlpage->pagetitle, '','<meta name="description" content="'. s(strip_tags($site->summary)) .'">',true, '', '');

print_footer(); ?>
This common code:

Checks the courseid corresponds to a valid course Checks that the user is logged in Checks that the simplehtml page id corresponds to an existing page id Prints out the header and footer for the page

Notice that this is similar to what has been used so far, but there another optional parameter 'confirm' has been added. This variable will be set when the user clicks the Yes or No button on the form. This means that a test needs to be added to test for the return value; if it is set then the database record containing the simple page id should be deleted. Add the following code after the all to the

print_header() function:

Important Tip!
Most IDEs and programmer's text editors allow you to create templates for commonly used code snippets. Turning sections of code you use often into templates can save a lot of time and typing!

if(!$confirm){ $optionsno = array('id'=>$courseid); $optionsyes = array ('id'=>$id, 'courseid'=>$courseid,'confirm'=>1, 'sesskey'=>sesskey()); print_heading(get_string('confirmdelete', 'block_simplehtml')); notice_yesno(get_string('deletepage', 'block_simplehtml', $simplehtmlpage->pagetitle), 'delete.php', $CFG->wwwroot.'/course/view.php', $optionsyes, $optionsno, 'post', 'get'); } else {

if (confirm_sesskey()) { if (! delete_records('block_simplehtml','id',$id)) { error('deleterror','block_simplehtml'); } } else { error('sessionerror','block_simplehtml'); } add_to_log($id, 'block_simplehtml', 'delete page', $CFG>wwwroot.'course/view.php?&id='. $courseid, '', $id, $USER->id); redirect("$CFG->wwwroot/course/view.php?id=$courseid"); }
In the if statement above, the two variables

optionsno and optionsyes are set.

These are used to pass variables from the form to get or post when the user selects "yes" or "no." They are passed to the

notice_yesno() function as the fifth and sixth

parameters. If the user clicks "no" they are sent to the course page, which means the courseid needs to be added to the form. If the user clicks "yes" the database record containing the simplehtml page id is deleted and the user is forwarded to the course. The page id, courseid, confirm, and the session key need to be passed to the form. The session key is passed to prevent the possibility of a cross-site scripting attach or users submitting valid form data without using Moodle. Now take a look at the parameters passed the

notice_yesno() function. The first

parameter is the text string that is displayed before the Yes and No buttons. The second parameter is the url where the form sends the user when they click the yes button.The third parameter is the url to where the user will be sent if they click on the no button. The sixth and seventh parameters are the http methods (Get or Post) used to send the form data for the yes and no buttons.

Final Cleanup
The block is almost finished! The one thing that has not been done is the cleanup of all data associated with the block on deletion. This is accomplished by adding a function named

instance_delete() to the block. In this function call the delete records and use the
blockid to pass in the

$this->instance->id variable. The function looks like this:

function instance_delete(){ delete_records('simplehtml','blockid', $this->instance->id); }

Unit 7 - Part E - Define a Role for the Block


Part A - Block Basics
1. 2. 3. Create a simple block following Moodle's tutorial. The block will be named "simplehtml." Create a language file and directory. Create a database table into which our block will insert information.

Part B - Forms
1. Add a form using the Moodle forms library to insert information into the table

o o o o o o o o
2.

Define a new form. Display the new form. Add a header. Add access control. Add logging. Add form elements. Add state variables. Finalize the form.

Process the form.

Part C - Refine the User Interface


1. 2. 3. Add links to each page of the block. Add methods to view pages. Refactor display method.

o o
4. 5. 6.

Add page title. Display the date

Display text. Display link to file. Display the picture.

Part D - Add Editing Capabilities


Add editing capabilities that allow users to edit data, including 1. 2. 3. Delete a page Add a link to the delete.php file Create the delete.php file Clean up all data associated with the block with the

4.

instance_delete() function

Part E - Define a Role for the Block


1. 2. 3. 4. Add check to the block for the capability Add a role to the simplehtml form Add a role to edit Add a role to delete

Block Basics | Forms | Refine the User Interface | Add Editing Capabilities | Define a Role Hyperlinks appear in new browser windows. With the table established, create a capability to allow the Moodle Administrator to determine which roles can add links to the simple html block. Read the Programming Interface section of Moodle docs to get a basic idea of how to create a capability. Create two capabilities for this block: 1. 2. View simplehtml page(s) which will be block/simplehtml:viewpages Modify/add simplehtml page(s) which will be block/simplehtml:managepages

Following the instructions in the Programming Interface section of Moodle docs, create an access.php file in the blocks/simplehtml/db directory. In that file add the simplehtml capability array:

<?php /* * Capabilities for simplehtml block */ $block_simplehtml_capabilities = array( ); ?>

Next add the two capabilities arrays, block/simplehtml:viewpages and block/simplehtml:managepages to the above array. Each array should have the following attributes:

block/simplehtml:viewpages

o o o

type: read context: course Legacy:

Guest: prevent Student: allow Teacher: allow Editing teacher: allow Coursecreator: allow Admin: allow

block/simplehtml:managepages

o o o

type: write context: course Legacy:

Guest: prevent Student: prevent Teacher: prevent Editing teacher: allow Coursecreator: allow Admin: allow

In the end, your access.php should look like:

<?php /* * Capabilities for simplehtml block */ $block_simplehtml_capabilities = array(

'block/simplehtml:viewpages' => array(

'captype' => 'read', 'contextlevel' => CONTEXT_COURSE, 'legacy' => array(

'guest' => CAP_PREVENT, 'student' => CAP_ALLOW, 'teacher' => CAP_ALLOW, 'editingteacher' => CAP_ALLOW, 'coursecreator' => CAP_ALLOW, 'admin' => CAP_ALLOW ) ),

'block/simplehtml:managepages' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_COURSE, 'legacy' => array( 'guest' => CAP_PREVENT, 'student' => CAP_PREVENT, 'teacher' => CAP_PREVENT, 'editingteacher' => CAP_ALLOW, 'coursecreator' => CAP_ALLOW, 'admin' => CAP_ALLOW ) ) ); ?>
Now bump the version number up in blocks/simplehtml/block_simplehtml.php. Change the last 0 to a 1 where you set

$this->version. The line should look like:

$this->version = 2008010101;
Next go to the notifications link in the Site Administration block. This should update the simplehtml block. Verify that capabilities have been added by going to Users > Permissions > Define roles and selecting Administrator. Search for simplehtml.

What does the simplehtml:viewpages mean? The presence of a string surrounded by double square brackets implies that there is a string referenced in code that has not been defined in an appropriate language file. Add the following to lang/en_utf8/block_simplehtml.php:

$string['simplehtml:viewpages'] = 'View Simple HTML Pages'; $string['simplehtml:managepages'] = 'Manage Simple HTML Pages';
With the problem fixed, your Define Roles page will now look like:

In this part of the unit so far, you have learned how to create a basic block with all the standard functions that Moodle needs to display the block with some limited configuration. You have learned how to create a database table using the XMLDB editor in Moodle, added a new language file for the block, and created capabilities that a block can use to determine if a user has the correct permissions. Next you will work on creating a form to add information to the database table you created.

Add check to the block for the capability


With the two new capabilities created, it's time to use them and add a link to the soon-to-becreated form in the block. The easiest place to add the link is in the footer, but it's critical that the person viewing this link has the capability to manage simplehtml page. Modify the

get_content() function in blocks/simplehtml/block_simplehtml.php to check for the


correct capabilities.To check for the capabilities, use the

has_capability()

function

found in lib/access.php. But first add the global variable $COURSE and $CFG to the function using:

global $COURSE, $CFG;


To check if the user has the correct view permissions replace:

$this->content->text = $this->config->text;
with

$context = get_context_instance(CONTEXT_COURSE, $COURSE>id); if (has_capability('block/simplehtml:viewpages', $context)) { $this->content->text = $this->config->text; } else { $this->content->text = ''; }

To add the link to the form replace:

$this->content->footer = '';
with:

if (has_capability('block/simplehtml:managepages', $context)) { $this->content->footer = '<a href="'. $CFG->wwwroot. '/blocks/simplehtml/simplehtml .php?blockid='.


$this->instance->id.'&courseid='.

$COURSE->id.'">'. get_string('addpage','block_simplehtml').'</a>'; } else { $this->content->footer = ''; }


Your final

get_content() should look like:

function get_content() { global $COURSE, $CFG; if ($this->content !== NULL) { return $this->content; }

$this->content = new stdClass;

$context = get_context_instance(CONTEXT_COURSE, $COURSE->id);

if (has_capability('block/simplehtml:viewpages', $context)) { $this->content->text = $this->config->text; } else { $this->content->text = ''; }

if (has_capability('block/simplehtml:managepages', $context)) {

$this->content->footer = '<a href="'. $CFG->wwwroot . '/blocks/simplehtml/page.php?blockid='. $this->instance->id.'&courseid='. $COURSE->id.'">'. get_string('addpage', 'block_simplehtml').'</a>'; } else { $this->content->footer = ''; }

return $this->content; }
Notice while building the link that

$this->instance->id is used. This is an identifier

that is unique to each block instance in a course and enables the use of multiple blocks in a course. Courseid is also used, along with the block instance id, to easily find all pages associated with the block for a course. The link to page.php is also sent, which is nonexistent; it will be added with the necessary code in the next section. While constructing our link,

get_string() is also used, so an entry for the string

'addpage' will need to be added to the language file for the block with text of your
choice. Finally, refresh the Moodle course to which you have added the simplehtml block. As an administrator or teacher you should see the 'addpage' link; as a student you should not see the link.

Add Role to the simplehtml Form


Currently any logged in user can use the simplehtml form. In development this is not as big of a concern, but before moving intro production always ensure that users have access only to those portions of the application that they should. In page.php after

require_login($course); add the following line: require_capability('block/simplehtml:managepages', get_context_instance(CONTEXT_COURSE, $courseid));


This ensures the user cannot access this page without having the capability 'block/simplehtml:managepages'.

Add Role to Editing


Restrict editing to users who have the block/simplehtml:managepages capability by adding access control to the editing action. In edit.php use the variable

$canmanage to

determine access. Set this variable by verifying the user has the proper capability.

$canmanage = isediting($course->id) && has_capability('block/simplehtml:managepages', get_context_instance(CONTEXT_COURSE, $courseid));

Add Role to Delete


To restrict deletion to those who have the managepages capability, add the following line to delete.php after

require_login($course);

require_capability('block/simplehtml:managepages', get_context_instance(CONTEXT_COURSE, $courseid));

Unit 8: Testing Methods


Overview | Unit 8 "To Do" List External resources will open in new browser windows. Software Testing and Q.A. (Quality Assurance) is a big topic, although it is also a very important topic to all programmers. Big companies usually have dedicated software Q.A. engineers responsible only for software testing or QA. Although crucial to software quality and widely deployed by programmers and testers, software testing still remains an art, due to limited understanding of the principles of software. The difficulty in software testing stems from the complexity of software: we can not completely test a program with moderate complexity. [Software-Engineering. (2002). Hagen: Fernuniv., Fachbereich Informatik.] Testing is more than just debugging. The purpose of testing can be quality assurance, verification and validation, or reliability estimation. Testing can be used as a generic metric as well. Correctness testing and reliability testing are two major areas of testing. Software testing is a trade-off between budget, time and quality.[Software Testing. (1999). Pan: Carnegie Mellon University.] More detail on software quality assurance. In this unit we will focus on some topics that are particularly important to Moodle developers.

Black Box Testing


According to Wikipedia (2-14-08): "Black box testing takes an external perspective of the test object to derive test cases. These tests can be functional or non-functional, though usually functional. The test designer selects valid and invalid input and determines the correct output. There is no knowledge of the test object's internal structure. This method of test design is applicable to all levels of software testing: unit, integration, functional testing, system and acceptance. The higher the level, and hence the bigger and more complex the box, the more one is forced to use black box testing to simplify. While this method can uncover unimplemented parts of the specification, one cannot be sure that all existent paths are tested." Users might want to evaluate or compare new versions of Moodle before making a final decision on upgrading. The "black box testing" of the new code base from an end users perspective--identifying possible issues--can be valuable.

White Box Testing


According to Wikipedia (2-14-08): "White box testing (a.k.a. clear box testing, glass box testing or structural testing) uses an internal perspective of the system to design test cases based on internal structure. It requires programming skills to identify all paths through the software. The tester chooses test case inputs to exercise paths through the code and determines the appropriate outputs ... Since the tests are based on the actual implementation, if the implementation changes, the tests probably will need to also." For example, if an important function in the Moodle quiz module changes, then most quiz test cases probably need to be reviewed as well. "While white box testing is applicable at the unit, integration and system levels of the software testing process, it is typically applied to the unit. While it normally tests paths within a unit, it can also test paths between units during integration, and between subsystems during a system level test. Though this method of test design can uncover an overwhelming number of test cases, it might not detect unimplemented parts of the specification or missing requirements, but one can be sure that all paths through the test object are executed."

Regression Test
According to Wikipedia (2-14-08): "Regression testing is any type of software testing which seeks to uncover regression bugs. Regression bugs occur whenever software functionality that previously worked as desired, stops working or no longer works in the same way that was previously planned. Typically regression bugs occur as an unintended consequence of program changes. Common methods of regression testing include re-running previously run tests and checking whether previously fixed faults have re-emerged." A typical example of using regression testing is to verify whether new bug fixes in Moodle actually introduced other new bugs. Other than the 'manual' way of testing, you might find using automated testing tools such as "Selenium IDE" with some pre-established test cases would be very helpful to verify whether the test cases still behave the same way. "Selenium IDE" will be explored in more detail later. top

Unit Test
According to Wikipedia (2-14-08): "In computer programming, unit testing is a procedure used to validate individual units of source code are working properly. A unit is the smallest testable part of an application. In procedural programming a unit may be an individual program, function, procedure, etc., while in object-oriented programming, the smallest unit is a method; which may belong to a base/super class, abstract class or derived/child class." Once unit testing has given you the confidence that each part works, then you should use other forms of testing to ensure that the different parts work together properly. Moodle has a built in unit test framework which is based on a SimpleTest framework. Later we will discuss how to use this framework. Refer to these helpful resources for additional information: unit testing in general; test design techniques, Moodle's unit tests. Moodles own Unit tests is a tool for Moodle developers to evaluate Moodle codes and is found in the Administration block under Reports when logged in as a Moodle system administrator.

Unit tests can be one of the first steps in a quality control process for developing or tweaking Moodle code.

Selenium Cases
According to OpenQA (2-14-08): "Selenim IDE is an Integrated Development Environment for Selenium tests. It is implemented as a Firefox extension, and allows you to record, edit, and debug tests. Selenium IDE includes the entire Selenium Core, allowing you to easily and quickly record and play back tests in the actual environment that they will run. Selenium IDE is not only a recording tool: it is a complete IDE. You can choose to use its recording capability, or you may edit your scripts by hand. With autocomplete support and the ability to move commands around quickly, Selenium IDE is the ideal environment for creating Selenium tests no matter what style of tests you prefer. Features of Selenium IDE are

Easy record and playback Intelligent field selection will use IDs, names, or XPath as needed Autocomplete for all common Selenium commands

Walk through tests Debug and set breakpoints Save tests as HTML, Ruby scripts, or any other format Support for Selenium

user-extensions.js file

Option to automatically assert the title of every page"

To use Selenium IDE for Moodle testing, you can record a sequence of interactions with your Moodle site, and later play them back and see if they still work after you tweak some of the Moodle codes. There are some limitations applying Selenium IDE to Moodle:

Selenium will not wait for 'Continue' redirects to happen. When recording a sequence of actions, you need to click on the continue links manually.

By default, it tends to record actions using ids, and in Moodle these sometimes contain arbitrary database ids. For example, submitting a quiz question, it will record

clickAndWait resp94_submit. However, you can edit this to say clickAndWait //input[@value='Submit'].

At other times, by default, it is not specific enough. For example, deleting a course, it records

//a[img/@alt='Delete'] which will just delete the first course //a[img/@alt='Delete' and

listed! Again, you can edit it to something like

../../td[1]/a='Selinium quiz test course'], which will delete


a named course.

It sometimes doesn't work with pop-up windows even though it should support them.

Additional information about how to use Selenium to design some automated tests for Moodle, is available at Moodle's "Quiz and questions community testing day" and in the discussion forum post by Tim Hunt, "Selinium [sic] for testing Moodle". top

"To Do" List


As part of this Unit's activities, follow the instructions below to (1) run the basic "unit test" tests, (2) write your own unit test code, and (3) create a Selenium case.

1. Run basic unit tests.


Use these steps to perform a basic Moodle unit" test.

a.

Log in with an admin account. Go to the Site Administration block Click on the Reports link near the bottom of the block on the lower right corner.

b. c. d. e.
f.

Click on the Unit tests link Click on the Run tests button. (You could select the options that you want here, we will explain these options below). Wait for the tests to complete.

Options for Running the Tests


o
Show passes as well as fails. Normally, only details of the tests that have failed are printed. Turning on this option shows details of all the successful passes too.

Show the search for test files. The tests to run are found automatically be searching the codebase for files whose names match test*.php in directories called simpletest. Turning on this option will print a list of the folders searched and the test files found. This is sometimes useful for debugging but is particularly useful when one of your test files has a syntax error. When this happens, you sometimes just get a blank page with no error message. Turning on the show search option lets you see which test file it was that gave the error. If necessary, you can enable this option manually by adding "showsearch=1" to the end of the URL.

Run a thorough test (may be slow). If you turn on this option, then as well as looking for files called test*.php, the search also looks for files called slowtest*.php. To be useful, the full test run should find most bugs, but not take too long to complete. So if you have very, very detailed tests of an area of the code, it may be better to select a subset for everday testing, and only use the more detailed tests when a bug is reported, or you are doing new development in that area of the code. This option is most useful when combined with the next option.

Only run tests in [textfield]. Normally, tests from all parts of the codebase are run. However, when you are just doing development of one part of the code, this is a waste of time. You can type the name of a directory (for example mod/quiz) or a particular test file (for example lib/simpletest/testdatalib.php) and then only those tests will be run.

Pass:

lib/simpletest/testdatalib.php ->

datalib_test -> test_get_record -> False xxxxxxxxx get False at [/var/www/html/tjh238/head/lib/simpletest/testdat alib.php line 92]
Instead of typing a path into this box, there is an easier way. Whenever a pass or fail is displayed, the name of the test file is printed. Each section of the path name is a link to run only the tests in that folder or file. top

2.

Write Test Code


Continuing with the example "simplehtml" from Unit 7, write a unit test for the function block_simplehtml_convert_unixtime in the file /blocks/simplehtml/lib.php. To get a better understanding of how to create codes for unit tests, browse through these files:

[For testing GROUPS] /group/simpletest/test_basicgrouplib.php (Unit tests for new Moodle Groups basicgrouplib.php and some functions in utillib.php) /group/simpletest/test_groupinglib.php (Unit tests for new Moodle Groups groupinglib.php) Create a directory called /blocks/simplehtml/testlib and create a file in it named test_lib.php. The actual content of this file should look like:

<?php require_once(dirname(__FILE__) . '/../../config.php'); global $CFG; require_once($CFG->libdir . '/simpletestlib.php'); require_once($CFG->dirroot . '/group/lib/basicgrouplib.php'); require_once($CFG->dirroot . '/group/lib/utillib.php');
class basicgrouplib_test

extends UnitTestCase {

var $courseid= 0;

var $userid = 0; var $userid_2= 0; var $groupid = 0; function __construct() { parent::UnitTestCase(); } function test_block_simplehtml_convert_unixtime() { xxxxx } } ?>
That is, you have a class called something_test, and in that class you have lots of methods called test_something. Normally,there is one test method for each function to test, and you may as well call the test method test_name_of_function_being_tested. In this example, this method can be called test_block_simplehtml_convert_unixtime.

How to write test case documents


Moodle has a preliminary standard to build up test cases. These test cases basically are some "scenarios" that should be run in Moodle before each release. Currently this test plan is far from perfect, although more people in the Moodle community are starting to contribute more test cases on the Moodle documentation wiki (http://docs.moodle.org). The existing scenarios should be run in the downloaded Moodle Test Course. Here are some general rules:

Test Case Naming conventions:

o o o

[AAA] : Three characters that represent the block or module name [000] : Three digits that number the question [A] : Potential actor = S: student, T: teacher, A: admin

The testing plans are categorized by modules:

o o o o o o

Tests/Assignment Tests/Chat Tests/Choice Tests/Forum Tests/Quiz Tests/Resource

top Using "simplehtml" as an example, following is a typical test case:

[Sim001TAS] : Adding Simplehtml block from the block pull-down menu ______________________________________ __
a. b. Click the "Turn editing on" button on the top right corner window. From the Blocks pull-down menu, find the "simplehtml" block on the list of blocks available c. d. Choose the "simplehtml" block from the menu Does the "simplehtml" block display correctly? The default will show up on the right hand side of the browser window. There should be no missing strings, etc.

More information about how to write a Moodle test case document is available at Moodle Docs. top

3. Try Selenium.
a.
b. Read OpenQA's Using Selenium IDE and Recording a Test (note the movie that illustrates the steps for the test near the top under the "View" tab). Install Selenium IDE from Open QA's Selenium IDE Downloads page. Download the Moodle Selenium example file and unzip it (say, in c:\xampp\moodle\)

c.

d.
e. f. g.

In Firefox, go to your local moodle installation (e.g,. http://localhost/moodle/) Login as admin Start Selenium IDE from the Firefox tools menu. From the Selenium menu, select File-> Open and open the file "Createquiz.selenium.html" from the unzipped file in Step 2.

h.

In the list of commands, look at the sixth one from the end--where it says "type newfile c:\Documents and Settings\TJH239\Desktop\Selenium tests\Test question suite.xml." Change that file path to point to your copy of "Test question suite.xml" from the unzipped file.

i.

Click the green play button in the Selenium toolbar. The test script will automatically:


j.

create a new course add a quiz to it import 12 sample questions add those questions to a quiz

Next, open 'Test matching - basic in quiz preview.selinium.html' and run it (no editing required this time). This runs through one of the test questions a few times.

k.

Finally, open "Delete test course.selinium.html", and run it to remove the test course and get back to where you started.

l.

Review the "Test question suite.xml" to see what is does, try to tweak it a little bit to understand how Selenium works.

4.

Complete the three Assignments and submit them in the designated Assignment areas.

a.

[Test Case] Follow the Moodle test case convention to write a simple test case (scenario) for testing Gradebook Plus version 2 (aka GBPv2). Consider a focus on testing one of the basic features in GBPv2. For example, adding a graded event, using the "edit grade" tab with out-of-bound values, etc. Submit your test case as an online text document in the Assignment area. Naming conventions and format for the Moodle test case must be observed.

b.

[Selenium] Design a Selenium case to automatically:

Use your local development Moodle installation (Moodle 1.8). Login as Admin.

Select the Moodle Test Case Course that you installed before. Click on "Grades" (gradebook). Click on the button of "Download in Excel format" button Manually check the content to see if everything works correctly. Write a simple code snippet using Moodles "unit tests" framework to test a particular function (you pick) in GBPv2. For example, the function of "grade_get_category_weight()" or "grade_get_grade_items()" in /grade/lib.php

c.

[Moodle Unit Test] Write a simple code snippet using Moodle's "unit tests" framework to test a particular function (you pick) in GBPv2. For example, the function of

grade_get_category_weight() or

grade_get_grade_items() in /grade/lib.php.
5. Share your thoughts on the discussion topics for this Unit.

Unit 9: Requirements Documents


Overview | Unit 9 "To Do" List External resources will open in new browser windows. Requirements documents are the glue that holds communication between a programmer and a user together. In this unit we will explain how to develop a requirements document that will help to solidify the reason a project should be completed, reduce feature creep, assist in quality assurance, as well as identify what functionality a programmer should be working to create. Throughout this unit we will be referring to the structure of a requirements document as described in the PDF file, "Writing a Software Requirements Document." Please use this as a reference and read it thoroughly. Also read through NASA's document, Writing Effective Requirements Specifications, to get an idea of how to word a requirements document for the best possible readability.

Why Write a Requirements Document?


"Products with the lowest defect counts also have the shortest schedules." M. Tim Jones in Version Control for Linux: Overview of architectures, models, and examples. A requirements document:

Is a starting point to ensure you do it right meaning you deliver what the customer wants at a quality level that is acceptable.

Can be used as a loose "contract" defining what functionality will be delivered. Is written such that everybody involved can understand the document including customer, project manager, developer, and testers.

Assures the customer that the development team understands what it is that they want.

Lists clearly features that must be present in the finished project. For example, it is a written document of what the software will do.

Provides a clear starting point for testing functionality. Is a clear starting point for creating user documentation. Settles any disputes between the customer and the development team Will list no more and no less than what is required. Serves as a reference point to do a feature-freeze. That is, if the requested functionality changes, then a new requirements document is created and the customer must take part in this process to understand the impact of making changes late in a project's life-cycle. This can also serve as a starting point for delivering functionality in versions.

Does not focus on how the software will accomplish the tasks necessary. This is often best left to the programmer who will be the most knowledgeable and capable of making implementation decisions.

Should be tailored to the application. If the application is large or may be easily misunderstood or misinterpreted then the requirements document will most likely need to be more detailed. However you should write so that it is easily understood. top

The User Interview


Before you can write a requirements document you must first determine the requirements. One of the best ways of doing this is talking to a user or group of users, whether these users are faculty, administrators, or students depends on the type of project. Interviewing the user face to face or over the phone allows the programmer, project manager, and user to do the following: 1. 2. 3. 4. 5. Come to a common understanding of the project requirements Discuss important decisions about the features of the project Discuss important decisions about the user interface for the project Come to a common understanding of how long a project will take to complete Identify which features are the most important

Below is a set of questions that should be useful as a starting point for most interviews a developer will have with a user or set of users. Feel free to modify this with more specific questions for the project, or add questions during the interview as they come to mind. The first set of questions is more general that the group should answer, and the second set is specific and should be asked of each user of the project or program.

General and Introductory Questions for the Entire User Group


1. 2. 3. 4. 5. What will this project help achieve for the organization? Why are we doing the project now? What will happen if we don't do the project at all? Who will benefit from the project? Do people who will benefit from the project consider it the most important improvement that can be made at this time? 6. 7. 8. 9. Should we do a different project instead? When does the project need to be completed? What are the most important parts of the project? What features of the project could be postponed or cut if the timeline slips?

User Specific Questions


1. 2. 3. 4. 5. 6. 7. 8. 9. What is the current process you perform? What part(s) of the process would you like to improve? Who will be affected by the changes you would like? Are there other systems that this change will need to interact with? How does the user see their interaction with the current process? How does the user see their interaction with the new process? What options would the user like to be able to configure? What terms doesn't the user understand? Is there anything the user would like to happen when the project is ready to be rolled out? 10. Who should be able to perform what actions within the system in relation to the new project? 11. Are there any reports that the user needs? 12. What kinds of auditing requirements does the user have? top

A Sample Interview

Project Idea
Faculty at Humboldt State University would like a way to print and record attendance from Moodle. The department assistants would like to reduce the work of creating role sheets for the faculty. Technical staff at Humboldt State University are in the exploration phase of project development to determine the best way to meet the needs of the faculty and department assistants.

General and Introductory Questions for the Entire User Group


1.
What will this project help achieve for the organization? It will allow faculty to be self sufficient when it comes to taking attendance instead of relying on department assistance to create role sheets.

2.

Why are we doing the project now? We are doing this project because fifteen faculty and twenty-two department assistants have requested this modification as their top priority over the last 6 months.

3.
4.

What will happen if we don't do the project at all? Things will continue as they are now. Who will benefit from the project? Faculty and department assistants. Do people who will benefit from the project consider it the most important improvement that can be made at this time? Yes absolutely.

5.
6.

Should we do a different project instead? No.

Faculty Specific Questions


1. 2.
What is the current process you perform? Request attendance sheet from the department assistant What part(s) of the process would you like to improve? I would like to be able to print out attendance sheets 10 minutes before the lecture instead of having to request the role sheet a week in advance. 3. Who will be affected by the changes you would like? Department assistants and faculty. 4. Are there other systems that this change will need to interact with? No. How does the user see their interaction with the current process? I see my interactions as restricted. All the information I want is in Moodle but I am unable to access it how I want to without going through a department assistant.

5.

6.
7.

How does the user see their interaction with the new process? I see myself as less confined and able to do my job better and in a more timely fashion. What options would the user like to be able to configure?

I would like to be able to configure which participants in the course are on the roster in case I have people that I don't need to take attendance for.

I would like to configure the date the role sheet is for so that I can print out different one.

I would like to be able to print out the role sheet for each time my class meets by just entering in the dates my class meets.

8. 9.

What terms doesn't the user understand? Unknown at this time. Is there anything the user would like to happen when the project is ready to be rolled out?

o o

I would like to be notified that this project has been completed I would like to get some training on how to use this program properly.

10. Who should be able to perform what actions within the system in relation to the new
project? Only faculty should be able to print out the role sheet.

11. Are there any reports that the user needs? If I can enter attendance I would like to
be able to see a report of who has attended what classes. 12. What kinds of auditing requirements does the user have? None.

Department Assistant Specific Questions


1. What is the current process you perform?

a. b. c. d. e. f. g. h. i. 2.
3.

Log into Moodle and locate the professor's course. Copy all students on one page of the People block and paste them into a spreadsheet. Repeat step b for each page in the People block Add a field for the date to the spreadsheet Add a title for the course to the spreadsheet Save the file Print the spreadsheet Place the roll sheet in the professor's box Repeat steps a-h for all requests

What part(s) of the process would you like to improve? I would like to remove this as my job function. Who will be affected by the changes you would like? Faculty and department assistants.

4.

Are there other systems that this change will need to interact with? No. How does the user see their interaction with the current process? I have to do a lot of repetitive tasks, copying and pasting. I also have to print and notify the faculty when their roll sheets are finished. I probably perform about 10 hours of work for each faculty.

5.

6.
7. 8.

How does the user see their interaction with the new process? I don't see myself interacting with the new process. What terms doesn't the user understand? Unknown at this time Is there anything the user would like to happen when the project is ready to be rolled out? I would like to be notified when the project is complete and I would like to know who to send faculty to get trained on how to use the block. top

Requirements Document Structure


A software requirements document should not delve into implementation details. That is, the document should focus on what the application should do and not how it accomplishes those tasks. This provides for flexibility in implementation while still delivering solid expectations of what the functionality the program will provide.

1.

Application Overview. The Applications overview should be completed as a collaborative effort between the programmer, user and project manager. A. Objectives & Justifications i. ii. iii. Explain why this project is being developed. Explain the need for the program or project. Explain why this is being done now rather than later.

B. Business Process i. Explain the business processes that drive the need for this application. ii. iii. Explain how the existing business process will change. Explain any other systems or processes that this application will be dependent upon. C. User Roles and responsibilities i. Describe unique responsibilities and interactions each user/role in Moodle will have to perform once the project is complete. For example a site administrator will have to configure settings or a student is able to do certain things.

ii.

For the most part the general roles that need to be defined are student, faculty/teacher and administrator.

D. Interactions with Other Systems i. Explain how the system will interact with other systems. For example Moodle will generate an excel file for a student system to use to upload grades ii. E. Define interactions with any and all external systems.

Replacement of Legacy Systems i. Explain any legacy systems that this is going to replace

F.

Production Rollout Considerations i. Explain any considerations that will need to be taken into account when this application goes into production.

G. Terminology i. ii. Define any terminology that a user might not completely understand Define all acronyms used within the requirements document or in later communications about the project between users and developers. top

2.

Functional Requirements. Functional requirements can be filled out by the project manager and programmer with the aid of the user, but should always be informed by the Application overview. This area of the requirements document is most important to the programmer because it details all the information that is specific to implementing the program. A. Statement of functionality i. Clearly state the required functionality of the program. Be careful to state exactly what is required; no more and no less. This will be a loosely binding contract between the customer and the development team. ii. In general for Moodle development you will want to break down the functional requirements based on user roles. If your program is more of a system-wide core feature then it may be better to list the requirements based on function. B. Security considerations

i.

Explain any security issues that may need to be addressed as part of your application.

ii.

Explain what actions specific users will be allowed to do or what actions they specifically cannot do.

C. Customization issues i. List any specific customization considerations that may need to be addressed as part of application deployment. Specifically address what customizations (if any) the user will need to accomplish. D. Reports i. Describe any reports, logging, or system overview that the application will need to provide. E. Performance Requirements i. List any specific performance requirements here. There must be specific metrics and acceptable values listed, no vague or ambiguous statements. F. Usability i. G. Scope i. List each of the requirements in the Statement of function requirements and in which phase of the project they are to be completed by. ii. Generally use a phased approach to list out each set of functional requirements that will be used. iii. Note when a feature or phase is optional. List any specific usability considerations or requirements here.

3.

Supplementary/Background Information/Appendixes. List any supplementary documents, references or background information that may be necessary to understand, implement, test, or use the application. top

"To Do" List


1. Humboldt State University has some sample requirements documents on their Trac system. Take a look at these two samples: a project to allow crosslisting of courses and a project to streamline updating activity dates. Also review this sample template for a requirements document.

2.

Read Tanya Berezin's "Writing a Software Requirements Document" (PDF document Adobe Reader required). What is the difference between the outline above and the

requirements document structure proposed by Tanya Berezin in "Writing a Software Requirements Document"? 3. Complete the requirements document writing assignment. Based on the sample interview provided in this Unit's lesson, write up section 1.1 Objectives & Justifications and 1.2 Business Process of the requirements document. Submit it in the designated Assignment area in this Unit's section. Be sure that your document explains each of the important points listed in the Requirements Documents structure. Based on the sample interview provided in this Unit's lesson, write up section 2.1 Statement of Functionality of the requirements document. Submit it in the designated Assignment area in this Unit's section. Be sure that your document explains each of the important points listed in the Requirements Documents structure. Think up a project idea that you would like to see implemented in Moodle. To get you started, consider these ideas:

Easy Projects
o o
A block that displays a live feed from a web cam. A block that stores the date, time and location of when the course meets

Project of Medium Difficulty


o
A block that serves as an online calculator with graphic, currency, and accounting functions

Difficult Projects
o o o o o o o o
A block to search Google Scholar for publications A block to search Amazon for books A block that interacts with Google Talk for chatting while in Moodle A block that adds all students in a course as Friends in Facebook A block that adds all students in a course as Friends in MySpace A block that allows FTP access to a server A block that adds SSH access to a server A block that displays the local weathr from Google or weather.com

Using the sample interview format provided in this Unit, role-play the interview process with yourself. Submit the answers to the interview questions and any other questions you feel need to be asked to the Assignment area. Be sure to conduct an interview from different user perspectives such as the faculty and student perspective. Using the answers to the interview questions create a complete requirements document. Submit the requirements document in the designated Assignment area. Be sure to explain all of the questions asked in each of the sections of the Requirements Structure above, as well as provide a screen shot of a mocked up user interface in an Appendix. 4. After completing the assigned readings and Assignment, choose from among the following discussion topics and post your ideas.

Compare and contrast the differences between HSU's requirements document and the model requirements document outlined in this Unit's lesson.

What is the difference between the outline in this lesson and the requirements document structure proposed by Tanya Berezin in "Writing a Software Requirements Document"?

What interview questions would you add to the set of standard interview questions?

What sections of the requirements document would you change? Or what sections would you add?

5.

Take the quiz. Two attempts are allowed.

GuUnit

10 - Programming a Moodle Block


Overview | Unit 10 "To Do" List

External resources open in new browser windows. Over the last nine units you have progressed through the steps to create a Moodle block, including

checking out code from a sourcecode repository learning about some useful development tools

setting up Moodle on your computer exploring useful Moodle libraries reviewing general information about good coding practices coding a block in Moodle creating test cases and running Selenium scripts writing a requirements document

In this unit you will use everything you've learned so far to create a block from a requirements document, write test cases, participate in a code review, and finally, release the block to the Moodle community! When selecting projects for block development in this course, several factors must be carefully considered. In some cases, the requirements documents developed in Unit 9 may not yield the best opportunity for success for beginning Moodle programmers, or might meet significant resistance when proposed to the Moodle community for reasons that could be difficult to anticipate. Seek advice from the course facilitator on whether to proceed with your Unit 9 project for full block development. The Unit 10 Requirements Document provided below is intended to offer a manageable task for successful completion of this course and should be used for Unit 10 unless specific encouragement is provided by the facilitator to continue with your Unit 9 project idea. You may work in project teams if desired. However, unless all team members are at the same institution, sharing the same CVS, there may be technical difficulties in managing edits to the code. Alert your facilitator of the members of your team. When submitting your project, you must document the contributions of each team member.

Post-Development Documentation
After completing the development of a block there are two types of information that the Moodle user community needs in order to use your block: 1. 2. Installation/Readme documentation Help documentation on how to use the block

Installation/Readme Documentation
Installation documentation informs the system administrator of the steps needed to install the block. This file, usually title INSTALL.txt, typically contains instructions on placing the block into the blocks directory and then logging in to Moodle as an administrator and clicking

the "Notifications" link in the Site Administration block. If however, your block is more complex than a simple block, like a cronjob, or the block modifies core Moodle code files (not recommended), then the installation file will need to contain information about how these files will be modified. The readme file, usually named README.txt, contains documentation on who developed the block, how to contact you with questions and any other information that is informative to the user and speaks about yourself and the project. A final optional file is the CHANGELOG file, which is intended to inform the user of the changes that have been made to a block in each version. This file is optional on the first release, but is recommended on each subsequent release. This file should contain all the bugs that have been fixed in the current version, possibly pointing to specific ticket numbers in a ticket tracking system. Important tip: both the README and INSTALL files should be saved in a common format across all platforms. Text files (.txt and .rtf) files are recommended.

Help Documentation
The final documentation required is Help documentation. This comes in the form of how-to files, wikis, FAQs, and/or video. This should teach the user how to configure and use the block. It is recommended that you have both a faculty and student guide for most blocks. This also comes in the form of HTML files in Moodle. These files are associated with the blue question-mark buttons on some forms. This button is printed using the function in weblib.php top

helpbutton()

"To Do" List


Planning Block Development
1. Choose a project of your choice or choose from the list provided in Unit 9's "To Do" List, item #3 to create a Requirements Document for this project as outlined in Unit 9.

2.

Read the details provided at Moodle.org, Working with the Community, to familiarize yourself with the process of sharing code with the Moodle community. Pay particular attention to the section near the bottom of the page, "Consider asking or discussing your proposal first."

3.

Share information with the Moodle community about what you plan to develop in the relevant discussion forum area at Moodle.org.

4.

Document unit tests that are needed to test the block based on the requirements document.

Creating the Block


5.
6. 7. 8. 9. Read this general resource, Writing Good Software Documentation, and consider how it applies to your Moodle block project. Write the block code based on the requirements document. Write test cases testing each of the requirements from the requirements document. Write Selenium test cases to test your block's functionality. Compose your in-development documentation as well as post-development documentation. 10. Attach your code in the designated Forum in this course as an attachment to a forum post (zip your block directory first). Participate in a code review of at least two other classmates' code with the facilitator. Post your feedback and review comments made on your code. Consider which comments should be incorporated to improve your code and make the changes. 11. After making the final edits to your code, submit your final zipped block directory in the designated Assignment area. Be sure to include your post-development documentation files and test cases within your zipped file . top

Contribute the Code to the Moodle Community


Now that the block is complete and the zipped block directory is posted to the Assignment are in this course, the next step is to release the block to the Moodle Community. Follow steps 9-12 below (and optionally steps 13 and 14) to release your code to the Moodle community. Only one block project will be released to the community. Use the Choice in the final section of this course's materials to cast your vote for the best block that should be shared. Consider the following criteria in your vote:

code maintainability consistency with Moodle coding guidelines

accessibility usability matching requirements document specifications quality of test cases documentation

The author(s) of the "winning" block will be assigned to complete steps 9-12 below (and optionally steps 13 and 14) to complete the release. 9. Post the zip file to a publicly-accessible server to allow others to download the file.

10. Create a new entry for the block in the "Modules and Plug-ins" database
o
Use a descriptive name for the block. Select a descriptive and unique name to identify it.

o o

Describe what the block is intended to do Take a screen capture of the block in action on its local test site and post the screen capture in the screen shot area

o o

Link the download for Moodle 1.8 to the server where you uploaded the file Enter your name as the maintainer

11. Create a new forum topic for the block in the Blocks discussion forum (http://moodle.org/mod/forum/view.php?id=2121) with the following information

o o o o o o

What the project does Contributors Requirements document Test cases Any Selenium cases Link to the module and plugins entry

12. Link the "Modules and Plugins" entry to the forums topic.

13. Optional: Add your project to the Moodle Bug Tracker


o o
Login to tracker.moodle.org Click the "Components" link under the project "Non-core contributed module" on the bottom left side

o o o

Click "Add a project here" Click "Create new issue" Enter the information for the issue ticket.

14. Optional: Request a contrib directory created for your project in the Moodle CVS
contrib branch.

o o

Login to tracker.moodle.org Click the "Components" link under the project "Non-core contributed module" on the bottom left side

o o o

Click "Add a project here" Click "Create new issue" Enter the information for the issue ticket with the title and text requesting a folder in the contrib block directory be made for your project.

15. Participate in the assigned discussion about managing code in a distributed community.

idelines
The following guidelines are crucial reading for anyone wanting to contribute to the Moodle code base: Coding guidelines have to be followed by all Moodle developers Moodle design goals spells out the basic design goals behind Moodle Interface guidelines aim to provide a common feel to the Moodle user interface Moodle CVS for developers explains how to work with the Moodle code in CVS Tracker explains the Moodle Tracker for keeping track of bugs, issues, feature requests etc Working with the Community explains how to engage with the dev community and discuss changes Unit tests explains how to run the unit tests, and how to write new test cases. Development:Fast portable SQL shows SQL techniques that are fast, efficient, and known to work on all supported DBs.

Documentation for core components


This section is for documentation of specific components of the existing core Moodle code. Discussion of components that are under discussion or in development can be found in the developer notes or on the roadmap. The documents below give a general overview. For detailed function-by-function documentation, see the phpDocumentor documentation that is automatically generated from the comments in the code.

And don't forget that the most up-to-date and detailed description of how the code works is the code itself, and you can browse the code online using PHPXref.

Core components that affect everything


The database schema What happens when you require config.php lib/moodlelib.php lib/weblib.php for outputting stuff JavaScript function available on the client side Database abstraction layer @ v1.7 Roles and Capabilities system @ v1.7 for controlling who can do what Forms library @ v1.8 for creating accessible and secure HTML forms that let users edit things File API @ v2.0 for managing files stored by Moodle

Core libraries with a more specific uses


Authentication API Cookieless Sessions Email processing Environment checking before install, check the user's server to ensure Moodle will work there. Groups system Gradebook Moodle Network Question engine Stats package Migration to UTF-8 @ v1.6 YUI JavaScript library - YUI was selected as the official AJAX library for Moodle. lib/graphlib Admin settings

Modules included in the standard distribution


Lesson Specification Quiz module SCORM module 1.5 schema

How you can contribute

Make a new plugin


The M in Moodle stands for modular, and the easiest, most maintainable way to add new functionality to Moodle is by using one of the many plugin APIs. There are many types of plugin you can write: Activity modules, see also Development:NEWMODULE Documentation (work in progress) Admin reports Assignment types Authentication plugins Blocks Course formats Course reports Database fields Database presets Enrolment plugins Filters Gradebook plugins (1.9 onwards) Gradebook report Gradebook export Gradebook import Portfolio plugins (2.0 onwards) Question types Question import/export formats Quiz reports Repository plugins (2.0 onwards) Resource types Search engine adapters

General information that applies to all types of plugins Where to put language strings for your plugin Defining the database tables for your plugin

Please see the Guidelines for contributed code for an overview of how to contribute to the Moodle code. Sometimes it is not possible to write a proper plugin for what you want to do, in which case you may have to resort to using the local customisations hook.

Change core code

Some types of change can only be made by editing the core Moodle code. Such changes are much harder to maintain than plugins. If you want your core change to be considered for inclusion in the official Moodle release, you need to create an issue in the tracker, and attach your change as a patch. It is also a good idea to discuss your ideas in the forums first. See Development:Overview#Major_Development for more details.

Ways to contribute that do not involve PHP programming


Create Moodle themes Translate Moodle into other languages Help document Moodle Join the testing effort, which involves participating in the bug tracker

Plans for the future


Ideas for and details of planned future features of Moodle are initially discussed on the forums in the Using Moodle course at moodle.org. That developer discussions are intermixed with user discussions in the same forums may seem strange at first but is one of the reasons for the success of Moodle. It is important that both endusers and developers discuss the future features together. Once ideas begin to crystallize on the forums they can be summarized in this wiki, either as part of the roadmap or in the form of developer notes. These pages then form the basis for further discussion in the forums. Roadmap Developer notes Student projects Developer meetings

Resources
Developer FAQ - frequently asked questions, especially useful for newcomers to Moodle Finding your way into the Moodle code - also aimed at newcomers Moodle tracker - bug reports, feature requests and other tracked issues Firefox tracker search - How to setup a firefox quicksearch to easily navigate to moodle bugs Firefox Search Plugins - Find tracked issues even more easily

Unmerged files - changes on the stable branch in CVS that have not been merged to HEAD Browse the code online: the code with a complete change history from CVS the code, with links generated by PHPXref Moodle PHP doc reference - compiled nightly from the comment attached to each class and function in the code. Database Schema - for recent releases Development news and discussion section of Using Moodle course especially the General developer forum cool tricks you can use in the moodle.org forums

Tools
Some tools people use when working on Moodle code:

IDEs
Setting up NetBeans for Moodle development - NetBeans for PHP is a great out-of-the-box editor. Setting up Eclipse for Moodle development - Eclipse is a great editor to use for php development, if you can work out how to set it up. Setting up Vim for Moodle development

Browser add-ons
Firebug, see Development:Firebug. Web developer extension ViewSourceWith - The main goal is to view page source with external applications, but you can do a lot of other things as well.

Miscellaneous
Ctags - Using a tags file to navigate code W3C HTML validator - Moodle has built in support to make using it easier. Windows Installer - Windows Installer documentation for developer.

See also: Useful Development Tools forumin the Introduction to Moodle Programming course

You might also like