initial commit; version 22.5.12042

This commit is contained in:
2022-12-12 23:28:25 -05:00
commit af1b03d79f
17653 changed files with 22692970 additions and 0 deletions

View File

@ -0,0 +1,34 @@
# CHANGELOG
## 0.6.1 (2014-11-20)
- [PATCH] [Issue #4](https://github.com/fabiang/xmpp/issues/4): Incomplete buffer response
## 0.6.0 (2014-11-13)
- [MINOR] [Issue #3](https://github.com/fabiang/xmpp/issues/3): Library now tries to reconnect via TLS if connection with TCP failed
- [PATCH]: Reducing output for blocking listeners.
## 0.5.0 (2014-10-29)
- [MINOR]: Messages get now quoted
- [MINOR]: Classes are now autoloaded with PSR-4
- [PATCH]: Cleanups
## 0.4.0 (2014-02-28)
- [MINOR]: Added a timeout to connection
## 0.3.0 (2014-02-05)
- [MINOR]: Digest-MD5 authentication wasn't working
- [PATCH]: various code optimizations
## 0.2.0 (2014-01-27)
- [MINOR]: Added support for DIGEST-MD5 authentication
- [PATCH]: Fixed a bug in xml parser, which triggered wrong events
## 0.1.0 (2014-01-23)
- [MINOR]: First release

View File

@ -0,0 +1,185 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp;
use Fabiang\Xmpp\Options;
use Fabiang\Xmpp\Connection\ConnectionInterface;
use Fabiang\Xmpp\Connection\Socket;
use Fabiang\Xmpp\Protocol\ProtocolImplementationInterface;
use Fabiang\Xmpp\Event\EventManagerAwareInterface;
use Fabiang\Xmpp\Event\EventManagerInterface;
use Fabiang\Xmpp\Event\EventManager;
use Fabiang\Xmpp\EventListener\Logger;
/**
* Xmpp connection client.
*
* @package Xmpp
*/
class Client implements EventManagerAwareInterface
{
/**
* Eventmanager.
*
* @var EventManagerInterface
*/
protected $eventManager;
/**
* Options.
*
* @var Options
*/
protected $options;
/**
* @var ConnectionInterface
*/
protected $connection;
/**
* Constructor.
*
* @param Options $options Client options
* @param EventManagerInterface $eventManager Event manager
*/
public function __construct(Options $options, EventManagerInterface $eventManager = null)
{
// create default connection
if (null !== $options->getConnection()) {
$connection = $options->getConnection();
} else {
$connection = Socket::factory($options);
$options->setConnection($connection);
}
$this->options = $options;
$this->connection = $connection;
if (null === $eventManager) {
$eventManager = new EventManager();
}
$this->eventManager = $eventManager;
$this->setupImplementation();
}
/**
* Setup implementation.
*
* @return void
*/
protected function setupImplementation()
{
$this->connection->setEventManager($this->eventManager);
$this->connection->setOptions($this->options);
$implementation = $this->options->getImplementation();
$implementation->setEventManager($this->eventManager);
$implementation->setOptions($this->options);
$implementation->register();
$implementation->registerListener(new Logger());
}
/**
* Connect to server.
*
* @return void
*/
public function connect()
{
$this->connection->connect();
}
/**
* Disconnect from server.
*
* @return void
*/
public function disconnect()
{
$this->connection->disconnect();
}
/**
* Send data to server.
*
* @param ProtocolImplementationInterface $interface Interface
* @return void
*/
public function send(ProtocolImplementationInterface $interface)
{
$data = $interface->toString();
$this->connection->send($data);
}
/**
* {@inheritDoc}
*/
public function getEventManager()
{
return $this->eventManager;
}
/**
* {@inheritDoc}
*/
public function setEventManager(EventManagerInterface $eventManager)
{
$this->eventManager = $eventManager;
return $this;
}
/**
* Get options.
*
* @return Options
*/
public function getOptions()
{
return $this->options;
}
/**
* @return ConnectionInterface
*/
public function getConnection()
{
return $this->connection;
}
}

View File

@ -0,0 +1,311 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Connection;
use Fabiang\Xmpp\Stream\XMLStream;
use Fabiang\Xmpp\EventListener\EventListenerInterface;
use Fabiang\Xmpp\Event\EventManager;
use Fabiang\Xmpp\Event\EventManagerInterface;
use Fabiang\Xmpp\EventListener\BlockingEventListenerInterface;
use Fabiang\Xmpp\Options;
use Fabiang\Xmpp\Exception\TimeoutException;
use Psr\Log\LogLevel;
/**
* Connection test double.
*
* @package Xmpp\Connection
*/
abstract class AbstractConnection implements ConnectionInterface
{
/**
*
* @var XMLStream
*/
protected $outputStream;
/**
*
* @var XMLStream
*/
protected $inputStream;
/**
* Options.
*
* @var Options
*/
protected $options;
/**
* Eventmanager.
*
* @var EventManagerInterface
*/
protected $events;
/**
* Event listeners.
*
* @var EventListenerInterface[]
*/
protected $listeners = array();
/**
* Connected.
*
* @var boolean
*/
protected $connected = false;
/**
*
* @var boolean
*/
protected $ready = false;
/**
* Timestamp of last response data received.
*
* @var integer
*/
private $lastResponse;
/**
* Last blocking event listener.
*
* Cached to reduce debug output a bit.
*
* @var BlockingEventListenerInterface
*/
private $lastBlockingListener;
/**
* {@inheritDoc}
*/
public function getOutputStream()
{
if (null === $this->outputStream) {
$this->outputStream = new XMLStream();
}
return $this->outputStream;
}
/**
* {@inheritDoc}
*/
public function getInputStream()
{
if (null === $this->inputStream) {
$this->inputStream = new XMLStream();
}
return $this->inputStream;
}
/**
* {@inheritDoc}
*/
public function setOutputStream(XMLStream $outputStream)
{
$this->outputStream = $outputStream;
return $this;
}
/**
* {@inheritDoc}
*/
public function setInputStream(XMLStream $inputStream)
{
$this->inputStream = $inputStream;
return $this;
}
/**
* {@inheritDoc}
*/
public function addListener(EventListenerInterface $eventListener)
{
$this->listeners[] = $eventListener;
return $this;
}
/**
* {@inheritDoc}
*/
public function isConnected()
{
return $this->connected;
}
/**
* {@inheritDoc}
*/
public function isReady()
{
return $this->ready;
}
/**
* {@inheritDoc}
*/
public function setReady($flag)
{
$this->ready = (bool) $flag;
return $this;
}
/**
* Reset streams.
*
* @return void
*/
public function resetStreams()
{
$this->getInputStream()->reset();
$this->getOutputStream()->reset();
}
/**
* {@inheritDoc}
*/
public function getEventManager()
{
if (null === $this->events) {
$this->setEventManager(new EventManager());
}
return $this->events;
}
/**
* {@inheritDoc}
*/
public function setEventManager(EventManagerInterface $events)
{
$this->events = $events;
return $this;
}
/**
* Get listeners.
*
* @return EventListenerInterface
*/
public function getListeners()
{
return $this->listeners;
}
/**
* {@inheritDoc}
*/
public function getOptions()
{
return $this->options;
}
/**
* {@inheritDoc}
*/
public function setOptions(Options $options)
{
$this->options = $options;
return $this;
}
/**
* Call logging event.
*
* @param string $message Log message
* @param integer $level Log level
* @return void
*/
protected function log($message, $level = LogLevel::DEBUG)
{
$this->getEventManager()->trigger('logger', $this, array($message, $level));
}
/**
* Check blocking event listeners.
*
* @return boolean
*/
protected function checkBlockingListeners()
{
$blocking = false;
foreach ($this->listeners as $listener) {
$instanceof = $listener instanceof BlockingEventListenerInterface;
if ($instanceof && true === $listener->isBlocking()) {
// cache the last blocking listener. Reducing output.
if ($this->lastBlockingListener !== $listener) {
$this->log('Listener "' . get_class($listener) . '" is currently blocking', LogLevel::DEBUG);
$this->lastBlockingListener = $listener;
}
$blocking = true;
}
}
return $blocking;
}
/**
* Check for timeout.
*
* @param string $buffer Function required current received buffer
* @throws TimeoutException
*/
protected function checkTimeout($buffer)
{
if (!empty($buffer)) {
$this->lastResponse = time();
return;
}
if (null === $this->lastResponse) {
$this->lastResponse = time();
}
$timeout = $this->getOptions()->getTimeout();
if (time() >= $this->lastResponse + $timeout) {
throw new TimeoutException('Connection lost after ' . $timeout . ' seconds');
}
}
}

View File

@ -0,0 +1,146 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Connection;
use Fabiang\Xmpp\Stream\XMLStream;
use Fabiang\Xmpp\Event\EventManagerAwareInterface;
use Fabiang\Xmpp\EventListener\EventListenerInterface;
use Fabiang\Xmpp\OptionsAwareInterface;
/**
* Connections must implement this interface.
*
* @package Xmpp\Connection
*/
interface ConnectionInterface extends EventManagerAwareInterface, OptionsAwareInterface
{
/**
* Connect.
*
* @return void
*/
public function connect();
/**
* Disconnect.
*
* @return void
*/
public function disconnect();
/**
* Set stream is ready.
*
* @param boolean $flag Flag
* @return $this
*/
public function setReady($flag);
/**
* Is stream ready.
*
* @return boolean
*/
public function isReady();
/**
* Is connection established.
*
* @return boolean
*/
public function isConnected();
/**
* Receive data.
*
* @return string
*/
public function receive();
/**
* Send data.
*
* @param string $buffer Data to send.
* @return void
*/
public function send($buffer);
/**
* Get output stream.
*
* @return XMLStream
*/
public function getOutputStream();
/**
* Get input stream.
*
* @return XMLStream
*/
public function getInputStream();
/**
* Set output stream.
*
* @param XMLStream $outputStream Output stream
* @return $this
*/
public function setOutputStream(XMLStream $outputStream);
/**
* Set input stream.
*
* @param XMLStream $inputStream Input stream
* @return $this
*/
public function setInputStream(XMLStream $inputStream);
/**
* Reset streams.
*
* @return void
*/
public function resetStreams();
/**
* Add listener.
*
* @param EventListenerInterface $eventListener
* @return $this
*/
public function addListener(EventListenerInterface $eventListener);
}

View File

@ -0,0 +1,228 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Connection;
use Psr\Log\LogLevel;
use Fabiang\Xmpp\Stream\SocketClient;
use Fabiang\Xmpp\Util\XML;
use Fabiang\Xmpp\Options;
use Fabiang\Xmpp\Exception\TimeoutException;
/**
* Connection to a socket stream.
*
* @package Xmpp\Connection
*/
class Socket extends AbstractConnection implements SocketConnectionInterface
{
const DEFAULT_LENGTH = 4096;
const STREAM_START = <<<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<stream:stream to="%s" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" version="1.0">
XML;
const STREAM_END = '</stream:stream>';
/**
* Socket.
*
* @var SocketClient
*/
protected $socket;
/**
* Did we received any data yet?
*
* @var bool
*/
private $receivedAnyData = false;
/**
* Constructor set default socket instance if no socket was given.
*
* @param StreamSocket $socket Socket instance
*/
public function __construct(SocketClient $socket)
{
$this->setSocket($socket);
}
/**
* Factory for connection class.
*
* @param Options $options Options object
* @return static
*/
public static function factory(Options $options)
{
$socket = new SocketClient($options->getAddress());
$object = new static($socket);
$object->setOptions($options);
return $object;
}
/**
* {@inheritDoc}
*/
public function receive()
{
$buffer = $this->getSocket()->read(static::DEFAULT_LENGTH);
if ($buffer) {
$this->receivedAnyData = true;
$address = $this->getAddress();
$this->log("Received buffer '$buffer' from '{$address}'", LogLevel::DEBUG);
$this->getInputStream()->parse($buffer);
return $buffer;
}
try {
$this->checkTimeout($buffer);
} catch (TimeoutException $exception) {
$this->reconnectTls($exception);
}
}
/**
* Try to reconnect via TLS.
*
* @param TimeoutException $exception
* @return null
* @throws TimeoutException
*/
private function reconnectTls(TimeoutException $exception)
{
// check if we didn't receive any data
// if not we re-try to connect via TLS
if (false === $this->receivedAnyData) {
$matches = array();
$previousAddress = $this->getOptions()->getAddress();
// only reconnect via tls if we've used tcp before.
if (preg_match('#tcp://(?<address>.+)#', $previousAddress, $matches)) {
$this->log('Connecting via TCP failed, now trying to connect via TLS');
$address = 'tls://' . $matches['address'];
$this->connected = false;
$this->getOptions()->setAddress($address);
$this->getSocket()->reconnect($address);
$this->connect();
return;
}
}
throw $exception;
}
/**
* {@inheritDoc}
*/
public function send($buffer)
{
if (false === $this->isConnected()) {
$this->connect();
}
$address = $this->getAddress();
$this->log("Sending data '$buffer' to '{$address}'", LogLevel::DEBUG);
$this->getSocket()->write($buffer);
$this->getOutputStream()->parse($buffer);
while ($this->checkBlockingListeners()) {
$this->receive();
}
}
/**
* {@inheritDoc}
*/
public function connect()
{
if (false === $this->connected) {
$address = $this->getAddress();
$this->getSocket()->connect($this->getOptions()->getTimeout());
$this->getSocket()->setBlocking(true);
$this->connected = true;
$this->log("Connected to '{$address}'", LogLevel::DEBUG);
}
$this->send(sprintf(static::STREAM_START, XML::quote($this->getOptions()->getTo())));
}
/**
* {@inheritDoc}
*/
public function disconnect()
{
if (true === $this->connected) {
$address = $this->getAddress();
$this->send(static::STREAM_END);
$this->getSocket()->close();
$this->connected = false;
$this->log("Disconnected from '{$address}'", LogLevel::DEBUG);
}
}
/**
* Get address from options object.
*
* @return string
*/
protected function getAddress()
{
return $this->getOptions()->getAddress();
}
/**
* Return socket instance.
*
* @return SocketClient
*/
public function getSocket()
{
return $this->socket;
}
/**
* {@inheritDoc}
*/
public function setSocket(SocketClient $socket)
{
$this->socket = $socket;
return $this;
}
}

View File

@ -0,0 +1,56 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Connection;
use Fabiang\Xmpp\Stream\SocketClient;
/**
* Interface for connection that connect to a socket.
*
* @package Xmpp\Connection
*/
interface SocketConnectionInterface
{
/**
* Set socket instance.
*
* @param SocketClient $socket
* @return $this
*/
public function setSocket(SocketClient $socket);
}

View File

@ -0,0 +1,165 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Event;
use Fabiang\Xmpp\Exception\OutOfRangeException;
use Fabiang\Xmpp\Exception\InvalidArgumentException;
/**
* Generic event.
*
* @package Xmpp\Event
*/
class Event implements EventInterface
{
/**
* Event name.
*
* @var string
*/
protected $name;
/**
* Target object.
*
* @var object
*/
protected $target;
/**
* Event parameters.
*
* @var array
*/
protected $parameters = array();
/**
* Event stack.
*
* @var array
*/
protected $eventStack = array();
/**
* {@inheritDoc}
*/
public function getName()
{
return $this->name;
}
/**
* {@inheritDoc}
*/
public function getTarget()
{
return $this->target;
}
/**
* {@inheritDoc}
*/
public function getParameters()
{
return $this->parameters;
}
/**
* {@inheritDoc}
*/
public function setName($name)
{
$this->name = (string) $name;
return $this;
}
/**
* {@inheritDoc}
*/
public function setTarget($target)
{
$this->target = $target;
return $this;
}
/**
* {@inheritDoc}
*/
public function setParameters(array $parameters)
{
$this->parameters = array_values($parameters);
return $this;
}
/**
* {@inheritDoc}
*/
public function getEventStack()
{
return $this->eventStack;
}
/**
* {@inheritDoc}
*/
public function setEventStack(array $eventStack)
{
$this->eventStack = $eventStack;
return $this;
}
/**
* {@inheritDoc}
*/
public function getParameter($index)
{
$parameters = $this->getParameters();
if (!is_int($index)) {
throw new InvalidArgumentException(
'Argument #1 of "' . __CLASS__ . '::' . __METHOD__ . '" must be an integer'
);
}
if (!array_key_exists($index, $parameters)) {
throw new OutOfRangeException("The offset $index is out of range.");
}
return $parameters[$index];
}
}

View File

@ -0,0 +1,114 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Event;
/**
* Interface for events.
*
* @package Xmpp\Event
*/
interface EventInterface
{
/**
* Get event name.
*
* @return string
*/
public function getName();
/**
* Set event name.
*
* @param string $name Event name
* @return $this
*/
public function setName($name);
/**
* Return calling object.
*
* @return object
*/
public function getTarget();
/**
* Set calling object.
*
* @param object $target Calling object
* @return $this
*/
public function setTarget($target);
/**
* Return parameters.
*
* @return array
*/
public function getParameters();
/**
* Set parameters.
*
* @param array $parameters Parameters
* @return $this
*/
public function setParameters(array $parameters);
/**
* Get a parameter by index.
*
* @param integer $index
* @retrun mixed
*/
public function getParameter($index);
/**
* Get list of previous called callbacks.
*
* @return array
*/
public function getEventStack();
/**
* Set event stack.
*
* @param array $stack Event stack
* @return $this
*/
public function setEventStack(array $stack);
}

View File

@ -0,0 +1,160 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Event;
use Fabiang\Xmpp\Exception\InvalidArgumentException;
/**
* Event manager.
*
* The EventManager holds and triggers events.
*
* @package Xmpp\Event
*/
class EventManager implements EventManagerInterface
{
const WILDCARD = '*';
/**
* Attached events.
*
* @var array
*/
protected $events = array(self::WILDCARD => array());
/**
* Event object.
*
* @var EventInterface
*/
protected $eventObject;
/**
* Constructor sets default event object.
*
* @param EventInterface $eventObject Event object
*/
public function __construct(EventInterface $eventObject = null)
{
if (null === $eventObject) {
$eventObject = new Event;
}
$this->eventObject = $eventObject;
}
/**
* {@inheritDoc}
*/
public function attach($event, $callback)
{
if (!is_callable($callback, true)) {
throw new InvalidArgumentException(
'Second argument of "' . __CLASS__ . '"::attach must be a valid callback'
);
}
if (!isset($this->events[$event])) {
$this->events[$event] = array();
}
if (!in_array($callback, $this->events[$event], true)) {
$this->events[$event][] = $callback;
}
}
/**
* {@inheritDoc}
*/
public function trigger($event, $caller, array $parameters)
{
if (empty($this->events[$event]) && empty($this->events[self::WILDCARD])) {
return;
}
$events = array();
if (!empty($this->events[$event])) {
$events = $this->events[$event];
}
$callbacks = array_merge($events, $this->events[self::WILDCARD]);
$previous = array();
$eventObject = clone $this->getEventObject();
$eventObject->setName($event);
$eventObject->setTarget($caller);
$eventObject->setParameters($parameters);
do {
$current = array_shift($callbacks);
call_user_func($current, $eventObject);
$previous[] = $current;
$eventObject = clone $eventObject;
$eventObject->setEventStack($previous);
} while (count($callbacks) > 0);
}
/**
* {@inheritDoc}
*/
public function getEventObject()
{
return $this->eventObject;
}
/**
* {@inheritDoc}
*/
public function setEventObject(EventInterface $eventObject)
{
$this->eventObject = $eventObject;
return $this;
}
/**
* Return list of events.
*
* @return array
*/
public function getEventList()
{
return $this->events;
}
}

View File

@ -0,0 +1,61 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Event;
/**
* Objects that use an event manager must implement this interface.
*
* @package Xmpp\Event
*/
interface EventManagerAwareInterface
{
/**
* Set event manager.
*
* @param EventManagerInterface $events Instance of event manager
* @return $this
*/
public function setEventManager(EventManagerInterface $events);
/**
* Get event manager instance.
*
* @return EventManagerInterface
*/
public function getEventManager();
}

View File

@ -0,0 +1,81 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Event;
use Fabiang\Xmpp\Event\EventInterface;
/**
* Event manager interface.
*
* @package Xmpp\Event
*/
interface EventManagerInterface
{
/**
* Trigger an event.
*
* @param string $event Name of the event
* @param object $caller Triggering object (caller)
* @param array $parameters Event parameters
* @return void
*/
public function trigger($event, $caller, array $parameters);
/**
* Attach event.
*
* @param string $event Name of the event
* @param callback $callback Callback that handles the event
* @return void
*/
public function attach($event, /*callback*/ $callback);
/**
* Return event object.
*
* @return EventInterface
*/
public function getEventObject();
/**
* Set event object.
*
* @param EventInterface $eventObject
* @return $this
*/
public function setEventObject(EventInterface $eventObject);
}

View File

@ -0,0 +1,78 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Event;
/**
* XML parsing events.
*
* @package Xmpp\Event
*/
class XMLEvent extends Event implements XMLEventInterface
{
/**
* Is start tag event.
*
* @var boolean
*/
protected $startTag = false;
/**
* {@inheritDoc}
*/
public function isStartTag()
{
return $this->startTag;
}
/**
* {@inheritDoc}
*/
public function setStartTag($startTag)
{
$this->startTag = (bool) $startTag;
return $this;
}
/**
* {@inheritDoc}
*/
public function isEndTag()
{
return !$this->isStartTag();
}
}

View File

@ -0,0 +1,68 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Event;
/**
* INterface for xml events.
*
* @package Xmpp\Event
*/
interface XMLEventInterface extends EventInterface
{
/**
* Is event triggered by a start tag.
*
* @return boolean
*/
public function isStartTag();
/**
* Set if event triggered by a start tag.
*
* @param boolean $startTag Flag
* @return $this
*/
public function setStartTag($startTag);
/**
* Was event triggered by end tag of an element?
*
* @return boolean
*/
public function isEndTag();
}

View File

@ -0,0 +1,132 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener;
use Fabiang\Xmpp\Connection\ConnectionInterface;
use Fabiang\Xmpp\Event\EventManagerInterface;
use Fabiang\Xmpp\Event\EventManager;
use Fabiang\Xmpp\Options;
/**
* Abstract implementaion of event listener
*
* @package Xmpp\EventListener
*/
abstract class AbstractEventListener implements EventListenerInterface
{
/**
* Options.
*
* @var Options
*/
protected $options;
/**
* Eventmanager.
*
* @var EventManagerInterface
*/
protected $eventManager;
/**
* Get connection.
*
* @return ConnectionInterface
*/
protected function getConnection()
{
return $this->getOptions()->getConnection();
}
/**
* Get event manager for XML input.
*
* @return EventManager
*/
protected function getInputEventManager()
{
return $this->getConnection()->getInputStream()->getEventManager();
}
/**
* Get event manager for XML output.
*
* @return EventManager
*/
protected function getOutputEventManager()
{
return $this->getConnection()->getOutputStream()->getEventManager();
}
/**
* {@inheritDoc}
*/
public function getEventManager()
{
if (null === $this->eventManager) {
$this->setEventManager(new EventManager());
}
return $this->eventManager;
}
/**
* {@inheritDoc}
*/
public function setEventManager(EventManagerInterface $eventManager)
{
$this->eventManager = $eventManager;
return $this;
}
/**
* {@inheritDoc}
*/
public function getOptions()
{
return $this->options;
}
/**
* {@inheritDoc}
*/
public function setOptions(Options $options)
{
$this->options = $options;
return $this;
}
}

View File

@ -0,0 +1,53 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener;
/**
* Interface for event listeners.
*
* @package Xmpp\EventListener
*/
interface BlockingEventListenerInterface
{
/**
* Event listener should return false as long he waits for events to finish.
*
* @return boolean
*/
public function isBlocking();
}

View File

@ -0,0 +1,56 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener;
use Fabiang\Xmpp\Event\EventManagerAwareInterface;
use Fabiang\Xmpp\OptionsAwareInterface;
/**
* Interface for event listeners.
*
* @package Xmpp\EventListener
*/
interface EventListenerInterface extends EventManagerAwareInterface, OptionsAwareInterface
{
/**
* Register events.
*
* @return void
*/
public function attachEvents();
}

View File

@ -0,0 +1,74 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener;
use Fabiang\Xmpp\Event\EventInterface;
/**
* Event listener for logging events.
*
* @package Xmpp\EventListener
*/
class Logger extends AbstractEventListener
{
/**
* Log event.
*
* @param \Fabiang\Xmpp\Event\EventInterface $event
* @return $this
*/
public function event(EventInterface $event)
{
$logger = $this->getOptions()->getLogger();
if (null !== $logger) {
list($message, $level) = $event->getParameters();
$logger->log($level, $message);
}
}
/**
* Attach events.
*
* @return void
*/
public function attachEvents()
{
$this->getEventManager()->attach('logger', array($this, 'event'));
}
}

View File

@ -0,0 +1,121 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener\Stream;
use Fabiang\Xmpp\EventListener\AbstractEventListener;
use Fabiang\Xmpp\Event\XMLEvent;
use Fabiang\Xmpp\Util\XML;
/**
* Listener
*
* @package Xmpp\EventListener
*/
abstract class AbstractSessionEvent extends AbstractEventListener
{
/**
* Generated id.
*
* @var string
*/
protected $id;
/**
* Listener is blocking.
*
* @var boolean
*/
protected $blocking = false;
/**
* Handle session event.
*
* @param XMLEvent $event
* @return void
*/
protected function respondeToFeatures(XMLEvent $event, $data)
{
if ($event->isEndTag()) {
/* @var $element \DOMElement */
$element = $event->getParameter(0);
// bind element occured in <features>
if ('features' === $element->parentNode->localName) {
$this->blocking = true;
$this->getConnection()->send(sprintf(
$data,
$this->getId()
));
}
}
}
/**
* {@inheritDoc}
*/
public function isBlocking()
{
return $this->blocking;
}
/**
* Get generated id.
*
* @return string
*/
public function getId()
{
if (null === $this->id) {
$this->id = XML::generateId();
}
return $this->id;
}
/**
* Set generated id.
*
* @param string $id
* @return $this
*/
public function setId($id)
{
$this->id = (string) $id;
return $this;
}
}

View File

@ -0,0 +1,211 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener\Stream;
use Fabiang\Xmpp\Event\XMLEvent;
use Fabiang\Xmpp\Exception\RuntimeException;
use Fabiang\Xmpp\EventListener\Stream\Authentication\AuthenticationInterface;
use Fabiang\Xmpp\Exception\Stream\AuthenticationErrorException;
use Fabiang\Xmpp\EventListener\AbstractEventListener;
use Fabiang\Xmpp\EventListener\BlockingEventListenerInterface;
/**
* Listener
*
* @package Xmpp\EventListener
*/
class Authentication extends AbstractEventListener implements BlockingEventListenerInterface
{
/**
* Listener is blocking.
*
* @var boolean
*/
protected $blocking = false;
/**
* Collected mechanisms.
*
* @var array
*/
protected $mechanisms = array();
/**
* {@inheritDoc}
*/
public function attachEvents()
{
$input = $this->getConnection()->getInputStream()->getEventManager();
$input->attach('{urn:ietf:params:xml:ns:xmpp-sasl}mechanisms', array($this, 'authenticate'));
$input->attach('{urn:ietf:params:xml:ns:xmpp-sasl}mechanism', array($this, 'collectMechanisms'));
$input->attach('{urn:ietf:params:xml:ns:xmpp-sasl}failure', array($this, 'failure'));
$input->attach('{urn:ietf:params:xml:ns:xmpp-sasl}success', array($this, 'success'));
}
/**
* Collect authentication machanisms.
*
* @param XMLEvent $event
* @return void
*/
public function collectMechanisms(XMLEvent $event)
{
if ($this->getConnection()->isReady() && false === $this->isAuthenticated()) {
/* @var $element \DOMElement */
list($element) = $event->getParameters();
$this->blocking = true;
if (false === $event->isStartTag()) {
$this->mechanisms[] = strtolower($element->nodeValue);
}
}
}
/**
* Authenticate after collecting machanisms.
*
* @param XMLEvent $event
* @return void
*/
public function authenticate(XMLEvent $event)
{
if ($this->getConnection()->isReady() && false === $this->isAuthenticated() && false === $event->isStartTag()) {
$this->blocking = true;
$authentication = $this->determineMechanismClass();
$authentication->setEventManager($this->getEventManager())
->setOptions($this->getOptions())
->attachEvents();
$this->getConnection()->addListener($authentication);
$authentication->authenticate($this->getOptions()->getUsername(), $this->getOptions()->getPassword());
}
}
/**
* Determine mechanismclass from collected mechanisms.
*
* @return AuthenticationInterface
* @throws RuntimeException
*/
protected function determineMechanismClass()
{
$authenticationClass = null;
$authenticationClasses = $this->getOptions()->getAuthenticationClasses();
foreach ($this->mechanisms as $mechanism) {
if (array_key_exists($mechanism, $authenticationClasses)) {
$authenticationClass = $authenticationClasses[$mechanism];
break;
}
}
if (null === $authenticationClass) {
throw new RuntimeException('No supportet authentication machanism found.');
}
$authentication = new $authenticationClass;
if (!($authentication instanceof AuthenticationInterface)) {
$message = 'Authentication class "' . get_class($authentication)
. '" is no instanceof AuthenticationInterface';
throw new RuntimeException($message);
}
return $authentication;
}
/**
* Authentication failed.
*
* @param XMLEvent $event
* @throws StreamErrorException
*/
public function failure(XMLEvent $event)
{
if (false === $event->isStartTag()) {
$this->blocking = false;
throw AuthenticationErrorException::createFromEvent($event);
}
}
/**
* Authentication successful.
*
* @param XMLEvent $event
*/
public function success(XMLEvent $event)
{
if (false === $event->isStartTag()) {
$this->blocking = false;
$connection = $this->getConnection();
$connection->resetStreams();
$connection->connect();
$this->getOptions()->setAuthenticated(true);
}
}
/**
* {@inheritDoc}
*/
public function isBlocking()
{
return $this->blocking;
}
/**
* Get collected mechanisms.
*
* @return array
*/
public function getMechanisms()
{
return $this->mechanisms;
}
/**
*
* @return boolean
*/
protected function isAuthenticated()
{
return $this->getOptions()->isAuthenticated();
}
}

View File

@ -0,0 +1,57 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener\Stream\Authentication;
use Fabiang\Xmpp\EventListener\EventListenerInterface;
/**
* Interface for classes that handle authentication.
*
* @package Xmpp\EventListener\Authentication
*/
interface AuthenticationInterface extends EventListenerInterface
{
/**
* Authenticate.
*
* @param string $username Username
* @param string $password Password
* @return void
*/
public function authenticate($username, $password);
}

View File

@ -0,0 +1,238 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener\Stream\Authentication;
use Fabiang\Xmpp\EventListener\AbstractEventListener;
use Fabiang\Xmpp\Event\XMLEvent;
use Fabiang\Xmpp\Util\XML;
use Fabiang\Xmpp\Exception\Stream\AuthenticationErrorException;
/**
* Handler for "digest md5" authentication mechanism.
*
* @package Xmpp\EventListener\Authentication
*/
class DigestMd5 extends AbstractEventListener implements AuthenticationInterface
{
/**
* Is event blocking stream.
*
* @var boolean
*/
protected $blocking = false;
/**
*
* @var string
*/
protected $username;
/**
*
* @var string
*/
protected $password;
/**
* {@inheritDoc}
*/
public function attachEvents()
{
$input = $this->getInputEventManager();
$input->attach('{urn:ietf:params:xml:ns:xmpp-sasl}challenge', array($this, 'challenge'));
$input->attach('{urn:ietf:params:xml:ns:xmpp-sasl}success', array($this, 'success'));
$output = $this->getOutputEventManager();
$output->attach('{urn:ietf:params:xml:ns:xmpp-sasl}auth', array($this, 'auth'));
}
/**
* {@inheritDoc}
*/
public function authenticate($username, $password)
{
$this->setUsername($username)->setPassword($password);
$auth = '<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="DIGEST-MD5"/>';
$this->getConnection()->send($auth);
}
/**
* Authentication starts -> blocking.
*
* @return void
*/
public function auth()
{
$this->blocking = true;
}
/**
* Challenge string received.
*
* @param XMLEvent $event XML event
* @return void
*/
public function challenge(XMLEvent $event)
{
if ($event->isEndTag()) {
list($element) = $event->getParameters();
$challenge = XML::base64Decode($element->nodeValue);
$values = $this->parseCallenge($challenge);
if (isset($values['nonce'])) {
$send = '<response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">'
. $this->response($values) . '</response>';
} elseif (isset($values['rspauth'])) {
$send = '<response xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>';
} else {
throw new AuthenticationErrorException("Error when receiving challenge: \"$challenge\"");
}
$this->getConnection()->send($send);
}
}
/**
* Generate response data.
*
* @param array $values
*/
protected function response($values)
{
$values['cnonce'] = uniqid(mt_rand(), false);
$values['nc'] = '00000001';
$values['qop'] = 'auth';
if (!isset($values['realm'])) {
$values['realm'] = $this->getOptions()->getTo();
}
if (!isset($values['digest-uri'])) {
$values['digest-uri'] = 'xmpp/' . $this->getOptions()->getTo();
}
$a1 = sprintf('%s:%s:%s', $this->getUsername(), $values['realm'], $this->getPassword());
if ('md5-sess' === $values['algorithm']) {
$a1 = pack('H32', md5($a1)) . ':' . $values['nonce'] . ':' . $values['cnonce'];
}
$a2 = "AUTHENTICATE:" . $values['digest-uri'];
$password = md5($a1) . ':' . $values['nonce'] . ':' . $values['nc'] . ':'
. $values['cnonce'] . ':' . $values['qop'] . ':' . md5($a2);
$password = md5($password);
$response = sprintf(
'username="%s",realm="%s",nonce="%s",cnonce="%s",nc=%s,qop=%s,digest-uri="%s",response=%s,charset=utf-8',
$this->getUsername(),
$values['realm'],
$values['nonce'],
$values['cnonce'],
$values['nc'],
$values['qop'],
$values['digest-uri'],
$password
);
return XML::base64Encode($response);
}
/**
* Parse challenge string and return its values as array.
*
* @param string $challenge
* @return array
*/
protected function parseCallenge($challenge)
{
if (!$challenge) {
return array();
}
$matches = array();
preg_match_all('#(\w+)\=(?:"([^"]+)"|([^,]+))#', $challenge, $matches);
list(, $variables, $quoted, $unquoted) = $matches;
// filter empty strings; preserve keys
$quoted = array_filter($quoted);
$unquoted = array_filter($unquoted);
// replace "unquoted" values into "quoted" array and combine variables array with it
return array_combine($variables, array_replace($quoted, $unquoted));
}
/**
* Handle success event.
*
* @return void
*/
public function success()
{
$this->blocking = false;
}
/**
* {@inheritDoc}
*/
public function isBlocking()
{
return $this->blocking;
}
public function getUsername()
{
return $this->username;
}
public function setUsername($username)
{
$this->username = $username;
return $this;
}
public function getPassword()
{
return $this->password;
}
public function setPassword($password)
{
$this->password = $password;
return $this;
}
}

View File

@ -0,0 +1,68 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener\Stream\Authentication;
use Fabiang\Xmpp\EventListener\AbstractEventListener;
use Fabiang\Xmpp\Util\XML;
/**
* Handler for "plain" authentication mechanism.
*
* @package Xmpp\EventListener\Authentication
*/
class Plain extends AbstractEventListener implements AuthenticationInterface
{
/**
* {@inheritDoc}
*/
public function attachEvents()
{
}
/**
* {@inheritDoc}
*/
public function authenticate($username, $password)
{
$authString = XML::quote(base64_encode("\x00" . $username . "\x00" . $password));
$this->getConnection()->send(
'<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">' . $authString . '</auth>'
);
}
}

View File

@ -0,0 +1,89 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener\Stream;
use Fabiang\Xmpp\EventListener\BlockingEventListenerInterface;
use Fabiang\Xmpp\Event\XMLEvent;
/**
* Listener
*
* @package Xmpp\EventListener
*/
class Bind extends AbstractSessionEvent implements BlockingEventListenerInterface
{
/**
* {@inheritDoc}
*/
public function attachEvents()
{
$input = $this->getInputEventManager();
$input->attach('{urn:ietf:params:xml:ns:xmpp-bind}bind', array($this, 'bindFeatures'));
$input->attach('{urn:ietf:params:xml:ns:xmpp-bind}jid', array($this, 'jid'));
}
/**
* Handle XML events for "bind".
*
* @param XMLEvent $event
* @return void
*/
public function bindFeatures(XMLEvent $event)
{
$this->respondeToFeatures(
$event,
'<iq type="set" id="%s"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/></iq>'
);
}
/**
* Handle jid.
*
* @param XMLEvent $event
* @return void
*/
public function jid(XMLEvent $event)
{
/* @var $element \DOMDocument */
$element = $event->getParameter(0);
$jid = $element->nodeValue;
$this->getOptions()->setJid($jid);
$this->blocking = false;
}
}

View File

@ -0,0 +1,154 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener\Stream;
use Fabiang\Xmpp\Event\XMLEvent;
use Fabiang\Xmpp\EventListener\AbstractEventListener;
use Fabiang\Xmpp\EventListener\BlockingEventListenerInterface;
use Fabiang\Xmpp\Protocol\User\User;
/**
* Listener
*
* @package Xmpp\EventListener
*/
class Roster extends AbstractEventListener implements BlockingEventListenerInterface
{
/**
* Blocking.
*
* @var boolean
*/
protected $blocking = false;
/**
* user object.
*
* @var User
*/
protected $userObject;
/**
* {@inheritDoc}
*/
public function attachEvents()
{
$this->getOutputEventManager()
->attach('{jabber:iq:roster}query', array($this, 'query'));
$this->getInputEventManager()
->attach('{jabber:iq:roster}query', array($this, 'result'));
}
/**
* Sending a query request for roster sets listener to blocking mode.
*
* @return void
*/
public function query()
{
$this->blocking = true;
}
/**
* Result received.
*
* @param \Fabiang\Xmpp\Event\XMLEvent $event
* @return void
*/
public function result(XMLEvent $event)
{
if ($event->isEndTag()) {
$users = array();
/* @var $element \DOMElement */
$element = $event->getParameter(0);
$items = $element->getElementsByTagName('item');
/* @var $item \DOMElement */
foreach ($items as $item) {
$user = clone $this->getUserObject();
$user->setName($item->getAttribute('name'))
->setJid($item->getAttribute('jid'))
->setSubscription($item->getAttribute('subscription'));
$groups = $item->getElementsByTagName('group');
foreach ($groups as $group) {
$user->addGroup($group->nodeValue);
}
$users[] = $user;
}
$this->getOptions()->setUsers($users);
$this->blocking = false;
}
}
/**
* Get user object.
*
* @return User
*/
public function getUserObject()
{
if (null === $this->userObject) {
$this->setUserObject(new User);
}
return $this->userObject;
}
/**
* Set user object.
*
* @param User $userObject
* @return $this
*/
public function setUserObject(User $userObject)
{
$this->userObject = $userObject;
return $this;
}
/**
* {@inheritDoc}
*/
public function isBlocking()
{
return $this->blocking;
}
}

View File

@ -0,0 +1,90 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener\Stream;
use Fabiang\Xmpp\EventListener\BlockingEventListenerInterface;
use Fabiang\Xmpp\Event\XMLEvent;
/**
* Listener
*
* @package Xmpp\EventListener
*/
class Session extends AbstractSessionEvent implements BlockingEventListenerInterface
{
/**
* {@inheritDoc}
*/
public function attachEvents()
{
$input = $this->getInputEventManager();
$input->attach('{urn:ietf:params:xml:ns:xmpp-session}session', array($this, 'sessionStart'));
$input->attach('{jabber:client}iq', array($this, 'iq'));
}
/**
* Handle session event.
*
* @param XMLEvent $event
* @return void
*/
public function sessionStart(XMLEvent $event)
{
$this->respondeToFeatures(
$event,
'<iq type="set" id="%s"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>'
);
}
/**
* Handle iq event.
*
* @param XMLEvent $event
* @retrun void
*/
public function iq(XMLEvent $event)
{
if ($event->isEndTag()) {
/* @var $element \DOMElement */
$element = $event->getParameter(0);
if ($this->getId() === $element->getAttribute('id')) {
$this->blocking = false;
}
}
}
}

View File

@ -0,0 +1,112 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener\Stream;
use Fabiang\Xmpp\Event\XMLEvent;
use Fabiang\Xmpp\EventListener\AbstractEventListener;
use Fabiang\Xmpp\EventListener\BlockingEventListenerInterface;
use Fabiang\Xmpp\Connection\SocketConnectionInterface;
/**
* Listener
*
* @package Xmpp\EventListener
*/
class StartTls extends AbstractEventListener implements BlockingEventListenerInterface
{
/**
* Listener blocks stream.
*
* @var boolean
*/
protected $blocking = false;
/**
* {@inheritDoc}
*/
public function attachEvents()
{
$input = $this->getInputEventManager();
$input->attach('{urn:ietf:params:xml:ns:xmpp-tls}starttls', array($this, 'starttlsEvent'));
$input->attach('{urn:ietf:params:xml:ns:xmpp-tls}proceed', array($this, 'proceed'));
}
/**
* Send start tls command.
*
* @param XMLEvent $event XMLEvent object
*/
public function starttlsEvent(XMLEvent $event)
{
if (false === $event->isStartTag()) {
$this->blocking = true;
$connection = $this->getConnection();
$connection->setReady(false);
$connection->send('<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>');
}
}
/**
* Start TLS response.
*
* @param XMLEvent $event XMLEvent object
* @return void
*/
public function proceed(XMLEvent $event)
{
if (false === $event->isStartTag()) {
$this->blocking = false;
$connection = $this->getConnection();
if ($connection instanceof SocketConnectionInterface) {
$connection->getSocket()->crypto(true, STREAM_CRYPTO_METHOD_SSLv23_CLIENT);
}
$connection->resetStreams();
$connection->connect();
}
}
/**
* {@inheritDoc}
*/
public function isBlocking()
{
return $this->blocking;
}
}

View File

@ -0,0 +1,119 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener\Stream;
use Fabiang\Xmpp\Event\XMLEvent;
use Fabiang\Xmpp\EventListener\AbstractEventListener;
use Fabiang\Xmpp\EventListener\BlockingEventListenerInterface;
/**
* Listener
*
* @package Xmpp\EventListener
*/
class Stream extends AbstractEventListener implements BlockingEventListenerInterface
{
/**
* Listener blocks stream.
*
* @var boolean
*/
protected $blocking = false;
/**
* {@inheritDoc}
*/
public function attachEvents()
{
$this->getOutputEventManager()
->attach('{http://etherx.jabber.org/streams}stream', array($this, 'streamStart'));
$input = $this->getInputEventManager();
$input->attach('{http://etherx.jabber.org/streams}stream', array($this, 'streamServer'));
$input->attach('{http://etherx.jabber.org/streams}features', array($this, 'features'));
}
/**
* Stream starts.
*
* @param XMLEvent $event XMLEvent
* @return void
*/
public function streamStart(XMLEvent $event)
{
if (true === $event->isStartTag()) {
$this->blocking = true;
}
}
/**
* Stream server.
*
* @param XMLEvent $event XMLEvent
* @return void
*/
public function streamServer(XMLEvent $event)
{
if (false === $event->isStartTag()) {
$this->blocking = false;
if ($this->getConnection()->isConnected()) {
$this->getConnection()->disconnect();
}
}
}
/**
* Server send stream start.
*
* @return void
*/
public function features()
{
$this->blocking = false;
$this->getConnection()->setReady(true);
}
/**
* {@inheritDoc}
*/
public function isBlocking()
{
return $this->blocking;
}
}

View File

@ -0,0 +1,74 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\EventListener\Stream;
use Fabiang\Xmpp\Event\XMLEvent;
use Fabiang\Xmpp\Exception\Stream\StreamErrorException;
use Fabiang\Xmpp\EventListener\AbstractEventListener;
/**
* Listener for stream errors.
*
* @package Xmpp\EventListener
*/
class StreamError extends AbstractEventListener
{
/**
* {@inheritDoc}
*/
public function attachEvents()
{
$this->getInputEventManager()->attach(
'{http://etherx.jabber.org/streams}error',
array($this, 'error')
);
}
/**
* Throws an exception when stream error comes from input stream.
*
* @param \Fabiang\Xmpp\Event\XMLEvent $event
* @throws StreamErrorException
*/
public function error(XMLEvent $event)
{
if (false === $event->isStartTag()) {
throw StreamErrorException::createFromEvent($event);
}
}
}

View File

@ -0,0 +1,47 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Exception;
/**
* Exception interface.
*
* @package Xmpp\Exception
*/
class ErrorException extends \ErrorException implements ExceptionInterface
{
}

View File

@ -0,0 +1,47 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Exception;
/**
* Exception interface.
*
* @package Xmpp\Exception
*/
interface ExceptionInterface
{
}

View File

@ -0,0 +1,49 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Exception;
/**
* Exception for invalid arguments.
*
* "Throw an InvalidArgumentException when your functions or methods receive arguments that are invalid."
*
* @package Xmpp\Exception
*/
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}

View File

@ -0,0 +1,50 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Exception;
/**
* Exception for out-of-bounds.
*
* "This is the same as OutOfBoundsException, but this should be used
* for normal arrays which are indexed by number, not by key."
*
* @package Xmpp\Exception
*/
class OutOfRangeException extends \OutOfBoundsException implements ExceptionInterface
{
}

View File

@ -0,0 +1,49 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Exception;
/**
* Runtime exception.
*
* "It should be throw in cases where the calling code does not necessarily have the capacity to handle it."
*
* @package Xmpp\Exception
*/
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}

