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
33 class Phergie_Plugin_Command extends Phergie_Plugin_Abstract
36 * Cache for command lookups used to confirm that methods exist and
37 * parameter counts match
41 protected $methods = array();
44 * Prefix for command method names
48 protected $methodPrefix = 'onCommand';
51 * Populates the methods cache.
55 protected function populateMethodCache()
57 foreach ($this->getPluginHandler() as $plugin) {
58 $reflector = new ReflectionClass($plugin);
59 foreach ($reflector->getMethods() as $method) {
60 $name = $method->getName();
61 if (strpos($name, $this->methodPrefix) === 0
62 && !isset($this->methods[$name])
64 $this->methods[$name] = array(
65 'total' => $method->getNumberOfParameters(),
66 'required' => $method->getNumberOfRequiredParameters()
74 * Parses a given message and, if its format corresponds to that of a
75 * defined command, calls the handler method for that command with any
76 * provided parameters.
80 public function onPrivmsg()
82 // Populate the methods cache if needed
83 if (empty($this->methods)) {
84 $this->populateMethodCache();
87 // Get the content of the message
88 $event = $this->getEvent();
89 $msg = trim($event->getText());
90 $prefix = $this->getConfig('command.prefix');
92 // Check for the command prefix if one is set and needed
93 if ($prefix && $event->isInChannel()) {
94 if (strpos($msg, $prefix) !== 0) {
97 $msg = substr($msg, strlen($prefix));
101 // Separate the command and arguments
102 $parsed = preg_split('/\s+/', $msg, 2);
103 $method = $this->methodPrefix . ucfirst(strtolower(array_shift($parsed)));
104 $args = count($parsed) ? array_shift($parsed) : '';
106 // Check to ensure the command exists
107 if (empty($this->methods[$method])) {
111 // If no arguments are passed...
114 // If the method requires no arguments, call it
115 if (empty($this->methods[$method]['required'])) {
116 $this->getPluginHandler()->$method();
120 // If arguments are passed...
122 // Parse the arguments
123 $args = preg_split('/\s+/', $args, $this->methods[$method]['total']);
125 // If the minimum arguments are passed, call the method
126 if ($this->methods[$method]['required'] <= count($args)) {
127 call_user_func_array(
128 array($this->getPluginHandler(), $method),