MDL-11719 increased size of idnumber in user table - needed for some enrolment plugin...
[moodle.git] / help.php
1 <?php
2 /**
3  * help.php - Displays help page.
4  *
5  * Prints a very simple page and includes
6  * page content or a string from elsewhere.
7  * Usually this will appear in a popup
8  * See {@link helpbutton()} in {@link lib/moodlelib.php}
9  *
10  * @author Martin Dougiamas
11  * @version $Id$
12  * @package moodlecore
13  */
14 require_once('config.php');
16 // Get URL parameters.
17 $file   = optional_param('file', '', PARAM_PATH);
18 $text   = optional_param('text', 'No text to display', PARAM_CLEAN);
19 $module = optional_param('module', 'moodle', PARAM_ALPHAEXT);
20 $forcelang = optional_param('forcelang', '', PARAM_SAFEDIR);
21 $skiplocal = optional_param('skiplocal', 0, PARAM_INT);     // shall _local help files be skipped?
23 // We look for the help to display in lots of different places, and
24 // only display an error at the end if we can't find the help file
25 // anywhere. This variable tracks that.
26 $helpfound = false;
28 // Buffer output so that we can examine it later to extract metadata (page title)
29 ob_start();
31 if (!empty($file)) {
32     // The help to display is from a help file.
34     // Get the list of parent languages.
35     if (empty($forcelang)) {
36         $langs = array(current_language(), get_string('parentlanguage'), 'en_utf8');  // Fallback
37     } else {
38         $langs = array($forcelang, 'en_utf8');
39     }
40     
41     if (!$skiplocal) {
42         // _local language packs take precedence with both forced language and non-forced language settings
43         $xlangs = array();
44         foreach ($langs as $lang) {
45             if (!empty($lang)) {
46                 $xlangs[] = $lang . '_local';
47                 $xlangs[] = $lang;
48             }
49         }
50         $langs = $xlangs;
51         unset($xlangs);
52     }
54 // Define possible locations for help file similar to locations for language strings
55 // Note: Always retain module directory as before
56     $locations = array();
57     if ($module == 'moodle') {
58         $locations[$CFG->dataroot.'/lang/'] = $file;
59         $locations[$CFG->dirroot.'/lang/'] = $file;
60     } else {
61         $modfile = $module.'/'.$file;
62         $locations[$CFG->dataroot.'/lang/'] = $modfile;
63         $locations[$CFG->dirroot.'/lang/'] = $modfile;
65         $rules = places_to_search_for_lang_strings();
66         $exceptions = $rules['__exceptions'];
67         unset($rules['__exceptions']);
68         
69         if (!in_array($module, $exceptions)) {
70             $dividerpos = strpos($module, '_');
71             if ($dividerpos === false) {
72                 $type = '';
73                 $plugin = $module;
74             } else {
75                 $type = substr($module, 0, $dividerpos + 1);
76                 $plugin = substr($module, $dividerpos + 1);
77             }
78             if (!empty($rules[$type])) {
79                 foreach ($rules[$type] as $location) {
80                     $locations[$CFG->dirroot . "/$location/$plugin/lang/"] = "$plugin/$file";
81                 }
82             }
83         }
84     }
86     // Work through the possible languages, starting with the most specific.
87     while (!$helpfound && (list(,$lang) = each($langs)) && !empty($lang)) {
89         while (!$helpfound && (list($locationprefix,$locationsuffix) = each($locations))) {
90             $filepath = $locationprefix.$lang.'/help/'.$locationsuffix;
92             // Now, try to include the help text from this file, if we can.
93             if (file_exists_and_readable($filepath)) {
94                 $helpfound = true;
95                 @include($filepath);   // The actual helpfile
97                 // Now, we process some special cases.
98                 $helpdir = $locationprefix.$lang.'/help';
99                 if ($module == 'moodle' and ($file == 'index.html' or $file == 'mods.html')) {
100                     include_help_for_each_module($file, $langs, $helpdir);
101                 }
103                 // The remaining horrible hardcoded special cases should be delegated to modules somehow.
104                 if ($module == 'moodle' and ($file == 'resource/types.html')) {  // RESOURCES
105                     include_help_for_each_resource($file, $langs, $helpdir);
106                 }
107                 if ($module == 'moodle' and ($file == 'assignment/types.html')) {  // ASSIGNMENTS
108                     include_help_for_each_assignment_type();
109                 }
110             }
111         }
112         reset($locations);
113     }
114 } else {
115     // The help to display was given as an argument to this function.
116     echo '<p>'.s($text).'</p>';   // This param was already cleaned
117     $helpfound = true;
120 // Finish buffer
121 $output=ob_get_contents();
122 ob_end_clean();
124 // Determine title
125 $title=get_string('help'); // Default is just 'Help'
126 $matches=array();
127 // You can include a <title> tag to override the standard behaviour:
128 // 'Help - title contents'. Otherwise it looks for the text of the first
129 // heading: 'Help - heading text'. If there aren't even any headings
130 // you just get 'Help'
131 if(preg_match('~^(.*?)<title>(.*?)</title>(.*)$~s',$output,$matches)) {
132     // Extract title
133     $title=$title.' - '.$matches[2]; 
134     // Strip title from output
135     $output=$matches[1].$matches[3];
136 } else if(preg_match('~<h[0-9]+(\s[^>]*)?>(.*?)</h[0-9]+>~s',$output,$matches)) {
137     // Use first heading as title (obviously leave it in output too). Strip
138     // any tags from inside
139     $matches[2]=preg_replace('~<[^>]*>~s','',$matches[2]);
140     $title=$title.' - '.$matches[2];
143 // use ##emoticons_html## to replace the emoticons documentation
144 if(preg_match('~(##emoticons_html##)~', $output, $matches)) {
145     $output = preg_replace('~(##emoticons_html##)~', get_emoticons_html(), $output);
148 // Do the main output.
149 print_header($title);
150 print_simple_box_start();
151 print $output;
152 print_simple_box_end();
154 // Display an error if necessary.
155 if (!$helpfound) {
156     notify('Help file "'. $file .'" could not be found!');
159 // End of page.
160 close_window_button();
161 echo '<p class="helpindex"><a href="help.php?file=index.html">'. get_string('helpindex') .'</a></p>';
163 $CFG->docroot = '';   // We don't want a doc link here
164 print_footer('none');
166 // Utility function =================================================================
168 function get_emoticons_html(){
169     global $CFG;
170     $output = '';
171     $emoticonstring = $CFG->emoticons;
172     $output .= '<ul>';
173     if ($emoticonstring) {
174         $items = explode('{;}', $CFG->emoticons);
175         foreach ($items as $item) {
176             $item = explode('{:}', $item);
177             $emoticons[$item[0]] = $item[1];
178             $output .= '<li><a href="javascript:inserttext(\''.$item[0].'\')"><img src="'.
179                 $CFG->pixpath.'/s/'.$item[1].'.gif" alt="'.$item[0].'" /></a>'.' <code>'.$item[0].
180                 '</code></li>';
181         }
183     }
184     $output .= '</ul>';
185     return $output;
189 function file_exists_and_readable($filepath) {
190     return file_exists($filepath) and is_file($filepath) and is_readable($filepath);
193 // Some functions for handling special cases ========================================
195 function include_help_for_each_module($file, $langs, $helpdir) {
196     global $CFG;
198     if (!$modules = get_records('modules', 'visible', 1)) {
199         print_error('nomodules', 'debug');        // Should never happen
200     }
201     
202     $grade = new stdClass();
203     $grade->name = 'grade';
204     $modules[] = $grade;
206     foreach ($modules as $mod) {
207         $strmodulename = get_string('modulename', $mod->name);
208         $modulebyname[$strmodulename] = $mod;
209     }
210     ksort($modulebyname, SORT_LOCALE_STRING);
212     foreach ($modulebyname as $mod) {
213         foreach ($langs as $lang) {
214             if (empty($lang)) {
215                 continue;
216             }
218             $filepath = "$helpdir/$mod->name/$file";
220             // If that does not exist, try a fallback into the module code folder.
221             if (!file_exists($filepath)) {
222                 $filepath = "$CFG->dirroot/mod/$mod->name/lang/$lang/help/$mod->name/$file";
223             }
225             if (file_exists_and_readable($filepath)) {
226                 echo '<hr />';
227                 @include($filepath); // The actual helpfile
228                 break; // Out of loop over languages.
229             }
230         }
231     }
234 function include_help_for_each_resource($file, $langs, $helpdir) {
235     global $CFG;
237     require_once($CFG->dirroot .'/mod/resource/lib.php');
238     $typelist = resource_get_types();
239     $typelist['label'] = get_string('resourcetypelabel', 'resource');
241     foreach ($typelist as $type => $name) {
242         foreach ($langs as $lang) {
243             if (empty($lang)) {
244                 continue;
245             }
247             $filepath = "$helpdir/resource/type/$type.html";
249             if (file_exists_and_readable($filepath)) {
250                 echo '<hr size="1" />';
251                 @include($filepath); // The actual helpfile
252                 break; // Out of loop over languages.
253             }
254         }
255     }
258 function include_help_for_each_assignment_type() {
259     global $CFG;
261     require_once($CFG->dirroot .'/mod/assignment/lib.php');
262     $typelist = assignment_types();
264     foreach ($typelist as $type => $name) {
265         echo '<p><b>'.$name.'</b></p>';
266         echo get_string('help'.$type, 'assignment');
267         echo '<hr size="1" />';
268     }
270 ?>