a0cb906aa830d6848dba9e7c11163f53b4684843
[atutor.git] / docs / documentation / developer / guidelines.html
1 <!doctype html public "-//w3c//dtd html 4.0 transitional//en">\r
2 <!-- $Id: guidelines.html 3071 2005-01-12 21:53:13Z joel $ -->\r
3 \r
4 <html>\r
5 <head>\r
6         <title>ATutor Developer Documentation</title>\r
7         <meta name="author" content="Joel Kronenberg" />\r
8         <meta name="description" content="ATutor developer documentation and coding guidelines" />\r
9 \r
10 <style type="text/css">\r
11 h1 {\r
12         background-color: #CCCCCC;\r
13         padding-left: 20px;\r
14         padding-right: 20px;\r
15         margin-bottom: 10px;\r
16         text-align: right;\r
17 }\r
18 \r
19 h2 {\r
20         background-color: #DDDDDD;\r
21         padding-left: 10px;\r
22         margin-bottom: 0px;\r
23 }\r
24 h3 {\r
25         background-color: #EFEFEF;\r
26         padding-left: 20px;\r
27         margin-bottom: 0px;\r
28 }\r
29 h4  { margin-bottom: 0px; }\r
30 p   { margin-top: 0px;    }\r
31 dl  { margin-top: 0px;    }\r
32 kbd { color: #761596;     }\r
33 blockquote { font-style: italic; }\r
34 pre.code {\r
35         background-color: #EEEEFF;\r
36         padding: 5px;\r
37         margin-left: 20px;\r
38         color:#761596;\r
39     margin-top: 0px;\r
40 }\r
41 .top {\r
42         float: right;\r
43         color: green;\r
44         padding-top: 2px;\r
45         padding-right: 5px;\r
46 }\r
47 \r
48 @media print {\r
49         h2 {\r
50                 page-break-after: avoid;\r
51                 border-bottom: solid 1px black;\r
52         }\r
53         h3 {\r
54                 page-break-after: avoid;\r
55                 border-bottom: solid 1px black;\r
56                 width: 75%;\r
57         }\r
58         .top {\r
59                 display: none;\r
60         }\r
61 \r
62         pre.code {\r
63                 page-break-inside: avoid;\r
64         }\r
65 }\r
66 </style>\r
67 </head>\r
68 <body>\r
69 <h1><a name="top"></a>ATutor Developer Documentation</h1>\r
70 \r
71 <h2>Table of Contents</h2>\r
72 \r
73 <ul>\r
74         <li>0. <a href="#version">Version Considerations</a></li>\r
75         <li>1. <a href="#introduction">Introduction</a></li>\r
76                 <ul>\r
77                         <li>1.1 <a href="#introduction-api">API Documentation</a></li>\r
78                 </ul>\r
79         <li>2. <a href="#conventions">Conventions Used in This Document</a>\r
80                 <ul>\r
81                         <li>2.1 <a href="#typographic-conventions">Typographic Conventions</a></li>\r
82                         <li>2.2 <a href="#links-conventions">Links</a></li>\r
83                         <li>2.3 <a href="#function-definitions">Function Definitions (Prototypes)</a></li>\r
84                 </ul></li>\r
85     <li>3. <a href="#setup">Setup</a>\r
86                 <ul>\r
87                         <li>3.1 <a href="#php-configuration">PHP Configuration</a></li>\r
88                 </ul></li>\r
89     <li>4. <a href="#github">GitHub Repository</a>\r
90                 <ul>\r
91                         <li>4.1 <a href="#github_setup">Setting up a Git Development Environment</a></li>\r
92                         <li>4.2 <a href="#github_maintaining">Creating anfd Maintaining a Git Fork</a></li>\r
93                         <li>4.3 <a href="#svn-install">Installing from GitHub</a></li>\r
94                         \r
95 \r
96                 </ul></li>\r
97     <li>5. <a href="#communication">Communication</a></li>\r
98     <li>6. <a href="#patches">Patches</a></li>\r
99     <li>7. <a href="#editor-tips">Editor Tips</a></li>\r
100     <li>8. <a href="#proposed-features">Proposed Features</a></li>\r
101     <li>9. <a href="#bug-tracking">Bug Tracking</a></li>\r
102     <li>10. <a href="#creating-bundles">Creating Bundles</a></li>\r
103         <li>11. <a href="#writing-portable-code">Writing Portable Code</a></li>\r
104         <li>12. <a href="#coding-style">Coding Style</a>\r
105                 <ul>\r
106                         <li>12.1 <a href="#indentation">Indentation</a></li>\r
107                         <li>12.2 <a href="#line-length">Line Length</a></li>\r
108                         <li>12.3 <a href="#whitespace">Using Whitespace</a></li>\r
109                         <li>12.4 <a href="#sql-guidelines">SQL Guidelines</a></li>\r
110                         <li>12.5 <a href="#sql-joins">SQL/99 Joins</a></li>\r
111                         <li>12.6 <a href="#control-flow-constructs">Control Flow Constructs</a></li>\r
112                         <li>12.7 <a href="#commenting">Commenting</a></li>\r
113                         <li>12.8 <a href="#naming-conventions">Naming Conventions</a>\r
114                                 <ul>\r
115                                         <li>12.8.1 <a href="#naming-variables">Naming Variables</a></li>\r
116                                         <li>12.8.2 <a href="#naming-functions">Naming Functions</a></li>\r
117                                         <li>12.8.3 <a href="#naming-files">Naming Files</a></li>\r
118                                 </ul></li>\r
119                 </ul></li>\r
120         <li>13. <a href="#directory-structure">Directory Structure</a>\r
121                 <ul>\r
122                         <li>13.1 <a href="#directories">Directories</a></li>\r
123                         <li>13.2 <a href="#files">Files</a></li>\r
124                 </ul></li>\r
125         <li>14. <a href="#database-structure">Database Structure</a></li>\r
126         <li>15. <a href="#localisation">Localisation</a>\r
127                 <ul>\r
128                         <li>15.1 <a href="#adding-language">Adding &amp; Editing Language</a></li>\r
129                 </ul></li>\r
130         <li>16. <a href="#error-feedback-messages">Error and Feedback Messages</a>\r
131                 <ul>\r
132                         <li>16.1 <a href="#error-feedback-internals">Internals</a></li>\r
133                         <li>16.2 <a href="#error-feedback-adding">Adding Messages</a></li>\r
134                         <li>16.3 <a href="#error-feedback-printing">Printing Messages</a></li>                  \r
135                         <li>16.4 <a href="#mbstring-support">UTF-8 and Multibyte language</a></li>\r
136                 </ul>\r
137         </li>\r
138         <li>17. <a href="#useful-variables">Useful Variables</a>\r
139                 <ul>\r
140                         <li>17.1 <a href="#var-db">$db</a></li>\r
141                         <li>17.2 <a href="#var-addslashes">$addslashes</a></li>\r
142                         <li>17.3 <a href="#var-base_href">$_base_href</a></li>\r
143                         <li>17.4 <a href="#var-base_path">$_base_path</a></li>\r
144                         <li>17.5 <a href="#var-user_location">$_user_location</a></li>\r
145                         <li>17.6 <a href="#var-rel_url">$_rel_url</a></li>\r
146                         <li>17.7 <a href="#var-my_uri">$_my_uri</a></li>\r
147                         <li>17.8 <a href="#var-content_manager">$contentManager</a></li>\r
148                         <li>17.9 <a href="#var-section">$_section</a></li>\r
149                 </ul></li>\r
150         <li>18. <a href="#useful-functions">Useful Functions</a>\r
151                 <ul>\r
152                         <li>18.1 <a href="#fn-authenticate">authenticate()</a></li>\r
153                         <li>18.2 <a href="#fn-at">_AT()</a></li>\r
154                         <li>18.3 <a href="#fn-at_print">AT_print()</a></li>\r
155                         <li>18.4 <a href="#fn-at_date">AT_date()</a></li>\r
156                         <li>18.5 <a href="#fn-addslashes">$addslashes()</a></li>\r
157                         <li>18.6 <a href="#fn-debug">debug()</a></li>\r
158                         <li>18.7 <a href="#fn-get_login">get_login()</a></li>\r
159                         <li>18.8 <a href="#fn-urlencode_feedback">urlencode_feedback()</a></li>\r
160                         <li>18.9 <a href="#fn-url_rewrite">url_rewrite()</a></li>\r
161                 </ul></li>\r
162         <li>19. <a href="#useful-constants">Useful Constants</a>\r
163                 <ul>\r
164                         <li>19.1 <a href="#const-include_path">AT_INCLUDE_PATH</a></li>\r
165                         <li>19.2 <a href="#const-sep">SEP</a></li>\r
166                         <li>19.3 <a href="#const-devel">AT_DEVEL</a></li>\r
167                         <li>19.4 <a href="#const-table_prefix">TABLE_PREFIX</a></li>\r
168                         <li>19.5 <a href="#const-version">VERSION</a></li>\r
169                 </ul></li>\r
170         <li>20. <a href="#install-upgrade-scripts">Install &amp; Upgrade Scripts</a>\r
171                 <ul>\r
172                         <li>20.1 <a href="#install-script">Install Script</a></li>\r
173                         <li>20.2 <a href="#upgrade-script">Upgrade Script</a></li>\r
174                 </ul></li>\r
175         <li>21. <a href="#accessibility">Accessibility</a></li>\r
176         <li>22. <a href="#validation">Validation</a></li>\r
177         <li>23. <a href="#example">Sample Script</a></li>\r
178         <li>24. <a href="#credits-sources">Credits &amp; Additional Sources</a></li>\r
179 </ul>\r
180 \r
181 <a href="#top" class="top">top</a>\r
182 <h2><a name="version"></a>0. Version Considerations</h2>\r
183         <p>This document is found in ATutor's <kbd>documentation/</kbd> directory and is maintained along with the rest of the code in the code repository. The latest version of this document will always be available in the repository. Versions bundled with ATutor releases are specific to that release. If you are modifying a previous version of ATutor then you should refer to the version of these guidlines as they are available with that specific version.</p>\r
184 \r
185 <a href="#top" class="top">top</a>\r
186 <h2><a name="introduction"></a>1. Introduction</h2>\r
187         <p>ATutor, as an open source project, encourages PHP developers to develop their own custom features, and potentially contribute those features so they become a permanent part of ATutor. To ensure that  code is easy to  maintain, we urge developers to follow the guidelines outlined below. These rules and recommendations were created to standardize the distributed development process.</p>\r
188 \r
189         <p>The latest version of this document can always be found at <a href="http://www.atutor.ca/atutor/docs/">ATutor.ca</a>.</p>\r
190         <h3><a name="introduction-api"></a>1.1 API Documentation</h3>\r
191                 <p>Detailed API documentation is distributed throughout the ATutor source code, describing functions and classes, and how they are used in developing features. API documentation can be extracted into a relatively compact form for easy scanning and searching using the <strong>phpDocumentor module</strong>. Download the module from atutor.ca, and install it like any other module, then run the application to extract the API documentation from ATutor.</p>\r
192 \r
193                 <p><a href="http://www.atutor.ca/atutor/modules/index.php">phpDocumentor Module</p>\r
194 <a href="#top" class="top">top</a>\r
195 <h2><a name="conventions"></a>2. Conventions Used in This Document</h2>\r
196         <p>This section covers the typographical conventions used in this document.</p>\r
197 \r
198         <h3><a name="typographic-conventions"></a>2.1 Typographic Conventions</h3>\r
199         <dl>\r
200                 <dt><kbd>Constant width</kbd></dt>\r
201                 <dd><p>Used for commands and code examples. Example: Use the <kbd>debug()</kbd> function to view a variable.</p></dd>\r
202 \r
203                 <dt><kbd>`Constant width surrounded by quotes`</kbd></dt>\r
204                 <dd><p>Constant-width font with surrounding quotes is used for filenames and path names. Example: The <kbd>`vitals.php`</kbd> file is important.</p></dd>\r
205 \r
206                 <dt>Square brackets (<kbd>`[`</kbd> and <kbd>`]`</kbd>)</dt>\r
207                 <dd><p>In syntax descriptions, square brackets (<kbd>`[`</kbd> and <kbd>`]`</kbd>) are used to indicate optional words or clauses. Not to be confused with the use of square brackets in <kbd>array</kbd> definitions. For example, in the following statement, <kbd>version</kbd> is optional: <kbd>./bundle.sh [version]</kbd>.</p></dd>\r
208 \r
209                 <dt>Pipe (<kbd>`|`</kbd>)</dt>\r
210                 <dd><p>When a syntax element consists of a number of alternatives, the alternatives are separated by pipes (<kbd>`|`</kbd>).</p></dd>\r
211         </dl>\r
212 \r
213         <p>Example code is to be used as examples only and not as tested production code. In most cases its usefulness in the context of the example outweighs its correctness as workable code. In other cases the syntax and style used in the example itself are irrelevant and do not follow the coding guidelines outlined below. For example, <kbd>array</kbd>s may be documented using <kbd>string</kbd> keys without quoting their value, <kbd>$_SESSION[prefs]</kbd>, while in practice it is always best to escape the key with quotes: <kbd>$_SESSION['prefs']</kbd>.</p>\r
214 \r
215         <h3><a name="links-conventions"></a>2.2 Links</h3>\r
216                 <p>All the links in this document open in the current browser. Links that are not obviously to external sites are supplemented with <em>title</em> text. All other links are assumed to be anchors within this document.</p>\r
217 \r
218         <h3><a name="function-definitions"></a>2.3 Function Definitions (Prototypes)</h3>\r
219                 <p>The usage of the square brackets (<kbd>`[`</kbd> and <kbd>`]`</kbd>) around parameters imply that they are optional, in which case the function documentation will then state what the default value for that variable is. Please pay close attention to the return types of functions: If a function is described to return <kbd>boolean</kbd> then it will return either <kbd>TRUE</kbd> or <kbd>FALSE</kbd> and <strong>not</strong> an <kbd>integer</kbd> such as 0 or 1. Optional arguments to functions must always be listed as the last parameters in the list.</p>\r
220 \r
221                 <p><kbd>returned_type <strong>function_name</strong>( param_type $param_name [, opt_param_type $opt_param_name])</kbd></p>\r
222                 <dl>\r
223                         <dt><kbd>returned_type</kbd></dt>\r
224                         <dd><p>Type of value this function returns. See <a href="http://www.php.net/manual/en/language.types.php" title="PHP.net - Chapter 6. Types">Types</a> and <a href="http://www.php.net/manual/en/types.comparisons.php" title="PHP.net - Appendix O. PHP type comparison tables">PHP type comparison tables</a>.</p></dd>\r
225 \r
226                         <dt><kbd>function_name</kbd></dt>\r
227                         <dd><p>The function name.</p></dd>\r
228 \r
229                         <dt><kbd>param_type</kbd> and <kbd>opt_param_type</kbd></dt>\r
230                         <dd><p>The type of the parameter that the function expects. See <a href="http://www.php.net/manual/en/language.types.php" title="PHP.net - Chapter 6. Types">Types</a> and <a href="http://www.php.net/manual/en/types.comparisons.php" title="PHP.net - Appendix O. PHP type comparison tables">PHP type comparison tables</a>.</p></dd>\r
231 \r
232                         <dt><kbd>$param_name</kbd> and <kbd>$opt_param_name</kbd></dt>\r
233                         <dd><p>The names of the parameters as they are used in the function. The <kbd>$opt_param_name</kbd> is optional.</p></dd>\r
234                 </dl>\r
235         </p>\r
236 \r
237 <a href="#top" class="top">top</a>\r
238 <h2><a name="setup">3. Setup</a></h2>\r
239         <p>Please review the <a href="http://atutor.ca/atutor/docs/requirements.php" title="ATutor.ca - requirements">ATutor requirements</a> and ensure that your development environment meets the minimum requirements.</p>\r
240 \r
241         <ul>\r
242                 <li><a href="http://dev.mysql.com/doc/mysql/en/Installing.html">MySQL.com - Installation MySQL</a></li>\r
243                 <li><a href="http://www.php.net/manual/en/installation.php">PHP.net - Installing PHP with Apache</a></li>\r
244                 <li><a href="http://www.thesitewizard.com/archive/php4install.shtml">How to Install and Configure PHP4 to Run with Apache on Windows</a></li>\r
245         </ul>\r
246 \r
247         <h3><a name="php-configuration"></a>3.1 PHP Configuration</h3>\r
248         <p>If you have a dedicated development environment that doesn't share a web server with other production code, then it is best to use the bundled <kbd>php.ini-dist</kbd> configuration file as the default--simply rename it to <kbd>php.ini</kbd>. Listed below are the essential configuration options and their recommended value:</p>\r
249 <pre class="code">\r
250 safe_mode            = Off\r
251 error_reporting      = E_ALL\r
252 display_errors       = On\r
253 arg_separator.input  = ";&"\r
254 register_globals     = Off\r
255 magic_quotes_gpc     = Off\r
256 magic_quotes_runtime = Off\r
257 allow_url_fopen      = On\r
258 register_argc_argv   = Off</pre></p>\r
259 \r
260 <a href="#top" class="top">top</a>\r
261 \r
262 <h2><a name="github"></a>4. GitHub</h2>\r
263 <p>The ATutor source code is maintained in a <a href="https://github.com/atutor/ATutor">GitHub repository</a>, a public version control system that provides "Social Coding" capabilities, making it relatively easy for ATutor developers to have work added to ATutor's public source code. Developers will need to become familiar with Git and GitHub if they wish to participate in ATutor development. There is plenty of documentation on using Git and GitHub. You might read through the book at <a href="http://progit.org/book/">Git Pro</a>, or review the <a href="http://help.github.com/">GitHub Help</a> documentaiton. </p>\r
264 <a name="github_setup"></a>\r
265         <h3><a name="git-install"></a>4.1 Setting up a Git Development Environment</h3>\r
266         <p>Though there are a variety of Git client applications available, working from a command prompt issuing Git commands is relatively easy to learn. Knowing a small set of Git commands is all you required to get up and running, and contributing code through GitHub. </p>\r
267         \r
268         <p>For <strong>Mac users</strong> there is <a href="http://mac.github.com/">GitHub for Mac</a>, which can be installed to setup Git on your Mac. It provides a graphical client through which GitHub can be accessed.</p>\r
269         \r
270         <p><strong>Windows users</strong> have a variety of GitHub clients available. A quick search will turn up many. One popular client for Windows is <a href="http://www.syntevo.com/smartgit/index.html">SmartGit</a>. Another is <a href="http://www.cygwin.com/">Cygwin</a></p>\r
271         \r
272         <p><strong>Linux users</strong> also have a variety of Github clients available, such as <a href="http://cola.tuxfamily.org/">Git Cola </a> or <a href="http://live.gnome.org/giggle">Giggle</a>, among others. And, of course, if you prefer to just work from the command prompt, just install git itself. Most, probably all, Linux systems have a Git package available that can be installed through their package management system. On Ubuntu or Debian for instance, as the root user issue the command <kbd>apt-get install git</kbd> at the command prompt.</p>\r
273         \r
274 <h3><a name="github_maintaining"></a>4.2 Creating and Maintaining a Git Fork</h3>\r
275         <p>All developers outside the core development team will work in their own fork of the ATutor source code located on GitHub. Creating a fork is pretty straight forward. Once your <a href="https://github.com/plans">GitHub account</a> is setup, and you have logged in, search for the atutor/ATutor repository. At the top of the screen while viewing the repository, click on the <kdb>"Fork"<kdb> button to create a fork of the master source code. You will now have a copy of the source code linked to your account, something like <kdb>[username]/ATutor</kdb>, where [username] is your GitHub login.</p>\r
276         \r
277         <p>Now you will want to clone the fork you created into your local development environment. Using your Git client you can then find its "clone" features to generate a local copy, or at the command prompt issue the following commands:</p>\r
278         \r
279         <p><strong>Create a clone</strong><br />\r
280         <kbd>git clone git@github.com/username/ATutor.git </kbd> (create a local copy, or clone, of the fork you created on GitHub)<br />\r
281         <kbd>cd ATutor </kbd> (move into the cloned repository)<br/>\r
282         <kbd>git remote add upstream git://github.com/atutor/ATutor.git</kbd> ( for later fetching upstream changes from the main ATutor repository to keep your code current)<br /></p>\r
283         \r
284         <p><strong>Create a branch to work in</strong><br />\r
285 \r
286         <kbd>git checkout -b new_feature </kbd> (to create a working branch and switch to that branch. give the branch a descriptive name.)<br />\r
287         <kbd>git branch </kbd> (to list the branches)<br /></p>\r
288 \r
289 \r
290         \r
291         <p><strong>Edit, create, add copies of file as you would during development</strong>\r
292         <br />\r
293         <kbd>git status </kbd> (to list modified files)<br />\r
294         <kbd>git add [filename] </kbd> (to stage modified file, or "git add *" to stage all modified files)<br />\r
295         <kbd>git status </kbd> (to list staged files)<br />\r
296         <kbd>git commit -m "describe the changes in a log message"</kbd> (to save the staged file to the new_feature branch you created above)<br />\r
297         <kbd>git log </kbd> (to list changes that were committed)<br /></p>\r
298         \r
299         <p><strong>Keep your branch up-to-date</strong> (perform these operations often)<br />\r
300         <kbd>git checkout master </kbd> (switch to the local master branch)<br />\r
301         <kbd>git pull upstream master  </kbd> (update your local master branch with code from the main ATutor repository)<br />\r
302         <kbd>git checkout new_feature </kbd> (switch to the local new_feature branch)<br />\r
303         <kbd>git merge master </kbd> (merge updates in the local master to your working branch, then resolve any conflicts)<br /></p>\r
304         \r
305         <p>After pulling from the ATutor master repository, review the latest SQL upgrade file to ensure your database structure is up-to-date (in the install/db/ directory ). The file will contain schema changes of the current pre-released source. Example: If the current working source will be version 1.9, then the upgrade file to keep track of will be named <kbd>atutor_upgrade_<em>x.y.z</em>_to_1.9.sql</kbd>, where <kbd><em>x.y.z</em></kbd> is the version of the currently available stable release.</p>\r
306         \r
307         <p><strong>Submitting code for review and addition to ATutor</strong> <br />\r
308         <kbd>git push origin new_feature </kbd> (push your new_feature branch to your own GitHub repository)<br />\r
309         Go to <a href="https://github.com">https://github.com</a>, login, then under "switch branches" select the <kbd>new_feature</kbd> branch you just pushed.<br />\r
310         Click on the <strong>Pull Request</strong> button, to send your code for review.<br />\r
311         Read through the pull request to ensure it is correct, for example \r
312         "<em>You're asking atutor to pull [1] commit into atutor:master from username:new_feature</em>" <br/>\r
313         Press <strong>Send pull request</strong> to finish your code submission.</p>\r
314 \r
315         <p><strong>Clean up when you're done</strong> (after the code has been reviewed, accepted, and merged into the ATutor master branch)<br />      \r
316         <kbd>git branch master</kbd> (move into a branch other than the one to be deleted)<br />\r
317         <kbd>git branch -D new_feature</kbd> (delete the branch from your local repository)<br />\r
318         <kbd>git push origin :new_feature</kbd> (remove the branch from GitHub)</p>\r
319 <h3><a name="svn-install"></a>4.3 Installing from GitHub</h3>\r
320         <p>Installing the development code cloned from GitHub requires one extra step in addition to the standard installation described in the <a href="http://atutor.ca/atutor/docs/installation.php#fresh">Installation Instructions</a>. Once the source code has been cloned, change to the ATutor/docs/include directory and create an empty configuration file by issuing the command <kbd>touch config.inc.php</kbd>, then run the installer as described in the instructions.</p>\r
321         \r
322         \r
323 <a href="#top" class="top">top</a>\r
324 <h2><a name="communication"></a>5. Communication</h2>\r
325         <p>Much communication between developers occurs in the <a href="http://atutor.ca/forum/12/1.html">Development Forum</a>. Please try to keep discussions public including any feature proposals. You may also communicate with directly through IRC. Using your IRC client, open <kbd>irc://irc.oftc.net/</kbd> then join the #atutor channel.  </p>\r
326 \r
327 <a href="#top" class="top">top</a>\r
328 <h2><a name="patches"></a>6. Patches</h2>\r
329         <p>As of ATutor 1.6 the Patcher module is available for applying and developing patches to repair bugs, and to add or modify features. Details on creating and applying patches can be found in the ATutor Handbook for version 1.6.1+, or on the ATutor Wiki.</p>\r
330         <p><a href="http://wiki.atutor.ca/display/atutorwiki/Patcher+Module+Documentation">Patcher Documentation</a></p>\r
331 \r
332 <a href="#top" class="top">top</a>\r
333 <h2><a name="editor-tips"></a>7. Editor Tips</h2>\r
334         <p>We use <a href="http://editplus.com">EditPlus</a>, but you can use whichever editor and settings you feel comfortable with. The most important part when editing is to ensure that tabs meet the coding guidelines on <a href="#indentation">indentation</a>. Unix KDE users might use Kate as their text editor.</p>\r
335 \r
336         <p>A few desirable features for a good text editor are listed below:\r
337         <ul>\r
338                 <li>Column and row numbering.</li>\r
339                 <li>Jump to line number.</li>\r
340                 <li>Word wrap toggle.</li>\r
341                 <li>Being able to specify soft or hard tabs.</li>\r
342                 <li>Syntax highlighting.</li>\r
343                 <li>Trim trailing whitespace.</li>\r
344                 <li>DOS to UNIX CR/LF conversions. Your editor must be able to save files with UNIX style line breaks. This means the <kbd>\n</kbd> character instead of the </kbd>\r</kbd> (Mac style) or <kbd>\r\n</kbd> (Windows style).</li>\r
345         </ul></p>\r
346 \r
347 \r
348 <a href="#top" class="top">top</a>\r
349 <h2><a name="proposed-features"></a>8. Proposed Features</h2>\r
350         <p>The <a href="http://atutor.ca/atutor/features.php" title="ATutor.ca - Proposed Features">Proposed Features</a> page lists features which have been requested by the ATutor community. ATutor.ca members can vote on features to establish a priority, while potential developers may then assign themselves to tasks. New feature requests should be posted to the <a href="http://atutor.ca/forum/2/1.html" title="ATutor.ca - Feature Requests Forum">ATutor Feature Requests</a> forum.</p>\r
351 \r
352 <a href="#top" class="top">top</a>\r
353 <h2><a name="bug-tracking"></a>9. Bug Tracking</h2>\r
354         <p>Please report bugs to the <a href="http://atutor.ca/forum/3/1.html" title="ATutor.ca - Bug Forum">ATutor Bug Reports</a> forum, or directly to the <a href="http://www.atutor.ca/atutor/mantis">Mantis Bug Tracker</a>. Be sure to indicate the code version being used, such as a release candidate, stable release, nightly build, or SVN checkout, etc. Also be sure to describe the details of the system that ATutor is being developed or tested on, such as the operating system, web server and version, PHP version, etc. Browse the <a href="http://www.atutor.ca/development/bugs/">Current Bug Summary</a> for a list of active bug fixing.</p>\r
355 \r
356 <a href="#top" class="top">top</a>\r
357 <h2><a name="creating-bundles"></a>10. Creating Bundles</h2>\r
358         <p>The file <kbd>`bundle.sh`</kbd> is located in a directory above <kbd>`docs`</kbd> and is used for creating bundles from the working <kbd>`docs`</kbd> directory. The Shell script must be run on UNIX and will retrieve the latest version of the language from the database, disables debugging, creates an empty config.inc.php filr, and lastly create a <kbd>.tar.gz</kbd> file. Note, by default this script will generate a bundle from the atutor \r
359 svn source code repository. You may change this path near the top of the file to point to a local version of the ATutor source code, if for instance you have your own customizations you'd like to build into an installable bundle. Usage:\r
360                 \r
361                 <dl>\r
362                         <dt><kbd>./bundle.sh [version_number]</kbd><dt>\r
363                         <dd><p>Note that you will need execute permissions on the script to use it, and if it isn't in your <kbd>PATH</kbd> then you will have to prefix it with a <kbd>./</kbd>. The optional <kbd>version_number</kbd> argument will be used for suffixing onto the file name.  For example, a version number of <kbd>1.8RC1</kbd> will generate a file named <kbd>ATutor-1.8RC1.tar.gz</kbd>.</p></dd>\r
364                 </dl>\r
365         </p>\r
366 \r
367 <a href="#top" class="top">top</a>\r
368 <h2><a name="writing-portable-code"></a>11. Writing Portable Code</h2>\r
369         <p>When writing your PHP code please try to use functions that exist since (the minimum requirement) PHP version 4.3.0. If you have to use a function that only exists in later versions of PHP, provide an alternative for older versions. To check if the function is available use either <kbd>version_compare(phpversion(), $min_version)</kbd> or <kbd>function_exists($function_name)</kbd>.\r
370 \r
371         <p>Code has to work on both Windows and UNIX. You should never use <kbd>exec()</kbd> or <kbd>system()</kbd>. In most cases we prefer to write code that works on both systems as is, without the need for if-statements that check for the operating system, since duplicating the functionality twice (once for each operating system) can be a source of bugs. Review the <a href="#php-configuration">PHP Configuration</a> section for details on how best to set-up your development environment.</p>\r
372 \r
373 <a href="#top" class="top">top</a>\r
374 <h2><a name="coding-style"></a>12. Coding Style</h2>\r
375         <p>This section should help those who would like to modify or add code. Anyone who wishes to contribute code must adhere to these guidelines or the code may not be accepted. Please try to write code that is easy to read and maintain with appropriate comments as needed. Correctness and efficiency are easier to certify if code is simple to read and understand.</p>\r
376 \r
377         <h3><a name="indentation"></a>12.1 Indentation</h3>\r
378                 <p>The importance of indentation for code organization cannot be overstated. Although indentation is not mandatory in PHP, it is a powerful visual organization tool that should consistently be applied to code.</p>\r
379                 <ul>\r
380                         <li>Indent using 4 spaces for each level.</li>\r
381                         <li>Think carefully about when too many nested levels has been reached. (Usually 4-5 is a good limit).</li>\r
382                         <li>Use <em>Hard tabs</em>, as described below.</li>\r
383                 </ul>\r
384 \r
385                 <p>Internally, we have used hard tabs as we all use the same editor, but we may decide to move to soft tabs in the future. Hard tabs are regular tabs while soft tabs are not really tabs at all; each soft tab is actually represented by a certain number of regular spaces. The benefit of using soft tabs is that they always appear the same, regardless of the editor's tab-spacing. With soft tabs set and enforced, it is easy to maintain consistent indentation and whitespace treatment throughout code. When hard tabs are used, especially if there are multiple developers using different editors, it is easy for mixed levels of indentation to be introduced, confusing the code's layout.</p>\r
386 \r
387         <h3><a name="line-length"></a>12.2 Line Length</h3>\r
388                 <p>Split the long lines into multiple lines: \r
389 <pre class="code">\r
390 if (($month = 'jan') || ($month = 'feb') || ($month = 'mar') || ($month = 'apr')) {\r
391     return 1;\r
392 }\r
393 </pre></p>\r
394 \r
395     <p>You can indent the second line to signify the association with the upper. For particularly long lines, you can indent and align every condition:\r
396 <pre class="code">\r
397 if (($month = 'jan') || \r
398     ($month = 'feb') || \r
399     ($month = 'mar') || \r
400     ($month = 'apr')) {\r
401 \r
402     return 1;\r
403 }\r
404 </pre></p>\r
405 \r
406         <p>This methodology works equally well for function parameters:\r
407 <pre class="code">\r
408 echo format_content($content_row['text'], \r
409                     $content_row['formatting'], \r
410                     $glossary,\r
411                     $indent);\r
412 </pre></p>\r
413 \r
414         <h3><a name="whitespace"></a>12.3 Using Whitespace</h3>\r
415                 <p>Whitespace can be used to provide and reinforce logical structure in the code. For example, it can be effectively used to group assignments and show associations. The following example is poorly formatted and difficult to read:\r
416 \r
417 <pre class="code">\r
418 $password = 'mypassword';\r
419 $website_url = 'http://atutor.ca';\r
420 $first_name = 'Joel';\r
421 $last_name = 'Kronenberg';\r
422 </pre></p>\r
423 \r
424         <p>But this code block can be improved by using whitespace to logically group related assignments together and align them on the equal sign (<kbd>=</kbd>):\r
425 <pre class="code">\r
426 $pet_type    = 'mypassword';\r
427 $website_url = 'http://atutor.ca';\r
428 $first_name  = 'Joel';\r
429 $last_name   = 'Kronenberg';\r
430 </pre></p>\r
431 \r
432         <h3><a name="sql-guidelines"></a>12.4 SQL Guidelines</h3>\r
433                 <p>Similar formatting and layout rules applied to PHP can be applied to SQL queries as well. SQL queries, especially in database systems that support complex subqueries, can become convoluted. As with PHP code, whitespace and line breaks should be used in SQL code as needed. Consider the following:\r
434         \r
435 <pre class="code">\r
436 select employees.first_name, employees.last_name from \r
437                employees where employees.vacation_time > 0 order by employees.last_name";\r
438 </pre>        \r
439         </p>\r
440 \r
441                 <p>This is a simple query, but it is poorly organized. Its organization can be improved in a number of ways, including the following:\r
442         <ul>\r
443             <li>Capitalize SQL keywords.</li>\r
444             <li>Break lines on SQL keywords.</li>\r
445             <li>Use table aliases to keep code clean.</li>\r
446         </ul>\r
447         \r
448 <pre class="code">\r
449 SELECT   S.first_name, S.last_name \r
450 FROM     students S\r
451 WHERE    S.email = '' \r
452 ORDER BY S.last_name";\r
453 </pre></p>\r
454 \r
455                 <h3><a name="sql-joins"></a>12.5 SQL/99 Joins</h3>\r
456            <p>ANSI SQL/99 features ANSI compliant joins. There are several advantages in using this new syntax, one of which is the separation of the <kbd>JOIN</kbd> condition from the <kbd>WHERE</kbd> clause.\r
457 <pre class="code">\r
458 SELECT  M.email, M.login \r
459 FROM    members M, forums_subscriptions S \r
460 WHERE   S.member_id=M.member_id \r
461 AND     M.email <> ''\r
462 </pre>\r
463 SQL/99 makes a clear distinction between the fields in the <kbd>JOIN</kbd> condition and the <kbd>WHERE</kbd> clause:\r
464 <pre class="code">\r
465 SELECT  M.email, M.login\r
466 FROM    members M\r
467 JOIN    forums_subscriptions S USING (member_id)\r
468 WHERE   M.email <> ''\r
469 </pre></p>\r
470 \r
471         <h3><a name="control-flow-constructs"></a>12.6 Control Flow Constructs</h3>\r
472                 <p>\r
473                         <ul>\r
474                                 <li><em>Always</em> use <kbd>&lt;?php ?></kbd> instead of the short form <kbd>&lt;? ?></kbd>. This implies that you must not use the <kbd>&lt;?=$var;?></kbd> short form either.</li>\r
475                                 <li>Always include the optional semicolon in single line PHP blocks: <kbd>&lt;?php echo $something<big>;</big> ?></kbd>\r
476                                 <li>Use <kbd>'</kbd> instead of <kbd>"</kbd> if there are no variables or special characters.</li>\r
477                                 <li>Use spaces around string concatenating. <kbd>echo 'str' . $value . 'str2';</kbd></li>\r
478                                 <li>Parenthesis <kbd>`( )`</kbd> should come right after a function name. <kbd>function()</kbd> not <kbd>function ()</kbd></li>\r
479                                 <li>Parenthesis <kbd>`( )`</kbd> should have a space right after a language construct (<kbd>if</kbd>, <kbd>while</kbd>, <kbd>for</kbd>). Examples: <kbd>for (...)</kbd>, <kbd>while (condition)</kbd></li>\r
480                                 <li>Avoid using <kbd>continue</kbd> and <kbd>break</kbd> as it makes debugging more difficult.</li>\r
481                     <li>Braces formatting is illustrating below. We use K&R style where the initial brace is placed on the same line as the keyword and the trailing brace inline on its own line with the keyword:\r
482 <pre class="code">\r
483 if (condition) {\r
484     ...\r
485 } else if (condition) {\r
486     ...\r
487 } else {\r
488     ...\r
489 }\r
490 </pre></li>\r
491                                 <li>Arrays should be referenced with no spaces. <kbd>$arr['index']</kbd> not <kbd>$arr[ 'index' ]</kbd></li>\r
492                                 <li>Avoid using short if-statement construct (<kbd>$var = ($query ? $val1 : $val2)</kbd>) except in very rare cases. It is confusing and has a lot of bug potential.</li>\r
493                         </ul>\r
494                 </p>\r
495 \r
496         <h3><a name="commenting"></a>12.7 Commenting</h3>\r
497                 <p>Avoid using Shell/Perl-style (<kbd>## this is a comment</kbd>) comments entirely. Use C-style comments (<kbd>/* ... */</kbd>) for large comment blocks and C++-style comments (<kbd>// ...</kbd>) for single-line comments only:\r
498 <pre class="code">\r
499 /* This is a comment block\r
500  * it is used for describing\r
501  * the code below.\r
502  */\r
503 ...\r
504 // this is a single line comment\r
505 </pre></p>\r
506         <p>Please, document while your code. See <a href="http://phpdocu.sourceforge.net/howto.php">phpdoc</a>, like <a href="http://java.sun.com/docs/books/jls/first_edition/html/18.doc.html">javadoc</a>, for details how to document functions, classes, methods, and variables. Coding is often hurried, but it will save a lot of time in the end to do this type of documenting! It looks like this:\r
507    <pre class="code">\r
508    /**\r
509    * what the function does in one line.\r
510    * more detailed description on 0-n lines, if needed.\r
511    * @access  [public|static|pseudostatic]\r
512    * @param   [string|int|double|bool|array|object|mixed] $paramName1 desc\r
513    * @param   [string|int|double|bool|array|object|mixed] $paramName2 desc\r
514    *  ...\r
515    * @param   [string|int|double|bool|array|object|mixed] $paramNameN desc\r
516    * @return  datatype  description\r
517    * @throws  <em>not until PHP 5</em>\r
518    * @see     some_function()\r
519    * @todo    description\r
520    * @since   ATutor version, PHP version   (comma separated list)\r
521    * @status  stable|experimental           (if not set then considered stable)\r
522    * @pattern singleton|factory|mvc|observer|facade|...\r
523    * @author  description                   (comma separated list)\r
524    */\r
525    function something() {\r
526    }\r
527    </pre>\r
528    Note that the description should be given as plain text not HTML.  The <kbd>@pattern singleton</kbd> means that the constructor returns a reference to an already existing instance, if there is one.</p>\r
529 \r
530         <h3><a name="naming-conventions"></a>12.8 Naming Conventions</h3>\r
531         <ul>\r
532                 <li><a name="naming-variables"></a>12.8.1 Naming Variables:\r
533                         <ul>\r
534                                 <li>Use capital letters for constants. E.g. <kbd>define('CONSTANT', 1)</kbd> and use the capital form of  <kbd>TRUE</kbd>, <kbd>FALSE</kbd> and <kbd>NULL</kbd></li>\r
535                                 <li>Otherwise, use all lower case</li>\r
536                                 <li>Use <kbd>_</kbd> to separate words. E.g. <kbd>$green_colour_value</kbd></li>\r
537                                 <li>Loop variables can be of the usual variety: <kbd>$i</kbd>, <kbd>$j</kbd>, <kbd>$k</kbd>, etc.</li>\r
538                                 <li>Count variables should follow the format $*_count. E.g. <kbd>$bug_count</kbd>, and always initialised to 0</li>\r
539                                 <li>Temporary variables should be prefixed with <kbd>temp_</kbd></li>\r
540                                 <li><kbd>$sql</kbd>, <kbd>$result</kbd>, and <kbd>$row</kbd> should be used for SQL query, results, and rows respectively</li>\r
541                         </ul>\r
542                 </li>\r
543 \r
544                 <li><a name="naming-functions"></a>12.8.2 Naming Functions:\r
545                         <ul>\r
546                                 <li>Use all lower case</li>\r
547                                 <li>Use <kbd>_</kbd> to separate words. E.g. <kbd>setup_page_breaks()</kbd></li>\r
548                                 <li>Keep functions to 5 words or less</li>\r
549                                 <li>Functions that print should be prefixed with <kbd>print_</kbd>.</li>\r
550                                 <li>Try to use prefixes to group functions (E.g., <kbd>email_</kbd>, <kbd>news_</kbd>, etc.)</li>\r
551                         </ul>\r
552                 </li>\r
553 \r
554                 <li><a name="naming-files"></a>12.8.3 Naming Files:\r
555                         <ul>\r
556                                 <li>Use all lower case</li>\r
557                                 <li>Use <kbd>_</kbd> to separate words. E.g. <kbd>view_new_bugs_page.php</kbd></li>\r
558                                 <li>Use <kbd>.php</kbd> file extensions (not <kbd>.html</kbd> or <kbd>.php3</kbd>)</li>\r
559                                 <li>Filenames must be less than 32 characters in length as this works with older file systems like MacOS</li>\r
560                                 <li>Included files should be suffixed by <kbd>.inc.php</kbd></li>\r
561                                 <li>Files containing classes should be suffixed by <kbd>.class.php</kbd></li>\r
562                                 <li>Exception: Files being included as part of an external library should not be renamed</li>\r
563                         </ul>\r
564                 </li>\r
565         </ul>\r
566 \r
567 <a href="#top" class="top">top</a>\r
568 <h2><a name="directory-structure"></a>13. Directory Structure</h2>\r
569         <p>The following is a short explanation of the important components of the ATutor directory structure.</p>\r
570 \r
571         <h3><a name="directories"></a>13.1 Directories</h3>\r
572         <dl>\r
573                 <dt><kbd>`admin/`</kbd></dt>\r
574                         <dd>This directory contains files used for the administration area (when a user logs in as an administrator). This includes files for system statistics, instructor requests, management of users, courses, categories and languages, and server configuration.</dd>\r
575 \r
576                 <dt><kbd>`editor/`</kbd></dt>\r
577                         <dd>This directory contains files used by a course instructor (or privileged user) to edit course content such as the glossary, course content, forums, announcements, and polls.</dd>\r
578 \r
579                 <dt><a name="directories-include"></a><kbd>`include/`</kbd></dt>\r
580                         <dd>This directory contains files that are required or included into other files.</dd>\r
581 \r
582                 <dt><kbd>`include/classes/`</kbd></dt>\r
583                         <dd>This directory contains classes, essential to certain ATutor functions, such as the phpMailer, XML, Savant templating, and content management classes.</dd>\r
584 \r
585                 <dt><kbd>`include/html/`</kbd></dt>\r
586                         <dd>This directory contains files that output HTML, usually displayed on (included into) multiple pages.</dd>\r
587 \r
588                 <dt><kbd>`include/lib/`</kbd></dt>\r
589                         <dd>This directory contains library files that hold functions and constants used throughout ATutor code.</dd>\r
590 \r
591                 <dt><kbd>`install/include/`</kbd></dt>\r
592                         <dd>This directory contains files used during the installation process, including each step of the fresh install and upgrade processes.</dd>\r
593 \r
594                 <dt><kbd>`install/db/`</kbd></dt>\r
595                         <dd>This directory contains the SQL files necessary to set up or upgrade the ATutor database.</dd>\r
596 \r
597                 <dt><kbd>`jscripts/`</kbd></dt>\r
598                         <dd>This directory contains all JavaScript files.</dd>\r
599 \r
600                 <dt><kbd>`themes/`</kbd></dt>\r
601                         <dd>This directory contains the different themes installed on an ATutor system, each with its own subdirectory.</dd>\r
602                 \r
603                 <dt><kbd>`mods/`</kbd></dt>\r
604                         <dd>This directory contains the module installed in an ATutor system.</dd>\r
605 \r
606         </dl>\r
607 \r
608         <h3><a name="files"></a>13.2 Files</h3>\r
609         <p>The following is a description of some of the important files.</p>\r
610         <dl>\r
611                 <dt><kbd>`include/config.inc.php`</kbd></dt>\r
612                         <dd>This file is created during installation and contains specific configuration information for an ATutor system.</dd>\r
613 \r
614                 <dt><a name="files-vitals"></a><kbd>`include/vitals.inc.php`</kbd></dt>\r
615                         <dd>This file is included by every directly accessible page.  It connects to the database, initiates the user session, includes common libraries and constants, and defines frequently used functions.</dd>\r
616 \r
617                 <dt><a name="them-readme"></a><kbd>`themes/themes_readme.txt`</kbd></dt>\r
618                         <dd>This file contains detailed information on how to create and install a theme.</dd>\r
619 \r
620                 <dt><a name="files-header"></a><kbd>`include/header.inc.php`</kbd></dt>\r
621                         <dd>This file outputs the page's header using the correct template and theme.</dd>\r
622 \r
623                 <dt><a name="files-footer"></a><kbd>`include/html/footer.inc.php`</kbd></dt>\r
624                         <dd>This file outputs the page's footer using the correct template and theme.</dd>\r
625 \r
626                 <dt><a name="files-output"></a><kbd>`include/lib/output.inc.php`</kbd></dt>\r
627                         <dd>Most output formatting is done in this file, including things such as language, dates, a paginator, and content formatting, among other things .</dd>\r
628         </dl>\r
629 \r
630 \r
631 <a href="#top" class="top">top</a>\r
632 <h2><a name="database-structure"></a>14. Database Structure</h2>\r
633         <p>A <a href="database.gif">database model diagram</a> (153 KB GIF) created from the ATutor 1.4.1 database schema is available. (somewhat outdated)</p>\r
634 \r
635 <a href="#top" class="top">top</a>\r
636 <h2><a name="localisation"></a>15. Localisation</h2>\r
637         <p>All language terms and phrases are stored in the ATutor database. See the <a href="#fn-at"><kbd>_AT()</kbd></a> function for details on displaying text. There are three tables that are used for managing languages, their roles are as follows:\r
638                 <dl>\r
639                         <dt><kbd>`language_pages`</kbd></dt>\r
640                         <dd>This table is used to cross reference language terms with pages. It allows selecting, via a <kbd>JOIN</kbd>, only the terms needed for a particular page. The <kbd>JOIN</kbd> may be slow at first but once the result is cached, subsequent calls are many times faster such that only the language needed for a particular page is restored from cache.</dd>\r
641 \r
642                         <dt><kbd>`language_text`</kbd></dt>\r
643                         <dd>This table holds all of the text for an ATutor installation.</dd>\r
644 \r
645                         <dt><kbd>`languages`</kbd></dt>\r
646                         <dd>This table holds the list of all available languages on the system and their attributes.</dd>\r
647 \r
648                 </dl></p>\r
649 \r
650         <h3><a name="adding-language"></a>15.1 Adding &amp; Editing Language</h3>\r
651                 <p>Please see the <a href="http://www.atutor.ca/atutor/docs/translate.php">Translator Documentation</a> for more details on translating a language within ATutor.</p>\r
652 \r
653 <a href="#top" class="top">top</a>\r
654 <h2><a name="error-feedback-messages"></a>16. Error and Feedback Messages</h2>\r
655         <p>All messages are handled using the <kbd>Message</kbd> class. The main purpose of the <kbd>Message</kbd> class is to encapsulate the functionality of tracking \r
656                 and managing various message types during a session by providing a nice layer of abstraction between you and the interface to <kbd>$_SESSION</kbd>, where the messages are stored.</p>\r
657 \r
658         <p>At the moment six types of messages are supported:\r
659         <dl>\r
660                 <dt><kbd>Error</kbd></dt>\r
661                 <dd>Messages reflecting negative feedback to the user, indicating issues that need resolving or addressing.</dd>\r
662 \r
663                 <dt><kbd>Feedback</kbd></dt>\r
664                 <dd>Messages reflecting positive feedback, aknowledging a users action was successfull.</dd>\r
665 \r
666                 <dt><kbd>Warning</kbd></dt>\r
667                 <dd>Messages warning the user of a possible action with undesireable effects.</dd>\r
668 \r
669                 <dt><kbd>Help</kbd></dt>\r
670                 <dd>Messages with helpful information about the current page.</dd>\r
671 \r
672                 <dt><kbd>Info</kbd></dt>\r
673                 <dd>Messages with useful information.</dd>\r
674 \r
675                 <dt><kbd>Confirmation</kbd></dt>\r
676                 <dd>Messages requiring a confirmation in order to execute an action.</dd>\r
677 \r
678         </dl></p>\r
679 \r
680                 \r
681         <p>Please note that using the old method of passing messages is not supported anymore.</p>\r
682 \r
683         <p>Messages can be passed between pages and can be accessed at any time, without any time restriction other than a session timeout.</p>\r
684 \r
685         <h3><a name="error-feedback-internals"></a>16.1 Internals</h3>\r
686                 <p>Essentially the internals of the class are divided into two segments, a section responsible for printing graphics via Savant templates and another that manages the storage of Messages.</p>\r
687         \r
688                 <p>Tracking messages is accomplished by storing message codes and their optional arguments associatively in <kbd>$_SESSION</kbd>. Printing messages is accomplished via Savant and built in templates which can be found in <kbd>`templates/`</kbd>.</p>\r
689         \r
690                 <p>The relational tracking structure is organized in the following manner inside <kbd>$_SESSION</kbd> in no particular order.\r
691                         <ul>\r
692                                 <li><kbd>message</kbd>\r
693                                         <ul>\r
694                                                 <li><kbd>error</kbd>\r
695                                                         <ul>\r
696                                                                 <li><kbd>AT_ERROR_{*}</kbd>\r
697                                                                         <ul>\r
698                                                                                 <li><kbd>AT_ERROR_{*}</kbd></li>\r
699                                                                                 <li><kbd>[argument_1]</kbd></li>\r
700                                                                                 <li><kbd>[argument_2]</kbd></li>\r
701                                                                         </ul>\r
702                                                                 </li>\r
703                                                         </ul>\r
704                                                 </li>\r
705                 \r
706                                                 <li><kbd>warning</kbd>\r
707                                                         <ul>\r
708                                                                 <li><kbd>AT_WARNING_{*}</kbd>\r
709                                                                         <ul>\r
710                                                                                 <li><kbd>AT_WARNING_{*}</kbd></li>\r
711                                                                                 <li><kbd>[argument_1]</kbd></li>\r
712                                                                         </ul>\r
713                                                                 </li>\r
714                                                         </ul>\r
715                                                 </li>\r
716                         \r
717                                                 <li><kbd>info</kbd>\r
718                                                         <ul>\r
719                                                                 <li><kbd>AT_INFOS_{*}</kbd>\r
720                                                                         <ul>\r
721                                                                                 <li><kbd>AT_INFOS_{*}</kbd></li>\r
722                                                                                 <li><kbd>[argument_1]</kbd></li>\r
723                                                                         </ul>\r
724                                                                 </li>\r
725                                                         </ul>\r
726                                                 </li>\r
727 \r
728                                                 <li><kbd>help</kbd>\r
729                                                         <ul>\r
730                                                                 <li><kbd>AT_HELP_{*}</kbd>\r
731                                                                         <ul>\r
732                                                                                 <li><kbd>AT_HELP_{*}</kbd></li>\r
733                                                                                 <li><kbd>[argument_1</kbd></li>\r
734                                                                         </ul>\r
735                                                                 </li>\r
736                                                         </ul>\r
737                                                 </li>\r
738 \r
739                                                 <li><kbd>feedback</kbd>\r
740                                                         <ul>\r
741                                                                 <li><kbd>AT_FEEDBACK_{*}</kbd>\r
742                                                                         <ul>\r
743                                                                                 <li><kbd>AT_FEEDBACK_{*}</kbd></li>\r
744                                                                                 <li><kbd>[argument_1]</kbd></li>\r
745                                                                         </ul>\r
746                                                                 </li>\r
747                                                         </ul>\r
748                                                 </li>\r
749 \r
750                                                 <li><kbd>confirm</kbd>\r
751                                                         <ul>\r
752                                                                 <li><kbd>AT_CONFIRM_{*}</kbd>\r
753                                                                         <ul>\r
754                                                                                 <li><kbd>AT_CONFIRM_{*}</kbd></li>\r
755                                                                                 <li><kbd>[argument_1]</kbd></li>\r
756                                                                         </ul>\r
757                                                                 </li>\r
758                                                         </ul>\r
759                                                 </li>\r
760                                         </ul>\r
761                                 </li>\r
762                         </ul>\r
763                 </p>\r
764         \r
765         <p>Messages are automaticaaly purged from <kbd>$_SESSION</kbd> following an appropriate print command.</p>\r
766 \r
767         <h3><a name="error-feedback-usage"></a>16.2 Adding Messages</h3>\r
768                 <kbd>$msg->add{Error|Warning|Info|Feedback|Help}($code);</kbd><br /><br />\r
769 \r
770                 <p><kbd>$code</kbd> is a <kbs>String</kbd> of a language _msgs code or an array with element 0 being the language _msgs code followed by optional arguments. Refer to the language_text table in the database.</p>\r
771 \r
772                 <p><strong>Important:</strong> One important thing to note is that <kbd>$code</kbd> must be stripped of the prefix for that type of message. By prefix it is meant <kbd>AT_[code_type]_</kbd>. For example:\r
773 \r
774                         <ul>\r
775                                 <li><kbd>`AT_ERROR_FORUM_NOT_FOUND`</kbd> should be specified as <kbd>`FORUM_NOT_FOUND`</kbd>, by stripping off the <kbd>`AT_ERROR_`</kbd> prefix.</li>\r
776                                 <li><kbd>`AT_WARNING_DELETE_MESSAGE`</kbd> as <kbd>`DELETE_MESSAGE`</kbd> by stripping off <kbd>`AT_WARNING_`</kbd>.</li>\r
777                                 <li><kbd>`AT_FEEDBACK_LOGOUT`</kbd> as <kbd>`LOGOUT`</kbd> by stripping off <kbd>`AT_FEEDBACK_`</kbd>.</li>\r
778                                 <li><kbd>`AT_INFOS_MSG_SEND_LOGIN`</kbd> as <kbd>`MSG_SEND_LOGIN`</kbd> by stripping off <kbd>`AT_INFOS_`</kbd>.</li>\r
779                                 <li><kbd>`AT_HELP_FILE_EXPORTABLE`</kbd> as <kbd>`FILE_EXPORTABLE`</kbd> by stripping off <kbd>`AT_HELP_`</kbd>.</li>\r
780                         </ul>\r
781                 </p>\r
782 \r
783                 <p>There are two ways of adding messages: a single code or a code with an array fo arguments. You can mix-and-match, a combination of both is supported even for the same code. Below is description of the formats:</p>\r
784 \r
785                 <p>\r
786                         <dt>Adding single code</dt>\r
787                         <dt><kbd>$msg->addHelp('FILE_EXPORTABLE');</kbd></dt>\r
788                 <br/>\r
789                 <dt><b>OR</b></dt>\r
790                 <br/>\r
791                 <dt>Adding array with arguments</dt>\r
792                 <dt><kbd>$f = array('FILE_EXPORTABLE', 'arg', 'arg2', ...);</kbd></dt>\r
793                 <dt><kbd>$msg->addHelp($f);</kbd></dt>\r
794                 </p>\r
795 \r
796                 <p>A nice feature implemented is that you do not have to provide all\r
797                 the arguments for a particular code at one time. Subsequent adding of\r
798                 the same code will just append the argument. This allows for greater\r
799                 manipulative flexibility in your source, without writing redundant code. Also note\r
800                 that encoding Feedback codes is no longer necessary for redirection.<p>\r
801 \r
802                 <p><b>Example 1:</b>\r
803                 <dt><kbd>$feedback=array('FORUM_ADDED', 'ac_access_groups');</kbd></dt>\r
804                 <dt><kbd>$msg->addFeedback($feedback);</kbd></dt><br/>\r
805 \r
806                 <dt><kbd>// Before we print lets addr another one to the same code</kbd></dt>\r
807                 <dt><kbd>$feedback2=array('FORUM_ADDED', 'about_atutor_help_text');</kbd></dt>\r
808                 <dt><kbd>$msg->addFeedback($feedback2);</kbd></dt><br/>\r
809 \r
810                 <dt><kbd>// No need to url_encode the code</kbd></dt>\r
811                 <dt><kbd>$filename = 'archive.zip';</kbd></dt>\r
812                 <dt><kbd>$f = array('FILE_UPLOADED_ZIP', $file_name);</kbd></dt>\r
813                 <dt><kbd>$msg->addFeedback($f);</kbd></dt>\r
814 \r
815                 </p>\r
816 \r
817 <p>Snapshot of a portion of <kbd>$_SESSION</kbd> as a result:</p>\r
818 <pre class="code">\r
819         [feedback] => Array\r
820                 (\r
821                     [AT_FEEDBACK_FORUM_ADDED] => Array\r
822                         (\r
823                             [0] => AT_FEEDBACK_FORUM_ADDED\r
824                             [1] => ac_access_groups\r
825                             [2] => about_atutor_help_text\r
826                         )\r
827                         \r
828                     [AT_FEEDBACK_FILE_UPLOADED_ZIP] => Array\r
829                         (\r
830                             [0] => AT_FEEDBACK_FILE_UPLOADED_ZIP\r
831                             [1] => archive.zip\r
832                         )\r
833 \r
834 \r
835                 )\r
836         ...\r
837 </pre>\r
838 \r
839 <p>\r
840 <dt><kbd>header('Location: file_manager.php');</kbd></dt>\r
841 <dt><kbd>exit;</kbd></dt>\r
842 </p>\r
843 \r
844 <h3><a name="error-feedback-printing"></a>16.3 Printing Messages</h3>\r
845 <kbd>$msg->print{Errors|Warnings|Infos|Feedbacks|Helps|All}($optional);</kbd><br/><br/>\r
846 \r
847 <p>Each will dump all the corresponding tracked messages of that type onto\r
848 the page at that given line with appropriate graphics defined by its templates file.<p>\r
849 \r
850 <p><kbd>printAll()</kbd> allows all Messages of all types to be dumped immediately.</p>\r
851 \r
852 <p>One thing to remember is that once a type of Message is printed\r
853 all tracked data relating to that type are gone. There is no need to worry\r
854 about purging messages from <kbd>$_SESSION</kbd>. The class manages this.</p>\r
855 \r
856 <p><b>Notice</b> <kbd>$optional</kbd> as the argument to this function. This allows you\r
857 to shortcut the process of adding and printing Message's in one go. For example,\r
858 suppose you want to add a Message and print it right away. Thus, you pass as an\r
859 argument ANY argument that you would pass when adding a Message of that type. \r
860 Essentially, two lines of code are accomplished in one.</p>\r
861 <dt>Example:</dt>\r
862 <pre class="code">\r
863         $msg->addError('MAX_ATTEMPTS');\r
864         $msg->printErrors();\r
865         \r
866         can also be accomplished as:\r
867         \r
868         $msg->printErrors('MAX_ATTEMPTS');\r
869 </pre>\r
870 \r
871 <h4><a name="Boolean"></a>Printing String inside Feedback style box</h4>\r
872 \r
873 <kbd>printNoLookup($str);</kbd><br/><br/>\r
874 \r
875 <p>Print <kbd>$str</kbd> inside a Feedback Message type style box. Performs\r
876 no dialog with <kbd>$_SESSION</kbd> or any language mappings in the language_text DB table.\r
877 Strictly used in <kbd>/resources/links/index.php</kbd> for compatibility.\r
878 </p>\r
879 \r
880 <h4><a name="Boolean"></a>Checking for existance of specific Message type</h4>\r
881 \r
882 <kbd>contains{Errors|Warnings|Feedbacks|Helps|Infos}();</kbd><br/><br/>\r
883 \r
884 <p>Returns true if the type of Message is being tracked and contains\r
885 some kind of data. Useful for branching conditions in knowning\r
886 when to print a Message or not. Otherwise returns false.</p>\r
887 \r
888 <h4><a name="Boolean"></a>Manually Deleting a specific Message from storage</h4>\r
889 \r
890 <kbd>delete{Error|Warning|Feedback|Help|Info}($codcuee);</kbd><br/><br/>\r
891 \r
892 <p>Will delete anything related to <kbd>$code</kbd> from <kbd>$_SESSION</kbd></p>\r
893 <dt>Example:</dt>\r
894 <pre class="code">\r
895         $msg->deleteFeedback('CANCELLED');\r
896 </pre>\r
897 \r
898 <h4><a name="Example"></a>Example Code</h4>\r
899         \r
900 <pre class="code">\r
901 \r
902 ...\r
903 \r
904 require_once(AT_INCLUDE_PATH . '/classes/Message/Message.class.php');\r
905 \r
906 global $savant;\r
907 \r
908 $msg = new Message($savant); \r
909 \r
910 $msg->addError('FORUM_NOT_FOUND');\r
911 $msg->addWarning('SAVE_YOUR_WORK');\r
912 $msg->addInfo('NO_SEARCH_RESULTS');\r
913 $msg->addFeedback('FORUM_ADDED');\r
914 \r
915 /* State of relevant section of $_SESSION at this point \r
916 [message] => Array\r
917         (\r
918             [error] => Array\r
919                 (\r
920                     [AT_ERROR_FORUM_NOT_FOUND] => AT_ERROR_FORUM_NOT_FOUND\r
921                 )\r
922 \r
923             [warning] => Array\r
924                 (\r
925                     [AT_WARNING_SAVE_YOUR_WORK] => AT_WARNING_SAVE_YOUR_WORK\r
926                 )\r
927 \r
928             [info] => Array\r
929                 (\r
930                     [AT_INFOS_NO_SEARCH_RESULTS] => AT_INFOS_NO_SEARCH_RESULTS\r
931                 )\r
932 \r
933             [feedback] => Array\r
934                 (\r
935                     [AT_FEEDBACK_FORUM_ADDED] => AT_FEEDBACK_FORUM_ADDED\r
936                 )\r
937 \r
938         )\r
939 */\r
940 \r
941 // Now print them\r
942 $msg->printErrors();\r
943 $msg->printWarnings();\r
944 $msg->printInfos();\r
945 $msg->printFeedbacks();\r
946 \r
947 /* State of relevant section of $_SESSION at this point\r
948  [message] => Array\r
949         (\r
950         )\r
951  */\r
952 \r
953 // Let's add an array of arguments\r
954 $feedback=array('FORUM_ADDED', 'ac_access_groups');\r
955 $msg->addFeedback($feedback);\r
956 \r
957 // Before we print lets another another one to the same code\r
958 $feedback2=array('FORUM_ADDED', 'about_atutor_help_text');\r
959 $msg->addFeedback($feedback2);\r
960 \r
961 $msg->addHelp('DEMO_HELP2');\r
962 \r
963 $help=array('DEMO_HELP2', $_my_uri);\r
964 $msg->addHelp($help);\r
965 \r
966 $help2=array('ADD_TEST', $_my_uri);\r
967 $msg->addHelp($help2);\r
968 \r
969 // No need to url_encode the code\r
970 $filename = 'archive.zip';\r
971 $f = array('FILE_UPLOADED_ZIP', $file_name);\r
972 $msg->addFeedback($f);\r
973 \r
974 /* State of relevant section of $_SESSION at this point. Notice the second addFeddback call above\r
975  * had its arguments appended\r
976 \r
977  [message] => Array\r
978         (\r
979             [feedback] => Array\r
980                 (\r
981                     [AT_FEEDBACK_FORUM_ADDED] => Array\r
982                         (\r
983                             [0] => AT_FEEDBACK_FORUM_ADDED\r
984                             [1] => ac_access_groups\r
985                             [2] => about_atutor_help_text\r
986                         )\r
987                         \r
988                     [AT_FEEDBACK_FILE_UPLOADED_ZIP] => Array\r
989                         (\r
990                             [0] => AT_FEEDBACK_FILE_UPLOADED_ZIP\r
991                             [1] => archive.zip\r
992                         )\r
993 \r
994                 )\r
995 \r
996             [help] => Array\r
997                 (\r
998                     [AT_HELP_DEMO_HELP2] => Array\r
999                         (\r
1000                             [0] => AT_HELP_DEMO_HELP2\r
1001                             [1] => /~Jay/docs/index.php?\r
1002                         )\r
1003 \r
1004                     [AT_HELP_ADD_TEST] => Array\r
1005                         (\r
1006                             [0] => AT_HELP_ADD_TEST\r
1007                             [1] => /~Jay/docs/index.php?\r
1008                         )\r
1009 \r
1010                 )\r
1011 \r
1012         }\r
1013 */\r
1014 \r
1015 $msg->printAll();\r
1016 \r
1017 /* State of relevant section of $_SESSION at this point\r
1018  [message] => Array\r
1019         (\r
1020         )\r
1021  */\r
1022  \r
1023  ...\r
1024 </pre>\r
1025 <a href="#top" class="top">top</a>\r
1026 <h2><a name="mbstring-support"></a>16.4 UTF-8 and Multibyte language</h2>\r
1027         <p>As of ATutor 1.6, string parsing is done with multibtyle string functions, either the <kbd>mbstring</kbd> function in PHP itself, or the multibyte string functions in the UTF-8 library included with ATutor. By default ATutor will attempt to use the PHP <kbd>mbstring</kbd> functions, and will fall back on the ATutor library if this fails. In order to support both methods of string processing, a set of custom string parsing functions have been created. The only time the ATutor functions will be used is when the mbstring check during the installation or upgrade process has been disabled. The functions mirror the standard string parsing function in PHP, but with the <kbd>$</kbd> prepended. So, where ever you would normally use a PHP function like <kbd>substr() </kbd>, instead use <kbd>$substr()</kbd>. These functions are located in the vital.inc.php\r
1028 <pre class="code">\r
1029  if (extension_loaded('mbstring')){\r
1030          $strtolower = 'mb_strtolower';\r
1031          $strtoupper = 'mb_strtoupper';\r
1032          $substr = 'mb_substr';\r
1033          $strpos = 'mb_strpos';\r
1034          $strrpos = 'mb_strrpos';\r
1035          $strlen = 'mb_strlen';\r
1036  } else {\r
1037          $strtolower = 'utf8_stringtolower';\r
1038          $strtoupper = 'utf8_stringtoupper';\r
1039          $substr = 'utf8_substr';\r
1040          $strpos = 'utf8_strpos';\r
1041          $strrpos = 'utf8_strrpos';\r
1042          $strlen = 'utf8_strlen';\r
1043  }\r
1044 \r
1045 </pre>\r
1046 \r
1047 \r
1048         <h3>String functions </h3>\r
1049                 <p><ul>\r
1050                         <li><kbd>string <strong>$strtolower</strong>(string $str)</kbd> -- UTF-8 aware strtolower function.  Make a string lowercase </li>\r
1051                         <li><kbd>string <strong>$strtoupper</strong>(string $str)</kbd> -- UTF-8 aware strtolower function.  Make a string uppercase </li>\r
1052                         <li><kbd>int <strong>$strpos</strong>(string $haystack  , string $needle  )</kbd> -- UTF-8 aware strpos function.  Find position of first occurrence of string in a string </li>\r
1053                         <li><kbd>int <strong>$strrpos</strong>(string $haystack , string $needle  )</kbd> -- UTF-8 aware strrpos function.  Find position of last occurrence of a string in a string </li>\r
1054                         <li><kbd>int <strong>$strlen</strong>(string $str)</kbd> -- UTF-8 aware strlen function.  Get string length </li>\r
1055                         <li><kbd>string <strong>validate_length</strong>(string $input, int $len, int $forDisplay)</kbd> -- Checks if the input data has exceeded the database perferred length, if so, the input will be truncated and returned. </li>\r
1056                 </ul></p>\r
1057 \r
1058                 <h4>Description</h4>\r
1059                         <p>Starting from 1.6, the above string functions will replace the original string functions when dealing with strings in order to adapt the utf-8 environment.</p>\r
1060 \r
1061                 <h4>Location</h4>\r
1062                         <p><kbd>`include/vitals.inc.php`</kbd></p>\r
1063                 \r
1064                 <h4>Example 1</h4>\r
1065                 <p>To alter a text to lowercase:\r
1066                 <pre class="code">\r
1067                 $str = 'Αρχαίο Πνεύμα';\r
1068                 echo $strtolower($str);\r
1069                 </pre></p>\r
1070 \r
1071                 <h4>Example 2</h4>\r
1072                 <p>To alter a text to uppercase:\r
1073                 <pre class="code">\r
1074                 $str = 'Αρχαίο Πνεύμα';\r
1075                 echo $strtoupper($str);\r
1076                 </pre></p>\r
1077 \r
1078                 <h4>Example 3</h4>\r
1079                 <p>To find the middle character of a string:\r
1080                 <pre class="code">\r
1081                 $str = 'Αρχαίο Πνεύμα';\r
1082                 $mid = $strlen;\r
1083                 echo $strpos($mid, $str);\r
1084                 </pre></p>\r
1085 \r
1086                 <h4>Example 4</h4>\r
1087                 <p>To check if the string has the appropriate length:\r
1088                 <pre class="code">\r
1089                 $str = 'Αρχαίο Πνεύμα';\r
1090                 $title = validate_length($str, 40);\r
1091                 //now the title is safe to insert into the db\r
1092                 </pre></p>\r
1093 \r
1094 <a href="#top" class="top">top</a>\r
1095 <h2><a name="useful-variables"></a>17. Useful Variables</h2>\r
1096         <p>Most of the variables documented here are required for most pages to function correctly. <kbd>constant</kbd> variables, although not explicitly declared as constants, should be considered as such, and not altered.</p>\r
1097 \r
1098         <h3><a name="var-db"></a>17.1 $db</h3>\r
1099                 <h4>Description</h4>\r
1100                         <p><kbd>constant resource $db</kbd></p>\r
1101 \r
1102                         <p><kbd>$db</kbd> is the main database handler. Use it to connect to the ATutor database.</p>\r
1103 \r
1104                 <h4>Location</h4>\r
1105                         <p><kbd>`include/vitals.inc.php`</kbd></p>\r
1106 \r
1107         <h3><a name="var-addslashes"></a>17.2 $addslashes</h3>\r
1108                 <p>See <a href="#fn-addslashes"><kbd>$addslashes()</kbd></a>.</p>\r
1109 \r
1110         <h3><a name="var-base_href"></a>17.3 $_base_href</h3>\r
1111                 <h4>Description</h4>\r
1112                 <p><kbd>constant string $_base_href</kbd></p>\r
1113                 <p>The full URL to the base href of the current page, an equivalence of the "href" attribute value in the page html &lt;base&gt; tag. Supports both regular and SSL protocols. Example: <kbd>http://myserver.org/files/ATutor/</kbd>.</p>\r
1114 \r
1115                 <h4>Location</h4>\r
1116                         <p><kbd>`include/lib/constants.inc.php`</kbd></p>\r
1117 \r
1118         <h3><a name="var-base_path"></a>17.4 $_base_path</h3>\r
1119                 <h4>Description</h4>\r
1120                 <p><kbd>constant string $_base_path</kbd></p>\r
1121                 <p>Extracted from $_base_href, the full absolute base path of the current page. Example: <kbd>/files/ATutor/</kbd>.</p>\r
1122 \r
1123                 <h4>Location</h4>\r
1124                         <p><kbd>`include/lib/constants.inc.php`</kbd></p>\r
1125 \r
1126         <h3><a name="var-user_location"></a>17.5 $_user_location</h3>\r
1127                 <h4>Description</h4>\r
1128                 <p><kbd>constant $_user_location</kbd></p>\r
1129                 <p><kbd>$_user_location</kbd> can be one of five values: <kbd>`public`</kbd>, <kbd>`admin`</kbd>, <kbd>`users`</kbd>, <kbd>`prog`</kbd> or <em>empty</em>. This variable must be set <em>before</em> requiring <kbd>`vitals.inc.php`</kbd>, and specifies what kind of general user authentication the page declaring it needs.</p>\r
1130 \r
1131                 <p><kbd>`public`</kbd> pages can be viewed by any user, signed-in as a member or not. <kbd>`admin`</kbd> pages (those in the <kbd>`admin/`</kbd> directory) can only be viewed by the administrator. <kbd>`users`</kbd> pages (those in the <kbd>`users/`</kbd> directory) can only be viewed by logged in members. If <kbd>$_user_location</kbd> is empty, it is assumed the page can only be accessed when a user is signed-in and viewing a course. <kbd>`prog`</kbd> is reserved for the pop-up window displaying the progress bar.</p>\r
1132 \r
1133                 <p>This variable was added as a way of specifying which template to use (public, admin, or member). Its role as a way of authenticating is not thoroughly established.</p>\r
1134 \r
1135                 <h4>Location</h4>\r
1136                         <p><em>Declared on every page that is directly accessible.</em></p>\r
1137 \r
1138 \r
1139         <h3><a name="var-rel_url"></a>17.6 $_rel_url</h3>\r
1140                 <h4>Description</h4>\r
1141                 <p><kbd>constant string $_rel_url</kbd></p>\r
1142                 <p>The absolute path and file name relative to ATutor's base installation. If ATutor was installed in <kbd>http://myserver.org/files/ATutor/</kbd>, the <kbd>$_rel_url</kbd> of the Site-Map page, for example, would evaluate to <kbd>/tools/sitemap/index.php</kbd>.</p>\r
1143 \r
1144                 <p>This URL will always be the same for a given page, regardless of the location or path of an installation. This variable was added as a way of standardising the <kbd>`page`</kbd> value in the <kbd>`lang_base_pages`</kbd> table.</p>\r
1145 \r
1146                 <h4>Location</h4>\r
1147                         <p><kbd>`include/lib/constants.inc.php`</kbd></p>\r
1148 \r
1149         <h3><a name="var-my_uri"></a>17.7 $_my_uri</h3>\r
1150                 <h4>Description</h4>\r
1151                 <p><kbd>constant string $_my_uri</kbd></p>\r
1152                 <p>The full path and file name to the current page in a format that is ready to accept additional URL arguments. The argument separator will be defined as <kbd><a href="#const-sep">SEP</a></kbd>.  For example, if the current URL is <kbd>http://myserver.org/index.php?cid=806;disable=PREF_MENU;menu_jump=2</kbd>, then <kbd>$_my_uri</kbd> would be <kbd>/index.php?cid=806;</kbd>.</p>\r
1153 \r
1154                 <p>So, <kbd>$_my_uri</kbd> is the URL to the current page without the temporary switch arguments. The following URL arguments are removed:\r
1155 \r
1156                 <kbd>enable</kbd>, <kbd>disable</kbd>, <kbd>expand</kbd>, <kbd>menu_jump</kbd>, <kbd>g</kbd>, <kbd>collapse</kbd>, <kbd>f</kbd>, <kbd>e</kbd>, <kbd>save</kbd>, and <kbd>lang</kbd>.</p>\r
1157                 \r
1158                 <h4>Location</h4>\r
1159                         <p><kbd>`include/lib/vitals.inc.php`</kbd></p>\r
1160 \r
1161         <h3><a name="var-content_manager"></a>17.8 $contentManager</h3>\r
1162                 <h4>Description</h4>\r
1163                 <p><kbd>constant ContentManager $contentManager</kbd></p>\r
1164                 <p>The <kbd>$contentManager</kbd> object provides access to methods for operating on content. All access to the <kbd>`content`</kbd> table should be done through this object.</p>\r
1165 \r
1166                 <h4>Locations</h4>\r
1167                         <p><kbd>`include/vitals.inc.php`</kbd><br />\r
1168                         <kbd>`include/classes/ContentManager.class.php`</kbd></p>\r
1169 \r
1170         <h3><a name="var-section"></a>17.9 $_section</h3>\r
1171                 <p><strong>Deprecated in ATutor 1.5</strong></p>\r
1172                 <h4>Description</h4>\r
1173                 <p><kbd>array $_section</kbd></p>\r
1174 \r
1175                 <p>This variable is a two-dimensional <kbd>array</kbd> used to display a page's breadcrumbs. The first index identifies the page starting from <kbd>0</kbd> such that <kbd>$_section[0]</kbd> defines the first page in the hierarchy, <kbd>$_section[1]</kbd> the second, and so on. The second index is used to assign that page's properties, defined as follows: index <kbd>0</kbd> is the page title, and index <kbd>1</kbd> is the URL. This variable must be defined <em>before</em> the <kbd>`header.inc.php</kbd> file is required.</p>\r
1176                 \r
1177                 <p>The URL for the last page (i.e.. the current page) is optional.</p>\r
1178 \r
1179                 <h4>Example 1</h4>\r
1180                         <p>To assign the path to the site-map:\r
1181 <pre class="code">\r
1182 // the Site-Map is a sub-page of the Tools page, hence we define the path:\r
1183 \r
1184 $_section[0][0] = _AT('tools');              // the Tools' page title\r
1185 $_section[0][1] = 'tools/';                  // the Tools' page URL\r
1186 $_section[1][0] = _AT('sitemap');            // the Site-Map's page title\r
1187 $_section[1][1] = 'tools/sitemap/index.php'; // the Site-Map's page URL\r
1188 </pre></p>\r
1189 \r
1190                 <h4>Location</h4>\r
1191                         <p><em>Declared on every page that is directly accessible.</em></p>\r
1192 \r
1193                 \r
1194 <a href="#top" class="top">top</a>\r
1195 <h2><a name="useful-functions"></a>18. Useful Functions</h2>\r
1196         <p>The functions listed below provide vital functionality for ATutor pages. Developers will most likely end up using most, if not all, of the functions below. Please review the <a href="#function-definitions">Function Definitions (Prototypes)</a> section for an explanation of the syntax being used. Additional javadoc comments can be found with each function's definition.</p>\r
1197 \r
1198         <h3><a name="fn-authenticate"></a>18.1 authenticate()</h3>\r
1199                 <p><kbd>authenticate()</kbd> -- Authenticates the current user against a specified privilege.</p>\r
1200 \r
1201                 <h4>Description</h4>\r
1202                         <p><kbd>mixed <strong>authenticate</strong>( integer $privilege [, boolean $check]</em> )</kbd></p>\r
1203 \r
1204                         <p>Authenticates the current user against <kbd>$privilege</kbd>. If <kbd>$check</kbd> is <kbd>AT_PRIV_RETURN</kbd> then the function will return the status of the authentication with <kbd>TRUE</kbd> meaning the user has been successfully authenticated or <kbd>FALSE</kbd> otherwise. With <kbd>$check</kbd> set to <kbd>FALSE</kbd> (default), the function will call <kbd>exit</kbd> to abort the script if the user cannot be authenticated and return <kbd>TRUE</kbd> otherwise.</p>\r
1205 \r
1206                         <p>The instructor user will always return <kbd>TRUE</kbd>.</p>\r
1207 \r
1208                         <p><kbd>$privilege</kbd> is set to one of the constants defined in <kbd>`include/lib/constants.inc.php`</kbd>.</p>\r
1209 \r
1210                         <p>Please use only <kbd>AT_PRIV_RETURN</kbd> or <kbd>FALSE</kbd> as possible values for <kbd>$check</kbd> as additional options may be added and the value of the constant changed.</p>\r
1211 \r
1212                 <h4>Location</h4>\r
1213                         <p><kbd>`include/vitals.inc.php`</kbd></p>\r
1214 \r
1215                 <h4>Example 1</h4>\r
1216                         <p>To authenticate an entire page using the announcements management privilege:\r
1217 <pre class="code">\r
1218 define('AT_INCLUDE_PATH', '../include/');\r
1219 require (AT_INCLUDE_PATH . 'vitals.inc.php');\r
1220 /**\r
1221 /* exit if the user cannot be authenticated\r
1222  * otherwise continue loading the page.\r
1223  */\r
1224 authenticate(AT_PRIV_ANNOUNCEMENTS);\r
1225 </pre></p>\r
1226                 <h4>Example 2</h4>\r
1227                         <p>To authenticate a block of code using the forums management privilege:\r
1228 <pre class="code">\r
1229 if (authenticate(AT_PRIV_FORUMS, AT_PRIV_RETURN)) {\r
1230     // ... this user has been authenticated\r
1231 }\r
1232 </pre></p>\r
1233 \r
1234         <h3><a name="fn-at"></a>18.2 _AT()</h3>\r
1235                 <p><kbd>_AT()</kbd> -- Returns translated terms.</p>\r
1236 \r
1237                 <h4>Description</h4>\r
1238                         <p><kbd>string <strong>_AT</strong>( string $term [, string $argument1 [, string $argument2 ...]] )</kbd></p>\r
1239                         \r
1240                         <p>This function returns a translated version of <kbd>$term</kbd> based on the user's current language preference as defined in <kbd>$_SESSION[lang]</kbd>. If <kbd>$term</kbd> cannot be found in the language database, it will return <kbd>`[ $term ]`</kbd> to signify that it was not found.</p>\r
1241 \r
1242                         <p>Terms may require supplements in the form of additional arguments (see example 2). A term may require zero or more arguments. If a <kbd>term</kbd> requires arguments, then they must all be provided; no argument can be left out.</p>\r
1243 \r
1244                 <h4>Location</h4>\r
1245                         <p><kbd>`include/lib/output.inc.php`</kbd></p>\r
1246 \r
1247                 <h4>Example 1</h4>\r
1248                         <p>Printing a single term:\r
1249 <pre class="code">\r
1250 /* echo a translated version of the 'tools' string.\r
1251  * i.e. 'Tools' in English, 'Outils' in French, etc..\r
1252  */\r
1253  $_SESSION['lang'] = 'en';\r
1254 echo '&lt;h2>' . _AT('tools') . '&lt;/h2>';\r
1255 \r
1256  $_SESSION['lang'] = 'fr';\r
1257 echo '&lt;h2>' . _AT('tools') . '&lt;/h2>';\r
1258 </pre></p>\r
1259 \r
1260                         <p>Result:\r
1261 <pre class="code">&lt;h2>Tools&lt;/h2>\r
1262 &lt;h2>Outils&lt;/h2>\r
1263 </pre></p>\r
1264 \r
1265                 <h4>Example 2</h4>\r
1266                         <p>Printing a phrase with arguments:\r
1267 <pre class="code">\r
1268 $username = 'Jon';\r
1269 echo _AT('welcome_message', $username);\r
1270 </pre></p>\r
1271                         <p>Result:\r
1272 <pre class="code">Hello, Jon. Welcome back.</pre></p>\r
1273 \r
1274 \r
1275         <h3><a name="fn-at_print"></a>18.3 AT_print()</h3>\r
1276                 <p><kbd>AT_print()</kbd> -- Transforms and formats user data for printing.</p>\r
1277 \r
1278                 <h4>Description</h4>\r
1279                         <p><kbd>string <strong>AT_print</strong>( string $input, string $field_name [, boolean $runtime_html] )</kbd></p>\r
1280 \r
1281                         <p>This function returns a transformed version of <kbd>$input</kbd> based on the rules specified by <kbd>$field_name</kbd>. <kbd>$input</kbd> is assumed to originate from the database, but it may be generalised in the future.</p>\r
1282 \r
1283                         <p><kbd>$field_name</kbd> is the unique name of the <kbd>$input</kbd> field in the form of <kbd><em>table_name</em>.<em>field_name</em></kbd>. The formatting options for the given field are defined in <kbd>`include/lib/constants.inc.php`</kbd>. If <kbd>$field_name</kbd> is not a valid option as defined in the constants file then the function will return <kbd>$input</kbd> unchanged.</p>\r
1284 \r
1285                         <p>The boolean <kbd>$runtime_html</kbd> is used by fields which have an optional HTML formatting field. <kbd>$runtime_html</kbd> should be the associated HTML formatting field for that data. If set to <kbd>FALSE</kbd> then HTML elements will be escaped from <kbd>$input</kbd> and new line characters converted to <kbd>&lt;br /></kbd>s.</p>\r
1286 \r
1287                         <p>No data from the database should be printed without passing it through this function first.</p>\r
1288 \r
1289                 <h4>Location</h4>\r
1290                         <p><kbd>`include/lib/output.inc.php`</kbd></p>\r
1291 \r
1292                 <h4>Example 1</h4>\r
1293                 <p>Printing a field where HTML is not allowed:\r
1294 <pre class="code">\r
1295 $username = 'my_name&lt;b>_is';\r
1296 $value    = AT_print($username, 'members.login'); // escape the '&lt;b>' tag\r
1297 echo $value</pre></p>\r
1298 \r
1299                 <p>Result:\r
1300 <pre class="code">my_name&lt;b>_is</pre></p>\r
1301 \r
1302 \r
1303         <h3><a name="fn-at_date"></a>18.4 AT_date()</h3>\r
1304                 <p><kbd>AT_date()</kbd> -- Returns a localised version of a date.</p>\r
1305 \r
1306                 <h4>Description</h4>\r
1307                         <p><kbd>string <strong>AT_date</strong>( [string $format [, integer $timestamp [, integer $format_type]]] )</kbd></p>\r
1308 \r
1309                         <p>This function returns the <kbd>string</kbd> representation of the given <kbd>$timestamp</kbd> as transformed by <kbd>$format</kbd>. Uses the same options as PHP's <kbd><a href="http://www.php.net/date" title="PHP.net - date()">date()</a></kbd> function, but requires a <kbd>%</kbd> in front of each argument. If <kbd>$timestamp</kbd> is not specified, then the current time will be used.</p>\r
1310 \r
1311                         <p><kbd>$format_type</kbd> specifies the type of time stamp being provided. Available types are defined in <kbd>`include/lib/constants.inc.php`</kbd>. Possible options are:\r
1312                                 <dl>\r
1313                                         <dt><kbd>AT_DATE_MYSQL_DATETIME</kbd></dt>\r
1314                                         <dd>The default. Format <kbd>YYYY-MM-DD HH:MM:SS</kbd>.</dd>\r
1315 \r
1316                                         <dt><kbd>AT_DATE_MYSQL_TIMESTAMP_14</kbd></dt>\r
1317                                         <dd>Format <kbd>YYYYMMDDHHMMSS</kbd>.</dd>\r
1318 \r
1319                                         <dt><kbd>AT_DATE_UNIX_TIMESTAMP</kbd></dt>\r
1320                                         <dd>A regular UNIX time stamp; seconds since epoch.</dd>\r
1321 \r
1322                                         <dt><kbd>AT_DATE_INDEX_VALUE</kbd></dt>\r
1323                                         <dd>A special case specifying that only the single value of <kbd>$format</kbd> should be returned. The index into a specified date <kbd>array</kbd>. Only available for the following date options: <kbd>%D</kbd>, <kbd>%l</kbd>, <kbd>%F</kbd>, <kbd>%M</kbd>.</dd>\r
1324                                 </dl>\r
1325                         </p>\r
1326 \r
1327                         <p>The following arguments are language dependent:\r
1328                                 <dl>\r
1329                                         <dt><kbd>%D</kbd></dt>\r
1330                                         <dd>A three-letter textual representation of a day, Mon through Sun</dd>\r
1331 \r
1332                                         <dt><kbd>%F</kbd></dt>\r
1333                                         <dd>A full textual representation of a month, January through December</dd>\r
1334 \r
1335                                         <dt><kbd>%l</kbd> (lowercase 'L')</kbd></dt>\r
1336                                         <dd>A full textual representation of the day of the week, Monday through Sunday</dd>\r
1337 \r
1338                                         <dt><kbd>%M</kbd></dt>\r
1339                                         <dd>A three-letter textual representation of a month, Jan through Dec</dd>\r
1340                                 </dl></p>\r
1341         \r
1342                         <p>The following arguments are <em>not yet</em> supported to be language dependent, but may be in the future:\r
1343                                 <dl>\r
1344                                         <dt><kbd>%S</kbd></dt>\r
1345                                         <dd>English ordinal suffix for the day of the month, 2 characters st, nd, rd or th. Works well with <kbd>%j</kbd></dd>\r
1346 \r
1347                                         <dt><kbd>%a</kbd></dt>\r
1348                                         <dd>Lowercase Ante meridiem and Post meridiem am or pm</dd>\r
1349 \r
1350                                         <dt><kbd>%A</kbd></dt>\r
1351                                         <dd>Uppercase Ante meridiem and Post meridiem AM or PM</dd>\r
1352                                 </dl></p>\r
1353 \r
1354                         <p>In most (soon to be all) cases, <kbd>$format</kbd> will be specified using a call to <kbd>_AT()</kbd> to retrieve the correct date format for that language. See Example 2 below.</p>\r
1355 \r
1356                 <h4>Location</h4>\r
1357                         <p><kbd>`include/lib/output.inc.php`</kbd></p>\r
1358 \r
1359                 <h4>Example 1</h4>\r
1360                         <p>Returning a specified date using a UNIX time stamp:\r
1361 <pre class="code">\r
1362 $time = mktime(0, 0, 0, 7, 14, 2004);\r
1363 echo AT_Date('%l %F %j, %Y', $time, AT_DATE_UNIX_TIMESTAMP);\r
1364 </pre></p>\r
1365 \r
1366                         <p>Result:\r
1367 <pre class="code">Wednesday July 14, 2004</pre></p>\r
1368 \r
1369                 <h4>Example 2</h4>\r
1370                         <p>Returning a specified date using a UNIX time stamp that is also language dependent:\r
1371 <pre class="code">\r
1372 $time = mktime(0, 0, 0, 7, 14, 2004);\r
1373 \r
1374 $_SESSION['lang'] = 'en';\r
1375 echo AT_Date(_AT('announcement_date_format'), $time, AT_DATE_UNIX_TIMESTAMP);\r
1376 \r
1377 echo '&lt;br />';\r
1378 $_SESSION['lang'] = 'fr';\r
1379 echo AT_Date(_AT('announcement_date_format'), $time, AT_DATE_UNIX_TIMESTAMP);\r
1380 </pre></p>\r
1381 \r
1382                         <p>Result:\r
1383 <pre class="code">Wednesday July 14, 2004\r
1384 mercredi, 14 juillet 2004</pre></p>\r
1385 \r
1386                 <h4>Example 3</h4>\r
1387                 <p>Returning a single month name:\r
1388 <pre class="code">\r
1389 $_SESSION['lang'] = 'fr';\r
1390 The second month in French is: &lt;?php echo AT_date('%F', 2, AT_DATE_INDEX_VALUE) ?>\r
1391 </pre></p>\r
1392 \r
1393                 <p>Result:\r
1394 <pre class="code">\r
1395 The second month in French is: f憝rier\r
1396 </pre></p>\r
1397 \r
1398         <h3><a name="fn-addslashes"></a>18.5 $addslashes()</h3>\r
1399                 <p><kbd>$addslashes()</kbd> -- Quotes a string with slashes.</p>\r
1400 \r
1401                 <h4>Description</h4>\r
1402                         <p><kbd>string <strong>$addslashes</strong>( string $str )</kbd></p>\r
1403 \r
1404                         <p>If <kbd>get_magic_quotes_gpc</kbd> is disabled, then this variable function maps onto <kbd><a href="http://www.php.net/addslashes" title="PHP.net - addslashes()">addslashes()</a></kbd>, otherwise it maps onto <kbd>my_add_null_slashes()</kbd> which simply returns the input <kbd>$str</kbd> unchanged.</p>\r
1405 \r
1406                 <h4>Location</h4>\r
1407                         <p><kbd>`include/vitals.inc.php`</kbd></p>\r
1408 \r
1409                 <h4>Example 1</h4>\r
1410                         <p>With <kbd>magic_quotes_gpc</kbd> enabled:\r
1411 <pre class="code">\r
1412 $str = "What's going on?";\r
1413 \r
1414 // prints magic_quotes_gpc: 1\r
1415 echo 'magic_quotes_gpc: ' . get_magic_quotes_gpc();\r
1416 \r
1417 // maps to my_add_null_slashes(). prints What\'s going on? [correct]\r
1418 echo $addslashes($str);\r
1419 \r
1420 // prints What\\\'s going on? [wrong]\r
1421 echo addslashes($str);\r
1422 </pre></p>\r
1423 \r
1424                 <h4>Example 2</h4>\r
1425                         <p>With <kbd>magic_quotes_gpc</kbd> disabled:\r
1426 <pre class="code">\r
1427 $str = "What's going on?";\r
1428 \r
1429 // prints magic_quotes_gpc: 0\r
1430 echo 'magic_quotes_gpc: ' . get_magic_quotes_gpc();\r
1431 \r
1432 // maps to addslashes(). prints What\'s going on? [correct]\r
1433 echo $addslashes($str);\r
1434 \r
1435 // prints What\'s going on? [correct]\r
1436 echo addslashes($str);\r
1437 </pre></p>\r
1438 \r
1439 \r
1440         <h3><a name="fn-debug"></a>18.6 debug()</h3>\r
1441                 <p><kbd>debug()</kbd> -- Outputs a variable.</p>\r
1442 \r
1443                 <h4>Description</h4>\r
1444                         <p><kbd>void <strong>debug</strong>( mixed $var [, string $title] )</kbd></p>\r
1445 \r
1446                         <p>This function is used for printing variables for debugging. <kbd>$var</kbd> can be of any type. The output is nicely formatted and easy to read. <kbd>debug()</kbd> will not output anything if the constant <kbd><a href="#const-devel">AT_DEVEL</a></kbd> evaluates to <kbd>FALSE</kbd>.</p>\r
1447 \r
1448                         <p><kbd>$title</kbd> is available to label the debugging box for distinguishing it from other debugging boxes on the same page.</p>\r
1449 \r
1450                 <h4>Location</h4>\r
1451                         <p><kbd>`include/vitals.inc.php`</kbd></p>\r
1452 \r
1453                 <h4>Example 1</h4>\r
1454                 <p>Viewing the contents of an <kbd>array</kbd>:\r
1455 <pre class="code">\r
1456 $my_array = array('apple' => 'green', 4 => 'something');\r
1457 debug($my_array, 'my_array');\r
1458 </pre></p>\r
1459 \r
1460                 <p>Result:\r
1461 <pre class="code">\r
1462     <b>my_array</b>\r
1463 Array\r
1464 (\r
1465     [apple] => green\r
1466     [4] => something\r
1467 )\r
1468 </pre></p>\r
1469 \r
1470         <h3><a name="fn-get_login"></a>18.7 get_login()</h3>\r
1471                 <p><kbd>get_login()</kbd> -- Returns the login name of a member.</p>\r
1472 \r
1473                 <h4>Description</h4>\r
1474                         <p><kbd>string <strong>get_login</strong>( integer $id )</kbd></p>\r
1475 \r
1476                         <p>Returns the login name of the member whose ID is <kbd>$id</kbd>. There is no error handling.</p>\r
1477                 \r
1478                 <h4>Location</h4>\r
1479                         <p><kbd>`include/vitals.inc.php`</kbd></p>\r
1480 \r
1481 \r
1482         <h3><a name="fn-urlencode_feedback"></a>18.8 urlencode_feedback()</h3>\r
1483                 <p><kbd>urlencode_feedback()</kbd> -- Encodes a feedback code.</p>\r
1484 \r
1485                 <h4>Description</h4>\r
1486                         <p><kbd>mixed <strong>urlencode_feedback</strong>( mixed $f )</kbd></p>\r
1487 \r
1488                         <p>This function returns a URL safe encoding of a feedback code. Its purpose is to encode the feedback into the URL so that the page being redirected to will then output the feedback. <kbd>$f</kbd> may be an <kbd>array</kbd> of feedback codes, where additionally, each feedback code may be an array consisting of supplementary arguments. If <kbd>$f</kbd> is an <kbd>array</kbd> then the return value will be its <kbd>string</kbd> representation, otherwise the function will return <kbd>$f</kbd> unchanged.</p>\r
1489 \r
1490                         <p>The way feedback is implemented may change in the future, so it is best to use this function even if the feedback code is not an <kbd>array</kbd>.</p>\r
1491 \r
1492                 <h4>Location</h4>\r
1493                         <p><kbd>`include/vitals.inc.php`</kbd></p>\r
1494                 \r
1495                 <h4>Example 1</h4>\r
1496                 <p>To encode a feedback array:\r
1497 <pre class="code">\r
1498 $f[] = array(AT_FEEDBACK_FILE_UPLOADED_ZIP, $file_name);\r
1499 \r
1500 header('Location: file_manager.php?f='.urlencode_feedback($f));\r
1501 exit;\r
1502 </pre></p>\r
1503 \r
1504         <h3><a name="fn-url_rewrite"></a>18.9 url_rewrite()</h3>\r
1505                 <p><kbd>url_rewrite()</kbd> -- Change an url to a pretty url.</p>\r
1506 \r
1507                 <h4>Description</h4>\r
1508                         <p><kbd>string <strong>url_rewrite</strong>( string $url, boolean $is_rewriting_header, boolean $force)</kbd></p>\r
1509 \r
1510                         <dt><kbd>$url</kbd></dt>\r
1511                         <dd><p>the Url should be a relative link to the file.</p></dd>\r
1512 \r
1513                         <dt><kbd>$is_rewriting_header</kbd></dt>\r
1514                         <dd><p>Determine if url_rewrite is rewriting a header (location: ..) path or not.  Available values are AT_PRETTY_URL_IS_HEADER, AT_PRETTY_URL_NOT_HEADER(default).  Use AT_PRETTY_URL_IS_HEADER if url_rewrite is being called inside header(Location:...)</p></dd>\r
1515 \r
1516                         <dt><kbd>$force</kbd></dt>\r
1517                         <dd><p>Apply url_rewrite forcefully if it is true, default value is false.</p></dd>\r
1518 \r
1519                         <p>This function returns a pretty URL from the given parameter. Its purpose is to change the URLs to a "prettier" format in order to extend user friendliness in the system, and to create indexes for Google search.  This function will authenticate itself towards the current pages.  In our definition, admins, login, registration pages should not have pretty url applied.  However, if one want to use url_rewrite on these pages, please set <kbd>$force</kbd> to TRUE, this will force it to change the urls to pretty urls.  Please note that the admin's system preference will still overwrite the force effect.  <kbd>$url</kbd> may be an <kbd>string</kbd> of URL, '?' and the seprators in the URL query will be replaced by slashes.  Please note that the PHP_SELF variable might break some of the form action/header redirect because the Pretty URI is a virtual path.  To address this problem, set $is_rewriting_header to AT_PRETTY_URL_IS_HEADER, as demonstrated in example 3.  </p>\r
1520 \r
1521                 <h4>Location</h4>\r
1522                         <p><kbd>`include/vitals.inc.php`</kbd></p>\r
1523                 \r
1524                 <h4>Example 1</h4>\r
1525                 <p>To change an URL:\r
1526 <pre class="code">\r
1527 $url = 'forum/view.php?fid=3&pid=4';\r
1528 echo url_rewrite($url);         //output go.php/1/forum/view.php/fid/3/pid/4\r
1529 </pre></p>\r
1530 \r
1531                 <h4>Example 2</h4>\r
1532                 <p>To change an URL for mods:\r
1533 <pre class="code">\r
1534 $url = 'mods/hello_world/index.php';\r
1535 echo url_rewrite($url, true);           //output go.php/1/mods/hello_world/index.php\r
1536 </pre></p>\r
1537 \r
1538                 <h4>Example 3</h4>\r
1539                 <p>To change an URL for header redirection:\r
1540 <pre class="code">\r
1541 header('Location: '. url_rewrite('forum/index.php', AT_PRETTY_URL_IS_HEADER)); \r
1542 </pre></p>\r
1543 \r
1544 <a href="#top" class="top">top</a>\r
1545 <h2><a name="useful-constants"></a>19. Useful Constants</h2>\r
1546         <p>These constants are part of the vital functionality of ATutor.</p>\r
1547 \r
1548         <h3><a name="const-include_path"></a>19.1 AT_INCLUDE_PATH</h3>\r
1549         <h4>Description</h4>\r
1550                 <p>The <kbd>AT_INCLUDE_PATH</kbd> must be defined <em>before</em> you <kbd>require</kbd> or <kbd>include</kbd> any files. The constant defines the relative path to the <kbd>`include/`</kbd> directory. For security reasons <em>no</em> file should ever be called-in without using this constant<em>!</em></p>\r
1551 \r
1552                 <h4>Example 1</h4>\r
1553                 <p>Requiring the vitals file from the tools page:\r
1554                                 <pre class="code">define('AT_INCLUDE_PATH', '../include/');\r
1555 require (AT_INCLUDE_PATH . 'vitals.inc.php');</pre></p>\r
1556 \r
1557                 <h4>Location</h4>\r
1558                         <p><em>Declared on every page that is directly accessible.</em></p>\r
1559 \r
1560         <h3><a name="const-sep"></a>19.2 SEP</h3>\r
1561         <h4>Description</h4>\r
1562                 <p>For XHTML compliance, we have created this constant to use when applying variables to URL arguments. The constant is one of the values defined by PHP's <kbd>arg_separator.input</kbd>, with a preference for the semi-colon (<kbd>`;`</kbd>), if available, over the ampersand (<kbd>`&amp;`</kbd>).</p>\r
1563 \r
1564                 <h4>Example 1</h4>\r
1565                 <p>Printing a dynamic link:\r
1566 <pre class="code">\r
1567 $arg1 = 'one';\r
1568 $arg2 = 'two';\r
1569 \r
1570 echo "SEP is ".SEP."\n";\r
1571 echo '&lt;a href="index.php?arg1=' . $arg1 . SEP . 'arg2=' . $arg2 . '">link&lt;/a>';</pre></p>\r
1572                 \r
1573                 <p>Result:\r
1574 <pre class="code">\r
1575 SEP is ;\r
1576 &lt;a href="index.php?arg1=one;arg2=two">link&lt;/a>\r
1577 </pre></p>\r
1578 \r
1579                 <h4>Location</h4>\r
1580                         <p><kbd>`include/lib/constants.inc.php`</kbd></p>\r
1581 \r
1582 \r
1583         <h3><a name="const-devel"></a>19.3 AT_DEVEL</h3>\r
1584         <h4>Description</h4>\r
1585                 <p>Enables or disables usage of the <a href="#fn-debug">debug()</a> function.</p>\r
1586 \r
1587                 <h4>Location</h4>\r
1588                         <p><kbd>`include/vitals.inc.php`</kbd></p>\r
1589 \r
1590 \r
1591         <h3><a name="const-table_prefix"></a>19.4 TABLE_PREFIX</h3>\r
1592         <h4>Description</h4>\r
1593                 <p>The <kbd>TABLE_PREFIX</kbd> constant holds the prefix to the ATutor database tables. It is needed when creating SQL queries.</p>\r
1594 \r
1595                 <h4>Location</h4>\r
1596                         <p><kbd>`include/config.inc.php`</kbd></p>\r
1597 \r
1598 \r
1599         <h3><a name="const-version"></a>19.5 VERSION</h3>\r
1600                 <h4>Description</h4>\r
1601                 <p>The version number of this ATutor installation.</p>\r
1602 \r
1603                 <h4>Location</h4>\r
1604                         <p><kbd>`include/lib/constants.inc.php`</kbd></p>\r
1605 \r
1606 \r
1607 \r
1608 <a href="#top" class="top">top</a>\r
1609 <h2><a name="install-upgrade-scripts"></a>20. Install &amp; Upgrade Scripts</h2>\r
1610         <p>Installing or upgrading ATutor is done with the scripts found in the <kbd>`install/`</kbd> directory. Two files in particular control the installation or upgrading flow and are appropriately named <kbd>`install.php`</kbd> and <kbd>`upgrade.php`</kbd>. For actual documentation on installing or upgrading please see <a href="http://atutor.ca/atutor/docs/installation.php">ATutor's official documentation</a>.</p>\r
1611 \r
1612         <p>The <kbd>`install/`</kbd> directory contains two other subdirectories that are used during the installation or upgrade process. The <kbd>`install/db/`</kbd> directory contains database schema files and are clearly labeled. The <kbd>`install/include/`</kbd> directory contains scripts that are common to both processes and labeled according to their order in either process.</p>\r
1613 \r
1614         <h3><a name="install-script">20.1 Install Script</h3>\r
1615                 <p>The <kbd>`install.php`</kbd> script requires each step as it's needed as the <kbd>$step</kbd> counter variable is incremented. To add or edit a step, edit the <kbd>`install.php`</kbd> file.</p>\r
1616 \r
1617         <h3><a name="upgrade-script">20.2 Upgrade Script</h3>\r
1618                 <p>The <kbd>`upgrade.php`</kbd> script works exactly the same as the install script does, but requires different files (step prefixed with a 'u'). To upgrade the database schema an SQL file named <kbd>`atutor_upgrade_<em>from</em>_to_<em>to</em>.sql`</kbd> must be created, where <kbd><em>from</em></kbd> is the exact version of the previous ATutor version, and <kbd><em>to</em></kbd> is the next stable version.</p>\r
1619 \r
1620 \r
1621 <a href="#top" class="top">top</a>\r
1622 <h2><a name="accessibility"></a>21. Accessibility</h2>\r
1623         <p>Part of ATutor's philosophy is to be "designed with accessibility and adaptability in mind", we advise you to consider carefully the practices outlined on the following sites:</p>\r
1624         <ul>\r
1625                 <li><a href="http://www.w3.org/WAI/References/QuickTips/#QuickTips">WAI Quick Tips</a></li>\r
1626                 <li><a href="http://websavvy-access.org/standards/index.php">Web-Savvy & Standards Compliance</a></li>\r
1627                 <li><a href="http://atutor.ca/atutor/docs/atutor_access.php">ATutor's specific accessibility features</a></li>\r
1628         </ul>\r
1629 \r
1630 <a href="#top" class="top">top</a>\r
1631 <h2><a name="validation"></a>22. Validation</h2>\r
1632         <p>Please use the <a href="http://validator.w3.org/">W3C Markup Validation Service</a>, a free service, to check your pages for XHTML conformance, W3C Recommendations and other standards.</p>\r
1633 \r
1634 <a href="#top" class="top">top</a>\r
1635 <h2><a name="example"></a>23. Sample Script</h2>\r
1636 <p>The following is sample code that shows the general flow of an ATutor script. The example shows how you may use some of the variables and functions available to you. Some scripts may not need all the variables and functions used below.\r
1637 <pre class="code" id="code">&lt;?php\r
1638 // 0. insert the SVN keywords\r
1639 // <a href="#svn-keywords">$Id</a>: guidelines.html 1275 2004-07-28 16:02:49Z joel $\r
1640 \r
1641 // 1. define relative path to `include` directory:\r
1642 define('<a href="#const-include_path">AT_INCLUDE_PATH</a>', '../<a href="#directories-include">include/</a>');\r
1643 \r
1644 // 2. require the `vitals` file before any others:\r
1645 require (<a href="#const-include_path">AT_INCLUDE_PATH</a> . '<a href="#files-vitals">vitals.inc.php</a>');\r
1646 \r
1647 // 3. authenticate this user:\r
1648 <a href="#fn-authenticate">authenticate</a>(AT_PRIV_SPECIAL_PRIV);\r
1649 \r
1650 // 4. define the breadcrumbs path:\r
1651 <a href="#var-section">$_section[0][0]</a> =  <a href="#fn-at">_AT</a>('tools');\r
1652 <a href="#var-section">$_section[0][1]</a> = 'tools/';\r
1653 <a href="#var-section">$_section[1][0]</a> =  <a href="#fn-at">_AT</a>('my_page');\r
1654 <a href="#var-section">$_section[1][1]</a> =  'tools/page.php;\r
1655 \r
1656 // 5. handle any post request:\r
1657 if (isset($_POST['submit'])) {\r
1658   // 5.1 check for errors:\r
1659   if ($_POST['some_field'] == '') {\r
1660       <a href="#error-feedback-messages">$msg->addError</a>('SOME_ERROR_CODE');\r
1661   }\r
1662 \r
1663   if (!<a href="#error-feedback-messages">$msg->containsErrors()</a>) {\r
1664       //5.2 complete the desired action here. (example: insert into DB)\r
1665 \r
1666       //5.3 set the feedback message and add it to the URL:\r
1667       <a href="#error-feedback-messages">$msg->addFeedback</a>('MESSAGE');\r
1668       $url = <a href="#var-base_href">$_base_href</a> . 'tools/index.php?arg1=yes';\r
1669 \r
1670       //5.4 redirect after successful operation:\r
1671       header('Location: ' . $url);\r
1672       exit;\r
1673   }\r
1674 }\r
1675 \r
1676 // 6. start the page display by calling the header\r
1677 require (<a href="#const-include_path">AT_INCLUDE_PATH</a> . '<a href="#files-header">header.inc.php</a>');\r
1678 \r
1679 // 7. display any feedback or error messages that my occur:\r
1680 require (<a href="#const-include_path">AT_INCLUDE_PATH</a> . 'html/<a href="#files-feedback">feedback.inc.php</a>');\r
1681 \r
1682 /*\r
1683  * 8. display the page contents here.\r
1684  */\r
1685 \r
1686 // 9. finish the page by calling the footer\r
1687 require (<a href="#const-include_path">AT_INCLUDE_PATH</a> . '<a href="#files-footer">footer.inc.php</a>');\r
1688 ?></pre></p>\r
1689 \r
1690 <a href="#top" class="top">top</a>\r
1691 <h2><a name="credits-sources"></a>24. Credits &amp; Additional Sources</h2>\r
1692         <ul>\r
1693                 <li><a href="http://atutor.ca">ATutor.ca</a></li>\r
1694                 <li><a href="http://atutor.ca/forum/12/1.html">ATutor Developer Support Forum</a></li>\r
1695                 <li>Documentation\r
1696                         <ul>\r
1697                                 <li><a href="http://atutor.ca/atutor/docs/translate.php">ATutor Translator Documentation</a></li>\r
1698                                 <li><a href="http://php.net/manual/en">PHP Manual</a></li>\r
1699                                 <li><a href="http://svnbook.red-bean.com/svnbook/">Version Control with Subversion</a></li>\r
1700                                 <li><a href="http://mysql.com/doc">MySQL Documentation</a></li>\r
1701                                 <li><a href="http://www.zend.com/zend/week/index.php">PHP Weekly Summaries</a></li>\r
1702                                 <li><a href="http://alltasks.net/code/php_coding_standard.html">PHP Coding Standard</a> by Todd Hoff and Fredrik Kristiansen</li>\r
1703                                 <li><a href="http://www.blueshoes.org/en/developer/coding_guidelines/">Blueshoes.org - Coding Guidelines for BlueShoes Developers</a> by Andrej Arn</li>\r
1704                                 <li><a href="http://www.blueshoes.org/en/developer/syntax_exam/">Blueshoes.org - PHP Syntax Exam</a></li>\r
1705                                 <li><a href="http://www.blueshoes.org/en/developer/php_cheat_sheet/">Blueshoes.org - PHP Cheat Sheet</a></li>\r
1706                                 <li><a href="http://www.htmlhelp.com/reference/css/">HTMLhelp.com - Cascading Style Sheets</a> by John Pozadzides and Liam Quinn</li>\r
1707                                 <li><a href="http://httpd.apache.org/docs/">Apache HTTP Server Documentation</a></li>\r
1708                                 <li><a href="http://www.w3.org/TR/WAI-WEBCONTENT/checkpoint-list.html">W3C's Web Content Accessibility Guidelines</a></li>\r
1709                         </ul>\r
1710                 </li>\r
1711                 <li>Tools\r
1712                         <ul>\r
1713                                 <li><a href="http://www.phpmyadmin.net">phpMyAdmin</a></li>\r
1714                                 <li><a href="http://editplus.com">EditPlus</a></li>\r
1715                                 <li><a href="http://tortoisesvn.tigris.org/">TortoiseSVN</a></li>\r
1716                         </ul>\r
1717                 </li>\r
1718         </ul>\r
1719 \r
1720 </body>\r
1721 </html>\r