View File

@ -0,0 +1,47 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Exception;
/**
* XML parser exception.
*
* @package Xmpp\Exception
*/
class SocketException extends RuntimeException
{
}

View File

@ -0,0 +1,46 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Exception\Stream;
/**
* Exception class for error generated by stream,
*
* @package Xmpp\Exception\Stream
*/
class AuthenticationErrorException extends StreamErrorException
{
}

View File

@ -0,0 +1,103 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Exception\Stream;
use Fabiang\Xmpp\Exception\RuntimeException;
use Fabiang\Xmpp\Event\XMLEvent;
/**
* Exception class for error generated by stream,
*
* @package Xmpp\Exception\Stream
*/
class StreamErrorException extends RuntimeException
{
/**
* XML content.
*
* @var string
*/
protected $content;
/**
* Create exception from XMLEvent object.
*
* @param \Fabiang\Xmpp\Event\XMLEvent $event XMLEvent object
* @return static
*/
public static function createFromEvent(XMLEvent $event)
{
/* @var $element \DOMElement */
list($element) = $event->getParameters();
/* @var $first \DOMElement */
$first = $element->firstChild;
if (null !== $first && XML_ELEMENT_NODE === $first->nodeType) {
$message = 'Stream Error: "' . $first->localName . '"';
} else {
$message = 'Generic stream error';
}
$exception = new static($message);
$exception->setContent($element->ownerDocument->saveXML($element));
return $exception;
}
/**
* Get xml content.
*
* @return string
*/
public function getContent()
{
return $this->content;
}
/**
* Set XML contents.
*
* @param string $content
* @return $this
*/
public function setContent($content)
{
$this->content = (string) $content;
return $this;
}
}

