mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 14:27:22 +01:00
271 lines
19 KiB
HTML
271 lines
19 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<title>Moodle Docs: Coding Guidelines</title>
|
|
<link rel="stylesheet" href="docstyles.css" type="TEXT/CSS" />
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
</head>
|
|
<body>
|
|
<h1>Moodle Coding Guidelines</h1>
|
|
<p class="normaltext">Any collaborative project needs consistency and stability
|
|
to stay strong.</p>
|
|
<p class="normaltext">These guidelines are to provide a goal for all Moodle code
|
|
to strive to. It's true that some of the older existing code falls short in
|
|
a few areas, but it will all be fixed eventually. All new code definitely must
|
|
adhere to these standards as closely as possible.</p>
|
|
<h2>General Rules</h2>
|
|
<ol class="normaltext">
|
|
<li class="spaced">All code files should use the .php extension.</li>
|
|
<li class="spaced">All template files should use the .html extension.</li>
|
|
<li class="spaced">All text files should use Unix-style text format (most text
|
|
editors have this as an option).</li>
|
|
<li class="spaced">All php tags must be 'full' tags like <font color="#339900"><?php
|
|
?></font> ... not 'short' tags like <font color="#339900"><? ?></font>.
|
|
</li>
|
|
<li class="spaced">All existing copyright notices must be retained. You can
|
|
add your own if necessary.</li>
|
|
<li class="spaced">Each file should include the main config.php file.</li>
|
|
<li class="spaced">Each file should check that the user is authenticated correctly,
|
|
using the correct has_capability() or required_capability() checks.</li>
|
|
<li class="spaced">All access to databases should use the functions in lib/datalib.php
|
|
whenever possible - this allows compatibility across a wide range of databases.
|
|
You should find that almost anything is possible using these functions. If you must write SQL code then make sure it is: cross-platform; restricted to specific functions
|
|
within your code (usually a lib.php file); and clearly marked.</li>
|
|
<li class="spaced">Don't create or use global variables except for the standard
|
|
$CFG, $SESSION, $THEME and $USER.</li>
|
|
<li class="spaced">All variables should be initialised or at least tested for
|
|
existence using isset() or empty() before they are used.</li>
|
|
<li class="spaced">All strings should be translatable - create new texts in
|
|
the "lang/en" files with concise English lowercase names and retrieve them
|
|
from your code using get_string() or print_string().</li>
|
|
<li class="spaced">All help files should be translatable - create new texts
|
|
in the "en/help" directory and call them using helpbutton().
|
|
<p>If you need to update a help file: </p>
|
|
<ul>
|
|
<li>with a minor change, where an old translation of the
|
|
file would still make sense, then it's OK to make the change
|
|
but you should notify translation@moodle.org</li>
|
|
<li>for a major change you should create a new file by adding
|
|
an incrementing number (eg filename2.html) so that translators
|
|
can easily see it's a new version of the file. Obviously the
|
|
new code and the help index files should also be modified to point
|
|
to the newest versions.</li>
|
|
</ul>
|
|
|
|
</li>
|
|
<li class="spaced">Incoming data from the browser (sent via GET or POST) automatically
|
|
has magic_quotes applied (regardless of the PHP settings) so that you can safely
|
|
insert it straight into the database. All other raw data (from files, or from databases)
|
|
must be escaped with <font color="#339900">addslashes()</font> before inserting it into the database.</li>
|
|
<li class="spaced">IMPORTANT: All texts within Moodle, especially those that have
|
|
come from users, should be printed using the format_text() function. This ensures that
|
|
text is filtered and cleaned correctly.</li>
|
|
</ol>
|
|
<p> </p>
|
|
<h2>Coding Style</h2>
|
|
<p class="normaltext">I know it can be a little annoying to change your style
|
|
if you're used to something else, but balance that annoyance against the annoyance
|
|
of all the people trying later on to make sense of Moodle code with mixed styles.
|
|
There are obviously many good points for and against any style that people use,
|
|
but the current style just <strong>is</strong>, so please stick to it. </p>
|
|
<ol class="normaltext">
|
|
<li class="spaced"><strong>Indenting</strong> should be consistently 4 spaces.
|
|
Don't use tabs AT ALL. </li>
|
|
<li class="spaced"><strong>Variable names</strong> should always be easy-to-read,
|
|
meaningful lowercase English words. If you really need more than one word
|
|
then run them together, but keep them short as possible. Use
|
|
plural names for arrays of objects.
|
|
<p class="examplecode"><font color="#006600">GOOD: $quiz<br />
|
|
GOOD: $errorstring<br />
|
|
GOOD: $assignments (for an array of objects)<br />
|
|
GOOD: $i (but only in little loops)<br />
|
|
<br />
|
|
BAD: $Quiz <br />
|
|
BAD: $aReallyLongVariableNameWithoutAGoodReason<br />
|
|
BAD: $error_string</font></p>
|
|
</li>
|
|
<li class="spaced"><strong>Constants</strong> should always be in upper case,
|
|
and always start with the name of the module. They should have words separated
|
|
by underscores.
|
|
<p class="examplecode"><font color="#006600">define("FORUM_MODE_FLATOLDEST",
|
|
1);</font></p>
|
|
</li>
|
|
<li class="spaced"><strong>Function names</strong> should be simple English
|
|
lowercase words, and start with the name of the module to avoid conflicts between modules.
|
|
Words should be separated by underscores. Parameters should always have sensible
|
|
defaults if possible. Note there is no space between the function name and
|
|
the following (brackets). <br />
|
|
<p class="examplecode"> <font color="#007700">function </font><font color="#0000BB">forum_set_display_mode</font><font color="#007700">(</font><font color="#0000BB">$mode</font><font color="#007700">=</font><font color="#0000BB">0</font><font color="#007700">)
|
|
{<br />
|
|
global </font><font color="#0000BB">$USER</font><font color="#007700">,
|
|
</font><font color="#0000BB">$CFG</font><font color="#007700">;<br />
|
|
<br />
|
|
if (</font><font color="#0000BB">$mode</font><font color="#007700">)
|
|
{<br />
|
|
</font><font color="#0000BB">$USER</font><font color="#007700">-></font><font color="#0000BB">mode
|
|
</font><font color="#007700">= </font><font color="#0000BB">$mode</font><font color="#007700">;<br />
|
|
} else if (empty(</font><font color="#0000BB">$USER</font><font color="#007700">-></font><font color="#0000BB">mode</font><font color="#007700">))
|
|
{<br />
|
|
</font><font color="#0000BB">$USER</font><font color="#007700">-></font><font color="#0000BB">mode
|
|
</font><font color="#007700">= </font><font color="#0000BB">$CFG</font><font color="#007700">-></font><font color="#0000BB">forum_displaymode</font><font color="#007700">;<br />
|
|
}<br />
|
|
}</font></p>
|
|
</li>
|
|
<li class="spaced"><strong>Blocks</strong> must always be enclosed in curly
|
|
braces (even if there is only one line). Moodle uses this style:
|
|
<p class="examplecode"> <font color="#006600">if (</font><font color="#0000CC">$quiz</font><font color="#006600">-></font><font color="#0000CC">attempts</font><font color="#006600">)
|
|
{<br />
|
|
if (</font><font color="#0000CC">$numattempts </font><font color="#006600">>
|
|
</font><font color="#0000CC">$quiz</font><font color="#006600">-></font><font color="#0000CC">attempts</font><font color="#006600">)
|
|
{<br />
|
|
</font><font color="#0000CC">error</font><font color="#006600">(</font><font color="#0000BB">$strtoomanyattempts</font><font color="#006600">,
|
|
</font><font color="#CC0000">"view.php?id=$cm</font><font color="#006600">-></font><font color="#CC0000">id"</font><font color="#006600">);<br />
|
|
}<br />
|
|
}</font></p>
|
|
</li>
|
|
<li class="spaced"><strong>Strings</strong> should be defined using single quotes
|
|
where possible, for increased speed.<br />
|
|
<p class="examplecode"> <font color="#006600">$var = 'some text without any
|
|
variables';<br />
|
|
$var = "with special characters like a new line \n";<br />
|
|
$var = 'a very, very long string with a '.$single.' variable in it';<br />
|
|
$var = "some $text with $many variables $within it"; </font></p>
|
|
</li>
|
|
|
|
|
|
<li class="spaced"><strong>Comments</strong> should be added as much as is
|
|
practical, to explain the code flow and the purpose of functions and variables.
|
|
<ul>
|
|
<li>Every function (and class) should use the popular
|
|
<a target="_blank" href="http://www.phpdoc.org/">phpDoc format</a>.
|
|
This allows code documentation to be generated automatically.</li>
|
|
<li>Inline comments should use the // style, laid out neatly
|
|
so that it fits among the code and lines up with it.</li>
|
|
</ul>
|
|
|
|
<p class="examplecode"><font color="#FF8000">
|
|
/**<br />
|
|
* The description should be first, with asterisks laid out exactly<br />
|
|
* like this example. If you want to refer to a another function,<br />
|
|
* do it like this: {@link clean_param()}. Then, add descriptions <br />
|
|
* for each parameter as follows.<br />
|
|
*<br />
|
|
* @param int $postid The PHP type is followed by the variable name<br />
|
|
* @param array $scale The PHP type is followed by the variable name<br />
|
|
* @param array $ratings The PHP type is followed by the variable name<br />
|
|
* @return mixed<br />
|
|
*/</font><br />
|
|
<font color="#006600">function </font><font color="#0000BB">forum_get_ratings_mean</font><font color="#007700">(</font><font color="#0000BB">$postid</font><font color="#007700">,
|
|
</font><font color="#0000BB">$scale</font><font color="#007700">, </font><font color="#0000BB">$ratings</font><font color="#007700">=</font><font color="#0000BB">NULL</font><font color="#007700">)
|
|
{<br /></font>
|
|
<font color="#007700">if (!</font><font color="#0000BB">$ratings</font><font color="#007700">)
|
|
{<br />
|
|
</font><font color="#0000BB">$ratings
|
|
</font><font color="#007700">= array(); </font><font color="#FF8000">//
|
|
Initialize the empty array</font><font color="#007700"><br />
|
|
if (</font><font color="#0000BB">$rates
|
|
</font><font color="#007700">= </font><font color="#0000BB">get_records</font><font color="#007700">(</font><font color="#DD0000">"forum_ratings"</font><font color="#007700">,
|
|
</font><font color="#DD0000">"post"</font><font color="#007700">, </font><font color="#0000BB">$postid</font><font color="#007700">))
|
|
{<br />
|
|
</font><font color="#FF8000">//
|
|
Process each rating in turn</font><font color="#007700"><br />
|
|
foreach
|
|
(</font><font color="#0000BB">$rates </font><font color="#007700">as </font><font color="#0000BB">$rate</font><font color="#007700">)
|
|
{</font> <br />
|
|
....etc </p>
|
|
</li>
|
|
|
|
<li class="spaced"><strong>Space</strong> should be used liberally - don't be
|
|
afraid to spread things out a little to gain some clarity. Generally, there
|
|
should be one space between brackets and normal statements, but no space between
|
|
brackets and variables or functions:<br />
|
|
<p class="examplecode"> <font color="#007700">foreach (</font><font color="#0000BB">$objects
|
|
</font><font color="#007700">as </font><font color="#0000BB">$key </font><font color="#007700">=></font><font color="#0000BB">
|
|
$thing</font><font color="#007700">)</font><font color="#006600"> {<br />
|
|
</font><font color="#007700"> </font><font color="#0000BB">process($thing);</font><font color="#006600">
|
|
<br />
|
|
} <br />
|
|
<br />
|
|
</font><font color="#007700">if (</font><font color="#0000BB">$x </font><font color="#007700">==
|
|
</font><font color="#0000BB">$y</font><font color="#007700">)</font><font color="#006600">
|
|
{<br />
|
|
</font><font color="#007700"> </font><font color="#0000BB">$a
|
|
</font><font color="#007700">= </font><font color="#0000BB">$b</font><font color="#007700">;</font><font color="#006600"><br />
|
|
} else if (</font><font color="#0000BB">$x </font><font color="#007700">==
|
|
</font><font color="#0000BB">$z</font><font color="#006600">) {<br />
|
|
</font><font color="#007700"> </font><font color="#0000BB">$a
|
|
</font><font color="#007700">= </font><font color="#0000BB">$c</font><font color="#007700">;</font><font color="#006600"><br />
|
|
} else {<br />
|
|
</font><font color="#007700"> </font><font color="#0000BB">$a
|
|
</font><font color="#007700">= </font><font color="#0000BB">$d</font><font color="#007700">;</font><font color="#006600"><br />
|
|
} </font></p>
|
|
</li>
|
|
</ol>
|
|
<p> </p>
|
|
<h2>Database structures</h2>
|
|
<ol class="normaltext">
|
|
<li class="spaced">Every table must have an auto-incrementing <strong>id</strong> field (INT10) as primary index.</li>
|
|
<li class="spaced">The main table containing instances of each module must have the same name as the module (eg <strong>widget</strong>) and contain the following minimum fields:
|
|
<ul>
|
|
<li><strong>id</strong> - as described above</li>
|
|
<li><strong>course</strong> - the id of the course that each instance belongs to</li>
|
|
<li><strong>name</strong> - the full name of each instance of the module</li>
|
|
</ul>
|
|
</li>
|
|
<li class="spaced">Other tables associated with a module that contain information about 'things' should be named <strong>widget_things</strong> (note the plural).</li>
|
|
<li class="spaced">Column names should be simple and short, following the same rules as for variable names.</li>
|
|
<li class="spaced">Where possible, columns that contain a reference to the id field of another table (eg <strong>widget</strong>) should be called <strong>widgetid</strong>. (Note that this convention is newish and not followed in some older tables)</li>
|
|
<li class="spaced">Boolean fields should be implemented as small integer fields (eg INT4) containing 0 or 1, to allow for later expansion of values if necessary.</li>
|
|
<li class="spaced">Most tables should have a <strong>timemodified</strong> field (INT10) which is updated with a current timestamp obtained with the PHP <strong>time</strong>() function.</li>
|
|
</ol>
|
|
<p> </p>
|
|
<h2>Security Issues (and handling form and URL data)</h2>
|
|
<ol class="normaltext">
|
|
<li class="spaced">Do not rely on 'register_globals'. <strong>Every</strong> variable must be
|
|
properly initialised in <strong>every</strong> code file. It must be obvious where the variable
|
|
came from</li>
|
|
<li class="spaced">Initialise all arrays and objects, even if empty. <code>$a = array()</code>
|
|
or <code>$obj = new stdClass();</code>.</li>
|
|
<li class="spaced">Do not use the <code>optional_variable()</code> function. Use the <code>optional_param()</code>
|
|
function instead. Pick the correct PARAM_XXXX value for the data type you expect. To check and set an optional
|
|
value for a variable, use the <code>set_default()</code> function.</li>
|
|
<li class="spaced">Do not use the <code>require_variable()</code> function. Use the <code>required_param()</code>
|
|
function instead. Pick the correct PARAM_XXXX value for the data type you expect.</li>
|
|
<li class="spaced">Use <code>data_submitted()</code>, with care. Data must still be cleaned before use.</li>
|
|
<li class="spaced">Do not use <code>$_GET</code>, <code>$_POST</code> or <code>$_REQUEST</code>. Use the
|
|
appropriate <code>required_param()</code> or <code>optional_param()</code> appropriate to your need.</li>
|
|
<li class="spaced">Do not check for an action using something like <code>if (isset($_GET['something']))</code>.
|
|
Use, e.g., <code>$something = optional_param( 'something',-1,PARAM_INT )</code> and then perform
|
|
proper test for it being in its expected range of values e.g., <code>if ($something>=0) {...</code>.</li>
|
|
<li class="spaced">Wherever possible group all your <code>required_param()</code>, <code>optional_param()</code>
|
|
and other variables initialisation at the beginning of each file to make them easy to find.</li>
|
|
<li class="spaced">Use 'sesskey' mechanism to protect form handling routines from attack.
|
|
Basic example of use: when form is generated,
|
|
include <code><input type="hidden" name="sesskey" value="<?php echo sesskey(); ?>" /></code>.
|
|
When you process the form check with <code>if (!confirm_sesskey()) {error('Bad Session Key');}</code>.</li>
|
|
<li class="spaced">All filenames must be 'cleaned' using the <code>clean_filename()</code> function, if this
|
|
has not been done already by appropriate use of <code>required_param()</code> or <code>optional_param()</code>
|
|
</li>
|
|
<li class="spaced">Any data read from the database must have <code>addslashes()</code> applied to it before it
|
|
can be written back. A whole object of data can be hit at once with <code>addslashes_object()</code>.</li>
|
|
<li class="spaced">Wherever possible, data to be stored in the database must come from <code>POST</code>
|
|
data (from a form with <code>method="POST"</code>) as opposed to <code>GET</code> data (ie, data from the URL line).</li>
|
|
<li class="spaced">Do not use data from <code>$_SERVER</code> if you can avoid it. This has portability
|
|
issues.</li>
|
|
<li class="spaced">If it hasn't been done somewhere else, make sure all data written to the database has
|
|
been through the <code>clean_param()</code> function using the appropriate PARAM_XXXX for the datatype.</li>
|
|
<li class="spaced">If you write custom SQL code, make very sure it is correct. In particular watch out for
|
|
missing quotes around values. Possible SQL 'injection' exploit.</li>
|
|
<li class="spaced">Check all data (particularly that written to the database) in <strong>every</strong>
|
|
file it is used. Do not expect or rely on it being done somewhere else.</li>
|
|
<li class="spaced">Blocks of code to be included should contain a definite PHP structure (e.g,
|
|
a class declaration, function definition(s) etc.) - straight blocks of code promote uninitialised
|
|
variable usage.</li>
|
|
</ol>
|
|
<hr />
|
|
<p align="center"><font size="1"><a href="." target="_top">Moodle Documentation</a></font></p>
|
|
<p align="center"><font size="1">Version: $Id$</font></p>
|
|
</body>
|
|
</html>
|