quiz editing: unindent entire file.
[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                 }
102                 if ($module == 'question' and ($file == 'types.html')) {
103                     include_help_for_each_qtype();
104                 }
106                 // The remaining horrible hardcoded special cases should be delegated to modules somehow.
107                 if ($module == 'moodle' and ($file == 'resource/types.html')) {  // RESOURCES
108                     include_help_for_each_resource($file, $langs, $helpdir);
109                 }
110                 if ($module == 'moodle' and ($file == 'assignment/types.html')) {  // ASSIGNMENTS
111                     include_help_for_each_assignment_type();
112                 }
113             }
114         }
115         reset($locations);
116     }
117 } else {
118     // The help to display was given as an argument to this function.
119     echo '<p>'.s($text).'</p>';   // This param was already cleaned
120     $helpfound = true;
123 // Finish buffer
124 $output=ob_get_contents();
125 ob_end_clean();
127 // Determine title
128 $title=get_string('help'); // Default is just 'Help'
129 $matches=array();
130 // You can include a <title> tag to override the standard behaviour:
131 // 'Help - title contents'. Otherwise it looks for the text of the first
132 // heading: 'Help - heading text'. If there aren't even any headings
133 // you just get 'Help'
134 if(preg_match('~^(.*?)<title>(.*?)</title>(.*)$~s',$output,$matches)) {
135     // Extract title
136     $title=$title.' - '.$matches[2]; 
137     // Strip title from output
138     $output=$matches[1].$matches[3];
139 } else if(preg_match('~<h[0-9]+(\s[^>]*)?>(.*?)</h[0-9]+>~s',$output,$matches)) {
140     // Use first heading as title (obviously leave it in output too). Strip
141     // any tags from inside
142     $matches[2]=preg_replace('~<[^>]*>~s','',$matches[2]);
143     $title=$title.' - '.$matches[2];
146 // use ##emoticons_html## to replace the emoticons documentation
147 if(preg_match('~(##emoticons_html##)~', $output, $matches)) {
148     $output = preg_replace('~(##emoticons_html##)~', get_emoticons_list_for_help_file(), $output);
151 // Do the main output.
152 print_header($title);
153 print_simple_box_start();
154 print $output;
155 print_simple_box_end();
157 // Display an error if necessary.
158 if (!$helpfound) {
159     notify('Help file "'. $file .'" could not be found!');
162 // End of page.
163 close_window_button();
164 echo '<p class="helpindex"><a href="help.php?file=index.html">'. get_string('helpindex') .'</a>';
166 // Offer a link to the alternative help file language
167 if (($helpfound) and (((current_language() != 'en_utf8') and $lang != 'en_utf8') or ($forcelang === 'en_utf8'))) {
168     $linklang = "{$CFG->wwwroot}/help.php?";
169     $linklang .= !empty($module)    ? "module=$module&amp;" : '';
170     $linklang .= !empty($file)      ? "file=$file&amp;" : '';
171     $linklang .= !empty($skiplocal) ? "skiplocal=$skiplocal&amp;" : '';
173     if (empty($forcelang) or $forcelang === current_language()) {
174         $nextlang = 'en_utf8';
175         $nextlangname = 'English';
176     } else {
177         $nextlang = current_language();
178         $nextlangname = get_string('thislanguage');
179     }
181     $linklang .= "forcelang=$nextlang";
182     echo "<br /><a href=\"$linklang\">" . get_string('showthishelpinlanguage', 'moodle', $nextlangname) . '</a>';
184 echo '</p>';
186 $CFG->docroot = '';   // We don't want a doc link here
187 print_footer('none');
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, $DB;
198     if (!$modules = $DB->get_records('modules', array('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_qtype() {
235     global $CFG;
236     require_once($CFG->libdir . '/questionlib.php');
237     global $QTYPES;
238     $types = question_type_menu();
239     $fakeqtypes = array();
240     foreach ($types as $qtype => $localizedname) {
241         if ($QTYPES[$qtype]->is_real_question_type()) {
242             include_help_for_qtype($qtype, $localizedname);
243         } else {
244             $fakeqtypes[$qtype] = $localizedname;
245         }
246     }
247     foreach ($fakeqtypes as $qtype => $localizedname) {
248         include_help_for_qtype($qtype, $localizedname);
249     }
251 function include_help_for_qtype($qtype, $localizedname) {
252     echo '<h2>' . $localizedname . "</h2>\n\n";
253     echo '<p>' . get_string($qtype . 'summary', 'qtype_' . $qtype) . "</p>\n\n";
256 function include_help_for_each_resource($file, $langs, $helpdir) {
257     global $CFG;
259     require_once($CFG->dirroot .'/mod/resource/lib.php');
260     $typelist = resource_get_types();
261     
262     //add label type
263     $labelType = new object();
264     $labelType->modclass = MOD_CLASS_RESOURCE;
265     $resourcetype = 'label';
266     $labelType->name = $resourcetype;
267     $labelType->type = "resource&amp;type=$resourcetype";
268     $labelType->typestr = get_string("resourcetype$resourcetype", 'resource');
269     $typelist[] = $labelType;
271     foreach ($typelist as $type) {
272    
273         foreach ($langs as $lang) {
274             if (empty($lang)) {
275                 continue;
276             }
278             $filepath = "$helpdir/resource/type/".$type->name.".html";
280             if (file_exists_and_readable($filepath)) {
281                 echo '<hr />';
282                 @include($filepath); // The actual helpfile
283                 break; // Out of loop over languages.
284             }
285         }
286     }
289 function include_help_for_each_assignment_type() {
290     global $CFG;
292     require_once($CFG->dirroot .'/mod/assignment/lib.php');
293     $typelist = assignment_types();
295     foreach ($typelist as $type => $name) {
296         echo '<p><b>'.$name.'</b></p>';
297         echo get_string('help'.$type, 'assignment');
298         echo '<hr size="1" />';
299     }
301 ?>