View File

@ -0,0 +1,47 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Exception;
/**
* XML parser exception.
*
* @package Xmpp\Exception
*/
class TimeoutException extends RuntimeException
{
}

View File

@ -0,0 +1,73 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Exception;
use Fabiang\Xmpp\Exception\InvalidArgumentException;
/**
* XML parser exception.
*
* @package Xmpp\Exception
*/
class XMLParserException extends RuntimeException
{
/**
* Factory XML parsing exception.
*
* @param resource $parser
* @throws static
*/
public static function create($parser)
{
if (!is_resource($parser) || 'xml' !== get_resource_type($parser)) {
$message = 'Argument #1 of "' . __CLASS__ . '::'
. __METHOD__ . '" must be a resource returned by "xml_parser_create"';
throw new InvalidArgumentException($message);
}
$code = xml_get_error_code($parser);
$error = xml_error_string($code);
$line = xml_get_current_line_number($parser);
$column = xml_get_current_column_number($parser);
return new static(
sprintf('XML parsing error: "%s" at Line %d at column %d', $error, $line, $column),
$code
);
}
}

View File

@ -0,0 +1,26 @@
Simplified BSD License
======================
Copyright 2014 Fabian Grutschus.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,416 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp;
use Fabiang\Xmpp\Connection\ConnectionInterface;
use Fabiang\Xmpp\Protocol\ImplementationInterface;
use Fabiang\Xmpp\Protocol\DefaultImplementation;
use Psr\Log\LoggerInterface;
/**
* Xmpp connection options.
*
* @package Xmpp
*/
class Options
{
/**
*
* @var ImplementationInterface
*/
protected $implementation;
/**
*
* @var string
*/
protected $address;
/**
* Connection object.
*
* @var ConnectionInterface
*/
protected $connection;
/**
* PSR-3 Logger interface.
*
* @var LoggerInterface
*/
protected $logger;
/**
*
* @var string
*/
protected $to;
/**
*
* @var string
*/
protected $username;
/**
*
* @var string
*/
protected $password;
/**
*
* @var string
*/
protected $jid;
/**
*
* @var boolean
*/
protected $authenticated = false;
/**
*
* @var array
*/
protected $users = array();
/**
* Timeout for connection.
*
* @var integer
*/
protected $timeout = 30;
/**
* Authentication methods.
*
* @var array
*/
protected $authenticationClasses = array(
'digest-md5' => '\\Fabiang\\Xmpp\\EventListener\\Stream\\Authentication\\DigestMd5',
'plain' => '\\Fabiang\\Xmpp\\EventListener\\Stream\\Authentication\\Plain'
);
/**
* Constructor.
*
* @param string $address Server address
*/
public function __construct($address = null)
{
if (null !== $address) {
$this->setAddress($address);
}
}
/**
* Get protocol implementation.
*
* @return ImplementationInterface
*/
public function getImplementation()
{
if (null === $this->implementation) {
$this->setImplementation(new DefaultImplementation());
}
return $this->implementation;
}
/**
* Set protocol implementation.
*
* @param ImplementationInterface $implementation
* @return $this
*/
public function setImplementation(ImplementationInterface $implementation)
{
$this->implementation = $implementation;
return $this;
}
/**
* Get server address.
*
* @return string
*/
public function getAddress()
{
return $this->address;
}
/**
* Set server address.
*
* When a address is passed this setter also calls setTo with the hostname part of the address.
*
* @param string $address Server address
* @return $this
*/
public function setAddress($address)
{
$this->address = (string) $address;
if (false !== ($host = parse_url($address, PHP_URL_HOST))) {
$this->setTo($host);
}
return $this;
}
/**
* Get connection object.
*
* @return ConnectionInterface
*/
public function getConnection()
{
return $this->connection;
}
/**
* Set connection object.
*
* @param ConnectionInterface $connection
* @return $this
*/
public function setConnection(ConnectionInterface $connection)
{
$this->connection = $connection;
return $this;
}
/**
* Get logger instance.
*
* @return LoggerInterface
*/
public function getLogger()
{
return $this->logger;
}
/**
* Set logger instance.
*
* @param \Psr\Log\LoggerInterface $logger PSR-3 Logger
* @return $this
*/
public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
return $this;
}
/**
* Get server name.
*
* @return string
*/
public function getTo()
{
return $this->to;
}
/**
* Set server name.
*
* This value is send to the server in requests as to="" attribute.
*
* @param string $to
* @return $this
*/
public function setTo($to)
{
$this->to = (string) $to;
return $this;
}
/**
* Get username.
*
* @return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set username.
*
* @param string $username
* @return $this
*/
public function setUsername($username)
{
$this->username = (string) $username;
return $this;
}
/**
* Get password.
*
* @return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set password.
*
* @param string $password
* @return $this
*/
public function setPassword($password)
{
$this->password = (string) $password;
return $this;
}
/**
* Get users jid.
*
* @return string
*/
public function getJid()
{
return $this->jid;
}
/**
* Set users jid.
*
* @param string $jid
* @return $this
*/
public function setJid($jid)
{
$this->jid = (string) $jid;
return $this;
}
/**
* Is user authenticated.
*
* @return boolean
*/
public function isAuthenticated()
{
return $this->authenticated;
}
/**
* Set authenticated.
*
* @param boolean $authenticated Flag
* @return $this
*/
public function setAuthenticated($authenticated)
{
$this->authenticated = (bool) $authenticated;
return $this;
}
/**
* Get users.
*
* @return Protocol\User\User[]
*/
public function getUsers()
{
return $this->users;
}
/**
* Set users.
*
* @param array $users User list
* @return $this
*/
public function setUsers(array $users)
{
$this->users = $users;
return $this;
}
/**
* Get authentication classes.
*
* @return array
*/
public function getAuthenticationClasses()
{
return $this->authenticationClasses;
}
/**
*
* @param array $authenticationClasses Authentication classes
* @return $this
*/
public function setAuthenticationClasses(array $authenticationClasses)
{
$this->authenticationClasses = $authenticationClasses;
return $this;
}
/**
* Get timeout for connection.
*
* @return integer
*/
public function getTimeout()
{
return $this->timeout;
}
/**
* Set timeout for connection.
*
* @param integer $timeout Seconds
* @return \Fabiang\Xmpp\Options
*/
public function setTimeout($timeout)
{
$this->timeout = (int) $timeout;
return $this;
}
}

