forked from kevinowino869/mitrobill
update PEAR
This commit is contained in:
@ -2,6 +2,7 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
@ -12,7 +13,7 @@
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -64,36 +65,52 @@ class Client
|
||||
const FILTER_ALL = 3;
|
||||
|
||||
/**
|
||||
* @var Communicator The communicator for this client.
|
||||
* The communicator for this client.
|
||||
*
|
||||
* @var Communicator
|
||||
*/
|
||||
protected $com;
|
||||
|
||||
/**
|
||||
* @var int The number of currently pending requests.
|
||||
* The number of currently pending requests.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $pendingRequestsCount = 0;
|
||||
|
||||
/**
|
||||
* @var array An array of responses that have not yet been extracted or
|
||||
* passed to a callback. Key is the tag of the request, and the value
|
||||
* is an array of associated responses.
|
||||
* An array of responses that have not yet been extracted
|
||||
* or passed to a callback.
|
||||
*
|
||||
* Key is the tag of the request, and the value is an array of
|
||||
* associated responses.
|
||||
*
|
||||
* @var array<string,Response[]>
|
||||
*/
|
||||
protected $responseBuffer = array();
|
||||
|
||||
/**
|
||||
* @var array An array of callbacks to be executed as responses come.
|
||||
* Key is the tag of the request, and the value is the callback for it.
|
||||
* An array of callbacks to be executed as responses come.
|
||||
*
|
||||
* Key is the tag of the request, and the value is the callback for it.
|
||||
*
|
||||
* @var array<string,callback>
|
||||
*/
|
||||
protected $callbacks = array();
|
||||
|
||||
/**
|
||||
* @var Registry A registry for the operations. Particularly helpful at
|
||||
* persistent connections.
|
||||
* A registry for the operations.
|
||||
*
|
||||
* Particularly helpful at persistent connections.
|
||||
*
|
||||
* @var Registry
|
||||
*/
|
||||
protected $registry = null;
|
||||
|
||||
/**
|
||||
* @var bool Whether to stream future responses.
|
||||
* Whether to stream future responses.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $_streamingResponses = false;
|
||||
|
||||
@ -103,24 +120,25 @@ class Client
|
||||
* Creates a new instance of a RouterOS API client with the specified
|
||||
* settings.
|
||||
*
|
||||
* @param string $host Hostname (IP or domain) of the RouterOS server.
|
||||
* @param string $username The RouterOS username.
|
||||
* @param string $password The RouterOS password.
|
||||
* @param int|null $port The port on which the RouterOS server provides
|
||||
* the API service. You can also specify NULL, in which case the port
|
||||
* will automatically be chosen between 8728 and 8729, depending on the
|
||||
* value of $crypto.
|
||||
* @param bool $persist Whether or not the connection should be a
|
||||
* @param string $host Hostname (IP or domain) of RouterOS.
|
||||
* @param string $username The RouterOS username.
|
||||
* @param string $password The RouterOS password.
|
||||
* @param int|null $port The port on which the RouterOS host
|
||||
* provides the API service. You can also specify NULL, in which case
|
||||
* the port will automatically be chosen between 8728 and 8729,
|
||||
* depending on the value of $crypto.
|
||||
* @param bool $persist Whether or not the connection should be a
|
||||
* persistent one.
|
||||
* @param float $timeout The timeout for the connection.
|
||||
* @param string $crypto The encryption for this connection. Must be one
|
||||
* of the PEAR2\Net\Transmitter\NetworkStream::CRYPTO_* constants. Off
|
||||
* by default. RouterOS currently supports only TLS, but the setting is
|
||||
* provided in this fashion for forward compatibility's sake. And for
|
||||
* the sake of simplicity, if you specify an encryption, don't specify a
|
||||
* context and your default context uses the value "DEFAULT" for
|
||||
* ciphers, "ADH" will be automatically added to the list of ciphers.
|
||||
* @param resource $context A context for the socket.
|
||||
* @param double|null $timeout The timeout for the connection.
|
||||
* @param string $crypto The encryption for this connection.
|
||||
* Must be one of the PEAR2\Net\Transmitter\NetworkStream::CRYPTO_*
|
||||
* constants. Off by default. RouterOS currently supports only TLS, but
|
||||
* the setting is provided in this fashion for forward compatibility's
|
||||
* sake. And for the sake of simplicity, if you specify an encryption,
|
||||
* don't specify a context and your default context uses the value
|
||||
* "DEFAULT" for ciphers, "ADH" will be automatically added to the list
|
||||
* of ciphers.
|
||||
* @param resource|null $context A context for the socket.
|
||||
*
|
||||
* @see sendSync()
|
||||
* @see sendAsync()
|
||||
@ -131,15 +149,10 @@ class Client
|
||||
$password = '',
|
||||
$port = 8728,
|
||||
$persist = false,
|
||||
$timeout = 10,
|
||||
$timeout = null,
|
||||
$crypto = N::CRYPTO_OFF,
|
||||
$context = null
|
||||
) {
|
||||
if(strpos($host,":")>-1){
|
||||
$part = explode(":",$host);
|
||||
$host = $part[0];
|
||||
$port = $part[1];
|
||||
}
|
||||
$this->com = new Communicator(
|
||||
$host,
|
||||
$port,
|
||||
@ -183,7 +196,7 @@ class Client
|
||||
* the class is invoked and its returned value is returned by this function.
|
||||
*
|
||||
* @param mixed $arg Value can be either a {@link Request} to send, which
|
||||
* would be sent asynchoniously if it has a tag, and synchroniously if
|
||||
* would be sent asynchronously if it has a tag, and synchronously if
|
||||
* not, a number to loop with or NULL to complete all pending requests.
|
||||
* Any other value is converted to string and treated as the tag of a
|
||||
* request to complete.
|
||||
@ -210,7 +223,7 @@ class Client
|
||||
* @param string $username The RouterOS username.
|
||||
* @param string $password The RouterOS password.
|
||||
* @param int|null $timeout The time to wait for each response. NULL
|
||||
* waits indefinetly.
|
||||
* waits indefinitely.
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure.
|
||||
*/
|
||||
@ -263,7 +276,7 @@ class Client
|
||||
* @param string $password The RouterOS password. Potentially parsed
|
||||
* already by iconv.
|
||||
* @param int|null $timeout The time to wait for each response. NULL
|
||||
* waits indefinetly.
|
||||
* waits indefinitely.
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure.
|
||||
*/
|
||||
@ -274,15 +287,31 @@ class Client
|
||||
$timeout = null
|
||||
) {
|
||||
$request = new Request('/login');
|
||||
// Update Mikrotik Versi terbaru
|
||||
// sayangnya ini ngga aman, bagusnya di setup ke port SSL
|
||||
$request->setArgument('name', $username);
|
||||
$request->setArgument('password', $password);
|
||||
$request->send($com);
|
||||
$response = new Response($com, false, $timeout);
|
||||
return $response->getType() === Response::TYPE_FINAL;
|
||||
null === $response->getProperty('ret');
|
||||
}
|
||||
$request->setArgument('name', $username);
|
||||
$request->setArgument('password', $password);
|
||||
// $request->setArgument(
|
||||
// 'response',
|
||||
// '00' . md5(
|
||||
// chr(0) . $password
|
||||
// . pack('H*', $response->getProperty('ret'))
|
||||
// )
|
||||
// );
|
||||
$request->verify($com)->send($com);
|
||||
|
||||
$response = new Response($com, false, $timeout);
|
||||
if ($response->getType() === Response::TYPE_FINAL) {
|
||||
return null === $response->getProperty('ret');
|
||||
} else {
|
||||
while ($response->getType() !== Response::TYPE_FINAL
|
||||
&& $response->getType() !== Response::TYPE_FATAL
|
||||
) {
|
||||
$response = new Response($com, false, $timeout);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the charset(s) for this connection.
|
||||
@ -307,6 +336,7 @@ class Client
|
||||
* @return string|array The old charset. If $charsetType is
|
||||
* {@link Communicator::CHARSET_ALL}, the old values will be returned as
|
||||
* an array with the types as keys, and charsets as values.
|
||||
*
|
||||
* @see Communicator::setDefaultCharset()
|
||||
*/
|
||||
public function setCharset(
|
||||
@ -326,6 +356,7 @@ class Client
|
||||
* @return string|array The current charset. If $charsetType is
|
||||
* {@link Communicator::CHARSET_ALL}, the current values will be
|
||||
* returned as an array with the types as keys, and charsets as values.
|
||||
*
|
||||
* @see setCharset()
|
||||
*/
|
||||
public function getCharset($charsetType)
|
||||
@ -336,16 +367,18 @@ class Client
|
||||
/**
|
||||
* Sends a request and waits for responses.
|
||||
*
|
||||
* @param Request $request The request to send.
|
||||
* @param callback $callback Optional. A function that is to be executed
|
||||
* when new responses for this request are available. The callback takes
|
||||
* two parameters. The {@link Response} object as the first, and the
|
||||
* {@link Client} object as the second one. If the function returns
|
||||
* TRUE, the request is canceled. Note that the callback may be executed
|
||||
* one last time after that with a response that notifies about the
|
||||
* canceling.
|
||||
* @param Request $request The request to send.
|
||||
* @param callback|null $callback Optional. A function that is to be
|
||||
* executed when new responses for this request are available.
|
||||
* The callback takes two parameters. The {@link Response} object as
|
||||
* the first, and the {@link Client} object as the second one. If the
|
||||
* callback returns TRUE, the request is canceled. Note that the
|
||||
* callback may be executed at least two times after that. Once with a
|
||||
* {@link Response::TYPE_ERROR} response that notifies about the
|
||||
* canceling, plus the {@link Response::TYPE_FINAL} response.
|
||||
*
|
||||
* @return $this The client object.
|
||||
*
|
||||
* @see completeRequest()
|
||||
* @see loop()
|
||||
* @see cancelRequest()
|
||||
@ -392,10 +425,11 @@ class Client
|
||||
* pending request and/or has responses that are not yet extracted.
|
||||
*
|
||||
* @param string $tag The tag of the request to look for.
|
||||
* @param int $filter One of the FILTER_* consntants. Limits the search
|
||||
* @param int $filter One of the FILTER_* constants. Limits the search
|
||||
* to the specified places.
|
||||
*
|
||||
* @return bool TRUE if the request is active, FALSE otherwise.
|
||||
*
|
||||
* @see getPendingRequestsCount()
|
||||
* @see completeRequest()
|
||||
*/
|
||||
@ -417,6 +451,7 @@ class Client
|
||||
* @param Request $request The request to send.
|
||||
*
|
||||
* @return ResponseCollection The received responses as a collection.
|
||||
*
|
||||
* @see sendAsync()
|
||||
* @see close()
|
||||
*/
|
||||
@ -437,8 +472,8 @@ class Client
|
||||
* Starts an event loop for the RouterOS callbacks and finishes when a
|
||||
* specified request is completed.
|
||||
*
|
||||
* @param string $tag The tag of the request to complete. Setting NULL
|
||||
* completes all requests.
|
||||
* @param string|null $tag The tag of the request to complete.
|
||||
* Setting NULL completes all requests.
|
||||
*
|
||||
* @return ResponseCollection A collection of {@link Response} objects that
|
||||
* haven't been passed to a callback function or previously extracted
|
||||
@ -481,11 +516,13 @@ class Client
|
||||
* Gets all new responses for a request that haven't been passed to a
|
||||
* callback and clears the buffer from them.
|
||||
*
|
||||
* @param string $tag The tag of the request to extract new responses for.
|
||||
* @param string|null $tag The tag of the request to extract
|
||||
* new responses for.
|
||||
* Specifying NULL with extract new responses for all requests.
|
||||
*
|
||||
* @return ResponseCollection A collection of {@link Response} objects for
|
||||
* the specified request.
|
||||
*
|
||||
* @see loop()
|
||||
*/
|
||||
public function extractNewResponses($tag = null)
|
||||
@ -526,12 +563,13 @@ class Client
|
||||
* are no more pending requests or when a specified timeout has passed
|
||||
* (whichever comes first).
|
||||
*
|
||||
* @param int $sTimeout Timeout for the loop. If NULL, there is no time
|
||||
* limit.
|
||||
* @param int $usTimeout Microseconds to add to the time limit.
|
||||
* @param int|null $sTimeout Timeout for the loop.
|
||||
* If NULL, there is no time limit.
|
||||
* @param int $usTimeout Microseconds to add to the time limit.
|
||||
*
|
||||
* @return bool TRUE when there are any more pending requests, FALSE
|
||||
* otherwise.
|
||||
*
|
||||
* @see extractNewResponses()
|
||||
* @see getPendingRequestsCount()
|
||||
*/
|
||||
@ -581,6 +619,7 @@ class Client
|
||||
* Gets the number of pending requests.
|
||||
*
|
||||
* @return int The number of pending requests.
|
||||
*
|
||||
* @see isRequestActive()
|
||||
*/
|
||||
public function getPendingRequestsCount()
|
||||
@ -592,15 +631,16 @@ class Client
|
||||
* Cancels a request.
|
||||
*
|
||||
* Cancels an active request. Using this function in favor of a plain call
|
||||
* to the "/cancel" command is highly reccomended, as it also updates the
|
||||
* to the "/cancel" command is highly recommended, as it also updates the
|
||||
* counter of pending requests properly. Note that canceling a request also
|
||||
* removes any responses for it that were not previously extracted with
|
||||
* {@link static::extractNewResponses()}.
|
||||
*
|
||||
* @param string $tag Tag of the request to cancel. Setting NULL will cancel
|
||||
* all requests.
|
||||
* @param string|null $tag Tag of the request to cancel.
|
||||
* Setting NULL will cancel all requests.
|
||||
*
|
||||
* @return $this The client object.
|
||||
*
|
||||
* @see sendAsync()
|
||||
* @see close()
|
||||
*/
|
||||
@ -671,6 +711,7 @@ class Client
|
||||
* @param bool $streamingResponses Whether to stream future responses.
|
||||
*
|
||||
* @return bool The previous value of the setting.
|
||||
*
|
||||
* @see isStreamingResponses()
|
||||
*/
|
||||
public function setStreamingResponses($streamingResponses)
|
||||
@ -686,6 +727,7 @@ class Client
|
||||
* Gets whether future responses are streamed.
|
||||
*
|
||||
* @return bool The value of the setting.
|
||||
*
|
||||
* @see setStreamingResponses()
|
||||
*/
|
||||
public function isStreamingResponses()
|
||||
@ -758,12 +800,13 @@ class Client
|
||||
* @param Request $request The request to send.
|
||||
*
|
||||
* @return $this The client object.
|
||||
*
|
||||
* @see sendSync()
|
||||
* @see sendAsync()
|
||||
*/
|
||||
protected function send(Request $request)
|
||||
{
|
||||
$request->send($this->com, $this->registry);
|
||||
$request->verify($this->com)->send($this->com, $this->registry);
|
||||
$this->pendingRequestsCount++;
|
||||
return $this;
|
||||
}
|
||||
@ -774,9 +817,10 @@ class Client
|
||||
* Dispatches the next response in queue, i.e. it executes the associated
|
||||
* callback if there is one, or places the response in the response buffer.
|
||||
*
|
||||
* @param int $sTimeout If a response is not immediatly available, wait
|
||||
* this many seconds. If NULL, wait indefinetly.
|
||||
* @param int $usTimeout Microseconds to add to the waiting time.
|
||||
* @param int|null $sTimeout If a response is not immediately available,
|
||||
* wait this many seconds.
|
||||
* If NULL, wait indefinitely.
|
||||
* @param int $usTimeout Microseconds to add to the waiting time.
|
||||
*
|
||||
* @throws SocketException When there's no response within the time limit.
|
||||
* @return Response The dispatched response.
|
||||
@ -805,7 +849,14 @@ class Client
|
||||
if ('' != $tag) {
|
||||
if ($this->isRequestActive($tag, self::FILTER_CALLBACK)) {
|
||||
if ($this->callbacks[$tag]($response, $this)) {
|
||||
$this->cancelRequest($tag);
|
||||
try {
|
||||
$this->cancelRequest($tag);
|
||||
} catch (DataFlowException $e) {
|
||||
if ($e->getCode() !== DataFlowException::CODE_UNKNOWN_REQUEST
|
||||
) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
} elseif ($isLastForRequest) {
|
||||
unset($this->callbacks[$tag]);
|
||||
}
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
*
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -27,13 +28,13 @@ use PEAR2\Net\Transmitter as T;
|
||||
|
||||
/**
|
||||
* A RouterOS communicator.
|
||||
*
|
||||
*
|
||||
* Implementation of the RouterOS API protocol. Unlike the other classes in this
|
||||
* package, this class doesn't provide any conviniences beyond the low level
|
||||
* package, this class doesn't provide any conveniences beyond the low level
|
||||
* implementation details (automatic word length encoding/decoding, charset
|
||||
* translation and data integrity), and because of that, its direct usage is
|
||||
* strongly discouraged.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -47,67 +48,76 @@ class Communicator
|
||||
* Used when getting/setting all (default) charsets.
|
||||
*/
|
||||
const CHARSET_ALL = -1;
|
||||
|
||||
|
||||
/**
|
||||
* Used when getting/setting the (default) remote charset.
|
||||
*
|
||||
*
|
||||
* The remote charset is the charset in which RouterOS stores its data.
|
||||
* If you want to keep compatibility with your Winbox, this charset should
|
||||
* match the default charset from your Windows' regional settings.
|
||||
*/
|
||||
const CHARSET_REMOTE = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Used when getting/setting the (default) local charset.
|
||||
*
|
||||
*
|
||||
* The local charset is the charset in which the data from RouterOS will be
|
||||
* returned as. This charset should match the charset of the place the data
|
||||
* will eventually be written to.
|
||||
*/
|
||||
const CHARSET_LOCAL = 1;
|
||||
|
||||
|
||||
/**
|
||||
* @var array An array with the default charset types as keys, and the
|
||||
* default charsets as values.
|
||||
* An array with the default charset.
|
||||
*
|
||||
* Charset types as keys, and the default charsets as values.
|
||||
*
|
||||
* @var array<string,string|null>
|
||||
*/
|
||||
protected static $defaultCharsets = array(
|
||||
self::CHARSET_REMOTE => null,
|
||||
self::CHARSET_LOCAL => null
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @var array An array with the current charset types as keys, and the
|
||||
* current charsets as values.
|
||||
* An array with the current charset.
|
||||
*
|
||||
* Charset types as keys, and the current charsets as values.
|
||||
*
|
||||
* @var array<string,string|null>
|
||||
*/
|
||||
protected $charsets = array();
|
||||
|
||||
/**
|
||||
* @var T\TcpClient The transmitter for the connection.
|
||||
* The transmitter for the connection.
|
||||
*
|
||||
* @var T\TcpClient
|
||||
*/
|
||||
protected $trans;
|
||||
|
||||
/**
|
||||
* Creates a new connection with the specified options.
|
||||
*
|
||||
* @param string $host Hostname (IP or domain) of the RouterOS server.
|
||||
* @param int|null $port The port on which the RouterOS server provides
|
||||
* the API service. You can also specify NULL, in which case the port
|
||||
* will automatically be chosen between 8728 and 8729, depending on the
|
||||
* value of $crypto.
|
||||
* @param bool $persist Whether or not the connection should be a
|
||||
*
|
||||
* @param string $host Hostname (IP or domain) of RouterOS.
|
||||
* @param int|null $port The port on which the RouterOS host
|
||||
* provides the API service. You can also specify NULL, in which case
|
||||
* the port will automatically be chosen between 8728 and 8729,
|
||||
* depending on the value of $crypto.
|
||||
* @param bool $persist Whether or not the connection should be a
|
||||
* persistent one.
|
||||
* @param float $timeout The timeout for the connection.
|
||||
* @param string $key A string that uniquely identifies the
|
||||
* @param double|null $timeout The timeout for the connection.
|
||||
* @param string $key A string that uniquely identifies the
|
||||
* connection.
|
||||
* @param string $crypto The encryption for this connection. Must be one
|
||||
* of the PEAR2\Net\Transmitter\NetworkStream::CRYPTO_* constants. Off
|
||||
* by default. RouterOS currently supports only TLS, but the setting is
|
||||
* provided in this fashion for forward compatibility's sake. And for
|
||||
* the sake of simplicity, if you specify an encryption, don't specify a
|
||||
* context and your default context uses the value "DEFAULT" for
|
||||
* ciphers, "ADH" will be automatically added to the list of ciphers.
|
||||
* @param resource $context A context for the socket.
|
||||
*
|
||||
* @param string $crypto The encryption for this connection.
|
||||
* Must be one of the PEAR2\Net\Transmitter\NetworkStream::CRYPTO_*
|
||||
* constants. Off by default. RouterOS currently supports only TLS, but
|
||||
* the setting is provided in this fashion for forward compatibility's
|
||||
* sake. And for the sake of simplicity, if you specify an encryption,
|
||||
* don't specify a context and your default context uses the value
|
||||
* "DEFAULT" for ciphers, "ADH" will be automatically added to the list
|
||||
* of ciphers.
|
||||
* @param resource|null $context A context for the socket.
|
||||
*
|
||||
* @see sendWord()
|
||||
*/
|
||||
public function __construct(
|
||||
@ -126,7 +136,16 @@ class Communicator
|
||||
if (!isset($opts['ssl']['ciphers'])
|
||||
|| 'DEFAULT' === $opts['ssl']['ciphers']
|
||||
) {
|
||||
stream_context_set_option($context, 'ssl', 'ciphers', 'ADH');
|
||||
stream_context_set_option(
|
||||
$context,
|
||||
array(
|
||||
'ssl' => array(
|
||||
'ciphers' => 'ADH',
|
||||
'verify_peer' => false,
|
||||
'verify_peer_name' => false
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
// @codeCoverageIgnoreStart
|
||||
@ -158,31 +177,31 @@ class Communicator
|
||||
self::CHARSET_ALL
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A shorthand gateway.
|
||||
*
|
||||
*
|
||||
* This is a magic PHP method that allows you to call the object as a
|
||||
* function. Depending on the argument given, one of the other functions in
|
||||
* the class is invoked and its returned value is returned by this function.
|
||||
*
|
||||
* @param string $string A string of the word to send, or NULL to get the
|
||||
* next word as a string.
|
||||
*
|
||||
*
|
||||
* @param string|null $string A string of the word to send, or NULL to get
|
||||
* the next word as a string.
|
||||
*
|
||||
* @return int|string If a string is provided, returns the number of bytes
|
||||
* sent, otherwise retuns the next word as a string.
|
||||
* sent, otherwise returns the next word as a string.
|
||||
*/
|
||||
public function __invoke($string = null)
|
||||
{
|
||||
return null === $string ? $this->getNextWord()
|
||||
: $this->sendWord($string);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether a variable is a seekable stream resource.
|
||||
*
|
||||
*
|
||||
* @param mixed $var The value to check.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if $var is a seekable stream, FALSE otherwise.
|
||||
*/
|
||||
public static function isSeekableStream($var)
|
||||
@ -193,16 +212,16 @@ class Communicator
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Uses iconv to convert a stream from one charset to another.
|
||||
*
|
||||
*
|
||||
* @param string $inCharset The charset of the stream.
|
||||
* @param string $outCharset The desired resulting charset.
|
||||
* @param resource $stream The stream to convert. The stream is assumed
|
||||
* to be seekable, and is read from its current position to its end,
|
||||
* after which, it is seeked back to its starting position.
|
||||
*
|
||||
*
|
||||
* @return resource A new stream that uses the $out_charset. The stream is a
|
||||
* subset from the original stream, from its current position to its
|
||||
* end, seeked at its start.
|
||||
@ -216,22 +235,25 @@ class Communicator
|
||||
'convert.iconv.' . $inCharset . '.' . $outCharset,
|
||||
STREAM_FILTER_WRITE
|
||||
);
|
||||
|
||||
|
||||
flock($stream, LOCK_SH);
|
||||
while (!feof($stream)) {
|
||||
$bytes += stream_copy_to_stream($stream, $result, 0xFFFFF);
|
||||
$reader = new T\Stream($stream, false);
|
||||
$writer = new T\Stream($result, false);
|
||||
$chunkSize = $reader->getChunk(T\Stream::DIRECTION_RECEIVE);
|
||||
while ($reader->isAvailable() && $reader->isDataAwaiting()) {
|
||||
$bytes += $writer->send(fread($stream, $chunkSize));
|
||||
}
|
||||
fseek($stream, -$bytes, SEEK_CUR);
|
||||
flock($stream, LOCK_UN);
|
||||
|
||||
|
||||
stream_filter_remove($iconvFilter);
|
||||
rewind($result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the default charset(s) for new connections.
|
||||
*
|
||||
*
|
||||
* @param mixed $charset The charset to set. If $charsetType is
|
||||
* {@link self::CHARSET_ALL}, you can supply either a string to use for
|
||||
* all charsets, or an array with the charset types as keys, and the
|
||||
@ -239,10 +261,11 @@ class Communicator
|
||||
* @param int $charsetType Which charset to set. Valid values are the
|
||||
* CHARSET_* constants. Any other value is treated as
|
||||
* {@link self::CHARSET_ALL}.
|
||||
*
|
||||
*
|
||||
* @return string|array The old charset. If $charsetType is
|
||||
* {@link self::CHARSET_ALL}, the old values will be returned as an
|
||||
* array with the types as keys, and charsets as values.
|
||||
*
|
||||
* @see setCharset()
|
||||
*/
|
||||
public static function setDefaultCharset(
|
||||
@ -263,17 +286,18 @@ class Communicator
|
||||
return $oldCharsets;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the default charset(s).
|
||||
*
|
||||
*
|
||||
* @param int $charsetType Which charset to get. Valid values are the
|
||||
* CHARSET_* constants. Any other value is treated as
|
||||
* {@link self::CHARSET_ALL}.
|
||||
*
|
||||
*
|
||||
* @return string|array The current charset. If $charsetType is
|
||||
* {@link self::CHARSET_ALL}, the current values will be returned as an
|
||||
* array with the types as keys, and charsets as values.
|
||||
*
|
||||
* @see setDefaultCharset()
|
||||
*/
|
||||
public static function getDefaultCharset($charsetType)
|
||||
@ -284,12 +308,12 @@ class Communicator
|
||||
|
||||
/**
|
||||
* Gets the length of a seekable stream.
|
||||
*
|
||||
*
|
||||
* Gets the length of a seekable stream.
|
||||
*
|
||||
*
|
||||
* @param resource $stream The stream to check. The stream is assumed to be
|
||||
* seekable.
|
||||
*
|
||||
*
|
||||
* @return double The number of bytes in the stream between its current
|
||||
* position and its end.
|
||||
*/
|
||||
@ -302,17 +326,17 @@ class Communicator
|
||||
fseek($stream, $streamPosition, SEEK_SET);
|
||||
return $streamLength;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the charset(s) for this connection.
|
||||
*
|
||||
*
|
||||
* Sets the charset(s) for this connection. The specified charset(s) will be
|
||||
* used for all future words. When sending, {@link self::CHARSET_LOCAL} is
|
||||
* converted to {@link self::CHARSET_REMOTE}, and when receiving,
|
||||
* {@link self::CHARSET_REMOTE} is converted to {@link self::CHARSET_LOCAL}.
|
||||
* Setting NULL to either charset will disable charset convertion, and data
|
||||
* Setting NULL to either charset will disable charset conversion, and data
|
||||
* will be both sent and received "as is".
|
||||
*
|
||||
*
|
||||
* @param mixed $charset The charset to set. If $charsetType is
|
||||
* {@link self::CHARSET_ALL}, you can supply either a string to use for
|
||||
* all charsets, or an array with the charset types as keys, and the
|
||||
@ -320,10 +344,11 @@ class Communicator
|
||||
* @param int $charsetType Which charset to set. Valid values are the
|
||||
* CHARSET_* constants. Any other value is treated as
|
||||
* {@link self::CHARSET_ALL}.
|
||||
*
|
||||
*
|
||||
* @return string|array The old charset. If $charsetType is
|
||||
* {@link self::CHARSET_ALL}, the old values will be returned as an
|
||||
* array with the types as keys, and charsets as values.
|
||||
*
|
||||
* @see setDefaultCharset()
|
||||
*/
|
||||
public function setCharset($charset, $charsetType = self::CHARSET_ALL)
|
||||
@ -342,17 +367,18 @@ class Communicator
|
||||
return $oldCharsets;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the charset(s) for this connection.
|
||||
*
|
||||
*
|
||||
* @param int $charsetType Which charset to get. Valid values are the
|
||||
* CHARSET_* constants. Any other value is treated as
|
||||
* {@link self::CHARSET_ALL}.
|
||||
*
|
||||
*
|
||||
* @return string|array The current charset. If $charsetType is
|
||||
* {@link self::CHARSET_ALL}, the current values will be returned as an
|
||||
* array with the types as keys, and charsets as values.
|
||||
*
|
||||
* @see getDefaultCharset()
|
||||
* @see setCharset()
|
||||
*/
|
||||
@ -364,7 +390,7 @@ class Communicator
|
||||
|
||||
/**
|
||||
* Gets the transmitter for this connection.
|
||||
*
|
||||
*
|
||||
* @return T\TcpClient The transmitter for this connection.
|
||||
*/
|
||||
public function getTransmitter()
|
||||
@ -374,12 +400,13 @@ class Communicator
|
||||
|
||||
/**
|
||||
* Sends a word.
|
||||
*
|
||||
*
|
||||
* Sends a word and automatically encodes its length when doing so.
|
||||
*
|
||||
*
|
||||
* @param string $word The word to send.
|
||||
*
|
||||
*
|
||||
* @return int The number of bytes sent.
|
||||
*
|
||||
* @see sendWordFromStream()
|
||||
* @see getNextWord()
|
||||
*/
|
||||
@ -407,16 +434,17 @@ class Communicator
|
||||
|
||||
/**
|
||||
* Sends a word based on a stream.
|
||||
*
|
||||
*
|
||||
* Sends a word based on a stream and automatically encodes its length when
|
||||
* doing so. The stream is read from its current position to its end, and
|
||||
* then returned to its current position. Because of those operations, the
|
||||
* supplied stream must be seekable.
|
||||
*
|
||||
*
|
||||
* @param string $prefix A string to prepend before the stream contents.
|
||||
* @param resource $stream The seekable stream to send.
|
||||
*
|
||||
*
|
||||
* @return int The number of bytes sent.
|
||||
*
|
||||
* @see sendWord()
|
||||
*/
|
||||
public function sendWordFromStream($prefix, $stream)
|
||||
@ -441,31 +469,31 @@ class Communicator
|
||||
$stream
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
flock($stream, LOCK_SH);
|
||||
$totalLength = strlen($prefix) + self::seekableStreamLength($stream);
|
||||
static::verifyLengthSupport($totalLength);
|
||||
|
||||
$bytes = $this->trans->send(self::encodeLength($totalLength) . $prefix);
|
||||
$bytes += $this->trans->send($stream);
|
||||
|
||||
|
||||
flock($stream, LOCK_UN);
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the length is supported.
|
||||
*
|
||||
*
|
||||
* Verifies if the specified length is supported by the API. Throws a
|
||||
* {@link LengthException} if that's not the case. Currently, RouterOS
|
||||
* supports words up to 0xFFFFFFFF in length, so that's the only check
|
||||
* performed.
|
||||
*
|
||||
*
|
||||
* @param int $length The length to verify.
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function verifyLengthSupport($length)
|
||||
public static function verifyLengthSupport($length)
|
||||
{
|
||||
if ($length > 0xFFFFFFFF) {
|
||||
throw new LengthException(
|
||||
@ -478,10 +506,10 @@ class Communicator
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the length as requred by the RouterOS API.
|
||||
*
|
||||
* Encodes the length as required by the RouterOS API.
|
||||
*
|
||||
* @param int $length The length to encode.
|
||||
*
|
||||
*
|
||||
* @return string The encoded length.
|
||||
*/
|
||||
public static function encodeLength($length)
|
||||
@ -519,11 +547,12 @@ class Communicator
|
||||
|
||||
/**
|
||||
* Get the next word in queue as a string.
|
||||
*
|
||||
*
|
||||
* Get the next word in queue as a string, after automatically decoding its
|
||||
* length.
|
||||
*
|
||||
*
|
||||
* @return string The word.
|
||||
*
|
||||
* @see close()
|
||||
*/
|
||||
public function getNextWord()
|
||||
@ -541,7 +570,7 @@ class Communicator
|
||||
'word'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (null !== ($remoteCharset = $this->getCharset(self::CHARSET_REMOTE))
|
||||
&& null !== ($localCharset = $this->getCharset(self::CHARSET_LOCAL))
|
||||
) {
|
||||
@ -551,17 +580,18 @@ class Communicator
|
||||
$word
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return $word;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next word in queue as a stream.
|
||||
*
|
||||
*
|
||||
* Get the next word in queue as a stream, after automatically decoding its
|
||||
* length.
|
||||
*
|
||||
*
|
||||
* @return resource The word, as a stream.
|
||||
*
|
||||
* @see close()
|
||||
*/
|
||||
public function getNextWordAsStream()
|
||||
@ -575,7 +605,7 @@ class Communicator
|
||||
$remoteCharset . '.' . $localCharset . '//IGNORE//TRANSLIT'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if ($this->trans->isPersistent()) {
|
||||
$old = $this->trans->lock(T\Stream::DIRECTION_RECEIVE);
|
||||
$stream = $this->trans->receiveStream(
|
||||
@ -591,20 +621,21 @@ class Communicator
|
||||
'stream word'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return $stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the lenght of the incoming message.
|
||||
*
|
||||
* Decodes the lenght of the incoming message, as specified by the RouterOS
|
||||
* Decodes the length of the incoming message.
|
||||
*
|
||||
* Decodes the length of the incoming message, as specified by the RouterOS
|
||||
* API.
|
||||
*
|
||||
*
|
||||
* @param T\Stream $trans The transmitter from which to decode the length of
|
||||
* the incoming message.
|
||||
*
|
||||
* @return int The decoded length.
|
||||
*
|
||||
* @return int|double The decoded length.
|
||||
* Is of type "double" only for values above "2 << 31".
|
||||
*/
|
||||
public static function decodeLength(T\Stream $trans)
|
||||
{
|
||||
@ -618,18 +649,19 @@ class Communicator
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the lenght of the incoming message.
|
||||
*
|
||||
* Decodes the lenght of the incoming message, as specified by the RouterOS
|
||||
* Decodes the length of the incoming message.
|
||||
*
|
||||
* Decodes the length of the incoming message, as specified by the RouterOS
|
||||
* API.
|
||||
*
|
||||
*
|
||||
* Difference with the non private function is that this one doesn't perform
|
||||
* locking if the connection is a persistent one.
|
||||
*
|
||||
*
|
||||
* @param T\Stream $trans The transmitter from which to decode the length of
|
||||
* the incoming message.
|
||||
*
|
||||
* @return int The decoded length.
|
||||
*
|
||||
* @return int|double The decoded length.
|
||||
* Is of type "double" only for values above "2 << 31".
|
||||
*/
|
||||
private static function _decodeLength(T\Stream $trans)
|
||||
{
|
||||
@ -661,7 +693,7 @@ class Communicator
|
||||
|
||||
/**
|
||||
* Closes the opened connection, even if it is a persistent one.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure.
|
||||
*/
|
||||
public function close()
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
*
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -27,7 +28,7 @@ use RuntimeException;
|
||||
|
||||
/**
|
||||
* Exception thrown when the request/response cycle goes an unexpected way.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
*
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -22,7 +23,7 @@ namespace PEAR2\Net\RouterOS;
|
||||
|
||||
/**
|
||||
* Generic exception class of this package.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
*
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -24,7 +25,7 @@ use InvalidArgumentException as I;
|
||||
|
||||
/**
|
||||
* Exception thrown when there's something wrong with message arguments.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
*
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -25,9 +26,14 @@ namespace PEAR2\Net\RouterOS;
|
||||
*/
|
||||
use LengthException as L;
|
||||
|
||||
/**
|
||||
* Used in $previous
|
||||
*/
|
||||
use Exception as E;
|
||||
|
||||
/**
|
||||
* Exception thrown when there is a problem with a word's length.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -36,30 +42,31 @@ use LengthException as L;
|
||||
*/
|
||||
class LengthException extends L implements Exception
|
||||
{
|
||||
|
||||
|
||||
const CODE_UNSUPPORTED = 1200;
|
||||
const CODE_INVALID = 1300;
|
||||
const CODE_BEYOND_SHEME = 1301;
|
||||
|
||||
/**
|
||||
* The problematic length.
|
||||
*
|
||||
* @var mixed The problematic length.
|
||||
* @var int|double|null
|
||||
*/
|
||||
private $_length;
|
||||
|
||||
/**
|
||||
* Creates a new LengthException.
|
||||
*
|
||||
* @param string $message The Exception message to throw.
|
||||
* @param int $code The Exception code.
|
||||
* @param \Exception $previous The previous exception used for the exception
|
||||
* chaining.
|
||||
* @param number $length The length.
|
||||
*
|
||||
* @param string $message The Exception message to throw.
|
||||
* @param int $code The Exception code.
|
||||
* @param E|null $previous The previous exception used for the
|
||||
* exception chaining.
|
||||
* @param int|double|null $length The length.
|
||||
*/
|
||||
public function __construct(
|
||||
$message,
|
||||
$code = 0,
|
||||
$previous = null,
|
||||
E $previous = null,
|
||||
$length = null
|
||||
) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
@ -68,8 +75,8 @@ class LengthException extends L implements Exception
|
||||
|
||||
/**
|
||||
* Gets the length.
|
||||
*
|
||||
* @return number The length.
|
||||
*
|
||||
* @return int|double|null The length.
|
||||
*/
|
||||
public function getLength()
|
||||
{
|
||||
@ -81,7 +88,7 @@ class LengthException extends L implements Exception
|
||||
|
||||
/**
|
||||
* Returns a string representation of the exception.
|
||||
*
|
||||
*
|
||||
* @return string The exception as a string.
|
||||
*/
|
||||
public function __toString()
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
*
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -31,13 +32,13 @@ use Countable;
|
||||
use IteratorAggregate;
|
||||
|
||||
/**
|
||||
* Requred for IteratorAggregate::getIterator() to work properly with foreach.
|
||||
* Required for IteratorAggregate::getIterator() to work properly with foreach.
|
||||
*/
|
||||
use ArrayObject;
|
||||
|
||||
/**
|
||||
* Represents a RouterOS message.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -48,27 +49,32 @@ abstract class Message implements IteratorAggregate, Countable
|
||||
{
|
||||
|
||||
/**
|
||||
* @var array An array with message attributes. Each array key is the the
|
||||
* name of an attribute, and the correspding array value is the value
|
||||
* for that attribute.
|
||||
* An array with message attributes.
|
||||
*
|
||||
* Each array key is the the name of an attribute,
|
||||
* and the corresponding array value is the value for that attribute.
|
||||
*
|
||||
* @var array<string,string|resource>
|
||||
*/
|
||||
protected $attributes = array();
|
||||
|
||||
/**
|
||||
* @var string An optional tag to associate the message with.
|
||||
* An optional tag to associate the message with.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_tag = null;
|
||||
|
||||
|
||||
/**
|
||||
* A shorthand gateway.
|
||||
*
|
||||
*
|
||||
* This is a magic PHP method that allows you to call the object as a
|
||||
* function. Depending on the argument given, one of the other functions in
|
||||
* the class is invoked and its returned value is returned by this function.
|
||||
*
|
||||
* @param string $name The name of an attribute to get the value of, or NULL
|
||||
* to get the tag.
|
||||
*
|
||||
*
|
||||
* @param string|null $name The name of an attribute to get the value of,
|
||||
* or NULL to get the tag.
|
||||
*
|
||||
* @return string|resource The value of the specified attribute,
|
||||
* or the tag if NULL is provided.
|
||||
*/
|
||||
@ -82,9 +88,9 @@ abstract class Message implements IteratorAggregate, Countable
|
||||
|
||||
/**
|
||||
* Sanitizes a name of an attribute (message or query one).
|
||||
*
|
||||
*
|
||||
* @param mixed $name The name to sanitize.
|
||||
*
|
||||
*
|
||||
* @return string The sanitized name.
|
||||
*/
|
||||
public static function sanitizeAttributeName($name)
|
||||
@ -103,10 +109,10 @@ abstract class Message implements IteratorAggregate, Countable
|
||||
|
||||
/**
|
||||
* Sanitizes a value of an attribute (message or query one).
|
||||
*
|
||||
*
|
||||
* @param mixed $value The value to sanitize.
|
||||
*
|
||||
* @return string The sanitized value.
|
||||
*
|
||||
* @return string|resource The sanitized value.
|
||||
*/
|
||||
public static function sanitizeAttributeValue($value)
|
||||
{
|
||||
@ -119,8 +125,9 @@ abstract class Message implements IteratorAggregate, Countable
|
||||
|
||||
/**
|
||||
* Gets the tag that the message is associated with.
|
||||
*
|
||||
*
|
||||
* @return string The current tag or NULL if there isn't a tag.
|
||||
*
|
||||
* @see setTag()
|
||||
*/
|
||||
public function getTag()
|
||||
@ -130,13 +137,14 @@ abstract class Message implements IteratorAggregate, Countable
|
||||
|
||||
/**
|
||||
* Sets the tag to associate the request with.
|
||||
*
|
||||
*
|
||||
* Sets the tag to associate the message with. Setting NULL erases the
|
||||
* currently set tag.
|
||||
*
|
||||
*
|
||||
* @param string $tag The tag to set.
|
||||
*
|
||||
*
|
||||
* @return $this The message object.
|
||||
*
|
||||
* @see getTag()
|
||||
*/
|
||||
protected function setTag($tag)
|
||||
@ -147,11 +155,12 @@ abstract class Message implements IteratorAggregate, Countable
|
||||
|
||||
/**
|
||||
* Gets the value of an attribute.
|
||||
*
|
||||
*
|
||||
* @param string $name The name of the attribute.
|
||||
*
|
||||
*
|
||||
* @return string|resource|null The value of the specified attribute.
|
||||
* Returns NULL if such an attribute is not set.
|
||||
*
|
||||
* @see setAttribute()
|
||||
*/
|
||||
protected function getAttribute($name)
|
||||
@ -165,9 +174,10 @@ abstract class Message implements IteratorAggregate, Countable
|
||||
|
||||
/**
|
||||
* Gets all arguments in an array.
|
||||
*
|
||||
*
|
||||
* @return ArrayObject An ArrayObject with the keys being argument names,
|
||||
* and the array values being argument values.
|
||||
*
|
||||
* @see getArgument()
|
||||
* @see setArgument()
|
||||
*/
|
||||
@ -177,40 +187,30 @@ abstract class Message implements IteratorAggregate, Countable
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of arguments.
|
||||
*
|
||||
* @param int $mode The counter mode.
|
||||
* Either COUNT_NORMAL or COUNT_RECURSIVE.
|
||||
* When in normal mode, counts the number of arguments.
|
||||
* When in recursive mode, counts the number of API words
|
||||
* (including the empty word at the end).
|
||||
*
|
||||
* @return int The number of arguments/words.
|
||||
* Counts the number of attributes.
|
||||
*
|
||||
* @return int The number of attributes.
|
||||
*/
|
||||
public function count($mode = COUNT_NORMAL)
|
||||
public function count()
|
||||
{
|
||||
$result = count($this->attributes);
|
||||
if ($mode !== COUNT_NORMAL) {
|
||||
$result += 2/*first+last word*/
|
||||
+ (int)(null !== $this->getTag());
|
||||
}
|
||||
return $result;
|
||||
return count($this->attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an attribute for the message.
|
||||
*
|
||||
*
|
||||
* @param string $name Name of the attribute.
|
||||
* @param string|resource|null $value Value of the attribute as a string or
|
||||
* seekable stream.
|
||||
* Setting the value to NULL removes an argument of this name.
|
||||
* If a seekable stream is provided, it is sent from its current
|
||||
* posistion to its end, and the pointer is seeked back to its current
|
||||
* position to its end, and the pointer is seeked back to its current
|
||||
* position after sending.
|
||||
* Non seekable streams, as well as all other types, are casted to a
|
||||
* string.
|
||||
*
|
||||
*
|
||||
* @return $this The message object.
|
||||
*
|
||||
* @see getArgument()
|
||||
*/
|
||||
protected function setAttribute($name, $value = '')
|
||||
@ -226,7 +226,7 @@ abstract class Message implements IteratorAggregate, Countable
|
||||
|
||||
/**
|
||||
* Removes all attributes from the message.
|
||||
*
|
||||
*
|
||||
* @return $this The message object.
|
||||
*/
|
||||
protected function removeAllAttributes()
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
*
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -28,7 +29,7 @@ use Exception as E;
|
||||
/**
|
||||
* Exception thrown when encountering something not supported by RouterOS or
|
||||
* this package.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -40,24 +41,30 @@ class NotSupportedException extends E implements Exception
|
||||
|
||||
const CODE_CONTROL_BYTE = 1601;
|
||||
|
||||
const CODE_MENU_MISMATCH = 60000;
|
||||
|
||||
const CODE_ARG_PROHIBITED = 60001;
|
||||
|
||||
/**
|
||||
* @var mixed The unsuppported value.
|
||||
* The unsupported value.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $_value;
|
||||
|
||||
/**
|
||||
* Creates a new NotSupportedException.
|
||||
*
|
||||
* @param string $message The Exception message to throw.
|
||||
* @param int $code The Exception code.
|
||||
* @param \Exception $previous The previous exception used for the exception
|
||||
*
|
||||
* @param string $message The Exception message to throw.
|
||||
* @param int $code The Exception code.
|
||||
* @param E|null $previous The previous exception used for the exception
|
||||
* chaining.
|
||||
* @param mixed $value The unsupported value.
|
||||
* @param mixed $value The unsupported value.
|
||||
*/
|
||||
public function __construct(
|
||||
$message,
|
||||
$code = 0,
|
||||
$previous = null,
|
||||
E $previous = null,
|
||||
$value = null
|
||||
) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
@ -66,7 +73,7 @@ class NotSupportedException extends E implements Exception
|
||||
|
||||
/**
|
||||
* Gets the unsupported value.
|
||||
*
|
||||
*
|
||||
* @return mixed The unsupported value.
|
||||
*/
|
||||
public function getValue()
|
||||
@ -79,7 +86,7 @@ class NotSupportedException extends E implements Exception
|
||||
|
||||
/**
|
||||
* Returns a string representation of the exception.
|
||||
*
|
||||
*
|
||||
* @return string The exception as a string.
|
||||
*/
|
||||
public function __toString()
|
||||
|
43
system/autoload/PEAR2/Net/RouterOS/ParserException.php
Normal file
43
system/autoload/PEAR2/Net/RouterOS/ParserException.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
* The namespace declaration.
|
||||
*/
|
||||
namespace PEAR2\Net\RouterOS;
|
||||
|
||||
/**
|
||||
* Base of this class.
|
||||
*/
|
||||
use DomainException;
|
||||
|
||||
/**
|
||||
* Exception thrown when a value can't be parsed properly.
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
class ParserException extends DomainException implements Exception
|
||||
{
|
||||
const CODE_DATETIME = 1;
|
||||
const CODE_DATEINTERVAL = 2;
|
||||
const CODE_ARRAY = 3;
|
||||
}
|
@ -2,17 +2,18 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
*
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -27,7 +28,7 @@ use PEAR2\Net\Transmitter as T;
|
||||
|
||||
/**
|
||||
* Represents a query for RouterOS requests.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -41,31 +42,35 @@ class Query
|
||||
* Checks if the property exists.
|
||||
*/
|
||||
const OP_EX = '';
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the property does not exist.
|
||||
*/
|
||||
const OP_NEX = '-';
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the property equals a certain value.
|
||||
*/
|
||||
const OP_EQ = '=';
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the property is less than a certain value.
|
||||
*/
|
||||
const OP_LT = '<';
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the property is greather than a certain value.
|
||||
* Checks if the property is greater than a certain value.
|
||||
*/
|
||||
const OP_GT = '>';
|
||||
|
||||
/**
|
||||
* @var array An array of the words forming the query. Each value is an
|
||||
* array with the first member being the predicate (operator and name),
|
||||
* and the second member being the value for the predicate.
|
||||
* An array of the words forming the query.
|
||||
*
|
||||
* Each value is an array with the first member being the predicate
|
||||
* (operator and name), and the second member being the value
|
||||
* for the predicate.
|
||||
*
|
||||
* @var array<string,string|null>[]
|
||||
*/
|
||||
protected $words = array();
|
||||
|
||||
@ -73,16 +78,16 @@ class Query
|
||||
* This class is not to be instantiated normally, but by static methods
|
||||
* instead. Use {@link static::where()} to create an instance of it.
|
||||
*/
|
||||
private function __construct()
|
||||
protected function __construct()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the operator of a condition.
|
||||
*
|
||||
*
|
||||
* @param string $operator The operator to sanitize.
|
||||
*
|
||||
*
|
||||
* @return string The sanitized operator.
|
||||
*/
|
||||
protected static function sanitizeOperator($operator)
|
||||
@ -107,18 +112,18 @@ class Query
|
||||
|
||||
/**
|
||||
* Creates a new query with an initial condition.
|
||||
*
|
||||
*
|
||||
* @param string $name The name of the property to test.
|
||||
* @param string|resource|null $value Value of the property as a string
|
||||
* or seekable stream. Not required for existence tests.
|
||||
* If a seekable stream is provided, it is sent from its current
|
||||
* posistion to its end, and the pointer is seeked back to its current
|
||||
* position to its end, and the pointer is seeked back to its current
|
||||
* position after sending.
|
||||
* Non seekable streams, as well as all other types, are casted to a
|
||||
* string.
|
||||
* @param string $operator One of the OP_* constants.
|
||||
* Describes the operation to perform.
|
||||
*
|
||||
*
|
||||
* @return static A new query object.
|
||||
*/
|
||||
public static function where(
|
||||
@ -132,7 +137,7 @@ class Query
|
||||
|
||||
/**
|
||||
* Negates the query.
|
||||
*
|
||||
*
|
||||
* @return $this The query object.
|
||||
*/
|
||||
public function not()
|
||||
@ -143,18 +148,18 @@ class Query
|
||||
|
||||
/**
|
||||
* Adds a condition as an alternative to the query.
|
||||
*
|
||||
*
|
||||
* @param string $name The name of the property to test.
|
||||
* @param string|resource|null $value Value of the property as a string
|
||||
* or seekable stream. Not required for existence tests.
|
||||
* If a seekable stream is provided, it is sent from its current
|
||||
* posistion to its end, and the pointer is seeked back to its current
|
||||
* position to its end, and the pointer is seeked back to its current
|
||||
* position after sending.
|
||||
* Non seekable streams, as well as all other types, are casted to a
|
||||
* string.
|
||||
* @param string $operator One of the OP_* constants.
|
||||
* Describes the operation to perform.
|
||||
*
|
||||
*
|
||||
* @return $this The query object.
|
||||
*/
|
||||
public function orWhere($name, $value = null, $operator = self::OP_EX)
|
||||
@ -165,18 +170,18 @@ class Query
|
||||
|
||||
/**
|
||||
* Adds a condition in addition to the query.
|
||||
*
|
||||
*
|
||||
* @param string $name The name of the property to test.
|
||||
* @param string|resource|null $value Value of the property as a string
|
||||
* or seekable stream. Not required for existence tests.
|
||||
* If a seekable stream is provided, it is sent from its current
|
||||
* posistion to its end, and the pointer is seeked back to its current
|
||||
* position to its end, and the pointer is seeked back to its current
|
||||
* position after sending.
|
||||
* Non seekable streams, as well as all other types, are casted to a
|
||||
* string.
|
||||
* @param string $operator One of the OP_* constants.
|
||||
* Describes the operation to perform.
|
||||
*
|
||||
*
|
||||
* @return $this The query object.
|
||||
*/
|
||||
public function andWhere($name, $value = null, $operator = self::OP_EX)
|
||||
@ -187,9 +192,9 @@ class Query
|
||||
|
||||
/**
|
||||
* Sends the query over a communicator.
|
||||
*
|
||||
*
|
||||
* @param Communicator $com The communicator to send the query over.
|
||||
*
|
||||
*
|
||||
* @return int The number of bytes sent.
|
||||
*/
|
||||
public function send(Communicator $com)
|
||||
@ -205,12 +210,12 @@ class Query
|
||||
|
||||
/**
|
||||
* Sends the query over a communicator.
|
||||
*
|
||||
*
|
||||
* The only difference with the non private equivalent is that this one does
|
||||
* not do locking.
|
||||
*
|
||||
*
|
||||
* @param Communicator $com The communicator to send the query over.
|
||||
*
|
||||
*
|
||||
* @return int The number of bytes sent.
|
||||
*/
|
||||
private function _send(Communicator $com)
|
||||
@ -239,20 +244,53 @@ class Query
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the query.
|
||||
*
|
||||
* Verifies the query against a communicator, i.e. whether the query
|
||||
* could successfully be sent (assuming the connection is still opened).
|
||||
*
|
||||
* @param Communicator $com The Communicator to check against.
|
||||
*
|
||||
* @return $this The query object itself.
|
||||
*
|
||||
* @throws LengthException If the resulting length of an API word is not
|
||||
* supported.
|
||||
*/
|
||||
public function verify(Communicator $com)
|
||||
{
|
||||
foreach ($this->words as $queryWord) {
|
||||
list($predicate, $value) = $queryWord;
|
||||
if (null === $value) {
|
||||
$com::verifyLengthSupport(strlen('?' . $predicate));
|
||||
} elseif (is_string($value)) {
|
||||
$com::verifyLengthSupport(
|
||||
strlen('?' . $predicate . '=' . $value)
|
||||
);
|
||||
} else {
|
||||
$com::verifyLengthSupport(
|
||||
strlen('?' . $predicate . '=') +
|
||||
$com::seekableStreamLength($value)
|
||||
);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a condition.
|
||||
*
|
||||
*
|
||||
* @param string $name The name of the property to test.
|
||||
* @param string|resource|null $value Value of the property as a string
|
||||
* or seekable stream. Not required for existence tests.
|
||||
* If a seekable stream is provided, it is sent from its current
|
||||
* posistion to its end, and the pointer is seeked back to its current
|
||||
* position to its end, and the pointer is seeked back to its current
|
||||
* position after sending.
|
||||
* Non seekable streams, as well as all other types, are casted to a
|
||||
* string.
|
||||
* @param string $operator One of the ACTION_* constants.
|
||||
* Describes the operation to perform.
|
||||
*
|
||||
*
|
||||
* @return $this The query object.
|
||||
*/
|
||||
protected function addWhere($name, $value, $operator)
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
*
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -27,12 +28,12 @@ use PEAR2\Cache\SHM;
|
||||
|
||||
/**
|
||||
* A RouterOS registry.
|
||||
*
|
||||
*
|
||||
* Provides functionality for managing the request/response flow. Particularly
|
||||
* useful in persistent connections.
|
||||
*
|
||||
*
|
||||
* Note that this class is not meant to be called directly.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -42,28 +43,36 @@ use PEAR2\Cache\SHM;
|
||||
class Registry
|
||||
{
|
||||
/**
|
||||
* @var SHM The storage.
|
||||
* The storage.
|
||||
*
|
||||
* @var SHM
|
||||
*/
|
||||
protected $shm;
|
||||
|
||||
|
||||
/**
|
||||
* @var int ID of request. Populated at first instance in request.
|
||||
* ID of request. Populated at first instance in request.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected static $requestId = -1;
|
||||
|
||||
|
||||
/**
|
||||
* @var int ID to be given to next instance, after incrementing it.
|
||||
* ID to be given to next instance, after incrementing it.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected static $instanceIdSeed = -1;
|
||||
|
||||
|
||||
/**
|
||||
* @var int ID of instance within the request.
|
||||
* ID of instance within the request.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $instanceId;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a registry.
|
||||
*
|
||||
*
|
||||
* @param string $uri An URI to bind the registry to.
|
||||
*/
|
||||
public function __construct($uri)
|
||||
@ -76,16 +85,17 @@ class Registry
|
||||
$this->instanceId = ++self::$instanceIdSeed;
|
||||
$this->shm->add('responseBuffer_' . $this->getOwnershipTag(), array());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a tag.
|
||||
*
|
||||
*
|
||||
* Parses a tag to reveal the ownership part of it, and the original tag.
|
||||
*
|
||||
*
|
||||
* @param string $tag The tag (as received) to parse.
|
||||
*
|
||||
* @return array An array with the first member being the ownership tag, and
|
||||
* the second one being the original tag.
|
||||
*
|
||||
* @return array<int,string|null> An array with
|
||||
* the first member being the ownership tag, and
|
||||
* the second one being the original tag.
|
||||
*/
|
||||
public static function parseTag($tag)
|
||||
{
|
||||
@ -99,10 +109,10 @@ class Registry
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if this instance is the tagless mode owner.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if this instance is the tagless mode owner, FALSE
|
||||
* otherwise.
|
||||
*/
|
||||
@ -114,21 +124,21 @@ class Registry
|
||||
$this->shm->unlock('taglessModeOwner');
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the "tagless mode" setting.
|
||||
*
|
||||
* While in tagless mode, this instance will claim owhership of any
|
||||
*
|
||||
* While in tagless mode, this instance will claim ownership of any
|
||||
* responses without a tag. While not in this mode, any requests without a
|
||||
* tag will be given to all instances.
|
||||
*
|
||||
*
|
||||
* Regardless of mode, if the type of the response is
|
||||
* {@link Response::TYPE_FATAL}, it will be given to all instances.
|
||||
*
|
||||
*
|
||||
* @param bool $taglessMode TRUE to claim tagless ownership, FALSE to
|
||||
* release such ownership, if taken.
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure.
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure.
|
||||
*/
|
||||
public function setTaglessMode($taglessMode)
|
||||
{
|
||||
@ -143,26 +153,26 @@ class Registry
|
||||
&& $this->shm->unlock('taglessModeOwner')
|
||||
&& $this->shm->unlock('taglessMode'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the ownership tag for this instance.
|
||||
*
|
||||
* @return string The ownership tag for this registry instance.
|
||||
*
|
||||
* @return string The ownership tag for this registry instance.
|
||||
*/
|
||||
public function getOwnershipTag()
|
||||
{
|
||||
return self::$requestId . '_' . $this->instanceId . '__';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a response to the registry.
|
||||
*
|
||||
*
|
||||
* @param Response $response The response to add. The caller of this
|
||||
* function is responsible for ensuring that the ownership tag and the
|
||||
* original tag are separated, so that only the original one remains in
|
||||
* the response.
|
||||
* @param string $ownershipTag The ownership tag that the response had.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if the request was added to its buffer, FALSE if
|
||||
* this instance owns the response, and therefore doesn't need to add
|
||||
* the response to its buffer.
|
||||
@ -175,7 +185,7 @@ class Registry
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (null === $ownershipTag) {
|
||||
$this->shm->lock('taglessModeOwner');
|
||||
if ($this->shm->exists('taglessModeOwner')
|
||||
@ -194,18 +204,18 @@ class Registry
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->_add($response, 'responseBuffer_' . $ownershipTag);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a response to a buffer.
|
||||
*
|
||||
*
|
||||
* @param Response $response The response to add.
|
||||
* @param string $targetBufferName The name of the buffer to add the
|
||||
* response to.
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _add(Response $response, $targetBufferName)
|
||||
@ -217,11 +227,11 @@ class Registry
|
||||
$this->shm->unlock($targetBufferName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the next response from this instance's buffer.
|
||||
*
|
||||
* @return Response|null The next response, or NULL if there isn't one.
|
||||
*
|
||||
* @return Response|null The next response, or NULL if there isn't one.
|
||||
*/
|
||||
public function getNextResponse()
|
||||
{
|
||||
@ -239,13 +249,13 @@ class Registry
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes the registry.
|
||||
*
|
||||
*
|
||||
* Closes the registry, meaning that all buffers are cleared.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
@ -253,12 +263,12 @@ class Registry
|
||||
self::$instanceIdSeed = -1;
|
||||
$this->shm->clear();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a buffer.
|
||||
*
|
||||
*
|
||||
* @param string $targetBufferName The buffer to remove.
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _close($targetBufferName)
|
||||
@ -268,9 +278,9 @@ class Registry
|
||||
$this->shm->unlock($targetBufferName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes this instance's buffer.
|
||||
* Removes this instance's buffer.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
*
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -27,7 +28,7 @@ use PEAR2\Net\Transmitter as T;
|
||||
|
||||
/**
|
||||
* Represents a RouterOS request.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -38,23 +39,27 @@ class Request extends Message
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string The command to be executed.
|
||||
* The command to be executed.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_command;
|
||||
|
||||
/**
|
||||
* @var Query A query for the command.
|
||||
* A query for the command.
|
||||
*
|
||||
* @var Query
|
||||
*/
|
||||
private $_query;
|
||||
|
||||
/**
|
||||
* Creates a request to send to RouterOS.
|
||||
*
|
||||
* @param string $command The command to send. Can also contain arguments
|
||||
* expressed in a shell-like syntax.
|
||||
* @param Query $query A query to associate with the request.
|
||||
* @param string $tag The tag for the request.
|
||||
*
|
||||
*
|
||||
* @param string $command The command to send.
|
||||
* Can also contain arguments expressed in a shell-like syntax.
|
||||
* @param Query|null $query A query to associate with the request.
|
||||
* @param string|null $tag The tag for the request.
|
||||
*
|
||||
* @see setCommand()
|
||||
* @see setArgument()
|
||||
* @see setTag()
|
||||
@ -75,20 +80,20 @@ class Request extends Message
|
||||
$this->setQuery($query);
|
||||
$this->setTag($tag);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A shorthand gateway.
|
||||
*
|
||||
*
|
||||
* This is a magic PHP method that allows you to call the object as a
|
||||
* function. Depending on the argument given, one of the other functions in
|
||||
* the class is invoked and its returned value is returned by this function.
|
||||
*
|
||||
*
|
||||
* @param Query|Communicator|string|null $arg A {@link Query} to associate
|
||||
* the request with, a {@link Communicator} to send the request over,
|
||||
* an argument to get the value of, or NULL to get the tag. If a
|
||||
* second argument is provided, this becomes the name of the argument to
|
||||
* set the value of, and the second argument is the value to set.
|
||||
*
|
||||
*
|
||||
* @return string|resource|int|$this Whatever the long form
|
||||
* function returns.
|
||||
*/
|
||||
@ -108,14 +113,15 @@ class Request extends Message
|
||||
|
||||
/**
|
||||
* Sets the command to send to RouterOS.
|
||||
*
|
||||
*
|
||||
* Sets the command to send to RouterOS. The command can use the API or CLI
|
||||
* syntax of RouterOS, but either way, it must be absolute (begin with a
|
||||
* "/") and without arguments.
|
||||
*
|
||||
*
|
||||
* @param string $command The command to send.
|
||||
*
|
||||
*
|
||||
* @return $this The request object.
|
||||
*
|
||||
* @see getCommand()
|
||||
* @see setArgument()
|
||||
*/
|
||||
@ -161,10 +167,11 @@ class Request extends Message
|
||||
|
||||
/**
|
||||
* Gets the command that will be send to RouterOS.
|
||||
*
|
||||
*
|
||||
* Gets the command that will be send to RouterOS in its API syntax.
|
||||
*
|
||||
*
|
||||
* @return string The command to send.
|
||||
*
|
||||
* @see setCommand()
|
||||
*/
|
||||
public function getCommand()
|
||||
@ -174,11 +181,12 @@ class Request extends Message
|
||||
|
||||
/**
|
||||
* Sets the query to send with the command.
|
||||
*
|
||||
* @param Query $query The query to be set. Setting NULL will remove the
|
||||
* currently associated query.
|
||||
*
|
||||
*
|
||||
* @param Query|null $query The query to be set.
|
||||
* Setting NULL will remove the currently associated query.
|
||||
*
|
||||
* @return $this The request object.
|
||||
*
|
||||
* @see getQuery()
|
||||
*/
|
||||
public function setQuery(Query $query = null)
|
||||
@ -189,8 +197,9 @@ class Request extends Message
|
||||
|
||||
/**
|
||||
* Gets the currently associated query
|
||||
*
|
||||
* @return Query The currently associated query.
|
||||
*
|
||||
* @return Query|null The currently associated query.
|
||||
*
|
||||
* @see setQuery()
|
||||
*/
|
||||
public function getQuery()
|
||||
@ -200,13 +209,14 @@ class Request extends Message
|
||||
|
||||
/**
|
||||
* Sets the tag to associate the request with.
|
||||
*
|
||||
*
|
||||
* Sets the tag to associate the request with. Setting NULL erases the
|
||||
* currently set tag.
|
||||
*
|
||||
* @param string $tag The tag to set.
|
||||
*
|
||||
*
|
||||
* @param string|null $tag The tag to set.
|
||||
*
|
||||
* @return $this The request object.
|
||||
*
|
||||
* @see getTag()
|
||||
*/
|
||||
public function setTag($tag)
|
||||
@ -216,18 +226,19 @@ class Request extends Message
|
||||
|
||||
/**
|
||||
* Sets an argument for the request.
|
||||
*
|
||||
*
|
||||
* @param string $name Name of the argument.
|
||||
* @param string|resource|null $value Value of the argument as a string or
|
||||
* seekable stream.
|
||||
* Setting the value to NULL removes an argument of this name.
|
||||
* If a seekable stream is provided, it is sent from its current
|
||||
* posistion to its end, and the pointer is seeked back to its current
|
||||
* position to its end, and the pointer is seeked back to its current
|
||||
* position after sending.
|
||||
* Non seekable streams, as well as all other types, are casted to a
|
||||
* string.
|
||||
*
|
||||
*
|
||||
* @return $this The request object.
|
||||
*
|
||||
* @see getArgument()
|
||||
*/
|
||||
public function setArgument($name, $value = '')
|
||||
@ -237,11 +248,12 @@ class Request extends Message
|
||||
|
||||
/**
|
||||
* Gets the value of an argument.
|
||||
*
|
||||
*
|
||||
* @param string $name The name of the argument.
|
||||
*
|
||||
*
|
||||
* @return string|resource|null The value of the specified argument.
|
||||
* Returns NULL if such an argument is not set.
|
||||
*
|
||||
* @see setAttribute()
|
||||
*/
|
||||
public function getArgument($name)
|
||||
@ -251,7 +263,7 @@ class Request extends Message
|
||||
|
||||
/**
|
||||
* Removes all arguments from the request.
|
||||
*
|
||||
*
|
||||
* @return $this The request object.
|
||||
*/
|
||||
public function removeAllArguments()
|
||||
@ -261,11 +273,12 @@ class Request extends Message
|
||||
|
||||
/**
|
||||
* Sends a request over a communicator.
|
||||
*
|
||||
* @param Communicator $com The communicator to send the request over.
|
||||
* @param Registry $reg An optional registry to sync the request with.
|
||||
*
|
||||
*
|
||||
* @param Communicator $com The communicator to send the request over.
|
||||
* @param Registry|null $reg An optional registry to sync the request with.
|
||||
*
|
||||
* @return int The number of bytes sent.
|
||||
*
|
||||
* @see Client::sendSync()
|
||||
* @see Client::sendAsync()
|
||||
*/
|
||||
@ -291,13 +304,14 @@ class Request extends Message
|
||||
|
||||
/**
|
||||
* Sends a request over a communicator.
|
||||
*
|
||||
*
|
||||
* The only difference with the non private equivalent is that this one does
|
||||
* not do locking.
|
||||
*
|
||||
*
|
||||
* @param Communicator $com The communicator to send the request over.
|
||||
*
|
||||
*
|
||||
* @return int The number of bytes sent.
|
||||
*
|
||||
* @see Client::sendSync()
|
||||
* @see Client::sendAsync()
|
||||
*/
|
||||
@ -329,19 +343,53 @@ class Request extends Message
|
||||
$bytes += $com->sendWord('');
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies the request.
|
||||
*
|
||||
* Verifies the request against a communicator, i.e. whether the request
|
||||
* could successfully be sent (assuming the connection is still opened).
|
||||
*
|
||||
* @param Communicator $com The Communicator to check against.
|
||||
*
|
||||
* @return $this The request object itself.
|
||||
*
|
||||
* @throws LengthException If the resulting length of an API word is not
|
||||
* supported.
|
||||
*/
|
||||
public function verify(Communicator $com)
|
||||
{
|
||||
$com::verifyLengthSupport(strlen($this->getCommand()));
|
||||
$com::verifyLengthSupport(strlen('.tag=' . (string)$this->getTag()));
|
||||
foreach ($this->attributes as $name => $value) {
|
||||
if (is_string($value)) {
|
||||
$com::verifyLengthSupport(strlen('=' . $name . '=' . $value));
|
||||
} else {
|
||||
$com::verifyLengthSupport(
|
||||
strlen('=' . $name . '=') +
|
||||
$com::seekableStreamLength($value)
|
||||
);
|
||||
}
|
||||
}
|
||||
$query = $this->getQuery();
|
||||
if ($query instanceof Query) {
|
||||
$query->verify($com);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the arguments of a command.
|
||||
*
|
||||
*
|
||||
* @param string $string The argument string to parse.
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function parseArgumentString($string)
|
||||
{
|
||||
/*
|
||||
* Grammar:
|
||||
*
|
||||
*
|
||||
* <arguments> := (<<\s+>>, <argument>)*,
|
||||
* <argument> := <name>, <value>?
|
||||
* <name> := <<[^\=\s]+>>
|
||||
@ -349,7 +397,7 @@ class Request extends Message
|
||||
* <quotedString> := <<">>, <<([^"]|\\"|\\\\)*>>, <<">>
|
||||
* <unquotedString> := <<\S+>>
|
||||
*/
|
||||
|
||||
|
||||
$token = '';
|
||||
$name = null;
|
||||
while ($string = substr($string, strlen($token))) {
|
||||
@ -394,10 +442,10 @@ class Request extends Message
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (null !== $name && ('' !== ($name = trim($name)))) {
|
||||
$this->setArgument($name, '');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
*
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -32,7 +33,7 @@ use Exception as E;
|
||||
|
||||
/**
|
||||
* Represents a RouterOS response.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -41,22 +42,22 @@ use Exception as E;
|
||||
*/
|
||||
class Response extends Message
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* The last response for a request.
|
||||
*/
|
||||
const TYPE_FINAL = '!done';
|
||||
|
||||
|
||||
/**
|
||||
* A response with data.
|
||||
*/
|
||||
const TYPE_DATA = '!re';
|
||||
|
||||
|
||||
/**
|
||||
* A response signifying error.
|
||||
*/
|
||||
const TYPE_ERROR = '!trap';
|
||||
|
||||
|
||||
/**
|
||||
* A response signifying a fatal error, due to which the connection would be
|
||||
* terminated.
|
||||
@ -64,28 +65,32 @@ class Response extends Message
|
||||
const TYPE_FATAL = '!fatal';
|
||||
|
||||
/**
|
||||
* @var array An array of unrecognized words in network order.
|
||||
* An array of unrecognized words in network order.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $unrecognizedWords = array();
|
||||
|
||||
/**
|
||||
* @var string The response type.
|
||||
* The response type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_type;
|
||||
|
||||
/**
|
||||
* Extracts a new response from a communicator.
|
||||
*
|
||||
* @param Communicator $com The communicator from which to extract
|
||||
*
|
||||
* @param Communicator $com The communicator from which to extract
|
||||
* the new response.
|
||||
* @param bool $asStream Whether to populate the argument values
|
||||
* @param bool $asStream Whether to populate the argument values
|
||||
* with streams instead of strings.
|
||||
* @param int $sTimeout If a response is not immediatly
|
||||
* available, wait this many seconds. If NULL, wait indefinetly.
|
||||
* @param int $usTimeout Microseconds to add to the waiting time.
|
||||
* @param Registry $reg An optional registry to sync the
|
||||
* @param int $sTimeout If a response is not immediately
|
||||
* available, wait this many seconds. If NULL, wait indefinitely.
|
||||
* @param int|null $usTimeout Microseconds to add to the waiting time.
|
||||
* @param Registry|null $reg An optional registry to sync the
|
||||
* response with.
|
||||
*
|
||||
*
|
||||
* @see getType()
|
||||
* @see getArgument()
|
||||
*/
|
||||
@ -120,12 +125,12 @@ class Response extends Message
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->_type = $response->_type;
|
||||
$this->attributes = $response->attributes;
|
||||
$this->unrecognizedWords = $response->unrecognizedWords;
|
||||
$this->setTag($response->getTag());
|
||||
|
||||
|
||||
if (!$asStream) {
|
||||
foreach ($this->attributes as $name => $value) {
|
||||
$this->setAttribute(
|
||||
@ -139,23 +144,23 @@ class Response extends Message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extracts a new response from a communicator.
|
||||
*
|
||||
*
|
||||
* This is the function that performs the actual receiving, while the
|
||||
* constructor is also involved in locks and registry sync.
|
||||
*
|
||||
*
|
||||
* @param Communicator $com The communicator from which to extract
|
||||
* the new response.
|
||||
* @param bool $asStream Whether to populate the argument values
|
||||
* with streams instead of strings.
|
||||
* @param int $sTimeout If a response is not immediatly
|
||||
* available, wait this many seconds. If NULL, wait indefinetly.
|
||||
* @param int $sTimeout If a response is not immediately
|
||||
* available, wait this many seconds. If NULL, wait indefinitely.
|
||||
* Note that if an empty sentence is received, the timeout will be
|
||||
* reset for another sentence receiving.
|
||||
* @param int $usTimeout Microseconds to add to the waiting time.
|
||||
*
|
||||
* @param int|null $usTimeout Microseconds to add to the waiting time.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _receive(
|
||||
@ -228,12 +233,13 @@ class Response extends Message
|
||||
|
||||
/**
|
||||
* Sets the response type.
|
||||
*
|
||||
*
|
||||
* Sets the response type. Valid values are the TYPE_* constants.
|
||||
*
|
||||
*
|
||||
* @param string $type The new response type.
|
||||
*
|
||||
*
|
||||
* @return $this The response object.
|
||||
*
|
||||
* @see getType()
|
||||
*/
|
||||
protected function setType($type)
|
||||
@ -257,8 +263,9 @@ class Response extends Message
|
||||
|
||||
/**
|
||||
* Gets the response type.
|
||||
*
|
||||
*
|
||||
* @return string The response type.
|
||||
*
|
||||
* @see setType()
|
||||
*/
|
||||
public function getType()
|
||||
@ -268,12 +275,13 @@ class Response extends Message
|
||||
|
||||
/**
|
||||
* Gets the value of an argument.
|
||||
*
|
||||
*
|
||||
* @param string $name The name of the argument.
|
||||
*
|
||||
*
|
||||
* @return string|resource|null The value of the specified argument.
|
||||
* Returns NULL if such an argument is not set.
|
||||
* @deprecated 1.0.0b5 Use {@link static::getProperty()} instead.
|
||||
*
|
||||
* @deprecated 1.0.0b5 Use {@link static::getProperty()} instead.
|
||||
* This method will be removed upon final release, and is currently
|
||||
* left standing merely because it can't be easily search&replaced in
|
||||
* existing code, due to the fact the name "getArgument()" is shared
|
||||
@ -293,9 +301,9 @@ class Response extends Message
|
||||
|
||||
/**
|
||||
* Gets the value of a property.
|
||||
*
|
||||
*
|
||||
* @param string $name The name of the property.
|
||||
*
|
||||
*
|
||||
* @return string|resource|null The value of the specified property.
|
||||
* Returns NULL if such a property is not set.
|
||||
*/
|
||||
@ -306,30 +314,11 @@ class Response extends Message
|
||||
|
||||
/**
|
||||
* Gets a list of unrecognized words.
|
||||
*
|
||||
* @return array The list of unrecognized words.
|
||||
*
|
||||
* @return string[] The list of unrecognized words.
|
||||
*/
|
||||
public function getUnrecognizedWords()
|
||||
{
|
||||
return $this->unrecognizedWords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of arguments or words.
|
||||
*
|
||||
* @param int $mode The counter mode.
|
||||
* Either COUNT_NORMAL or COUNT_RECURSIVE.
|
||||
* When in normal mode, counts the number of arguments.
|
||||
* When in recursive mode, counts the number of API words.
|
||||
*
|
||||
* @return int The number of arguments/words.
|
||||
*/
|
||||
public function count($mode = COUNT_NORMAL)
|
||||
{
|
||||
$result = parent::count($mode);
|
||||
if ($mode !== COUNT_NORMAL) {
|
||||
$result += count($this->unrecognizedWords);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
*
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -37,13 +38,13 @@ use SeekableIterator;
|
||||
|
||||
/**
|
||||
* Represents a collection of RouterOS responses.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*
|
||||
*
|
||||
* @method string getType()
|
||||
* Calls {@link Response::getType()}
|
||||
* on the response pointed by the pointer.
|
||||
@ -59,61 +60,88 @@ use SeekableIterator;
|
||||
*/
|
||||
class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @var array An array with all {@link Response} objects.
|
||||
* An array with all {@link Response} objects.
|
||||
*
|
||||
* An array with all Response objects.
|
||||
*
|
||||
* @var Response[]
|
||||
*/
|
||||
protected $responses = array();
|
||||
|
||||
|
||||
/**
|
||||
* @var array An array with each {@link Response} object's type.
|
||||
* An array with each Response object's type.
|
||||
*
|
||||
* An array with each {@link Response} object's type.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $responseTypes = array();
|
||||
|
||||
|
||||
/**
|
||||
* @var array An array with each {@link Response} object's tag.
|
||||
* An array with each Response object's tag.
|
||||
*
|
||||
* An array with each {@link Response} object's tag.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $responseTags = array();
|
||||
|
||||
/**
|
||||
* @var array An array with positions of responses, based on an property
|
||||
* name. The name of each property is the array key, and the array value
|
||||
* is another array where the key is the value for that property, and
|
||||
* the value is the posistion of the response. For performance reasons,
|
||||
* each key is built only when {@link static::setIndex()} is called with
|
||||
* that property, and remains available for the lifetime of this
|
||||
* collection.
|
||||
* An array with positions of responses, based on an property name.
|
||||
*
|
||||
* The name of each property is the array key, and the array value
|
||||
* is another array where the key is the value for that property, and
|
||||
* the value is the position of the response. For performance reasons,
|
||||
* each key is built only when {@link static::setIndex()} is called with
|
||||
* that property, and remains available for the lifetime of this collection.
|
||||
*
|
||||
* @var array<string,array<string,int>>
|
||||
*/
|
||||
protected $responsesIndex = array();
|
||||
|
||||
|
||||
/**
|
||||
* @var array An array with all distinct properties across all
|
||||
* {@link Response} objects. Created at the first call of
|
||||
* {@link static::getPropertyMap()}.
|
||||
* An array with all distinct properties.
|
||||
*
|
||||
* An array with all distinct properties across all {@link Response}
|
||||
* objects. Created at the first call of {@link static::getPropertyMap()}.
|
||||
*
|
||||
* @var array<string,int[]>
|
||||
*/
|
||||
protected $propertyMap = null;
|
||||
|
||||
|
||||
/**
|
||||
* @var int A pointer, as required by SeekableIterator.
|
||||
* A pointer, as required by SeekableIterator.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $position = 0;
|
||||
|
||||
/**
|
||||
* @var string|null Name of property to use as index. NULL when disabled.
|
||||
* Name of property to use as index
|
||||
*
|
||||
* NULL when disabled.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $index = null;
|
||||
|
||||
/**
|
||||
* @var array Criterias used by {@link compare()} to determine the order
|
||||
* between two respones. See {@link orderBy()} for a detailed
|
||||
* description of this array's format.
|
||||
* Compare criteria.
|
||||
*
|
||||
* Used by {@link static::compare()} to determine the order between
|
||||
* two responses. See {@link static::orderBy()} for a detailed description
|
||||
* of this array's format.
|
||||
*
|
||||
* @var string[]|array<string,null|int|array<int|callable>>
|
||||
*/
|
||||
protected $compareBy = array();
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new collection.
|
||||
*
|
||||
* @param array $responses An array of responses, in network order.
|
||||
*
|
||||
* @param Response[] $responses An array of responses, in network order.
|
||||
*/
|
||||
public function __construct(array $responses)
|
||||
{
|
||||
@ -129,16 +157,16 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* A shorthand gateway.
|
||||
*
|
||||
*
|
||||
* This is a magic PHP method that allows you to call the object as a
|
||||
* function. Depending on the argument given, one of the other functions in
|
||||
* the class is invoked and its returned value is returned by this function.
|
||||
*
|
||||
*
|
||||
* @param int|string|null $offset The offset of the response to seek to.
|
||||
* If the offset is negative, seek to that relative to the end.
|
||||
* If the collection is indexed, you can also supply a value to seek to.
|
||||
* Setting NULL will get the current response's interator.
|
||||
*
|
||||
* Setting NULL will get the current response's iterator.
|
||||
*
|
||||
* @return Response|ArrayObject The {@link Response} at the specified
|
||||
* offset, the current response's iterator (which is an ArrayObject)
|
||||
* when NULL is given, or FALSE if the offset is invalid
|
||||
@ -153,15 +181,15 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Sets a property to be usable as a key in the collection.
|
||||
*
|
||||
*
|
||||
* @param string|null $name The name of the property to use. Future calls
|
||||
* that accept a position will then also be able to search values of
|
||||
* that property for a matching value.
|
||||
* Specifying NULL will disable such lookups (as is by default).
|
||||
* Note that in case this value occures multiple times within the
|
||||
* Note that in case this value occurs multiple times within the
|
||||
* collection, only the last matching response will be accessible by
|
||||
* that value.
|
||||
*
|
||||
*
|
||||
* @return $this The object itself.
|
||||
*/
|
||||
public function setIndex($name)
|
||||
@ -184,7 +212,7 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Gets the name of the property used as an index.
|
||||
*
|
||||
*
|
||||
* @return string|null Name of property used as index. NULL when disabled.
|
||||
*/
|
||||
public function getIndex()
|
||||
@ -194,11 +222,11 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Gets the whole collection as an array.
|
||||
*
|
||||
*
|
||||
* @param bool $useIndex Whether to use the index values as keys for the
|
||||
* resulting array.
|
||||
*
|
||||
* @return array An array with all responses, in network order.
|
||||
*
|
||||
* @return Response[] An array with all responses, in network order.
|
||||
*/
|
||||
public function toArray($useIndex = false)
|
||||
{
|
||||
@ -215,35 +243,22 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the responses/words in the collection.
|
||||
*
|
||||
* @param int $mode The counter mode.
|
||||
* Either COUNT_NORMAL or COUNT_RECURSIVE.
|
||||
* When in normal mode, counts the number of responses.
|
||||
* When in recursive mode, counts the total number of API words.
|
||||
*
|
||||
* Counts the responses in the collection.
|
||||
*
|
||||
* @return int The number of responses in the collection.
|
||||
*/
|
||||
public function count($mode = COUNT_NORMAL)
|
||||
public function count()
|
||||
{
|
||||
if ($mode !== COUNT_NORMAL) {
|
||||
$result = 0;
|
||||
foreach ($this->responses as $response) {
|
||||
$result += $response->count($mode);
|
||||
}
|
||||
return $result;
|
||||
} else {
|
||||
return count($this->responses);
|
||||
}
|
||||
return count($this->responses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an offset exists.
|
||||
*
|
||||
*
|
||||
* @param int|string $offset The offset to check. If the
|
||||
* collection is indexed, you can also supply a value to check.
|
||||
* Note that negative numeric offsets are NOT accepted.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if the offset exists, FALSE otherwise.
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
@ -255,10 +270,10 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Gets a {@link Response} from a specified offset.
|
||||
*
|
||||
*
|
||||
* @param int|string $offset The offset of the desired response. If the
|
||||
* collection is indexed, you can also supply the value to search for.
|
||||
*
|
||||
*
|
||||
* @return Response The response at the specified offset.
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
@ -272,42 +287,44 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* N/A
|
||||
*
|
||||
*
|
||||
* This method exists only because it is required for ArrayAccess. The
|
||||
* collection is read only.
|
||||
*
|
||||
*
|
||||
* @param int|string $offset N/A
|
||||
* @param Response $value N/A
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* N/A
|
||||
*
|
||||
*
|
||||
* This method exists only because it is required for ArrayAccess. The
|
||||
* collection is read only.
|
||||
*
|
||||
*
|
||||
* @param int|string $offset N/A
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the pointer to 0, and returns the first response.
|
||||
*
|
||||
* @return Response The first response in the collection, or FALSE if the
|
||||
* collection is empty.
|
||||
*
|
||||
* @return Response|false The first response in the collection,
|
||||
* or FALSE if the collection is empty.
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
@ -316,13 +333,13 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Moves the position pointer to a specified position.
|
||||
*
|
||||
*
|
||||
* @param int|string $position The position to move to. If the collection is
|
||||
* indexed, you can also supply a value to move the pointer to.
|
||||
* A non-existent index will move the pointer to "-1".
|
||||
*
|
||||
* @return Response The {@link Response} at the specified position, or FALSE
|
||||
* if the specified position is not valid.
|
||||
*
|
||||
* @return Response|false The {@link Response} at the specified position,
|
||||
* or FALSE if the specified position is not valid.
|
||||
*/
|
||||
public function seek($position)
|
||||
{
|
||||
@ -338,9 +355,9 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Moves the pointer forward by 1, and gets the next response.
|
||||
*
|
||||
* @return Response The next {@link Response} object, or FALSE if the
|
||||
* position is not valid.
|
||||
*
|
||||
* @return Response|false The next {@link Response} object,
|
||||
* or FALSE if the position is not valid.
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
@ -350,9 +367,9 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Gets the response at the current pointer position.
|
||||
*
|
||||
* @return Response The response at the current pointer position, or FALSE
|
||||
* if the position is not valid.
|
||||
*
|
||||
* @return Response|false The response at the current pointer position,
|
||||
* or FALSE if the position is not valid.
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
@ -361,9 +378,9 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Moves the pointer backwards by 1, and gets the previous response.
|
||||
*
|
||||
* @return Response The next {@link Response} object, or FALSE if the
|
||||
* position is not valid.
|
||||
*
|
||||
* @return Response|false The next {@link Response} object,
|
||||
* or FALSE if the position is not valid.
|
||||
*/
|
||||
public function prev()
|
||||
{
|
||||
@ -374,9 +391,9 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
/**
|
||||
* Moves the pointer to the last valid position, and returns the last
|
||||
* response.
|
||||
*
|
||||
* @return Response The last response in the collection, or FALSE if the
|
||||
* collection is empty.
|
||||
*
|
||||
* @return Response|false The last response in the collection,
|
||||
* or FALSE if the collection is empty.
|
||||
*/
|
||||
public function end()
|
||||
{
|
||||
@ -386,9 +403,10 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Gets the key at the current pointer position.
|
||||
*
|
||||
* @return int The key at the current pointer position, i.e. the pointer
|
||||
* position itself, or FALSE if the position is not valid.
|
||||
*
|
||||
* @return int|false The key at the current pointer position,
|
||||
* i.e. the pointer position itself, or FALSE if the position
|
||||
* is not valid.
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
@ -397,7 +415,7 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Checks if the pointer is still pointing to an existing offset.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if the pointer is valid, FALSE otherwise.
|
||||
*/
|
||||
public function valid()
|
||||
@ -407,11 +425,12 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Gets all distinct property names.
|
||||
*
|
||||
*
|
||||
* Gets all distinct property names across all responses.
|
||||
*
|
||||
* @return array An array with all distinct property names as keys, and the
|
||||
* indexes at which they occur as values.
|
||||
*
|
||||
* @return array<string,int[]> An array with
|
||||
* all distinct property names as keys, and
|
||||
* the indexes at which they occur as values.
|
||||
*/
|
||||
public function getPropertyMap()
|
||||
{
|
||||
@ -433,10 +452,10 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Gets all responses of a specified type.
|
||||
*
|
||||
*
|
||||
* @param string $type The response type to filter by. Valid values are the
|
||||
* Response::TYPE_* constants.
|
||||
*
|
||||
*
|
||||
* @return static A new collection with responses of the
|
||||
* specified type.
|
||||
*/
|
||||
@ -451,9 +470,9 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Gets all responses with a specified tag.
|
||||
*
|
||||
*
|
||||
* @param string $tag The tag to filter by.
|
||||
*
|
||||
*
|
||||
* @return static A new collection with responses having the
|
||||
* specified tag.
|
||||
*/
|
||||
@ -468,8 +487,9 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Order resones by criteria.
|
||||
*
|
||||
* @param mixed[] $criteria The criteria to order respones by. It takes the
|
||||
*
|
||||
* @param string[]|array<string,null|int|array<int|callable>> $criteria The
|
||||
* criteria to order responses by. It takes the
|
||||
* form of an array where each key is the name of the property to use
|
||||
* as (N+1)th sorting key. The value of each member can be either NULL
|
||||
* (for that property, sort normally in ascending order), a single sort
|
||||
@ -479,12 +499,12 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
* array functions) or a callback.
|
||||
* If a callback is provided, it must accept two arguments
|
||||
* (the two values to be compared), and return -1, 0 or 1 if the first
|
||||
* value is respectively less than, equal to or greather than the second
|
||||
* value is respectively less than, equal to or greater than the second
|
||||
* one.
|
||||
* Each key of $criteria can also be numeric, in which case the
|
||||
* value is the name of the property, and sorting is done normally in
|
||||
* ascending order.
|
||||
*
|
||||
*
|
||||
* @return static A new collection with the responses sorted in the
|
||||
* specified order.
|
||||
*/
|
||||
@ -498,14 +518,14 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
|
||||
/**
|
||||
* Calls a method of the response pointed by the pointer.
|
||||
*
|
||||
*
|
||||
* Calls a method of the response pointed by the pointer. This is a magic
|
||||
* PHP method, thanks to which any function you call on the collection that
|
||||
* is not defined will be redirected to the response.
|
||||
*
|
||||
*
|
||||
* @param string $method The name of the method to call.
|
||||
* @param array $args The arguments to pass to the method.
|
||||
*
|
||||
*
|
||||
* @return mixed Whatever the called function returns.
|
||||
*/
|
||||
public function __call($method, array $args)
|
||||
@ -517,15 +537,15 @@ class ResponseCollection implements ArrayAccess, SeekableIterator, Countable
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two respones.
|
||||
*
|
||||
* Compares two respones, based on criteria defined in
|
||||
* Compares two responses.
|
||||
*
|
||||
* Compares two responses, based on criteria defined in
|
||||
* {@link static::$compareBy}.
|
||||
*
|
||||
*
|
||||
* @param Response $itemA The response to compare.
|
||||
* @param Response $itemB The response to compare $a against.
|
||||
*
|
||||
* @return int Returns 0 if the two respones are equal according to every
|
||||
*
|
||||
* @return int Returns 0 if the two responses are equal according to every
|
||||
* criteria specified, -1 if $a should be placed before $b, and 1 if $b
|
||||
* should be placed before $a.
|
||||
*/
|
||||
|
127
system/autoload/PEAR2/Net/RouterOS/RouterErrorException.php
Normal file
127
system/autoload/PEAR2/Net/RouterOS/RouterErrorException.php
Normal file
@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
* The namespace declaration.
|
||||
*/
|
||||
namespace PEAR2\Net\RouterOS;
|
||||
|
||||
/**
|
||||
* Base of this class.
|
||||
*/
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Refered to in the constructor.
|
||||
*/
|
||||
use Exception as E;
|
||||
|
||||
/**
|
||||
* Exception thrown by higher level classes (Util, etc.) when the router
|
||||
* returns an error.
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
class RouterErrorException extends RuntimeException implements Exception
|
||||
{
|
||||
const CODE_ITEM_ERROR = 0x100000;
|
||||
const CODE_SCRIPT_ERROR = 0x200000;
|
||||
const CODE_READ_ERROR = 0x010000;
|
||||
const CODE_WRITE_ERROR = 0x020000;
|
||||
const CODE_EXEC_ERROR = 0x040000;
|
||||
|
||||
const CODE_CACHE_ERROR = 0x100001;
|
||||
const CODE_GET_ERROR = 0x110001;
|
||||
const CODE_GETALL_ERROR = 0x110002;
|
||||
const CODE_ADD_ERROR = 0x120001;
|
||||
const CODE_SET_ERROR = 0x120002;
|
||||
const CODE_REMOVE_ERROR = 0x120004;
|
||||
const CODE_ENABLE_ERROR = 0x120012;
|
||||
const CODE_DISABLE_ERROR = 0x120022;
|
||||
const CODE_COMMENT_ERROR = 0x120042;
|
||||
const CODE_UNSET_ERROR = 0x120082;
|
||||
const CODE_MOVE_ERROR = 0x120107;
|
||||
const CODE_SCRIPT_ADD_ERROR = 0x220001;
|
||||
const CODE_SCRIPT_REMOVE_ERROR = 0x220004;
|
||||
const CODE_SCRIPT_RUN_ERROR = 0x240001;
|
||||
const CODE_SCRIPT_FILE_ERROR = 0x240003;
|
||||
|
||||
/**
|
||||
* The complete response returned by the router.
|
||||
*
|
||||
* NULL when the router was not contacted at all.
|
||||
*
|
||||
* @var ResponseCollection|null
|
||||
*/
|
||||
private $_responses = null;
|
||||
|
||||
/**
|
||||
* Creates a new RouterErrorException.
|
||||
*
|
||||
* @param string $message The Exception message to throw.
|
||||
* @param int $code The Exception code.
|
||||
* @param E|null $previous The previous exception used for
|
||||
* the exception chaining.
|
||||
* @param ResponseCollection|null $responses The complete set responses
|
||||
* returned by the router.
|
||||
*/
|
||||
public function __construct(
|
||||
$message,
|
||||
$code = 0,
|
||||
E $previous = null,
|
||||
ResponseCollection $responses = null
|
||||
) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->_responses = $responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the complete set responses returned by the router.
|
||||
*
|
||||
* @return ResponseCollection|null The complete set responses
|
||||
* returned by the router.
|
||||
*/
|
||||
public function getResponses()
|
||||
{
|
||||
return $this->_responses;
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
// String representation is not reliable in testing
|
||||
|
||||
/**
|
||||
* Returns a string representation of the exception.
|
||||
*
|
||||
* @return string The exception as a string.
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$result = parent::__toString();
|
||||
if ($this->_responses instanceof ResponseCollection) {
|
||||
$result .= "\nResponse collection:\n" .
|
||||
print_r($this->_responses->toArray(), true);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
642
system/autoload/PEAR2/Net/RouterOS/Script.php
Normal file
642
system/autoload/PEAR2/Net/RouterOS/Script.php
Normal file
@ -0,0 +1,642 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
* The namespace declaration.
|
||||
*/
|
||||
namespace PEAR2\Net\RouterOS;
|
||||
|
||||
/**
|
||||
* Values at {@link Script::escapeValue()} can be casted from this type.
|
||||
*/
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* Values at {@link Script::escapeValue()} can be casted from this type.
|
||||
*/
|
||||
use DateInterval;
|
||||
|
||||
/**
|
||||
* Used at {@link Script::escapeValue()} to get the proper time.
|
||||
*/
|
||||
use DateTimeZone;
|
||||
|
||||
/**
|
||||
* Used to reliably write to streams at {@link Script::prepare()}.
|
||||
*/
|
||||
use PEAR2\Net\Transmitter\Stream;
|
||||
|
||||
/**
|
||||
* Used to catch DateTime and DateInterval exceptions at
|
||||
* {@link Script::parseValue()}.
|
||||
*/
|
||||
use Exception as E;
|
||||
|
||||
/**
|
||||
* Scripting class.
|
||||
*
|
||||
* Provides functionality related to parsing and composing RouterOS scripts and
|
||||
* values.
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
class Script
|
||||
{
|
||||
/**
|
||||
* Parses a value from a RouterOS scripting context.
|
||||
*
|
||||
* Turns a value from RouterOS into an equivalent PHP value, based on
|
||||
* determining the type in the same way RouterOS would determine it for a
|
||||
* literal.
|
||||
*
|
||||
* This method is intended to be the very opposite of
|
||||
* {@link static::escapeValue()}. That is, results from that method, if
|
||||
* given to this method, should produce equivalent results.
|
||||
*
|
||||
* @param string $value The value to be parsed.
|
||||
* Must be a literal of a value,
|
||||
* e.g. what {@link static::escapeValue()} will give you.
|
||||
* @param DateTimeZone|null $timezone The timezone which any resulting
|
||||
* DateTime object (either the main value, or values within an array)
|
||||
* will use. Defaults to UTC.
|
||||
*
|
||||
* @return mixed Depending on RouterOS type detected:
|
||||
* - "nil" (the string "[]") or "nothing" (empty string) - NULL.
|
||||
* - "num" - int or double for large values.
|
||||
* - "bool" - a boolean.
|
||||
* - "array" - an array, with the keys and values processed recursively.
|
||||
* - "time" - a {@link DateInterval} object.
|
||||
* - "date" (pseudo type; string in the form "M/j/Y") - a DateTime
|
||||
* object with the specified date, at midnight.
|
||||
* - "datetime" (pseudo type; string in the form "M/j/Y H:i:s") - a
|
||||
* DateTime object with the specified date and time.
|
||||
* - "str" (a quoted string) - a string, with the contents escaped.
|
||||
* - Unrecognized type - casted to a string, unmodified.
|
||||
*/
|
||||
public static function parseValue($value, DateTimeZone $timezone = null)
|
||||
{
|
||||
$value = static::parseValueToSimple($value);
|
||||
if (!is_string($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
try {
|
||||
return static::parseValueToArray($value, $timezone);
|
||||
} catch (ParserException $e) {
|
||||
try {
|
||||
return static::parseValueToDateInterval($value);
|
||||
} catch (ParserException $e) {
|
||||
try {
|
||||
return static::parseValueToDateTime($value, $timezone);
|
||||
} catch (ParserException $e) {
|
||||
return static::parseValueToString($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a RouterOS value into a PHP string.
|
||||
*
|
||||
* @param string $value The value to be parsed.
|
||||
* Must be a literal of a value,
|
||||
* e.g. what {@link static::escapeValue()} will give you.
|
||||
*
|
||||
* @return string If a quoted string is provided, it would be parsed.
|
||||
* Otherwise, the value is casted to a string, and returned unmodified.
|
||||
*/
|
||||
public static function parseValueToString($value)
|
||||
{
|
||||
$value = (string)$value;
|
||||
if ('"' === $value[0] && '"' === $value[strlen($value) - 1]) {
|
||||
return str_replace(
|
||||
array('\"', '\\\\', "\\\n", "\\\r\n", "\\\r"),
|
||||
array('"', '\\'),
|
||||
substr($value, 1, -1)
|
||||
);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a RouterOS value into a PHP simple type.
|
||||
*
|
||||
* Parses a RouterOS value into a PHP simple type. "Simple" types being
|
||||
* scalar types, plus NULL.
|
||||
*
|
||||
* @param string $value The value to be parsed. Must be a literal of a
|
||||
* value, e.g. what {@link static::escapeValue()} will give you.
|
||||
*
|
||||
* @return string|bool|int|double|null Depending on RouterOS type detected:
|
||||
* - "nil" (the string "[]") or "nothing" (empty string) - NULL.
|
||||
* - "num" - int or double for large values.
|
||||
* - "bool" - a boolean.
|
||||
* - Unrecognized type - casted to a string, unmodified.
|
||||
*/
|
||||
public static function parseValueToSimple($value)
|
||||
{
|
||||
$value = (string)$value;
|
||||
|
||||
if (in_array($value, array('', '[]'), true)) {
|
||||
return null;
|
||||
} elseif (in_array($value, array('true', 'false', 'yes', 'no'), true)) {
|
||||
return $value === 'true' || $value === 'yes';
|
||||
} elseif ($value === (string)($num = (int)$value)
|
||||
|| $value === (string)($num = (double)$value)
|
||||
) {
|
||||
return $num;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a RouterOS value into a PHP DateTime object
|
||||
*
|
||||
* Parses a RouterOS value into a PHP DateTime object.
|
||||
*
|
||||
* @param string $value The value to be parsed.
|
||||
* Must be a literal of a value,
|
||||
* e.g. what {@link static::escapeValue()} will give you.
|
||||
* @param DateTimeZone|null $timezone The timezone which the resulting
|
||||
* DateTime object will use. Defaults to UTC.
|
||||
*
|
||||
* @return DateTime Depending on RouterOS type detected:
|
||||
* - "date" (pseudo type; string in the form "M/j/Y") - a DateTime
|
||||
* object with the specified date, at midnight UTC time (regardless
|
||||
* of timezone provided).
|
||||
* - "datetime" (pseudo type; string in the form "M/j/Y H:i:s") - a
|
||||
* DateTime object with the specified date and time,
|
||||
* with the specified timezone.
|
||||
*
|
||||
* @throws ParserException When the value is not of a recognized type.
|
||||
*/
|
||||
public static function parseValueToDateTime(
|
||||
$value,
|
||||
DateTimeZone $timezone = null
|
||||
) {
|
||||
$previous = null;
|
||||
$value = (string)$value;
|
||||
if ('' !== $value && preg_match(
|
||||
'#^
|
||||
(?<mon>jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)
|
||||
/
|
||||
(?<day>\d\d?)
|
||||
/
|
||||
(?<year>\d{4})
|
||||
(?:
|
||||
\s+(?<time>\d{2}\:\d{2}:\d{2})
|
||||
)?
|
||||
$#uix',
|
||||
$value,
|
||||
$date
|
||||
)) {
|
||||
if (!isset($date['time'])) {
|
||||
$date['time'] = '00:00:00';
|
||||
$timezone = new DateTimeZone('UTC');
|
||||
} elseif (null === $timezone) {
|
||||
$timezone = new DateTimeZone('UTC');
|
||||
}
|
||||
try {
|
||||
return new DateTime(
|
||||
$date['year'] .
|
||||
'-' . ucfirst($date['mon']) .
|
||||
"-{$date['day']} {$date['time']}",
|
||||
$timezone
|
||||
);
|
||||
} catch (E $e) {
|
||||
$previous = $e;
|
||||
}
|
||||
}
|
||||
throw new ParserException(
|
||||
'The supplied value can not be converted to a DateTime',
|
||||
ParserException::CODE_DATETIME,
|
||||
$previous
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a RouterOS value into a PHP DateInterval.
|
||||
*
|
||||
* Parses a RouterOS value into a PHP DateInterval.
|
||||
*
|
||||
* @param string $value The value to be parsed. Must be a literal of a
|
||||
* value, e.g. what {@link static::escapeValue()} will give you.
|
||||
*
|
||||
* @return DateInterval The value as a DateInterval object.
|
||||
*
|
||||
* @throws ParserException When the value is not of a recognized type.
|
||||
*/
|
||||
public static function parseValueToDateInterval($value)
|
||||
{
|
||||
$value = (string)$value;
|
||||
if ('' !== $value && preg_match(
|
||||
'/^
|
||||
(?:(\d+)w)?
|
||||
(?:(\d+)d)?
|
||||
(?:(\d+)(?:\:|h))?
|
||||
(?|
|
||||
(\d+)\:
|
||||
(\d*(?:\.\d{1,9})?)
|
||||
|
|
||||
(?:(\d+)m)?
|
||||
(?:(\d+|\d*\.\d{1,9})s)?
|
||||
(?:((?5))ms)?
|
||||
(?:((?5))us)?
|
||||
(?:((?5))ns)?
|
||||
)
|
||||
$/x',
|
||||
$value,
|
||||
$time
|
||||
)) {
|
||||
$days = isset($time[2]) ? (int)$time[2] : 0;
|
||||
if (isset($time[1])) {
|
||||
$days += 7 * (int)$time[1];
|
||||
}
|
||||
if (empty($time[3])) {
|
||||
$time[3] = 0;
|
||||
}
|
||||
if (empty($time[4])) {
|
||||
$time[4] = 0;
|
||||
}
|
||||
if (empty($time[5])) {
|
||||
$time[5] = 0;
|
||||
}
|
||||
|
||||
$subsecondTime = 0.0;
|
||||
//@codeCoverageIgnoreStart
|
||||
// No PHP version currently supports sub-second DateIntervals,
|
||||
// meaning this section is untestable, since no version constraints
|
||||
// can be specified for test inputs.
|
||||
// All inputs currently use integer seconds only, making this
|
||||
// section unreachable during tests.
|
||||
// Nevertheless, this section exists right now, in order to provide
|
||||
// such support as soon as PHP has it.
|
||||
if (!empty($time[6])) {
|
||||
$subsecondTime += ((double)$time[6]) / 1000;
|
||||
}
|
||||
if (!empty($time[7])) {
|
||||
$subsecondTime += ((double)$time[7]) / 1000000;
|
||||
}
|
||||
if (!empty($time[8])) {
|
||||
$subsecondTime += ((double)$time[8]) / 1000000000;
|
||||
}
|
||||
//@codeCoverageIgnoreEnd
|
||||
|
||||
$secondsSpec = $time[5] + $subsecondTime;
|
||||
try {
|
||||
return new DateInterval(
|
||||
"P{$days}DT{$time[3]}H{$time[4]}M{$secondsSpec}S"
|
||||
);
|
||||
//@codeCoverageIgnoreStart
|
||||
// See previous ignored section's note.
|
||||
//
|
||||
// This section is added for backwards compatibility with current
|
||||
// PHP versions, when in the future sub-second support is added.
|
||||
// In that event, the test inputs for older versions will be
|
||||
// expected to get a rounded up result of the sub-second data.
|
||||
} catch (E $e) {
|
||||
$secondsSpec = (int)round($secondsSpec);
|
||||
return new DateInterval(
|
||||
"P{$days}DT{$time[3]}H{$time[4]}M{$secondsSpec}S"
|
||||
);
|
||||
}
|
||||
//@codeCoverageIgnoreEnd
|
||||
}
|
||||
throw new ParserException(
|
||||
'The supplied value can not be converted to DateInterval',
|
||||
ParserException::CODE_DATEINTERVAL
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a RouterOS value into a PHP array.
|
||||
*
|
||||
* Parses a RouterOS value into a PHP array.
|
||||
*
|
||||
* @param string $value The value to be parsed.
|
||||
* Must be a literal of a value,
|
||||
* e.g. what {@link static::escapeValue()} will give you.
|
||||
* @param DateTimeZone|null $timezone The timezone which any resulting
|
||||
* DateTime object within the array will use. Defaults to UTC.
|
||||
*
|
||||
* @return array An array, with the keys and values processed recursively,
|
||||
* the keys with {@link static::parseValueToSimple()},
|
||||
* and the values with {@link static::parseValue()}.
|
||||
*
|
||||
* @throws ParserException When the value is not of a recognized type.
|
||||
*/
|
||||
public static function parseValueToArray(
|
||||
$value,
|
||||
DateTimeZone $timezone = null
|
||||
) {
|
||||
$value = (string)$value;
|
||||
if ('{' === $value[0] && '}' === $value[strlen($value) - 1]) {
|
||||
$value = substr($value, 1, -1);
|
||||
if ('' === $value) {
|
||||
return array();
|
||||
}
|
||||
$parsedValue = preg_split(
|
||||
'/
|
||||
(\"(?:\\\\\\\\|\\\\"|[^"])*\")
|
||||
|
|
||||
(\{[^{}]*(?2)?\})
|
||||
|
|
||||
([^;=]+)
|
||||
/sx',
|
||||
$value,
|
||||
null,
|
||||
PREG_SPLIT_DELIM_CAPTURE
|
||||
);
|
||||
$result = array();
|
||||
$newVal = null;
|
||||
$newKey = null;
|
||||
for ($i = 0, $l = count($parsedValue); $i < $l; ++$i) {
|
||||
switch ($parsedValue[$i]) {
|
||||
case '':
|
||||
break;
|
||||
case ';':
|
||||
if (null === $newKey) {
|
||||
$result[] = $newVal;
|
||||
} else {
|
||||
$result[$newKey] = $newVal;
|
||||
}
|
||||
$newKey = $newVal = null;
|
||||
break;
|
||||
case '=':
|
||||
$newKey = static::parseValueToSimple($parsedValue[$i - 1]);
|
||||
$newVal = static::parseValue($parsedValue[++$i], $timezone);
|
||||
break;
|
||||
default:
|
||||
$newVal = static::parseValue($parsedValue[$i], $timezone);
|
||||
}
|
||||
}
|
||||
if (null === $newKey) {
|
||||
$result[] = $newVal;
|
||||
} else {
|
||||
$result[$newKey] = $newVal;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
throw new ParserException(
|
||||
'The supplied value can not be converted to an array',
|
||||
ParserException::CODE_ARRAY
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a script.
|
||||
*
|
||||
* Prepares a script for eventual execution by prepending parameters as
|
||||
* variables to it.
|
||||
*
|
||||
* This is particularly useful when you're creating scripts that you don't
|
||||
* want to execute right now (as with {@link Util::exec()}, but instead
|
||||
* you want to store it for later execution, perhaps by supplying it to
|
||||
* "/system scheduler".
|
||||
*
|
||||
* @param string|resource $source The source of the script,
|
||||
* as a string or stream. If a stream is provided, reading starts from
|
||||
* the current position to the end of the stream, and the pointer stays
|
||||
* at the end after reading is done.
|
||||
* @param array<string|int,mixed> $params An array of parameters to make
|
||||
* available in the script as local variables.
|
||||
* Variable names are array keys, and variable values are array values.
|
||||
* Array values are automatically processed with
|
||||
* {@link static::escapeValue()}. Streams are also supported, and are
|
||||
* processed in chunks, each with
|
||||
* {@link static::escapeString()} with all bytes being escaped.
|
||||
* Processing starts from the current position to the end of the stream,
|
||||
* and the stream's pointer is left untouched after the reading is done.
|
||||
* Variables with a value of type "nothing" can be declared with a
|
||||
* numeric array key and the variable name as the array value
|
||||
* (that is casted to a string).
|
||||
*
|
||||
* @return resource A new PHP temporary stream with the script as contents,
|
||||
* with the pointer back at the start.
|
||||
*
|
||||
* @see static::append()
|
||||
*/
|
||||
public static function prepare(
|
||||
$source,
|
||||
array $params = array()
|
||||
) {
|
||||
$resultStream = fopen('php://temp', 'r+b');
|
||||
static::append($resultStream, $source, $params);
|
||||
rewind($resultStream);
|
||||
return $resultStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a script.
|
||||
*
|
||||
* Appends a script to an existing stream.
|
||||
*
|
||||
* @param resource $stream An existing stream to write the
|
||||
* resulting script to.
|
||||
* @param string|resource $source The source of the script,
|
||||
* as a string or stream. If a stream is provided, reading starts from
|
||||
* the current position to the end of the stream, and the pointer stays
|
||||
* at the end after reading is done.
|
||||
* @param array<string|int,mixed> $params An array of parameters to make
|
||||
* available in the script as local variables.
|
||||
* Variable names are array keys, and variable values are array values.
|
||||
* Array values are automatically processed with
|
||||
* {@link static::escapeValue()}. Streams are also supported, and are
|
||||
* processed in chunks, each with
|
||||
* {@link static::escapeString()} with all bytes being escaped.
|
||||
* Processing starts from the current position to the end of the stream,
|
||||
* and the stream's pointer is left untouched after the reading is done.
|
||||
* Variables with a value of type "nothing" can be declared with a
|
||||
* numeric array key and the variable name as the array value
|
||||
* (that is casted to a string).
|
||||
*
|
||||
* @return int The number of bytes written to $stream is returned,
|
||||
* and the pointer remains where it was after the write
|
||||
* (i.e. it is not seeked back, even if seeking is supported).
|
||||
*/
|
||||
public static function append(
|
||||
$stream,
|
||||
$source,
|
||||
array $params = array()
|
||||
) {
|
||||
$writer = new Stream($stream, false);
|
||||
$bytes = 0;
|
||||
|
||||
foreach ($params as $pname => $pvalue) {
|
||||
if (is_int($pname)) {
|
||||
$pvalue = static::escapeString((string)$pvalue);
|
||||
$bytes += $writer->send(":local \"{$pvalue}\";\n");
|
||||
continue;
|
||||
}
|
||||
$pname = static::escapeString($pname);
|
||||
$bytes += $writer->send(":local \"{$pname}\" ");
|
||||
if (Stream::isStream($pvalue)) {
|
||||
$reader = new Stream($pvalue, false);
|
||||
$chunkSize = $reader->getChunk(Stream::DIRECTION_RECEIVE);
|
||||
$bytes += $writer->send('"');
|
||||
while ($reader->isAvailable() && $reader->isDataAwaiting()) {
|
||||
$bytes += $writer->send(
|
||||
static::escapeString(fread($pvalue, $chunkSize), true)
|
||||
);
|
||||
}
|
||||
$bytes += $writer->send("\";\n");
|
||||
} else {
|
||||
$bytes += $writer->send(static::escapeValue($pvalue) . ";\n");
|
||||
}
|
||||
}
|
||||
|
||||
$bytes += $writer->send($source);
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a value for a RouterOS scripting context.
|
||||
*
|
||||
* Turns any native PHP value into an equivalent whole value that can be
|
||||
* inserted as part of a RouterOS script.
|
||||
*
|
||||
* DateInterval objects will be casted to RouterOS' "time" type.
|
||||
*
|
||||
* DateTime objects will be casted to a string following the "M/d/Y H:i:s"
|
||||
* format. If the time is exactly midnight (including microseconds), and
|
||||
* the timezone is UTC, the string will include only the "M/d/Y" date.
|
||||
*
|
||||
* Unrecognized types (i.e. resources and other objects) are casted to
|
||||
* strings, and those strings are then escaped.
|
||||
*
|
||||
* @param mixed $value The value to be escaped.
|
||||
*
|
||||
* @return string A string representation that can be directly inserted in a
|
||||
* script as a whole value.
|
||||
*/
|
||||
public static function escapeValue($value)
|
||||
{
|
||||
switch(gettype($value)) {
|
||||
case 'NULL':
|
||||
$value = '[]';
|
||||
break;
|
||||
case 'integer':
|
||||
$value = (string)$value;
|
||||
break;
|
||||
case 'boolean':
|
||||
$value = $value ? 'true' : 'false';
|
||||
break;
|
||||
case 'array':
|
||||
if (0 === count($value)) {
|
||||
$value = '({})';
|
||||
break;
|
||||
}
|
||||
$result = '';
|
||||
foreach ($value as $key => $val) {
|
||||
$result .= ';';
|
||||
if (!is_int($key)) {
|
||||
$result .= static::escapeValue($key) . '=';
|
||||
}
|
||||
$result .= static::escapeValue($val);
|
||||
}
|
||||
$value = '{' . substr($result, 1) . '}';
|
||||
break;
|
||||
case 'object':
|
||||
if ($value instanceof DateTime) {
|
||||
$usec = $value->format('u');
|
||||
$usec = '000000' === $usec ? '' : '.' . $usec;
|
||||
$value = '00:00:00.000000 UTC' === $value->format('H:i:s.u e')
|
||||
? $value->format('M/d/Y')
|
||||
: $value->format('M/d/Y H:i:s') . $usec;
|
||||
}
|
||||
if ($value instanceof DateInterval) {
|
||||
if (false === $value->days || $value->days < 0) {
|
||||
$value = $value->format('%r%dd%H:%I:%S');
|
||||
} else {
|
||||
$value = $value->format('%r%ad%H:%I:%S');
|
||||
}
|
||||
break;
|
||||
}
|
||||
//break; intentionally omitted
|
||||
default:
|
||||
$value = '"' . static::escapeString((string)$value) . '"';
|
||||
break;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a string for a RouterOS scripting context.
|
||||
*
|
||||
* Escapes a string for a RouterOS scripting context. The value can then be
|
||||
* surrounded with quotes at a RouterOS script (or concatenated onto a
|
||||
* larger string first), and you can be sure there won't be any code
|
||||
* injections coming from it.
|
||||
*
|
||||
* By default, for the sake of brevity of the output, ASCII alphanumeric
|
||||
* characters and underscores are left untouched. And for the sake of
|
||||
* character conversion, bytes above 0x7F are also left untouched.
|
||||
*
|
||||
* @param string $value Value to be escaped.
|
||||
* @param bool $full Whether to escape all bytes in the string, including
|
||||
* ASCII alphanumeric characters, underscores and bytes above 0x7F.
|
||||
*
|
||||
* @return string The escaped value.
|
||||
*
|
||||
* @internal Why leave ONLY those ASCII characters and not also others?
|
||||
* Because those can't in any way be mistaken for language constructs,
|
||||
* unlike many other "safe inside strings, but not outside" ASCII
|
||||
* characters, like ",", ".", "+", "-", "~", etc.
|
||||
*/
|
||||
public static function escapeString($value, $full = false)
|
||||
{
|
||||
if ($full) {
|
||||
return self::_escapeCharacters(array($value));
|
||||
}
|
||||
return preg_replace_callback(
|
||||
'/[^\\_A-Za-z0-9\\x80-\\xFF]+/S',
|
||||
array(__CLASS__, '_escapeCharacters'),
|
||||
$value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a character for a RouterOS scripting context.
|
||||
*
|
||||
* Escapes a character for a RouterOS scripting context.
|
||||
* Intended to only be called by {@link self::escapeString()} for the
|
||||
* matching strings.
|
||||
*
|
||||
* @param array $chars The matches array, expected to contain exactly one
|
||||
* member, in which is the whole string to be escaped.
|
||||
*
|
||||
* @return string The escaped characters.
|
||||
*/
|
||||
private static function _escapeCharacters(array $chars)
|
||||
{
|
||||
$result = '';
|
||||
for ($i = 0, $l = strlen($chars[0]); $i < $l; ++$i) {
|
||||
$result .= '\\' . str_pad(
|
||||
strtoupper(dechex(ord($chars[0][$i]))),
|
||||
2,
|
||||
'0',
|
||||
STR_PAD_LEFT
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
@ -2,17 +2,18 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
*
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -27,7 +28,7 @@ use RuntimeException;
|
||||
|
||||
/**
|
||||
* Exception thrown when something goes wrong with the connection.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
/**
|
||||
* RouterOS API client implementation.
|
||||
*
|
||||
|
||||
*
|
||||
* RouterOS is the flag product of the company MikroTik and is a powerful router software. One of its many abilities is to allow control over it via an API. This package provides a client for that API, in turn allowing you to use PHP to control RouterOS hosts.
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0b5
|
||||
* @version 1.0.0b6
|
||||
* @link http://pear2.php.net/PEAR2_Net_RouterOS
|
||||
*/
|
||||
/**
|
||||
@ -20,11 +21,19 @@
|
||||
*/
|
||||
namespace PEAR2\Net\RouterOS;
|
||||
|
||||
/**
|
||||
* The base for this exception.
|
||||
*/
|
||||
use UnexpectedValueException as U;
|
||||
|
||||
/**
|
||||
* Used in $previous.
|
||||
*/
|
||||
use Exception as E;
|
||||
|
||||
/**
|
||||
* Exception thrown when encountering an invalid value in a function argument.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_RouterOS
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -38,23 +47,25 @@ class UnexpectedValueException extends U implements Exception
|
||||
const CODE_RESPONSE_TYPE_UNKNOWN = 50100;
|
||||
|
||||
/**
|
||||
* @var mixed The unexpected value.
|
||||
* The unexpected value.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $_value;
|
||||
|
||||
/**
|
||||
* Creates a new UnexpectedValueException.
|
||||
*
|
||||
* @param string $message The Exception message to throw.
|
||||
* @param int $code The Exception code.
|
||||
* @param \Exception $previous The previous exception used for the exception
|
||||
*
|
||||
* @param string $message The Exception message to throw.
|
||||
* @param int $code The Exception code.
|
||||
* @param E|null $previous The previous exception used for the exception
|
||||
* chaining.
|
||||
* @param mixed $value The unexpected value.
|
||||
* @param mixed $value The unexpected value.
|
||||
*/
|
||||
public function __construct(
|
||||
$message,
|
||||
$code = 0,
|
||||
$previous = null,
|
||||
E $previous = null,
|
||||
$value = null
|
||||
) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
@ -63,7 +74,7 @@ class UnexpectedValueException extends U implements Exception
|
||||
|
||||
/**
|
||||
* Gets the unexpected value.
|
||||
*
|
||||
*
|
||||
* @return mixed The unexpected value.
|
||||
*/
|
||||
public function getValue()
|
||||
@ -76,7 +87,7 @@ class UnexpectedValueException extends U implements Exception
|
||||
|
||||
/**
|
||||
* Returns a string representation of the exception.
|
||||
*
|
||||
*
|
||||
* @return string The exception as a string.
|
||||
*/
|
||||
public function __toString()
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,7 @@
|
||||
|
||||
/**
|
||||
* Wrapper for network stream functionality.
|
||||
|
||||
*
|
||||
* PHP has built in support for various types of network streams, such as HTTP and TCP sockets. One problem that arises with them is the fact that a single fread/fwrite call might not read/write all the data you intended, regardless of whether you're in blocking mode or not. While the PHP manual offers a workaround in the form of a loop with a few variables, using it every single time you want to read/write can be tedious.
|
||||
|
||||
@ -14,7 +15,7 @@ This package abstracts this away, so that when you want to get exactly N amount
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0a5
|
||||
* @version 1.0.0b2
|
||||
* @link http://pear2.php.net/PEAR2_Net_Transmitter
|
||||
*/
|
||||
/**
|
||||
|
@ -2,19 +2,20 @@
|
||||
|
||||
/**
|
||||
* Wrapper for network stream functionality.
|
||||
*
|
||||
|
||||
*
|
||||
* PHP has built in support for various types of network streams, such as HTTP and TCP sockets. One problem that arises with them is the fact that a single fread/fwrite call might not read/write all the data you intended, regardless of whether you're in blocking mode or not. While the PHP manual offers a workaround in the form of a loop with a few variables, using it every single time you want to read/write can be tedious.
|
||||
|
||||
This package abstracts this away, so that when you want to get exactly N amount of bytes, you can be sure the upper levels of your app will be dealing with N bytes. Oh, and the functionality is nicely wrapped in an object (but that's just the icing on the cake).
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_Transmitter
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0a5
|
||||
* @version 1.0.0b2
|
||||
* @link http://pear2.php.net/PEAR2_Net_Transmitter
|
||||
*/
|
||||
/**
|
||||
@ -24,9 +25,9 @@ namespace PEAR2\Net\Transmitter;
|
||||
|
||||
/**
|
||||
* A filter collection.
|
||||
*
|
||||
*
|
||||
* Represents a collection of stream filters.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_Transmitter
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -37,21 +38,25 @@ namespace PEAR2\Net\Transmitter;
|
||||
class FilterCollection implements \SeekableIterator, \Countable
|
||||
{
|
||||
/**
|
||||
* @var array The filter collection itself.
|
||||
* The filter collection itself.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $filters = array();
|
||||
|
||||
|
||||
/**
|
||||
* @var int A pointer, as required by SeekableIterator.
|
||||
* A pointer, as required by SeekableIterator.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $position = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Appends a filter to the collection
|
||||
*
|
||||
*
|
||||
* @param string $name The name of the filter.
|
||||
* @param array $params An array of parameters for the filter.
|
||||
*
|
||||
*
|
||||
* @return $this The collection itself.
|
||||
*/
|
||||
public function append($name, array $params = array())
|
||||
@ -59,19 +64,19 @@ class FilterCollection implements \SeekableIterator, \Countable
|
||||
$this->filters[] = array((string) $name, $params);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inserts the filter before a position.
|
||||
*
|
||||
*
|
||||
* Inserts the specified filter before a filter at a specified position. The
|
||||
* new filter takes the specified position, while previous filters are moved
|
||||
* forward by one.
|
||||
*
|
||||
*
|
||||
* @param int $position The position before which the filter will be
|
||||
* inserted.
|
||||
* @param string $name The name of the filter.
|
||||
* @param array $params An array of parameters for the filter.
|
||||
*
|
||||
*
|
||||
* @return $this The collection itself.
|
||||
*/
|
||||
public function insertBefore($position, $name, array $params = array())
|
||||
@ -94,12 +99,12 @@ class FilterCollection implements \SeekableIterator, \Countable
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a filter at a specified position.
|
||||
*
|
||||
*
|
||||
* @param int $position The position from which to remove a filter.
|
||||
*
|
||||
*
|
||||
* @return $this The collection itself.
|
||||
*/
|
||||
public function removeAt($position)
|
||||
@ -108,10 +113,10 @@ class FilterCollection implements \SeekableIterator, \Countable
|
||||
$this->filters = array_values($this->filters);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clears the collection
|
||||
*
|
||||
*
|
||||
* @return $this The collection itself.
|
||||
*/
|
||||
public function clear()
|
||||
@ -122,7 +127,7 @@ class FilterCollection implements \SeekableIterator, \Countable
|
||||
|
||||
/**
|
||||
* Gets the number of filters in the collection.
|
||||
*
|
||||
*
|
||||
* @return int The number of filters in the collection.
|
||||
*/
|
||||
public function count()
|
||||
@ -132,7 +137,7 @@ class FilterCollection implements \SeekableIterator, \Countable
|
||||
|
||||
/**
|
||||
* Resets the pointer to 0.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if the collection is not empty, FALSE otherwise.
|
||||
*/
|
||||
public function rewind()
|
||||
@ -142,9 +147,9 @@ class FilterCollection implements \SeekableIterator, \Countable
|
||||
|
||||
/**
|
||||
* Moves the pointer to a specified position.
|
||||
*
|
||||
*
|
||||
* @param int $position The position to move to.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if the specified position is valid, FALSE otherwise.
|
||||
*/
|
||||
public function seek($position)
|
||||
@ -152,10 +157,10 @@ class FilterCollection implements \SeekableIterator, \Countable
|
||||
$this->position = $position;
|
||||
return $this->valid();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the current position.
|
||||
*
|
||||
*
|
||||
* @return int The current position.
|
||||
*/
|
||||
public function getCurrentPosition()
|
||||
@ -165,7 +170,7 @@ class FilterCollection implements \SeekableIterator, \Countable
|
||||
|
||||
/**
|
||||
* Moves the pointer forward by 1.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if the new position is valid, FALSE otherwise.
|
||||
*/
|
||||
public function next()
|
||||
@ -176,8 +181,8 @@ class FilterCollection implements \SeekableIterator, \Countable
|
||||
|
||||
/**
|
||||
* Gets the filter name at the current pointer position.
|
||||
*
|
||||
* @return string The name of the filter at the current position.
|
||||
*
|
||||
* @return string|false The name of the filter at the current position.
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
@ -186,9 +191,9 @@ class FilterCollection implements \SeekableIterator, \Countable
|
||||
|
||||
/**
|
||||
* Gets the filter parameters at the current pointer position.
|
||||
*
|
||||
* @return array An array of parameters for the filter at the current
|
||||
* position.
|
||||
*
|
||||
* @return array|false An array of parameters for the filter at the current
|
||||
* position, or FALSE if the position is not valid.
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
@ -197,7 +202,7 @@ class FilterCollection implements \SeekableIterator, \Countable
|
||||
|
||||
/**
|
||||
* Moves the pointer backwards by 1.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if the new position is valid, FALSE otherwise.
|
||||
*/
|
||||
public function prev()
|
||||
@ -208,7 +213,7 @@ class FilterCollection implements \SeekableIterator, \Countable
|
||||
|
||||
/**
|
||||
* Moves the pointer to the last valid position.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if the collection is not empty, FALSE otherwise.
|
||||
*/
|
||||
public function end()
|
||||
@ -219,7 +224,7 @@ class FilterCollection implements \SeekableIterator, \Countable
|
||||
|
||||
/**
|
||||
* Checks if the pointer is still pointing to an existing offset.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if the pointer is valid, FALSE otherwise.
|
||||
*/
|
||||
public function valid()
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
/**
|
||||
* Wrapper for network stream functionality.
|
||||
|
||||
*
|
||||
* PHP has built in support for various types of network streams, such as HTTP and TCP sockets. One problem that arises with them is the fact that a single fread/fwrite call might not read/write all the data you intended, regardless of whether you're in blocking mode or not. While the PHP manual offers a workaround in the form of a loop with a few variables, using it every single time you want to read/write can be tedious.
|
||||
|
||||
@ -14,7 +15,7 @@ This package abstracts this away, so that when you want to get exactly N amount
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0a5
|
||||
* @version 1.0.0b2
|
||||
* @link http://pear2.php.net/PEAR2_Net_Transmitter
|
||||
*/
|
||||
/**
|
||||
|
@ -2,19 +2,20 @@
|
||||
|
||||
/**
|
||||
* Wrapper for network stream functionality.
|
||||
*
|
||||
|
||||
*
|
||||
* PHP has built in support for various types of network streams, such as HTTP and TCP sockets. One problem that arises with them is the fact that a single fread/fwrite call might not read/write all the data you intended, regardless of whether you're in blocking mode or not. While the PHP manual offers a workaround in the form of a loop with a few variables, using it every single time you want to read/write can be tedious.
|
||||
|
||||
This package abstracts this away, so that when you want to get exactly N amount of bytes, you can be sure the upper levels of your app will be dealing with N bytes. Oh, and the functionality is nicely wrapped in an object (but that's just the icing on the cake).
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_Transmitter
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0a5
|
||||
* @version 1.0.0b2
|
||||
* @link http://pear2.php.net/PEAR2_Net_Transmitter
|
||||
*/
|
||||
/**
|
||||
@ -24,10 +25,10 @@ namespace PEAR2\Net\Transmitter;
|
||||
|
||||
/**
|
||||
* A network transmitter.
|
||||
*
|
||||
* This is a convinience wrapper for network streams. Used to ensure data
|
||||
*
|
||||
* This is a convenience wrapper for network streams. Used to ensure data
|
||||
* integrity.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_Transmitter
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -62,22 +63,27 @@ abstract class NetworkStream extends Stream
|
||||
* negotiated between 1.0 and 1.2).
|
||||
*/
|
||||
const CRYPTO_TLS = 'TLS';
|
||||
|
||||
|
||||
/**
|
||||
* @var string The type of stream. Can be either "_CLIENT" or "_SERVER".
|
||||
* Used to complement the encryption type. Must be set by child classes
|
||||
* for {@link setCrypto()} to work properly.
|
||||
* The type of stream. Can be either "_CLIENT" or "_SERVER".
|
||||
*
|
||||
* Used to complement the encryption type. Must be set by child classes
|
||||
* for {@link setCrypto()} to work properly.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $streamType = '';
|
||||
|
||||
/**
|
||||
* @var string The current cryptography setting.
|
||||
* The current cryptography setting.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $crypto = '';
|
||||
|
||||
/**
|
||||
* Wraps around the specified stream.
|
||||
*
|
||||
*
|
||||
* @param resource $stream The stream to wrap around.
|
||||
*/
|
||||
public function __construct($stream)
|
||||
@ -87,7 +93,7 @@ abstract class NetworkStream extends Stream
|
||||
|
||||
/**
|
||||
* Gets the current cryptography setting.
|
||||
*
|
||||
*
|
||||
* @return string One of this class' CRYPTO_* constants.
|
||||
*/
|
||||
public function getCrypto()
|
||||
@ -97,10 +103,10 @@ abstract class NetworkStream extends Stream
|
||||
|
||||
/**
|
||||
* Sets the current connection's cryptography setting.
|
||||
*
|
||||
*
|
||||
* @param string $type The encryption type to set. Must be one of this
|
||||
* class' CRYPTO_* constants.
|
||||
*
|
||||
*
|
||||
* @return boolean TRUE on success, FALSE on failure.
|
||||
*/
|
||||
public function setCrypto($type)
|
||||
@ -123,12 +129,12 @@ abstract class NetworkStream extends Stream
|
||||
|
||||
/**
|
||||
* Checks whether the stream is available for operations.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if the stream is available, FALSE otherwise.
|
||||
*/
|
||||
public function isAvailable()
|
||||
{
|
||||
if (parent::isStream($this->stream)) {
|
||||
if ($this->isStream($this->stream)) {
|
||||
if ($this->isBlocking && feof($this->stream)) {
|
||||
return false;
|
||||
}
|
||||
@ -137,14 +143,14 @@ abstract class NetworkStream extends Stream
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the size of a stream's buffer.
|
||||
*
|
||||
* @param int $size The desired size of the buffer, in bytes.
|
||||
* @param string $direction The buffer of which direction to set. Valid
|
||||
*
|
||||
* @param int $size The desired size of the buffer, in bytes.
|
||||
* @param int $direction The buffer of which direction to set. Valid
|
||||
* values are the DIRECTION_* constants.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure.
|
||||
*/
|
||||
public function setBuffer($size, $direction = self::DIRECTION_ALL)
|
||||
@ -157,15 +163,15 @@ abstract class NetworkStream extends Stream
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shutdown a full-duplex connection
|
||||
*
|
||||
*
|
||||
* Shutdowns (partially or not) a full-duplex connection.
|
||||
*
|
||||
* @param string $direction The direction for which to disable further
|
||||
*
|
||||
* @param int $direction The direction for which to disable further
|
||||
* communications.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure.
|
||||
*/
|
||||
public function shutdown($direction = self::DIRECTION_ALL)
|
||||
|
@ -2,19 +2,20 @@
|
||||
|
||||
/**
|
||||
* Wrapper for network stream functionality.
|
||||
*
|
||||
|
||||
*
|
||||
* PHP has built in support for various types of network streams, such as HTTP and TCP sockets. One problem that arises with them is the fact that a single fread/fwrite call might not read/write all the data you intended, regardless of whether you're in blocking mode or not. While the PHP manual offers a workaround in the form of a loop with a few variables, using it every single time you want to read/write can be tedious.
|
||||
|
||||
This package abstracts this away, so that when you want to get exactly N amount of bytes, you can be sure the upper levels of your app will be dealing with N bytes. Oh, and the functionality is nicely wrapped in an object (but that's just the icing on the cake).
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_Transmitter
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0a5
|
||||
* @version 1.0.0b2
|
||||
* @link http://pear2.php.net/PEAR2_Net_Transmitter
|
||||
*/
|
||||
/**
|
||||
@ -29,7 +30,7 @@ use Exception as E;
|
||||
|
||||
/**
|
||||
* Exception thrown when something goes wrong with the connection.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_Transmitter
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -40,18 +41,22 @@ class SocketException extends StreamException
|
||||
{
|
||||
|
||||
/**
|
||||
* @var int The system level error code.
|
||||
* The system level error code.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $errorNo;
|
||||
|
||||
/**
|
||||
* @var string The system level error message.
|
||||
* The system level error message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $errorStr;
|
||||
|
||||
/**
|
||||
* Creates a new socket exception.
|
||||
*
|
||||
*
|
||||
* @param string $message The Exception message to throw.
|
||||
* @param int $code The Exception code.
|
||||
* @param E|null $previous Previous exception thrown,
|
||||
@ -62,7 +67,7 @@ class SocketException extends StreamException
|
||||
* successfully before the failure.
|
||||
* On failure when receiving, this is a string/stream holding
|
||||
* the contents received successfully before the failure.
|
||||
* NULL if the failure occured before the operation started.
|
||||
* NULL if the failure occurred before the operation started.
|
||||
* @param int $errorNo The system level error number.
|
||||
* @param string $errorStr The system level
|
||||
* error message.
|
||||
@ -82,7 +87,7 @@ class SocketException extends StreamException
|
||||
|
||||
/**
|
||||
* Gets the system level error code on the socket.
|
||||
*
|
||||
*
|
||||
* @return int The system level error number.
|
||||
*/
|
||||
public function getSocketErrorNumber()
|
||||
@ -95,7 +100,7 @@ class SocketException extends StreamException
|
||||
|
||||
/**
|
||||
* Gets the system level error message on the socket.
|
||||
*
|
||||
*
|
||||
* @return string The system level error message.
|
||||
*/
|
||||
public function getSocketErrorMessage()
|
||||
@ -105,7 +110,7 @@ class SocketException extends StreamException
|
||||
|
||||
/**
|
||||
* Returns a string representation of the exception.
|
||||
*
|
||||
*
|
||||
* @return string The exception as a string.
|
||||
*/
|
||||
public function __toString()
|
||||
|
@ -2,19 +2,20 @@
|
||||
|
||||
/**
|
||||
* Wrapper for network stream functionality.
|
||||
*
|
||||
|
||||
*
|
||||
* PHP has built in support for various types of network streams, such as HTTP and TCP sockets. One problem that arises with them is the fact that a single fread/fwrite call might not read/write all the data you intended, regardless of whether you're in blocking mode or not. While the PHP manual offers a workaround in the form of a loop with a few variables, using it every single time you want to read/write can be tedious.
|
||||
|
||||
This package abstracts this away, so that when you want to get exactly N amount of bytes, you can be sure the upper levels of your app will be dealing with N bytes. Oh, and the functionality is nicely wrapped in an object (but that's just the icing on the cake).
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_Transmitter
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0a5
|
||||
* @version 1.0.0b2
|
||||
* @link http://pear2.php.net/PEAR2_Net_Transmitter
|
||||
*/
|
||||
/**
|
||||
@ -26,11 +27,11 @@ use Exception as E;
|
||||
|
||||
/**
|
||||
* A stream transmitter.
|
||||
*
|
||||
* This is a convinience wrapper for stream functionality. Used to ensure data
|
||||
*
|
||||
* This is a convenience wrapper for stream functionality. Used to ensure data
|
||||
* integrity. Designed for TCP sockets, but it has intentionally been made to
|
||||
* accept any stream.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_Transmitter
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -57,32 +58,44 @@ class Stream
|
||||
const DIRECTION_ALL = 3;
|
||||
|
||||
/**
|
||||
* @var resource The stream to wrap around.
|
||||
* The stream to wrap around.
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
protected $stream;
|
||||
|
||||
/**
|
||||
* @var bool Whether to automaticaly close the stream on
|
||||
* object destruction if it's not a persistent one. Setting this to
|
||||
* FALSE may be useful if you're only using this class "part time",
|
||||
* while setting it to TRUE might be useful if you're doing some
|
||||
* "on offs".
|
||||
* Whether to automatically close the stream on object destruction if
|
||||
* it's not a persistent one.
|
||||
*
|
||||
* Setting this to FALSE may be useful if you're only using this class
|
||||
* "part time", while setting it to TRUE might be useful if you're doing
|
||||
* some "one offs".
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $autoClose = false;
|
||||
|
||||
/**
|
||||
* @var bool A flag that tells whether or not the stream is persistent.
|
||||
* A flag that tells whether or not the stream is persistent.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $persist;
|
||||
|
||||
/**
|
||||
* @var bool Whether the wrapped stream is in blocking mode or not.
|
||||
* Whether the wrapped stream is in blocking mode or not.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isBlocking = true;
|
||||
|
||||
|
||||
/**
|
||||
* @var array An associative array with the chunk size of each direction.
|
||||
* Key is the direction, value is the size in bytes as integer.
|
||||
* An associative array with the chunk size of each direction.
|
||||
*
|
||||
* Key is the direction, value is the size in bytes as integer.
|
||||
*
|
||||
* @var array<int,int>
|
||||
*/
|
||||
protected $chunkSize = array(
|
||||
self::DIRECTION_SEND => 0xFFFFF, self::DIRECTION_RECEIVE => 0xFFFFF
|
||||
@ -90,14 +103,14 @@ class Stream
|
||||
|
||||
/**
|
||||
* Wraps around the specified stream.
|
||||
*
|
||||
*
|
||||
* @param resource $stream The stream to wrap around.
|
||||
* @param bool $autoClose Whether to automaticaly close the stream on
|
||||
* @param bool $autoClose Whether to automatically close the stream on
|
||||
* object destruction if it's not a persistent one. Setting this to
|
||||
* FALSE may be useful if you're only using this class "part time",
|
||||
* while setting it to TRUE might be useful if you're doing some
|
||||
* "on offs".
|
||||
*
|
||||
*
|
||||
* @see static::isFresh()
|
||||
*/
|
||||
public function __construct($stream, $autoClose = false)
|
||||
@ -117,12 +130,14 @@ class Stream
|
||||
|
||||
/**
|
||||
* PHP error handler for connection errors.
|
||||
*
|
||||
*
|
||||
* @param string $level Level of PHP error raised. Ignored.
|
||||
* @param string $message Message raised by PHP.
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws SocketException That's how the error is handled.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*/
|
||||
protected function handleError($level, $message)
|
||||
@ -132,9 +147,9 @@ class Stream
|
||||
|
||||
/**
|
||||
* Checks if a given variable is a stream resource.
|
||||
*
|
||||
*
|
||||
* @param mixed $var The variable to check.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure.
|
||||
*/
|
||||
public static function isStream($var)
|
||||
@ -145,11 +160,11 @@ class Stream
|
||||
|
||||
/**
|
||||
* Checks whether the wrapped stream is fresh.
|
||||
*
|
||||
*
|
||||
* Checks whether the wrapped stream is fresh. A stream is considered fresh
|
||||
* if there hasn't been any activity on it. Particularly useful for
|
||||
* detecting reused persistent connections.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if the socket is fresh, FALSE otherwise.
|
||||
*/
|
||||
public function isFresh()
|
||||
@ -159,8 +174,8 @@ class Stream
|
||||
|
||||
/**
|
||||
* Checks whether the wrapped stream is a persistent one.
|
||||
*
|
||||
* @return bool TRUE if the stream is a persistent one, FALSE otherwise.
|
||||
*
|
||||
* @return bool TRUE if the stream is a persistent one, FALSE otherwise.
|
||||
*/
|
||||
public function isPersistent()
|
||||
{
|
||||
@ -169,8 +184,8 @@ class Stream
|
||||
|
||||
/**
|
||||
* Checks whether the wrapped stream is a blocking one.
|
||||
*
|
||||
* @return bool TRUE if the stream is a blocking one, FALSE otherwise.
|
||||
*
|
||||
* @return bool TRUE if the stream is a blocking one, FALSE otherwise.
|
||||
*/
|
||||
public function isBlocking()
|
||||
{
|
||||
@ -179,9 +194,9 @@ class Stream
|
||||
|
||||
/**
|
||||
* Sets blocking mode.
|
||||
*
|
||||
*
|
||||
* @param bool $block Sets whether the stream is in blocking mode.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure.
|
||||
*/
|
||||
public function setIsBlocking($block)
|
||||
@ -193,28 +208,28 @@ class Stream
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the timeout for the stream.
|
||||
*
|
||||
*
|
||||
* @param int $seconds Timeout in seconds.
|
||||
* @param int $microseconds Timeout in microseconds to be added to the
|
||||
* seconds.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure.
|
||||
*/
|
||||
public function setTimeout($seconds, $microseconds = 0)
|
||||
{
|
||||
return stream_set_timeout($this->stream, $seconds, $microseconds);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the size of a stream's buffer.
|
||||
*
|
||||
* @param int $size The desired size of the buffer, in bytes.
|
||||
* @param string $direction The buffer of which direction to set. Valid
|
||||
*
|
||||
* @param int $size The desired size of the buffer, in bytes.
|
||||
* @param int $direction The buffer of which direction to set. Valid
|
||||
* values are the DIRECTION_* constants.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure.
|
||||
*/
|
||||
public function setBuffer($size, $direction = self::DIRECTION_ALL)
|
||||
@ -230,18 +245,18 @@ class Stream
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the size of the chunk.
|
||||
*
|
||||
*
|
||||
* To ensure data integrity, as well as to allow for lower memory
|
||||
* consumption, data is sent/received in chunks. This function
|
||||
* allows you to set the size of each chunk. The default is 0xFFFFF.
|
||||
*
|
||||
* @param int $size The desired size of the chunk, in bytes.
|
||||
* @param string $direction The chunk of which direction to set. Valid
|
||||
*
|
||||
* @param int $size The desired size of the chunk, in bytes.
|
||||
* @param int $direction The chunk of which direction to set. Valid
|
||||
* values are the DIRECTION_* constants.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure.
|
||||
*/
|
||||
public function setChunk($size, $direction = self::DIRECTION_ALL)
|
||||
@ -262,14 +277,14 @@ class Stream
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the size of the chunk.
|
||||
*
|
||||
* @param string $direction The chunk of which direction to get. Valid
|
||||
*
|
||||
* @param int $direction The chunk of which direction to get. Valid
|
||||
* values are the DIRECTION_* constants.
|
||||
*
|
||||
* @return int|array|false The chunk size in bytes,
|
||||
*
|
||||
* @return int|array<int,int>|false The chunk size in bytes,
|
||||
* or an array of chunk sizes with the directions as keys.
|
||||
* FALSE on invalid direction.
|
||||
*/
|
||||
@ -287,18 +302,18 @@ class Stream
|
||||
|
||||
/**
|
||||
* Sends a string or stream over the wrapped stream.
|
||||
*
|
||||
*
|
||||
* Sends a string or stream over the wrapped stream. If a seekable stream is
|
||||
* provided, it will be seeked back to the same position it was passed as,
|
||||
* regardless of the $offset parameter.
|
||||
*
|
||||
*
|
||||
* @param string|resource $contents The string or stream to send.
|
||||
* @param int $offset The offset from which to start sending.
|
||||
* If a stream is provided, and this is set to NULL, sending will start
|
||||
* from the current stream position.
|
||||
* @param int $length The maximum length to send. If omitted,
|
||||
* the string/stream will be sent to its end.
|
||||
*
|
||||
*
|
||||
* @return int The number of bytes sent.
|
||||
*/
|
||||
public function send($contents, $offset = null, $length = null)
|
||||
@ -318,21 +333,22 @@ class Stream
|
||||
) {
|
||||
break;
|
||||
}
|
||||
$bytesNow = @fwrite(
|
||||
$this->stream,
|
||||
fread($contents, $chunkSize)
|
||||
);
|
||||
if (0 != $bytesNow) {
|
||||
$bytes += $bytesNow;
|
||||
} elseif ($this->isBlocking || false === $bytesNow) {
|
||||
throw $this->createException(
|
||||
'Failed while sending stream.',
|
||||
2,
|
||||
null,
|
||||
$bytes
|
||||
$contentsToSend = fread($contents, $chunkSize);
|
||||
if ('' != $contentsToSend) {
|
||||
$bytesNow = @fwrite(
|
||||
$this->stream,
|
||||
$contentsToSend
|
||||
);
|
||||
} else {
|
||||
usleep(300000);
|
||||
if (0 != $bytesNow) {
|
||||
$bytes += $bytesNow;
|
||||
} elseif ($this->isBlocking || false === $bytesNow) {
|
||||
throw $this->createException(
|
||||
'Failed while sending stream.',
|
||||
2,
|
||||
null,
|
||||
$bytes
|
||||
);
|
||||
}
|
||||
}
|
||||
$this->isAcceptingData(null);
|
||||
}
|
||||
@ -364,8 +380,6 @@ class Stream
|
||||
null,
|
||||
$bytes
|
||||
);
|
||||
} else {
|
||||
usleep(300000);
|
||||
}
|
||||
$this->isAcceptingData(null);
|
||||
}
|
||||
@ -375,13 +389,13 @@ class Stream
|
||||
|
||||
/**
|
||||
* Reads from the wrapped stream to receive.
|
||||
*
|
||||
*
|
||||
* Reads from the wrapped stream to receive content as a string.
|
||||
*
|
||||
*
|
||||
* @param int $length The number of bytes to receive.
|
||||
* @param string $what Descriptive string about what is being received
|
||||
* (used in exception messages).
|
||||
*
|
||||
*
|
||||
* @return string The received content.
|
||||
*/
|
||||
public function receive($length, $what = 'data')
|
||||
@ -412,16 +426,16 @@ class Stream
|
||||
|
||||
/**
|
||||
* Reads from the wrapped stream to receive.
|
||||
*
|
||||
*
|
||||
* Reads from the wrapped stream to receive content as a stream.
|
||||
*
|
||||
*
|
||||
* @param int $length The number of bytes to receive.
|
||||
* @param FilterCollection $filters A collection of filters to apply to the
|
||||
* stream while receiving. Note that the filters will not be present on
|
||||
* the stream after receiving is done.
|
||||
* @param string $what Descriptive string about what is being
|
||||
* received (used in exception messages).
|
||||
*
|
||||
*
|
||||
* @return resource The received content.
|
||||
*/
|
||||
public function receiveStream(
|
||||
@ -432,16 +446,16 @@ class Stream
|
||||
$result = fopen('php://temp', 'r+b');
|
||||
$appliedFilters = array();
|
||||
if (null !== $filters) {
|
||||
foreach ($filters as $filtername => $params) {
|
||||
foreach ($filters as $filterName => $params) {
|
||||
$appliedFilters[] = stream_filter_append(
|
||||
$result,
|
||||
$filtername,
|
||||
$filterName,
|
||||
STREAM_FILTER_WRITE,
|
||||
$params
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$chunkSize = $this->chunkSize[self::DIRECTION_RECEIVE];
|
||||
while ($length > 0) {
|
||||
while ($this->isAvailable()) {
|
||||
@ -477,10 +491,10 @@ class Stream
|
||||
|
||||
/**
|
||||
* Checks whether the stream is available for operations.
|
||||
*
|
||||
*
|
||||
* For network streams, this means whether the other end has closed the
|
||||
* connection.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if the stream is available, FALSE otherwise.
|
||||
*/
|
||||
public function isAvailable()
|
||||
@ -490,13 +504,14 @@ class Stream
|
||||
|
||||
/**
|
||||
* Checks whether there is data to be read from the wrapped stream.
|
||||
*
|
||||
* @param int|null $sTimeout If theere isn't data awaiting currently,
|
||||
*
|
||||
* @param int|null $sTimeout If there isn't data awaiting currently,
|
||||
* wait for it this many seconds for data to arrive. If NULL is
|
||||
* specified, wait indefinetly for that.
|
||||
* specified, wait indefinitely for that.
|
||||
* @param int $usTimeout Microseconds to add to the waiting time.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE if there is data to be read, FALSE otherwise.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ShortVariable)
|
||||
*/
|
||||
public function isDataAwaiting($sTimeout = 0, $usTimeout = 0)
|
||||
@ -522,14 +537,15 @@ class Stream
|
||||
|
||||
/**
|
||||
* Checks whether the wrapped stream can be written to without a block.
|
||||
*
|
||||
*
|
||||
* @param int|null $sTimeout If the stream isn't currently accepting data,
|
||||
* wait for it this many seconds to start accepting data. If NULL is
|
||||
* specified, wait indefinetly for that.
|
||||
* specified, wait indefinitely for that.
|
||||
* @param int $usTimeout Microseconds to add to the waiting time.
|
||||
*
|
||||
* @return bool TRUE if the wrapped stream would not block on a write, FALSE
|
||||
* otherwise.
|
||||
*
|
||||
* @return bool TRUE if the wrapped stream would not block on a write,
|
||||
* FALSE otherwise.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ShortVariable)
|
||||
*/
|
||||
public function isAcceptingData($sTimeout = 0, $usTimeout = 0)
|
||||
@ -567,7 +583,7 @@ class Stream
|
||||
|
||||
/**
|
||||
* Closes the opened stream, even if it is a persistent one.
|
||||
*
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on failure.
|
||||
*/
|
||||
public function close()
|
||||
@ -577,10 +593,10 @@ class Stream
|
||||
|
||||
/**
|
||||
* Creates a new exception.
|
||||
*
|
||||
*
|
||||
* Creates a new exception. Used by the rest of the functions in this class.
|
||||
* Override in derived classes for custom exception handling.
|
||||
*
|
||||
*
|
||||
* @param string $message The exception message.
|
||||
* @param int $code The exception code.
|
||||
* @param E|null $previous Previous exception thrown,
|
||||
@ -591,7 +607,7 @@ class Stream
|
||||
* successfully before the failure.
|
||||
* On failure when receiving, this is a string/stream holding
|
||||
* the contents received successfully before the failure.
|
||||
*
|
||||
*
|
||||
* @return StreamException The exception to then be thrown.
|
||||
*/
|
||||
protected function createException(
|
||||
|
@ -2,19 +2,20 @@
|
||||
|
||||
/**
|
||||
* Wrapper for network stream functionality.
|
||||
*
|
||||
|
||||
*
|
||||
* PHP has built in support for various types of network streams, such as HTTP and TCP sockets. One problem that arises with them is the fact that a single fread/fwrite call might not read/write all the data you intended, regardless of whether you're in blocking mode or not. While the PHP manual offers a workaround in the form of a loop with a few variables, using it every single time you want to read/write can be tedious.
|
||||
|
||||
This package abstracts this away, so that when you want to get exactly N amount of bytes, you can be sure the upper levels of your app will be dealing with N bytes. Oh, and the functionality is nicely wrapped in an object (but that's just the icing on the cake).
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_Transmitter
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0a5
|
||||
* @version 1.0.0b2
|
||||
* @link http://pear2.php.net/PEAR2_Net_Transmitter
|
||||
*/
|
||||
/**
|
||||
@ -34,7 +35,7 @@ use Exception as E;
|
||||
|
||||
/**
|
||||
* Exception thrown when something goes wrong with the connection.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_Transmitter
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -44,18 +45,21 @@ use Exception as E;
|
||||
class StreamException extends RuntimeException implements Exception
|
||||
{
|
||||
/**
|
||||
* @var int|string|resource|null The fragment up until the point of failure.
|
||||
* On failure with sending, this is the number of bytes sent
|
||||
* successfully before the failure.
|
||||
* On failure when receiving, this is a string/stream holding
|
||||
* the contents received successfully before the failure.
|
||||
* NULL if the failure occured before the operation started.
|
||||
* The fragment up until the point of failure.
|
||||
*
|
||||
* On failure with sending, this is the number of bytes sent successfully
|
||||
* before the failure.
|
||||
* On failure when receiving, this is a string/stream holding the contents
|
||||
* received successfully before the failure.
|
||||
* NULL if the failure occurred before the operation started.
|
||||
*
|
||||
* @var int|string|resource|null
|
||||
*/
|
||||
protected $fragment = null;
|
||||
|
||||
/**
|
||||
* Creates a new stream exception.
|
||||
*
|
||||
*
|
||||
* @param string $message The Exception message to throw.
|
||||
* @param int $code The Exception code.
|
||||
* @param E|null $previous Previous exception thrown,
|
||||
@ -66,7 +70,7 @@ class StreamException extends RuntimeException implements Exception
|
||||
* successfully before the failure.
|
||||
* On failure when receiving, this is a string/stream holding
|
||||
* the contents received successfully before the failure.
|
||||
* NULL if the failure occured before the operation started.
|
||||
* NULL if the failure occurred before the operation started.
|
||||
*/
|
||||
public function __construct(
|
||||
$message,
|
||||
@ -80,14 +84,14 @@ class StreamException extends RuntimeException implements Exception
|
||||
|
||||
/**
|
||||
* Gets the stream fragment.
|
||||
*
|
||||
*
|
||||
* @return int|string|resource|null The fragment up until the
|
||||
* point of failure.
|
||||
* On failure with sending, this is the number of bytes sent
|
||||
* successfully before the failure.
|
||||
* On failure when receiving, this is a string/stream holding
|
||||
* the contents received successfully before the failure.
|
||||
* NULL if the failure occured before the operation started.
|
||||
* NULL if the failure occurred before the operation started.
|
||||
*/
|
||||
public function getFragment()
|
||||
{
|
||||
@ -99,7 +103,7 @@ class StreamException extends RuntimeException implements Exception
|
||||
|
||||
/**
|
||||
* Returns a string representation of the exception.
|
||||
*
|
||||
*
|
||||
* @return string The exception as a string.
|
||||
*/
|
||||
public function __toString()
|
||||
|
@ -2,19 +2,20 @@
|
||||
|
||||
/**
|
||||
* Wrapper for network stream functionality.
|
||||
*
|
||||
|
||||
*
|
||||
* PHP has built in support for various types of network streams, such as HTTP and TCP sockets. One problem that arises with them is the fact that a single fread/fwrite call might not read/write all the data you intended, regardless of whether you're in blocking mode or not. While the PHP manual offers a workaround in the form of a loop with a few variables, using it every single time you want to read/write can be tedious.
|
||||
|
||||
This package abstracts this away, so that when you want to get exactly N amount of bytes, you can be sure the upper levels of your app will be dealing with N bytes. Oh, and the functionality is nicely wrapped in an object (but that's just the icing on the cake).
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_Transmitter
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0a5
|
||||
* @version 1.0.0b2
|
||||
* @link http://pear2.php.net/PEAR2_Net_Transmitter
|
||||
*/
|
||||
/**
|
||||
@ -35,10 +36,10 @@ use Exception as E;
|
||||
|
||||
/**
|
||||
* A socket transmitter.
|
||||
*
|
||||
* This is a convinience wrapper for socket functionality. Used to ensure data
|
||||
*
|
||||
* This is a convenience wrapper for socket functionality. Used to ensure data
|
||||
* integrity.
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_Transmitter
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -49,27 +50,41 @@ class TcpClient extends NetworkStream
|
||||
{
|
||||
|
||||
/**
|
||||
* @var int The error code of the last error on the socket.
|
||||
* The error code of the last error on the socket.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $errorNo = 0;
|
||||
|
||||
/**
|
||||
* @var string The error message of the last error on the socket.
|
||||
* The error message of the last error on the socket.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $errorStr = null;
|
||||
|
||||
|
||||
/**
|
||||
* @var SHM Persistent connection handler. Remains NULL for non-persistent
|
||||
* connections.
|
||||
* Persistent connection handler.
|
||||
*
|
||||
* Remains NULL for non-persistent connections.
|
||||
*
|
||||
* @var SHM
|
||||
*/
|
||||
protected $shmHandler = null;
|
||||
|
||||
|
||||
/**
|
||||
* @var array An array with all connections from this PHP request (as keys)
|
||||
* and their lock state (as a value).
|
||||
* An array with all connections from this PHP request (as keys)
|
||||
* and their lock state (as a value).
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $lockState = array();
|
||||
|
||||
|
||||
/**
|
||||
* Mappings from a protocol name to an URI scheme.
|
||||
*
|
||||
* @var array<string,string>
|
||||
*/
|
||||
protected static $cryptoScheme = array(
|
||||
parent::CRYPTO_OFF => 'tcp',
|
||||
parent::CRYPTO_SSL2 => 'sslv2',
|
||||
@ -77,27 +92,29 @@ class TcpClient extends NetworkStream
|
||||
parent::CRYPTO_SSL => 'ssl',
|
||||
parent::CRYPTO_TLS => 'tls'
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @var string The URI of this connection.
|
||||
* The URI of this connection.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $uri;
|
||||
|
||||
/**
|
||||
* Creates a new connection with the specified options.
|
||||
*
|
||||
*
|
||||
* @param string $host Hostname (IP or domain) of the server.
|
||||
* @param int $port The port on the server.
|
||||
* @param bool $persist Whether or not the connection should be a
|
||||
* persistent one.
|
||||
* @param float $timeout The timeout for the connection.
|
||||
* @param string $key A string that uniquely identifies the
|
||||
* connection.
|
||||
* connection. Ignored for non-persistent connections.
|
||||
* @param string $crypto Encryption setting. Must be one of the
|
||||
* NetworkStream::CRYPTO_* constants. By default, encryption is
|
||||
* disabled. If the setting has an associated scheme for it, it will be
|
||||
* used, and if not, the setting will be adjusted right after the
|
||||
* connection is estabilished.
|
||||
* connection is established.
|
||||
* @param resource $context A context for the socket.
|
||||
*/
|
||||
public function __construct(
|
||||
@ -114,16 +131,10 @@ class TcpClient extends NetworkStream
|
||||
if (strpos($host, ':') !== false) {
|
||||
$host = "[{$host}]";
|
||||
}
|
||||
$flags = STREAM_CLIENT_CONNECT;
|
||||
if ($persist) {
|
||||
$flags |= STREAM_CLIENT_PERSISTENT;
|
||||
}
|
||||
|
||||
$timeout
|
||||
= null == $timeout ? ini_get('default_socket_timeout') : $timeout;
|
||||
|
||||
$key = rawurlencode($key);
|
||||
|
||||
if (null === $context) {
|
||||
$context = stream_context_get_default();
|
||||
} elseif ((!is_resource($context))
|
||||
@ -133,7 +144,14 @@ class TcpClient extends NetworkStream
|
||||
}
|
||||
$hasCryptoScheme = array_key_exists($crypto, static::$cryptoScheme);
|
||||
$scheme = $hasCryptoScheme ? static::$cryptoScheme[$crypto] : 'tcp';
|
||||
$this->uri = "{$scheme}://{$host}:{$port}/{$key}";
|
||||
$flags = STREAM_CLIENT_CONNECT;
|
||||
if ($persist) {
|
||||
$flags |= STREAM_CLIENT_PERSISTENT;
|
||||
$key = rawurlencode($key);
|
||||
$this->uri = "{$scheme}://{$host}:{$port}/{$key}";
|
||||
} else {
|
||||
$this->uri = "{$scheme}://{$host}:{$port}";
|
||||
}
|
||||
set_error_handler(array($this, 'handleError'));
|
||||
try {
|
||||
parent::__construct(
|
||||
@ -168,7 +186,9 @@ class TcpClient extends NetworkStream
|
||||
} elseif (parent::CRYPTO_OFF !== $crypto) {
|
||||
$this->setCrypto($crypto);
|
||||
}
|
||||
$this->setIsBlocking(parent::CRYPTO_OFF === $crypto);
|
||||
if (parent::CRYPTO_OFF !== $crypto) {
|
||||
$this->setIsBlocking(false);
|
||||
}
|
||||
|
||||
if ($persist) {
|
||||
$this->shmHandler = SHM::factory(
|
||||
@ -180,9 +200,9 @@ class TcpClient extends NetworkStream
|
||||
|
||||
/**
|
||||
* Creates a new exception.
|
||||
*
|
||||
*
|
||||
* Creates a new exception. Used by the rest of the functions in this class.
|
||||
*
|
||||
*
|
||||
* @param string $message The exception message.
|
||||
* @param int $code The exception code.
|
||||
* @param E|null $previous Previous exception thrown,
|
||||
@ -193,7 +213,7 @@ class TcpClient extends NetworkStream
|
||||
* successfully before the failure.
|
||||
* On failure when receiving, this is a string/stream holding
|
||||
* the contents received successfully before the failure.
|
||||
*
|
||||
*
|
||||
* @return SocketException The exception to then be thrown.
|
||||
*/
|
||||
protected function createException(
|
||||
@ -211,26 +231,27 @@ class TcpClient extends NetworkStream
|
||||
$this->errorStr
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Locks transmission.
|
||||
*
|
||||
*
|
||||
* Locks transmission in one or more directions. Useful when dealing with
|
||||
* persistent connections. Note that every send/receive call implicitly
|
||||
* calls this function and then restores it to the previous state. You only
|
||||
* need to call this function if you need to do an uninterrputed sequence of
|
||||
* need to call this function if you need to do an uninterrupted sequence of
|
||||
* such calls.
|
||||
*
|
||||
*
|
||||
* @param int $direction The direction(s) to have locked. Acceptable values
|
||||
* are the DIRECTION_* constants. If a lock for a direction can't be
|
||||
* obtained immediatly, the function will block until one is aquired.
|
||||
* Note that if you specify {@link DIRECTION_ALL}, the sending lock will
|
||||
* be obtained before the receiving one, and if obtaining the receiving
|
||||
* lock afterwards fails, the sending lock will be released too.
|
||||
* obtained immediately, the function will block until one is acquired.
|
||||
* Note that if you specify {@link static::DIRECTION_ALL},
|
||||
* the sending lock will be obtained before the receiving one,
|
||||
* and if obtaining the receiving lock afterwards fails,
|
||||
* the sending lock will be released too.
|
||||
* @param bool $replace Whether to replace all locks with the specified
|
||||
* ones. Setting this to FALSE will make the function only obtain the
|
||||
* locks which are not already obtained.
|
||||
*
|
||||
*
|
||||
* @return int|false The previous state or FALSE if the connection is not
|
||||
* persistent or arguments are invalid.
|
||||
*/
|
||||
@ -256,7 +277,7 @@ class TcpClient extends NetworkStream
|
||||
throw new LockException('Unable to release sending lock.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
if ($direction & self::DIRECTION_RECEIVE) {
|
||||
if (($old & self::DIRECTION_RECEIVE)
|
||||
@ -292,23 +313,24 @@ class TcpClient extends NetworkStream
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sends a string or stream to the server.
|
||||
*
|
||||
*
|
||||
* Sends a string or stream to the server. If a seekable stream is
|
||||
* provided, it will be seeked back to the same position it was passed as,
|
||||
* regardless of the $offset parameter.
|
||||
*
|
||||
*
|
||||
* @param string|resource $contents The string or stream to send.
|
||||
* @param int $offset The offset from which to start sending.
|
||||
* If a stream is provided, and this is set to NULL, sending will start
|
||||
* from the current stream position.
|
||||
* @param int $length The maximum length to send. If omitted,
|
||||
* the string/stream will be sent to its end.
|
||||
*
|
||||
*
|
||||
* @return int The number of bytes sent.
|
||||
* @throws E
|
||||
*/
|
||||
public function send($contents, $offset = null, $length = null)
|
||||
{
|
||||
@ -332,13 +354,13 @@ class TcpClient extends NetworkStream
|
||||
|
||||
/**
|
||||
* Receives data from the server.
|
||||
*
|
||||
*
|
||||
* Receives data from the server as a string.
|
||||
*
|
||||
*
|
||||
* @param int $length The number of bytes to receive.
|
||||
* @param string $what Descriptive string about what is being received
|
||||
* (used in exception messages).
|
||||
*
|
||||
*
|
||||
* @return string The received content.
|
||||
*/
|
||||
public function receive($length, $what = 'data')
|
||||
@ -363,16 +385,16 @@ class TcpClient extends NetworkStream
|
||||
|
||||
/**
|
||||
* Receives data from the server.
|
||||
*
|
||||
*
|
||||
* Receives data from the server as a stream.
|
||||
*
|
||||
*
|
||||
* @param int $length The number of bytes to receive.
|
||||
* @param FilterCollection $filters A collection of filters to apply to the
|
||||
* stream while receiving. Note that the filters will not be present on
|
||||
* the stream after receiving is done.
|
||||
* @param string $what Descriptive string about what is being
|
||||
* received (used in exception messages).
|
||||
*
|
||||
*
|
||||
* @return resource The received content.
|
||||
*/
|
||||
public function receiveStream(
|
||||
|
@ -2,19 +2,20 @@
|
||||
|
||||
/**
|
||||
* Wrapper for network stream functionality.
|
||||
*
|
||||
|
||||
*
|
||||
* PHP has built in support for various types of network streams, such as HTTP and TCP sockets. One problem that arises with them is the fact that a single fread/fwrite call might not read/write all the data you intended, regardless of whether you're in blocking mode or not. While the PHP manual offers a workaround in the form of a loop with a few variables, using it every single time you want to read/write can be tedious.
|
||||
|
||||
This package abstracts this away, so that when you want to get exactly N amount of bytes, you can be sure the upper levels of your app will be dealing with N bytes. Oh, and the functionality is nicely wrapped in an object (but that's just the icing on the cake).
|
||||
*
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_Transmitter
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
* @copyright 2011 Vasil Rangelov
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
||||
* @version 1.0.0a5
|
||||
* @version 1.0.0b2
|
||||
* @link http://pear2.php.net/PEAR2_Net_Transmitter
|
||||
*/
|
||||
/**
|
||||
@ -26,12 +27,12 @@ use Exception as E;
|
||||
|
||||
/**
|
||||
* A transmitter for connections to a socket server.
|
||||
*
|
||||
* This is a convinience wrapper for functionality of socket server connections.
|
||||
*
|
||||
* This is a convenience wrapper for functionality of socket server connections.
|
||||
* Used to ensure data integrity. Server handling is not part of the class in
|
||||
* order to allow its usage as part of various server implementations (e.g. fork
|
||||
* and/or sequential).
|
||||
*
|
||||
*
|
||||
* @category Net
|
||||
* @package PEAR2_Net_Transmitter
|
||||
* @author Vasil Rangelov <boen.robot@gmail.com>
|
||||
@ -42,21 +43,26 @@ class TcpServerConnection extends NetworkStream
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string The IP address of the connected client.
|
||||
* The IP address of the connected client.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $peerIP;
|
||||
|
||||
/**
|
||||
* @var int The port of the connected client.
|
||||
* The port of the connected client.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $peerPort;
|
||||
|
||||
/**
|
||||
* Creates a new connection with the specified options.
|
||||
*
|
||||
* @param resource $server A socket server, created with
|
||||
* {@link stream_socket_server()}.
|
||||
* @param float $timeout The timeout for the connection.
|
||||
*
|
||||
* @param resource $server A socket server, created with
|
||||
* {@link stream_socket_server()}.
|
||||
* @param float|null $timeout The timeout for the connection. Leaving this
|
||||
* to NULL uses the default socket timeout.
|
||||
*/
|
||||
public function __construct($server, $timeout = null)
|
||||
{
|
||||
@ -71,15 +77,15 @@ class TcpServerConnection extends NetworkStream
|
||||
set_error_handler(array($this, 'handleError'));
|
||||
try {
|
||||
parent::__construct(
|
||||
stream_socket_accept($server, $timeout, $peername)
|
||||
stream_socket_accept($server, $timeout, $peerName)
|
||||
);
|
||||
restore_error_handler();
|
||||
$portString = strrchr($peername, ':');
|
||||
$portString = strrchr($peerName, ':');
|
||||
$this->peerPort = (int) substr($portString, 1);
|
||||
$ipString = substr(
|
||||
$peername,
|
||||
$peerName,
|
||||
0,
|
||||
strlen($peername) - strlen($portString)
|
||||
strlen($peerName) - strlen($portString)
|
||||
);
|
||||
if (strpos($ipString, '[') === 0
|
||||
&& strpos(strrev($ipString), ']') === 0
|
||||
@ -96,20 +102,20 @@ class TcpServerConnection extends NetworkStream
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the IP address of the connected client.
|
||||
*
|
||||
*
|
||||
* @return string The IP address of the connected client.
|
||||
*/
|
||||
public function getPeerIP()
|
||||
{
|
||||
return $this->peerIP;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the port of the connected client.
|
||||
*
|
||||
*
|
||||
* @return int The port of the connected client.
|
||||
*/
|
||||
public function getPeerPort()
|
||||
@ -119,16 +125,16 @@ class TcpServerConnection extends NetworkStream
|
||||
|
||||
/**
|
||||
* Creates a new exception.
|
||||
*
|
||||
*
|
||||
* Creates a new exception. Used by the rest of the functions in this class.
|
||||
*
|
||||
*
|
||||
* @param string $message The exception message.
|
||||
* @param int $code The exception code.
|
||||
* @param E|null $previous Previous exception thrown, or NULL if there
|
||||
* is none.
|
||||
* @param string|null $fragment The fragment up until the point of failure.
|
||||
* NULL if the failure occured before the operation started.
|
||||
*
|
||||
* NULL if the failure occurred before the operation started.
|
||||
*
|
||||
* @return SocketException The exception to then be thrown.
|
||||
*/
|
||||
protected function createException(
|
||||
|
Reference in New Issue
Block a user