Help system now uses SimpleXML.
authorMichael M Slusarz <slusarz@curecanti.org>
Wed, 3 Feb 2010 07:36:00 +0000 (00:36 -0700)
committerMichael M Slusarz <slusarz@curecanti.org>
Mon, 8 Mar 2010 02:46:27 +0000 (19:46 -0700)
framework/Core/lib/Horde/Help.php
horde/services/help/index.php

index 1aa95ad..fba3c5b 100644 (file)
@@ -19,74 +19,11 @@ class Horde_Help
     const SOURCE_FILE = 1;
 
     /**
-     * Handle for the XML parser object.
+     * Handle for the XML object.
      *
-     * @var resource
+     * @var SimpleXMLElement
      */
-    protected $_parser;
-
-    /**
-     * String buffer to hold the XML help source.
-     *
-     * @var string
-     */
-    protected $_buffer = '';
-
-    /**
-     * String containing the ID of the requested help entry.
-     *
-     * @var string
-     */
-    protected $_reqEntry = '';
-
-    /**
-     * String containing the ID of the current help entry.
-     *
-     * @var string
-     */
-    protected $_curEntry = '';
-
-    /**
-     * String containing the formatted output.
-     *
-     * @var string
-     */
-    protected $_output = '';
-
-    /**
-     * Boolean indicating whether we're inside a <help> block.
-     *
-     * @var boolean
-     */
-    protected $_inHelp = false;
-
-    /**
-     * Boolean indicating whether we're inside the requested block.
-     *
-     * @var boolean
-     */
-    protected $_inBlock = false;
-
-    /**
-     * Boolean indicating whether we're inside a <title> block.
-     *
-     * @var boolean
-     */
-    protected $_inTitle = false;
-
-    /**
-     * Boolean indicating whether we're inside a heading block.
-     *
-     * @var boolean
-     */
-    protected $_inHeading = false;
-
-    /**
-     * Hash containing an index of all of the help entries.
-     *
-     * @var array
-     */
-    protected $_entries = array();
+    protected $_xml;
 
     /**
      * String containing the charset of the XML data source.
@@ -96,432 +33,189 @@ class Horde_Help
     protected $_charset = 'iso-8859-1';
 
     /**
-     * Hash of user-defined function handlers for the XML elements.
-     *
-     * @var array
-     */
-    protected $_handlers = array(
-        'help'     =>  '_helpHandler',
-        'entry'    =>  '_entryHandler',
-        'title'    =>  '_titleHandler',
-        'heading'  =>  '_headingHandler',
-        'para'     =>  '_paraHandler',
-        'ref'      =>  '_refHandler',
-        'eref'     =>  '_erefHandler',
-        'href'     =>  '_hrefHandler',
-        'b'        =>  '_bHandler',
-        'i'        =>  '_iHandler',
-        'pre'      =>  '_preHandler',
-        'tip'      =>  '_tipHandler',
-        'warn'     =>  '_warnHandler'
-    );
-
-    /**
-     * Hash containing an index of all of the search results.
-     *
-     * @var array
-     */
-    protected $_search = array();
-
-    /**
-     * String containing the keyword for the search.
-     *
-     * @var string
-     */
-    protected $_keyword = '';
-
-    /**
      * Constructor.
      *
      * @param integer $source  The source of the XML help data, based on the
      *                         SOURCE_* constants.
-     * @param string $arg      Source-dependent argument for this Help
-     *                         instance.
+     * @param array $data      The list of data sources to use.
+     *
+     * @throws Horde_Exception
      */
