/[drupal]/contributions/modules/advanced_help/advanced_help.module
ViewVC logotype

Contents of /contributions/modules/advanced_help/advanced_help.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.41 - (show annotations) (download) (as text)
Tue Oct 28 17:33:47 2008 UTC (12 months, 4 weeks ago) by merlinofchaos
Branch: MAIN
CVS Tags: DRUPAL-6--1-2, HEAD
Changes since 1.40: +10 -9 lines
File MIME type: text/x-php
#327082: Move the linebreak filter to after regex parsing to make sure path replacement happens.
1 <?php
2 // $Id: advanced_help.module,v 1.40 2008/10/27 22:43:28 merlinofchaos Exp $
3 /**
4 * @file advanced_help.module
5 *
6 * Pluggable system to provide advanced help facilities for Drupal and modules.
7 *
8 * Modules utilizing this help system should create a 'help' directory in their
9 * module. Inside that directory place MODULENAME.help.ini which will be formatted
10 * like this:
11 *
12 * @code
13 * [buses]
14 * title = "How buses are tied into the system"
15 * file = buses
16 *
17 * [TOPIC_ID]
18 * title = "Title of topic"
19 * file = filename of topic, without the .html extension
20 * weight = the importance of the topic on the index page
21 * parent = the optional topic parent to use in the breadcrumb. Can be either topic or module%topic
22 * @endcode
23 *
24 * All topics are addressed by the module that provides the topic, and the topic
25 * id. Links may be embedded as in the following example:
26 *
27 * @code
28 * $output .= theme('advanced_help_topic', $module, $topic);
29 * @endcode
30 *
31 * Link to other topics using <a href="topic:module/topic">. (Using
32 * this format ensures the popup status remains consistent for all
33 * links.)
34 */
35
36 /**
37 * Implementation of hook_menu().
38 */
39 function advanced_help_menu() {
40 // View help topic index.
41
42 // This is structured a little oddly so POTX can properly handle the translation.
43 if (module_exists('help')) {
44 $items['admin/advanced_help'] = array(
45 'title' => 'Advanced help',
46 'page callback' => 'advanced_help_index_page',
47 'access arguments' => array('view advanced help index'),
48 'weight' => 9,
49 );
50 }
51 else {
52 $items['admin/advanced_help'] = array(
53 'title' => 'Help',
54 'page callback' => 'advanced_help_index_page',
55 'access arguments' => array('view advanced help index'),
56 'weight' => 9,
57 );
58 }
59 $items['advanced_help/search/%menu_tail'] = array(
60 'title' => 'Search help',
61 'page callback' => 'advanced_help_search_view',
62 'page arguments' => array('advanced_help'),
63 'access arguments' => array('view advanced help index'),
64 );
65
66 // View help topic.
67 $items['help/%/%'] = array(
68 'page callback' => 'advanced_help_topic_page',
69 'page arguments' => array(1, 2),
70 'access arguments' => array('view advanced help topic'),
71 'type' => MENU_CALLBACK,
72 );
73
74 return $items;
75 }
76
77 /**
78 * Inplementation of hook_menu_alter().
79 **/
80 function advanced_help_menu_alter(&$callbacks) {
81 // We need to fix the menu item provided by search module to restrict access.
82 $callbacks['search/advanced_help/%menu_tail']['access callback'] = 'user_access';
83 $callbacks['search/advanced_help/%menu_tail']['access arguments'] = array('view advanced help index');
84 }
85
86 /**
87 * Implementation of hook_theme().
88 */
89 function advanced_help_theme() {
90 $hooks['advanced_help_topic'] = array(
91 'arguments' => array('module' => NULL, 'topic' => NULL),
92 );
93
94 $hooks['advanced_help_popup'] = array(
95 'arguments' => array('content' => NULL),
96 'template' => 'advanced-help-popup',
97 );
98
99 return $hooks;
100 }
101
102 function advanced_help_uasort($id_a, $id_b) {
103 $topics = advanced_help_get_topics();
104 list($module_a, $topic_a) = $id_a;
105 $a = $topics[$module_a][$topic_a];
106 list($module_b, $topic_b) = $id_b;
107 $b = $topics[$module_b][$topic_b];
108
109 $a_weight = isset($a['weight']) ? $a['weight'] : 0;
110 $b_weight = isset($b['weight']) ? $b['weight'] : 0;
111 if ($a_weight != $b_weight) {
112 return ($a_weight < $b_weight) ? -1 : 1;
113 }
114
115 if ($a['title'] != $b['title']) {
116 return ($a['title'] < $b['title']) ? -1 : 1;
117 }
118 return 0;
119 }
120
121 /**
122 * Page callback for advanced help search.
123 */
124 function advanced_help_search_view() {
125 if (!module_exists('search')) {
126 return MENU_NOT_FOUND;
127 }
128
129 $breadcrumb[] = advanced_help_l(t('Help'), 'admin/advanced_help');
130
131 if (!isset($_POST['form_id'])) {
132 $keys = search_get_keys();
133 // Only perform search if there is non-whitespace search term:
134 $results = '';
135 if (trim($keys)) {
136
137 // Collect the search results:
138 $results = search_data($keys, 'advanced_help');
139
140 if ($results) {
141 $results = theme('box', t('Search results'), $results);
142 }
143 else {
144 $results = theme('box', t('Your search yielded no results'), search_help('search#noresults', drupal_help_arg()));
145 }
146 }
147
148 // Construct the search form.
149 $output = drupal_get_form('advanced_help_search_form', $keys);
150 $output .= $results;
151
152 }
153 else {
154 $output = drupal_get_form('advanced_help_search_form', empty($keys) ? '' : $keys);
155 }
156
157 $popup = !empty($_GET['popup']) && user_access('view advanced help popup');
158 if ($popup) {
159 $GLOBALS['devel_shutdown'] = FALSE; // Prevent devel module from spewing.
160 module_invoke('admin_menu', 'suppress'); // Suppress admin_menu.
161 drupal_set_breadcrumb(array_reverse($breadcrumb));
162 print theme('advanced_help_popup', $output);
163 return;
164 }
165
166 $breadcrumb = array_merge(drupal_get_breadcrumb(), array_reverse($breadcrumb));
167 drupal_set_breadcrumb($breadcrumb);
168 return $output;
169 }
170
171 /**
172 * Page callback to view the advanced help topic index.
173 */
174 function advanced_help_index_page($module = '') {
175 $topics = advanced_help_get_topics();
176 $settings = advanced_help_get_settings();
177
178 // Print a search widget.
179 $output = '';
180 if (module_exists('search')) {
181 $output .= drupal_get_form('advanced_help_search_form');
182 }
183 else {
184 $output .= t('Enable the search module to search help.');
185 }
186
187 $breadcrumb = array();
188 if ($module) {
189 if (empty($topics[$module])) {
190 return drupal_not_found();
191 }
192
193 advanced_help_get_topic_hierarchy($topics);
194 $items = advanced_help_get_tree($topics, $topics[$module]['']['children']);
195
196 $breadcrumb[] = advanced_help_l(t('Help'), 'admin/advanced_help');
197
198 drupal_set_title(t('@module help index', array('@module' => advanced_help_get_module_name($module))));
199 $output .= theme('item_list', $items);
200 }
201 else {
202 // Print a module index.
203 $modules = array();
204 $result = db_query("SELECT * FROM {system}");
205 while ($info = db_fetch_object($result)) {
206 $module_info = unserialize($info->info);
207 $modules[$info->name] = $module_info['name'];
208 }
209
210 asort($modules);
211
212 $items = array();
213 foreach ($modules as $module => $module_name) {
214 if (!empty($topics[$module]) && empty($settings[$module]['hide'])) {
215 if (isset($settings[$module]['index name'])) {
216 $name = $settings[$module]['index name'];
217 }
218 elseif (isset($settings[$module]['name'])) {
219 $name = $settings[$module]['name'];
220 }
221 else {
222 $name = t($module_name);
223 }
224 $items[] = advanced_help_l($name, "admin/advanced_help/$module");
225 }
226 }
227
228 drupal_set_title(t('Module help index'));
229 $output .= theme('item_list', $items);
230 }
231
232 $popup = !empty($_GET['popup']) && user_access('view advanced help popup');
233 if ($popup) {
234 $GLOBALS['devel_shutdown'] = FALSE; // Prevent devel module from spewing.
235 module_invoke('admin_menu', 'suppress'); // Suppress admin_menu.
236 drupal_set_breadcrumb(array_reverse($breadcrumb));
237 print theme('advanced_help_popup', $output);
238 return;
239 }
240
241 $breadcrumb = array_merge(drupal_get_breadcrumb(), array_reverse($breadcrumb));
242 drupal_set_breadcrumb($breadcrumb);
243
244 return $output;
245 }
246
247 /**
248 * Build a tree of advanced help topics.
249 */
250 function advanced_help_get_tree($topics, $topic_ids, $max_depth = -1, $depth = 0) {
251 uasort($topic_ids, 'advanced_help_uasort');
252 $items = array();
253 foreach ($topic_ids as $info) {
254 list($module, $topic) = $info;
255 $item = advanced_help_l($topics[$module][$topic]['title'], "help/$module/$topic");
256 if (!empty($topics[$module][$topic]['children']) && ($max_depth == -1 || $depth < $max_depth)) {
257 $item .= theme('item_list', advanced_help_get_tree($topics, $topics[$module][$topic]['children'], $max_depth, $depth + 1));
258 }
259
260 $items[] = $item;
261 }
262
263 return $items;
264 }
265
266 /**
267 * Build a hierarchy for a single module's topics.
268 */
269 function advanced_help_get_topic_hierarchy(&$topics) {
270 foreach ($topics as $module => $module_topics) {
271 foreach ($module_topics as $topic => $info) {
272 $parent_module = $module;
273 // We have a blank topic that we don't want parented to
274 // itself.
275 if (!$topic) {
276 continue;
277 }
278
279 if (empty($info['parent'])) {
280 $parent = '';
281 }
282 else if (strpos($info['parent'], '%')) {
283 list($parent_module, $parent) = explode('%', $info['parent']);
284 if (empty($topics[$parent_module][$parent])) {
285 // If it doesn't exist, top level.
286 $parent = '';
287 }
288 }
289 else {
290 $parent = $info['parent'];
291 if (empty($module_topics[$parent])) {
292 // If it doesn't exist, top level.
293 $parent = '';
294 }
295 }
296
297 if (!isset($topics[$parent_module][$parent]['children'])) {
298 $topics[$parent_module][$parent]['children'] = array();
299 }
300 $topics[$parent_module][$parent]['children'][] = array($module, $topic);
301 $topics[$module][$topic]['_parent'] = array($parent_module, $parent);
302 }
303 }
304 }
305
306 /**
307 * Form builder callback to build the search form.
308 */
309 function advanced_help_search_form(&$form_state, $keys = '') {
310 $form = search_form($form_state, advanced_help_url('admin/advanced_help'), $keys, 'advanced_help', t('Search help'));
311 require_once './' . drupal_get_path('module', 'search') . '/search.pages.inc';
312
313 $form['basic']['inline']['submit']['#validate'] = array('search_form_validate');
314 $form['basic']['inline']['submit']['#submit'] = array('advanced_help_search_form_submit');
315
316 return $form;
317 }
318
319 /**
320 * Process a search form submission.
321 */
322 function advanced_help_search_form_submit($form, &$form_state) {
323 $keys = $form_state['values']['processed_keys'];
324 if ($keys == '') {
325 form_set_error('keys', t('Please enter some keywords.'));
326 return;
327 }
328
329 $popup = !empty($_GET['popup']) && user_access('view advanced help popup');
330
331 if ($popup) {
332 $form_state['redirect'] = array('advanced_help/search/' . $keys, 'popup=true');
333 }
334 else {
335 $form_state['redirect'] = 'advanced_help/search/' . $keys;
336 }
337 }
338
339
340 /**
341 * Small helper function to get a module's proper name.
342 */
343 function advanced_help_get_module_name($module) {
344 $settings = advanced_help_get_settings();
345 if (isset($settings[$module]['name'])) {
346 $name = $settings[$module]['name'];
347 }
348 else {
349 $info = db_fetch_object(db_query("SELECT * FROM {system} WHERE name = '%s'", $module));
350 $info = unserialize($info->info);
351 $name = t($info['name']);
352 }
353 return $name;
354 }
355
356 /**
357 * Page callback to view a help topic.
358 */
359 function advanced_help_topic_page($module, $topic) {
360 $info = advanced_help_get_topic($module, $topic);
361 if (!$info) {
362 return drupal_not_found();
363 }
364
365 $popup = !empty($_GET['popup']) && user_access('view advanced help popup');
366
367 drupal_set_title($info['title']);
368
369 // Set up breadcrumb.
370 $breadcrumb = array();
371
372 $parent = $info;
373 $pmodule = $module;
374
375 // Loop checker.
376 $checked = array();
377 while (!empty($parent['parent'])) {
378 if (strpos($parent['parent'], '%')) {
379 list($pmodule, $ptopic) = explode('%', $parent['parent']);
380 }
381 else {
382 $ptopic = $parent['parent'];
383 }
384
385 if (!empty($checked[$pmodule][$ptopic])) {
386 break;
387 }
388 $checked[$pmodule][$ptopic] = TRUE;
389
390 $parent = advanced_help_get_topic($pmodule, $ptopic);
391 if (!$parent) {
392 break;
393 }
394
395 $breadcrumb[] = advanced_help_l($parent['title'], "help/$pmodule/$ptopic");
396 }
397
398 $breadcrumb[] = advanced_help_l(advanced_help_get_module_name($pmodule), "admin/advanced_help/$pmodule");
399 $breadcrumb[] = advanced_help_l(t('Help'), "admin/advanced_help");
400
401 $output = advanced_help_view_topic($module, $topic, $popup);
402 if (empty($output)) {
403 $output = t('Missing help topic.');
404 }
405
406 if ($popup) {
407 $GLOBALS['devel_shutdown'] = FALSE; // Prevent devel module from spewing.
408 module_invoke('admin_menu', 'suppress'); // Suppress admin_menu.
409 drupal_set_breadcrumb(array_reverse($breadcrumb));
410 print theme('advanced_help_popup', $output);
411 return;
412 }
413
414 drupal_add_css(drupal_get_path('module', 'advanced_help') . '/help.css');
415 $breadcrumb[] = l(t('Home'), '');
416 drupal_set_breadcrumb(array_reverse($breadcrumb));
417 return $output;
418 }
419
420 /**
421 * Implementation of hook_perm().
422 */
423 function advanced_help_perm() {
424 return array('view advanced help topic', 'view advanced help popup', 'view advanced help index');
425 }
426
427 /**
428 * Display a help icon with a link to view the topic in a popup.
429 *
430 * @param $module
431 * The module that owns this help topic.
432 * @param $topic
433 * The identifier for the topic
434 * @param $type
435 * - 'icon' to display the question mark icon
436 * - 'title' to display the topic's title
437 * - any other text to display the text. Be sure to t() it!
438 */
439 function theme_advanced_help_topic($module, $topic, $type = 'icon') {
440 $info = advanced_help_get_topic($module, $topic);
441 if (!$info) {
442 return;
443 }
444
445 switch ($type) {
446 case 'icon':
447 $text = '<span>' . t('Help') . '</span>';
448 $class = 'advanced-help-link';
449 break;
450 case 'title':
451 $text = $info['title'];
452 $class = 'advanced-help-title';
453 break;
454 default:
455 $class = 'advanced-help-title';
456 $text = $type;
457 break;
458 }
459
460 if (user_access('view advanced help popup')) {
461 drupal_add_css(drupal_get_path('module', 'advanced_help') . '/help-icon.css');
462 return l($text, "help/$module/$topic", array(
463 'attributes' => array(
464 'class' => $class,
465 'onclick' => "var w=window.open(this.href, 'advanced_help_window', 'width=". $info['popup width'] .",height=". $info['popup height'] .",scrollbars,resizable'); w.focus(); return false;",
466 'title' => $info['title']
467 ),
468 'query' => array('popup' => TRUE),
469 'html' => TRUE)
470 );
471 }
472 else {
473 return l($text, "help/$module/$topic", array(
474 'attributes' => array(
475 'class' => $class,
476 'title' => $info['title']
477 ),
478 'html' => TRUE)
479 );
480 }
481 }
482
483 /**
484 * Load and render a help topic.
485 */
486 function advanced_help_get_topic_filename($module, $topic) {
487 $info = advanced_help_get_topic_file_info($module, $topic);
488 if ($info) {
489 return "./$info[path]/$info[file]";
490 }
491 }
492 /**
493 * Load and render a help topic.
494 */
495 function advanced_help_get_topic_file_info($module, $topic) {
496 init_theme();
497 global $language;
498
499 $info = advanced_help_get_topic($module, $topic);
500 if (empty($info)) {
501 return;
502 }
503
504 // Search paths:
505 $paths = array(
506 path_to_theme() . '/help', // Allow theme override.
507 drupal_get_path('module', $module) . "/translations/help/$language->language", // Translations.
508 $info['path'], // In same directory as .inc file.
509 );
510
511 foreach ($paths as $path) {
512 if (file_exists("./$path/$info[file]")) {
513 return array('path' => $path, 'file' => $info['file']);
514 }
515 }
516 }
517
518 /**
519 * Load and render a help topic.
520 */
521 function advanced_help_view_topic($module, $topic, $popup = FALSE) {
522 $file_info = advanced_help_get_topic_file_info($module, $topic);
523 if ($file_info) {
524 $info = advanced_help_get_topic($module, $topic);
525 $file = "./$file_info[path]/$file_info[file]";
526
527 // @todo is this trusted output?
528 $output = file_get_contents($file);
529 // Make some exchanges. The strtr is because url() translates $ into %24
530 // but we need to change it back for the regex replacement.
531
532 // Change 'topic:' to the URL for another help topic.
533 if ($popup) {
534 $output = preg_replace('/href="topic:([^"]+)"/', 'href="' . strtr(url('help/$1', array('query' => 'popup=true')), array('%24' => '$')) . '"', $output);
535 $output = preg_replace('/src="topic:([^"]+)"/', 'src="' . strtr(url('help/$1', array('query' => 'popup=true')), array('%24' => '$')) . '"', $output);
536 $output = preg_replace('/&topic:([^"]+)&/', strtr(url('help/$1', array('query' => 'popup=true')), array('%24' => '$')), $output);
537 }
538 else {
539 $output = preg_replace('/href="topic:([^"]+)"/', 'href="' . strtr(url('help/$1'), array('%24' => '$')) . '"', $output);
540 $output = preg_replace('/src="topic:([^"]+)"/', 'src="' . strtr(url('help/$1'), array('%24' => '$')) . '"', $output);
541 $output = preg_replace('/&topic:([^"]+)&/', strtr(url('help/$1'), array('%24' => '$')), $output);
542 }
543
544 global $base_path;
545
546 // Change 'path:' to the URL to the base help directory.
547 $output = preg_replace('/href="path:([^"]+)"/', 'href="' . $base_path . $info['path'] . '/$1"', $output);
548 $output = preg_replace('/src="path:([^"]+)"/', 'src="' . $base_path . $info['path'] . '/$1"', $output);
549 $output = str_replace('&path&', $base_path . $info['path'] .'/', $output);
550
551 // Change 'trans_path:' to the URL to the actual help directory.
552 $output = preg_replace('/href="trans_path:([^"]+)"/', 'href="' . $base_path . $file_info['path'] . '/$1"', $output);
553 $output = preg_replace('/src="trans_path:([^"]+)"/', 'src="' . $base_path . $file_info['path'] . '/$1"', $output);
554 $output = str_replace('&trans_path&', $base_path . $file_info['path'] .'/', $output);
555
556 // Change 'base_url:' to the URL to the site.
557 $output = preg_replace('/href="base_url:([^"]+)"/', 'href="' . strtr(url('$1'), array('%24' => '$')) . '"', $output);
558 $output = preg_replace('/src="base_url:([^"]+)"/', 'src="' . strtr(url('$1'), array('%24' => '$')) . '"', $output);
559 $output = str_replace('&base_url&', $base_path, $output);
560
561 // Run the line break filter if requested
562 if (!empty($info['line break'])) {
563 // Remove the header since it adds an extra <br /> to the filter.
564 $output = preg_replace('/^<!--[^\n]*-->\n/', '', $output);
565
566 $output = _filter_autop($output);
567 }
568
569 if (!empty($info['navigation'])) {
570 $topics = advanced_help_get_topics();
571 advanced_help_get_topic_hierarchy($topics);
572 if (!empty($topics[$module][$topic]['children'])) {
573 $items = advanced_help_get_tree($topics, $topics[$module][$topic]['children']);
574 $output .= theme('item_list', $items);
575 }
576
577 list($parent_module, $parent_topic) = $topics[$module][$topic]['_parent'];
578 if ($parent_topic) {
579 $parent = $topics[$module][$topic]['_parent'];
580 $up = "help/$parent[0]/$parent[1]";
581 }
582 else {
583 $up = "admin/advanced_help/$module";
584 }
585
586 $siblings = $topics[$parent_module][$parent_topic]['children'];
587 uasort($siblings, 'advanced_help_uasort');
588 $prev = $next = NULL;
589 $found = FALSE;
590 foreach ($siblings as $sibling) {
591 list($sibling_module, $sibling_topic) = $sibling;
592 if ($found) {
593 $next = $sibling;
594 break;
595 }
596 if ($sibling_module == $module && $sibling_topic == $topic) {
597 $found = TRUE;
598 continue;
599 }
600 $prev = $sibling;
601 }
602
603 if ($prev || $up || $next) {
604 $navigation = '<div class="help-navigation clear-block">';
605
606 if ($prev) {
607 $navigation .= advanced_help_l('<< ' . $topics[$prev[0]][$prev[1]]['title'], "help/$prev[0]/$prev[1]", array('attributes' => array('class' => 'help-left')));
608 }
609 if ($up) {
610 $navigation .= advanced_help_l(t('Up'), $up, array('attributes' => array('class' => $prev ? 'help-up' : 'help-up-noleft')));
611 }
612 if ($next) {
613 $navigation .= advanced_help_l($topics[$next[0]][$next[1]]['title'] . ' >>', "help/$next[0]/$next[1]", array('attributes' => array('class' => 'help-right')));
614 }
615
616 $navigation .= '</div>';
617
618 $output .= $navigation;
619 }
620 }
621
622 if (!empty($info['css'])) {
623 drupal_add_css($info['path'] . '/' . $info['css']);
624 }
625
626 $output = '<div class="advanced-help-topic">' . $output . '</div>';
627 drupal_alter('advanced_help_topic', $output, $popup);
628 return $output;
629 }
630 }
631
632 /**
633 * Get the information for a single help topic.
634 */
635 function advanced_help_get_topic($module, $topic) {
636 $topics = advanced_help_get_topics();
637 if (!empty($topics[$module][$topic])) {
638 return $topics[$module][$topic];
639 }
640 }
641
642 /**
643 * Search the system for all available help topics.
644 */
645 function advanced_help_get_topics() {
646 $cache = _advanced_help_parse_ini();
647 return $cache['topics'];
648 }
649
650 function advanced_help_get_settings() {
651 $cache = _advanced_help_parse_ini();
652 return $cache['settings'];
653 }
654
655 function _advanced_help_parse_ini() {
656 static $cache = NULL;
657
658 if (!isset($cache)) {
659 $cache = array('topics' => array(), 'settings' => array());
660
661 $help_path = drupal_get_path('module', 'advanced_help') . '/modules';
662 foreach (module_list() as $module) {
663 $module_path = drupal_get_path('module', $module);
664 $info = array();
665 if (file_exists("$module_path/help/$module.help.ini")) {
666 $path = "$module_path/help";
667 $info = parse_ini_file("./$module_path/help/$module.help.ini", TRUE);
668 }
669 elseif (file_exists("$help_path/$module/$module.help.ini")) {
670 $path = "$help_path/$module";
671 $info = parse_ini_file("./$help_path/$module/$module.help.ini", TRUE);
672 }
673 elseif (!file_exists("$module_path/help")) {
674 // Look for one or more README files.
675 $files = file_scan_directory("./$module_path", '^(README|readme).*\.(txt|TXT)$', array('.', '..', 'CVS'), 0, FALSE);
676 $path = "./$module_path";
677 foreach ($files as $name => $fileinfo) {
678 $info[$fileinfo->basename] = array('line break' => TRUE, 'readme file' => TRUE, 'file' => $fileinfo->basename, 'title' => $fileinfo->name);
679 }
680 }
681
682 if (!empty($info)) {
683 // Get translated titles:
684 global $language;
685 $translation = array();
686 if (file_exists("$module_path/translations/help/$language->language/$module.help.ini")) {
687 $translation = parse_ini_file("$module_path/translations/help/$language->language/$module.help.ini", TRUE);
688 }
689
690 $cache['settings'][$module] = array();
691 if (!empty($info['advanced help settings'])) {
692 $cache['settings'][$module] = $info['advanced help settings'];
693 unset($info['advanced help settings']);
694
695 // Check translated strings for translatable global settings.
696 if (isset($translation['advanced help settings']['name'])) {
697 $cache['settings']['name'] = $translation['advanced help settings']['name'];
698 }
699 if (isset($translation['advanced help settings']['index name'])) {
700 $cache['settings']['index name'] = $translation['advanced help settings']['index name'];
701 }
702
703 }
704
705 foreach ($info as $name => $topic) {
706 // Each topic should have a name, a title, a file and of course the path.
707 $file = !empty($topic['file']) ? $topic['file'] : $name;
708 $cache['topics'][$module][$name] = array(
709 'name' => $name,
710 'title' => !empty($translation[$name]['title']) ? $translation[$name]['title'] : $topic['title'],
711 'weight' => isset($topic['weight']) ? $topic['weight'] : 0,
712 'parent' => isset($topic['parent']) ? $topic['parent'] : 0,
713 'popup width' => isset($topic['popup width']) ? $topic['popup width'] : 500,
714 'popup height' => isset($topic['popup height']) ? $topic['popup height'] : 500,
715 'file' => isset($topic['readme file']) ? $file : $file . '.html', // require extension
716 'path' => $path, // not in .ini file
717 'line break' => isset($topic['line break']) ? $topic['line break'] : (isset($cache['settings'][$module]['line break']) ? $cache['settings'][$module]['line break'] : FALSE),
718 'navigation' => isset($topic['navigation']) ? $topic['navigation'] : (isset($cache['settings'][$module]['navigation']) ? $cache['settings'][$module]['navigation'] : TRUE),
719 'css' => isset($topic['css']) ? $topic['css'] : (isset($cache['settings'][$module]['css']) ? $cache['settings'][$module]['css'] : NULL),
720 );
721 }
722 }
723 }
724 drupal_alter('advanced_help_topic_info', $cache);
725 }
726 return $cache;
727 }
728
729 /**
730 * Implementation of hook_search()
731 */
732 function advanced_help_search($op = 'search', $keys = null) {
733 switch ($op) {
734 case 'name':
735 return t('Help');
736 case 'reset':
737 variable_del('advanced_help_last_cron');
738 return;
739 case 'search':
740 $topics = advanced_help_get_topics();
741 $find = do_search($keys, 'help');
742 if (!$find) {
743 return;
744 }
745
746 $results = array();
747
748 $placeholders = implode(', ', array_fill(0, count($find), '%d'));
749 foreach ($find as $item) {
750 $sids[] = $item->sid;
751 }
752
753 $result = db_query("SELECT * FROM {advanced_help_index} WHERE sid IN ($placeholders)", $sids);
754 while ($sid = db_fetch_object($result)) {
755 // Guard against removed help topics that are still indexed.
756 if (empty($topics[$sid->module][$sid->topic])) {
757 continue;
758 }
759 $info = $topics[$sid->module][$sid->topic];
760 $text = advanced_help_view_topic($sid->module, $sid->topic);
761 $results[] = array('link' => advanced_help_url("help/$sid->module/$sid->topic"),
762 'title' => $info['title'],
763 'snippet' => search_excerpt($keys, $text));
764 }
765 return $results;
766 }
767 }
768
769 /**
770 * Get or create an sid (search id) that correllates to each topic for
771 * the search system.
772 */
773 function advanced_help_get_sids(&$topics) {
774 global $language;
775 $result = db_query("SELECT * FROM {advanced_help_index} WHERE language = '%s'", $language->language);
776 while ($sid = db_fetch_object($result)) {
777 if (empty($topics[$sid->module][$sid->topic])) {
778 db_query("DELETE FROM {advanced_help_index} WHERE sid = %d", $sid->sid);
779 }
780 else {
781 $topics[$sid->module][$sid->topic]['sid'] = $sid->sid;
782 }
783 }
784 }
785
786 /**
787 * Implementation of hook_update_index().
788 */
789 function advanced_help_update_index() {
790 global $language;
791
792 // If we got interrupted by limit, this will contain the last module
793 // and topic we looked at.
794 $last = variable_get('advanced_help_last_cron', array('time' => 0));
795 $limit = intval(variable_get('search_cron_limit', 100));
796 $topics = advanced_help_get_topics();
797 advanced_help_get_sids($topics);
798
799 $count = 0;
800
801 foreach ($topics as $module => $module_topics) {
802 // Fast forward if necessary.
803 if (!empty($last['module']) && $last['module'] != $module) {
804 continue;
805 }
806
807 foreach ($module_topics as $topic => $info) {
808 // Fast forward if necessary.
809 if (!empty($last['topic']) && $last['topic'] != $topic) {
810 continue;
811 }
812
813 // If we've been looking to catch up, and we have, reset so we
814 // stop fast forwarding.
815 if (!empty($last['module'])) {
816 unset($last['topic']);
817 unset($last['module']);
818 }
819
820 $file = advanced_help_get_topic_filename($module, $topic);
821 if ($file && (empty($info['sid']) || filemtime($file) > $last['time'])) {
822 if (empty($info['sid'])) {
823 db_query("INSERT INTO {advanced_help_index} (module, topic, language) VALUES ('%s', '%s', '%s')", $module, $topic, $language->language);
824 $info['sid'] = db_last_insert_id('advanced_help_index', 'sid');
825 }
826
827 search_index($info['sid'], 'help', '<h1>' . $info['title'] . '</h1>' . file_get_contents($file));
828 $count++;
829 if ($count >= $limit) {
830 $last['topic'] = $topic;
831 $last['module'] = $module;
832 // Don't change time if we stop.
833 variable_set('advanced_help_last_cron', $last);
834 return;
835 }
836 }
837 }
838 }
839 variable_set('advanced_help_last_cron', array('time' => time()));
840 }
841
842 /**
843 * Fill in a bunch of page variables for our specialized popup page.
844 */
845 function template_preprocess_advanced_help_popup(&$variables) {
846 // Add favicon.
847 if (theme_get_setting('toggle_favicon')) {
848 drupal_set_html_head('<link rel="shortcut icon" href="'. check_url(theme_get_setting('favicon')) .'" type="image/x-icon" />');
849 }
850
851 global $theme;
852 // Construct page title.
853 if (drupal_get_title()) {
854 $head_title = array(strip_tags(drupal_get_title()), variable_get('site_name', 'Drupal'));
855 }
856 else {
857 $head_title = array(variable_get('site_name', 'Drupal'));
858 if (variable_get('site_slogan', '')) {
859 $head_title[] = variable_get('site_slogan', '');
860 }
861 }
862
863 drupal_add_css(drupal_get_path('module', 'advanced_help') . '/help-popup.css');
864 drupal_add_css(drupal_get_path('module', 'advanced_help') . '/help.css');
865
866 $variables['head_title'] = implode(' | ', $head_title);
867 $variables['base_path'] = base_path();
868 $variables['front_page'] = url();
869 $variables['breadcrumb'] = theme('breadcrumb', drupal_get_breadcrumb());
870 $variables['feed_icons'] = drupal_get_feeds();
871 $variables['head'] = drupal_get_html_head();
872 $variables['language'] = $GLOBALS['language'];
873 $variables['language']->dir = $GLOBALS['language']->direction ? 'rtl' : 'ltr';
874 $variables['logo'] = theme_get_setting('logo');
875 $variables['messages'] = theme('status_messages');
876 $variables['site_name'] = (theme_get_setting('toggle_name') ? variable_get('site_name', 'Drupal') : '');
877 $variables['css'] = drupal_add_css();
878 $css = drupal_add_css();
879
880 // Remove theme css.
881 foreach ($css as $media => $types) {
882 if (isset($css[$media]['theme'])) {
883 $css[$media]['theme'] = array();
884 }
885 }
886
887 $variables['styles'] = drupal_get_css($css);
888 $variables['scripts'] = drupal_get_js();
889 $variables['title'] = drupal_get_title();
890 // Closure should be filled last.
891 $variables['closure'] = theme('closure');
892 }
893
894 /**
895 * Format a link but preserve popup identity.
896 */
897 function advanced_help_l($text, $dest, $options = array()) {
898 $popup = !empty($_GET['popup']) && user_access('view advanced help popup');
899 if ($popup) {
900 if (empty($options['query'])) {
901 $options['query'] = array();
902 }
903
904 if (is_array($options['query'])) {
905 $options['query'] += array('popup' => TRUE);
906 }
907 else {
908 $options['query'] += '&popup=TRUE';
909 }
910 }
911
912 return l($text, $dest, $options);
913 }
914
915 /**
916 * Format a URL but preserve popup identity.
917 */
918 function advanced_help_url($dest, $options = array()) {
919 $popup = !empty($_GET['popup']) && user_access('view advanced help popup');
920 if ($popup) {
921 if (empty($options['query'])) {
922 $options['query'] = array();
923 }
924
925 $options['query'] += array('popup' => TRUE);
926 }
927
928 return url($dest, $options);
929 }

  ViewVC Help
Powered by ViewVC 1.1.2