diff --git a/system/autoload/PEAR2/Autoload.php b/system/autoload/PEAR2/Autoload.php index 3d6161e9..704b7d85 100644 --- a/system/autoload/PEAR2/Autoload.php +++ b/system/autoload/PEAR2/Autoload.php @@ -1,22 +1,87 @@ + * @author Brett Bieber + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version 0.3.0 + * @link http://pear2.php.net/PEAR2_Autoload + */ namespace PEAR2; + if (!class_exists('\PEAR2\Autoload', false)) { + /** + * Standard Autoloader for PEAR2 + * + * PEAR2_Autoload is the standard method of class loading for development + * and low-volume web sites using PEAR2 packages. + * + * PHP version 5 + * + * @category PEAR2 + * @package PEAR2_Autoload + * @author Gregory Beaver + * @author Brett Bieber + * @license http://www.opensource.org/licenses/bsd-license.php BSD + * New BSDLicense + * @link http://pear2.php.net/PEAR2_Autoload + */ class Autoload { + /** + * Used at {@link initialize()} to specify that the load function, path + * and map should be appended to the respective lists. + */ + const APPEND = 0; + + /** + * Used at {@link initialize()} to specify that the load function should + * be prepended on the autoload stack, instead of being appended. + */ + const PREPEND_LOAD = 1; + + /** + * Used at {@link initialize()} to specify that the path should be + * prepended on the list of paths, instead of being appended. + */ + const PREPEND_PATH = 2; + + /** + * Used at {@link initialize()} to specify that the map should be + * prepended on the list of maps, instead of being appended. + */ + const PREPEND_MAP = 4; + + /** + * Used at {@link initialize()} to specify that the load function, path + * and map should be prepended on their respective lists, instead of + * being appended. + */ + const PREPEND = 7; + /** * Whether the autoload class has been spl_autoload_register-ed - * + * * @var bool */ protected static $registered = false; /** * Array of PEAR2 autoload paths registered - * + * * @var array */ protected static $paths = array(); - + /** * Array of classname-to-file mapping * @@ -45,86 +110,124 @@ if (!class_exists('\PEAR2\Autoload', false)) { */ protected static $unmapped = array(); + /** + * Array of functions to be checked in exception traces. + * + * @var array + */ + protected static $checkFunctions = array( + 'class_exists', 'interface_exists' + ); + /** * Initialize the PEAR2 autoloader - * - * @param string $path Directory path to register - * + * + * @param string $path Directory path(s) to register. + * @param string $mapfile Path to a mapping file to register. + * @param int $flags A bitmaks with options for the autoloader. + * See the PREPEND(_*) constants for details. + * * @return void */ - static function initialize($path, $mapfile = null) - { - self::register(); - self::addPath($path); - self::addMap($mapfile); + public static function initialize( + $path, + $mapfile = null, + $flags = self::APPEND + ) { + self::register(0 !== $flags & self::PREPEND_LOAD); + self::addPath($path, 0 !== ($flags & self::PREPEND_PATH)); + self::addMap($mapfile, 0 !== ($flags & self::PREPEND_MAP)); } /** * Register the PEAR2 autoload class with spl_autoload_register - * + * + * @param bool $prepend Whether to prepend the load function to the + * autoload stack instead of appending it. + * * @return void */ - protected static function register() + protected static function register($prepend = false) { if (!self::$registered) { // set up __autoload $autoload = spl_autoload_functions(); - spl_autoload_register('PEAR2\Autoload::load'); + spl_autoload_register('PEAR2\Autoload::load', true, $prepend); if (function_exists('__autoload') && ($autoload === false)) { - // __autoload() was being used, but now would be ignored, add - // it to the autoload stack + // __autoload() was being used, but now would be ignored, + // add it to the autoload stack spl_autoload_register('__autoload'); } + if (function_exists('trait_exists')) { + self::$checkFunctions[] = 'trait_exists'; + } + self::$registered = true; } - self::$registered = true; } /** * Add a path - * - * @param string $path The directory to add to the set of PEAR2 paths - * + * + * @param string $paths The folder(s) to add to the set of paths. + * @param bool $prepend Whether to prepend the path to the list of + * paths instead of appending it. + * * @return void */ - protected static function addPath($path) + protected static function addPath($paths, $prepend = false) { - if (!in_array($path, self::$paths)) { - self::$paths[] = $path; + foreach (explode(PATH_SEPARATOR, $paths) as $path) { + if (!in_array($path, self::$paths)) { + if ($prepend) { + self::$paths = array_merge(array($path), self::$paths); + } else { + self::$paths[] = $path; + } + } } } /** * Add a classname-to-file map * - * @param string $mapfile The filename of the classmap + * @param string $mapfile The filename of the classmap. + * @param bool $prepend Whether to prepend the map to the list of maps + * instead of appending it. * * @return void */ - protected static function addMap($mapfile) + protected static function addMap($mapfile, $prepend = false) { - if (! in_array($mapfile, self::$maps)) { - + if (!in_array($mapfile, self::$maps)) { // keep track of specific map file loaded in this - // instance so we can update it if necessary + // instance so we can update it if necessary self::$mapfile = $mapfile; - - if (file_exists($mapfile)) { + + if (is_file($mapfile)) { $map = include $mapfile; if (is_array($map)) { // mapfile contains a valid map, so we'll keep it - self::$maps[] = $mapfile; - self::$map = array_merge(self::$map, $map); + if ($prepend) { + self::$maps = array_merge( + array($mapfile), + self::$maps + ); + self::$map = array_merge($map, self::$map); + } else { + self::$maps[] = $mapfile; + self::$map = array_merge(self::$map, $map); + } } } - + } } /** * Check if the class is already defined in a classmap - * + * * @param string $class The class to look for - * + * * @return bool */ protected static function isMapped($class) @@ -141,18 +244,18 @@ if (!class_exists('\PEAR2\Autoload', false)) { /** * Load a PEAR2 class - * + * * @param string $class The class to load - * + * * @return bool */ - static function load($class) + public static function load($class) { // need to check if there's a current map file specified ALSO. // this could be the first time writing it. $mapped = self::isMapped($class); - if ($mapped) { - require self::$map[$class]; + if ($mapped && is_file(self::$map[$class])) { + include self::$map[$class]; if (!self::loadSuccessful($class)) { // record this failure & keep going, we may still find it self::$unmapped[] = $class; @@ -161,34 +264,59 @@ if (!class_exists('\PEAR2\Autoload', false)) { } } - $file = str_replace(array('_', '\\'), DIRECTORY_SEPARATOR, $class) . '.php'; + $file = ''; + $className = $class; + if (false !== $lastNsPos = strrpos($class, '\\')) { + $namespace = substr($class, 0, $lastNsPos); + $className = substr($class, $lastNsPos + 1); + $file = str_replace( + '\\', + DIRECTORY_SEPARATOR, + $namespace + ) . DIRECTORY_SEPARATOR; + } + $file .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; foreach (self::$paths as $path) { - if (file_exists($path . DIRECTORY_SEPARATOR . $file)) { - require $path . DIRECTORY_SEPARATOR . $file; + if (is_file($path . DIRECTORY_SEPARATOR . $file)) { + include $path . DIRECTORY_SEPARATOR . $file; if (!self::loadSuccessful($class)) { - throw new \Exception('Class ' . $class . ' was not present in ' . + if (count(spl_autoload_functions()) > 1) { + return false; + } + throw new \Exception( + 'Class ' . $class . ' was not present in ' . $path . DIRECTORY_SEPARATOR . $file . - '") [PEAR2_Autoload-0.2.4]'); + '") [PEAR2_Autoload-@PACKAGE_VERSION@]' + ); } - + if (in_array($class, self::$unmapped)) { - self::updateMap($class, $path . DIRECTORY_SEPARATOR . $file); + self::updateMap( + $class, + $path . DIRECTORY_SEPARATOR . $file + ); } return true; } } - - $e = new \Exception('Class ' . $class . ' could not be loaded from ' . - $file . ', file does not exist (registered paths="' . - implode(PATH_SEPARATOR, self::$paths) . - '") [PEAR2_Autoload-0.2.4]'); - $trace = $e->getTrace(); - if (isset($trace[2]) && isset($trace[2]['function']) && - in_array($trace[2]['function'], array('class_exists', 'interface_exists'))) { + if (count(spl_autoload_functions()) > 1) { return false; } - if (isset($trace[1]) && isset($trace[1]['function']) && - in_array($trace[1]['function'], array('class_exists', 'interface_exists'))) { + $e = new \Exception( + 'Class ' . $class . ' could not be loaded from ' . + $file . ', file does not exist (registered paths="' . + implode(PATH_SEPARATOR, self::$paths) . + '") [PEAR2_Autoload-@PACKAGE_VERSION@]' + ); + $trace = $e->getTrace(); + if (isset($trace[2]) && isset($trace[2]['function']) + && in_array($trace[2]['function'], self::$checkFunctions) + ) { + return false; + } + if (isset($trace[1]) && isset($trace[1]['function']) + && in_array($trace[1]['function'], self::$checkFunctions) + ) { return false; } throw $e; @@ -196,31 +324,36 @@ if (!class_exists('\PEAR2\Autoload', false)) { /** * Check if the requested class was loaded from the specified path - * + * + * @param string $class The name of the class to check. + * * @return bool */ protected static function loadSuccessful($class) { - if (!class_exists($class, false) && !interface_exists($class, false)) { - return false; - } - return true; + return class_exists($class, false) + || interface_exists($class, false) + || (in_array('trait_exists', self::$checkFunctions, true) + && trait_exists($class, false)); } - + /** - * If possible, update the classmap file with newly-discovered + * If possible, update the classmap file with newly-discovered * mapping. - * - * @param string $class Class name discovered - * + * + * @param string $class Class name discovered * @param string $origin File where class was found - * + * + * @return void */ protected static function updateMap($class, $origin) { - if (is_writable(self::$mapfile) || is_writable(dirname(self::$mapfile))) { + if (is_writable(self::$mapfile) + || is_writable(dirname(self::$mapfile)) + ) { self::$map[$class] = $origin; - file_put_contents(self::$mapfile, + file_put_contents( + self::$mapfile, '<'."?php\n" . "// PEAR2\Autoload auto-generated classmap\n" . "return " . var_export(self::$map, true) . ';', @@ -228,16 +361,16 @@ if (!class_exists('\PEAR2\Autoload', false)) { ); } } - + /** - * return the array of paths PEAR2 autoload has registered - * + * Return the array of paths PEAR2 autoload has registered + * * @return array */ - static function getPaths() + public static function getPaths() { return self::$paths; } } } -Autoload::initialize(dirname(__DIR__)); \ No newline at end of file +Autoload::initialize(dirname(__DIR__)); diff --git a/system/autoload/PEAR2/Cache/SHM.php b/system/autoload/PEAR2/Cache/SHM.php index 02bec966..505e169a 100644 --- a/system/autoload/PEAR2/Cache/SHM.php +++ b/system/autoload/PEAR2/Cache/SHM.php @@ -1,18 +1,19 @@ * @copyright 2011 Vasil Rangelov * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 - * @version 0.1.3 + * @version 0.2.0 * @link http://pear2.php.net/PEAR2_Cache_SHM */ @@ -38,9 +39,9 @@ use PEAR2\Cache\SHM\InvalidArgumentException; /** * Main class for this package. - * + * * Automatically chooses an adapter based on the available extensions. - * + * * @category Caching * @package PEAR2_Cache_SHM * @author Vasil Rangelov @@ -50,18 +51,20 @@ use PEAR2\Cache\SHM\InvalidArgumentException; abstract class SHM implements IteratorAggregate { /** - * @var array An array of adapter names that meet their requirements. + * An array of adapter names that meet their requirements. + * + * @var array */ private static $_adapters = array(); - + /** * Creates a new shared memory storage. - * - * Estabilishes a separate persistent storage. Adapter is automatically + * + * Establishes a separate persistent storage. Adapter is automatically * chosen based on the available extensions. - * + * * @param string $persistentId The ID for the storage. - * + * * @return static|SHM A new instance of an SHM adapter (child of this * class). */ @@ -79,28 +82,28 @@ abstract class SHM implements IteratorAggregate 1 ); } - + /** * Checks if the adapter meets its requirements. - * + * * @return bool TRUE on success, FALSE on failure. */ public static function isMeetingRequirements() { return true; } - + /** * Registers an adapter. - * + * * Registers an SHM adapter, allowing you to call it with {@link factory()}. - * + * * @param string $adapter FQCN of adapter. A valid adapter is one that * extends this class. The class will be autoloaded if not already * present. * @param bool $prepend Whether to prepend this adapter into the list of * possible adapters, instead of appending to it. - * + * * @return bool TRUE on success, FALSE on failure. */ final public static function registerAdapter($adapter, $prepend = false) @@ -121,244 +124,244 @@ abstract class SHM implements IteratorAggregate } return false; } - + /** * Adds a value to the shared memory storage. - * + * * Adds a value to the storage if it doesn't exist, or fails if it does. - * + * * @param string $key Name of key to associate the value with. * @param mixed $value Value for the specified key. * @param int $ttl Seconds to store the value. If set to 0 indicates no * time limit. - * + * * @return bool TRUE on success, FALSE on failure. */ public function __invoke($key, $value, $ttl = 0) { return $this->add($key, $value, $ttl); } - + /** * Gets a value from the shared memory storage. - * + * * This is a magic method, thanks to which any property you attempt to get * the value of will be fetched from the adapter, treating the property name * as the key of the value to get. - * + * * @param string $key Name of key to get. - * + * * @return mixed The current value of the specified key. */ public function __get($key) { return $this->get($key); } - + /** * Sets a value in the shared memory storage. - * + * * This is a magic method, thanks to which any property you attempt to set * the value of will be set by the adapter, treating the property name as * the key of the value to set. The value is set without a TTL. - * + * * @param string $key Name of key to associate the value with. * @param mixed $value Value for the specified key. - * + * * @return bool TRUE on success, FALSE on failure. */ public function __set($key, $value) { return $this->set($key, $value); } - + /** * Checks if a specified key is in the storage. - * + * * This is a magic method, thanks to which any property you call isset() on * will be checked by the adapter, treating the property name as the key * of the value to check. - * + * * @param string $key Name of key to check. - * - * @return bool TRUE if the key is in the storage, FALSE otherwise. + * + * @return bool TRUE if the key is in the storage, FALSE otherwise. */ public function __isset($key) { return $this->exists($key); } - + /** * Deletes a value from the shared memory storage. - * + * * This is a magic method, thanks to which any property you attempt to unset * the value of will be unset by the adapter, treating the property name as * the key of the value to delete. - * + * * @param string $key Name of key to delete. - * + * * @return bool TRUE on success, FALSE on failure. */ public function __unset($key) { return $this->delete($key); } - + /** * Creates a new shared memory storage. - * - * Estabilishes a separate persistent storage. - * + * + * Establishes a separate persistent storage. + * * @param string $persistentId The ID for the storage. The storage will be * reused if it exists, or created if it doesn't exist. Data and locks * are namespaced by this ID. */ abstract public function __construct($persistentId); - + /** * Obtains a named lock. - * + * * @param string $key Name of the key to obtain. Note that $key may * repeat for each distinct $persistentId. - * @param double $timeout If the lock can't be immediatly obtained, the + * @param double $timeout If the lock can't be immediately obtained, the * script will block for at most the specified amount of seconds. * Setting this to 0 makes lock obtaining non blocking, and setting it * to NULL makes it block without a time limit. - * + * * @return bool TRUE on success, FALSE on failure. */ abstract public function lock($key, $timeout = null); - + /** * Releases a named lock. - * + * * @param string $key Name of the key to release. Note that $key may * repeat for each distinct $persistentId. - * + * * @return bool TRUE on success, FALSE on failure. */ abstract public function unlock($key); - + /** * Checks if a specified key is in the storage. - * + * * @param string $key Name of key to check. - * - * @return bool TRUE if the key is in the storage, FALSE otherwise. + * + * @return bool TRUE if the key is in the storage, FALSE otherwise. */ abstract public function exists($key); - + /** * Adds a value to the shared memory storage. - * + * * Adds a value to the storage if it doesn't exist, or fails if it does. - * + * * @param string $key Name of key to associate the value with. * @param mixed $value Value for the specified key. * @param int $ttl Seconds to store the value. If set to 0 indicates no * time limit. - * + * * @return bool TRUE on success, FALSE on failure. */ abstract public function add($key, $value, $ttl = 0); - + /** * Sets a value in the shared memory storage. - * + * * Adds a value to the storage if it doesn't exist, overwrites it otherwise. - * + * * @param string $key Name of key to associate the value with. * @param mixed $value Value for the specified key. * @param int $ttl Seconds to store the value. If set to 0 indicates no * time limit. - * + * * @return bool TRUE on success, FALSE on failure. */ abstract public function set($key, $value, $ttl = 0); - + /** * Gets a value from the shared memory storage. - * + * * Gets the current value, or throws an exception if it's not stored. - * + * * @param string $key Name of key to get the value of. - * + * * @return mixed The current value of the specified key. */ abstract public function get($key); - + /** * Deletes a value from the shared memory storage. - * + * * @param string $key Name of key to delete. - * + * * @return bool TRUE on success, FALSE on failure. */ abstract public function delete($key); - + /** * Increases a value from the shared memory storage. - * + * * Increases a value from the shared memory storage. Unlike a plain * set($key, get($key)+$step) combination, this function also implicitly * performs locking. - * + * * @param string $key Name of key to increase. * @param int $step Value to increase the key by. - * + * * @return int The new value. */ abstract public function inc($key, $step = 1); - + /** * Decreases a value from the shared memory storage. - * + * * Decreases a value from the shared memory storage. Unlike a plain * set($key, get($key)-$step) combination, this function also implicitly * performs locking. - * + * * @param string $key Name of key to decrease. * @param int $step Value to decrease the key by. - * + * * @return int The new value. */ abstract public function dec($key, $step = 1); /** * Sets a new value if a key has a certain value. - * + * * Sets a new value if a key has a certain value. This function only works * when $old and $new are longs. - * + * * @param string $key Key of the value to compare and set. * @param int $old The value to compare the key against. * @param int $new The value to set the key to. - * - * @return bool TRUE on success, FALSE on failure. + * + * @return bool TRUE on success, FALSE on failure. */ abstract public function cas($key, $old, $new); - + /** * Clears the persistent storage. - * + * * Clears the persistent storage, i.e. removes all keys. Locks are left * intact. - * + * * @return void */ abstract public function clear(); - + /** * Retrieve an external iterator - * + * * Returns an external iterator. - * + * * @param string|null $filter A PCRE regular expression. * Only matching keys will be iterated over. * Setting this to NULL matches all keys of this instance. * @param bool $keysOnly Whether to return only the keys, * or return both the keys and values. - * + * * @return \Traversable An array with all matching keys as array keys, * and values as array values. If $keysOnly is TRUE, the array keys are * numeric, and the array values are key names. @@ -368,4 +371,5 @@ abstract class SHM implements IteratorAggregate SHM::registerAdapter('\\' . __NAMESPACE__ . '\SHM\Adapter\Placebo'); SHM::registerAdapter('\\' . __NAMESPACE__ . '\SHM\Adapter\Wincache'); +SHM::registerAdapter('\\' . __NAMESPACE__ . '\SHM\Adapter\APCu'); SHM::registerAdapter('\\' . __NAMESPACE__ . '\SHM\Adapter\APC'); diff --git a/system/autoload/PEAR2/Cache/SHM/Adapter/APC.php b/system/autoload/PEAR2/Cache/SHM/Adapter/APC.php index a1b6ee7b..455d8db2 100644 --- a/system/autoload/PEAR2/Cache/SHM/Adapter/APC.php +++ b/system/autoload/PEAR2/Cache/SHM/Adapter/APC.php @@ -1,18 +1,19 @@ * @copyright 2011 Vasil Rangelov * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 - * @version 0.1.3 + * @version 0.2.0 * @link http://pear2.php.net/PEAR2_Cache_SHM */ /** @@ -32,7 +33,7 @@ use ArrayObject; /** * Shared memory adapter for the APC extension. - * + * * @category Caching * @package PEAR2_Cache_SHM * @author Vasil Rangelov @@ -42,32 +43,39 @@ use ArrayObject; class APC extends SHM { /** - * @var string ID of the current storage. + * ID of the current storage. + * + * @var string */ protected $persistentId; - + /** * List of persistent IDs. - * + * * A list of persistent IDs within the current request (as keys) with an int * (as a value) specifying the number of instances in the current request. * Used as an attempt to ensure implicit lock releases even on errors in the * critical sections, since APC doesn't have an actual locking function. - * @var array + * + * @var array */ protected static $requestInstances = array(); - + /** - * @var array Array of lock names (as values) for each persistent ID (as - * key) obtained during the current request. + * Array of lock names for each persistent ID. + * + * Array of lock names (as values) for each persistent ID (as key) obtained + * during the current request. + * + * @var array */ protected static $locksBackup = array(); /** * Creates a new shared memory storage. - * - * Estabilishes a separate persistent storage. - * + * + * Establishes a separate persistent storage. + * * @param string $persistentId The ID for the storage. The storage will be * reused if it exists, or created if it doesn't exist. Data and locks * are namespaced by this ID. @@ -87,35 +95,36 @@ class APC extends SHM true ); } - + /** * Checks if the adapter meets its requirements. - * + * * @return bool TRUE on success, FALSE on failure. */ public static function isMeetingRequirements() { return extension_loaded('apc') - && version_compare(phpversion('apc'), '3.0.13', '>=') + && version_compare(phpversion('apc'), '3.1.1', '>=') && ini_get('apc.enabled') && ('cli' !== PHP_SAPI || ini_get('apc.enable_cli')); } - + /** * Releases all locks in a storage. - * + * * This function is not meant to be used directly. It is implicitly called * by the the destructor and as a shutdown function when the request ends. * One of these calls ends up releasing any unreleased locks obtained * during the request. A lock is also implicitly released as soon as there * are no objects left in the current request using the same persistent ID. - * + * * @param string $internalPersistentId The internal persistent ID, the locks * of which are being released. * @param bool $isAtShutdown Whether the function was executed at * shutdown. - * + * * @return void + * * @internal */ public static function releaseLocks($internalPersistentId, $isAtShutdown) @@ -127,7 +136,7 @@ class APC extends SHM } } } - + /** * Releases any locks obtained by this instance as soon as there are no more * references to the object's persistent ID. @@ -137,18 +146,18 @@ class APC extends SHM static::$requestInstances[$this->persistentId]--; static::releaseLocks($this->persistentId, false); } - - + + /** * Obtains a named lock. - * + * * @param string $key Name of the key to obtain. Note that $key may * repeat for each distinct $persistentId. - * @param double $timeout If the lock can't be immediatly obtained, the + * @param double $timeout If the lock can't be immediately obtained, the * script will block for at most the specified amount of seconds. * Setting this to 0 makes lock obtaining non blocking, and setting it * to NULL makes it block without a time limit. - * + * * @return bool TRUE on success, FALSE on failure. */ public function lock($key, $timeout = null) @@ -164,13 +173,13 @@ class APC extends SHM static::$locksBackup[$this->persistentId] = $key; return true; } - + /** * Releases a named lock. - * + * * @param string $key Name of the key to release. Note that $key may * repeat for each distinct $persistentId. - * + * * @return bool TRUE on success, FALSE on failure. */ public function unlock($key) @@ -178,69 +187,71 @@ class APC extends SHM $lock = $this->persistentId . 'l ' . $key; $success = apc_delete($lock); if ($success) { - unset(static::$locksBackup[$this->persistentId][array_search( - $key, - static::$locksBackup[$this->persistentId], - true - )]); + unset( + static::$locksBackup[$this->persistentId][array_search( + $key, + static::$locksBackup[$this->persistentId], + true + )] + ); return true; } return false; } - + /** * Checks if a specified key is in the storage. - * + * * @param string $key Name of key to check. - * - * @return bool TRUE if the key is in the storage, FALSE otherwise. + * + * @return bool TRUE if the key is in the storage, FALSE otherwise. */ public function exists($key) { return apc_exists($this->persistentId . 'd ' . $key); } - + /** * Adds a value to the shared memory storage. - * + * * Adds a value to the storage if it doesn't exist, or fails if it does. - * + * * @param string $key Name of key to associate the value with. * @param mixed $value Value for the specified key. * @param int $ttl Seconds to store the value. If set to 0 indicates no * time limit. - * + * * @return bool TRUE on success, FALSE on failure. */ public function add($key, $value, $ttl = 0) { return apc_add($this->persistentId . 'd ' . $key, $value, $ttl); } - + /** * Sets a value in the shared memory storage. - * + * * Adds a value to the storage if it doesn't exist, overwrites it otherwise. - * + * * @param string $key Name of key to associate the value with. * @param mixed $value Value for the specified key. * @param int $ttl Seconds to store the value. If set to 0 indicates no * time limit. - * + * * @return bool TRUE on success, FALSE on failure. */ public function set($key, $value, $ttl = 0) { return apc_store($this->persistentId . 'd ' . $key, $value, $ttl); } - + /** * Gets a value from the shared memory storage. - * + * * Gets the current value, or throws an exception if it's not stored. - * + * * @param string $key Name of key to get the value of. - * + * * @return mixed The current value of the specified key. */ public function get($key) @@ -260,29 +271,29 @@ class APC extends SHM } throw new SHM\InvalidArgumentException('No such key in cache', 101); } - + /** * Deletes a value from the shared memory storage. - * + * * @param string $key Name of key to delete. - * + * * @return bool TRUE on success, FALSE on failure. */ public function delete($key) { return apc_delete($this->persistentId . 'd ' . $key); } - + /** * Increases a value from the shared memory storage. - * + * * Increases a value from the shared memory storage. Unlike a plain * set($key, get($key)+$step) combination, this function also implicitly * performs locking. - * + * * @param string $key Name of key to increase. * @param int $step Value to increase the key by. - * + * * @return int The new value. */ public function inc($key, $step = 1) @@ -300,17 +311,17 @@ class APC extends SHM } return $newValue; } - + /** * Decreases a value from the shared memory storage. - * + * * Decreases a value from the shared memory storage. Unlike a plain * set($key, get($key)-$step) combination, this function also implicitly * performs locking. - * + * * @param string $key Name of key to decrease. * @param int $step Value to decrease the key by. - * + * * @return int The new value. */ public function dec($key, $step = 1) @@ -331,27 +342,27 @@ class APC extends SHM /** * Sets a new value if a key has a certain value. - * + * * Sets a new value if a key has a certain value. This function only works * when $old and $new are longs. - * + * * @param string $key Key of the value to compare and set. * @param int $old The value to compare the key against. * @param int $new The value to set the key to. - * - * @return bool TRUE on success, FALSE on failure. + * + * @return bool TRUE on success, FALSE on failure. */ public function cas($key, $old, $new) { return apc_cas($this->persistentId . 'd ' . $key, $old, $new); } - + /** * Clears the persistent storage. - * + * * Clears the persistent storage, i.e. removes all keys. Locks are left * intact. - * + * * @return void */ public function clear() @@ -366,18 +377,18 @@ class APC extends SHM apc_delete($key); } } - + /** * Retrieve an external iterator - * + * * Returns an external iterator. - * + * * @param string|null $filter A PCRE regular expression. * Only matching keys will be iterated over. * Setting this to NULL matches all keys of this instance. * @param bool $keysOnly Whether to return only the keys, * or return both the keys and values. - * + * * @return ArrayObject An array with all matching keys as array keys, * and values as array values. If $keysOnly is TRUE, the array keys are * numeric, and the array values are key names. diff --git a/system/autoload/PEAR2/Cache/SHM/Adapter/APCu.php b/system/autoload/PEAR2/Cache/SHM/Adapter/APCu.php new file mode 100644 index 00000000..534b59e2 --- /dev/null +++ b/system/autoload/PEAR2/Cache/SHM/Adapter/APCu.php @@ -0,0 +1,416 @@ + + * @copyright 2011 Vasil Rangelov + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version 0.2.0 + * @link http://pear2.php.net/PEAR2_Cache_SHM + */ +/** + * The namespace declaration. + */ +namespace PEAR2\Cache\SHM\Adapter; + +/** + * Throws exceptions from this namespace, and extends from this class. + */ +use PEAR2\Cache\SHM; + +/** + * {@link APC::getIterator()} returns this object. + */ +use ArrayObject; + +/** + * Shared memory adapter for the APC extension. + * + * @category Caching + * @package PEAR2_Cache_SHM + * @author Vasil Rangelov + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @link http://pear2.php.net/PEAR2_Cache_SHM + */ +class APCu extends SHM +{ + /** + * ID of the current storage. + * + * @var string + */ + protected $persistentId; + + /** + * List of persistent IDs. + * + * A list of persistent IDs within the current request (as keys) with an int + * (as a value) specifying the number of instances in the current request. + * Used as an attempt to ensure implicit lock releases even on errors in the + * critical sections, since APC doesn't have an actual locking function. + * + * @var array + */ + protected static $requestInstances = array(); + + /** + * Array of lock names for each persistent ID. + * + * Array of lock names (as values) for each persistent ID (as key) obtained + * during the current request. + * + * @var array + */ + protected static $locksBackup = array(); + + /** + * Creates a new shared memory storage. + * + * Establishes a separate persistent storage. + * + * @param string $persistentId The ID for the storage. The storage will be + * reused if it exists, or created if it doesn't exist. Data and locks + * are namespaced by this ID. + */ + public function __construct($persistentId) + { + $this->persistentId = __CLASS__ . ' ' . $persistentId; + if (isset(static::$requestInstances[$this->persistentId])) { + static::$requestInstances[$this->persistentId]++; + } else { + static::$requestInstances[$this->persistentId] = 1; + static::$locksBackup[$this->persistentId] = array(); + } + register_shutdown_function( + get_called_class() . '::releaseLocks', + $this->persistentId, + true + ); + } + + /** + * Checks if the adapter meets its requirements. + * + * @return bool TRUE on success, FALSE on failure. + */ + public static function isMeetingRequirements() + { + return extension_loaded('apcu') + && version_compare(phpversion('apcu'), '5.0.0', '>=') + && ini_get('apc.enabled') + && ('cli' !== PHP_SAPI || ini_get('apc.enable_cli')); + } + + /** + * Releases all locks in a storage. + * + * This function is not meant to be used directly. It is implicitly called + * by the the destructor and as a shutdown function when the request ends. + * One of these calls ends up releasing any unreleased locks obtained + * during the request. A lock is also implicitly released as soon as there + * are no objects left in the current request using the same persistent ID. + * + * @param string $internalPersistentId The internal persistent ID, the locks + * of which are being released. + * @param bool $isAtShutdown Whether the function was executed at + * shutdown. + * + * @return void + * + * @internal + */ + public static function releaseLocks($internalPersistentId, $isAtShutdown) + { + $hasInstances = 0 !== static::$requestInstances[$internalPersistentId]; + if ($isAtShutdown === $hasInstances) { + foreach (static::$locksBackup[$internalPersistentId] as $key) { + apcu_delete($internalPersistentId . 'l ' . $key); + } + } + } + + /** + * Releases any locks obtained by this instance as soon as there are no more + * references to the object's persistent ID. + */ + public function __destruct() + { + static::$requestInstances[$this->persistentId]--; + static::releaseLocks($this->persistentId, false); + } + + + /** + * Obtains a named lock. + * + * @param string $key Name of the key to obtain. Note that $key may + * repeat for each distinct $persistentId. + * @param double $timeout If the lock can't be immediately obtained, the + * script will block for at most the specified amount of seconds. + * Setting this to 0 makes lock obtaining non blocking, and setting it + * to NULL makes it block without a time limit. + * + * @return bool TRUE on success, FALSE on failure. + */ + public function lock($key, $timeout = null) + { + $lock = $this->persistentId . 'l ' . $key; + $hasTimeout = $timeout !== null; + $start = microtime(true); + while (!apcu_add($lock, 1)) { + if ($hasTimeout && (microtime(true) - $start) > $timeout) { + return false; + } + } + static::$locksBackup[$this->persistentId] = $key; + return true; + } + + /** + * Releases a named lock. + * + * @param string $key Name of the key to release. Note that $key may + * repeat for each distinct $persistentId. + * + * @return bool TRUE on success, FALSE on failure. + */ + public function unlock($key) + { + $lock = $this->persistentId . 'l ' . $key; + $success = apcu_delete($lock); + if ($success) { + unset( + static::$locksBackup[$this->persistentId][array_search( + $key, + static::$locksBackup[$this->persistentId], + true + )] + ); + return true; + } + return false; + } + + /** + * Checks if a specified key is in the storage. + * + * @param string $key Name of key to check. + * + * @return bool TRUE if the key is in the storage, FALSE otherwise. + */ + public function exists($key) + { + return apcu_exists($this->persistentId . 'd ' . $key); + } + + /** + * Adds a value to the shared memory storage. + * + * Adds a value to the storage if it doesn't exist, or fails if it does. + * + * @param string $key Name of key to associate the value with. + * @param mixed $value Value for the specified key. + * @param int $ttl Seconds to store the value. If set to 0 indicates no + * time limit. + * + * @return bool TRUE on success, FALSE on failure. + */ + public function add($key, $value, $ttl = 0) + { + return apcu_add($this->persistentId . 'd ' . $key, $value, $ttl); + } + + /** + * Sets a value in the shared memory storage. + * + * Adds a value to the storage if it doesn't exist, overwrites it otherwise. + * + * @param string $key Name of key to associate the value with. + * @param mixed $value Value for the specified key. + * @param int $ttl Seconds to store the value. If set to 0 indicates no + * time limit. + * + * @return bool TRUE on success, FALSE on failure. + */ + public function set($key, $value, $ttl = 0) + { + return apcu_store($this->persistentId . 'd ' . $key, $value, $ttl); + } + + /** + * Gets a value from the shared memory storage. + * + * Gets the current value, or throws an exception if it's not stored. + * + * @param string $key Name of key to get the value of. + * + * @return mixed The current value of the specified key. + */ + public function get($key) + { + $fullKey = $this->persistentId . 'd ' . $key; + if (apcu_exists($fullKey)) { + $value = apcu_fetch($fullKey, $success); + if (!$success) { + throw new SHM\InvalidArgumentException( + 'Unable to fetch key. ' . + 'Key has either just now expired or (if no TTL was set) ' . + 'is possibly in a race condition with another request.', + 100 + ); + } + return $value; + } + throw new SHM\InvalidArgumentException('No such key in cache', 101); + } + + /** + * Deletes a value from the shared memory storage. + * + * @param string $key Name of key to delete. + * + * @return bool TRUE on success, FALSE on failure. + */ + public function delete($key) + { + return apcu_delete($this->persistentId . 'd ' . $key); + } + + /** + * Increases a value from the shared memory storage. + * + * Increases a value from the shared memory storage. Unlike a plain + * set($key, get($key)+$step) combination, this function also implicitly + * performs locking. + * + * @param string $key Name of key to increase. + * @param int $step Value to increase the key by. + * + * @return int The new value. + */ + public function inc($key, $step = 1) + { + $newValue = apcu_inc( + $this->persistentId . 'd ' . $key, + (int) $step, + $success + ); + if (!$success) { + throw new SHM\InvalidArgumentException( + 'Unable to increase the value. Are you sure the value is int?', + 102 + ); + } + return $newValue; + } + + /** + * Decreases a value from the shared memory storage. + * + * Decreases a value from the shared memory storage. Unlike a plain + * set($key, get($key)-$step) combination, this function also implicitly + * performs locking. + * + * @param string $key Name of key to decrease. + * @param int $step Value to decrease the key by. + * + * @return int The new value. + */ + public function dec($key, $step = 1) + { + $newValue = apcu_dec( + $this->persistentId . 'd ' . $key, + (int) $step, + $success + ); + if (!$success) { + throw new SHM\InvalidArgumentException( + 'Unable to decrease the value. Are you sure the value is int?', + 103 + ); + } + return $newValue; + } + + /** + * Sets a new value if a key has a certain value. + * + * Sets a new value if a key has a certain value. This function only works + * when $old and $new are longs. + * + * @param string $key Key of the value to compare and set. + * @param int $old The value to compare the key against. + * @param int $new The value to set the key to. + * + * @return bool TRUE on success, FALSE on failure. + */ + public function cas($key, $old, $new) + { + return apcu_cas($this->persistentId . 'd ' . $key, $old, $new); + } + + /** + * Clears the persistent storage. + * + * Clears the persistent storage, i.e. removes all keys. Locks are left + * intact. + * + * @return void + */ + public function clear() + { + foreach (new APCIterator( + 'user', + '/^' . preg_quote($this->persistentId, '/') . 'd /', + APC_ITER_KEY, + 100, + APC_LIST_ACTIVE + ) as $key) { + apcu_delete($key); + } + } + + /** + * Retrieve an external iterator + * + * Returns an external iterator. + * + * @param string|null $filter A PCRE regular expression. + * Only matching keys will be iterated over. + * Setting this to NULL matches all keys of this instance. + * @param bool $keysOnly Whether to return only the keys, + * or return both the keys and values. + * + * @return ArrayObject An array with all matching keys as array keys, + * and values as array values. If $keysOnly is TRUE, the array keys are + * numeric, and the array values are key names. + */ + public function getIterator($filter = null, $keysOnly = false) + { + $result = array(); + foreach (new APCUIterator( + '/^' . preg_quote($this->persistentId, '/') . 'd /', + APC_ITER_KEY, + 100, + APC_LIST_ACTIVE + ) as $key) { + $localKey = strstr($key, $this->persistentId . 'd '); + if (null === $filter || preg_match($filter, $localKey)) { + if ($keysOnly) { + $result[] = $localKey; + } else { + $result[$localKey] = apcu_fetch($key); + } + } + } + return new ArrayObject($result); + } +} diff --git a/system/autoload/PEAR2/Cache/SHM/Adapter/Placebo.php b/system/autoload/PEAR2/Cache/SHM/Adapter/Placebo.php index bbce22f4..56c35f3e 100644 --- a/system/autoload/PEAR2/Cache/SHM/Adapter/Placebo.php +++ b/system/autoload/PEAR2/Cache/SHM/Adapter/Placebo.php @@ -1,18 +1,19 @@ * @copyright 2011 Vasil Rangelov * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 - * @version 0.1.3 + * @version 0.2.0 * @link http://pear2.php.net/PEAR2_Cache_SHM */ /** @@ -31,10 +32,10 @@ use PEAR2\Cache\SHM; use ArrayObject; /** - * This adapter is not truly persistent. It is intended to emulate persistency + * This adapter is not truly persistent. It is intended to emulate persistence * in non persistent environments, so that upper level applications can use a * single code path for persistent and non persistent code. - * + * * @category Caching * @package PEAR2_Cache_SHM * @author Vasil Rangelov @@ -44,42 +45,50 @@ use ArrayObject; class Placebo extends SHM { /** - * @var string ID of the current storage. + * ID of the current storage. + * + * @var string */ protected $persistentId; - + /** * List of persistent IDs. - * + * * A list of persistent IDs within the current request (as keys) with an int * (as a value) specifying the number of instances in the current request. * Used as an attempt to ensure implicit lock releases on destruction. - * @var array + * + * @var array */ protected static $requestInstances = array(); - + /** - * @var array Array of lock names (as values) for each persistent ID (as + * Array of lock names for each persistent ID. + * + * Array of lock names (as values) for each persistent ID (as * key) obtained during the current request. + * + * @var array */ protected static $locksBackup = array(); - + /** * The data storage. - * + * * Each persistent ID is a key, and the value is an array. * Each such array has data keys as its keys, and an array as a value. * Each such array has as its elements the value, the timeout and the time * the data was set. - * @var array + * + * @var array */ protected static $data = array(); - + /** * Creates a new shared memory storage. - * - * Estabilishes a separate persistent storage. - * + * + * Establishes a separate persistent storage. + * * @param string $persistentId The ID for the storage. The storage will be * reused if it exists, or created if it doesn't exist. Data and locks * are namespaced by this ID. @@ -95,9 +104,9 @@ class Placebo extends SHM } $this->persistentId = $persistentId; } - + /** - * Releases any unreleased locks. + * Releases any unreleased locks. */ public function __destruct() { @@ -105,23 +114,23 @@ class Placebo extends SHM static::$locksBackup[$this->persistentId] = array(); } } - + /** * Checks if the adapter meets its requirements. - * + * * @return bool TRUE on success, FALSE on failure. */ public static function isMeetingRequirements() { return 'cli' === PHP_SAPI; } - + /** * Pretends to obtain a lock. - * + * * @param string $key Ignored. * @param double $timeout Ignored. - * + * * @return bool TRUE on success, FALSE on failure. */ public function lock($key, $timeout = null) @@ -133,12 +142,12 @@ class Placebo extends SHM static::$locksBackup[$this->persistentId][] = $key; return true; } - + /** * Pretends to release a lock. - * + * * @param string $key Ignored - * + * * @return bool TRUE on success, FALSE on failure. */ public function unlock($key) @@ -147,36 +156,38 @@ class Placebo extends SHM if (!in_array($key, static::$locksBackup[$this->persistentId], true)) { return false; } - unset(static::$locksBackup[$this->persistentId][array_search( - $key, - static::$locksBackup[$this->persistentId], - true - )]); + unset( + static::$locksBackup[$this->persistentId][array_search( + $key, + static::$locksBackup[$this->persistentId], + true + )] + ); return true; } - + /** * Checks if a specified key is in the storage. - * + * * @param string $key Name of key to check. - * - * @return bool TRUE if the key is in the storage, FALSE otherwise. + * + * @return bool TRUE if the key is in the storage, FALSE otherwise. */ public function exists($key) { return array_key_exists($key, static::$data[$this->persistentId]); } - + /** * Adds a value to the shared memory storage. - * + * * Adds a value to the storage if it doesn't exist, or fails if it does. - * + * * @param string $key Name of key to associate the value with. * @param mixed $value Value for the specified key. * @param int $ttl Because "true" adapters purge the cache at the next * request, this setting is ignored. - * + * * @return bool TRUE on success, FALSE on failure. */ public function add($key, $value, $ttl = 0) @@ -186,17 +197,17 @@ class Placebo extends SHM } return $this->set($key, $value, $ttl); } - + /** * Sets a value in the shared memory storage. - * + * * Adds a value to the storage if it doesn't exist, overwrites it otherwise. - * + * * @param string $key Name of key to associate the value with. * @param mixed $value Value for the specified key. * @param int $ttl Because "true" adapters purge the cache at the next * request, this setting is ignored. - * + * * @return bool TRUE on success, FALSE on failure. */ public function set($key, $value, $ttl = 0) @@ -204,14 +215,14 @@ class Placebo extends SHM static::$data[$this->persistentId][$key] = $value; return true; } - + /** * Gets a value from the shared memory storage. - * + * * Gets the current value, or throws an exception if it's not stored. - * + * * @param string $key Name of key to get the value of. - * + * * @return mixed The current value of the specified key. */ public function get($key) @@ -224,12 +235,12 @@ class Placebo extends SHM 200 ); } - + /** * Deletes a value from the shared memory storage. - * + * * @param string $key Name of key to delete. - * + * * @return bool TRUE on success, FALSE on failure. */ public function delete($key) @@ -240,17 +251,17 @@ class Placebo extends SHM } return false; } - + /** * Increases a value from the shared memory storage. - * + * * Increases a value from the shared memory storage. Unlike a plain * set($key, get($key)+$step) combination, this function also implicitly * performs locking. - * + * * @param string $key Name of key to increase. * @param int $step Value to increase the key by. - * + * * @return int The new value. */ public function inc($key, $step = 1) @@ -265,17 +276,17 @@ class Placebo extends SHM } return $this->get($key); } - + /** * Decreases a value from the shared memory storage. - * + * * Decreases a value from the shared memory storage. Unlike a plain * set($key, get($key)-$step) combination, this function also implicitly * performs locking. - * + * * @param string $key Name of key to decrease. * @param int $step Value to decrease the key by. - * + * * @return int The new value. */ public function dec($key, $step = 1) @@ -293,46 +304,46 @@ class Placebo extends SHM /** * Sets a new value if a key has a certain value. - * + * * Sets a new value if a key has a certain value. This function only works * when $old and $new are longs. - * + * * @param string $key Key of the value to compare and set. * @param int $old The value to compare the key against. * @param int $new The value to set the key to. - * - * @return bool TRUE on success, FALSE on failure. + * + * @return bool TRUE on success, FALSE on failure. */ public function cas($key, $old, $new) { return $this->exists($key) && ($this->get($key) === $old) && is_int($new) && $this->set($key, $new); } - + /** * Clears the persistent storage. - * + * * Clears the persistent storage, i.e. removes all keys. Locks are left * intact. - * + * * @return void */ public function clear() { static::$data[$this->persistentId] = array(); } - + /** * Retrieve an external iterator - * + * * Returns an external iterator. - * + * * @param string|null $filter A PCRE regular expression. * Only matching keys will be iterated over. * Setting this to NULL matches all keys of this instance. * @param bool $keysOnly Whether to return only the keys, * or return both the keys and values. - * + * * @return ArrayObject An array with all matching keys as array keys, * and values as array values. If $keysOnly is TRUE, the array keys are * numeric, and the array values are key names. @@ -346,7 +357,7 @@ class Placebo extends SHM : static::$data[$this->persistentId] ); } - + $result = array(); foreach (static::$data[$this->persistentId] as $key => $value) { if (preg_match($filter, $key)) { diff --git a/system/autoload/PEAR2/Cache/SHM/Adapter/Wincache.php b/system/autoload/PEAR2/Cache/SHM/Adapter/Wincache.php index 5d2e7261..5633f453 100644 --- a/system/autoload/PEAR2/Cache/SHM/Adapter/Wincache.php +++ b/system/autoload/PEAR2/Cache/SHM/Adapter/Wincache.php @@ -1,18 +1,19 @@ * @copyright 2011 Vasil Rangelov * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 - * @version 0.1.3 + * @version 0.2.0 * @link http://pear2.php.net/PEAR2_Cache_SHM */ /** @@ -32,7 +33,7 @@ use ArrayObject; /** * Shared memory adapter for the WinCache extension. - * + * * @category Caching * @package PEAR2_Cache_SHM * @author Vasil Rangelov @@ -42,30 +43,35 @@ use ArrayObject; class Wincache extends SHM { /** - * @var string ID of the current storage. + * ID of the current storage. + * + * @var string */ protected $persistentId; - + /** * List of persistent IDs. - * + * * A list of persistent IDs within the current request (as keys) with an int * (as a value) specifying the number of instances in the current request. * Used as an attempt to ensure implicit lock releases on destruction. - * @var array + * + * @var array */ protected static $requestInstances = array(); - + /** - * @var array Array of lock names obtained during the current request. + * Array of lock names obtained during the current request. + * + * @var array */ protected static $locksBackup = array(); - + /** * Creates a new shared memory storage. - * - * Estabilishes a separate persistent storage. - * + * + * Establishes a separate persistent storage. + * * @param string $persistentId The ID for the storage. The storage will be * reused if it exists, or created if it doesn't exist. Data and locks * are namespaced by this ID. @@ -81,28 +87,29 @@ class Wincache extends SHM static::$locksBackup[$this->persistentId] = array(); } } - + /** * Encodes a lock name - * + * * Encodes a lock name, so that it can be properly obtained. The scheme used * is a subset of URL encoding, with only the "%" and "\" characters being * escaped. The encoding itself is necessary, since lock names can't contain * the "\" character. - * + * * @param string $name The lock name to encode. - * + * * @return string The encoded name. + * * @link http://msdn.microsoft.com/en-us/library/ms682411(VS.85).aspx */ protected static function encodeLockName($name) { return str_replace(array('%', '\\'), array('%25', '%5C'), $name); } - + /** * Checks if the adapter meets its requirements. - * + * * @return bool TRUE on success, FALSE on failure. */ public static function isMeetingRequirements() @@ -112,7 +119,7 @@ class Wincache extends SHM && ini_get('wincache.ucenabled') && ('cli' !== PHP_SAPI || ini_get('wincache.enablecli')); } - + /** * Releases any locks obtained by this instance as soon as there are no more * references to the object's persistent ID. @@ -128,15 +135,15 @@ class Wincache extends SHM } } - + /** * Obtains a named lock. - * + * * @param string $key Name of the key to obtain. Note that $key may * repeat for each distinct $persistentId. * @param double $timeout Ignored with WinCache. Script will always block if - * the lock can't be immediatly obtained. - * + * the lock can't be immediately obtained. + * * @return bool TRUE on success, FALSE on failure. */ public function lock($key, $timeout = null) @@ -149,13 +156,13 @@ class Wincache extends SHM } return $result; } - + /** * Releases a named lock. - * + * * @param string $key Name of the key to release. Note that $key may * repeat for each distinct $persistentId. - * + * * @return bool TRUE on success, FALSE on failure. */ public function unlock($key) @@ -164,68 +171,70 @@ class Wincache extends SHM $this->persistentId . static::encodeLockName($key) ); if ($result) { - unset(static::$locksBackup[$this->persistentId][array_search( - $key, - static::$locksBackup[$this->persistentId], - true - )]); + unset( + static::$locksBackup[$this->persistentId][array_search( + $key, + static::$locksBackup[$this->persistentId], + true + )] + ); } return $result; } - + /** * Checks if a specified key is in the storage. - * + * * @param string $key Name of key to check. - * - * @return bool TRUE if the key is in the storage, FALSE otherwise. + * + * @return bool TRUE if the key is in the storage, FALSE otherwise. */ public function exists($key) { return wincache_ucache_exists($this->persistentId . $key); } - + /** * Adds a value to the shared memory storage. - * + * * Sets a value to the storage if it doesn't exist, or fails if it does. - * + * * @param string $key Name of key to associate the value with. * @param mixed $value Value for the specified key. * @param int $ttl Seconds to store the value. If set to 0 indicates no * time limit. - * + * * @return bool TRUE on success, FALSE on failure. */ public function add($key, $value, $ttl = 0) { return wincache_ucache_add($this->persistentId . $key, $value, $ttl); } - + /** * Sets a value in the shared memory storage. - * + * * Adds a value to the storage if it doesn't exist, overwrites it otherwise. - * + * * @param string $key Name of key to associate the value with. * @param mixed $value Value for the specified key. * @param int $ttl Seconds to store the value. If set to 0 indicates no * time limit. - * + * * @return bool TRUE on success, FALSE on failure. */ public function set($key, $value, $ttl = 0) { return wincache_ucache_set($this->persistentId . $key, $value, $ttl); } - + /** * Gets a value from the shared memory storage. - * + * * Gets the current value, or throws an exception if it's not stored. - * + * * @param string $key Name of key to get the value of. - * + * * @return mixed The current value of the specified key. */ public function get($key) @@ -239,29 +248,29 @@ class Wincache extends SHM } return $value; } - + /** * Deletes a value from the shared memory storage. - * + * * @param string $key Name of key to delete. - * + * * @return bool TRUE on success, FALSE on failure. */ public function delete($key) { return wincache_ucache_delete($this->persistentId . $key); } - + /** * Increases a value from the shared memory storage. - * + * * Increases a value from the shared memory storage. Unlike a plain * set($key, get($key)+$step) combination, this function also implicitly * performs locking. - * + * * @param string $key Name of key to increase. * @param int $step Value to increase the key by. - * + * * @return int The new value. */ public function inc($key, $step = 1) @@ -279,17 +288,17 @@ class Wincache extends SHM } return $newValue; } - + /** * Decreases a value from the shared memory storage. - * + * * Decreases a value from the shared memory storage. Unlike a plain * set($key, get($key)-$step) combination, this function also implicitly * performs locking. - * + * * @param string $key Name of key to decrease. * @param int $step Value to decrease the key by. - * + * * @return int The new value. */ public function dec($key, $step = 1) @@ -310,27 +319,27 @@ class Wincache extends SHM /** * Sets a new value if a key has a certain value. - * + * * Sets a new value if a key has a certain value. This function only works * when $old and $new are longs. - * + * * @param string $key Key of the value to compare and set. * @param int $old The value to compare the key against. * @param int $new The value to set the key to. - * - * @return bool TRUE on success, FALSE on failure. + * + * @return bool TRUE on success, FALSE on failure. */ public function cas($key, $old, $new) { return wincache_ucache_cas($this->persistentId . $key, $old, $new); } - + /** * Clears the persistent storage. - * + * * Clears the persistent storage, i.e. removes all keys. Locks are left * intact. - * + * * @return void */ public function clear() @@ -344,18 +353,18 @@ class Wincache extends SHM } } } - + /** * Retrieve an external iterator - * + * * Returns an external iterator. - * + * * @param string|null $filter A PCRE regular expression. * Only matching keys will be iterated over. * Setting this to NULL matches all keys of this instance. * @param bool $keysOnly Whether to return only the keys, * or return both the keys and values. - * + * * @return ArrayObject An array with all matching keys as array keys, * and values as array values. If $keysOnly is TRUE, the array keys are * numeric, and the array values are key names. diff --git a/system/autoload/PEAR2/Cache/SHM/Exception.php b/system/autoload/PEAR2/Cache/SHM/Exception.php index 59847298..cfcac1ec 100644 --- a/system/autoload/PEAR2/Cache/SHM/Exception.php +++ b/system/autoload/PEAR2/Cache/SHM/Exception.php @@ -1,9 +1,10 @@ * @copyright 2011 Vasil Rangelov * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 - * @version 0.1.3 + * @version 0.2.0 * @link http://pear2.php.net/PEAR2_Cache_SHM */ /** diff --git a/system/autoload/PEAR2/Cache/SHM/InvalidArgumentException.php b/system/autoload/PEAR2/Cache/SHM/InvalidArgumentException.php index 817f2ab1..556edddb 100644 --- a/system/autoload/PEAR2/Cache/SHM/InvalidArgumentException.php +++ b/system/autoload/PEAR2/Cache/SHM/InvalidArgumentException.php @@ -1,9 +1,10 @@ * @copyright 2011 Vasil Rangelov * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 - * @version 0.1.3 + * @version 0.2.0 * @link http://pear2.php.net/PEAR2_Cache_SHM */ /** diff --git a/system/autoload/PEAR2/Console/CommandLine.php b/system/autoload/PEAR2/Console/CommandLine.php index f2fc4784..322607bc 100644 --- a/system/autoload/PEAR2/Console/CommandLine.php +++ b/system/autoload/PEAR2/Console/CommandLine.php @@ -59,6 +59,7 @@ class CommandLine * Error messages. * * @var array $errors Error messages + * * @todo move this to PEAR2\Console\CommandLine\MessageProvider */ public static $errors = array( @@ -130,7 +131,7 @@ class CommandLine /** * The command line parser renderer instance. * - * @var object that implements PEAR2\Console\CommandLine\Renderer interface + * @var PEAR2\Console\CommandLine\Renderer a renderer */ public $renderer = false; @@ -144,7 +145,7 @@ class CommandLine /** * The command line message provider instance. * - * @var PEAR2\Console\CommandLine\MessageProvider A message provider instance + * @var PEAR2\Console\CommandLine\MessageProvider A message provider */ public $message_provider = false; @@ -191,6 +192,7 @@ class CommandLine * convenience. * * @var PEAR2\Console\CommandLine The parent instance + * * @todo move CommandLine::parent to CommandLine\Command */ public $parent = false; @@ -272,7 +274,7 @@ class CommandLine * * * @var array - * @see PEAR2\Console\CommandLine\MessageProvider_Default + * @see PEAR2\Console\CommandLine\MessageProvider\DefaultProvider */ public $messages = array(); @@ -286,6 +288,9 @@ class CommandLine */ private $_dispatchLater = array(); + private $_lastopt = false; + private $_stopflag = false; + // }}} // __construct() {{{ @@ -345,7 +350,7 @@ class CommandLine // set default instances $this->renderer = new CommandLine\Renderer_Default($this); $this->outputter = new CommandLine\Outputter_Default(); - $this->message_provider = new CommandLine\MessageProvider_Default(); + $this->message_provider = new CommandLine\MessageProvider\DefaultProvider(); } // }}} @@ -481,6 +486,7 @@ class CommandLine * @param array $params An array containing the argument attributes * * @return PEAR2\Console\CommandLine\Argument the added argument + * * @see PEAR2\Console\CommandLine\Argument */ public function addArgument($name, $params = array()) @@ -842,6 +848,7 @@ class CommandLine * @param array $params An array of search=>replaces entries * * @return void + * * @todo remove Console::triggerError() and use exceptions only */ public static function triggerError($msgId, $level, $params=array()) @@ -912,7 +919,7 @@ class CommandLine // Check if an invalid subcommand was specified. If there are // subcommands and no arguments, but an argument was provided, it is // an invalid subcommand. - if ( count($this->commands) > 0 + if (count($this->commands) > 0 && count($this->args) === 0 && count($args) > 0 ) { @@ -925,7 +932,7 @@ class CommandLine } // if subcommand_required is set to true we must check that we have a // subcommand. - if ( count($this->commands) + if (count($this->commands) && $this->subcommand_required && !$result->command_name ) { @@ -989,23 +996,21 @@ class CommandLine */ protected function parseToken($token, $result, &$args, $argc) { - static $lastopt = false; - static $stopflag = false; $last = $argc === 0; - if (!$stopflag && $lastopt) { + if (!$this->_stopflag && $this->_lastopt) { if (substr($token, 0, 1) == '-') { - if ($lastopt->argument_optional) { - $this->_dispatchAction($lastopt, '', $result); - if ($lastopt->action != 'StoreArray') { - $lastopt = false; + if ($this->_lastopt->argument_optional) { + $this->_dispatchAction($this->_lastopt, '', $result); + if ($this->_lastopt->action != 'StoreArray') { + $this->_lastopt = false; } - } else if (isset($result->options[$lastopt->name])) { + } else if (isset($result->options[$this->_lastopt->name])) { // case of an option that expect a list of args - $lastopt = false; + $this->_lastopt = false; } else { throw CommandLine\Exception::factory( 'OPTION_VALUE_REQUIRED', - array('name' => $lastopt->name), + array('name' => $this->_lastopt->name), $this, $this->messages ); @@ -1015,8 +1020,8 @@ class CommandLine // is to consider that if there's already an element in the // array, and the commandline expects one or more args, we // leave last tokens to arguments - if ($lastopt->action == 'StoreArray' - && !empty($result->options[$lastopt->name]) + if ($this->_lastopt->action == 'StoreArray' + && !empty($result->options[$this->_lastopt->name]) && count($this->args) > ($argc + count($args)) ) { if (!is_null($token)) { @@ -1024,22 +1029,22 @@ class CommandLine } return; } - if (!is_null($token) || $lastopt->action == 'Password') { - $this->_dispatchAction($lastopt, $token, $result); + if (!is_null($token) || $this->_lastopt->action == 'Password') { + $this->_dispatchAction($this->_lastopt, $token, $result); } - if ($lastopt->action != 'StoreArray') { - $lastopt = false; + if ($this->_lastopt->action != 'StoreArray') { + $this->_lastopt = false; } return; } } - if (!$stopflag && substr($token, 0, 2) == '--') { + if (!$this->_stopflag && substr($token, 0, 2) == '--') { // a long option $optkv = explode('=', $token, 2); if (trim($optkv[0]) == '--') { // the special argument "--" forces in all cases the end of // option scanning. - $stopflag = true; + $this->_stopflag = true; return; } $opt = $this->findOption($optkv[0]); @@ -1072,14 +1077,14 @@ class CommandLine ); } // we will have a value next time - $lastopt = $opt; + $this->_lastopt = $opt; return; } if ($opt->action == 'StoreArray') { - $lastopt = $opt; + $this->_lastopt = $opt; } $this->_dispatchAction($opt, $value, $result); - } else if (!$stopflag && substr($token, 0, 1) == '-') { + } else if (!$this->_stopflag && substr($token, 0, 1) == '-') { // a short option $optname = substr($token, 0, 2); if ($optname == '-') { @@ -1100,7 +1105,7 @@ class CommandLine // in short: handle -f and -f $next = substr($token, 2, 1); // check if we must wait for a value - if ($next === false) { + if (!$next) { if ($opt->expectsArgument()) { if ($last && !$opt->argument_optional) { throw CommandLine\Exception::factory( @@ -1111,7 +1116,7 @@ class CommandLine ); } // we will have a value next time - $lastopt = $opt; + $this->_lastopt = $opt; return; } $value = false; @@ -1136,7 +1141,7 @@ class CommandLine } } if ($opt->action == 'StoreArray') { - $lastopt = $opt; + $this->_lastopt = $opt; } $value = substr($token, 2); } @@ -1145,8 +1150,8 @@ class CommandLine // We have an argument. // if we are in POSIX compliant mode, we must set the stop flag to // true in order to stop option parsing. - if (!$stopflag && $this->force_posix) { - $stopflag = true; + if (!$this->_stopflag && $this->force_posix) { + $this->_stopflag = true; } if (!is_null($token)) { $args[] = $token; diff --git a/system/autoload/PEAR2/Console/CommandLine/Action.php b/system/autoload/PEAR2/Console/CommandLine/Action.php index 2aca60ad..a1d8cb3b 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Action.php +++ b/system/autoload/PEAR2/Console/CommandLine/Action.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ namespace PEAR2\Console\CommandLine; diff --git a/system/autoload/PEAR2/Console/CommandLine/Action/Callback.php b/system/autoload/PEAR2/Console/CommandLine/Action/Callback.php index a5edd7a7..e5eb2101 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Action/Callback.php +++ b/system/autoload/PEAR2/Console/CommandLine/Action/Callback.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ namespace PEAR2\Console\CommandLine\Action; diff --git a/system/autoload/PEAR2/Console/CommandLine/Action/Counter.php b/system/autoload/PEAR2/Console/CommandLine/Action/Counter.php index fd2adb94..919b8f0b 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Action/Counter.php +++ b/system/autoload/PEAR2/Console/CommandLine/Action/Counter.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ @@ -46,7 +47,7 @@ use PEAR2\Console\CommandLine; * * $ script.php -v -v -v * - * or: + * or: * * $ script.php -vvv * diff --git a/system/autoload/PEAR2/Console/CommandLine/Action/Help.php b/system/autoload/PEAR2/Console/CommandLine/Action/Help.php index b4a733aa..1c7778ed 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Action/Help.php +++ b/system/autoload/PEAR2/Console/CommandLine/Action/Help.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ diff --git a/system/autoload/PEAR2/Console/CommandLine/Action/List.php b/system/autoload/PEAR2/Console/CommandLine/Action/List.php index 3419f292..15555d0e 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Action/List.php +++ b/system/autoload/PEAR2/Console/CommandLine/Action/List.php @@ -11,21 +11,22 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License + * @license http://opensource.org/licenses/mit-license.php MIT License * @version CVS: $Id: List.php,v 1.2 2009/02/27 08:03:17 izi Exp $ * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ namespace PEAR2\Console\CommandLine; /** - * Class that represent the List action, a special action that simply output an + * Class that represent the List action, a special action that simply output an * array as a list. * * @category Console @@ -43,10 +44,10 @@ class Action_List extends Action /** * Executes the action with the value entered by the user. * Possible parameters are: - * - message: an alternative message to display instead of the default + * - message: an alternative message to display instead of the default * message, * - delimiter: an alternative delimiter instead of the comma, - * - post: a string to append after the message (default is the new line + * - post: a string to append after the message (default is the new line * char). * * @param mixed $value The option value @@ -57,8 +58,8 @@ class Action_List extends Action public function execute($value = false, $params = array()) { $list = isset($params['list']) ? $params['list'] : array(); - $msg = isset($params['message']) - ? $params['message'] + $msg = isset($params['message']) + ? $params['message'] : $this->parser->message_provider->get('LIST_DISPLAYED_MESSAGE'); $del = isset($params['delimiter']) ? $params['delimiter'] : ', '; $post = isset($params['post']) ? $params['post'] : "\n"; diff --git a/system/autoload/PEAR2/Console/CommandLine/Action/Password.php b/system/autoload/PEAR2/Console/CommandLine/Action/Password.php index ad825398..3ce67035 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Action/Password.php +++ b/system/autoload/PEAR2/Console/CommandLine/Action/Password.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ @@ -27,8 +28,8 @@ namespace PEAR2\Console\CommandLine\Action; use PEAR2\Console\CommandLine; /** - * Class that represent the Password action, a special action that allow the - * user to specify the password on the commandline or to be prompted for + * Class that represent the Password action, a special action that allow the + * user to specify the password on the commandline or to be prompted for * entering it. * * @category Console @@ -62,7 +63,8 @@ class Password extends CommandLine\Action * Prompts the password to the user without echoing it. * * @return string - * @todo not echo-ing the password does not work on windows is there a way + * + * @todo not echo-ing the password does not work on windows is there a way * to make this work ? */ private function _promptPassword() diff --git a/system/autoload/PEAR2/Console/CommandLine/Action/StoreArray.php b/system/autoload/PEAR2/Console/CommandLine/Action/StoreArray.php index af9c8d48..8ed2b8d4 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Action/StoreArray.php +++ b/system/autoload/PEAR2/Console/CommandLine/Action/StoreArray.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ @@ -29,7 +30,7 @@ use PEAR2\Console\CommandLine; /** * Class that represent the StoreArray action. * - * The execute method appends the value of the option entered by the user to + * The execute method appends the value of the option entered by the user to * the result option array entry. * * @category Console diff --git a/system/autoload/PEAR2/Console/CommandLine/Action/StoreFalse.php b/system/autoload/PEAR2/Console/CommandLine/Action/StoreFalse.php index 20e8cbd3..e22f83b4 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Action/StoreFalse.php +++ b/system/autoload/PEAR2/Console/CommandLine/Action/StoreFalse.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ @@ -30,7 +31,7 @@ use PEAR2\Console\CommandLine; * Class that represent the StoreFalse action. * * The execute method store the boolean 'false' in the corrsponding result - * option array entry (the value is true if the option is not present in the + * option array entry (the value is true if the option is not present in the * command line entered by the user). * * @category Console diff --git a/system/autoload/PEAR2/Console/CommandLine/Action/StoreFloat.php b/system/autoload/PEAR2/Console/CommandLine/Action/StoreFloat.php index 4242f9b6..6fe33441 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Action/StoreFloat.php +++ b/system/autoload/PEAR2/Console/CommandLine/Action/StoreFloat.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ diff --git a/system/autoload/PEAR2/Console/CommandLine/Action/StoreInt.php b/system/autoload/PEAR2/Console/CommandLine/Action/StoreInt.php index af92024e..b8508857 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Action/StoreInt.php +++ b/system/autoload/PEAR2/Console/CommandLine/Action/StoreInt.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ @@ -30,7 +31,7 @@ use PEAR2\Console\CommandLine; * Class that represent the StoreInt action. * * The execute method store the value of the option entered by the user as an - * integer in the result option array entry, if the value passed is not an + * integer in the result option array entry, if the value passed is not an * integer an Exception is raised. * * @category Console diff --git a/system/autoload/PEAR2/Console/CommandLine/Action/StoreString.php b/system/autoload/PEAR2/Console/CommandLine/Action/StoreString.php index 8e77e8a6..3eaf225d 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Action/StoreString.php +++ b/system/autoload/PEAR2/Console/CommandLine/Action/StoreString.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ @@ -29,7 +30,7 @@ use PEAR2\Console\CommandLine; /** * Class that represent the StoreString action. * - * The execute method store the value of the option entered by the user as a + * The execute method store the value of the option entered by the user as a * string in the result option array entry. * * @category Console diff --git a/system/autoload/PEAR2/Console/CommandLine/Action/StoreTrue.php b/system/autoload/PEAR2/Console/CommandLine/Action/StoreTrue.php index 419bc61d..2984dac2 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Action/StoreTrue.php +++ b/system/autoload/PEAR2/Console/CommandLine/Action/StoreTrue.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ @@ -30,7 +31,7 @@ use PEAR2\Console\CommandLine; * Class that represent the StoreTrue action. * * The execute method store the boolean 'true' in the corrsponding result - * option array entry (the value is false if the option is not present in the + * option array entry (the value is false if the option is not present in the * command line entered by the user). * * @category Console diff --git a/system/autoload/PEAR2/Console/CommandLine/Action/Version.php b/system/autoload/PEAR2/Console/CommandLine/Action/Version.php index b31600da..80b349a4 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Action/Version.php +++ b/system/autoload/PEAR2/Console/CommandLine/Action/Version.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ diff --git a/system/autoload/PEAR2/Console/CommandLine/Argument.php b/system/autoload/PEAR2/Console/CommandLine/Argument.php index 1e02302e..cfb3c08a 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Argument.php +++ b/system/autoload/PEAR2/Console/CommandLine/Argument.php @@ -16,9 +16,10 @@ * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ @@ -65,6 +66,7 @@ class Argument extends Element * * @return void * @throws PEAR2\Console\CommandLine\Exception + * * @todo use exceptions */ public function validate() diff --git a/system/autoload/PEAR2/Console/CommandLine/Command.php b/system/autoload/PEAR2/Console/CommandLine/Command.php index 2d00a476..57bf2cfd 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Command.php +++ b/system/autoload/PEAR2/Console/CommandLine/Command.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ @@ -27,7 +28,7 @@ namespace PEAR2\Console\CommandLine; /** * Class that represent a command with option and arguments. * - * This class exist just to clarify the interface but at the moment it is + * This class exist just to clarify the interface but at the moment it is * strictly identical to PEAR2\Console\CommandLine class, it could change in the * future though. * @@ -60,7 +61,7 @@ class Command extends \PEAR2\Console\CommandLine * * @return void */ - public function __construct($params = array()) + public function __construct($params = array()) { if (isset($params['aliases'])) { $this->aliases = $params['aliases']; diff --git a/system/autoload/PEAR2/Console/CommandLine/CustomMessageProvider.php b/system/autoload/PEAR2/Console/CommandLine/CustomMessageProvider.php index c822faa0..95ea9a86 100644 --- a/system/autoload/PEAR2/Console/CommandLine/CustomMessageProvider.php +++ b/system/autoload/PEAR2/Console/CommandLine/CustomMessageProvider.php @@ -20,6 +20,7 @@ * @version CVS: $Id: CustomMessageProvider.php 282427 2009-06-19 10:22:48Z izi $ * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 1.1.0 + * * @filesource */ @@ -56,8 +57,9 @@ interface CustomMessageProvider * indexes are message codes. * * @return string + * * @see PEAR2\Console\CommandLine_MessageProvider - * @see PEAR2\Console\CommandLine_MessageProvider_Default + * @see PEAR2\Console\CommandLine_MessageProvider\DefaultProvider */ public function getWithCustomMessages( $code, $vars = array(), $messages = array() diff --git a/system/autoload/PEAR2/Console/CommandLine/Element.php b/system/autoload/PEAR2/Console/CommandLine/Element.php index 825606a8..49f23b3e 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Element.php +++ b/system/autoload/PEAR2/Console/CommandLine/Element.php @@ -16,9 +16,10 @@ * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ @@ -92,7 +93,7 @@ abstract class Element * * * @var array - * @see PEAR2\Console\CommandLine_MessageProvider_Default + * @see PEAR2\Console\CommandLine_MessageProvider\DefaultProvider */ public $messages = array(); @@ -124,6 +125,7 @@ abstract class Element * Returns the string representation of the element. * * @return string The string representation of the element + * * @todo use __toString() instead */ public function toString() diff --git a/system/autoload/PEAR2/Console/CommandLine/Exception.php b/system/autoload/PEAR2/Console/CommandLine/Exception.php index 6528f5d2..89011214 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Exception.php +++ b/system/autoload/PEAR2/Console/CommandLine/Exception.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ diff --git a/system/autoload/PEAR2/Console/CommandLine/MessageProvider.php b/system/autoload/PEAR2/Console/CommandLine/MessageProvider.php index 91813269..d02a5ee8 100644 --- a/system/autoload/PEAR2/Console/CommandLine/MessageProvider.php +++ b/system/autoload/PEAR2/Console/CommandLine/MessageProvider.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ @@ -42,14 +43,15 @@ interface MessageProvider /** * Retrieves the given string identifier corresponding message. - * For a list of identifiers please see the provided default message + * For a list of identifiers please see the provided default message * provider. * * @param string $code The string identifier of the message * @param array $vars An array of template variables * * @return string - * @see PEAR2\Console\CommandLine_MessageProvider_Default + * + * @see PEAR2\Console\CommandLine\MessageProvider\DefaultProvider */ public function get($code, $vars=array()); diff --git a/system/autoload/PEAR2/Console/CommandLine/MessageProvider/Default.php b/system/autoload/PEAR2/Console/CommandLine/MessageProvider/DefaultProvider.php similarity index 96% rename from system/autoload/PEAR2/Console/CommandLine/MessageProvider/Default.php rename to system/autoload/PEAR2/Console/CommandLine/MessageProvider/DefaultProvider.php index c3781f78..a7419e91 100644 --- a/system/autoload/PEAR2/Console/CommandLine/MessageProvider/Default.php +++ b/system/autoload/PEAR2/Console/CommandLine/MessageProvider/DefaultProvider.php @@ -16,13 +16,17 @@ * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ -namespace PEAR2\Console\CommandLine; +namespace PEAR2\Console\CommandLine\MessageProvider; + +use PEAR2\Console\CommandLine\MessageProvider; +use PEAR2\Console\CommandLine\CustomMessageProvider; /** * Lightweight class that manages messages used by PEAR2\Console\CommandLine package, @@ -37,7 +41,7 @@ namespace PEAR2\Console\CommandLine; * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since Class available since release 0.1.0 */ -class MessageProvider_Default +class DefaultProvider implements MessageProvider, CustomMessageProvider { diff --git a/system/autoload/PEAR2/Console/CommandLine/Option.php b/system/autoload/PEAR2/Console/CommandLine/Option.php index 912e8aad..1db19e53 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Option.php +++ b/system/autoload/PEAR2/Console/CommandLine/Option.php @@ -16,9 +16,10 @@ * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ @@ -173,6 +174,7 @@ class Option extends Element * @param string $delim Delimiter to use between short and long option * * @return string The string representation of the option + * * @todo use __toString() instead */ public function toString($delim = ", ") @@ -269,6 +271,7 @@ class Option extends Element * * @return void * @throws PEAR2\Console\CommandLine\Exception + * * @todo use exceptions instead */ public function validate() diff --git a/system/autoload/PEAR2/Console/CommandLine/Outputter.php b/system/autoload/PEAR2/Console/CommandLine/Outputter.php index ecb05267..5e4a70a9 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Outputter.php +++ b/system/autoload/PEAR2/Console/CommandLine/Outputter.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ diff --git a/system/autoload/PEAR2/Console/CommandLine/Outputter/Default.php b/system/autoload/PEAR2/Console/CommandLine/Outputter/Default.php index 9b4d0c38..faa6cb75 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Outputter/Default.php +++ b/system/autoload/PEAR2/Console/CommandLine/Outputter/Default.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ diff --git a/system/autoload/PEAR2/Console/CommandLine/Renderer.php b/system/autoload/PEAR2/Console/CommandLine/Renderer.php index 35d175a3..b5ea9263 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Renderer.php +++ b/system/autoload/PEAR2/Console/CommandLine/Renderer.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ diff --git a/system/autoload/PEAR2/Console/CommandLine/Renderer/Default.php b/system/autoload/PEAR2/Console/CommandLine/Renderer/Default.php index ff410a3f..9742352c 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Renderer/Default.php +++ b/system/autoload/PEAR2/Console/CommandLine/Renderer/Default.php @@ -16,7 +16,7 @@ * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 */ diff --git a/system/autoload/PEAR2/Console/CommandLine/Result.php b/system/autoload/PEAR2/Console/CommandLine/Result.php index 20e7e8c9..82c9fc25 100644 --- a/system/autoload/PEAR2/Console/CommandLine/Result.php +++ b/system/autoload/PEAR2/Console/CommandLine/Result.php @@ -11,14 +11,15 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ diff --git a/system/autoload/PEAR2/Console/CommandLine/XmlParser.php b/system/autoload/PEAR2/Console/CommandLine/XmlParser.php index bddd4df9..3777df3c 100644 --- a/system/autoload/PEAR2/Console/CommandLine/XmlParser.php +++ b/system/autoload/PEAR2/Console/CommandLine/XmlParser.php @@ -11,20 +11,24 @@ * through the world-wide-web at the following URI: * http://opensource.org/licenses/mit-license.php * - * @category Console + * @category Console * @package PEAR2\Console\CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS - * @license http://opensource.org/licenses/mit-license.php MIT License - * @version 0.2.1 + * @license http://opensource.org/licenses/mit-license.php MIT License + * @version 0.2.3 * @link http://pear2.php.net/PEAR2_Console_CommandLine * @since File available since release 0.1.0 + * * @filesource */ namespace PEAR2\Console\CommandLine; use PEAR2\Console\CommandLine; +use DOMDocument; +use DOMNode; +use Phar; /** * Parser for command line xml definitions. @@ -49,7 +53,7 @@ class XmlParser * * @return PEAR2\Console\CommandLine A parser instance */ - public static function parse($xmlfile) + public static function parse($xmlfile) { if (!is_readable($xmlfile)) { CommandLine::triggerError( @@ -58,7 +62,7 @@ class XmlParser array('{$file}' => $xmlfile) ); } - $doc = new \DomDocument(); + $doc = new DOMDocument(); $doc->load($xmlfile); self::validate($doc); $nodes = $doc->getElementsByTagName('command'); @@ -77,9 +81,9 @@ class XmlParser * * @return PEAR2\Console\CommandLine A parser instance */ - public static function parseString($xmlstr) + public static function parseString($xmlstr) { - $doc = new \DomDocument(); + $doc = new DOMDocument(); $doc->loadXml($xmlstr); self::validate($doc); $nodes = $doc->getElementsByTagName('command'); @@ -93,27 +97,48 @@ class XmlParser /** * Validates the xml definition using Relax NG. * - * @param DomDocument $doc The document to validate + * @param DOMDocument $doc The document to validate * * @return boolean Whether the xml data is valid or not. * @throws PEAR2\Console\CommandLine\Exception + * * @todo use exceptions only */ - public static function validate($doc) + public static function validate(DOMDocument $doc) { - $rngfile = __DIR__ - . '/../../../../data/pear2.php.net/PEAR2_Console_CommandLine/xmlschema.rng'; - if (!is_file($rngfile)) { - $rngfile = __DIR__ . '/../../../../data/xmlschema.rng'; + $paths = array(); + if (!class_exists('Phar', false) || !Phar::running()) { + // Pyrus + $paths[] + = 'D:\Vasko\WEB\PHP\_shared\PEAR2\data/pear2.php.net/PEAR2_Console_CommandLine/xmlschema.rng'; + // PEAR + $pearDataDirEnv = getenv('PHP_PEAR_DATA_DIR'); + if ($pearDataDirEnv) { + $paths[] = $pearDataDirEnv . + '/PEAR2_Console_CommandLine/xmlschema.rng'; + } + $paths[] = 'D:\Vasko\WEB\PHP\_shared\PEAR2\data/PEAR2_Console_CommandLine/xmlschema.rng'; } - if (!is_readable($rngfile)) { - CommandLine::triggerError( - 'invalid_xml_file', - E_USER_ERROR, - array('{$file}' => $rngfile) - ); + $pkgData = __DIR__ . '/../../../../data/'; + // PHAR dep + $paths[] = $pkgData . + 'pear2.php.net/PEAR2_Console_CommandLine/xmlschema.rng'; + $paths[] = $pkgData . 'PEAR2_Console_CommandLine/xmlschema.rng'; + $paths[] = $pkgData . 'pear2/console_commandline/xmlschema.rng'; + // Git/Composer + $paths[] = $pkgData . 'xmlschema.rng'; + $paths[] = 'xmlschema.rng'; + + foreach ($paths as $path) { + if (is_readable($path)) { + return $doc->relaxNGValidate($path); + } } - return $doc->relaxNGValidate($rngfile); + CommandLine::triggerError( + 'invalid_xml_file', + E_USER_ERROR, + array('{$file}' => $path) + ); } // }}} @@ -124,14 +149,15 @@ class XmlParser * constructed PEAR2\Console\CommandLine or PEAR2\Console\CommandLine_Command * instance. * - * @param DomDocumentNode $node The node to parse - * @param bool $isRootNode Whether it is a root node or not + * @param DOMNode $node The node to parse + * @param bool $isRootNode Whether it is a root node or not * - * @return mixed PEAR2\Console\CommandLine or PEAR2\Console\CommandLine_Command + * @return CommandLine|CommandLine\Command An instance of CommandLine for + * root node, CommandLine\Command otherwise. */ - private static function _parseCommandNode($node, $isRootNode = false) + private static function _parseCommandNode(DOMNode $node, $isRootNode = false) { - if ($isRootNode) { + if ($isRootNode) { $obj = new CommandLine(); } else { $obj = new CommandLine\Command(); @@ -184,11 +210,11 @@ class XmlParser * Parses an option node and returns the constructed * PEAR2\Console\CommandLine_Option instance. * - * @param DomDocumentNode $node The node to parse + * @param DOMNode $node The node to parse * * @return PEAR2\Console\CommandLine\Option The built option */ - private static function _parseOptionNode($node) + private static function _parseOptionNode(DOMNode $node) { $obj = new CommandLine\Option($node->getAttribute('name')); foreach ($node->childNodes as $cNode) { @@ -221,14 +247,14 @@ class XmlParser // _parseArgumentNode() {{{ /** - * Parses an argument node and returns the constructed + * Parses an argument node and returns the constructed * PEAR2\Console\CommandLine_Argument instance. * - * @param DomDocumentNode $node The node to parse + * @param DOMNode $node The node to parse * * @return PEAR2\Console\CommandLine\Argument The built argument */ - private static function _parseArgumentNode($node) + private static function _parseArgumentNode(DOMNode $node) { $obj = new CommandLine\Argument($node->getAttribute('name')); foreach ($node->childNodes as $cNode) { @@ -260,7 +286,7 @@ class XmlParser /** * Returns a boolean according to true/false possible strings. - * + * * @param string $str The string to process * * @return boolean diff --git a/system/autoload/PEAR2/Net/RouterOS/Client.php b/system/autoload/PEAR2/Net/RouterOS/Client.php index 299a8e93..0747e675 100644 --- a/system/autoload/PEAR2/Net/RouterOS/Client.php +++ b/system/autoload/PEAR2/Net/RouterOS/Client.php @@ -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 * @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 */ 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 */ 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]); } diff --git a/system/autoload/PEAR2/Net/RouterOS/Communicator.php b/system/autoload/PEAR2/Net/RouterOS/Communicator.php index 8176cfd4..4cee4ddd 100644 --- a/system/autoload/PEAR2/Net/RouterOS/Communicator.php +++ b/system/autoload/PEAR2/Net/RouterOS/Communicator.php @@ -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 * @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 @@ -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 */ 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 */ 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() diff --git a/system/autoload/PEAR2/Net/RouterOS/DataFlowException.php b/system/autoload/PEAR2/Net/RouterOS/DataFlowException.php index 2d7f279f..99c71a3d 100644 --- a/system/autoload/PEAR2/Net/RouterOS/DataFlowException.php +++ b/system/autoload/PEAR2/Net/RouterOS/DataFlowException.php @@ -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 * @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 diff --git a/system/autoload/PEAR2/Net/RouterOS/Exception.php b/system/autoload/PEAR2/Net/RouterOS/Exception.php index 842f128e..67d1dffe 100644 --- a/system/autoload/PEAR2/Net/RouterOS/Exception.php +++ b/system/autoload/PEAR2/Net/RouterOS/Exception.php @@ -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 * @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 diff --git a/system/autoload/PEAR2/Net/RouterOS/InvalidArgumentException.php b/system/autoload/PEAR2/Net/RouterOS/InvalidArgumentException.php index e0181dad..b966bf37 100644 --- a/system/autoload/PEAR2/Net/RouterOS/InvalidArgumentException.php +++ b/system/autoload/PEAR2/Net/RouterOS/InvalidArgumentException.php @@ -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 * @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 diff --git a/system/autoload/PEAR2/Net/RouterOS/LengthException.php b/system/autoload/PEAR2/Net/RouterOS/LengthException.php index cd69adbe..1617a06e 100644 --- a/system/autoload/PEAR2/Net/RouterOS/LengthException.php +++ b/system/autoload/PEAR2/Net/RouterOS/LengthException.php @@ -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 * @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 @@ -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() diff --git a/system/autoload/PEAR2/Net/RouterOS/Message.php b/system/autoload/PEAR2/Net/RouterOS/Message.php index 8935b310..fd1d3aa9 100644 --- a/system/autoload/PEAR2/Net/RouterOS/Message.php +++ b/system/autoload/PEAR2/Net/RouterOS/Message.php @@ -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 * @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 @@ -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 */ 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() diff --git a/system/autoload/PEAR2/Net/RouterOS/NotSupportedException.php b/system/autoload/PEAR2/Net/RouterOS/NotSupportedException.php index 2a7e3096..e71fafb0 100644 --- a/system/autoload/PEAR2/Net/RouterOS/NotSupportedException.php +++ b/system/autoload/PEAR2/Net/RouterOS/NotSupportedException.php @@ -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 * @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 @@ -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() diff --git a/system/autoload/PEAR2/Net/RouterOS/ParserException.php b/system/autoload/PEAR2/Net/RouterOS/ParserException.php new file mode 100644 index 00000000..9efea325 --- /dev/null +++ b/system/autoload/PEAR2/Net/RouterOS/ParserException.php @@ -0,0 +1,43 @@ + + * @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 + * @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; +} diff --git a/system/autoload/PEAR2/Net/RouterOS/Query.php b/system/autoload/PEAR2/Net/RouterOS/Query.php index 4e759aaa..5aee531e 100644 --- a/system/autoload/PEAR2/Net/RouterOS/Query.php +++ b/system/autoload/PEAR2/Net/RouterOS/Query.php @@ -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 * @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 @@ -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[] */ 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) diff --git a/system/autoload/PEAR2/Net/RouterOS/Registry.php b/system/autoload/PEAR2/Net/RouterOS/Registry.php index 30d2e758..439e58b9 100644 --- a/system/autoload/PEAR2/Net/RouterOS/Registry.php +++ b/system/autoload/PEAR2/Net/RouterOS/Registry.php @@ -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 * @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 @@ -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 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() { diff --git a/system/autoload/PEAR2/Net/RouterOS/Request.php b/system/autoload/PEAR2/Net/RouterOS/Request.php index eeba12f2..58a536a2 100644 --- a/system/autoload/PEAR2/Net/RouterOS/Request.php +++ b/system/autoload/PEAR2/Net/RouterOS/Request.php @@ -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 * @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 @@ -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: - * + * * := (<<\s+>>, )*, * := , ? * := <<[^\=\s]+>> @@ -349,7 +397,7 @@ class Request extends Message * := <<">>, <<([^"]|\\"|\\\\)*>>, <<">> * := <<\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, ''); } - + } } diff --git a/system/autoload/PEAR2/Net/RouterOS/Response.php b/system/autoload/PEAR2/Net/RouterOS/Response.php index c5fd414b..6e381cf4 100644 --- a/system/autoload/PEAR2/Net/RouterOS/Response.php +++ b/system/autoload/PEAR2/Net/RouterOS/Response.php @@ -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 * @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 @@ -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; - } } diff --git a/system/autoload/PEAR2/Net/RouterOS/ResponseCollection.php b/system/autoload/PEAR2/Net/RouterOS/ResponseCollection.php index 9b27575f..fb557e09 100644 --- a/system/autoload/PEAR2/Net/RouterOS/ResponseCollection.php +++ b/system/autoload/PEAR2/Net/RouterOS/ResponseCollection.php @@ -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 * @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 * @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> */ 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 */ 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> */ 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 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> $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. */ diff --git a/system/autoload/PEAR2/Net/RouterOS/RouterErrorException.php b/system/autoload/PEAR2/Net/RouterOS/RouterErrorException.php new file mode 100644 index 00000000..0b1ed3de --- /dev/null +++ b/system/autoload/PEAR2/Net/RouterOS/RouterErrorException.php @@ -0,0 +1,127 @@ + + * @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 + * @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 +} diff --git a/system/autoload/PEAR2/Net/RouterOS/Script.php b/system/autoload/PEAR2/Net/RouterOS/Script.php new file mode 100644 index 00000000..29f01d6a --- /dev/null +++ b/system/autoload/PEAR2/Net/RouterOS/Script.php @@ -0,0 +1,642 @@ + + * @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 + * @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( + '#^ + (?jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec) + / + (?\d\d?) + / + (?\d{4}) + (?: + \s+(?