src/EventQueue.php
<?php
/**
* Phergie (http://phergie.org)
* @copyright Copyright (c) 2008-2014 Phergie Development Team (http://phergie.org)
* @license http://phergie.org/license Simplified BSD License
* @package Phergie\Irc\Bot\React
*/
namespace Phergie\Irc\Bot\React;
use Phergie\Irc\Event\CtcpEvent;
use Phergie\Irc\Event\UserEvent;
use Phergie\Irc\Event\UserEventInterface;
/**
* Queue to contain commands issued by plugins to be sent to servers so as to
* allow for manipulation of those commands by plugins prior to their
* transmission.
*
* @category Phergie
* @package Phergie\Irc\Bot\React
*/
class EventQueue implements EventQueueInterface
{
/**
* Internal priority queue.
*
* @var \Phergie\Irc\Bot\React\EventQueueInternal
*/
protected $queue;
/**
* Prefix for queued messages
*
* @var string
*/
protected $prefix;
/**
* Enumerated array of commands in priority order
*
* @var array
*/
protected $priorities;
/**
* Track the last timestamp used for priority so we can avoid duplicate values
*
* @var int
*/
protected $lastTimestamp = 0;
/**
* Initializes the list of event priorities.
*/
public function __construct()
{
$this->queue = new EventQueueInternal;
$this->priorities = $this->getPriorities();
}
/**
* Allows iteration over the event queue.
*
* @return \Phergie\Irc\Bot\React\EventQueueInternal
*/
public function getIterator()
{
return clone $this->queue;
}
/**
* Wrapper for the queue's internal count method.
*
* @return int
*/
public function count()
{
return $this->queue->count();
}
/**
* Removes and returns an event from the front of the queue.
*
* @return \Phergie\Irc\Event\EventInterface|null Removed event or null if
* the queue is empty
*/
public function extract()
{
if ($this->queue->isEmpty()) {
return null;
}
return $this->queue->extract();
}
/**
* Implements \Phergie\Irc\GeneratorInterface->setPrefix().
*
* @param string $prefix
*/
public function setPrefix($prefix)
{
$this->prefix = $prefix;
}
/**
* Returns the priority of a specified command.
*
* @param string $command
* @param array $params Unused, intended for use by subclasses
* @return \Phergie\Irc\Bot\React\EventQueuePriority
*/
protected function getPriority($command, array $params)
{
$priority = new EventQueuePriority;
$priority->value = $this->priorities[$command];
$priority->timestamp = (int) (microtime(true) * 10000);
if ($priority->timestamp <= $this->lastTimestamp) {
$priority->timestamp = $this->lastTimestamp + 1;
}
$this->lastTimestamp = $priority->timestamp;
return $priority;
}
/**
* Enqueues a new event.
*
* @param \Phergie\Irc\Event\UserEventInterface
* @param string $command
* @param array $params
*/
protected function queueRequest(UserEventInterface $event, $command, array $params)
{
$event->setPrefix($this->prefix);
$event->setCommand($command);
$event->setParams(array_filter($params, 'strlen'));
$this->queue->insert($event, $this->getPriority($command, $params));
}
/**
* Enqueues a new IRC event.
*
* @param string $command
* @param array $params
*/
protected function queueIrcRequest($command, array $params = [])
{
$this->queueRequest(new UserEvent, $command, $params);
}
/**
* Enqueues a new CTCP event.
*
* @param string $command IRC command
* @param string $ctcpCommand CTCP command
* @param array $params Command parameters
*/
protected function queueCtcpEvent($command, $ctcpCommand, array $params = [])
{
$event = new CtcpEvent;
$event->setCtcpCommand($ctcpCommand);
$this->queueRequest($event, $command, $params);
}
/**
* Enqueues a new CTCP request.
*
* @param string $ctcpCommand CTCP command
* @param array $params Command parameters
*/
protected function queueCtcpRequest($ctcpCommand, array $params = [])
{
$this->queueCtcpEvent('PRIVMSG', $ctcpCommand, $params);
}
/**
* Enqueues a new CTCP response.
*
* @param string $ctcpCommand CTCP command
* @param array $params CTCP parameters
*/
protected function queueCtcpResponse($ctcpCommand, array $params = [])
{
$this->queueCtcpEvent('NOTICE', $ctcpCommand, $params);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircPass().
*
* @param string $password
*/
public function ircPass($password)
{
$this->queueIrcRequest('PASS', [ $password ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircNick().
*
* @param string $nickname
* @param int $hopcount
*/
public function ircNick($nickname, $hopcount = null)
{
$this->queueIrcRequest('NICK', [ $nickname, $hopcount ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircUser().
*
* @param string $username
* @param string $hostname
* @param string $servername
* @param string $realname
*/
public function ircUser($username, $hostname, $servername, $realname)
{
$this->queueIrcRequest('USER', [ $username, $hostname, $servername, $realname ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircServer().
*
* @param string $servername
* @param int $hopcount
* @param string $info
*/
public function ircServer($servername, $hopcount, $info)
{
$this->queueIrcRequest('SERVER', [ $servername, $hopcount, $info ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircOper().
*
* @param string $user
* @param string $password
*/
public function ircOper($user, $password)
{
$this->queueIrcRequest('OPER', [ $user, $password ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircQuit().
*
* @param string $message
*/
public function ircQuit($message = null)
{
$this->queueIrcRequest('QUIT', [ $message ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircSquit().
*
* @param string $server
* @param string $comment
*/
public function ircSquit($server, $comment)
{
$this->queueIrcRequest('SQUIT', [ $server, $comment ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircJoin().
*
* @param string $channels
* @param string $keys
*/
public function ircJoin($channels, $keys = null)
{
$this->queueIrcRequest('JOIN', [ $channels, $keys ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircPart().
*
* @param string $channels
* @param string|null $message
*/
public function ircPart($channels, $message = null)
{
$this->queueIrcRequest('PART', [ $channels, $message ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircMode().
*
* @param string $target
* @param string|null $mode
* @param string|null $param
*/
public function ircMode($target, $mode = null, $param = null)
{
$this->queueIrcRequest('MODE', [ $target, $mode, $param ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircTopic().
*
* @param string $channel
* @param string $topic
*/
public function ircTopic($channel, $topic = null)
{
$this->queueIrcRequest('TOPIC', [ $channel, $topic ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircNames().
*
* @param string $channels
*/
public function ircNames($channels)
{
$this->queueIrcRequest('NAMES', [ $channels ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircList().
*
* @param string $channels
* @param string $server
*/
public function ircList($channels = null, $server = null)
{
$this->queueIrcRequest('LIST', [ $channels, $server ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircInvite().
*
* @param string $nickname
* @param string $channel
*/
public function ircInvite($nickname, $channel)
{
$this->queueIrcRequest('INVITE', [ $nickname, $channel ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircKick().
*
* @param string $channel
* @param string $user
* @param string $comment
*/
public function ircKick($channel, $user, $comment = null)
{
$this->queueIrcRequest('KICK', [ $channel, $user, $comment ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircVersion().
*
* @param string $server
*/
public function ircVersion($server = null)
{
$this->queueIrcRequest('VERSION', [ $server ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircStats().
*
* @param string $query
* @param string $server
*/
public function ircStats($query, $server = null)
{
$this->queueIrcRequest('STATS', [ $query, $server ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircLinks().
*
* @param string $servermask
* @param string $remoteserver
*/
public function ircLinks($servermask = null, $remoteserver = null)
{
$this->queueIrcRequest('LINKS', [ $servermask, $remoteserver ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircTime().
*
* @param string $server
*/
public function ircTime($server = null)
{
$this->queueIrcRequest('TIME', [ $server ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircConnect().
*
* @param string $targetserver
* @param int $port
* @param string $remoteserver
*/
public function ircConnect($targetserver, $port = null, $remoteserver = null)
{
$this->queueIrcRequest('CONNECT', [ $targetserver, $port, $remoteserver ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircTrace().
*
* @param string $server
*/
public function ircTrace($server = null)
{
$this->queueIrcRequest('TRACE', [ $server ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircAdmin()
*
* @param string $server
*/
public function ircAdmin($server = null)
{
$this->queueIrcRequest('ADMIN', [ $server ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircInfo().
*
* @param string $server
*/
public function ircInfo($server = null)
{
$this->queueIrcRequest('INFO', [ $server ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircPrivmsg().
*
* @param string $receivers
* @param string $text
*/
public function ircPrivmsg($receivers, $text)
{
$this->queueIrcRequest('PRIVMSG', [ $receivers, $text ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircNotice().
*
* @param string $nickname
* @param string $text
*/
public function ircNotice($nickname, $text)
{
$this->queueIrcRequest('NOTICE', [ $nickname, $text ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircWho().
*
* @param string $name
* @param string $o
*/
public function ircWho($name, $o = null)
{
$this->queueIrcRequest('WHO', [ $name, $o ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircWhois().
*
* @param string $nickmasks
* @param string $server Optional
*/
public function ircWhois($nickmasks, $server = null)
{
$this->queueIrcRequest('WHOIS', [ $server, $nickmasks ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircWhowas().
*
* @param string $nickname
* @param int $count
* @param string $server
*/
public function ircWhowas($nickname, $count = null, $server = null)
{
$this->queueIrcRequest('WHOWAS', [ $nickname, $count, $server ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircKill().
*
* @param string $nickname
* @param string $comment
*/
public function ircKill($nickname, $comment)
{
$this->queueIrcRequest('KILL', [ $nickname, $comment ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircPing().
*
* @param string $server1
* @param string $server2
*/
public function ircPing($server1, $server2 = null)
{
$this->queueIrcRequest('PING', [ $server1, $server2 ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircPong().
*
* @param string $daemon
* @param string $daemon2
*/
public function ircPong($daemon, $daemon2 = null)
{
$this->queueIrcRequest('PONG', [ $daemon, $daemon2 ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircError().
*
* @param string $message
*/
public function ircError($message)
{
$this->queueIrcRequest('ERROR', [ $message ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircAway().
*
* @param string $message
*/
public function ircAway($message = null)
{
$this->queueIrcRequest('AWAY', [ $message ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircRehash().
*/
public function ircRehash()
{
$this->queueIrcRequest('REHASH');
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircRestart().
*/
public function ircRestart()
{
$this->queueIrcRequest('RESTART');
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircSummon().
*
* @param string $user
* @param string $server
*/
public function ircSummon($user, $server = null)
{
$this->queueIrcRequest('SUMMON', [ $user, $server ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircUsers().
*
* @param string $server
*/
public function ircUsers($server = null)
{
$this->queueIrcRequest('USERS', [ $server ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircWallops().
*
* @param string $text
*/
public function ircWallops($text)
{
$this->queueIrcRequest('WALLOPS', [ $text ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircUserhost().
*
* @param string $nickname1
* @param string $nickname2
* @param string $nickname3
* @param string $nickname4
* @param string $nickname5
*/
public function ircUserhost($nickname1, $nickname2 = null, $nickname3 = null, $nickname4 = null, $nickname5 = null)
{
$this->queueIrcRequest('USERHOST', [ $nickname1, $nickname2, $nickname3, $nickname4, $nickname5 ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircIson().
*
* @param string $nicknames
*/
public function ircIson($nicknames)
{
$this->queueIrcRequest('ISON', [ $nicknames ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ircProtoctl().
*
* @param string $proto
*/
public function ircProtoctl($proto)
{
$this->queueIrcRequest('PROTOCTL', [ $proto ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpFinger().
*
* @param string $receivers
*/
public function ctcpFinger($receivers)
{
$this->queueCtcpRequest('FINGER', [ $receivers ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpFingerResponse().
*
* @param string $nickname
* @param string $text
*/
public function ctcpFingerResponse($nickname, $text)
{
$this->queueCtcpResponse('FINGER', [ $nickname, $text ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpVersion().
*
* @param string $receivers
*/
public function ctcpVersion($receivers)
{
$this->queueCtcpRequest('VERSION', [ $receivers ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpVersionResponse().
*
* @param string $nickname
* @param string $name
* @param string $version
* @param string $environment
*/
public function ctcpVersionResponse($nickname, $name, $version, $environment)
{
$this->queueCtcpResponse('VERSION', [ $nickname, $name, $version, $environment ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpSource().
*
* @param string $receivers
*/
public function ctcpSource($receivers)
{
$this->queueCtcpRequest('SOURCE', [ $receivers ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpSourceResponse().
*
* @param string $nickname
* @param string $host
* @param string $directories
* @param string $files
*/
public function ctcpSourceResponse($nickname, $host, $directories, $files)
{
$this->queueCtcpResponse('SOURCE', [ $nickname, $host, $directories, $files ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpUserinfo().
*
* @param string $receivers
*/
public function ctcpUserinfo($receivers)
{
$this->queueCtcpRequest('USERINFO', [ $receivers ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpUserinfoResponse().
*
* @param string $nickname
* @param string $text
*/
public function ctcpUserinfoResponse($nickname, $text)
{
$this->queueCtcpResponse('USERINFO', [ $nickname, $text ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpClientinfo().
*
* @param string $receivers
*/
public function ctcpClientinfo($receivers)
{
$this->queueCtcpRequest('CLIENTINFO', [ $receivers ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpClientinfoResponse().
*
* @param string $nickname
* @param string $client
*/
public function ctcpClientinfoResponse($nickname, $client)
{
$this->queueCtcpResponse('CLIENTINFO', [ $nickname, $client ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpErrmsg().
*
* @param string $receivers
* @param string $query
*/
public function ctcpErrmsg($receivers, $query)
{
$this->queueCtcpRequest('ERRMSG', [ $receivers, $query ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpErrmsgResponse().
*
* @param string $nickname
* @param string $query
* @param string $message
*/
public function ctcpErrmsgResponse($nickname, $query, $message)
{
$this->queueCtcpResponse('ERRMSG', [ $nickname, $query, $message ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpPing().
*
* @param string $receivers
* @param int $timestamp
*/
public function ctcpPing($receivers, $timestamp)
{
$this->queueCtcpRequest('PING', [ $receivers, $timestamp ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpPingResponse().
*
* @param string $nickname
* @param int $timestamp
*/
public function ctcpPingResponse($nickname, $timestamp)
{
$this->queueCtcpResponse('PING', [ $nickname, $timestamp ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpTime().
*
* @param string $receivers
*/
public function ctcpTime($receivers)
{
$this->queueCtcpRequest('TIME', [ $receivers ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpTimeResponse().
*
* @param string $nickname
* @param string $time
*/
public function ctcpTimeResponse($nickname, $time)
{
$this->queueCtcpResponse('TIME', [ $nickname, $time ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpAction().
*
* @param string $receivers
* @param string $action
*/
public function ctcpAction($receivers, $action)
{
$this->queueCtcpRequest('ACTION', [ $receivers, $action ]);
}
/**
* Implements \Phergie\Irc\GeneratorInterface->ctcpActionResponse().
*
* @param string $nickname
* @param string $action
*/
public function ctcpActionResponse($nickname, $action)
{
$this->queueCtcpResponse('ACTION', [ $nickname, $action ]);
}
/**
* Returns a list of IRC events in order from most to least destructive.
*
* @return array Associative array keyed by event name
*/
protected function getPriorities()
{
return array_flip([
'RESTART',
'SQUIT',
'QUIT',
'ERROR',
'KICK',
'PART',
'KILL',
'INVITE',
'TOPIC',
'ACTION',
'PRIVMSG',
'NICK',
'MODE',
'WHOWAS',
'WHOIS',
'WHO',
'INFO',
'ADMIN',
'TRACE',
'TIME',
'LINKS',
'STATS',
'VERSION',
'NAMES',
'LIST',
'JOIN',
'NOTICE',
'PONG',
'PING',
'USER',
'PASS',
'ISON',
'USERHOST',
'WALLOPS',
'PROTOCTL',
'USERS',
'SUMMON',
'REHASH',
'AWAY',
'CONNECT',
'OPER',
'SERVER',
]);
}
}