View File

@ -0,0 +1,61 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp;
/**
* Classes that take options should implent this interface.
*
* @package Xmpp
*/
interface OptionsAwareInterface
{
/**
* Set options.
*
* @param Options $options
* @return $this
*/
public function setOptions(Options $options);
/**
* Get options.
*
* @return Options
*/
public function getOptions();
}

View File

@ -0,0 +1,138 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Protocol;
use Fabiang\Xmpp\Options;
use Fabiang\Xmpp\EventListener\EventListenerInterface;
use Fabiang\Xmpp\Event\EventManagerInterface;
use Fabiang\Xmpp\Event\EventManager;
use Fabiang\Xmpp\EventListener\Stream\Stream;
use Fabiang\Xmpp\EventListener\Stream\StreamError;
use Fabiang\Xmpp\EventListener\Stream\StartTls;
use Fabiang\Xmpp\EventListener\Stream\Authentication;
use Fabiang\Xmpp\EventListener\Stream\Bind;
use Fabiang\Xmpp\EventListener\Stream\Session;
use Fabiang\Xmpp\EventListener\Stream\Roster as RosterListener;
/**
* Default Protocol implementation.
*
* @package Xmpp\Protocol
*/
class DefaultImplementation implements ImplementationInterface
{
/**
* Options.
*
* @var Options
*/
protected $options;
/**
* Eventmanager.
*
* @var EventManagerInterface
*/
protected $events;
/**
* {@inheritDoc}
*/
public function register()
{
$this->registerListener(new Stream);
$this->registerListener(new StreamError);
$this->registerListener(new StartTls);
$this->registerListener(new Authentication);
$this->registerListener(new Bind);
$this->registerListener(new Session);
$this->registerListener(new RosterListener);
}
/**
* {@inheritDoc}
*/
public function registerListener(EventListenerInterface $eventListener)
{
$connection = $this->getOptions()->getConnection();
$eventListener->setEventManager($this->getEventManager())
->setOptions($this->getOptions())
->attachEvents();
$connection->addListener($eventListener);
}
/**
* {@inheritDoc}
*/
public function getOptions()
{
return $this->options;
}
/**
* {@inheritDoc}
*/
public function setOptions(Options $options)
{
$this->options = $options;
return $this;
}
/**
* {@inheritDoc}
*/
public function getEventManager()
{
if (null === $this->events) {
$this->setEventManager(new EventManager());
}
return $this->events;
}
/**
* {@inheritDoc}
*/
public function setEventManager(EventManagerInterface $events)
{
$this->events = $events;
return $this;
}
}

