* @copyright 2008-2010 Phergie Development Team (http://phergie.org) * @license http://phergie.org/license New BSD License * @link http://pear.phergie.org/package/Phergie */ /** * Base class for plugins to provide event handler stubs and commonly needed * functionality. * * @category Phergie * @package Phergie * @author Phergie Development Team * @license http://phergie.org/license New BSD License * @link http://pear.phergie.org/package/Phergie */ abstract class Phergie_Plugin_Abstract { /** * Current configuration handler * * @var Phergie_Config */ protected $config; /** * Plugin handler used to provide access to other plugins * * @var Phergie_Plugin_Handler */ protected $plugins; /** * Current event handler instance for outgoing events * * @var Phergie_Event_Handler */ protected $events; /** * Current connection instance * * @var Phergie_Connection */ protected $connection; /** * Current incoming event being handled * * @var Phergie_Event_Request|Phergie_Event_Response */ protected $event; /** * Plugin short name * * @var string */ protected $name; /** * Returns the short name for the plugin based on its class name. * * @return string */ public function getName() { if (empty($this->name)) { $this->name = substr(strrchr(get_class($this), '_'), 1); } return $this->name; } /** * Sets the short name for the plugin. * * @param string $name Plugin short name * * @return Phergie_Plugin_Abstract Provides a fluent interface */ public function setName($name) { $this->name = (string) $name; return $this; } /** * Indicates that the plugin failed to load due to an unsatisfied * runtime requirement, such as a missing dependency. * * @param string $message Error message to provide more information * about the reason for the failure * * @return Phergie_Plugin_Abstract Provides a fluent interface * @throws Phergie_Plugin_Exception Always */ protected function fail($message) { throw new Phergie_Plugin_Exception( $message, Phergie_Plugin_Exception::ERR_REQUIREMENT_UNSATISFIED ); } /** * Sets the current configuration handler. * * @param Phergie_Config $config Configuration handler * * @return Phergie_Plugin_Abstract Provides a fluent interface */ public function setConfig(Phergie_Config $config) { $this->config = $config; return $this; } /** * Returns the current configuration handler or the value of a single * setting from it. * * @param string $name Optional name of a setting for which the value * should be returned instead of the entire configuration handler * @param mixed $default Optional default value to return if no value * is set for the setting indicated by $name * * @return Phergie_Config|mixed Configuration handler or value of the * setting specified by $name * @throws Phergie_Plugin_Exception No configuration handler has been set */ public function getConfig($name = null, $default = null) { if (empty($this->config)) { throw new Phergie_Plugin_Exception( 'Configuration handler cannot be accessed before one is set', Phergie_Plugin_Exception::ERR_NO_CONFIG_HANDLER ); } if (!is_null($name)) { if (!isset($this->config[$name])) { return $default; } return $this->config[$name]; } return $this->config; } /** * Sets the current plugin handler. * * @param Phergie_Plugin_Handler $handler Plugin handler * * @return Phergie_Plugin_Abstract Provides a fluent interface */ public function setPluginHandler(Phergie_Plugin_Handler $handler) { $this->plugins = $handler; return $this; } /** * Returns the current plugin handler. * * @return Phergie_Plugin_Handler * @throws Phergie_Plugin_Exception No plugin handler has been set */ public function getPluginHandler() { if (empty($this->plugins)) { throw new Phergie_Plugin_Exception( 'Plugin handler cannot be accessed before one is set', Phergie_Plugin_Exception::ERR_NO_PLUGIN_HANDLER ); } return $this->plugins; } /** * Sets the current event handler. * * @param Phergie_Event_Handler $handler Event handler * * @return Phergie_Plugin_Abstract Provides a fluent interface */ public function setEventHandler(Phergie_Event_Handler $handler) { $this->events = $handler; return $this; } /** * Returns the current event handler. * * @return Phergie_Event_Handler * @throws Phergie_Plugin_Exception No event handler has been set */ public function getEventHandler() { if (empty($this->events)) { throw new Phergie_Plugin_Exception( 'Event handler cannot be accessed before one is set', Phergie_Plugin_Exception::ERR_NO_EVENT_HANDLER ); } return $this->events; } /** * Sets the current connection. * * @param Phergie_Connection $connection Connection * * @return Phergie_Plugin_Abstract Provides a fluent interface */ public function setConnection(Phergie_Connection $connection) { $this->connection = $connection; return $this; } /** * Returns the current event connection. * * @return Phergie_Connection * @throws Phergie_Plugin_Exception No connection has been set */ public function getConnection() { if (empty($this->connection)) { throw new Phergie_Plugin_Exception( 'Connection cannot be accessed before one is set', Phergie_Plugin_Exception::ERR_NO_CONNECTION ); } return $this->connection; } /** * Sets the current incoming event to be handled. * * @param Phergie_Event_Request|Phergie_Event_Response $event Event * * @return Phergie_Plugin_Abstract Provides a fluent interface */ public function setEvent($event) { $this->event = $event; return $this; } /** * Returns the current incoming event to be handled. * * @return Phergie_Event_Request|Phergie_Event_Response */ public function getEvent() { if (empty($this->event)) { throw new Phergie_Plugin_Exception( 'Event cannot be accessed before one is set', Phergie_Plugin_Exception::ERR_NO_EVENT ); } return $this->event; } /** * Provides do* methods with signatures identical to those of * Phergie_Driver_Abstract but that queue up events to be dispatched * later. * * @param string $name Name of the method called * @param array $args Arguments passed in the call * * @return mixed */ public function __call($name, array $args) { $subcmd = substr($name, 0, 2); if ($subcmd == 'do') { $type = strtolower(substr($name, 2)); $this->getEventHandler()->addEvent($this, $type, $args); } else if ($subcmd != 'on') { throw new Phergie_Plugin_Exception( 'Called invalid method ' . $name . ' in ' . get_class($this), Phergie_Plugin_Exception::ERR_INVALID_CALL ); } } /** * Handler for when the plugin is initially loaded - useful for checking * runtime dependencies or performing any setup necessary for the plugin * to function properly such as initializing a database. * * @return void */ public function onLoad() { } /** * Handler for when the bot initially connects to a server. * * @return void */ public function onConnect() { } /** * Handler for each tick, a single iteration of the continuous loop * executed by the bot to receive, handle, and send events - useful for * repeated execution of tasks on a time interval. * * @return void */ public function onTick() { } /** * Handler for when any event is received but has not yet been dispatched * to the plugin handler method specific to its event type. * * @return bool|null|void FALSE to short-circuit further event * processing, TRUE or NULL otherwise */ public function preEvent() { } /** * Handler for after plugin processing of an event has concluded but * before any events triggered in response by plugins are sent to the * server - useful for modifying outgoing events before they are sent. * * @return void */ public function preDispatch() { } /** * Handler for after any events triggered by plugins in response to a * received event are sent to the server. * * @return void */ public function postDispatch() { } /** * Handler for when the server prompts the client for a nick. * * @return void * @link http://irchelp.org/irchelp/rfc/chapter4.html#c4_1_2 */ public function onNick() { } /** * Handler for when a user obtains operator privileges. * * @return void * @link http://irchelp.org/irchelp/rfc/chapter4.html#c4_1_5 */ public function onOper() { } /** * Handler for when the client session is about to be terminated. * * @return void * @link http://irchelp.org/irchelp/rfc/chapter4.html#c4_1_6 */ public function onQuit() { } /** * Handler for when a user joins a channel. * * @return void * @link http://irchelp.org/irchelp/rfc/chapter4.html#c4_2_1 */ public function onJoin() { } /** * Handler for when a user leaves a channel. * * @return void * @link http://irchelp.org/irchelp/rfc/chapter4.html#c4_2_2 */ public function onPart() { } /** * Handler for when a user or channel mode is changed. * * @return void * @link http://irchelp.org/irchelp/rfc/chapter4.html#c4_2_3 */ public function onMode() { } /** * Handler for when a channel topic is viewed or changed. * * @return void * @link http://irchelp.org/irchelp/rfc/chapter4.html#c4_2_4 */ public function onTopic() { } /** * Handler for when a message is received from a channel or user. * * @return void * @link http://irchelp.org/irchelp/rfc/chapter4.html#c4_4_1 */ public function onPrivmsg() { } /** * Handler for when the bot receives a CTCP ACTION request. * * @return void * @link http://www.invlogic.com/irc/ctcp.html#4.4 */ public function onAction() { } /** * Handler for when a notice is received. * * @return void * @link http://irchelp.org/irchelp/rfc/chapter4.html#c4_4_2 */ public function onNotice() { } /** * Handler for when a user is kicked from a channel. * * @return void * @link http://irchelp.org/irchelp/rfc/chapter4.html#c4_2_8 */ public function onKick() { } /** * Handler for when the bot receives a ping event from a server, at * which point it is expected to respond with a pong request within * a short period else the server may terminate its connection. * * @return void * @link http://irchelp.org/irchelp/rfc/chapter4.html#c4_6_2 */ public function onPing() { } /** * Handler for when the bot receives a CTCP TIME request. * * @return void * @link http://www.invlogic.com/irc/ctcp.html#4.6 */ public function onTime() { } /** * Handler for when the bot receives a CTCP VERSION request. * * @return void * @link http://www.invlogic.com/irc/ctcp.html#4.1 */ public function onVersion() { } /** * Handler for when the bot receives a CTCP PING request. * * @return void * @link http://www.invlogic.com/irc/ctcp.html#4.2 */ public function onCtcpPing() { } /** * Handler for when the bot receives a CTCP request of an unknown type. * * @return void * @link http://www.invlogic.com/irc/ctcp.html */ public function onCtcp() { } /** * Handler for when a reply is received for a CTCP PING request sent by * the bot. * * @return void * @link http://www.invlogic.com/irc/ctcp.html#4.2 */ public function onPingReply() { } /** * Handler for when a reply is received for a CTCP TIME request sent by * the bot. * * @return void * @link http://www.invlogic.com/irc/ctcp.html#4.6 */ public function onTimeReply() { } /** * Handler for when a reply is received for a CTCP VERSION request sent * by the bot. * * @return void * @link http://www.invlogic.com/irc/ctcp.html#4.1 */ public function onVersionReply() { } /** * Handler for when a reply received for a CTCP request of an unknown * type. * * @return void * @link http://www.invlogic.com/irc/ctcp.html */ public function onCtcpReply() { } /** * Handler for when the bot receives a kill request from a server. * * @return void * @link http://irchelp.org/irchelp/rfc/chapter4.html#c4_6_1 */ public function onKill() { } /** * Handler for when the bot receives an invitation to join a channel. * * @return void * @link http://irchelp.org/irchelp/rfc/chapter4.html#c4_2_7 */ public function onInvite() { } /** * Handler for when a server response is received to a command issued by * the bot. * * @return void * @link http://irchelp.org/irchelp/rfc/chapter6.html */ public function onResponse() { } }