MDL-17457 migrated all modules to new db/install.php; added upgrade.txt file for...
[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_list_for_help_file(), $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 function file_exists_and_readable($filepath) {
167     return file_exists($filepath) and is_file($filepath) and is_readable($filepath);
170 // Some functions for handling special cases ========================================
172 function include_help_for_each_module($file, $langs, $helpdir) {
173     global $CFG, $DB;
175     if (!$modules = $DB->get_records('modules', array('visible'=>1))) {
176         print_error('nomodules', 'debug');        // Should never happen
177     }
178     
179     $grade = new stdClass();
180     $grade->name = 'grade';
181     $modules[] = $grade;
183     foreach ($modules as $mod) {
184         $strmodulename = get_string('modulename', $mod->name);
185         $modulebyname[$strmodulename] = $mod;
186     }
187     ksort($modulebyname, SORT_LOCALE_STRING);
189     foreach ($modulebyname as $mod) {
190         foreach ($langs as $lang) {
191             if (empty($lang)) {
192                 continue;
193             }
195             $filepath = "$helpdir/$mod->name/$file";
197             // If that does not exist, try a fallback into the module code folder.
198             if (!file_exists($filepath)) {
199                 $filepath = "$CFG->dirroot/mod/$mod->name/lang/$lang/help/$mod->name/$file";
200             }
202             if (file_exists_and_readable($filepath)) {
203                 echo '<hr />';
204                 @include($filepath); // The actual helpfile
205                 break; // Out of loop over languages.
206             }
207         }
208     }
211 function include_help_for_each_resource($file, $langs, $helpdir) {
212     global $CFG;
214     require_once($CFG->dirroot .'/mod/resource/lib.php');
215     $typelist = resource_get_types();
216     
217     //add label type
218     $labelType = new object();
219     $labelType->modclass = MOD_CLASS_RESOURCE;
220     $resourcetype = 'label';
221     $labelType->name = $resourcetype;
222     $labelType->type = "resource&amp;type=$resourcetype";
223     $labelType->typestr = get_string("resourcetype$resourcetype", 'resource');
224     $typelist[] = $labelType;
226     foreach ($typelist as $type) {
227    
228         foreach ($langs as $lang) {
229             if (empty($lang)) {
230                 continue;
231             }
233             $filepath = "$helpdir/resource/type/".$type->name.".html";
235             if (file_exists_and_readable($filepath)) {
236                 echo '<hr />';
237                 @include($filepath); // The actual helpfile
238                 break; // Out of loop over languages.
239             }
240         }
241     }
244 function include_help_for_each_assignment_type() {
245     global $CFG;
247     require_once($CFG->dirroot .'/mod/assignment/lib.php');
248     $typelist = assignment_types();
250     foreach ($typelist as $type => $name) {
251         echo '<p><b>'.$name.'</b></p>';
252         echo get_string('help'.$type, 'assignment');
253         echo '<hr size="1" />';
254     }
256 ?>