View File

@ -0,0 +1,65 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Protocol;
use Fabiang\Xmpp\OptionsAwareInterface;
use Fabiang\Xmpp\EventListener\EventListenerInterface;
use Fabiang\Xmpp\Event\EventManagerAwareInterface;
/**
* Protocol implementation interface.
*
* @package Xmpp\Protocol
*/
interface ImplementationInterface extends OptionsAwareInterface, EventManagerAwareInterface
{
/**
* Register listeners that implement xmpp protocol.
*
* @return void
*/
public function register();
/**
* Register a listener.
*
* @param EventListenerInterface $eventListener Event listener
* @return $this
*/
public function registerListener(EventListenerInterface $eventListener);
}

View File

@ -0,0 +1,173 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Protocol;
use Fabiang\Xmpp\Util\XML;
/**
* Protocol setting for Xmpp.
*
* @package Xmpp\Protocol
*/
class Message implements ProtocolImplementationInterface
{
/**
* Chat between to users.
*/
const TYPE_CHAT = 'chat';
/**
* Chat in a multi-user channel (MUC).
*/
const TYPE_GROUPCHAT = 'groupchat';
/**
* Message type.
*
* @var string
*/
protected $type = self::TYPE_CHAT;
/**
* Set message receiver.
*
* @var string
*/
protected $to;
/**
* Message.
*
* @var string
*/
protected $message = '';
/**
* Constructor.
*
* @param string $message
* @param string $to
* @param string $type
*/
public function __construct($message = '', $to = '', $type = self::TYPE_CHAT)
{
$this->setMessage($message)->setTo($to)->setType($type);
}
/**
* {@inheritDoc}
*/
public function toString()
{
return XML::quoteMessage(
'<message type="%s" id="%s" to="%s"><body>%s</body></message>',
$this->getType(),
XML::generateId(),
$this->getTo(),
$this->getMessage()
);
}
/**
* Get message type.
*
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* Set message type.
*
* See {@link self::TYPE_CHAT} and {@link self::TYPE_GROUPCHAT}
*
* @param string $type
* @return $this
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Get message receiver.
*
* @return string
*/
public function getTo()
{
return $this->to;
}
/**
* Set message receiver.
*
* @param string $to
* @return $this
*/
public function setTo($to)
{
$this->to = (string) $to;
return $this;
}
/**
* Get message.
*
* @return string
*/
public function getMessage()
{
return $this->message;
}
/**
* Set message.
*
* @param string $message
* @return $this
*/
public function setMessage($message)
{
$this->message = (string) $message;
return $this;
}
}

