diff --git a/src/Client.php b/src/Client.php index e7006e4..e539459 100644 --- a/src/Client.php +++ b/src/Client.php @@ -2,13 +2,15 @@ namespace RouterOS; +use RouterOS\Exceptions\ClientException; +use RouterOS\Exceptions\ConfigException; use RouterOS\Exceptions\Exception; use RouterOS\Interfaces\ClientInterface; use RouterOS\Interfaces\ConfigInterface; use RouterOS\Interfaces\QueryInterface; /** - * Class Client + * Class Client for RouterOS management * @package RouterOS * @since 0.1 */ @@ -40,12 +42,40 @@ class Client implements Interfaces\ClientInterface /** * Client constructor. + * * @param ConfigInterface $config + * @throws ConfigException + * @throws ClientException */ public function __construct(ConfigInterface $config) { + // Check for important keys + $this->keysCheck(['host', 'user', 'pass'], $config); + + // Save config if everything is okay $this->_config = $config; - $this->connect(); + + // Throw error if cannot to connect + if (false === $this->connect()) { + throw new ClientException('Unable to connect to ' . $config->get('host') . ':' . $config->get('port')); + } + } + + /** + * Check for important keys + * + * @param array $keys + * @param ConfigInterface $config + * @throws ConfigException + */ + private function keysCheck(array $keys, ConfigInterface $config) + { + $parameters = $config->getParameters(); + foreach ($keys as $key) { + if (false === (array_key_exists($key, $parameters) && isset($parameters[$key]))) { + throw new ConfigException("Parameter '$key' of Config is not set or empty"); + } + } } /** @@ -153,24 +183,24 @@ class Client implements Interfaces\ClientInterface return $this; } - public function read2(bool $parse = true): array - { - while (true) { - - $res = ''; - while ($buf = fread($this->_socket, 1)) { - if (substr($res, -5) === '!done') { - echo 'done'; - break 2; - } - echo "$buf\n"; - $res .= $buf; - } - $result[] = $res; - } - print_r($result); - die(); - } +// public function read2(bool $parse = true): array +// { +// while (true) { +// +// $res = ''; +// while ($buf = fread($this->_socket, 1)) { +// if (substr($res, -5) === '!done') { +// echo 'done'; +// break 2; +// } +// echo "$buf\n"; +// $res .= $buf; +// } +// $result[] = $res; +// } +// print_r($result); +// die(); +// } /** * Read answer from server after query was executed @@ -219,8 +249,6 @@ class Client implements Interfaces\ClientInterface */ private function parseResponse(array $response): array { - print_r($response); - $result = []; $i = -1; foreach ($response as $value) { @@ -253,12 +281,12 @@ class Client implements Interfaces\ClientInterface if ($this->config('legacy')) { // For the first we need get hash with salt $query = new Query('/login'); - $response = $this->write($query)->read(); + $response = $this->write($query)->read(false); // Now need use this hash for authorization $query = (new Query('/login')) ->add('=name=' . $this->config('user')) - ->add('=response=00' . md5(\chr(0) . $this->config('pass') . pack('H*', $response[0]))); + ->add('=response=00' . md5(\chr(0) . $this->config('pass') . pack('H*', $response[1]))); } else { // Just login with our credentials $query = (new Query('/login')) @@ -280,6 +308,9 @@ class Client implements Interfaces\ClientInterface */ public function connect(): bool { + // By default we not connected + $connected = false; + // Few attempts in loop for ($attempt = 1; $attempt <= $this->config('attempts'); $attempt++) { @@ -291,6 +322,7 @@ class Client implements Interfaces\ClientInterface // If we logged in then exit from loop if (true === $this->login()) { + $connected = true; break; } @@ -303,7 +335,7 @@ class Client implements Interfaces\ClientInterface } // Return status of connection - return true; + return $connected; } /** @@ -337,6 +369,7 @@ class Client implements Interfaces\ClientInterface * Initiate socket session * * @return bool + * @throws ClientException */ private function openSocket(): bool { @@ -355,23 +388,19 @@ class Client implements Interfaces\ClientInterface // Default: Proto tcp:// but for ssl we need ssl:// $proto = $this->config('ssl') ? 'ssl://' : ''; - try { - // Initiate socket client - $socket = stream_socket_client( - $proto . $this->config('host') . ':' . $this->config('port'), - $this->_socket_err_num, - $this->_socket_err_str, - $this->config('timeout'), - STREAM_CLIENT_CONNECT, - $context - ); - // Throw error is socket is not initiated - if (false === $socket) { - throw new Exception('stream_socket_client() failed: code: ' . $this->_socket_err_num . ' reason:' . $this->_socket_err_str); - } - - } catch (Exception $e) { - // __construct + // Initiate socket client + $socket = stream_socket_client( + $proto . $this->config('host') . ':' . $this->config('port'), + $this->_socket_err_num, + $this->_socket_err_str, + $this->config('timeout'), + STREAM_CLIENT_CONNECT, + $context + ); + + // Throw error is socket is not initiated + if (false === $socket) { + throw new ClientException('stream_socket_client() failed: code: ' . $this->_socket_err_num . ' reason: ' . $this->_socket_err_str); } // Save socket to static variable diff --git a/src/Config.php b/src/Config.php index bf2a666..8313b03 100644 --- a/src/Config.php +++ b/src/Config.php @@ -2,18 +2,18 @@ namespace RouterOS; -use RouterOS\Exceptions\Exception; +use RouterOS\Exceptions\ConfigException; use RouterOS\Interfaces\ConfigInterface; /** - * Class Config + * Class Config with array of parameters * @package RouterOS * @since 0.1 */ class Config implements ConfigInterface { /** - * Array of parameters (with defaults) + * Array of parameters (with some default values) * @var array */ private $_parameters = [ @@ -25,41 +25,50 @@ class Config implements ConfigInterface ]; /** - * Check if key in array + * Check if key in list of allowed parameters * * @param string $key * @param array $array - * @throws Exception + * @throws ConfigException */ private function keyAllowed(string $key, array $array) { - // Check if parameter in list of allowed parameters if (!array_key_exists($key, $array)) { - throw new Exception("Requested parameter '$key' not found in allowed list [" . implode(',', + throw new ConfigException("Requested parameter '$key' not found in allowed list [" . implode(',', array_keys($array)) . ']'); } } /** + * Compare data types of some value + * + * @param string $name Name of value + * @param mixed $whatType What type has value + * @param mixed $isType What type should be + * @throws ConfigException + */ + private function keyType(string $name, $whatType, $isType) + { + if ($whatType !== $isType) { + throw new ConfigException("Parameter '$name' has wrong type '$whatType'' but should be '$isType''"); + } + } + + /** * Set parameter into array * * @param string $name * @param mixed $value * @return ConfigInterface - * @throws Exception + * @throws ConfigException */ public function set(string $name, $value): ConfigInterface { // Check of key in array $this->keyAllowed($name, self::ALLOWED); - $whatType = \gettype($value); - $isType = self::ALLOWED[$name]; - // Check what type has this value - if ($whatType !== $isType) { - throw new Exception("Parameter '$name' has wrong type '$whatType'' but should be '$isType''"); - } + $this->keyType($name, \gettype($value), self::ALLOWED[$name]); // Save value to array $this->_parameters[$name] = $value; @@ -90,7 +99,7 @@ class Config implements ConfigInterface * * @param string $parameter * @return ConfigInterface - * @throws Exception + * @throws ConfigException */ public function delete(string $parameter): ConfigInterface { @@ -108,7 +117,7 @@ class Config implements ConfigInterface * * @param string $parameter * @return mixed - * @throws Exception + * @throws ConfigException */ public function get(string $parameter) { diff --git a/src/Exceptions/ClientException.php b/src/Exceptions/ClientException.php new file mode 100644 index 0000000..c02a653 --- /dev/null +++ b/src/Exceptions/ClientException.php @@ -0,0 +1,12 @@ +