summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManu Chaudhary2013-02-21 20:48:16 (GMT)
committer Manu Chaudhary2013-02-21 20:48:16 (GMT)
commitaee61fa84536decc9e45e2d33c1d186fff0a4d72 (patch)
tree0f6275c487049c007ec4db232957bdfa7ccda759
First commit - removed direct SQL queries
-rw-r--r--LICENSE.txt339
-rw-r--r--advanced-help-popup.tpl.php41
-rw-r--r--advanced_help.info7
-rw-r--r--advanced_help.install65
-rw-r--r--advanced_help.module1051
-rw-r--r--help-icon.css19
-rw-r--r--help-popup.css114
-rw-r--r--help.css68
-rw-r--r--help.pngbin0 -> 1025 bytes
-rw-r--r--help/advanced_help.help.ini15
-rw-r--r--help/ini-file.html53
-rw-r--r--help/translation.html9
-rw-r--r--help/using-advanced-help.html45
-rw-r--r--help/why-advanced-help.html44
-rw-r--r--help_example/help/180px-Andi_Gutmans_1.jpgbin0 -> 11007 bytes
-rw-r--r--help_example/help/180px-Lerdorf.jpgbin0 -> 14535 bytes
-rw-r--r--help_example/help/180px-PHP_Hello_World_screenshot.pngbin0 -> 10133 bytes
-rw-r--r--help_example/help/about-php.html5
-rw-r--r--help_example/help/help_example.help.ini24
-rw-r--r--help_example/help/history.html23
-rw-r--r--help_example/help/security.html1
-rw-r--r--help_example/help/syntax.html38
-rw-r--r--help_example/help/usage.html9
-rw-r--r--help_example/help_example.info7
-rw-r--r--help_example/help_example.module29
25 files changed, 2006 insertions, 0 deletions
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/advanced-help-popup.tpl.php b/advanced-help-popup.tpl.php
new file mode 100644
index 0000000..45634d7
--- /dev/null
+++ b/advanced-help-popup.tpl.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * @file
+ * Default theme implementation to display a help popup.
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language ?>" lang="<?php print $language->language ?>" dir="<?php print $language->dir ?>">
+
+<head>
+ <title><?php print $head_title; ?></title>
+ <?php print $head; ?>
+ <?php print $styles; ?>
+ <?php print $scripts; ?>
+ <script type="text/javascript"><?php /* Needed to avoid Flash of Unstyled Content in IE */ ?> </script>
+</head>
+<body>
+ <div id="page">
+ <div id="header">
+ <?php if (!empty($search_box)): ?>
+ <div id="search-box"><?php print $search_box; ?></div>
+ <?php endif; ?>
+ </div> <!-- /header -->
+ <div id="breadcrumb"><?php print $breadcrumb; ?></div>
+
+ <div id="content">
+ <?php if (!empty($title)): ?><h1 class="title" id="page-title"><?php print $title; ?></h1><?php endif; ?>
+ <?php if (!empty($tabs)): ?><div class="tabs"><?php print $tabs; ?></div><?php endif; ?>
+ <?php if (!empty($messages)): print $messages; endif; ?>
+ <?php if (!empty($help)): print $help; endif; ?>
+ <div id="content-content" class="clear-block">
+ <?php print $content; ?>
+ </div> <!-- /content-content -->
+ </div> <!-- /content -->
+
+ <?php print $closure; ?>
+
+ </div> <!-- /page -->
+</body>
+</html>
diff --git a/advanced_help.info b/advanced_help.info
new file mode 100644
index 0000000..db5953e
--- /dev/null
+++ b/advanced_help.info
@@ -0,0 +1,7 @@
+name = Advanced help
+description = Allow advanced help and documentation.
+core = 8.x
+files[] = advanced_help.module
+files[] = advanced_help.install
+
+; \ No newline at end of file
diff --git a/advanced_help.install b/advanced_help.install
new file mode 100644
index 0000000..ce9a878
--- /dev/null
+++ b/advanced_help.install
@@ -0,0 +1,65 @@
+<?php
+/**
+ * @file
+ * Contains install and update functions for advanced_help.
+ */
+
+/**
+ * Implements hook_install().
+ */
+function advanced_help_install() {
+ // drupal_set_message('Installing advanced_help.');
+}
+
+/**
+ * Implements hook_uninstall().
+ */
+function advanced_help_uninstall() {
+ variable_del('advanced_help_last_cron');
+}
+
+/**
+ * Implements hook_schema().
+ */
+function advanced_help_schema() {
+ $schema['advanced_help_index'] = array(
+ 'description' => 'Stores search index correlations for advanced help topics.',
+ 'fields' => array(
+ 'sid' => array(
+ 'type' => 'serial',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'description' => 'The primary key to give to the search engine for this topic.',
+ 'no export' => TRUE,
+ ),
+ 'module' => array(
+ 'type' => 'varchar',
+ 'length' => '255',
+ 'default' => '',
+ 'not null' => TRUE,
+ 'description' => 'The module that owns this topic.',
+ ),
+ 'topic' => array(
+ 'type' => 'varchar',
+ 'length' => '255',
+ 'default' => '',
+ 'not null' => TRUE,
+ 'description' => 'The topic id.',
+ ),
+ 'language' => array(
+ 'type' => 'varchar',
+ 'length' => 12,
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'The language this search index relates to.',
+ ),
+ ),
+ 'primary key' => array('sid'),
+ 'indexes' => array('language' => array('language')),
+ 'foreign keys' => array(
+ 'module' => array('system' => 'name'),
+ ),
+ );
+
+ return $schema;
+}
diff --git a/advanced_help.module b/advanced_help.module
new file mode 100644
index 0000000..dd21423
--- /dev/null
+++ b/advanced_help.module
@@ -0,0 +1,1051 @@
+<?php
+/**
+ * @file
+ *
+ * Pluggable system to provide advanced help facilities for Drupal and modules.
+ *
+ * Modules utilizing this help system should create a 'help' directory in their
+ * module. Inside that directory place MODULENAME.help.ini which will be formatted
+ * like this:
+ *
+ * @code
+ * [buses]
+ * title = "How buses are tied into the system"
+ * file = buses
+ *
+ * [TOPIC_ID]
+ * title = "Title of topic"
+ * file = filename of topic, without the .html extension
+ * weight = the importance of the topic on the index page
+ * parent = the optional topic parent to use in the breadcrumb. Can be either topic or module%topic
+ * @endcode
+ *
+ * All topics are addressed by the module that provides the topic, and the topic
+ * id. Links may be embedded as in the following example:
+ *
+ * @code
+ * $output .= theme('advanced_help_topic', $module, $topic);
+ * @endcode
+ *
+ * Link to other topics using <a href="topic:module/topic">. (Using
+ * this format ensures the popup status remains consistent for all
+ * links.)
+ */
+
+/**
+ * Implements hook_menu().
+ */
+function advanced_help_menu() {
+ // View help topic index.
+
+ // This is structured a little oddly so POTX can properly handle the translation.
+ if (module_exists('help')) {
+ $items['admin/advanced_help'] = array(
+ 'title' => 'Advanced help',
+ 'page callback' => 'advanced_help_index_page',
+ 'access arguments' => array('view advanced help index'),
+ 'weight' => 9,
+ );
+ }
+ else {
+ $items['admin/advanced_help'] = array(
+ 'title' => 'Help',
+ 'page callback' => 'advanced_help_index_page',
+ 'access arguments' => array('view advanced help index'),
+ 'weight' => 9,
+ );
+ }
+ $items['advanced_help/search/%menu_tail'] = array(
+ 'title' => 'Search help',
+ 'page callback' => 'advanced_help_search_view',
+ 'page arguments' => array('advanced_help'),
+ 'access arguments' => array('view advanced help index'),
+ );
+
+ // View help topic.
+ $items['help/%/%'] = array(
+ 'page callback' => 'advanced_help_topic_page',
+ 'page arguments' => array(1, 2),
+ 'access arguments' => array('view advanced help topic'),
+ 'type' => MENU_CALLBACK,
+ );
+
+ return $items;
+}
+
+/**
+ * Implements hook_menu_alter().
+ */
+function advanced_help_menu_alter(&$callbacks) {
+ // We need to fix the menu item provided by search module to restrict access.
+ $callbacks['search/advanced_help/%menu_tail']['access callback'] = 'user_access';
+ $callbacks['search/advanced_help/%menu_tail']['access arguments'] = array('view advanced help index');
+}
+
+/**
+ * Implements hook_theme().
+ */
+function advanced_help_theme() {
+ $hooks['advanced_help_topic'] = array(
+ 'variables' => array(
+ 'module' => NULL,
+ 'topic' => NULL,
+ 'type' => 'icon',
+ ),
+ );
+
+ $hooks['advanced_help_popup'] = array(
+ 'render element' => 'content',
+ 'template' => 'advanced-help-popup',
+ );
+
+ return $hooks;
+}
+
+function advanced_help_uasort($id_a, $id_b) {
+ $topics = advanced_help_get_topics();
+ list($module_a, $topic_a) = $id_a;
+ $a = $topics[$module_a][$topic_a];
+ list($module_b, $topic_b) = $id_b;
+ $b = $topics[$module_b][$topic_b];
+
+ $a_weight = isset($a['weight']) ? $a['weight'] : 0;
+ $b_weight = isset($b['weight']) ? $b['weight'] : 0;
+ if ($a_weight != $b_weight) {
+ return ($a_weight < $b_weight) ? -1 : 1;
+ }
+
+ if ($a['title'] != $b['title']) {
+ return ($a['title'] < $b['title']) ? -1 : 1;
+ }
+ return 0;
+}
+
+/**
+ * Page callback for advanced help search.
+ */
+function advanced_help_search_view() {
+ if (!module_exists('search')) {
+ return drupal_not_found();
+ }
+
+ $breadcrumb[] = advanced_help_l(t('Help'), 'admin/advanced_help');
+
+ if (!isset($_POST['form_id'])) {
+ $keys = search_get_keys();
+ // Only perform search if there is non-whitespace search term:
+ $results = '';
+ if (trim($keys)) {
+ // Collect the search results:
+ $results = array(
+ '#type' => 'markup',
+ '#markup' => search_data($keys, 'advanced_help'),
+ );
+ }
+
+ // Construct the search form.
+ $output['advanced_help_search_form'] = drupal_get_form('advanced_help_search_form', $keys);
+ $output['results'] = $results;
+
+ }
+ else {
+ $output = drupal_get_form('advanced_help_search_form', empty($keys) ? '' : $keys);
+ }
+
+ $popup = !empty($_GET['popup']) && user_access('view advanced help popup');
+ if ($popup) {
+ $GLOBALS['devel_shutdown'] = FALSE; // Prevent devel module from spewing.
+ module_invoke('admin_menu', 'suppress'); // Suppress admin_menu.
+ drupal_set_breadcrumb(array_reverse($breadcrumb));
+ print theme('advanced_help_popup', array('content' => $output));
+ return;
+ }
+
+ $breadcrumb = array_merge(drupal_get_breadcrumb(), array_reverse($breadcrumb));
+ drupal_set_breadcrumb($breadcrumb);
+ return $output;
+}
+
+/**
+ * Page callback to view the advanced help topic index.
+ *
+ * @param string $module
+ * @return array
+ */
+function advanced_help_index_page($module = '') {
+ $topics = advanced_help_get_topics();
+ $settings = advanced_help_get_settings();
+
+ $output = array();
+ // Print a search widget.
+ $output['advanced_help_search'] = module_exists('search')
+ ? drupal_get_form('advanced_help_search_form')
+ : t('Enable the search module to search help.');
+
+ $breadcrumb = array();
+ if ($module) {
+ if (empty($topics[$module])) {
+ return drupal_not_found();
+ }
+
+ advanced_help_get_topic_hierarchy($topics);
+ $items = advanced_help_get_tree($topics, $topics[$module]['']['children']);
+
+ $breadcrumb[] = advanced_help_l(t('Help'), 'admin/advanced_help');
+
+ drupal_set_title(t('@module help index', array('@module' => advanced_help_get_module_name($module))));
+ $output['items-module'] = array(
+ '#theme' => 'item_list',
+ '#items' => $items,
+ );
+ }
+ else {
+
+ // Print a module index.
+ $modules = array();
+ $result = system_get_info('module');
+ foreach ($result as $key => $info) {
+ $modules[$key] = $info['name'];
+ }
+
+ asort($modules);
+
+ $items = array();
+ foreach ($modules as $module => $module_name) {
+ if (!empty($topics[$module]) && empty($settings[$module]['hide'])) {
+ if (isset($settings[$module]['index name'])) {
+ $name = $settings[$module]['index name'];
+ }
+ elseif (isset($settings[$module]['name'])) {
+ $name = $settings[$module]['name'];
+ }
+ else {
+ $name = t($module_name);
+ }
+ $items[] = advanced_help_l($name, "admin/advanced_help/$module");
+ }
+ }
+
+ drupal_set_title(t('Module help index'));
+ $output['items-nomodule'] = array(
+ '#theme' => 'item_list',
+ '#items' => $items,
+ );
+ }
+
+ $popup = !empty($_GET['popup']) && user_access('view advanced help popup');
+ if ($popup) {
+ $GLOBALS['devel_shutdown'] = FALSE; // Prevent devel module from spewing.
+ module_invoke('admin_menu', 'suppress'); // Suppress admin_menu.
+ drupal_set_breadcrumb(array_reverse($breadcrumb));
+ print theme('advanced_help_popup', array('content' => $output));
+ return;
+ }
+
+ $breadcrumb = array_merge(drupal_get_breadcrumb(), array_reverse($breadcrumb));
+ drupal_set_breadcrumb($breadcrumb);
+ return $output;
+}
+
+/**
+ * Build a tree of advanced help topics.
+ *
+ * @param array $topics
+ * @param array $topic_ids
+ * @param int $max_depth
+ * @param int $depth
+ * @return array
+ */
+function advanced_help_get_tree($topics, $topic_ids, $max_depth = -1, $depth = 0) {
+ uasort($topic_ids, 'advanced_help_uasort');
+ $items = array();
+ foreach ($topic_ids as $info) {
+ list($module, $topic) = $info;
+ $item = advanced_help_l($topics[$module][$topic]['title'], "help/$module/$topic");
+ if (!empty($topics[$module][$topic]['children']) && ($max_depth == -1 || $depth < $max_depth)) {
+ $item .= theme('item_list', array('items' =>
+ advanced_help_get_tree($topics, $topics[$module][$topic]['children'], $max_depth, $depth + 1)));
+ }
+
+ $items[] = $item;
+ }
+
+ return $items;
+}
+
+/**
+ * Build a hierarchy for a single module's topics.
+ */
+function advanced_help_get_topic_hierarchy(&$topics) {
+ foreach ($topics as $module => $module_topics) {
+ foreach ($module_topics as $topic => $info) {
+ $parent_module = $module;
+ // We have a blank topic that we don't want parented to itself.
+ if (!$topic) {
+ continue;
+ }
+
+ if (empty($info['parent'])) {
+ $parent = '';
+ }
+ elseif (strpos($info['parent'], '%')) {
+ list($parent_module, $parent) = explode('%', $info['parent']);
+ if (empty($topics[$parent_module][$parent])) {
+ // If it doesn't exist, top level.
+ $parent = '';
+ }
+ }
+ else {
+ $parent = $info['parent'];
+ if (empty($module_topics[$parent])) {
+ // If it doesn't exist, top level.
+ $parent = '';
+ }
+ }
+
+ if (!isset($topics[$parent_module][$parent]['children'])) {
+ $topics[$parent_module][$parent]['children'] = array();
+ }
+ $topics[$parent_module][$parent]['children'][] = array($module, $topic);
+ $topics[$module][$topic]['_parent'] = array($parent_module, $parent);
+ }
+ }
+}
+
+/**
+ * Implements hook_form_system_modules_alter().
+ *
+ * Add advanced help links to the modules page.
+ */
+function advanced_help_form_system_modules_alter(&$form, &$form_state) {
+ $advanced_help_modules = drupal_map_assoc(array_keys(advanced_help_get_topics()));
+ foreach (element_children($form['modules']) as $group) {
+ foreach (element_children($form['modules'][$group]) as $module) {
+ if (isset($advanced_help_modules[$module])) {
+ $form['modules'][$group][$module]['links']['help'] = array(
+ '#type' => 'link',
+ '#title' => t('Help'),
+ '#href' => "admin/advanced_help/$module",
+ '#options' => array('attributes' => array('class' => array('module-link', 'module-link-help'), 'title' => t('Help'))),
+ );
+ }
+ }
+ }
+}
+
+/**
+ * Form builder callback to build the search form.
+ *
+ * Load search/search.pages so that its template preprocess functions are
+ * visible and can be invoked.
+ */
+function advanced_help_search_form($form, &$form_state, $keys = '') {
+ module_load_include('inc', 'search', 'search.pages');
+ $form = search_form($form, $form_state, advanced_help_url('admin/advanced_help'), $keys, 'advanced_help', t('Search help'));
+
+ $form['basic']['inline']['submit']['#validate'] = array('search_form_validate');
+ $form['basic']['inline']['submit']['#submit'] = array('advanced_help_search_form_submit');
+
+ return $form;
+}
+
+/**
+ * Process a search form submission.
+ */
+function advanced_help_search_form_submit($form, &$form_state) {
+ $keys = $form_state['values']['processed_keys'];
+ if ($keys == '') {
+ form_set_error('keys', t('Please enter some keywords.'));
+ return;
+ }
+
+ $popup = !empty($_GET['popup']) && user_access('view advanced help popup');
+
+ if ($popup) {
+ $form_state['redirect'] = array('advanced_help/search/' . $keys, array('query' => array('popup' => 'true')));
+ }
+ else {
+ $form_state['redirect'] = 'advanced_help/search/' . $keys;
+ }
+}
+
+/**
+ * Small helper function to get a module's proper name.
+ *
+ * @param $module string
+ * @return string
+ */
+function advanced_help_get_module_name($module) {
+ $settings = advanced_help_get_settings();
+ if (isset($settings[$module]['name'])) {
+ $name = $settings[$module]['name'];
+ }
+ else {
+ $info = system_get_info('module',$module);
+ $name = t($info['name']);
+ }
+ return $name;
+}
+
+/**
+ * Page callback to view a help topic.
+ */
+function advanced_help_topic_page($module, $topic) {
+ $info = advanced_help_get_topic($module, $topic);
+ if (!$info) {
+ return drupal_not_found();
+ }
+
+ $popup = !empty($_GET['popup']) && user_access('view advanced help popup');
+
+ drupal_set_title($info['title']);
+
+ // Set up breadcrumb.
+ $breadcrumb = array();
+
+ $parent = $info;
+ $pmodule = $module;
+
+ // Loop checker.
+ $checked = array();
+ while (!empty($parent['parent'])) {
+ if (strpos($parent['parent'], '%')) {
+ list($pmodule, $ptopic) = explode('%', $parent['parent']);
+ }
+ else {
+ $ptopic = $parent['parent'];
+ }
+
+ if (!empty($checked[$pmodule][$ptopic])) {
+ break;
+ }
+ $checked[$pmodule][$ptopic] = TRUE;
+
+ $parent = advanced_help_get_topic($pmodule, $ptopic);
+ if (!$parent) {
+ break;
+ }
+
+ $breadcrumb[] = advanced_help_l($parent['title'], "help/$pmodule/$ptopic");
+ }
+
+ $breadcrumb[] = advanced_help_l(advanced_help_get_module_name($pmodule), "admin/advanced_help/$pmodule");
+ $breadcrumb[] = advanced_help_l(t('Help'), "admin/advanced_help");
+
+ $output = advanced_help_view_topic($module, $topic, $popup);
+ if (empty($output)) {
+ $output = t('Missing help topic.');
+ }
+
+ if ($popup) {
+ $GLOBALS['devel_shutdown'] = FALSE; // Prevent devel module from spewing.
+ module_invoke('admin_menu', 'suppress'); // Suppress admin_menu.
+ drupal_set_breadcrumb(array_reverse($breadcrumb));
+ print theme('advanced_help_popup', array('content' => $output));
+ return;
+ }
+
+ drupal_add_css(drupal_get_path('module', 'advanced_help') . '/help.css');
+ $breadcrumb[] = l(t('Home'), '');
+ drupal_set_breadcrumb(array_reverse($breadcrumb));
+ return $output;
+}
+
+/**
+ * Implements hook_permission().
+ */
+function advanced_help_permission() {
+ return array(
+ 'view advanced help topic' => array('title' => t('View help topics')),
+ 'view advanced help popup' => array('title' => t('View help popups')),
+ 'view advanced help index' => array('title' => t('View help index')),
+ );
+}
+
+/**
+ * Display a help icon with a link to view the topic in a popup.
+ *
+ * @param $variables
+ * An associative array containing:
+ * - module: The module that owns this help topic.
+ * - topic: The identifier for the topic
+ * - type
+ * - 'icon' to display the question mark icon
+ * - 'title' to display the topic's title
+ * - any other text to display the text. Be sure to t() it!
+ */
+function theme_advanced_help_topic($variables) {
+ $module = $variables['module'];
+ $topic = $variables['topic'];
+ $type = $variables['type'];
+
+ $info = advanced_help_get_topic($module, $topic);
+ if (!$info) {
+ return;
+ }
+
+ switch ($type) {
+ case 'icon':
+ $text = '<span>' . t('Help') . '</span>';
+ $class = 'advanced-help-link';
+ break;
+
+ case 'title':
+ $text = $info['title'];
+ $class = 'advanced-help-title';
+ break;
+
+ default:
+ $class = 'advanced-help-title';
+ $text = $type;
+ break;
+ }
+
+ if (user_access('view advanced help popup')) {
+ drupal_add_css(drupal_get_path('module', 'advanced_help') . '/help-icon.css');
+ return l($text, "help/$module/$topic", array(
+ 'attributes' => array(
+ 'class' => $class,
+ 'onclick' => "var w=window.open(this.href, 'advanced_help_window', 'width=" . $info['popup width'] . ",height=" . $info['popup height'] . ",scrollbars,resizable'); w.focus(); return false;",
+ 'title' => $info['title']
+ ),
+ 'query' => array('popup' => TRUE),
+ 'html' => TRUE)
+ );
+ }
+ else {
+ return l($text, "help/$module/$topic", array(
+ 'attributes' => array(
+ 'class' => $class,
+ 'title' => $info['title']
+ ),
+ 'html' => TRUE)
+ );
+ }
+}
+
+/**
+ * Load and render a help topic.
+ */
+function advanced_help_get_topic_filename($module, $topic) {
+ $info = advanced_help_get_topic_file_info($module, $topic);
+ if ($info) {
+ return "./$info[path]/$info[file]";
+ }
+}
+/**
+ * Load and render a help topic.
+ */
+function advanced_help_get_topic_file_info($module, $topic) {
+ global $language;
+
+ $info = advanced_help_get_topic($module, $topic);
+ if (empty($info)) {
+ return;
+ }
+
+ // Search paths:
+ $paths = array(
+ path_to_theme() . '/help', // Allow theme override.
+ drupal_get_path('module', $module) . "/translations/help/$language->language", // Translations.
+ $info['path'], // In same directory as .inc file.
+ );
+
+ foreach ($paths as $path) {
+ if (file_exists("./$path/$info[file]")) {
+ return array('path' => $path, 'file' => $info['file']);
+ }
+ }
+}
+
+/**
+ * Load and render a help topic.
+ *
+ * @param string $module
+ * @param string $topic
+ * @param boolean $popup
+ * @return array
+ */
+function advanced_help_view_topic($module, $topic, $popup = FALSE) {
+ $file_info = advanced_help_get_topic_file_info($module, $topic);
+ if ($file_info) {
+ $info = advanced_help_get_topic($module, $topic);
+ $file = "./$file_info[path]/$file_info[file]";
+
+ $output = file_get_contents($file);
+ if (isset($info['readme file']) && $info['readme file']) {
+ // Readme files are treated as plain text: filter accordingly.
+ $output = check_plain($output);
+ }
+
+ // Make some exchanges. The strtr is because url() translates $ into %24
+ // but we need to change it back for the regex replacement.
+
+ // Change 'topic:' to the URL for another help topic.
+ if ($popup) {
+ $output = preg_replace('/href="topic:([^"]+)"/', 'href="' . strtr(url('help/$1', array('query' => array('popup' => 'true'))), array('%24' => '$')) . '"', $output);
+ $output = preg_replace('/src="topic:([^"]+)"/', 'src="' . strtr(url('help/$1', array('query' => array('popup' => 'true'))), array('%24' => '$')) . '"', $output);
+ $output = preg_replace('/&topic:([^"]+)&/', strtr(url('help/$1', array('query' => array('popup' => 'true'))), array('%24' => '$')) , $output);
+ }
+ else {
+ $output = preg_replace('/href="topic:([^"]+)"/', 'href="' . strtr(url('help/$1'), array('%24' => '$')) . '"', $output);
+ $output = preg_replace('/src="topic:([^"]+)"/', 'src="' . strtr(url('help/$1'), array('%24' => '$')) . '"', $output);
+ $output = preg_replace('/&topic:([^"]+)&/', strtr(url('help/$1'), array('%24' => '$')), $output);
+ }
+
+ global $base_path;
+
+ // Change 'path:' to the URL to the base help directory.
+ $output = preg_replace('/href="path:([^"]+)"/', 'href="' . $base_path . $info['path'] . '/$1"', $output);
+ $output = preg_replace('/src="path:([^"]+)"/', 'src="' . $base_path . $info['path'] . '/$1"', $output);
+ $output = str_replace('&path&', $base_path . $info['path'] . '/', $output);
+
+ // Change 'trans_path:' to the URL to the actual help directory.
+ $output = preg_replace('/href="trans_path:([^"]+)"/', 'href="' . $base_path . $file_info['path'] . '/$1"', $output);
+ $output = preg_replace('/src="trans_path:([^"]+)"/', 'src="' . $base_path . $file_info['path'] . '/$1"', $output);
+ $output = str_replace('&trans_path&', $base_path . $file_info['path'] . '/', $output);
+
+ // Change 'base_url:' to the URL to the site.
+ $output = preg_replace('/href="base_url:([^"]+)"/', 'href="' . strtr(url('$1'), array('%24' => '$')) . '"', $output);
+ $output = preg_replace('/src="base_url:([^"]+)"/', 'src="' . strtr(url('$1'), array('%24' => '$')) . '"', $output);
+ $output = preg_replace('/&base_url&([^"]+)"/', strtr(url('$1'), array('%24' => '$')) . '"', $output);
+
+ // Run the line break filter if requested
+ if (!empty($info['line break'])) {
+ // Remove the header since it adds an extra <br /> to the filter.
+ $output = preg_replace('/^<!--[^\n]*-->\n/', '', $output);
+
+ $output = _filter_autop($output);
+ }
+
+ if (!empty($info['navigation'])) {
+ $topics = advanced_help_get_topics();
+ advanced_help_get_topic_hierarchy($topics);
+ if (!empty($topics[$module][$topic]['children'])) {
+ $items = advanced_help_get_tree($topics, $topics[$module][$topic]['children']);
+ $output .= theme('item_list', array('items' => $items));
+ }
+
+ list($parent_module, $parent_topic) = $topics[$module][$topic]['_parent'];
+ if ($parent_topic) {
+ $parent = $topics[$module][$topic]['_parent'];
+ $up = "help/$parent[0]/$parent[1]";
+ }
+ else {
+ $up = "admin/advanced_help/$module";
+ }
+
+ $siblings = $topics[$parent_module][$parent_topic]['children'];
+ uasort($siblings, 'advanced_help_uasort');
+ $prev = $next = NULL;
+ $found = FALSE;
+ foreach ($siblings as $sibling) {
+ list($sibling_module, $sibling_topic) = $sibling;
+ if ($found) {
+ $next = $sibling;
+ break;
+ }
+ if ($sibling_module == $module && $sibling_topic == $topic) {
+ $found = TRUE;
+ continue;
+ }
+ $prev = $sibling;
+ }
+
+ if ($prev || $up || $next) {
+ $navigation = '<div class="help-navigation clear-block">';
+
+ if ($prev) {
+ $navigation .= advanced_help_l('<< ' . $topics[$prev[0]][$prev[1]]['title'], "help/$prev[0]/$prev[1]", array('attributes' => array('class' => 'help-left')));
+ }
+ if ($up) {
+ $navigation .= advanced_help_l(t('Up'), $up, array('attributes' => array('class' => $prev ? 'help-up' : 'help-up-noleft')));
+ }
+ if ($next) {
+ $navigation .= advanced_help_l($topics[$next[0]][$next[1]]['title'] . ' >>', "help/$next[0]/$next[1]", array('attributes' => array('class' => 'help-right')));
+ }
+
+ $navigation .= '</div>';
+
+ $output .= $navigation;
+ }
+ }
+
+ if (!empty($info['css'])) {
+ drupal_add_css($info['path'] . '/' . $info['css']);
+ }
+
+ $output = '<div class="advanced-help-topic">' . $output . '</div>';
+ drupal_alter('advanced_help_topic', $output, $popup);
+ return $output;
+ }
+}
+
+/**
+ * Get the information for a single help topic.
+ */
+function advanced_help_get_topic($module, $topic) {
+ $topics = advanced_help_get_topics();
+ if (!empty($topics[$module][$topic])) {
+ return $topics[$module][$topic];
+ }
+}
+
+/**
+ * Search the system for all available help topics.
+ */
+function advanced_help_get_topics() {
+ $cache = _advanced_help_parse_ini();
+ return $cache['topics'];
+}
+
+function advanced_help_get_settings() {
+ $cache = _advanced_help_parse_ini();
+ return $cache['settings'];
+}
+
+function _advanced_help_parse_ini() {
+ static $cache = NULL;
+
+ if (!isset($cache)) {
+ $cache = array('topics' => array(), 'settings' => array());
+
+ $help_path = drupal_get_path('module', 'advanced_help') . '/modules';
+ foreach (module_list() as $module) {
+ $module_path = drupal_get_path('module', $module);
+ $info = array();
+ if (file_exists("$module_path/help/$module.help.ini")) {
+ $path = "$module_path/help";
+ $info = parse_ini_file("./$module_path/help/$module.help.ini", TRUE);
+ }
+ elseif (file_exists("$help_path/$module/$module.help.ini")) {
+ $path = "$help_path/$module";
+ $info = parse_ini_file("./$help_path/$module/$module.help.ini", TRUE);
+ }
+ elseif (!file_exists("$module_path/help")) {
+ // Look for one or more README files.
+ $files = file_scan_directory("./$module_path",
+ '/^(README|readme).*\.(txt|TXT)$/', array('.', '..', 'CVS'),
+ 0, FALSE);
+ $path = "./$module_path";
+ foreach ($files as $name => $fileinfo) {
+ $info[$fileinfo->filename] = array(
+ 'line break' => TRUE,
+ 'readme file' => TRUE,
+ 'file' => $fileinfo->filename,
+ 'title' => $fileinfo->name,
+ );
+ }
+ }
+
+ if (!empty($info)) {
+
+ // Get translated titles:
+ global $language;
+ $translation = array();
+ if (file_exists("$module_path/translations/help/en/$module.help.ini")) {
+ $translation = parse_ini_file("$module_path/translations/help/en/$module.help.ini", TRUE);
+ }
+
+ $cache['settings'][$module] = array();
+ if (!empty($info['advanced help settings'])) {
+ $cache['settings'][$module] = $info['advanced help settings'];
+ unset($info['advanced help settings']);
+
+ // Check translated strings for translatable global settings.
+ if (isset($translation['advanced help settings']['name'])) {
+ $cache['settings']['name'] = $translation['advanced help settings']['name'];
+ }
+ if (isset($translation['advanced help settings']['index name'])) {
+ $cache['settings']['index name'] = $translation['advanced help settings']['index name'];
+ }
+
+ }
+
+ foreach ($info as $name => $topic) {
+ // Each topic should have a name, a title, a file and of course the path.
+ $file = !empty($topic['file']) ? $topic['file'] : $name;
+ $cache['topics'][$module][$name] = array(
+ 'name' => $name,
+ 'title' => !empty($translation[$name]['title']) ? $translation[$name]['title'] : $topic['title'],
+ 'weight' => isset($topic['weight']) ? $topic['weight'] : 0,
+ 'parent' => isset($topic['parent']) ? $topic['parent'] : 0,
+ 'popup width' => isset($topic['popup width']) ? $topic['popup width'] : 500,
+ 'popup height' => isset($topic['popup height']) ? $topic['popup height'] : 500,
+ 'file' => isset($topic['readme file']) ? $file : $file . '.html', // require extension
+ 'path' => $path, // not in .ini file
+ 'line break' => isset($topic['line break']) ? $topic['line break'] : (isset($cache['settings'][$module]['line break']) ? $cache['settings'][$module]['line break'] : FALSE),
+ 'navigation' => isset($topic['navigation']) ? $topic['navigation'] : (isset($cache['settings'][$module]['navigation']) ? $cache['settings'][$module]['navigation'] : TRUE),
+ 'css' => isset($topic['css']) ? $topic['css'] : (isset($cache['settings'][$module]['css']) ? $cache['settings'][$module]['css'] : NULL),
+ 'readme file' => isset($topic['readme file']) ? $topic['readme file'] : FALSE,
+ );
+ }
+ }
+ }
+ drupal_alter('advanced_help_topic_info', $cache);
+ }
+ return $cache;
+}
+
+/**
+ * Implements hook_search_info().
+ *
+ * @return array
+ */
+function advanced_help_search_info() {
+ return array(
+ 'title' => t('Help'),
+ 'path' => 'advanced_help',
+ );
+}
+
+/**
+ * Implements hook_search_execute().
+ */
+function advanced_help_search_execute($keys = NULL) {
+ $topics = advanced_help_get_topics();
+
+ $query = db_select('search_index', 'i', array('target' => 'slave'))
+ ->extend('SearchQuery')
+ ->extend('PagerDefault');
+ $query->join('advanced_help_index', 'ahi', 'i.sid = ahi.sid');
+ $query->searchExpression($keys, 'help');
+
+ // Only continue if the first pass query matches.
+ if (!$query->executeFirstPass()) {
+ return array();
+ }
+
+ $results = array();
+
+ $find = $query->execute();
+ foreach ($find as $item) {
+ $sids[] = $item->sid;
+ }
+
+ $query = db_select('advanced_help_index', 'ahi');
+ $result = $query
+ ->fields('ahi')
+ ->condition('sid', $sids, 'IN')
+ ->execute();
+
+ foreach ($result as $sid) {
+ // Guard against removed help topics that are still indexed.
+ if (empty($topics[$sid->module][$sid->topic])) {
+ continue;
+ }
+ $info = $topics[$sid->module][$sid->topic];
+ $text = advanced_help_view_topic($sid->module, $sid->topic);
+ $results[] = array(
+ 'link' => advanced_help_url("help/$sid->module/$sid->topic"),
+ 'title' => $info['title'],
+ 'snippet' => search_excerpt($keys, $text),
+ );
+ }
+ return $results;
+}
+
+/**
+ * Implements hook_search_reset().
+ */
+function advanced_help_search_reset() {
+ variable_del('advanced_help_last_cron');
+}
+
+/**
+ * Implements hook_search_status().
+ */
+function advanced_help_search_status() {
+ $topics = advanced_help_get_topics();
+ $total = 0;
+ foreach ($topics as $module => $module_topics) {
+ foreach ($module_topics as $topic => $info) {
+ $file = advanced_help_get_topic_filename($module, $topic);
+ if ($file) {
+ $total++;
+ }
+ }
+ }
+
+ $last_cron = variable_get('advanced_help_last_cron', array('time' => 0));
+ $indexed = 0;
+ if ($last_cron['time'] != 0) {
+ $indexed = db_query("SELECT COUNT(*) FROM {search_dataset} sd WHERE sd.type = 'help' AND sd.sid IS NOT NULL AND sd.reindex = 0")->fetchField();
+ }
+ return array('remaining' => $total - $indexed, 'total' => $total);
+}
+
+/**
+ * Get or create an sid (search id) that correllates to each topic for
+ * the search system.
+ */
+function advanced_help_get_sids(&$topics) {
+ global $language;
+ $result = db_query("SELECT * FROM {advanced_help_index} WHERE language = :language",
+ array(':language' => $language->language));
+ foreach ($result as $sid) {
+ if (empty($topics[$sid->module][$sid->topic])) {
+ db_query("DELETE FROM {advanced_help_index} WHERE sid = :sid",
+ array(':sid' => $sid->sid));
+ }
+ else {
+ $topics[$sid->module][$sid->topic]['sid'] = $sid->sid;
+ }
+ }
+}
+
+/**
+ * Implements hook_update_index().
+ */
+function advanced_help_update_index() {
+ global $language;
+
+ // If we got interrupted by limit, this will contain the last module
+ // and topic we looked at.
+ $last = variable_get('advanced_help_last_cron', array('time' => 0));
+ $limit = intval(variable_get('search_cron_limit', 100));
+ $topics = advanced_help_get_topics();
+ advanced_help_get_sids($topics);
+
+ $count = 0;
+
+ foreach ($topics as $module => $module_topics) {
+ // Fast forward if necessary.
+ if (!empty($last['module']) && $last['module'] != $module) {
+ continue;
+ }
+
+ foreach ($module_topics as $topic => $info) {
+ // Fast forward if necessary.
+ if (!empty($last['topic']) && $last['topic'] != $topic) {
+ continue;
+ }
+
+ // If we've been looking to catch up, and we have, reset so we
+ // stop fast forwarding.
+ if (!empty($last['module'])) {
+ unset($last['topic']);
+ unset($last['module']);
+ }
+
+ $file = advanced_help_get_topic_filename($module, $topic);
+ if ($file && (empty($info['sid']) || filemtime($file) > $last['time'])) {
+ if (empty($info['sid'])) {
+ $info['sid'] = db_insert('advanced_help_index')
+ ->fields(array(
+ 'module' => $module,
+ 'topic' => $topic,
+ 'language' => $language->language,
+ ))
+ ->execute();
+ }
+
+ search_index($info['sid'], 'help', '<h1>' . $info['title'] . '</h1>' . file_get_contents($file));
+ $count++;
+ if ($count >= $limit) {
+ $last['topic'] = $topic;
+ $last['module'] = $module;
+ // Don't change time if we stop.
+ variable_set('advanced_help_last_cron', $last);
+ return;
+ }
+ }
+ }
+ }
+
+ variable_set('advanced_help_last_cron', array('time' => time()));
+}
+
+/**
+ * Fill in a bunch of page variables for our specialized popup page.
+ */
+function template_preprocess_advanced_help_popup(&$variables) {
+ // Add favicon.
+ if (theme_get_setting('toggle_favicon')) {
+ drupal_add_html_head('<link rel="shortcut icon" href="' . check_url(theme_get_setting('favicon')) . '" type="image/x-icon" />');
+ }
+
+ global $theme;
+ // Construct page title.
+ if (drupal_get_title()) {
+ $head_title = array(strip_tags(drupal_get_title()), variable_get('site_name', 'Drupal'));
+ }
+ else {
+ $head_title = array(variable_get('site_name', 'Drupal'));
+ if (variable_get('site_slogan', '')) {
+ $head_title[] = variable_get('site_slogan', '');
+ }
+ }
+
+ drupal_add_css(drupal_get_path('module', 'advanced_help') . '/help-popup.css');
+ drupal_add_css(drupal_get_path('module', 'advanced_help') . '/help.css');
+
+ $variables['head_title'] = implode(' | ', $head_title);
+ $variables['base_path'] = base_path();
+ $variables['front_page'] = url();
+ $variables['breadcrumb'] = theme('breadcrumb', array('breadcrumb' => drupal_get_breadcrumb()));
+ $variables['feed_icons'] = drupal_get_feeds();
+ $variables['head'] = drupal_get_html_head();
+ $variables['language'] = $GLOBALS['language'];
+ $variables['language']->dir = $GLOBALS['language']->direction ? 'rtl' : 'ltr';
+ $variables['logo'] = theme_get_setting('logo');
+ $variables['messages'] = theme('status_messages');
+ $variables['site_name'] = (theme_get_setting('toggle_name') ? variable_get('site_name', 'Drupal') : '');
+ $variables['css'] = drupal_add_css();
+ $css = drupal_add_css();
+
+ // Remove theme css.
+ foreach ($css as $media => $types) {
+ if (isset($css[$media]['theme'])) {
+ $css[$media]['theme'] = array();
+ }
+ }
+
+ $variables['styles'] = drupal_get_css($css);
+ $variables['scripts'] = drupal_get_js();
+ $variables['title'] = drupal_get_title();
+
+ // this function can be called either with a render array or an already rendered string
+ if (is_array($variables['content'])) {
+ $variables['content'] = drupal_render($variables['content']);
+ }
+ // Closure should be filled last.
+ $variables['closure'] = theme('closure');
+}
+
+/**
+ * Format a link but preserve popup identity.
+ */
+function advanced_help_l($text, $dest, $options = array()) {
+ $popup = !empty($_GET['popup']) && user_access('view advanced help popup');
+ if ($popup) {
+ if (empty($options['query'])) {
+ $options['query'] = array();
+ }
+
+ if (is_array($options['query'])) {
+ $options['query'] += array('popup' => TRUE);
+ }
+ else {
+ $options['query'] += '&popup=TRUE';
+ }
+ }
+
+ return l($text, $dest, $options);
+}
+
+/**
+ * Format a URL but preserve popup identity.
+ */
+function advanced_help_url($dest, $options = array()) {
+ $popup = !empty($_GET['popup']) && user_access('view advanced help popup');
+ if ($popup) {
+ if (empty($options['query'])) {
+ $options['query'] = array();
+ }
+
+ $options['query'] += array('popup' => TRUE);
+ }
+
+ return url($dest, $options);
+}
diff --git a/help-icon.css b/help-icon.css
new file mode 100644
index 0000000..6f4fb0e
--- /dev/null
+++ b/help-icon.css
@@ -0,0 +1,19 @@
+
+.advanced-help-link {
+ width: 12px;
+ height: 12px;
+ background: transparent url('help.png') no-repeat top left;
+ background-position: 0px 0px;
+ display: block;
+ float: left; /* this is cheesy, I know */
+ margin-top: 2px;
+ padding: 0px;
+}
+
+.advanced-help-link span {
+ display: none;
+}
+
+.advanced-help-link:hover {
+ background-position: 0px -12px;
+} \ No newline at end of file
diff --git a/help-popup.css b/help-popup.css
new file mode 100644
index 0000000..edaaffe
--- /dev/null
+++ b/help-popup.css
@@ -0,0 +1,114 @@
+
+body {
+ margin: 0;
+ padding: 0;
+ background: #edf5fa;
+ font: 12px/170% Verdana, sans-serif;
+ color: #494949;
+}
+
+input {
+ font: 12px/100% Verdana, sans-serif;
+ color: #494949;
+}
+
+textarea, select {
+ font: 12px/160% Verdana, sans-serif;
+ color: #494949;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ margin: 0;
+ padding: 0;
+ font-weight: normal;
+ font-family: Helvetica, Arial, sans-serif;
+}
+
+h1 {
+ font-size: 170%;
+}
+
+h2 {
+ font-size: 160%;
+ line-height: 130%;
+}
+
+h3 {
+ font-size: 140%;
+}
+
+h4 {
+ font-size: 130%;
+}
+
+h5 {
+ font-size: 120%;
+}
+
+h6 {
+ font-size: 110%;
+}
+
+ul, quote, code, fieldset {
+ margin: .5em 0;
+}
+
+p {
+ margin: 0.6em 0 1.2em;
+ padding: 0;
+}
+
+a:link, a:visited {
+ color: #027AC6;
+ text-decoration: none;
+}
+
+a:hover {
+ color: #0062A0;
+ text-decoration: underline;
+}
+
+a:active, a.active {
+ color: #5895be;
+}
+
+hr {
+ margin: 0;
+ padding: 0;
+ border: none;
+ height: 1px;
+ background: #5294c1;
+}
+
+ol li, ul li {
+ margin: 0.4em 0 0.4em .5em; /* LTR */
+}
+
+
+#content {
+ margin: .5em 1em 1em 1em;
+}
+
+#content #page-title {
+ padding-bottom: .5em;
+}
+
+div#breadcrumb {
+ padding-left: 1em;
+ background-color: white;
+ border-bottom: 1px solid #ccc;
+ height: 2em;
+}
+
+div#breadcrumb .breadcrumb {
+ padding: 0;
+ margin: 0;
+}
+
+code, pre {
+ border: 1px solid #444;
+ background: #f1f1f1;
+ margin: 1em;
+ padding: .2em;
+ display: block;
+}
diff --git a/help.css b/help.css
new file mode 100644
index 0000000..8754ab4
--- /dev/null
+++ b/help.css
@@ -0,0 +1,68 @@
+
+.advanced-help-topic code, .advanced-help-topic pre {
+ border: 1px solid #444;
+ background: #f1f1f1;
+ margin: 1em;
+ padding: .2em;
+ display: block;
+}
+
+.advanced-help-topic h3,
+.advanced-help-topic h4,
+.advanced-help-topic h5,
+.advanced-help-topic h6,
+.advanced-help-topic dt {
+ font-weight: bold;
+}
+
+.advanced-help-topic li h3,
+.advanced-help-topic li h4,
+.advanced-help-topic li h5,
+.advanced-help-topic li h6 {
+ font-weight: normal;
+}
+
+.help-left {
+ text-align: left;
+ width: 42%;
+ display: block;
+ float: left; /* LTR */
+}
+
+.help-up {
+ margin: 0 5%;
+ width: 4%;
+ display: block;
+ float: left; /* LTR */
+}
+
+.help-up-noleft {
+ margin: 0 5%;
+ width: 42%;
+ text-align: right;
+ display: block;
+ float: left; /* LTR */
+}
+
+.help-right {
+ text-align: right;
+ width: 42%;
+ display: block;
+ float: right;
+}
+
+.help-box {
+ margin: .5em;
+}
+
+.help-navigation {
+ border-top: 1px dotted #ccc;
+}
+
+.help-previous {
+ float: left;
+}
+
+.help-next {
+ float: right;
+}
diff --git a/help.png b/help.png
new file mode 100644
index 0000000..7645023
--- /dev/null
+++ b/help.png
Binary files differ
diff --git a/help/advanced_help.help.ini b/help/advanced_help.help.ini
new file mode 100644
index 0000000..923d559
--- /dev/null
+++ b/help/advanced_help.help.ini
@@ -0,0 +1,15 @@
+
+[using-advanced-help]
+title = Using advanced help
+weight = -10
+
+[translation]
+title = Translating advanced help
+
+[ini-file]
+title = Help .ini file format
+line break = TRUE
+
+[why-advanced-help]
+title = Why advanced help?
+line break = TRUE
diff --git a/help/ini-file.html b/help/ini-file.html
new file mode 100644
index 0000000..375fe67
--- /dev/null
+++ b/help/ini-file.html
@@ -0,0 +1,53 @@
+The advanced help configuration file is in simple .ini file format, divided into sections for each help file, plus an optional section for global settings that might be inherited for each help file.
+
+The first line of an advanced help ini file should be ;&#x24;Id &#x24; which will be a comment providing the CVS identifier for the file. The ; indicates a comment character. Anything after the ; will be ignored.
+
+Global settings may be put into a section named <strong>[advanced help settings]</strong> -- this means that this name is reserved and it cannot be a help file in any module. The following settings may be set in this section:
+<dl>
+<dt><strong>line break</strong></dt>
+<dd>If set to any value, the line break filter will be applied to all help files defined by this module, unless that help file specifically is set otherwise. By default, the line break filter is not applied; however, help files can be much easier to write with the line break filter on.</dd>
+<dt><strong>navigation</strong></dt>
+<dd>If set to true, the navigation will be displayed at the end of the help topic: previous topic, next topic, and child topics.</dd>
+<dt><strong>css</strong></dt>
+<dd>Specify a css file that will be used for all help files (unless overridden), including the .css extension. This .css file must reside in the help directory along with the .html files, and will not be affected by translation.</dd>
+<dt><strong>name</strong></dt>
+<dd>May be set to override the module name as displayed in both the module index as well as the navigation and breadcrumb trail. In general this does not need to be set, but a few modules may want to use a more friendly name than appears in the .info file.</dd>
+<dt><strong>index name</strong></dt>
+<dd>This may be set to change the name of the module in the module index. It overrides the 'name' setting above, as well as the module name in its .info file.</dd>
+<dt><strong>hide</strong></dt>
+<dd>This may be used to hide a module in the module index. This is particularly useful for modules who insert their help files into the hierarchy of another module, as might be done by modules that extend Views or CCK. By setting "hide = TRUE" the module will not appear as its own entry.</dd>
+</dl>
+
+Each section after that will correspond to a single help file, and each one may have the following settings:
+<dl>
+<dt><strong>title</strong></dt>
+<dd>The title of the topic, presented to the user and used in links. If you have special characters in your title, be sure to enclose it in quotes.</dd>
+<dt><strong>file</strong></dt>
+<dd>The filename, without the .html extension, used for the topic. This is optional; if not specified, the topic name wil be the file name.</dd>
+<dt><strong>weight</strong></dt>
+<dd>The weight, used for sorting topics on the administration page. Defaults to 0 of unspecified. Items with the same weight are sorted alphabetically.</dd>
+<dt><strong>parent</strong></dt>
+<dd>The topic ID to use in a hierarchy; children will be listed beneath parents in the topic list, and will have the parent in their breadcrumb trail. You may parent this topic to another module's topic by using module%topic as the identifier. For example, 'views%display' will make this a child of the 'display' topic in the 'views' module.</dd>
+<dt><strong>line break</strong></dt>
+<dd>If set to true, linebreaks will be converted into br and p tags automatically. If unspecified, will default to off. Set to 0 to disable the filter if this has been turned on in the global settings.</dd>
+<dt><strong>css</strong></dt>
+<dd>Specify a css file that will be used for this file. This .css file must reside in the help directory along with the .html files. This will override any .css file added by the global system.</dd>
+<dt><strong>popup width</strong></dt>
+<dd>The width in pixels of the popup window. Defaults to 500 if unspecified.</dd>
+<dt><strong>popup height</strong></dt>
+<dd>The height in pixels of the popup window. Defaults to 500 if unspecified.</dd>
+</dl>
+
+For example, here is a version of the <strong>advanced_help.help.ini</strong> file:
+<pre>
+[using-advanced-help]
+title = "Using advanced help"
+weight = -10
+
+[translation]
+title = Translating advanced help
+
+[ini-file]
+title = Help .ini file format
+line break = TRUE
+</pre> \ No newline at end of file
diff --git a/help/translation.html b/help/translation.html
new file mode 100644
index 0000000..82a2fe7
--- /dev/null
+++ b/help/translation.html
@@ -0,0 +1,9 @@
+<p>To translate advanced help, first create a <b>translations/help/$language</b> directory
+in the module directory. Then, copy the .ini file and all .html files from
+the help directory.</p>
+
+<p>The .ini file only needs to keep the titles, and if there is a 'name' or 'index name' setting in the 'advanced help settings' portion, that should be retained. Any retained settings should be translated. The rest of the data in the .ini file may be discarded or ignored.</p>
+
+<p>Each file should then be translated in place.</p>
+
+<p>When translating a .html file, you will find that the <b>path</b> keyword will lead to the original directory. If you must translate items that are linked, such as images, use <b>trans_path</b> instead, which will lead to the translated directory. This will allow you to pick and choose which linked items, if any, will be translated.</p> \ No newline at end of file
diff --git a/help/using-advanced-help.html b/help/using-advanced-help.html
new file mode 100644
index 0000000..ad85eb6
--- /dev/null
+++ b/help/using-advanced-help.html
@@ -0,0 +1,45 @@
+<p>The <em>Advanced help</em> system is a pluggable system that provides advanced help facilities for Drupal and its modules. Although the advanced help does not provide general help by itself, it provides a powerful and easy framework that modules may use to provide their own help.
+</p>
+
+<p>
+Modules utilizing <em>Advanced help</em> should create a 'help' subdirectory inside their
+module's directory. Place the file MODULENAME.help.ini in this subdirectory, formatted
+similar to the following example:
+</p>
+<pre>
+[buses]
+title = "How buses are tied into the system"
+file = buses
+
+[TOPIC_ID]
+title = "Title of topic".
+file = filename of topic, without the .html extension.
+weight = How important the topic is on the index page.
+parent = The optional topic parent to use in the breadcrumb,
+ either topic or module%topic.
+</pre>
+
+<p>
+All topics are addressed by the module providing the topic, and by the topic
+id. To embed links, use the following format:
+</p>
+<code>
+$output .= theme('advanced_help_topic', $module, $topic);
+</code>
+
+<p>Inside your help file, link to other topics using the format <strong>&lt;a href="&amp;topic:module/topic&amp;"&gt;</strong>. This
+format will ensure the popup status remains consistent when switching between links.</p>
+
+<p>Use <strong>&lt;a href="&amp;path&amp;example.jpg"&gt;</strong> to reference items
+within the help directory, such as images you wish to embed within the help text.</p>
+
+<p>Use <strong>&lt;a href="&amp;base_url&amp;admin/settings/site-configuration"&gt;</strong> to reference any normal path in the site.</p>
+
+<p>If the search module is enabled, the contents of help system will be indexed on cron. If you enable new modules and wish to immediately index its help text, visit the "Administration -> Reports -> Status report" and click the "Run cron manually" link.</p>
+
+<p>Example: <a href="&path&nowhere.jpg">Don't click this!</a></p>
+
+<p>See: <a href="&topic:advanced_help/ini-file&">ini file format</a></p>
+
+<p><strong>NOTE: </strong> In previous versions Advanced Help did not require the &amp;'s wrapped around the topic:, path:, and base_url: links. This
+is currently still supported, but may be removed in a future version. By adding the &'s these tokens are now not limited to href="" and src="" paramaters.</p>
diff --git a/help/why-advanced-help.html b/help/why-advanced-help.html
new file mode 100644
index 0000000..2f12dab
--- /dev/null
+++ b/help/why-advanced-help.html
@@ -0,0 +1,44 @@
+The advanced help system was designed to replace the original Drupal help system, which has several flaws that make it hard to create new help, hard to maintain existing help, and particularly hard to access help.
+
+The primary goal, then, is to increase the accessibility of help, meaning the ability of both the user and the help text author to access the needed tools to use, create, maintain and translate the help.
+
+This system is completely separate from Drupal's hook_help(). In Drupal 6, it actually co-exists with it; in the future, it is hoped that it will completely replace it allowing hook_help() to be deprecated and removed.
+
+Messages added to the top of a page are not really "help". Often these messages are an introduction to a form or a short blurb telling a user what to do with a particular page. The problem is, these messages are always there, they are easily ignored, and they come before the actual page. In general, when users are learning, they want to see the page first, then ask questions. The reverse order is much less conducive to actually teaching a user how to use something. By allowing help to be available on request, the system conforms more naturally to how most people work.
+
+<h3><strong>Advanced help is organized by topic</strong></h3>
+With the hook_help() method, help text is organized by URL path. This is fine if you have help text describing how to use a particular page or what a particular page does, but ultimately is limiting because manuals and documentation are usually grouped by topic, and those topics are determined by the material itself.
+
+Advanced help allows the documentation author to organize topics as he or she sees fit; the only restriction, really, is that each individual chunk of text needs to stand on its own as a discrete topic.
+
+What's more, modules can insert their topics into another module's hierarchy. This would allow the Drupal core to create a task based help navigation system which allows modules insert topics into that navigation fluidly. This allows modules to continue to keep their systems separate, yet integrate into the main system.
+
+<h3><strong>Advanced help topics are processed HTML in their own files</strong></h3>
+This separation makes it easy to find and modify. Currently, everything is lumped together in hook_help() in PHP strings that are run through t(), and there is a fair amount of PHP code necessary in this system that actually gets in the way of writing good, explanatory text.
+
+In fact, requiring a documentation author to understand PHP at all is a detriment. The idea that documentation writers need to have PHP development as a skill seriously reduces the number of available contributors. HTML, on the other hand, is a much more common skill, is relatively easy to learn, and the amount of HTML needed to write documentation is only a little bit more than the HTML used in forum posts.
+
+Another benefit to not using PHP is that the files themselves are safe. They are unlikely to include malicious PHP code that could take over the server or do worse things. This means that these files can be used relatively easily on the drupal.org hardware so that a module's help files can be made immediately available without needing to download the module. It also means that descriptions of the module can be made on drupal.org that are version aware, can be corrected easily in CVS with patches, but can also be made available with the module so that drupal.org is not required.
+
+This also means that we could, if we wanted, package the drupal.org handbooks, or a subset of them, directly into a drupal distribution, or a drupal add-on, so that Drupal administrators can have Drupal help without needing to visit drupal.org. This can be valuable in locked down corporate environments and on planes. But more importantly, the handbooks can be made version aware much more easily than the current method on drupal.org.
+
+The downside to this method is that these books can't easily be made dynamic. Though the use of alter hooks could allow a module to make modifications to the help as needed, doing this could make the help files less useful when you take them out of context.
+
+<h3><strong>Advanced help files are translated as a file</strong></h3>
+It is actually not easy to translate documents as strings, particularly when the language being used is very much unlike English. In fact, when translating a document, the organization of the sentences may change drastically. It is also a burden on the CPU to do this, as you are indexing on very long strings.
+
+Translators have a much better time translating a document as a unit, because of the presence of the entire context.
+
+<h3><strong>Advanced help has its own navigation system</strong></h3>
+By making use of a navigation system specified in a .ini file (which is not PHP code and therefore safe to use on *.drupal.org sites), the help can be structured like a book, which is typical of online manuals. This is familiar to users, can be organized (and re-organized) and allows a module to include significantly richer text without burdening the PHP code with having its help loaded unnecessarily.
+
+This book can be navigated hierarchically as well, making it easy to keep related topics together.
+<h3><strong>Advanced help is indexed by the search engine</strong></h3>
+An important goal of this system was to add searchability to the help. By being able to enter keywords into the search box and find relevant topics, we come up with a system that resembles the kind of help that comes with many operating systems. This is very valuable when searching through manuals trying to find out how to do a particular thing.
+
+This search is specific to the help, meaning that the help will not be mixed in with the global node search. This can be considered both an advantage and a disadvantage. For the most part, this help system is meant to provide help to site administrators, and content searches should not find it. The disadvantage, of course, is when you want to use it for end user help, you will not be able to.
+
+<h3><strong>Inline help can be brought in via popups</strong></h3>
+In addition to the manual-like hierarchical navigation, advanced help can also provide context-sensitive additional help through a popup. While popups are controversial, the argument for using them is that when getting help while on a form, <i>a popup will not throw away a user's data.</i> Browsers are not very friendly to input forms if they are not submitted, and navigating away from the form can be dangerous. There are various other solutions to this problem, but each one has a drawback. The drawbacks to popups are well known, but mostly it is the irritation of having new windows. When getting help, though, a popup is usually invited. Help should not interfere with what the operation the user is trying to complete. It differs greatly from the uninvited popup, which are usually ads or popups meant to prevent users from navigating away from a site.
+
+These popups can be added to a page with text links or icon links.
diff --git a/help_example/help/180px-Andi_Gutmans_1.jpg b/help_example/help/180px-Andi_Gutmans_1.jpg
new file mode 100644
index 0000000..b182676
--- /dev/null
+++ b/help_example/help/180px-Andi_Gutmans_1.jpg
Binary files differ
diff --git a/help_example/help/180px-Lerdorf.jpg b/help_example/help/180px-Lerdorf.jpg
new file mode 100644
index 0000000..5a437f4
--- /dev/null
+++ b/help_example/help/180px-Lerdorf.jpg
Binary files differ
diff --git a/help_example/help/180px-PHP_Hello_World_screenshot.png b/help_example/help/180px-PHP_Hello_World_screenshot.png
new file mode 100644
index 0000000..38f33b8
--- /dev/null
+++ b/help_example/help/180px-PHP_Hello_World_screenshot.png
Binary files differ
diff --git a/help_example/help/about-php.html b/help_example/help/about-php.html
new file mode 100644
index 0000000..f19f30c
--- /dev/null
+++ b/help_example/help/about-php.html
@@ -0,0 +1,5 @@
+<p><b>PHP</b> (<i>PHP: Hypertext Preprocessor</i>) is a computer <a target="_blank" href="http://en.wikipedia.org/wiki/Scripting_language" title="Scripting language">scripting language</a>, originally designed for producing <a target="_blank" href="http://en.wikipedia.org/wiki/Dynamic_web_page" title="Dynamic web page">dynamic web pages</a>. It is mainly used in <a target="_blank" href="http://en.wikipedia.org/wiki/Server-side_scripting" title="Server-side scripting">server-side scripting</a>, but can be used from a <a target="_blank" href="http://en.wikipedia.org/wiki/Command_line_interface" title="Command line interface">command line interface</a> or in <a target="_blank" href="http://en.wikipedia.org/wiki/Standalone" title="Standalone">standalone</a> <a target="_blank" href="http://en.wikipedia.org/wiki/Graphical_user_interface" title="Graphical user interface">graphical applications</a>.<sup id="cite_ref-1" class="reference"><a href="#cite_note-1" title="">[2]</a></sup></p>
+
+<p>While PHP was originally created by <a target="_blank" href="http://en.wikipedia.org/wiki/Rasmus_Lerdorf" title="Rasmus Lerdorf">Rasmus Lerdorf</a> in 1994, the main implementation of PHP is now produced by The PHP Group and serves as the <a target="_blank" href="http://en.wikipedia.org/wiki/De_facto_standard" title="De facto standard"><i>de facto</i> standard</a> for PHP as there is no <a target="_blank" href="http://en.wikipedia.org/wiki/Formal_specification" title="Formal specification">formal specification</a>.<sup id="cite_ref-history_2-0" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup> Released under the <a target="_blank" href="http://en.wikipedia.org/wiki/PHP_License" title="PHP License">PHP License</a>, the <a target="_blank" href="http://en.wikipedia.org/wiki/Free_Software_Foundation" title="Free Software Foundation">Free Software Foundation</a> considers it to be <a target="_blank" href="http://en.wikipedia.org/wiki/Free_software" title="Free software">free software</a>.<sup id="cite_ref-3" class="reference"><a href="#cite_note-3" title="">[4]</a></sup></p>
+
+<p>PHP is a widely-used general-purpose scripting language that is especially suited for <a target="_blank" href="http://en.wikipedia.org/wiki/Web_development" title="Web development">web development</a> and can be embedded into <a target="_blank" href="http://en.wikipedia.org/wiki/HTML" title="HTML">HTML</a>. It generally runs on a <a target="_blank" href="http://en.wikipedia.org/wiki/Web_server" title="Web server">web server</a>, taking PHP code as its input and creating <a target="_blank" href="http://en.wikipedia.org/wiki/Web_page" title="Web page">web pages</a> as output. It can be deployed on most web servers and on almost every <a target="_blank" href="http://en.wikipedia.org/wiki/Operating_system" title="Operating system">operating system</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Platform_%28computing%29" class="mw-redirect" title="Platform (computing)">platform</a> free of charge.<sup id="cite_ref-foundations_4-0" class="reference"><a href="#cite_note-foundations-4" title="">[5]</a></sup> PHP is installed on more than 20 million websites and 1 million <a target="_blank" href="http://en.wikipedia.org/wiki/Server_%28computing%29" title="Server (computing)">servers</a>, although the number of websites with PHP <a target="_blank" href="http://en.wikipedia.org/wiki/Installation_%28computer_programs%29" title="Installation (computer programs)">installed</a> has declined since August 2005.<sup id="cite_ref-usage_5-0" class="reference"><a href="#cite_note-usage-5" title="">[6]</a></sup> It is also the most popular <a target="_blank" href="http://en.wikipedia.org/wiki/Apache_HTTP_Server" title="Apache HTTP Server">Apache</a> module among computers using Apache as a web server.<sup id="cite_ref-usage_5-1" class="reference"><a href="#cite_note-usage-5" title="">[6]</a></sup> The most recent major release of PHP was version 5.2.5 on <a target="_blank" href="http://en.wikipedia.org/wiki/November_8" title="November 8">November 8</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/2007" title="2007">2007</a>.<sup id="cite_ref-php5changelog_6-0" class="reference"><a href="#cite_note-php5changelog-6" title="">[7]</a></sup></p>
diff --git a/help_example/help/help_example.help.ini b/help_example/help/help_example.help.ini
new file mode 100644
index 0000000..83f9ec7
--- /dev/null
+++ b/help_example/help/help_example.help.ini
@@ -0,0 +1,24 @@
+[about-php]
+title = About PHP
+file = about-php
+weight = -10
+
+[history]
+title = History of PHP
+file = history
+parent = about-php
+
+[usage]
+title = Usage of PHP
+file = usage
+weight = 1
+
+[security]
+title = Security of PHP
+file = security
+weight = 2
+
+[syntax]
+title = PHP syntax
+file = syntax
+parent = usage \ No newline at end of file
diff --git a/help_example/help/history.html b/help_example/help/history.html
new file mode 100644
index 0000000..9993403
--- /dev/null
+++ b/help_example/help/history.html
@@ -0,0 +1,23 @@
+<div class="help-box help-left">
+<div class="thumbinner" style="width:182px;"><a href="http://en.wikipedia.org/wiki/Image:Lerdorf.jpg" class="image" title="Rasmus Lerdorf, who wrote the original Common Gateway Interface binaries"><img alt="Rasmus Lerdorf, who wrote the original Common Gateway Interface binaries" src="path:180px-Lerdorf.jpg" width="180" height="270" border="0" class="thumbimage" /></a>
+<div class="thumbcaption">
+<div class="magnify"><a href="/wiki/Image:Lerdorf.jpg" class="internal" title="Enlarge"><img src="/skins-1.5/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>
+<a href="/wiki/Rasmus_Lerdorf" title="Rasmus Lerdorf">Rasmus Lerdorf</a>, who wrote the original <a href="/wiki/Common_Gateway_Interface" title="Common Gateway Interface">Common Gateway Interface</a> binaries</div>
+</div>
+</div>
+
+
+<p>PHP, standing for Personal Home Page, began as a set of <a target="_blank" href="http://en.wikipedia.org/wiki/Common_Gateway_Interface" title="Common Gateway Interface">Common Gateway Interface</a> <a target="_blank" href="http://en.wikipedia.org/wiki/Binary_file" title="Binary file">binaries</a> written in the <a target="_blank" href="http://en.wikipedia.org/wiki/C_programming_language" class="mw-redirect" title="C programming language">C programming language</a> in 1994 by the <a target="_blank" href="http://en.wikipedia.org/wiki/Danish_people" title="Danish people">Danish</a>/<a target="_blank" href="http://en.wikipedia.org/wiki/Greenland" title="Greenland">Greenlandic</a> programmer <a target="_blank" href="http://en.wikipedia.org/wiki/Rasmus_Lerdorf" title="Rasmus Lerdorf">Rasmus Lerdorf</a>. Lerdorf initially created these Personal Home Page Tools to replace a small set of <a target="_blank" href="http://en.wikipedia.org/wiki/Perl" title="Perl">Perl</a> scripts he had been using to maintain his <a target="_blank" href="http://en.wikipedia.org/wiki/Personal_homepage" class="mw-redirect" title="Personal homepage">personal homepage</a>. The tools were originally created to perform tasks such as displaying his <a target="_blank" href="http://en.wikipedia.org/wiki/R%C3%A9sum%C3%A9" title="Résumé">résumé</a> and recording how much <a target="_blank" href="http://en.wikipedia.org/wiki/Web_traffic" title="Web traffic">traffic</a> his page was receiving.<sup id="cite_ref-history_2-1" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup> He combined these binaries with his Form Interpreter to create PHP/FI, which had more functionality. It included a larger <a target="_blank" href="http://en.wikipedia.org/wiki/C_%28programming_language%29" title="C (programming language)">C implementation</a> which could communicate with <a target="_blank" href="http://en.wikipedia.org/wiki/Database" title="Database">databases</a> and helped build simple, dynamic <a target="_blank" href="http://en.wikipedia.org/wiki/Web_application" title="Web application">web applications</a>. He released PHP publicly on <a target="_blank" href="http://en.wikipedia.org/wiki/June_8" title="June 8">June 8</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/1995" title="1995">1995</a> to speed up the finding of <a target="_blank" href="http://en.wikipedia.org/wiki/Software_bug" title="Software bug">bugs</a> and improving the code.<sup id="cite_ref-7" class="reference"><a href="#cite_note-7" title="">[8]</a></sup> This release was named PHP version 2, and already had basic functionality that PHP has today. This includes Perl-like variables, form handling, and the ability to embed HTML. The syntax was similar to Perl but was more limited, simpler, and less consistent.<sup id="cite_ref-history_2-2" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup></p>
+
+<div class="help-box help-right">
+<div class="thumbinner" style="width:182px;"><a target="_blank" href="http://en.wikipedia.org/wiki/Image:Andi_Gutmans_1.jpg" class="image" title="Andi Gutmans, who, along with Zeev Suraski, rewrote the parser that formed PHP 3"><img alt="Andi Gutmans, who, along with Zeev Suraski, rewrote the parser that formed PHP 3" src="path:180px-Andi_Gutmans_1.jpg" width="180" height="244" border="0" class="thumbimage" /></a>
+<div class="thumbcaption">
+<div class="magnify"><a target="_blank" href="http://en.wikipedia.org/wiki/Image:Andi_Gutmans_1.jpg" class="internal" title="Enlarge"><img src="/skins-1.5/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>
+<a target="_blank" href="http://en.wikipedia.org/wiki/Andi_Gutmans" title="Andi Gutmans">Andi Gutmans</a>, who, along with <a target="_blank" href="http://en.wikipedia.org/wiki/Zeev_Suraski" title="Zeev Suraski">Zeev Suraski</a>, rewrote the <a target="_blank" href="http://en.wikipedia.org/wiki/Parser" class="mw-redirect" title="Parser">parser</a> that formed PHP 3</div>
+</div>
+</div>
+<p><a target="_blank" href="http://en.wikipedia.org/wiki/Zeev_Suraski" title="Zeev Suraski">Zeev Suraski</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Andi_Gutmans" title="Andi Gutmans">Andi Gutmans</a>, two <a target="_blank" href="http://en.wikipedia.org/wiki/Israelis" title="Israelis">Israeli</a> developers at the <a target="_blank" href="http://en.wikipedia.org/wiki/Technion_IIT" class="mw-redirect" title="Technion IIT">Technion IIT</a>, rewrote the <a target="_blank" href="http://en.wikipedia.org/wiki/Parser" class="mw-redirect" title="Parser">parser</a> in 1997 and formed the base of PHP 3, changing the language's name to the <a target="_blank" href="http://en.wikipedia.org/wiki/Recursive_initialism" class="mw-redirect" title="Recursive initialism">recursive initialism</a> <i>PHP: Hypertext Preprocessor</i>.<sup id="cite_ref-history_2-3" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup> The development team officially released PHP/FI 2 in November 1997 after months of <a target="_blank" href="http://en.wikipedia.org/wiki/Development_stage#beta" class="mw-redirect" title="Development stage">beta</a> testing. Afterwards, public testing of PHP 3 began, and the official launch came in June 1998. Suraski and Gutmans then started a new <a target="_blank" href="http://en.wikipedia.org/wiki/Rewrite_%28programming%29" title="Rewrite (programming)">rewrite</a> of PHP's core, producing the <a target="_blank" href="http://en.wikipedia.org/wiki/Zend_Engine" title="Zend Engine">Zend Engine</a> in 1999.<sup id="cite_ref-8" class="reference"><a href="#cite_note-8" title="">[9]</a></sup> They also founded <a target="_blank" href="http://en.wikipedia.org/wiki/Zend_Technologies" title="Zend Technologies">Zend Technologies</a> in <a target="_blank" href="http://en.wikipedia.org/wiki/Ramat_Gan" title="Ramat Gan">Ramat Gan</a>, Israel, which manages the development of PHP.<sup id="cite_ref-history_2-4" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup></p>
+
+<p>On <a target="_blank" href="http://en.wikipedia.org/wiki/May_22" title="May 22">May 22</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/2000" title="2000">2000</a>, PHP 4, powered by the Zend Engine 1.0, was released.<sup id="cite_ref-history_2-5" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup> On <a target="_blank" href="http://en.wikipedia.org/wiki/July_13" title="July 13">July 13</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/2004" title="2004">2004</a>, PHP 5 was released and is powered by the new Zend Engine II.<sup id="cite_ref-history_2-6" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup> PHP 5 included new features such as improved support for <a target="_blank" href="http://en.wikipedia.org/wiki/Object-oriented_programming" title="Object-oriented programming">object-oriented programming</a>, the PHP Data Objects extension (which defines a lightweight and consistent interface for accessing databases), and numerous performance enhancements.<sup id="cite_ref-9" class="reference"><a href="#cite_note-9" title="">[10]</a></sup> The most recent update released by The PHP Group is for the older PHP version 4 code branch. As of January 2008, this branch is up to version 4.4.8. PHP 4 will be supported by security updates until <a target="_blank" href="http://en.wikipedia.org/wiki/August_8" title="August 8">August 8</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/2008" title="2008">2008</a>.<sup id="cite_ref-2007_news_10-0" class="reference"><a href="#cite_note-2007_news-10" title="">[11]</a></sup></p>
+
+<p>PHP 5 is the only stable version still being developed. <a target="_blank" href="http://en.wikipedia.org/wiki/Late_static_binding" class="mw-redirect" title="Late static binding">Late static binding</a> has been missing from PHP and will be added in version 5.3.<sup id="cite_ref-11" class="reference"><a href="#cite_note-11" title="">[12]</a></sup> <sup id="cite_ref-12" class="reference"><a href="#cite_note-12" title="">[13]</a></sup> Development on PHP 4 ceased at the end of 2007, except for the critical security updates for PHP 4 already mentioned.<sup id="cite_ref-13" class="reference"><a href="#cite_note-13" title="">[14]</a></sup><sup id="cite_ref-2007_news_10-1" class="reference"><a href="#cite_note-2007_news-10" title="">[11]</a></sup> PHP 6 is now under development and major changes include the removal of <code>register_globals</code><sup id="cite_ref-14" class="reference"><a href="#cite_note-14" title="">[15]</a></sup>, <a target="_blank" href="http://en.wikipedia.org/wiki/Magic_quotes" title="Magic quotes">magic quotes</a>, and <a target="_blank" href="http://en.wikipedia.org/wiki/Safe_mode#Application_software_safe_mode" title="Safe mode">safe mode</a>.<sup id="cite_ref-2007_news_10-2" class="reference"><a href="#cite_note-2007_news-10" title="">[11]</a></sup><sup id="cite_ref-15" class="reference"><a href="#cite_note-15" title="">[16]</a></sup> PHP does not have complete native support for <a target="_blank" href="http://en.wikipedia.org/Unicode" title="Unicode">Unicode</a> or multibyte strings;<sup id="cite_ref-16" class="reference"><a href="#cite_note-16" title="">[17]</a></sup> unicode support will be added in PHP 6.<sup id="cite_ref-17" class="reference"><a href="#cite_note-17" title="">[18]</a></sup> Many high profile open source projects ceased to support PHP 4 in new code as of <a target="_blank" href="http://en.wikipedia.org/wiki/February_5" title="February 5">February 5</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/2008" title="2008">2008</a>, due to the GoPHP5 initiative, provided by a consortium of PHP developers promoting the transition from PHP 4 to PHP 5.<sup id="cite_ref-gophp5_18-0" class="reference"><a href="#cite_note-gophp5-18" title="">[19]</a></sup><sup id="cite_ref-19" class="reference"><a href="#cite_note-19" title="">[20]</a></sup></p>
diff --git a/help_example/help/security.html b/help_example/help/security.html
new file mode 100644
index 0000000..31d43dc
--- /dev/null
+++ b/help_example/help/security.html
@@ -0,0 +1 @@
+<p>PHP is a popular target of <a target="_blank" href="http://en.wikipedia.org/wiki/Hacker" title="Hacker">hackers</a> who exploit vulnerable applications written in PHP. Software vulnerabilities related to PHP are identified among the <a target="_blank" href="http://en.wikipedia.org/wiki/Common_Vulnerabilities_and_Exposures" title="Common Vulnerabilities and Exposures">CVE (Common Vulnerabilities and Exposures)</a> records, available from the <a target="_blank" href="http://en.wikipedia.org/wiki/National_Vulnerability_Database" title="National Vulnerability Database">National Vulnerability Database</a>. The proportion of vulnerabilities related to PHP, out of the total of all common vulnerabilities, amounted to: 12% in 2003, 20% in 2004, 28% in 2005, 43% in 2006, 36% in 2007, and 33.8% for the first quarter of 2008. More than a quarter of all software vulnerabilities listed in this database are related to PHP, and more than a third of vulnerabilities listed recently. Most of these vulnerabilities can be exploited remotely, that is without being logged on the computer hosting the vulnerable application.<sup id="cite_ref-27" class="reference"><a href="#cite_note-27" title="">[28]</a></sup> Such exploitation is made possible due to poor programming habits, such as failing to check data before entering it into a database, and features of the language such as <code>register_globals</code>, which is now deprecated.<sup id="cite_ref-register_globals_21-1" class="reference"><a href="#cite_note-register_globals-21" title="">[22]</a></sup> These result in <a target="_blank" href="http://en.wikipedia.org/wiki/Code_injection" title="Code injection">code injection</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/Cross-site_scripting" title="Cross-site scripting">cross-site scripting</a> and other <a target="_blank" href="http://en.wikipedia.org/wiki/Application_security" title="Application security">application security</a> issues. It's important to note that none of these attacks are exclusive to PHP and all are avoidable by following proper coding techniques and principles.</p>
diff --git a/help_example/help/syntax.html b/help_example/help/syntax.html
new file mode 100644
index 0000000..48d8109
--- /dev/null
+++ b/help_example/help/syntax.html
@@ -0,0 +1,38 @@
+<h2> <span class="mw-headline">Syntax</span></h2>
+<div class="help-right">
+<div class="thumbinner" style="width:182px;"><a target="_blank" href="http://en.wikipedia.org/wiki/Image:PHP_Hello_World_screenshot.png" class="image" title="Syntax-highlighted PHP code"><img alt="Syntax-highlighted PHP code" src="path:180px-PHP_Hello_World_screenshot.png" width="180" height="87" border="0" class="thumbimage" /></a>
+<div class="thumbcaption">
+
+<div class="magnify"><a target="_blank" href="http://en.wikipedia.org/wiki/Image:PHP_Hello_World_screenshot.png" class="internal" title="Enlarge"><img src="/skins-1.5/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>
+<a target="_blank" href="http://en.wikipedia.org/wiki/Syntax-highlighted" class="mw-redirect" title="Syntax-highlighted">Syntax-highlighted</a> PHP code</div>
+</div>
+</div>
+<p>PHP only parses code within its <a target="_blank" href="http://en.wikipedia.org/wiki/Delimiter" title="Delimiter">delimiters</a>. Anything outside its delimiters is sent directly to the output and is not parsed by PHP. The most common delimiters are <span s>&lt;?php</span> and <span>?&gt;</span>, which are open and close delimiters respectively. <span>&lt;script language="php"&gt;</span> and <span>&lt;/script&gt;</span> delimiters are also available. Short tags (<span>&lt;?</span> or <span>&lt;?=</span> and <span>?&gt;</span>) are also commonly used, but like ASP-style tags (<span>&lt;%</span> or <span>&lt;%=</span> and <span>%&gt;</span>), they are less portable as they can be disabled in the PHP configuration. For this reason, the use of short tags and ASP-style tags is discouraged.<sup id="cite_ref-basic_syntax_28-0" class="reference"><a href="#cite_note-basic_syntax-28" title="">[29]</a></sup> The purpose of these delimiters is to separate PHP code from non-PHP code, including HTML. Everything outside the delimiters is ignored by the parser and is passed through as output.<sup id="cite_ref-29" class="reference"><a href="#cite_note-29" title="">[30]</a></sup></p>
+
+<p>Variables are prefixed with a <a target="_blank" href="http://en.wikipedia.org/wiki/Dollar_sign" title="Dollar sign">dollar symbol</a> and a <a target="_blank" href="http://en.wikipedia.org/wiki/Primitive_type" title="Primitive type">type</a> does not need to be specified in advance. Unlike function and class names, variable names are case sensitive. Both double-quoted (<span>""</span>) and <a target="_blank" href="http://en.wikipedia.org/wiki/Heredoc" class="mw-redirect" title="Heredoc">heredoc</a> strings allow the ability to embed the variable's value into the string.<sup id="cite_ref-30" class="reference"><a href="#cite_note-30" title="">[31]</a></sup> PHP treats <a target="_blank" href="http://en.wikipedia.org/wiki/Newline" title="Newline">newlines</a> as <a target="_blank" href="http://en.wikipedia.org/wiki/Whitespace_%28computer_science%29" title="Whitespace (computer science)">whitespace</a> in the manner of a <a target="_blank" href="http://en.wikipedia.org/wiki/Free-form_language" title="Free-form language">free-form language</a> (except when inside string quotes), and statements are terminated by a semicolon.<sup id="cite_ref-31" class="reference"><a href="#cite_note-31" title="">[32]</a></sup> PHP has three types of <a target="_blank" href="http://en.wikipedia.org/wiki/Comparison_of_programming_languages_%28syntax%29#Comments" title="Comparison of programming languages (syntax)">comment syntax</a>: <span>/* */</span> serves as block comments, and <span>//</span> as well as <span>#</span> are used for inline comments.<sup id="cite_ref-32" class="reference"><a href="#cite_note-32" title="">[33]</a></sup> To output text to the browser, either the <tt>print</tt> function or the <tt>echo</tt> function is used. Both functions are nearly identical; the major difference is that <tt>print</tt> is slower than <tt>echo</tt> because the former will return a status indicating if it was successful or not, whereas the latter does not return a status and only returns the text for output.<sup id="cite_ref-33" class="reference"><a href="#cite_note-33" title="">[34]</a></sup></p>
+
+<p><a name="Data_types" id="Data_types"></a></p>
+<h3><span class="mw-headline">Data types</span></h3>
+<p>PHP stores whole numbers in a platform-dependent range. This range is typically that of 32-bit <a target="_blank" href="http://en.wikipedia.org/wiki/Signed_number_representations" title="Signed number representations">signed</a> <a target="_blank" href="http://en.wikipedia.org/wiki/Integer_%28computer_science%29" title="Integer (computer science)">integers</a>. Unsigned integers are converted to signed values in certain situations; this behavior is different from other programming languages.<sup id="cite_ref-34" class="reference"><a href="#cite_note-34" title="">[35]</a></sup> Integer variables can be assigned using decimal (positive and negative), <a target="_blank" href="http://en.wikipedia.org/wiki/Octal" title="Octal">octal</a>, and <a target="_blank" href="http://en.wikipedia.org/wiki/Hexadecimal" title="Hexadecimal">hexadecimal</a> notations. <a target="_blank" href="http://en.wikipedia.org/wiki/Real_numbers" class="mw-redirect" title="Real numbers">Real numbers</a> are also stored in a platform-specific range. They can be specified using <a target="_blank" href="http://en.wikipedia.org/wiki/Floating_point" title="Floating point">floating point</a> notation, or two forms of <a target="_blank" href="http://en.wikipedia.org/wiki/Scientific_notation" title="Scientific notation">scientific notation</a>.<sup id="cite_ref-types_35-0" class="reference"><a href="#cite_note-types-35" title="">[36]</a></sup> PHP has a native <a target="_blank" href="http://en.wikipedia.org/wiki/Boolean_datatype" title="Boolean datatype">Boolean</a> type that is similar to the native Boolean types in <a target="_blank" href="http://en.wikipedia.org/wiki/Java_%28programming_language%29" title="Java (programming language)">Java</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/C%2B%2B" title="C++">C++</a>. Using the Boolean type conversion rules, non-zero values are interpreted as true and zero as false, as in Perl and C++.<sup id="cite_ref-types_35-1" class="reference"><a href="#cite_note-types-35" title="">[36]</a></sup> The null data type represents a variable that has no value. The only value in the null data type is <i>NULL</i>.<sup id="cite_ref-types_35-2" class="reference"><a href="#cite_note-types-35" title="">[36]</a></sup> Variables of the "resource" type represent references to resources from external sources. These are typically created by functions from a particular extension, and can only be processed by functions from the same extension; examples include file, image, and database resources.<sup id="cite_ref-types_35-3" class="reference"><a href="#cite_note-types-35" title="">[36]</a></sup> Arrays can contain elements of any type that PHP can handle, including resources, objects, and even other arrays. Order is preserved in lists of values and in <a target="_blank" href="http://en.wikipedia.org/wiki/Hash_table" title="Hash table">hashes</a> with both keys and values, and the two can be intermingled.<sup id="cite_ref-types_35-4" class="reference"><a href="#cite_note-types-35" title="">[36]</a></sup> PHP also supports <a target="_blank" href="http://en.wikipedia.org/wiki/String_%28computing%29" class="mw-redirect" title="String (computing)">strings</a>, which can be used with single quotes, double quotes, or <a target="_blank" href="http://en.wikipedia.org/wiki/Heredoc" class="mw-redirect" title="Heredoc">heredoc syntax</a>.<sup id="cite_ref-36" class="reference"><a href="#cite_note-36" title="">[37]</a></sup></p>
+
+<p><a name="Functions" id="Functions"></a></p>
+<h3><span class="mw-headline">Functions</span></h3>
+<p>PHP has hundreds of base functions and thousands more from extensions. Functions are not <a target="_blank" href="http://en.wikipedia.org/wiki/First-class_function" title="First-class function">first-class functions</a> and can only be referenced by their name. <sup id="cite_ref-functions_37-0" class="reference"><a href="#cite_note-functions-37" title="">[38]</a></sup> User-defined functions can be created at any time without being prototyped.<sup id="cite_ref-functions_37-1" class="reference"><a href="#cite_note-functions-37" title="">[38]</a></sup> Functions can be defined inside code blocks, permitting a <a target="_blank" href="http://en.wikipedia.org/wiki/Dynamic_dispatch" title="Dynamic dispatch">run-time decision</a> as to whether or not a function should be defined. Function calls must use parentheses, with the exception of zero argument class <a target="_blank" href="http://en.wikipedia.org/wiki/Constructor_%28computer_science%29" title="Constructor (computer science)">constructor</a> functions called with the PHP <span>new</span> operator, where parentheses are optional. PHP supports quasi-<a target="_blank" href="http://en.wikipedia.org/wiki/Anonymous_function" title="Anonymous function">anonymous functions</a> through the <span>create_function()</span> function, although they are not true anonymous functions because anonymous functions are nameless, but functions can only be referenced by name, or indirectly through a variable <span>$function_name();</span>, in PHP.<sup id="cite_ref-functions_37-2" class="reference"><a href="#cite_note-functions-37" title="">[38]</a></sup></p>
+
+<p><a name="Objects" id="Objects"></a></p>
+<h3><span class="mw-headline">Objects</span></h3>
+<p>Basic <a target="_blank" href="http://en.wikipedia.org/wiki/Object-oriented_programming" title="Object-oriented programming">object-oriented programming</a> functionality was added in PHP 3.<sup id="cite_ref-history_2-10" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup> Object handling was completely rewritten for PHP 5, expanding the feature set and enhancing performance.<sup id="cite_ref-php_5_objects_38-0" class="reference"><a href="#cite_note-php_5_objects-38" title="">[39]</a></sup> In previous versions of PHP, objects were handled like <a target="_blank" href="http://en.wikipedia.org/wiki/Primitive_type" title="Primitive type">primitive types</a>.<sup id="cite_ref-php_5_objects_38-1" class="reference"><a href="#cite_note-php_5_objects-38" title="">[39]</a></sup> The drawback of this method was that the whole object was copied when a variable was assigned or passed as a parameter to a method. In the new approach, objects are referenced by <a target="_blank" href="http://en.wikipedia.org/wiki/Smart_pointer#Handles" title="Smart pointer">handle</a>, and not by value. PHP 5 introduced private and protected <a target="_blank" href="http://en.wikipedia.org/wiki/Member_variable" class="mw-redirect" title="Member variable">member variables</a> and methods, along with <a target="_blank" href="http://en.wikipedia.org/wiki/Abstract_type" title="Abstract type">abstract classes</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Final_type" class="mw-redirect" title="Final type">final classes</a> as well as <a target="_blank" href="http://en.wikipedia.org/wiki/Abstract_method" class="mw-redirect" title="Abstract method">abstract methods</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Final_method" class="mw-redirect" title="Final method">final methods</a>. It also introduced a standard way of declaring <a target="_blank" href="http://en.wikipedia.org/wiki/Constructor_%28computer_science%29" title="Constructor (computer science)">constructors</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Destructor_%28computer_science%29" title="Destructor (computer science)">destructors</a>, similar to that of other object-oriented languages such as <a target="_blank" href="http://en.wikipedia.org/wiki/C%2B%2B" title="C++">C++</a>, and a standard <a target="_blank" href="http://en.wikipedia.org/wiki/Exception_handling" title="Exception handling">exception handling</a> model. Furthermore, PHP 5 added <a target="_blank" href="http://en.wikipedia.org/wiki/Interfaces" class="mw-redirect" title="Interfaces">interfaces</a> and allowed for multiple interfaces to be implemented. There are special interfaces that allow objects to interact with the runtime system. <a target="_blank" href="http://en.wikipedia.org/wiki/Object" title="Object">Objects</a> implementing <a target="_blank" href="http://en.wikipedia.org/wiki/ArrayAccess" class="mw-redirect" title="ArrayAccess">ArrayAccess</a> can be used with array syntax and <a target="_blank" href="http://en.wikipedia.org/wiki/Object" title="Object">objects</a> implementing <a target="_blank" href="http://en.wikipedia.org/wiki/Iterator" title="Iterator">Iterator</a> or <a target="_blank" href="http://en.wikipedia.org/wiki/IteratorAggregate" class="mw-redirect" title="IteratorAggregate">IteratorAggregate</a> can be used with the <span>foreach</span> language construct. There is no <a target="_blank" href="http://en.wikipedia.org/wiki/Virtual_table" class="mw-redirect" title="Virtual table">virtual table</a> feature in the engine, so <a target="_blank" href="http://en.wikipedia.org/wiki/Static_variable" title="Static variable">static variables</a> are bound with a name instead of a reference at compile time.<sup id="cite_ref-zend_engine_2_39-0" class="reference"><a href="#cite_note-zend_engine_2-39" title="">[40]</a></sup></p>
+
+<p>If the developer creates a copy of an object using the reserved word <i>clone</i>, the Zend engine will check if a <tt>__clone()</tt> method has been defined or not. If not, it will call a default <tt>__clone()</tt> which will copy the object's properties. If a <tt>__clone()</tt> method is defined, then it will be responsible for setting the necessary properties in the created object. For convenience, the engine will supply a function that imports the properties of the source object, so that the programmer can start with a by-value <a href="http://en.wiktionary.org/wiki/replica" class="extiw" title="wikt:replica">replica</a> of the source object and only override properties that need to be changed.<sup id="cite_ref-40" class="reference"><a href="#cite_note-40" title="">[41]</a></sup></p>
+
+<p><a name="Resources" id="Resources"></a></p>
+<h2> <span class="mw-headline">Resources</span></h2>
+<p>PHP includes <a target="_blank" href="http://en.wikipedia.org/wiki/List_of_PHP_libraries" title="List of PHP libraries">free and open source libraries</a> with the core build. PHP is a fundamentally <a target="_blank" href="http://en.wikipedia.org/wiki/Internet" title="Internet">Internet</a>-aware system with modules built in for accessing <a target="_blank" href="http://en.wikipedia.org/wiki/File_transfer_protocol" class="mw-redirect" title="File transfer protocol">FTP</a> servers, many database servers, embedded SQL libraries such as embedded <a target="_blank" href="http://en.wikipedia.org/wiki/MySQL" title="MySQL">MySQL</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/SQLite" title="SQLite">SQLite</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol" title="Lightweight Directory Access Protocol">LDAP</a> servers, and others. Many functions familiar to C programmers such as those in the <tt><a target="_blank" href="http://en.wikipedia.org/wiki/Stdio.h" title="Stdio.h">stdio</a></tt> family are available in the standard PHP build.<sup id="cite_ref-41" class="reference"><a href="#cite_note-41" title="">[42]</a></sup> PHP has traditionally used features such as "<a target="_blank" href="http://en.wikipedia.org/wiki/Magic_quotes" title="Magic quotes">magic_quotes_gpc</a>" and "magic_quotes_runtime" which attempt to escape apostrophes (') and quotes (") in strings in the assumption that they will be used in databases, to prevent <a target="_blank" href="http://en.wikipedia.org/wiki/SQL_injection" title="SQL injection">SQL injection</a> attacks. This leads to confusion over which data is escaped and which is not, and to problems when data is not in fact used as input to a database and when the escaping used is not completely correct.<sup id="cite_ref-42" class="reference"><a href="#cite_note-42" title="">[43]</a></sup> To make code portable between servers which do and do not use magic quotes, developers can preface their code with a script to reverse the effect of magic quotes when it is applied.<sup id="cite_ref-43" class="reference"><a href="#cite_note-43" title="">[44]</a></sup></p>
+
+<p>PHP allows developers to write <a target="_blank" href="http://en.wikipedia.org/wiki/Extension_%28computing%29" class="mw-redirect" title="Extension (computing)">extensions</a> in <a target="_blank" href="http://en.wikipedia.org/wiki/C_%28programming_language%29" title="C (programming language)">C</a> to add functionality to the PHP language. These can then be compiled into PHP or loaded dynamically at runtime. Extensions have been written to add support for the <a target="_blank" href="http://en.wikipedia.org/wiki/Windows_API" title="Windows API">Windows API</a>, process management on <a target="_blank" href="http://en.wikipedia.org/wiki/Unix-like" title="Unix-like">Unix-like</a> <a target="_blank" href="http://en.wikipedia.org/wiki/Operating_system" title="Operating system">operating systems</a>, multibyte strings (<a target="_blank" href="http://en.wikipedia.org/wiki/Unispan" title="Unispan">Unispan</a>), <a target="_blank" href="http://en.wikipedia.org/wiki/CURL" title="CURL">cURL</a>, and several popular <a target="_blank" href="http://en.wikipedia.org/wiki/Compression_formats" class="mw-redirect" title="Compression formats">compression formats</a>. Some more unusual features include integration with <a target="_blank" href="http://en.wikipedia.org/wiki/Internet_relay_chat" class="mw-redirect" title="Internet relay chat">Internet relay chat</a>, dynamic generation of images and <a target="_blank" href="http://en.wikipedia.org/wiki/Adobe_Flash" title="Adobe Flash">Adobe Flash</a> content, and even <a target="_blank" href="http://en.wikipedia.org/wiki/Speech_synthesis" title="Speech synthesis">speech synthesis</a>. The <a target="_blank" href="http://en.wikipedia.org/wiki/PHP_Extension_Community_Library" class="mw-redirect" title="PHP Extension Community Library">PHP Extension Community Library</a> (PECL) project is a repository for extensions to the PHP language.<sup id="cite_ref-44" class="reference"><a href="#cite_note-44" title="">[45]</a></sup></p>
+
+<p>As with many scripting languages, PHP scripts are normally kept as human-readable source code, even on production web servers.<sup id="cite_ref-45" class="reference"><a href="#cite_note-45" title="">[46]</a></sup> While this allows flexibility, releasing scripts in source form is undesirable for commercial software developers, and can raise issues with security of web servers; as an example, if a hacker acquires control of a server, database passwords may be quickly discovered, and undesirable changes to scripts may be made that remain undiscovered indefinitely. Various encoding tools are available for PHP to offer code protection.<sup class="noprint Template-Fact"><span title="This claim needs references to reliable sources&#160;since March 2008" style="white-space: nowrap;">[<i><a target="_blank" href="http://en.wikipedia.org/wiki/Wikipedia:Citation_needed" title="Wikipedia:Citation needed">citation needed</a></i>]</span></sup></p>
+<p>span optimizers improve the quality of the compiled code by reducing its size and making changes that can reduce the execution time and improve performance. The nature of the PHP <a target="_blank" href="http://en.wikipedia.org/wiki/Compiler" title="Compiler">compiler</a> is such that there are often opportunities for <a target="_blank" href="http://en.wikipedia.org/wiki/Optimization_%28computer_science%29" title="Optimization (computer science)">span optimization</a><sup id="cite_ref-46" class="reference"><a href="#cite_note-46" title="">[47]</a></sup>, and an example of a code optimizer is the <a target="_blank" href="http://en.wikipedia.org/wiki/PHP_accelerator#Zend_Optimizer" title="PHP accelerator">Zend Optimizer</a> PHP extension.<sup id="cite_ref-47" class="reference"><a href="#cite_note-47" title="">[48]</a></sup></p>
+
+<p><a target="_blank" href="http://en.wikipedia.org/wiki/PHP_accelerator" title="PHP accelerator">PHP accelerators</a> can offer significant performance gains by <a target="_blank" href="http://en.wikipedia.org/wiki/Caching" class="mw-redirect" title="Caching">caching</a> the compiled form of a PHP script in <a target="_blank" href="http://en.wikipedia.org/wiki/Shared_memory" title="Shared memory">shared memory</a> to avoid the overhead of <a target="_blank" href="http://en.wikipedia.org/wiki/Parsing" title="Parsing">parsing</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Compiling" class="mw-redirect" title="Compiling">compiling</a> the code every time the script runs. They may also perform <a target="_blank" href="http://en.wikipedia.org/wiki/span_optimization" class="mw-redirect" title="span optimization">span optimization</a> to provide increased execution performance.<sup class="noprint Template-Fact"><span title="This claim needs references to reliable sources&#160;since March 2008" style="white-space: nowrap;">[<i><a target="_blank" href="http://en.wikipedia.org/wiki/Wikipedia:Citation_needed" title="Wikipedia:Citation needed">citation needed</a></i>]</span></sup></p>
+
diff --git a/help_example/help/usage.html b/help_example/help/usage.html
new file mode 100644
index 0000000..8f1e9ad
--- /dev/null
+++ b/help_example/help/usage.html
@@ -0,0 +1,9 @@
+<p>PHP is a general-purpose scripting language that is especially suited for <a target="_blank" href="http://en.wikipedia.org/wiki/Web_development" title="Web development">web development</a>. It is the fourth most popular computer programming language, ranking behind <a target="_blank" href="http://en.wikipedia.org/wiki/Java_%28programming_language%29" title="Java (programming language)">Java</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/C_%28programming_language%29" title="C (programming language)">C</a>, and <a target="_blank" href="http://en.wikipedia.org/wiki/Visual_Basic" title="Visual Basic">Visual Basic</a>.<sup id="cite_ref-22" class="reference"><a href="#cite_note-22" title="">[23]</a></sup> PHP generally runs on a <a target="_blank" href="http://en.wikipedia.org/wiki/Web_server" title="Web server">web server</a>, taking PHP code as its input and creating <a target="_blank" href="http://en.wikipedia.org/wiki/Web_page" title="Web page">web pages</a> as output. It can also be used for <a target="_blank" href="http://en.wikipedia.org/wiki/Command-line" class="mw-redirect" title="Command-line">command-line</a> scripting and <a target="_blank" href="http://en.wikipedia.org/wiki/Client-side" title="Client-side">client-side</a> <a target="_blank" href="http://en.wikipedia.org/wiki/Graphical_user_interface" title="Graphical user interface">GUI</a> applications. PHP can be deployed on most <a target="_blank" href="http://en.wikipedia.org/wiki/Web_server" title="Web server">web servers</a>, many <a target="_blank" href="http://en.wikipedia.org/wiki/Operating_system" title="Operating system">operating systems</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Platform_%28computing%29" class="mw-redirect" title="Platform (computing)">platforms</a>, and can be used with many <a target="_blank" href="http://en.wikipedia.org/wiki/Relational_database_management_system" title="Relational database management system">relational database management systems</a>. It is available free of charge, and the PHP Group provides the complete source code for users to build, customize and extend for their own use.<sup id="cite_ref-foundations_4-1" class="reference"><a href="#cite_note-foundations-4" title="">[5]</a></sup></p>
+
+<p>PHP primarily acts as a <a target="_blank" href="http://en.wikipedia.org/wiki/Filter_%28software%29" title="Filter (software)">filter</a><sup id="cite_ref-23" class="reference"><a href="#cite_note-23" title="">[24]</a></sup>, taking input from a file or stream containing text and/or PHP instructions and outputs another stream of data; most commonly the output will be HTML. From PHP 4, the PHP <a target="_blank" href="http://en.wikipedia.org/wiki/Parser" class="mw-redirect" title="Parser">parser</a> <a target="_blank" href="http://en.wikipedia.org/wiki/Compiler" title="Compiler">compiles</a> input to produce <a target="_blank" href="http://en.wikipedia.org/wiki/Bytecode" title="Bytecode">bytecode</a> for processing by the <a target="_blank" href="http://en.wikipedia.org/wiki/Zend_Engine" title="Zend Engine">Zend Engine</a>, giving improved performance over its <a target="_blank" href="http://en.wikipedia.org/wiki/Interpreter_%28computing%29" title="Interpreter (computing)">interpreter</a> predecessor.<sup id="cite_ref-24" class="reference"><a href="#cite_note-24" title="">[25]</a></sup></p>
+
+<p>Originally designed to create dynamic web pages, PHP's principal focus is <a target="_blank" href="http://en.wikipedia.org/wiki/Server-side_scripting" title="Server-side scripting">server-side scripting</a><sup id="cite_ref-25" class="reference"><a href="#cite_note-25" title="">[26]</a></sup>, and it is similar to other server-side scripting languages that provide dynamic content from a web server to a <a target="_blank" href="http://en.wikipedia.org/wiki/Client_%28computing%29" title="Client (computing)">client</a>, such as <a target="_blank" href="http://en.wikipedia.org/wiki/Microsoft" title="Microsoft">Microsoft</a>'s <a target="_blank" href="http://en.wikipedia.org/wiki/ASP.NET" title="ASP.NET">ASP.NET</a> system, <a target="_blank" href="http://en.wikipedia.org/wiki/Sun_Microsystems" title="Sun Microsystems">Sun Microsystems</a>' <a target="_blank" href="http://en.wikipedia.org/wiki/JavaServer_Pages" title="JavaServer Pages">JavaServer Pages</a><sup id="cite_ref-26" class="reference"><a href="#cite_note-26" title="">[27]</a></sup>, and <a target="_blank" href="http://en.wikipedia.org/wiki/Mod_perl" title="Mod perl">mod_perl</a>. PHP has also attracted the development of many <a target="_blank" href="http://en.wikipedia.org/wiki/Software_framework" title="Software framework">frameworks</a> that provide building blocks and a design structure to promote <a target="_blank" href="http://en.wikipedia.org/wiki/Rapid_application_development" title="Rapid application development">rapid application development</a> (RAD). Some of these include <a target="_blank" href="http://en.wikipedia.org/wiki/CakePHP" title="CakePHP">CakePHP</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/PRADO" title="PRADO">PRADO</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/Symfony" title="Symfony">Symfony</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Zend_Framework" title="Zend Framework">Zend Framework</a>, offering features similar to other <a target="_blank" href="http://en.wikipedia.org/wiki/List_of_web_application_frameworks" title="List of web application frameworks">web application frameworks</a>.</p>
+
+<p>The <a target="_blank" href="http://en.wikipedia.org/wiki/LAMP_%28software_bundle%29" title="LAMP (software bundle)">LAMP</a> architecture has become popular in the web industry as a way of deploying web applications. PHP is commonly used as the <i>P</i> in this bundle alongside <a target="_blank" href="http://en.wikipedia.org/wiki/Linux" title="Linux">Linux</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/Apache_HTTP_Server" title="Apache HTTP Server">Apache</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/MySQL" title="MySQL">MySQL</a>, although the <i>P</i> can also refer to <a target="_blank" href="http://en.wikipedia.org/wiki/Python_%28programming_language%29" title="Python (programming language)">Python</a> or <a target="_blank" href="http://en.wikipedia.org/wiki/Perl" title="Perl">Perl</a>.</p>
+
+<p>As of April 2007, over 20 million Internet domains were hosted on servers with PHP installed, and PHP was recorded as the most popular Apache module.<sup id="cite_ref-usage_5-2" class="reference"><a href="#cite_note-usage-5" title="">[6]</a></sup></p>
diff --git a/help_example/help_example.info b/help_example/help_example.info
new file mode 100644
index 0000000..8ba3f51
--- /dev/null
+++ b/help_example/help_example.info
@@ -0,0 +1,7 @@
+name = Advanced help example
+description = A example help module to demonstrate the advanced help module.
+core = 8.x
+dependencies[] = advanced_help
+files[] = help_example.module
+
+; \ No newline at end of file
diff --git a/help_example/help_example.module b/help_example/help_example.module
new file mode 100644
index 0000000..3aacf6a
--- /dev/null
+++ b/help_example/help_example.module
@@ -0,0 +1,29 @@
+<?php
+/**
+ * @file
+ *
+ * Provide example help for the advanced help module.
+ */
+
+/**
+ * Implementation of hook_menu().
+ */
+function help_example_menu() {
+ // View help topic index.
+ $items['admin/help_example'] = array(
+ 'title' => 'Example help',
+ 'page callback' => 'help_example_index_page',
+ 'access arguments' => array('view advanced help index'),
+ 'weight' => 9,
+ );
+ return $items;
+}
+
+function help_example_index_page() {
+ $output = theme('advanced_help_topic', array(
+ 'module' => 'help_example',
+ 'topic' => 'about-php',
+ ));
+ $output .= '&nbsp;' . t('Click the help icon to view some example help about the PHP programming language (from wikipedia.org). Be sure to run cron to update the index if you want to try out the search features.');
+ return $output;
+}