View File

@ -0,0 +1,226 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Protocol;
use Fabiang\Xmpp\Util\XML;
/**
* Protocol setting for Xmpp.
*
* @package Xmpp\Protocol
*/
class Presence implements ProtocolImplementationInterface
{
/**
* Signals that the entity is available for communication.
*/
const TYPE_AVAILABLE = 'available';
/**
* Signals that the entity is no longer available for communication.
*/
const TYPE_UNAVAILABLE = 'unavailable';
/**
* The sender wishes to subscribe to the recipient's presence.
*/
const TYPE_SUBSCRIBE = 'subscribe';
/**
* The sender has allowed the recipient to receive their presence.
*/
const TYPE_SUBSCRIBED = 'subscribed';
/**
* The sender is unsubscribing from another entity's presence.
*/
const TYPE_UNSUBSCRIBE = 'unsubscribe';
/**
* The subscription request has been denied or a previously-granted subscription has been cancelled.
*/
const TYPE_UNSUBSCRIBED = 'unsubscribed';
/**
* A request for an entity's current presence; SHOULD be generated only by a server on behalf of a user.
*/
const TYPE_PROBE = 'probe';
/**
* An error has occurred regarding processing or delivery of a previously-sent presence stanza.
*/
const TYPE_ERROR = 'error';
/**
* The entity or resource is available.
*/
const SHOW_AVAILABLE = 'available';
/**
* The entity or resource is temporarily away.
*/
const SHOW_AWAY = 'away';
/**
* The entity or resource is actively interested in chatting.
*/
const SHOW_CHAT = 'chat';
/**
* The entity or resource is busy (dnd = "Do Not Disturb").
*/
const SHOW_DND = 'dnd';
/**
* The entity or resource is away for an extended period (xa = "eXtended Away").
*/
const SHOW_XA = 'xa';
/**
* Presence to.
*
* @var string|null
*/
protected $to;
/**
* Priority.
*
* @var integer
*/
protected $priority = 1;
/**
* Nickname for presence.
*
* @var string
*/
protected $nickname;
/**
* Constructor.
*
* @param integer $priority
* @param string $to
* @param string $nickname
*/
public function __construct($priority = 1, $to = null, $nickname = null)
{
$this->setPriority($priority)->setTo($to)->setNickname($nickname);
}
/**
* {@inheritDoc}
*/
public function toString()
{
$presence = '<presence';
if (null !== $this->getTo()) {
$presence .= ' to="' . XML::quote($this->getTo()) . '/' . XML::quote($this->getNickname()) . '"';
}
return $presence . '><priority>' . $this->getPriority() . '</priority></presence>';
}
/**
* Get nickname.
*
* @return string
*/
public function getNickname()
{
return $this->nickname;
}
/**
* Set nickname.
*
* @param string $nickname
* @return $this
*/
public function setNickname($nickname)
{
$this->nickname = (string) $nickname;
return $this;
}
/**
* Get to.
*
* @return string¦null
*/
public function getTo()
{
return $this->to;
}
/**
* Set to.
*
* @param string|null $to
* @return $this
*/
public function setTo($to = null)
{
$this->to = $to;
return $this;
}
/**
* Get priority.
*
* @return integer
*/
public function getPriority()
{
return $this->priority;
}
/**
* Set priority.
*
* @param integer $priority
* @return $this
*/
public function setPriority($priority)
{
$this->priority = (int) $priority;
return $this;
}
}

