[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/advanced_help/ -> advanced_help.module (source)

   1  <?php
   2  // $Id: advanced_help.module,v 1.41 2008/10/28 17:33:47 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  }


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7