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
15 * @package Phergie_Plugin_Command
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_Command
23 * Handles parsing and execution of commands sent by users via messages sent
24 * to channels in which the bot is present or directly to the bot.
27 * @package Phergie_Plugin_Command
28 * @author Phergie Development Team <team@phergie.org>
29 * @license http://phergie.org/license New BSD License
30 * @link http://pear.phergie.org/package/Phergie_Plugin_Command
31 * @uses extension reflection
32 * @uses Phergie_Plugin_Message pear.phergie.org
34 class Phergie_Plugin_Command extends Phergie_Plugin_Abstract
37 * Prefix for command method names
41 const METHOD_PREFIX = 'onCommand';
44 * Cache for command lookups used to confirm that methods exist and
45 * parameter counts match
49 protected $methods = array();
52 * Load the Message plugin
56 public function onLoad()
58 $plugins = $this->getPluginHandler();
59 $plugins->getPlugin('Message');
63 * Populates the methods cache.
67 public function populateMethodCache()
69 foreach ($this->getPluginHandler()->getPlugins() as $plugin) {
70 $reflector = new ReflectionClass($plugin);
71 foreach ($reflector->getMethods() as $method) {
72 $name = $method->getName();
73 if (strpos($name, self::METHOD_PREFIX) === 0
74 && !isset($this->methods[$name])
76 $this->methods[$name] = array(
77 'total' => $method->getNumberOfParameters(),
78 'required' => $method->getNumberOfRequiredParameters()
86 * Parses a given message and, if its format corresponds to that of a
87 * defined command, calls the handler method for that command with any
88 * provided parameters.
92 public function onPrivmsg()
94 // Populate the methods cache if needed
95 if (empty($this->methods)) {
96 $this->populateMethodCache();
99 // Check for a prefixed message
100 $msg = $this->plugins->message->getMessage();
101 if ($msg === false) {
105 // Separate the command and arguments
106 $parsed = preg_split('/\s+/', $msg, 2);
107 $command = strtolower(array_shift($parsed));
108 $args = count($parsed) ? array_shift($parsed) : '';
110 // Resolve aliases to their corresponding commands
111 $aliases = $this->getConfig('command.aliases', array());
112 $result = preg_grep('/^' . preg_quote($command, '/') . '$/i', array_keys($aliases));
114 $command = $aliases[array_shift($result)];
117 // Check to ensure the command exists
118 $method = self::METHOD_PREFIX . ucfirst($command);
119 if (empty($this->methods[$method])) {
123 // If no arguments are passed...
126 // If the method requires no arguments, call it
127 if (empty($this->methods[$method]['required'])) {
128 $this->getPluginHandler()->$method();
132 // If arguments are passed...
134 // Parse the arguments
135 $args = preg_split('/\s+/', $args, $this->methods[$method]['total']);
137 // If the minimum arguments are passed, call the method
138 if ($this->methods[$method]['required'] <= count($args)) {
139 call_user_func_array(
140 array($this->getPluginHandler(), $method),