View File

@ -0,0 +1,53 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Protocol;
/**
* Protocol setting for Xmpp.
*
* @package Xmpp\Protocol
*/
interface ProtocolImplementationInterface
{
/**
* Protocol implementations should be turned into an string.
*
* @return string
*/
public function toString();
}

View File

@ -0,0 +1,56 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Protocol;
use Fabiang\Xmpp\Util\XML;
/**
* Protocol setting for Xmpp.
*
* @package Xmpp\Protocol
*/
class Roster implements ProtocolImplementationInterface
{
/**
* {@inheritDoc}
*/
public function toString()
{
return '<iq type="get" id="' . XML::generateId() . '"><query xmlns="jabber:iq:roster"/></iq>';
}
}

View File

@ -0,0 +1,124 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Protocol\User;
/**
* User object.
*
* @package Xmpp\Protocol
*/
class User
{
/**
*
* @var string
*/
protected $name;
/**
*
* @var string
*/
protected $jid;
/**
*
* @var string
*/
protected $subscription;
/**
*
* @var array
*/
protected $groups = array();
public function getName()
{
return $this->name;
}
public function setName($name = null)
{
if (null === $name || '' === $name) {
$this->name = null;
} else {
$this->name = $name;
}
return $this;
}
public function getJid()
{
return $this->jid;
}
public function setJid($jid)
{
$this->jid = (string) $jid;
return $this;
}
public function getSubscription()
{
return $this->subscription;
}
public function setSubscription($subscription)
{
$this->subscription = (string) $subscription;
return $this;
}
public function getGroups()
{
return $this->groups;
}
public function setGroups(array $groups)
{
$this->groups = $groups;
return $this;
}
public function addGroup($group)
{
$this->groups[] = (string) $group;
return $this;
}
}

116
libs/Fabiang/Xmpp/README.md Normal file
View File

