]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/Irc/extlib/phergie/Phergie/Plugin/Help.php
Revert "Merged in Phergie changes"
[quix0rs-gnu-social.git] / plugins / Irc / extlib / phergie / Phergie / Plugin / Help.php
1 <?php
2 /**
3  * Phergie
4  *
5  * PHP version 5
6  *
7  * LICENSE
8  *
9  * This source file is subject to the new BSD license that is bundled
10  * with this package in the file LICENSE.
11  * It is also available through the world-wide-web at this URL:
12  * http://phergie.org/license
13  *
14  * @category  Phergie
15  * @package   Phergie_Plugin_Help
16  * @author    Phergie Development Team <team@phergie.org>
17  * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
18  * @license   http://phergie.org/license New BSD License
19  * @link      http://pear.phergie.org/package/Phergie_Plugin_Help
20  */
21
22 /**
23  * Provides access to descriptions of plugins and the commands they provide.
24  *
25  * @category Phergie
26  * @package  Phergie_Plugin_Help
27  * @author   Phergie Development Team <team@phergie.org>
28  * @license  http://phergie.org/license New BSD License
29  * @link     http://pear.phergie.org/package/Phergie_Plugin_Help
30  * @uses     Phergie_Plugin_Command pear.phergie.org
31  *
32  * @pluginDesc Provides access to plugin help information
33  */
34 class Phergie_Plugin_Help extends Phergie_Plugin_Abstract
35 {
36
37     /**
38      * Holds the registry of help data indexed by plugin name
39      *
40      * @var array
41      */
42     protected $registry;
43
44     /**
45      * Whether the registry has been alpha sorted
46      *
47      * @var bool
48      */
49     protected $registry_sorted = false;
50
51     /**
52      * Checks for dependencies.
53      *
54      * @return void
55      */
56     public function onLoad()
57     {
58         $this->getPluginHandler()->getPlugin('Command');
59         $this->register($this);
60     }
61
62     /**
63      * Displays a list of plugins with help information available or
64      * commands available for a specific plugin.
65      *
66      * @param string $plugin Short name of the plugin for which commands
67      *        should be returned, else a list of plugins with help
68      *        information available is returned
69      *
70      * @return void
71      *
72      * @pluginCmd Show all active plugins with help available
73      * @pluginCmd [plugin] Shows commands line for a specific plugin
74      */
75     public function onCommandHelp($plugin = null)
76     {
77         $nick = $this->getEvent()->getNick();
78
79         if (!$plugin) {
80             // protect from sorting the registry each time help is called
81             if (!$this->registry_sorted) {
82                 asort($this->registry);
83                 $this->registry_sorted = true;
84             }
85
86             $msg = 'These plugins below have help information available.';
87             $this->doPrivMsg($nick, $msg);
88
89             foreach ($this->registry as $plugin => $data) {
90                 $this->doPrivMsg($nick, "{$plugin} - {$data['desc']}");
91             }
92         } else {
93             if (isset($this->getPluginHandler()->{$plugin})
94                 && isset($this->registry[strtolower($plugin)]['cmd'])
95             ) {
96                 $msg
97                     = 'The ' .
98                     $plugin .
99                     ' plugin exposes the commands shown below.';
100                 $this->doPrivMsg($nick, $msg);
101                 if ($this->getConfig('command.prefix')) {
102                     $msg
103                         = 'Note that these commands must be prefixed with "' .
104                         $this->getConfig('command.prefix') .
105                         '" (without quotes) when issued in a public channel.';
106                     $this->doPrivMsg($nick, $msg);
107                 }
108
109                 foreach ($this->registry[strtolower($plugin)]['cmd']
110                     as $cmd => $descs
111                 ) {
112                     foreach ($descs as $desc) {
113                         $this->doPrivMsg($nick, "{$cmd} {$desc}");
114                     }
115                 }
116
117             } else {
118                 $this->doPrivMsg($nick, 'That plugin is not loaded.');
119             }
120         }
121     }
122
123     /**
124      * Sets the description for the plugin instance
125      *
126      * @param Phergie_Plugin_Abstract $plugin      plugin instance
127      * @param string                  $description plugin description
128      *
129      * @return void
130      */
131     public function setPluginDescription(
132         Phergie_Plugin_Abstract $plugin,
133         $description
134     ) {
135         $this->registry[strtolower($plugin->getName())]
136                 ['desc'] = $description;
137     }
138
139     /**
140      * Sets the description for the command on the plugin instance
141      *
142      * @param Phergie_Plugin_Abstract $plugin      plugin instance
143      * @param string                  $command     from onCommand method
144      * @param string                  $description command description
145      *
146      * @return void
147      */
148     public function setCommandDescription(
149         Phergie_Plugin_Abstract $plugin,
150         $command,
151         array $description
152     ) {
153         $this->registry[strtolower($plugin->getName())]
154             ['cmd'][$command] = $description;
155     }
156
157     /**
158      * registers the plugin with the help plugin. this will parse the docblocks
159      * for specific annotations that this plugin will respond with when
160      * queried.
161      *
162      * @param Phergie_Plugin_Abstract $plugin plugin instance
163      *
164      * @return void
165      */
166     public function register(Phergie_Plugin_Abstract $plugin)
167     {
168         $class = new ReflectionClass($plugin);
169
170         $annotations = self::parseAnnotations($class->getDocComment());
171         if (isset($annotations['pluginDesc'])) {
172             $this->setPluginDescription(
173                 $plugin,
174                 join(' ', $annotations['pluginDesc'])
175             );
176         }
177
178         foreach ($class->getMethods() as $method) {
179             if (strpos($method->getName(), 'onCommand') !== false) {
180                 $annotations = self::parseAnnotations($method->getDocComment());
181                 if (isset($annotations['pluginCmd'])) {
182                     $cmd = strtolower(substr($method->getName(), 9));
183                     $this->setCommandDescription(
184                         $plugin,
185                         $cmd,
186                         $annotations['pluginCmd']
187                     );
188                 }
189             }
190         }
191     }
192
193     /**
194      * Taken from PHPUnit/Util/Test.php:243 and modified to fix an issue
195      * with tag content spanning multiple lines.
196      *
197      * PHPUnit
198      *
199      * Copyright (c) 2002-2010, Sebastian Bergmann <sb@sebastian-bergmann.de>.
200      * All rights reserved.
201      *
202      * Redistribution and use in source and binary forms, with or without
203      * modification, are permitted provided that the following conditions
204      * are met:
205      *
206      *   * Redistributions of source code must retain the above copyright
207      *     notice, this list of conditions and the following disclaimer.
208      *
209      *   * Redistributions in binary form must reproduce the above copyright
210      *     notice, this list of conditions and the following disclaimer in
211      *     the documentation and/or other materials provided with the
212      *     distribution.
213      *
214      *   * Neither the name of Sebastian Bergmann nor the names of his
215      *     contributors may be used to endorse or promote products derived
216      *     from this software without specific prior written permission.
217      *
218      * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
219      * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
220      * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
221      * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
222      * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
223      * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
224      * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
225      * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
226      * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
227      * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
228      * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
229      * POSSIBILITY OF SUCH DAMAGE.
230      *
231      * @param string $docblock docblock to parse
232      *
233      * @return array
234      */
235     protected static function parseAnnotations($docblock)
236     {
237         $annotations = array();
238
239         $regex = '/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?(?:\*\/|\* @)/ms';
240
241         if (preg_match_all($regex, $docblock, $matches)) {
242             $numMatches = count($matches[0]);
243
244             for ($i = 0; $i < $numMatches; ++$i) {
245                 $annotation = $matches['value'][$i];
246                 $annotation = preg_replace('/\s*\v+\s*\*\s*/', ' ', $annotation);
247                 $annotation = rtrim($annotation);
248                 $annotations[$matches['name'][$i]][] = $annotation;
249             }
250         }
251
252         return $annotations;
253     }
254 }