-    public function __construct($source, $arg = null)
+    public function __construct($source, $data = array())
     {
+        if (!Horde_Util::extensionExists('SimpleXML')) {
+            throw new Horde_Exception('SimpleXML not available.');
+        }
+
         if (isset($GLOBALS['nls']['charsets'][$GLOBALS['language']])) {
             $this->_charset = $GLOBALS['nls']['charsets'][$GLOBALS['language']];
         }
 
-        /* Populate $this->_buffer based on $source. */
         switch ($source) {
         case self::SOURCE_RAW:
-            $this->_buffer = $arg;
+            $this->_xml = new SimpleXMLElement($data[0]);
             break;
 
         case self::SOURCE_FILE:
-            if (file_exists($arg[0]) && filesize($arg[0])) {
-                $this->_buffer = file_get_contents($arg[0]);
-            } elseif (file_exists($arg[1]) && filesize($arg[1])) {
-                $this->_buffer = file_get_contents($arg[1]);
-            } else {
-                $this->_buffer = '';
+            foreach ($data as $val) {
+                if (@is_file($val)) {
+                    $this->_xml = new SimpleXMLElement($val, null, true);
+                    break;
+                }
             }
             break;
-
-        default:
-            $this->_buffer = '';
-            break;
         }
     }
 
     /**
-     * Generates the HTML link that will pop up a help window for the
-     * requested topic.
-     *
-     * @param string $module  The name of the current Horde module.
-     * @param string $topic   The help topic to be displayed.
-     *
-     * @return string  The HTML to create the help link.
-     */
-    static public function link($module, $topic)
-    {
-        if (!Horde_Menu::showService('help')) {
-            return '&nbsp;';
-        }
-
-        $url = Horde::url($GLOBALS['registry']->get('webroot', 'horde') . '/services/help/', true);
-        $url = Horde_Util::addParameter($url, array('module' => $module,
-                                                    'topic' => $topic), null, false);
-
-        return Horde::link($url, _("Help"), 'helplink', 'hordehelpwin', Horde::popupJs($url, array('urlencode' => true)) . 'return false;') .
-            Horde::img('help.png', _("Help"), 'width="16" height="16"', $GLOBALS['registry']->getImageDir('horde')) . '</a>';
-    }
-
-    /**
      * Looks up the requested entry in the XML help buffer.
      *
-     * @param string $entry  String containing the entry ID.
-     */
-    public function lookup($entry)
-    {
-        $this->_output = '';
-        $this->_reqEntry = Horde_String::upper($entry);
-        $this->_init();
-        xml_parse($this->_parser, $this->_buffer, true);
-    }
-
-    /**
-     * Returns a hash of all of the topics in this help buffer
-     * containing the keyword specified.
+     * @param string $id  String containing the entry ID.
      *
-     * @return array  Hash of all of the search results.
+     * @return string  The HTML formatted help entry.
      */
-    public function search($keyword)
+    public function lookup($id)
     {
-        $this->_init();
-        $this->_keyword = $keyword;
-        xml_parse($this->_parser, $this->_buffer, true);
+        $out = '';
 
-        return $this->_search;
-    }
+        foreach ($this->_xml->entry as $entry) {
+            if ($entry->attributes()->id == $id) {
+                foreach ($entry->children() as $child) {
+                    switch ($child->getName()) {
+                    case 'title':
+                        $out .= '<h1>' . $this->_processNode($child) . '</h1>';
+                        break;
 
-    /**
-     * Returns a hash of all of the topics in this help buffer.
-     *
-     * @return array  Hash of all of the topics in this buffer.
-     */
-    public function topics()
-    {
-        $this->_init();
-        xml_parse($this->_parser, $this->_buffer, true);
-
-        return $this->_entries;
-    }
+                    case 'heading':
+                        $out .= '<h2>' . $this->_processNode($child) . '</h2>';
+                        break;
 
-    /**
-     * Display the contents of the formatted output buffer.
-     */
-    public function display()
-    {
-        echo $this->_output;
-    }
+                    case 'para':
+                        $out .= '<p>' . $this->_processNode($child) . '</h2>';
+                        break;
+                    }
+                }
 
-    /**
-     * Initializes the XML parser.
-     *
-     * @return boolean  Returns true on success, false on failure.
-     * @throws Horde_Exception
-     */
-    protected function _init()
-    {
-        if (!isset($this->_parser)) {
-            if (!Horde_Util::extensionExists('xml')) {
-                throw new Horde_Exception('The XML functions are not available. Rebuild PHP with --with-xml.');
+                break;
             }
-
-            /* Create a new parser and set its default properties. */
-            $this->_parser = xml_parser_create();
-            xml_set_object($this->_parser, $this);
-            xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
-            xml_set_element_handler($this->_parser, '_startElement', '_endElement');
-            xml_set_character_data_handler($this->_parser, '_defaultHandler');
         }
 
-        return ($this->_parser != 0);
+        return $out;
     }
 
     /**
-     * User-defined function callback for start elements.
-     *
-     * @param object $parser  Handle to the parser instance.
-     * @param string $name    The name of this XML element.
-     * @param array $attrs    List of this element's attributes.
+     * TODO
      */
-    protected function _startElement($parser, $name, $attrs)
+    protected function _processNode($node)
     {
-        /* Call the assigned handler for this element, if one is
-         * available. */
-        if (in_array($name, array_keys($this->_handlers))) {
-            call_user_func(array(&$this, $this->_handlers[$name]), true, $attrs);
+        if (!count($node->children())) {
+            return strval($node);
         }
-    }
 
-    /**
-     * User-defined function callback for end elements.
-     *
-     * @param object $parser  Handle to the parser instance.
-     * @param string $name    The name of this XML element.
-     */
-    protected function _endElement($parser, $name)
-    {
-        /* Call the assigned handler for this element, if one is available. */
-        if (in_array($name, array_keys($this->_handlers))) {
-            call_user_func(array(&$this, $this->_handlers[$name]), false);
-        }
-    }
+        $out = '';
 
-    /**
-     * User-defined function callback for character data.
-     *
-     * @param object $parser  Handle to the parser instance.
-     * @param string $data    String of character data.
-     */
-    protected function _defaultHandler($parser, $data)
-    {
-        $data = Horde_String::convertCharset($data, version_compare(zend_version(), '2', '<') ? $this->_charset : 'UTF-8');
-        if ($this->_inTitle) {
-            $this->_entries[$this->_curEntry] .= $data;
-        }
+        foreach ($node->children() as $child) {
+            switch ($child->getName()) {
+            case 'ref':
+                $out .= Horde::link(Horde::selfUrl()->add(array(
+                    'module' => $child->attributes()->module,
+                    'show' => 'entry',
+                    'topic'  => $child->attributes()->entry
+                ))) . strval($child) . '</a>';
+                break;
 
-        if ($this->_inHelp && $this->_inBlock) {
-            $this->_output .= htmlspecialchars($data);
-        }
+            case 'eref':
+                $out .= Horde::link($child->attributes()->url, null, '', '_blank') . strval($child) . '</a>';
+                break;
 
-        if ($this->_keyword) {
-            if (stristr($data, $this->_keyword) !== false) {
-                $this->_search[$this->_curEntry] = $this->_entries[$this->_curEntry];
-            }
-        }
-    }
+            case 'href':
+                $out .= Horde::link(Horde::url($GLOBALS['registry']->get('webroot', $child->attributes()->app) . '/' . $child->attributes()->url), null, '', '_blank') . strval($child) . '</a>';
+                break;
 
-    /**
-     * XML element handler for the <help> tag.
-     *
-     * @param boolean $startTag  Boolean indicating whether this instance is a
-     *                           start tag.
-     * @param array $attrs       Additional element attributes (Not used).
-     */
-    protected function _helpHandler($startTag, $attrs = array())
-    {
-        $this->_inHelp = $startTag ?  true : false;
-    }
+            case 'b':
+                $out .= '<strong>' . strval($child) . '</strong>';
+                break;
 
-    /**
-     * XML element handler for the <entry> tag.
-     * Attributes: id
-     *
-     * @param boolean $startTag  Boolean indicating whether this instance is a
-     *                           start tag.
-     * @param array $attrs       Additional element attributes.
-     */
-    protected function _entryHandler($startTag, $attrs = array())
-    {
-        if (!$startTag) {
-            $this->_inBlock = false;
-        } else {
-            $id = Horde_String::upper($attrs['id']);
-            $this->_curEntry = $id;
-            $this->_entries[$id] = '';
-            $this->_inBlock = ($id == $this->_reqEntry);
-        }
-    }
+            case 'i':
+                $out .= '<em>' . strval($child) . '</em>';
+                break;
 
-    /**
-     * XML element handler for the <title> tag.
-     *
-     * @param boolean $startTag  Boolean indicating whether this instance is a
-     *                           start tag.
-     * @param array $attrs       Additional element attributes (Not used).
-     */
-    protected function _titleHandler($startTag, $attrs = array())
-    {
-        $this->_inTitle = $startTag;
-        if ($this->_inHelp && $this->_inBlock) {
-            $this->_output .= $startTag ? '<h1>' : '</h1>';
-        }
-    }
+            case 'pre':
+                $out .= '<pre>' . strval($child) . '</pre>';
+                break;
 
-    /**
-     * XML element handler for the <heading> tag.
-     *
-     * @param boolean $startTag  Boolean indicating whether this instance is a
-     *                           start tag.
-     * @param  array $attrs      Additional element attributes (Not used).
-     */
-    protected function _headingHandler($startTag, $attrs = array())
-    {
-        $this->_inHeading = $startTag;
-        if ($this->_inHelp && $this->_inBlock) {
-            $this->_output .= $startTag ? '<h2>' : '</h2>';
-        }
-    }
+            case 'tip':
+                $out .= '<em class="helpTip">' . strval($child) . '</em>';
+                break;
 
-    /**
-     * XML element handler for the <para> tag.
-     *
-     * @param boolean $startTag  Boolean indicating whether this instance is a
-     *                           start tag.
-     * @param array $attrs       Additional element attributes (Not used).
-     */
-    protected function _paraHandler($startTag, $attrs = array())
-    {
-        if ($this->_inHelp && $this->_inBlock) {
-            $this->_output .= $startTag ? '<p>' : '</p>';
-        }
-    }
-
-    /**
-     * XML element handler for the <ref> tag.
-     * Required attributes: ENTRY, MODULE
-     *
-     * @param boolean $startTag  Boolean indicating whether this instance is a
-     *                           start tag.
-     * @param array $attrs       Additional element attributes.
-     */
-    protected function _refHandler($startTag, $attrs = array())
-    {
-        if ($this->_inHelp && $this->_inBlock) {
-            if ($startTag && isset($attrs['module']) && isset($attrs['entry'])) {
-                $url = Horde_Util::addParameter(Horde::selfUrl(),
-                                          array('show' => 'entry',
-                                                'module' => $attrs['module'],
-                                                'topic'  => $attrs['entry']));
-                $this->_output .= Horde::link($url);
-            } else {
-                $this->_output .= '</a>';
+            case 'warn':
+                $out .= '<em class="helpWarn">' . strval($child) . '</em>';
+                break;
             }
         }
-    }
 
-    /**
-     * XML element handler for the <eref> tag.
-     * Required elements: URL
-     *
-     * @param boolean $startTag  Boolean indicating whether this instance is a
-     *                           start tag.
-     * @param array $attrs       Additional element attributes.
-     */
-    protected function _erefHandler($startTag, $attrs = array())
-    {
-        if ($this->_inHelp && $this->_inBlock) {
-            if ($startTag) {
-                $this->_output .= Horde::link($attrs['url'], null, '', '_blank');
-            } else {
-                $this->_output .= '</a>';
-            }
-        }
+        return $out;
     }
 
     /**
-     * XML element handler for the <href> tag.
-     * Required elements: url, app.
+     * Returns a hash of all of the topics in this help buffer
+     * containing the keyword specified.
      *
-     * @param boolean $startTag  Boolean indicating whether this instance is a
-     *                           start tag.
-     * @param array $attrs       Additional element attributes.
+     * @return array  Hash of all of the search results.
      */
-    protected function _hrefHandler($startTag, $attrs = array())
+    public function search($keyword)
     {
-        if ($this->_inHelp && $this->_inBlock) {
-            if ($startTag) {
-                $url = Horde::url($GLOBALS['registry']->get('webroot', $attrs['app']) . '/' . $attrs['url']);
-                $this->_output .= Horde::link($url, null, '', '_blank');
-            } else {
-                $this->_output .= '</a>';
+        $results = array();
+
+        foreach ($this->_xml->entry as $entry) {
+            foreach ($entry as $elt) {
+                if (stripos(strval($elt), $keyword) !== false) {
+                    $results[strval($entry->attributes()->id)] = strval($entry->title);
+                    break;
+                }
             }
         }
-    }
 
-    /**
-     * XML element handler for the &lt;b&gt; tag.
-     *
-     * @param boolean $startTag  Boolean indicating whether this instance is a
-     *                           start tag.
-     * @param array $attrs       Additional element attributes (Not used).
-     */
-    protected function _bHandler($startTag, $attrs = array())
-    {
-        if ($this->_inHelp && $this->_inBlock) {
-            $this->_output .= $startTag ? '<strong>' : '</strong>';
-        }
+        return $results;
     }
 
     /**
-     * XML element handler for the &lt;i&gt; tag.
+     * Returns a hash of all of the topics in this help buffer.
      *
-     * @param boolean $startTag  Boolean indicating whether this instance is a
-     *                           start tag.
-     * @param array $attrs       Additional element attributes.
+     * @return array  Hash of all of the topics in this buffer (keys are IDs,
+     *                values are the title names).
      */
-    protected function _iHandler($startTag, $attrs = array())
+    public function topics()
     {
-        if ($this->_inHelp && $this->_inBlock) {
-            $this->_output .= $startTag ? '<em>' : '</em>';
-        }
-    }
+        $topics = array();
 
-    /**
-     * XML element handler for the &lt;pre&gt; tag.
-     *
-     * @param boolean $startTag  Boolean indicating whether this instance is a
-     *                           start tag.
-     * @param array $attrs       Additional element attributes.
-     */
-    protected function _preHandler($startTag, $attrs = array())
-    {
-        if ($this->_inHelp && $this->_inBlock) {
-            $this->_output .= $startTag ? '<pre>' : '</pre>';
+        foreach ($this->_xml->entry as $elt) {
+            $topics[strval($elt->attributes()->id)] = strval($elt->title);
         }
-    }
 
-    /**
-     * XML element handler for the <tip> tag.
-     *
-     * @param boolean $startTag  Boolean indicating whether this instance is a
-     *                           start tag.
-     * @param array $attrs       Additional element attributes.
-     */
-    protected function _tipHandler($startTag, $attrs = array())
-    {
-        if ($this->_inHelp && $this->_inBlock) {
-            $this->_output .= $startTag ? '<em class="helpTip">' : '</em>';
-        }
+        return $topics;
     }
 
+
     /**
-     * XML element handler for the <warn> tag.
+     * Generates the HTML link that will pop up a help window for the
+     * requested topic.
+     *
+     * @param string $module  The name of the current Horde module.
+     * @param string $topic   The help topic to be displayed.
      *
-     * @param boolean $startTag  Boolean indicating whether this instance is a
-     *                           start tag.
-     * @param array $attrs       Additional element attributes.
+     * @return string  The HTML to create the help link.
      */
-    protected function _warnHandler($startTag, $attrs = array())
+    static public function link($module, $topic)
     {
-        if ($this->_inHelp && $this->_inBlock) {
-            $this->_output .= $startTag ? '<em class="helpWarn">' : '</em>';
+        if (!Horde_Menu::showService('help')) {
+            return '';
         }
+
+        $url = Horde::getServiceLink('help', $module)->add('topic', $topic)->setRaw(true);
+        return Horde::link($url, _("Help"), 'helplink', 'hordehelpwin', Horde::popupJs($url, array('urlencode' => true)) . 'return false;') .
+            Horde::img('help.png', _("Help"), 'width="16" height="16"', $GLOBALS['registry']->getImageDir('horde')) . '</a>';
     }
 
+
 }
index 8a93a4b..ae5f82b 100644 (file)
@@ -160,8 +160,7 @@ case 'sidebar':
 
 case 'entry':
     if ($topic) {
-        $help->lookup($topic);
-        $help->display();
+        echo $help->lookup($topic);
     }
     break;
 }