@ -0,0 +1,116 @@
# fabiang/xmpp
[![Latest Stable Version](https://poser.pugx.org/fabiang/xmpp/v/stable.svg)](https://packagist.org/packages/fabiang/xmpp) [![Total Downloads](https://poser.pugx.org/fabiang/xmpp/downloads.svg)](https://packagist.org/packages/fabiang/xmpp) [![Latest Unstable Version](https://poser.pugx.org/fabiang/xmpp/v/unstable.svg)](https://packagist.org/packages/fabiang/xmpp) [![License](https://poser.pugx.org/fabiang/xmpp/license.svg)](https://packagist.org/packages/fabiang/xmpp)
[![Build Status](https://travis-ci.org/fabiang/xmpp.png?branch=master)](https://travis-ci.org/fabiang/xmpp) [![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/fabiang/xmpp/badges/quality-score.png?s=2605ad2bc987ff8501b8f749addff43ec1ac7098)](https://scrutinizer-ci.com/g/fabiang/xmpp/) [![Coverage Status](https://img.shields.io/coveralls/fabiang/xmpp.svg)](https://coveralls.io/r/fabiang/xmpp?branch=master) [![Dependency Status](https://gemnasium.com/fabiang/xmpp.png)](https://gemnasium.com/fabiang/xmpp) [![SensioLabsInsight](https://insight.sensiolabs.com/projects/a535cd82-788d-4506-803e-02ede44a9e74/mini.png)](https://insight.sensiolabs.com/projects/a535cd82-788d-4506-803e-02ede44a9e74)
Library for XMPP protocol connections (Jabber) for PHP.
## SYSTEM REQUIREMENTS
- PHP >= 5.3.3
- psr/log
- psr/log-implementation - like monolog/monolog for logging (optional)
## INSTALLATION
New to Composer? Read the [introduction](https://getcomposer.org/doc/00-intro.md#introduction). Add the following to your composer file:
```json
{
"require": {
"fabiang/xmpp": "*"
}
}
```
## DOCUMENTATION
This library uses an object to hold options:
```php
use Fabiang\Xmpp\Options;
$options = new Options($address);
$options->setUsername($username)
->setPassword($password);
```
The server address must be in the format `tcp://myjabber.com:5222`.
If the server supports TLS the connection will automatically be encrypted.
You can also pass a PSR-2-compatible object to the options object:
```php
$options->setLogger($logger)
```
The client manages the connection to the Jabber server and requires the options object:
```php
use Fabiang\Xmpp\Client;
$client = new Client($options);
// optional connect manually
$client->connect();
```
For sending data you just need to pass a object that implements `Fabiang\Xmpp\Protocol\ProtocolImplementationInterface`:
```php
use Fabiang\Xmpp\Protocol\Roster;
use Fabiang\Xmpp\Protocol\Presence;
use Fabiang\Xmpp\Protocol\Message;
// fetch roster list; users and their groups
$client->send(new Roster);
// set status to online
$client->send(new Presence);
// send a message to another user
$message = new Message;
$message->setMessage('test')
->setTo('nickname@myjabber.com')
$client->send($message);
// join a channel
$channel = new Presence;
$channel->setTo('channelname@conference.myjabber.com')
->setNickName('mynick');
$client->send($channel);
// send a message to the above channel
$message = new Message;
$message->setMessage('test')
->setTo('channelname@conference.myjabber.com')
->setType(Message::TYPE_GROUPCHAT);
$client->send($message);
```
After all you should disconnect:
```php
$client->disconnect();
```
## DEVELOPING
If you like this library and you want to contribute, make sure the unit-tests and integration tests are running.
Composer will help you to install the right version of PHPUnit and [Behat](http://behat.org/).
composer install --dev
After that:
./vendor/bin/phpunit -c tests
./vendor/bin/behat --config=tests/behat.yml --strict
New features should allways tested with Behat.
## LICENSE
BSD-2-Clause. See the [LICENSE](LICENSE.md).
## TODO
- Better integration of channels
- Factory method for server addresses
- Add support von vCard
- improve documentation

View File

@ -0,0 +1,221 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Stream;
use Fabiang\Xmpp\Exception\InvalidArgumentException;
use Fabiang\Xmpp\Util\ErrorHandler;
/**
* Stream functions wrapper class.
*
* @package Xmpp\Stream
*/
class SocketClient
{
const BUFFER_LENGTH = 4096;
/**
* Resource.
*
* @var resource
*/
protected $resource;
/**
* Address.
*
* @var string
*/
protected $address;
/**
* Constructor takes address as argument.
*
* @param string $address
*/
public function __construct($address)
{
$this->address = $address;
}
/**
* Connect.
*
* @param integer $timeout Timeout for connection
* @param boolean $persistent Persitent connection
* @return void
*/
public function connect($timeout = 30, $persistent = false)
{
if (true === $persistent) {
$flags = STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT;
} else {
$flags = STREAM_CLIENT_CONNECT;
}
// call stream_socket_client with custom error handler enabled
$handler = new ErrorHandler(
function ($address, $timeout, $flags) {
$options = [
'ssl' => [
'allow_self_signed' => true,
'verify_peer_name' => false,
],
];
$context = stream_context_create($options);
return stream_socket_client($address, $errno, $errstr, $timeout, $flags, $context);
},
$this->address,
$timeout,
$flags
);
$resource = $handler->execute(__FILE__, __LINE__);
stream_set_timeout($resource, $timeout);
$this->resource = $resource;
}
/**
* Reconnect and optionally use different address.
*
* @param string $address
* @param integer $timeout
* @param bool $persistent
*/
public function reconnect($address = null, $timeout = 30, $persistent = false)
{
$this->close();
if (null !== $this->address) {
$this->address = $address;
}
$this->connect($timeout, $persistent);
}
/**
* Close stream.
*
* @return void
*/
public function close()
{
fclose($this->resource);
}
/**
* Set stream blocking mode.
*
* @param boolean $flag Flag
* @return $this
*/
public function setBlocking($flag = true)
{
stream_set_blocking($this->resource, (int) $flag);
return $this;
}
/**
* Read from stream.
*
* @param integer $length Bytes to read
* @return string
*/
public function read($length = self::BUFFER_LENGTH)
{
return fread($this->resource, $length);
}
/**
* Write to stream.
*
* @param string $string String
* @param integer $length Limit
* @return void
*/
public function write($string, $length = null)
{
if (null !== $length) {
fwrite($this->resource, $string, $length);
} else {
fwrite($this->resource, $string);
}
}
/**
* Enable/disable cryptography on stream.
*
* @param boolean $enable Flag
* @param integer $cryptoType One of the STREAM_CRYPTO_METHOD_* constants.
* @return void
* @throws InvalidArgumentException
*/
public function crypto($enable, $cryptoType = null)
{
if (false === $enable) {
$handler = new ErrorHandler('stream_socket_enable_crypto', $this->resource, false);
return $handler->execute(__FILE__, __LINE__);
}
if (null === $cryptoType) {
throw new InvalidArgumentException('Second argument is require when enabling crypto an stream');
}
return stream_socket_enable_crypto($this->resource, $enable, $cryptoType);
}
/**
* Get socket stream.
*
* @return resource
*/
public function getResource()
{
return $this->resource;
}
/**
* Return address.
*
* @return string
*/
public function getAddress()
{
return $this->address;
}
}

View File

@ -0,0 +1,443 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Stream;
use Fabiang\Xmpp\Event\EventManagerAwareInterface;
use Fabiang\Xmpp\Event\EventManagerInterface;
use Fabiang\Xmpp\Event\EventManager;
use Fabiang\Xmpp\Event\XMLEvent;
use Fabiang\Xmpp\Event\XMLEventInterface;
use Fabiang\Xmpp\Exception\XMLParserException;
/**
* Xml stream class.
*
* @package Xmpp\Stream
*/
class XMLStream implements EventManagerAwareInterface
{
const NAMESPACE_SEPARATOR = ':';
/**
* Eventmanager.
*
* @var EventManagerInterface
*/
protected $events;
/**
* Document encoding.
*
* @var string
*/
protected $encoding;
/**
* Current parsing depth.
*
* @var integer
*/
protected $depth = 0;
/**
*
* @var \DOMDocument
*/
protected $document;
/**
* Collected namespaces.
*
* @var array
*/
protected $namespaces = array();
/**
* Cache of namespace prefixes.
*
* @var array
*/
protected $namespacePrefixes = array();
/**
* Element cache.
*
* @var array
*/
protected $elements = array();
/**
* XML parser.
*
* @var resource
*/
protected $parser;
/**
* Event object.
*
* @var XMLEventInterface
*/
protected $eventObject;
/**
* Collected events while parsing.
*
* @var array
*/
protected $eventCache = array();
/**
* Constructor.
*/
public function __construct($encoding = 'UTF-8', XMLEventInterface $eventObject = null)
{
$this->encoding = $encoding;
$this->reset();
if (null === $eventObject) {
$eventObject = new XMLEvent();
}
$this->eventObject = $eventObject;
}
/**
* Free XML parser on desturct.
*/
public function __destruct()
{
xml_parser_free($this->parser);
}
/**
* Parse XML data and trigger events.
*
* @param string $source XML source
* @return \DOMDocument
*/
public function parse($source)
{
$this->clearDocument($source);
$this->eventCache = array();
if (0 === xml_parse($this->parser, $source, false)) {
throw XMLParserException::create($this->parser);
}
// trigger collected events.
$this->trigger();
$this->eventCache = array();
// </stream> was not there, so lets close the document
if ($this->depth > 0) {
$this->document->appendChild($this->elements[0]);
}
return $this->document;
}
/**
* Clear document.
*
* Method resets the parser instance if <?xml is found. Overwise it clears the DOM document.
*
* @return void
*/
protected function clearDocument($source)
{
$documentElement = $this->document->documentElement;
// collect xml declaration
if ('<?xml' === substr($source, 0, 5)) {
$this->reset();
$matches = array();
if (preg_match('/^<\?xml.*encoding=(\'|")([\w-]+)\1.*?>/i', $source, $matches)) {
$this->encoding = $matches[2];
xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->encoding);
}
} elseif (null !== $documentElement) {
// clean the document
/* @var $childNode \DOMNode */
while ($documentElement->hasChildNodes()) {
$documentElement->removeChild($documentElement->firstChild);
}
}
}
/**
* Starting tag found.
*
* @param resource $parser XML parser
* @param string $name Element name
* @param attribs $attribs Element attributes
* @return void
*/
protected function startXml()
{
list (, $name, $attribs) = func_get_args();
$elementData = explode(static::NAMESPACE_SEPARATOR, $name, 2);
$elementName = $elementData[0];
$prefix = null;
if (isset($elementData[1])) {
$elementName = $elementData[1];
$prefix = $elementData[0];
}
$attributesNodes = $this->createAttributeNodes($attribs);
$namespaceAttrib = false;
// current namespace
if (array_key_exists('xmlns', $attribs)) {
$namespaceURI = $attribs['xmlns'];
} else {
$namespaceURI = $this->namespaces[$this->depth - 1];
}
// namespace of the element
if (null !== $prefix) {
$namespaceElement = $this->namespacePrefixes[$prefix];
} else {
$namespaceAttrib = true;
$namespaceElement = $namespaceURI;
}
$this->namespaces[$this->depth] = $namespaceURI;
// workaround for multiple xmlns defined, since we did have parent element inserted into the dom tree yet
if (true === $namespaceAttrib) {
$element = $this->document->createElement($elementName);
} else {
$elementNameFull = $elementName;
if (null !== $prefix) {
$elementNameFull = $prefix . static::NAMESPACE_SEPARATOR . $elementName;
}
$element = $this->document->createElementNS($namespaceElement, $elementNameFull);
}
foreach ($attributesNodes as $attributeNode) {
$element->setAttributeNode($attributeNode);
}
$this->elements[$this->depth] = $element;
$this->depth++;
$event = '{' . $namespaceElement . '}' . $elementName;
$this->cacheEvent($event, true, array($element));
}
/**
* Turn attribes into attribute nodes.
*
* @param array $attribs Attributes
* @return array
*/
protected function createAttributeNodes(array $attribs)
{
$attributesNodes = array();
foreach ($attribs as $name => $value) {
// collect namespace prefixes
if ('xmlns:' === substr($name, 0, 6)) {
$prefix = substr($name, 6);
$this->namespacePrefixes[$prefix] = $value;
} else {
$attribute = $this->document->createAttribute($name);
$attribute->value = $value;
$attributesNodes[] = $attribute;
}
}
return $attributesNodes;
}
/**
* End tag found.
*
* @return void
*/
protected function endXml()
{
$this->depth--;
$element = $this->elements[$this->depth];
if ($this->depth > 0) {
$parent = $this->elements[$this->depth - 1];
} else {
$parent = $this->document;
}
$parent->appendChild($element);
$localName = $element->localName;
// Frist: try to get the namespace from element.
$namespaceURI = $element->namespaceURI;
// Second: loop over namespaces till namespace is not null
if (null === $namespaceURI) {
$namespaceURI = $this->namespaces[$this->depth];
}
$event = '{' . $namespaceURI . '}' . $localName;
$this->cacheEvent($event, false, array($element));
}
/**
* Data found.
*
* @param resource $parser XML parser
* @param string $data Element data
* @return void
*/
protected function dataXml()
{
$data = func_get_arg(1);
if (isset($this->elements[$this->depth - 1])) {
$element = $this->elements[$this->depth - 1];
$element->appendChild($this->document->createTextNode($data));
}
}
/**
* Add event to cache.
*
* @param string $event
* @param boolean $startTag
* @param array $params
* @return void
*/
protected function cacheEvent($event, $startTag, $params)
{
$this->eventCache[] = array($event, $startTag, $params);
}
/**
* Trigger cached events
*
* @return void
*/
protected function trigger()
{
foreach ($this->eventCache as $event) {
list($event, $startTag, $param) = $event;
$this->eventObject->setStartTag($startTag);
$this->getEventManager()->setEventObject($this->eventObject);
$this->getEventManager()->trigger($event, $this, $param);
}
}
/**
* Reset class properties.
*
* @return void
*/
public function reset()
{
$parser = xml_parser_create($this->encoding);
xml_set_object($parser, $this);
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
xml_set_element_handler($parser, 'startXml', 'endXml');
xml_set_character_data_handler($parser, 'dataXml');
$this->parser = $parser;
$this->depth = 0;
$this->document = new \DOMDocument('1.0', $this->encoding);
$this->namespaces = array();
$this->namespacePrefixes = array();
$this->elements = array();
}
/**
* Get XML parser resource.
*
* @return resource
*/
public function getParser()
{
return $this->parser;
}
/**
* {@inheritDoc}
*/
public function getEventManager()
{
if (null === $this->events) {
$this->setEventManager(new EventManager());
}
return $this->events;
}
/**
* {@inheritDoc}
*/
public function setEventManager(EventManagerInterface $events)
{
$this->events = $events;
$events->setEventObject($this->getEventObject());
return $this;
}
/**
* Get event object.
*
* @return XMLEventInterface
*/
public function getEventObject()
{
return $this->eventObject;
}
/**
* Set event object.
*
* @param XMLEventInterface $eventObject
* @return $this
*/
public function setEventObject(XMLEventInterface $eventObject)
{
$this->eventObject = $eventObject;
return $this;
}
}

View File

@ -0,0 +1,100 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Util;
use Fabiang\Xmpp\Exception\InvalidArgumentException;
use Fabiang\Xmpp\Exception\ErrorException;
/**
* XML utility methods.
*
* @package Xmpp\Util
*/
class ErrorHandler
{
/**
* Method to be called.
*
* @var callable
*/
protected $method;
/**
* Arguments for method.
*
* @var array
*/
protected $arguments = array();
public function __construct($method)
{
if (!is_callable($method)) {
throw new InvalidArgumentException('Argument 1 of "' . __METHOD__ . '" must be a callable');
}
$arguments = func_get_args();
array_shift($arguments);
$this->method = $method;
$this->arguments = $arguments;
}
/**
* Execute a function and handle all types of errors.
*
* @param string $file
* @param int $line
* @return mixed
* @throws ErrorException
*/
public function execute($file, $line)
{
set_error_handler(function ($errno, $errstr) use ($file, $line) {
throw new ErrorException($errstr, 0, $errno, $file, $line);
});
try {
$value = call_user_func_array($this->method, $this->arguments);
restore_error_handler();
return $value;
} catch (ErrorException $exception) {
restore_error_handler();
throw $exception;
}
}
}

View File

@ -0,0 +1,128 @@
<?php
/**
* Copyright 2014 Fabian Grutschus. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the copyright holders.
*
* @author Fabian Grutschus <f.grutschus@lubyte.de>
* @copyright 2014 Fabian Grutschus. All rights reserved.
* @license BSD
* @link http://github.com/fabiang/xmpp
*/
namespace Fabiang\Xmpp\Util;
/**
* XML utility methods.
*
* @package Xmpp\Util
*/
class XML
{
/**
* Quote XML string.
*
* @param string $string String to be quoted
* @param string $encoding Encoding used for quotation
* @return string
*/
public static function quote($string, $encoding = 'UTF-8')
{
$flags = ENT_QUOTES;
if (defined('ENT_XML1')) {
$flags |= ENT_XML1;
}
return htmlspecialchars($string, $flags, $encoding);
}
/**
* Replace variables in a string and quote them before.
*
* <b>Hint:</b> this function works like <code>sprintf</code>
*
* @param string $message
* @param mixed $args
* @param mixed $...
* @return string
*/
public static function quoteMessage($message)
{
$variables = func_get_args();
// shift message variable
array_shift($variables);
// workaround for `static` call in a closure
$class = __CLASS__;
return vsprintf(
$message,
array_map(
function ($var) use ($class) {
return $class::quote($var);
},
$variables
)
);
}
/**
* Generate a unique id.
*
* @return string
*/
public static function generateId()
{
return static::quote('fabiang_xmpp_' . uniqid());
}
/**
* Encode a string with Base64 and quote it.
*
* @param string $data
* @param string $encoding
* @return string
*/
public static function base64Encode($data, $encoding = 'UTF-8')
{
return static::quote(base64_encode($data), $encoding);
}
/**
* Decode a Base64 encoded string.
*
* @param string $data
* @return string
*/
public static function base64Decode($data)
{
return base64_decode($data);
}
}