From 48482d661ab4af894e76153d5b653ade0b64de73 Mon Sep 17 00:00:00 2001 From: malle-pietje Date: Fri, 9 Feb 2024 18:11:43 +0100 Subject: [PATCH] API client class v1.1.84 - PHP 7.4 is now the minimum required version - updated the code for 7.4. specific features such as parameter type hinting, return types, etc. - added the ability to the constructor to change the key that is used to store the unificookie in the session, ($_SESSION['unificookie'] is used by default), this is useful when running multiple applications on the same server --- README.md | 19 +- composer.json | 2 +- src/Client.php | 1269 ++++++++++++++++++++++++++---------------------- 3 files changed, 697 insertions(+), 593 deletions(-) diff --git a/README.md b/README.md index c008217..90f7ec1 100755 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ A PHP class that provides access to Ubiquiti's [**UniFi Network Application**](https://unifi-network.ui.com/) API. -UniFi Network Application software versions 5.X.X, 6.X.X, 7.X.X, and 8.X.X (version **8.0.26** has been confirmed to work) -are supported as well as Network Applications on **UniFi OS-based consoles** (UniFi OS **3.2.9** has been confirmed to work). -This class is used by our API Browser tool which can be found +UniFi Network Application software versions 5.X.X, 6.X.X, 7.X.X, and 8.X.X (version **8.1.104** has been confirmed to work) +are supported as well as Network Applications on **UniFi OS-based consoles** (UniFi OS **3.2.12** has been confirmed to work). +This class is used by our API Browser tool, which can be found [here](https://github.com/Art-of-WiFi/UniFi-API-browser). The package can be installed manually or by using @@ -15,9 +15,9 @@ easy inclusion in your projects. ## Requirements - a server with: - - PHP 5.5.0 or higher (this requirement will soon be raised to PHP **7.4**) + - PHP **7.4.0** or higher (use version [1.1.83](https://github.com/Art-of-WiFi/UniFi-API-client/releases/tag/v1.1.83) for PHP 7.3.x and lower) - PHP json and PHP cURL modules - - tested on Apache 2.4 with PHP 5.6.1 and cURL 7.42.1 and with PHP 7.4.9 and cURL 7.68.0 + - tested on Apache 2.4 with PHP 7.4.27 and cURL 7.60.0 and with PHP 8.2.12 and cURL 7.81.0 - direct network connectivity between this server and the host and port (usually TCP port 8443 or port 443 for UniFi OS) where the UniFi Controller is running - you **must** use **accounts with local access permissions** to access the UniFi Controller API through this class @@ -50,6 +50,15 @@ https://artofwifi.net/blog/how-to-access-the-unifi-controller-by-wan-ip-or-hostn The "custom firewall rule" approach described there is the recommended method. +## Upgrading from a previous version + +When upgrading from a version before **1.1.84**, please: +- make sure you are using PHP **7.4** or higher +- test the client with your code for any breaking changes; the class methods now have strict parameter type hints and + response types which can break your code in certain cases where the wrong type is passed or a different response type + is expected back + + ## Installation Use [Composer](#composer), [Git](#git) or simply [Download the Release](#download-the-release) to install the diff --git a/composer.json b/composer.json index 3b55f7a..4043a24 100755 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ } ], "require": { - "php": ">=5.5.0", + "php": ">=7.4.0", "ext-curl": "*", "ext-json": "*" }, diff --git a/src/Client.php b/src/Client.php index eddf0f9..92979e1 100755 --- a/src/Client.php +++ b/src/Client.php @@ -3,7 +3,7 @@ namespace UniFi_API; /** - * the UniFi API client class + * The UniFi API client class * * This UniFi API client class is based on the work done by the following developers: * domwo: https://community.ui.com/questions/little-php-class-for-unifi-api/933d3fb3-b401-4499-993a-f9af079a4a3a @@ -13,7 +13,7 @@ namespace UniFi_API; * * @package UniFi_Controller_API_Client_Class * @author Art of WiFi - * @version Release: 1.1.83 + * @version Release: 1.1.84 * @license This class is subject to the MIT license that is bundled with this package in the file LICENSE.md * @example This directory in the package repository contains a collection of examples: * https://github.com/Art-of-WiFi/UniFi-API-client/tree/master/examples @@ -25,50 +25,55 @@ class Client * * NOTE: do **not** modify the values here, instead use the constructor or the getter and setter functions/methods */ - const CLASS_VERSION = '1.1.83'; - protected $baseurl = 'https://127.0.0.1:8443'; - protected $user = ''; - protected $password = ''; - protected $site = 'default'; - protected $version = '7.3.76'; - protected $debug = false; - protected $is_logged_in = false; - protected $is_unifi_os = false; - protected $exec_retries = 0; - protected $cookies = ''; - protected $last_results_raw = null; - protected $last_error_message = ''; - protected $curl_ssl_verify_peer = false; - protected $curl_ssl_verify_host = false; - protected $curl_http_version = CURL_HTTP_VERSION_NONE; - protected $curl_headers = []; - protected $curl_method = 'GET'; - protected $curl_methods_allowed = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']; - protected $curl_request_timeout = 30; - protected $curl_connect_timeout = 10; + const CLASS_VERSION = '1.1.84'; + protected string $baseurl = 'https://127.0.0.1:8443'; + protected string $user = ''; + protected string $password = ''; + protected string $site = 'default'; + protected string $version = '8.0.28'; + protected bool $debug = false; + protected bool $is_logged_in = false; + protected bool $is_unifi_os = false; + protected int $exec_retries = 0; + protected string $cookies = ''; + protected $last_results_raw = null; + protected string $last_error_message = ''; + protected bool $curl_ssl_verify_peer = false; + protected int $curl_ssl_verify_host = 0; + protected int $curl_http_version = CURL_HTTP_VERSION_NONE; + protected array $curl_headers = []; + protected string $curl_method = 'GET'; + protected array $curl_methods_allowed = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']; + protected int $curl_request_timeout = 30; + protected int $curl_connect_timeout = 10; + protected string $unificookie_name; /** * Construct an instance of the UniFi API client class * - * @param string $user username to use when connecting to the UniFi controller - * @param string $password password to use when connecting to the UniFi controller - * @param string $baseurl optional, base URL of the UniFi controller which *must* include an 'https://' prefix, + * @param string $user username to use when connecting to the UniFi controller + * @param string $password password to use when connecting to the UniFi controller + * @param string $baseurl optional, base URL of the UniFi controller which *must* include an 'https://' prefix, * a port suffix (e.g. :8443) is required for non-UniFi OS controllers, * do not add trailing slashes, default value is 'https://127.0.0.1:8443' - * @param string $site optional, short site name to access, defaults to 'default' - * @param string $version optional, the version number of the controller - * @param bool $ssl_verify optional, whether to validate the controller's SSL certificate or not, a value of true + * @param string $site optional, short site name to access, defaults to 'default' + * @param string $version optional, the version number of the controller + * @param bool $ssl_verify optional, whether to validate the controller's SSL certificate or not, a value of true * is recommended for production environments to prevent potential MitM attacks, default * value (false) disables validation of the controller's SSL certificate + * @param string $unificookie_name optional, name of the cookie to use, default value is 'unificookie'. + * This is only needed when you have multiple apps using the API on the same web + * server. */ - public function __construct($user, $password, $baseurl = '', $site = '', $version = '', $ssl_verify = false) + public function __construct(string $user, string $password, string $baseurl = '', string $site = '', string $version = '', bool $ssl_verify = false, string $unificookie_name = 'unificookie') { if (!extension_loaded('curl')) { trigger_error('The PHP curl extension is not loaded. Please correct this before proceeding!'); } - $this->user = trim($user); - $this->password = trim($password); + $this->unificookie_name = trim($unificookie_name); + $this->user = trim($user); + $this->password = trim($password); if (!empty($baseurl)) { $this->check_base_url($baseurl); @@ -84,7 +89,7 @@ class Client $this->version = trim($version); } - if ((bool) $ssl_verify === true) { + if ($ssl_verify === true) { $this->curl_ssl_verify_peer = true; $this->curl_ssl_verify_host = 2; } @@ -99,9 +104,9 @@ class Client public function __destruct() { /** - * if $_SESSION['unificookie'] is set, do not log out here except when this is a UniFi OS-based controller + * if $_SESSION[$this->unificookie_name] is set, do not log out here except when this is a UniFi OS-based controller */ - if (isset($_SESSION['unificookie'])) { + if (isset($_SESSION[$this->unificookie_name])) { return; } @@ -139,7 +144,7 @@ class Client } $curl_options = [ - CURLOPT_URL => $this->baseurl . '/', + CURLOPT_URL => $this->baseurl . '/', ]; curl_setopt_array($ch, $curl_options); @@ -226,7 +231,7 @@ class Client * * @return bool returns true upon success */ - public function logout() + public function logout(): bool { /** * prepare cURL and options @@ -285,16 +290,16 @@ class Client /** * Authorize a client device * - * @param string $mac client MAC address - * @param int $minutes minutes (from now) until authorization expires - * @param int $up optional, upload speed limit in kbps - * @param int $down optional, download speed limit in kbps - * @param int $megabytes optional, data transfer limit in MB - * @param int $ap_mac optional, AP MAC address to which client is connected, should result in faster - * authorization + * @param string $mac client MAC address + * @param int $minutes minutes (from now) until authorization expires + * @param int|null $up optional, upload speed limit in kbps + * @param int|null $down optional, download speed limit in kbps + * @param int|null $megabytes optional, data transfer limit in MB + * @param string|null $ap_mac optional, AP MAC address to which client is connected, should result in faster + * authorization * @return bool returns true upon success */ - public function authorize_guest($mac, $minutes, $up = null, $down = null, $megabytes = null, $ap_mac = null) + public function authorize_guest(string $mac, int $minutes, int $up = null, int $down = null, int $megabytes = null, string $ap_mac = null) { $payload = ['cmd' => 'authorize-guest', 'mac' => strtolower($mac), 'minutes' => intval($minutes)]; @@ -326,7 +331,7 @@ class Client * @param string $mac client MAC address * @return bool returns true upon success */ - public function unauthorize_guest($mac) + public function unauthorize_guest(string $mac): bool { $payload = ['cmd' => 'unauthorize-guest', 'mac' => strtolower($mac)]; return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/stamgr', $payload); @@ -338,7 +343,7 @@ class Client * @param string $mac client MAC address * @return bool returns true upon success */ - public function reconnect_sta($mac) + public function reconnect_sta(string $mac): bool { $payload = ['cmd' => 'kick-sta', 'mac' => strtolower($mac)]; return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/stamgr', $payload); @@ -350,7 +355,7 @@ class Client * @param string $mac client MAC address * @return bool returns true upon success */ - public function block_sta($mac) + public function block_sta(string $mac): bool { $payload = ['cmd' => 'block-sta', 'mac' => strtolower($mac)]; return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/stamgr', $payload); @@ -362,7 +367,7 @@ class Client * @param string $mac client MAC address * @return bool returns true upon success */ - public function unblock_sta($mac) + public function unblock_sta(string $mac): bool { $payload = ['cmd' => 'unblock-sta', 'mac' => strtolower($mac)]; return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/stamgr', $payload); @@ -378,7 +383,7 @@ class Client * @param array $macs array of client MAC addresses (strings) * @return bool returns true upon success */ - public function forget_sta($macs) + public function forget_sta(array $macs): bool { $payload = ['cmd' => 'forget-sta', 'macs' => array_map('strtolower', $macs)]; return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/stamgr', $payload); @@ -387,17 +392,17 @@ class Client /** * Create a new user/client-device * - * @param string $mac client MAC address + * @param string $mac client MAC address * @param string $user_group_id _id value for the user group the new user/client-device should belong to which * can be obtained from the output of list_usergroups() - * @param string $name optional, name to be given to the new user/client-device - * @param string $note optional, note to be applied to the new user/client-device - * @param bool $is_guest optional, defines whether the new user/client-device is a guest or not - * @param bool $is_wired optional, defines whether the new user/client-device is wired or not + * @param string|null $name optional, name to be given to the new user/client-device + * @param string|null $note optional, note to be applied to the new user/client-device + * @param bool|null $is_guest optional, defines whether the new user/client-device is a guest or not + * @param bool|null $is_wired optional, defines whether the new user/client-device is wired or not * @return array|bool returns an array with a single object containing details of the new user/client-device on * success, else returns false */ - public function create_user($mac, $user_group_id, $name = null, $note = null, $is_guest = null, $is_wired = null) + public function create_user(string $mac, string $user_group_id, string $name = null, string $note = null, bool $is_guest = null, bool $is_wired = null) { $new_user = ['mac' => strtolower($mac), 'usergroup_id' => $user_group_id]; if (!empty($name)) { @@ -425,10 +430,10 @@ class Client * Add/modify/remove a client-device note * * @param string $user_id id of the client-device to be modified - * @param string $note optional, note to be applied to the client-device + * @param string $note optional, note to be applied to the client-device * @return bool returns true upon success */ - public function set_sta_note($user_id, $note = '') + public function set_sta_note(string $user_id, string $note = ''): bool { $payload = ['note' => $note]; return $this->fetch_results_boolean('/api/s/' . $this->site . '/upd/user/' . trim($user_id), $payload); @@ -438,18 +443,18 @@ class Client * Add/modify/remove a client device name * * @param string $user_id id of the client-device to be modified - * @param string $name optional, name to be applied to the client device, when empty or not set, + * @param string $name optional, name to be applied to the client device, when empty or not set, * the existing name for the client device is removed * @return bool returns true upon success */ - public function set_sta_name($user_id, $name = '') + public function set_sta_name(string $user_id, string $name = ''): bool { $payload = ['name' => $name]; return $this->fetch_results_boolean('/api/s/' . $this->site . '/upd/user/' . trim($user_id), $payload); } /** - * Fetch 5 minutes site stats + * Fetch 5-minute site stats * * NOTES: * - defaults to the past 12 hours @@ -457,11 +462,11 @@ class Client * - make sure that the retention policy for 5 minutes stats is set to the correct value in * the controller settings * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds * @return array returns an array of 5-minute stats objects for the current site */ - public function stat_5minutes_site($start = null, $end = null) + public function stat_5minutes_site(int $start = null, int $end = null): array { $end = empty($end) ? time() * 1000 : intval($end); $start = empty($start) ? $end - (12 * 3600 * 1000) : intval($start); @@ -489,11 +494,11 @@ class Client * - defaults to the past 7*24 hours * - "bytes" are no longer returned with controller version 4.9.1 and later * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds * @return array returns an array of hourly stats objects for the current site */ - public function stat_hourly_site($start = null, $end = null) + public function stat_hourly_site(int $start = null, int $end = null): array { $end = empty($end) ? time() * 1000 : intval($end); $start = empty($start) ? $end - (7 * 24 * 3600 * 1000) : intval($start); @@ -518,11 +523,11 @@ class Client * - defaults to the past 52*7*24 hours * - "bytes" are no longer returned with controller version 4.9.1 and later * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds * @return array returns an array of daily stats objects for the current site */ - public function stat_daily_site($start = null, $end = null) + public function stat_daily_site(int $start = null, int $end = null): array { $end = empty($end) ? (time() - (time() % 3600)) * 1000 : intval($end); $start = empty($start) ? $end - (52 * 7 * 24 * 3600 * 1000) : intval($start); @@ -547,11 +552,11 @@ class Client * - defaults to the past 52 weeks (52*7*24 hours) * - "bytes" are no longer returned with controller version 4.9.1 and later * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds * @return array returns an array of monthly stats objects for the current site */ - public function stat_monthly_site($start = null, $end = null) + public function stat_monthly_site(int $start = null, int $end = null): array { $end = empty($end) ? (time() - (time() % 3600)) * 1000 : intval($end); $start = empty($start) ? $end - (52 * 7 * 24 * 3600 * 1000) : intval($start); @@ -570,7 +575,7 @@ class Client } /** - * Fetch 5 minutes stats for a single access point or all access points + * Fetch 5-minutes stats for a single access point or all access points * * NOTES: * - defaults to the past 12 hours @@ -578,13 +583,13 @@ class Client * - make sure that the retention policy for 5 minutes stats is set to the correct value in * the controller settings * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds - * @param string $mac optional, AP MAC address to return stats for, when empty, + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds + * @param string|null $mac optional, AP MAC address to return stats for, when empty, * stats for all APs are returned * @return array returns an array of 5-minute stats objects */ - public function stat_5minutes_aps($start = null, $end = null, $mac = null) + public function stat_5minutes_aps(int $start = null, int $end = null, string $mac = null): array { $end = empty($end) ? time() * 1000 : intval($end); $start = empty($start) ? $end - (12 * 3600 * 1000) : intval($start); @@ -625,13 +630,13 @@ class Client * - make sure that the retention policy for hourly stats is set to the correct value in * the controller settings * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds - * @param string $mac optional, AP MAC address to return stats for, when empty, + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds + * @param string|null $mac optional, AP MAC address to return stats for, when empty, * stats for all APs are returned * @return array returns an array of hourly stats objects */ - public function stat_hourly_aps($start = null, $end = null, $mac = null) + public function stat_hourly_aps(int $start = null, int $end = null, string $mac = null): array { $end = empty($end) ? (time() * 1000) : intval($end); $start = empty($start) ? $end - (7 * 24 * 3600 * 1000) : intval($start); @@ -652,13 +657,13 @@ class Client * - make sure that the retention policy for hourly stats is set to the correct value in * the controller settings * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds - * @param string $mac optional, AP MAC address to return stats for, when empty, + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds + * @param string|null $mac optional, AP MAC address to return stats for, when empty, * stats for all APs are returned * @return array returns an array of daily stats objects */ - public function stat_daily_aps($start = null, $end = null, $mac = null) + public function stat_daily_aps(int $start = null, int $end = null, string $mac = null): array { $end = empty($end) ? time() * 1000 : intval($end); $start = empty($start) ? $end - (7 * 24 * 3600 * 1000) : intval($start); @@ -679,13 +684,13 @@ class Client * - make sure that the retention policy for hourly stats is set to the correct value in * the controller settings * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds - * @param string $mac optional, AP MAC address to return stats for, when empty, + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds + * @param string|null $mac optional, AP MAC address to return stats for, when empty, * stats for all APs are returned * @return array returns an array of monthly stats objects */ - public function stat_monthly_aps($start = null, $end = null, $mac = null) + public function stat_monthly_aps(int $start = null, int $end = null, string $mac = null): array { $end = empty($end) ? time() * 1000 : intval($end); $start = empty($start) ? $end - (52 * 7 * 24 * 3600 * 1000) : intval($start); @@ -699,7 +704,7 @@ class Client } /** - * Fetch 5 minutes stats for a single user/client device + * Fetch 5-minutes stats for a single user/client device * * * NOTES: @@ -710,16 +715,16 @@ class Client * - make sure that "Clients Historical Data" has been enabled in the UniFi controller settings in the Maintenance * section * - * @param string $mac MAC address of user/client device to return stats for - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds - * @param array $attribs array containing attributes (strings) to be returned, valid values are: + * @param string $mac MAC address of user/client device to return stats for + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds + * @param array|null $attribs array containing attributes (strings) to be returned, valid values are: * rx_bytes, tx_bytes, signal, rx_rate, tx_rate, rx_retries, tx_retries, rx_packets, * tx_packets, satisfaction, wifi_tx_attempts * default value is ['rx_bytes', 'tx_bytes'] * @return array returns an array of 5-minute stats objects */ - public function stat_5minutes_user($mac, $start = null, $end = null, $attribs = null) + public function stat_5minutes_user(string $mac, int $start = null, int $end = null, array $attribs = null): array { $end = empty($end) ? time() * 1000 : intval($end); $start = empty($start) ? $end - (12 * 3600 * 1000) : intval($start); @@ -739,16 +744,16 @@ class Client * - make sure that "Clients Historical Data" has been enabled in the UniFi controller settings in the Maintenance * section * - * @param string $mac MAC address of user/client device to return stats fo - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds - * @param array $attribs array containing attributes (strings) to be returned, valid values are: + * @param string $mac MAC address of user/client device to return stats fo + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds + * @param array|null $attribs array containing attributes (strings) to be returned, valid values are: * rx_bytes, tx_bytes, signal, rx_rate, tx_rate, rx_retries, tx_retries, rx_packets, * tx_packets, satisfaction, wifi_tx_attempts * default value is ['rx_bytes', 'tx_bytes'] * @return array returns an array of hourly stats objects */ - public function stat_hourly_user($mac, $start = null, $end = null, array $attribs = null) + public function stat_hourly_user(string $mac, int $start = null, int $end = null, array $attribs = null): array { $end = empty($end) ? time() * 1000 : intval($end); $start = empty($start) ? $end - (7 * 24 * 3600 * 1000) : intval($start); @@ -768,16 +773,16 @@ class Client * - make sure that "Clients Historical Data" has been enabled in the UniFi controller settings in the Maintenance * section * - * @param string $mac MAC address of user/client device to return stats for - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds - * @param array $attribs array containing attributes (strings) to be returned, valid values are: + * @param string $mac MAC address of user/client device to return stats for + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds + * @param array|null $attribs array containing attributes (strings) to be returned, valid values are: * rx_bytes, tx_bytes, signal, rx_rate, tx_rate, rx_retries, tx_retries, rx_packets, * tx_packets, satisfaction, wifi_tx_attempts * default value is ['rx_bytes', 'tx_bytes'] * @return array returns an array of daily stats objects */ - public function stat_daily_user($mac, $start = null, $end = null, $attribs = null) + public function stat_daily_user(string $mac, int $start = null, int $end = null, array $attribs = null): array { $end = empty($end) ? time() * 1000 : intval($end); $start = empty($start) ? $end - (7 * 24 * 3600 * 1000) : intval($start); @@ -797,16 +802,16 @@ class Client * - make sure that "Clients Historical Data" has been enabled in the UniFi controller settings in the Maintenance * section * - * @param string $mac MAC address of user/client device to return stats for - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds - * @param array $attribs array containing attributes (strings) to be returned, valid values are: + * @param string $mac MAC address of user/client device to return stats for + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds + * @param array|null $attribs array containing attributes (strings) to be returned, valid values are: * rx_bytes, tx_bytes, signal, rx_rate, tx_rate, rx_retries, tx_retries, rx_packets, * tx_packets, satisfaction, wifi_tx_attempts * default value is ['rx_bytes', 'tx_bytes'] * @return array returns an array of monthly stats objects */ - public function stat_monthly_user($mac, $start = null, $end = null, $attribs = null) + public function stat_monthly_user(string $mac, int $start = null, int $end = null, array $attribs = null): array { $end = empty($end) ? time() * 1000 : intval($end); $start = empty($start) ? $end - (13 * 7 * 24 * 3600 * 1000) : intval($start); @@ -816,7 +821,7 @@ class Client } /** - * Fetch 5 minutes gateway stats + * Fetch 5-minute gateway stats * * NOTES: * - defaults to the past 12 hours @@ -825,15 +830,15 @@ class Client * the controller settings * - requires a UniFi gateway * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds - * @param array $attribs array containing attributes (strings) to be returned, valid values are: + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds + * @param array|null $attribs array containing attributes (strings) to be returned, valid values are: * mem, cpu, loadavg_5, lan-rx_errors, lan-tx_errors, lan-rx_bytes, * lan-tx_bytes, lan-rx_packets, lan-tx_packets, lan-rx_dropped, lan-tx_dropped * default is ['time', 'mem', 'cpu', 'loadavg_5'] * @return array returns an array of 5-minute stats objects for the gateway belonging to the current site */ - public function stat_5minutes_gateway($start = null, $end = null, $attribs = null) + public function stat_5minutes_gateway(int $start = null, int $end = null, array $attribs = null): array { $end = empty($end) ? time() * 1000 : intval($end); $start = empty($start) ? $end - (12 * 3600 * 1000) : intval($start); @@ -849,15 +854,15 @@ class Client * - defaults to the past 7*24 hours * - requires a UniFi gateway * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds - * @param array $attribs array containing attributes (strings) to be returned, valid values are: + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds + * @param array|null $attribs array containing attributes (strings) to be returned, valid values are: * mem, cpu, loadavg_5, lan-rx_errors, lan-tx_errors, lan-rx_bytes, * lan-tx_bytes, lan-rx_packets, lan-tx_packets, lan-rx_dropped, lan-tx_dropped * default is ['time', 'mem', 'cpu', 'loadavg_5'] * @return array returns an array of hourly stats objects for the gateway belonging to the current site */ - public function stat_hourly_gateway($start = null, $end = null, $attribs = null) + public function stat_hourly_gateway(int $start = null, int $end = null, array $attribs = null): array { $end = empty($end) ? time() * 1000 : intval($end); $start = empty($start) ? $end - (7 * 24 * 3600 * 1000) : intval($start); @@ -873,15 +878,15 @@ class Client * - defaults to the past 52 weeks (52*7*24 hours) * - requires a UniFi gateway * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds - * @param array $attribs array containing attributes (strings) to be returned, valid values are: + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds + * @param array|null $attribs array containing attributes (strings) to be returned, valid values are: * mem, cpu, loadavg_5, lan-rx_errors, lan-tx_errors, lan-rx_bytes, * lan-tx_bytes, lan-rx_packets, lan-tx_packets, lan-rx_dropped, lan-tx_dropped * default is ['time', 'mem', 'cpu', 'loadavg_5'] * @return array returns an array of hourly stats objects for the gateway belonging to the current site */ - public function stat_daily_gateway($start = null, $end = null, $attribs = null) + public function stat_daily_gateway(int $start = null, int $end = null, array $attribs = null): array { $end = empty($end) ? (time() - (time() % 3600)) * 1000 : intval($end); $start = empty($start) ? $end - (52 * 7 * 24 * 3600 * 1000) : intval($start); @@ -897,15 +902,15 @@ class Client * - defaults to the past 52 weeks (52*7*24 hours) * - requires a UniFi gateway * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds - * @param array $attribs array containing attributes (strings) to be returned, valid values are: + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds + * @param array|null $attribs array containing attributes (strings) to be returned, valid values are: * mem, cpu, loadavg_5, lan-rx_errors, lan-tx_errors, lan-rx_bytes, * lan-tx_bytes, lan-rx_packets, lan-tx_packets, lan-rx_dropped, lan-tx_dropped * default is ['time', 'mem', 'cpu', 'loadavg_5'] * @return array returns an array of monthly stats objects for the gateway belonging to the current site */ - public function stat_monthly_gateway($start = null, $end = null, $attribs = null) + public function stat_monthly_gateway(int $start = null, int $end = null, array $attribs = null): array { $end = empty($end) ? (time() - (time() % 3600)) * 1000 : intval($end); $start = empty($start) ? $end - (52 * 7 * 24 * 3600 * 1000) : intval($start); @@ -921,11 +926,11 @@ class Client * - defaults to the past 24 hours * - requires a UniFi gateway * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds * @return array returns an array of speed test result objects */ - public function stat_speedtest_results($start = null, $end = null) + public function stat_speedtest_results(int $start = null, int $end = null): array { $end = empty($end) ? time() * 1000 : intval($end); $start = empty($start) ? $end - (24 * 3600 * 1000) : intval($start); @@ -941,12 +946,12 @@ class Client * - requires a UniFi gateway * - supported in UniFi controller versions 5.9.X and higher * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds - * @param int $limit optional, maximum number of events to return, defaults to 10000 + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds + * @param int|null $limit optional, maximum number of events to return, defaults to 10000 * @return array returns an array of IPS/IDS event objects */ - public function stat_ips_events($start = null, $end = null, $limit = null) + public function stat_ips_events(int $start = null, int $end = null, int $limit = null): array { $end = empty($end) ? time() * 1000 : intval($end); $start = empty($start) ? $end - (24 * 3600 * 1000) : intval($start); @@ -961,15 +966,15 @@ class Client * NOTES: * - defaults to the past 7*24 hours * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds - * @param string $mac optional, client MAC address to return sessions for (can only be used when start and end + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds + * @param string|null $mac optional, client MAC address to return sessions for (can only be used when start and end * are also provided) - * @param string $type optional, client type to return sessions for, can be 'all', 'guest' or 'user'; default + * @param string $type optional, client type to return sessions for, can be 'all', 'guest' or 'user'; default * value is 'all' * @return array|false returns an array of login session objects for all devices or a single device */ - public function stat_sessions($start = null, $end = null, $mac = null, $type = 'all') + public function stat_sessions(int $start = null, int $end = null, string $mac = null, string $type = 'all'): array { if (!in_array($type, ['all', 'guest', 'user'])) { return false; @@ -991,11 +996,11 @@ class Client * NOTES: * - defaults to the past 7*24 hours * - * @param string $mac client MAC address - * @param int $limit optional, maximum number of sessions to get (default value is 5) + * @param string $mac client MAC address + * @param int|null $limit optional, maximum number of sessions to get (default value is 5) * @return array returns an array of login session objects for all devices or a single device */ - public function stat_sta_sessions_latest($mac, $limit = null) + public function stat_sta_sessions_latest(string $mac, int $limit = null): array { $limit = empty($limit) ? 5 : intval($limit); $payload = ['mac' => strtolower($mac), '_limit' => $limit, '_sort' => '-assoc_time']; @@ -1008,11 +1013,11 @@ class Client * NOTES: * - defaults to the past 7*24 hours * - * @param int $start optional, Unix timestamp in milliseconds - * @param int $end optional, Unix timestamp in milliseconds + * @param int|null $start optional, Unix timestamp in milliseconds + * @param int|null $end optional, Unix timestamp in milliseconds * @return array returns an array of authorization objects */ - public function stat_auths($start = null, $end = null) + public function stat_auths(int $start = null, int $end = null): array { $end = empty($end) ? time() : intval($end); $start = empty($start) ? $end - (7 * 24 * 3600) : intval($start); @@ -1030,7 +1035,7 @@ class Client * @param int $historyhours optional, hours to go back (default is 8760 hours or 1 year) * @return array returns an array of client device objects */ - public function stat_allusers($historyhours = 8760) + public function stat_allusers(int $historyhours = 8760): array { $payload = ['type' => 'all', 'conn' => 'all', 'within' => intval($historyhours)]; return $this->fetch_results('/api/s/' . $this->site . '/stat/alluser', $payload); @@ -1046,21 +1051,22 @@ class Client * hours) * @return array returns an array of guest device objects with valid access */ - public function list_guests($within = 8760) + public function list_guests(int $within = 8760): array { $payload = ['within' => intval($within)]; + return $this->fetch_results('/api/s/' . $this->site . '/stat/guest', $payload); } /** * Fetch online client device(s) * - * @param string $client_mac optional, the MAC address of a single online client device for which the call must be + * @param string|null $client_mac optional, the MAC address of a single online client device for which the call must be * made * @return array|false returns an array of online client device objects, or in case of a single device request, returns a * single client device object, false upon error */ - public function list_clients($client_mac = null) + public function list_clients(string $client_mac = null) { if (is_string($client_mac)) { $client_mac = strtolower(trim($client_mac)); @@ -1075,7 +1081,7 @@ class Client * @param string $client_mac client device MAC address * @return array returns an object with the client device information */ - public function stat_client($client_mac) + public function stat_client(string $client_mac): array { return $this->fetch_results('/api/s/' . $this->site . '/stat/user/' . strtolower(trim($client_mac))); } @@ -1083,33 +1089,31 @@ class Client /** * Assign client device to another group * - * @param string $client_id _id value of the client device to be modified - * @param string $group_id _id value of the user group to assign client device to + * @param string $client_id _id value of the client device to be modified + * @param string $group_id _id value of the user group to assign client device to * @return bool returns true upon success */ - public function set_usergroup($client_id, $group_id) + public function set_usergroup(string $client_id, string $group_id): bool { $payload = ['usergroup_id' => $group_id]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/upd/user/' . trim($client_id), $payload); } /** * Update client device fixed IP address (using REST) * - * @param string $client_id _id value for the client device - * @param bool $use_fixedip determines whether to enable the fixed IP address or not - * @param string $network_id optional, _id value for the network where the ip belongs to - * @param string $fixed_ip optional, IP address, value of client device's fixed_ip field + * @param string $client_id _id value for the client device + * @param bool $use_fixedip determines whether to enable the fixed IP address or not + * @param string|null $network_id optional, _id value for the network where the ip belongs to + * @param string|null $fixed_ip optional, IP address, value of client device's fixed_ip field * @return array|false returns an array containing a single object with attributes of the updated client on success */ - public function edit_client_fixedip($client_id, $use_fixedip, $network_id = null, $fixed_ip = null) + public function edit_client_fixedip(string $client_id, bool $use_fixedip, string $network_id = null, string $fixed_ip = null) { - if (!is_bool($use_fixedip)) { - return false; - } - $this->curl_method = 'PUT'; - $payload = [ + + $payload = [ '_id' => $client_id, 'use_fixedip' => $use_fixedip, ]; @@ -1130,18 +1134,19 @@ class Client /** * Update client device name (using REST) * - * @param string $client_id _id value for the client device - * @param string $name name of the client + * @param string $client_id _id value for the client device + * @param string $name name of the client * @return array|false returns an array containing a single object with attributes of the updated client on success */ - public function edit_client_name($client_id, $name) + public function edit_client_name(string $client_id, string $name) { if (empty($name)) { return false; } $this->curl_method = 'PUT'; - $payload = [ + + $payload = [ '_id' => $client_id, 'name' => $name, ]; @@ -1154,50 +1159,53 @@ class Client * * @return array returns an array of user group objects */ - public function list_usergroups() + public function list_usergroups(): array { return $this->fetch_results('/api/s/' . $this->site . '/list/usergroup'); } /** - * Create user group (using REST) + * Create a user group (using REST) * * @param string $group_name name of the user group - * @param int $group_dn limit download bandwidth in Kbps (default = -1, which sets bandwidth to unlimited) - * @param int $group_up limit upload bandwidth in Kbps (default = -1, which sets bandwidth to unlimited) + * @param int $group_dn limit download bandwidth in Kbps (default = -1, which sets bandwidth to unlimited) + * @param int $group_up limit upload bandwidth in Kbps (default = -1, which sets bandwidth to unlimited) * @return array containing a single object with attributes of the new usergroup ("_id", "name", * "qos_rate_max_down", "qos_rate_max_up", "site_id") on success */ - public function create_usergroup($group_name, $group_dn = -1, $group_up = -1) + public function create_usergroup(string $group_name, int $group_dn = -1, int $group_up = -1): array { $payload = [ 'name' => $group_name, 'qos_rate_max_down' => intval($group_dn), 'qos_rate_max_up' => intval($group_up), ]; + return $this->fetch_results('/api/s/' . $this->site . '/rest/usergroup', $payload); } /** * Modify user group (using REST) * - * @param string $group_id _id value of the user group - * @param string $site_id _id value of the site + * @param string $group_id _id value of the user group + * @param string $site_id _id value of the site * @param string $group_name name of the user group - * @param int $group_dn limit download bandwidth in Kbps (default = -1, which sets bandwidth to unlimited) - * @param int $group_up limit upload bandwidth in Kbps (default = -1, which sets bandwidth to unlimited) + * @param int $group_dn limit download bandwidth in Kbps (default = -1, which sets bandwidth to unlimited) + * @param int $group_up limit upload bandwidth in Kbps (default = -1, which sets bandwidth to unlimited) * @return array returns an array containing a single object with attributes of the updated usergroup on success */ - public function edit_usergroup($group_id, $site_id, $group_name, $group_dn = -1, $group_up = -1) + public function edit_usergroup(string $group_id, string $site_id, string $group_name, int $group_dn = -1, int $group_up = -1): array { $this->curl_method = 'PUT'; - $payload = [ + + $payload = [ '_id' => $group_id, 'name' => $group_name, 'qos_rate_max_down' => intval($group_dn), 'qos_rate_max_up' => intval($group_up), 'site_id' => $site_id, ]; + return $this->fetch_results('/api/s/' . $this->site . '/rest/usergroup/' . trim($group_id), $payload); } @@ -1207,9 +1215,10 @@ class Client * @param string $group_id _id value of the user group to delete * @return bool returns true on success */ - public function delete_usergroup($group_id) + public function delete_usergroup(string $group_id): bool { $this->curl_method = 'DELETE'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/usergroup/' . trim($group_id)); } @@ -1218,7 +1227,7 @@ class Client * * @return array containing the current AP groups on success */ - public function list_apgroups() + public function list_apgroups(): array { return $this->fetch_results('/v2/api/site/' . $this->site . '/apgroups'); } @@ -1226,35 +1235,38 @@ class Client /** * Create AP group * - * @param string $group_name name to assign to the AP group - * @param array $device_macs optional, array containing the MAC addresses (strings) of the APs to add to the new + * @param string $group_name name to assign to the AP group + * @param array $device_macs optional, array containing the MAC addresses (strings) of the APs to add to the new * group * @return array containing a single object with attributes of the new AP group on success */ - public function create_apgroup($group_name, $device_macs = []) + public function create_apgroup(string $group_name, array $device_macs = []): array { $payload = ['device_macs' => $device_macs, 'name' => $group_name]; + return $this->fetch_results('/v2/api/site/' . $this->site . '/apgroups', $payload); } /** * Modify AP group * - * @param string $group_id _id value of the AP group to modify - * @param string $group_name name to assign to the AP group - * @param array $device_macs array containing the members of the AP group which overwrites the existing + * @param string $group_id _id value of the AP group to modify + * @param string $group_name name to assign to the AP group + * @param array $device_macs array containing the members of the AP group which overwrites the existing * group_members (passing an empty array clears the AP member list) * @return array|bool containing a single object with attributes of the updated AP group on success */ - public function edit_apgroup($group_id, $group_name, $device_macs) + public function edit_apgroup(string $group_id, string $group_name, array $device_macs): array { $this->curl_method = 'PUT'; - $payload = [ + + $payload = [ '_id' => $group_id, 'attr_no_delete' => false, 'name' => $group_name, 'device_macs' => $device_macs, ]; + return $this->fetch_results('/v2/api/site/' . $this->site . '/apgroups/' . trim($group_id), $payload); } @@ -1264,9 +1276,10 @@ class Client * @param string $group_id _id value of the AP group to delete * @return bool returns true on success */ - public function delete_apgroup($group_id) + public function delete_apgroup(string $group_id): bool { $this->curl_method = 'DELETE'; + return $this->fetch_results_boolean('/v2/api/site/' . $this->site . '/apgroups/' . trim($group_id)); } @@ -1276,58 +1289,61 @@ class Client * @param string $group_id optional, _id value of the single firewall group to list * @return array containing the current firewall groups or the selected firewall group on success */ - public function list_firewallgroups($group_id = '') + public function list_firewallgroups(string $group_id = ''): array { return $this->fetch_results('/api/s/' . $this->site . '/rest/firewallgroup/' . trim($group_id)); } /** - * Create firewall group (using REST) + * Create a firewall group (using REST) * - * @param string $group_name name to assign to the firewall group - * @param string $group_type firewall group type; valid values are address-group, ipv6-address-group, port-group - * @param array $group_members array containing the members of the new group (IPv4 addresses, IPv6 addresses or + * @param string $group_name name to assign to the firewall group + * @param string $group_type firewall group type; valid values are address-group, ipv6-address-group, port-group + * @param array $group_members array containing the members of the new group (IPv4 addresses, IPv6 addresses or * port numbers) * (default is an empty array) * @return array|false containing a single object with attributes of the new firewall group on success */ - public function create_firewallgroup($group_name, $group_type, $group_members = []) + public function create_firewallgroup(string $group_name, string $group_type, array $group_members = []) { if (!in_array($group_type, ['address-group', 'ipv6-address-group', 'port-group'])) { return false; } $payload = ['name' => $group_name, 'group_type' => $group_type, 'group_members' => $group_members]; + return $this->fetch_results('/api/s/' . $this->site . '/rest/firewallgroup', $payload); } /** - * Modify firewall group (using REST) + * Modify a firewall group (using REST) * - * @param string $group_id _id value of the firewall group to modify - * @param string $site_id site_id value of the firewall group to modify - * @param string $group_name name of the firewall group - * @param string $group_type firewall group type; valid values are address-group, ipv6-address-group, + * @param string $group_id _id value of the firewall group to modify + * @param string $site_id site_id value of the firewall group to modify + * @param string $group_name name of the firewall group + * @param string $group_type firewall group type; valid values are address-group, ipv6-address-group, * port-group, * group_type cannot be changed for an existing firewall group! - * @param array $group_members array containing the members of the group (IPv4 addresses, IPv6 addresses or port + * @param array $group_members array containing the members of the group (IPv4 addresses, IPv6 addresses or port * numbers) which overwrites the existing group_members (default is an empty array) * @return array|false containing a single object with attributes of the updated firewall group on success */ - public function edit_firewallgroup($group_id, $site_id, $group_name, $group_type, $group_members = []) + public function edit_firewallgroup(string $group_id, string $site_id, string $group_name, string $group_type, array $group_members = []) { if (!in_array($group_type, ['address-group', 'ipv6-address-group', 'port-group'])) { return false; } $this->curl_method = 'PUT'; - $payload = [ + + $payload = [ '_id' => $group_id, 'name' => $group_name, 'group_type' => $group_type, 'group_members' => $group_members, 'site_id' => $site_id, ]; + return $this->fetch_results('/api/s/' . $this->site . '/rest/firewallgroup/' . trim($group_id), $payload); } @@ -1337,9 +1353,10 @@ class Client * @param string $group_id _id value of the firewall group to delete * @return bool returns true on success */ - public function delete_firewallgroup($group_id) + public function delete_firewallgroup(string $group_id): bool { $this->curl_method = 'DELETE'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/firewallgroup/' . trim($group_id)); } @@ -1348,7 +1365,7 @@ class Client * * @return array containing the current firewall rules on success */ - public function list_firewallrules() + public function list_firewallrules(): array { return $this->fetch_results('/api/s/' . $this->site . '/rest/firewallrule'); } @@ -1359,7 +1376,7 @@ class Client * @param string $route_id _id value of the static route to get settings for * @return array containing the static routes and their settings */ - public function list_routing($route_id = '') + public function list_routing(string $route_id = ''): array { return $this->fetch_results('/api/s/' . $this->site . '/rest/routing/' . trim($route_id)); } @@ -1369,7 +1386,7 @@ class Client * * @return array containing health metric objects */ - public function list_health() + public function list_health(): array { return $this->fetch_results('/api/s/' . $this->site . '/stat/health'); } @@ -1381,9 +1398,10 @@ class Client * returns hourly stats by default (supported on controller versions 5.5.* and higher) * @return array containing dashboard metric objects (available since controller version 4.9.1.alpha) */ - public function list_dashboard($five_minutes = false) + public function list_dashboard(bool $five_minutes = false): array { $path_suffix = $five_minutes ? '?scale=5minutes' : null; + return $this->fetch_results('/api/s/' . $this->site . '/stat/dashboard' . $path_suffix); } @@ -1392,7 +1410,7 @@ class Client * * @return array containing known client device objects */ - public function list_users() + public function list_users(): array { return $this->fetch_results('/api/s/' . $this->site . '/list/user'); } @@ -1417,7 +1435,7 @@ class Client */ public function list_devices($device_macs = []) { - $payload = ['macs' => (array) $device_macs]; + $payload = ['macs' => (array)$device_macs]; return $this->fetch_results('/api/s/' . $this->site . '/stat/device', $payload); } @@ -1429,7 +1447,7 @@ class Client * * @return array containing known device tag objects */ - public function list_tags() + public function list_tags(): array { return $this->fetch_results('/api/s/' . $this->site . '/rest/tag'); } @@ -1440,7 +1458,7 @@ class Client * @param int $within optional, hours to go back to list discovered "rogue" access points (default = 24 hours) * @return array containing rogue/neighboring access point objects */ - public function list_rogueaps($within = 24) + public function list_rogueaps(int $within = 24): array { $payload = ['within' => intval($within)]; return $this->fetch_results('/api/s/' . $this->site . '/stat/rogueap', $payload); @@ -1451,7 +1469,7 @@ class Client * * @return array containing known rogue access point objects */ - public function list_known_rogueaps() + public function list_known_rogueaps(): array { return $this->fetch_results('/api/s/' . $this->site . '/rest/rogueknown'); } @@ -1466,6 +1484,7 @@ class Client public function generate_backup() { $payload = ['cmd' => 'backup']; + return $this->fetch_results('/api/s/' . $this->site . '/cmd/backup', $payload); } @@ -1474,9 +1493,10 @@ class Client * * @return array containing objects with backup details on success */ - public function list_backups() + public function list_backups(): array { $payload = ['cmd' => 'list-backups']; + return $this->fetch_results('/api/s/' . $this->site . '/cmd/backup', $payload); } @@ -1499,7 +1519,7 @@ class Client * * @return array containing a list of sites hosted on this controller with some details */ - public function list_sites() + public function list_sites(): array { return $this->fetch_results('/api/self/sites'); } @@ -1511,7 +1531,7 @@ class Client * * @return array containing statistics for all sites hosted on this controller */ - public function stat_sites() + public function stat_sites(): array { return $this->fetch_results('/api/stat/sites'); } @@ -1522,9 +1542,10 @@ class Client * @param string $description the long name for the new site * @return array containing a single object with attributes of the new site ("_id", "desc", "name") on success */ - public function create_site($description) + public function create_site(string $description): array { $payload = ['desc' => $description, 'cmd' => 'add-site']; + return $this->fetch_results('/api/s/' . $this->site . '/cmd/sitemgr', $payload); } @@ -1534,9 +1555,10 @@ class Client * @param string $site_id _id value of the site to delete * @return bool true on success */ - public function delete_site($site_id) + public function delete_site(string $site_id): bool { $payload = ['site' => $site_id, 'cmd' => 'delete-site']; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/sitemgr', $payload); } @@ -1548,17 +1570,18 @@ class Client * @param string $site_name the new long name for the current site * @return bool true on success */ - public function set_site_name($site_name) + public function set_site_name(string $site_name): bool { $payload = ['cmd' => 'update-site', 'desc' => $site_name]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/sitemgr', $payload); } /** * Update site country * - * @param string $country_id _id value of the country key - * @param object|array $payload stdClass object or associative array containing the configuration to apply to + * @param string $country_id _id value of the country key + * @param object|array $payload stdClass object or associative array containing the configuration to apply to * the site, must be a (partial) object/array structured in the same manner as is * returned by list_settings() for the section with the "country" key. Valid * country codes can be obtained using the list_country_codes() function/method. Do @@ -1566,9 +1589,10 @@ class Client * success. * @return bool true on success */ - public function set_site_country($country_id, $payload) + public function set_site_country(string $country_id, $payload): bool { $this->curl_method = 'PUT'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/country/' . trim($country_id), $payload); } @@ -1576,8 +1600,8 @@ class Client /** * Update site locale * - * @param string $locale_id _id value of the locale section - * @param object|array $payload stdClass object or associative array containing the configuration to apply to the + * @param string $locale_id _id value of the locale section + * @param object|array $payload stdClass object or associative array containing the configuration to apply to the * site, must be a (partial) object/array structured in the same manner as is * returned by list_settings() for section with the "locale" key. Valid * timezones can be obtained in Javascript as explained here: @@ -1586,9 +1610,10 @@ class Client * is assigned by the controller and returned upon success. * @return bool true on success */ - public function set_site_locale($locale_id, $payload) + public function set_site_locale(string $locale_id, $payload): bool { $this->curl_method = 'PUT'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/locale/' . trim($locale_id), $payload); } @@ -1596,49 +1621,52 @@ class Client /** * Update site snmp * - * @param string $snmp_id _id value of the snmp section + * @param string $snmp_id _id value of the snmp section * @param object|array $payload stdClass object or associative array containing the configuration to apply to the * site, must be a (partial) object/array structured in the same manner as is returned * by list_settings() for the section with the "snmp" key. Do not include the _id * property, it is assigned by the controller and returned upon success. * @return bool true on success */ - public function set_site_snmp($snmp_id, $payload) + public function set_site_snmp(string $snmp_id, $payload): bool { $this->curl_method = 'PUT'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/snmp/' . trim($snmp_id), $payload); } /** * Update site mgmt * - * @param string $mgmt_id _id value of the mgmt section + * @param string $mgmt_id _id value of the mgmt section * @param object|array $payload stdClass object or associative array containing the configuration to apply to the * site, must be a (partial) object/array structured in the same manner as is returned * by list_settings() for the section with the "mgmt" key. Do not include the _id * property, it is assigned by the controller and returned upon success. * @return bool true on success */ - public function set_site_mgmt($mgmt_id, $payload) + public function set_site_mgmt(string $mgmt_id, $payload): bool { $this->curl_method = 'PUT'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/mgmt/' . trim($mgmt_id), $payload); } /** * Update site guest access * - * @param string $guest_access_id _id value of the guest_access section - * @param object|array $payload stdClass object or associative array containing the configuration to apply + * @param string $guest_access_id _id value of the guest_access section + * @param object|array $payload stdClass object or associative array containing the configuration to apply * to the site, must be a (partial) object/array structured in the same manner * as is returned by list_settings() for the section with the "guest_access" * key. Do not include the _id property, it is assigned by the controller and * returned upon success. * @return bool true on success */ - public function set_site_guest_access($guest_access_id, $payload) + public function set_site_guest_access(string $guest_access_id, $payload): bool { $this->curl_method = 'PUT'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/guest_access/' . trim($guest_access_id), $payload); } @@ -1646,33 +1674,35 @@ class Client /** * Update site ntp * - * @param string $ntp_id _id value of the ntp section + * @param string $ntp_id _id value of the ntp section * @param object|array $payload stdClass object or associative array containing the configuration to apply to the * site, must be a (partial) object/array structured in the same manner as is returned * by list_settings() for the section with the "ntp" key. Do not include the _id * property, it is assigned by the controller and returned upon success. * @return bool true on success */ - public function set_site_ntp($ntp_id, $payload) + public function set_site_ntp(string $ntp_id, $payload): bool { $this->curl_method = 'PUT'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/ntp/' . trim($ntp_id), $payload); } /** * Update site connectivity * - * @param string $connectivity_id _id value of the connectivity section - * @param object|array $payload stdClass object or associative array containing the configuration to apply + * @param string $connectivity_id _id value of the connectivity section + * @param object|array $payload stdClass object or associative array containing the configuration to apply * to the site, must be a (partial) object/array structured in the same manner * as is returned by list_settings() for the section with the "connectivity" * key. Do not include the _id property, it is assigned by the controller and * returned upon success. * @return bool true on success */ - public function set_site_connectivity($connectivity_id, $payload) + public function set_site_connectivity(string $connectivity_id, $payload): bool { $this->curl_method = 'PUT'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/connectivity/' . trim($connectivity_id), $payload); } @@ -1682,9 +1712,10 @@ class Client * * @return array containing administrator objects for selected site */ - public function list_admins() + public function list_admins(): array { $payload = ['cmd' => 'get-admins']; + return $this->fetch_results('/api/s/' . $this->site . '/cmd/sitemgr', $payload); } @@ -1693,7 +1724,7 @@ class Client * * @return array containing administrator objects for all sites */ - public function list_all_admins() + public function list_all_admins(): array { return $this->fetch_results('/api/stat/admin'); } @@ -1705,31 +1736,33 @@ class Client * - after issuing a valid request, an invite is sent to the email address provided * - issuing this command against an existing admin triggers a "re-invite" * - * @param string $name name to assign to the new admin user - * @param string $email email address to assign to the new admin user - * @param bool $enable_sso optional, whether SSO is allowed for the new admin + * @param string $name name to assign to the new admin user + * @param string $email email address to assign to the new admin user + * @param bool $enable_sso optional, whether SSO is allowed for the new admin * default value is true which enables the SSO capability - * @param bool $readonly optional, whether the new admin has readonly + * @param bool $readonly optional, whether the new admin has readonly * permissions, default value is false which gives the new admin * Administrator permissions - * @param bool $device_adopt optional, whether the new admin has permissions to + * @param bool $device_adopt optional, whether the new admin has permissions to * adopt devices, default value is false. With versions < 5.9.X this only applies * when readonly is true. - * @param bool $device_restart optional, whether the new admin has permissions to + * @param bool $device_restart optional, whether the new admin has permissions to * restart devices, default value is false. With versions < 5.9.X this only applies * when readonly is true. * @return bool true on success */ public function invite_admin( - $name, - $email, - $enable_sso = true, - $readonly = false, - $device_adopt = false, - $device_restart = false - ) { + string $name, + string $email, + bool $enable_sso = true, + bool $readonly = false, + bool $device_adopt = false, + bool $device_restart = false + ): bool + { $email = trim($email); $email_valid = filter_var($email, FILTER_VALIDATE_EMAIL); + if (!$email_valid) { trigger_error('The email address provided is invalid!'); return false; @@ -1762,20 +1795,25 @@ class Client /** * Assign an existing admin to the current site * - * @param string $admin_id _id value of the admin user to assign, can be obtained using the + * @param string $admin_id _id value of the admin user to assign, can be obtained using the * list_all_admins() method/function - * @param bool $readonly optional, whether the new admin has readonly + * @param bool $readonly optional, whether the new admin has readonly * permissions, default value is false which gives the new admin * Administrator permissions - * @param bool $device_adopt optional, whether the new admin has permissions to + * @param bool $device_adopt optional, whether the new admin has permissions to * adopt devices, default value is false. With versions < 5.9.X this only applies * when readonly is true. - * @param bool $device_restart optional, whether the new admin has permissions to + * @param bool $device_restart optional, whether the new admin has permissions to * restart devices, default value is false. With versions < 5.9.X this only applies * when readonly is true. * @return bool true on success */ - public function assign_existing_admin($admin_id, $readonly = false, $device_adopt = false, $device_restart = false) + public function assign_existing_admin( + string $admin_id, + bool $readonly = false, + bool $device_adopt = false, + bool $device_restart = false + ): bool { $payload = [ 'cmd' => 'grant-admin', @@ -1809,9 +1847,10 @@ class Client * list_all_admins() method/function * @return bool true on success */ - public function revoke_admin($admin_id) + public function revoke_admin(string $admin_id): bool { $payload = ['cmd' => 'revoke-admin', 'admin' => $admin_id]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/sitemgr', $payload); } @@ -1820,7 +1859,7 @@ class Client * * @return array containing known wlan_groups */ - public function list_wlan_groups() + public function list_wlan_groups(): array { return $this->fetch_results('/api/s/' . $this->site . '/list/wlangroup'); } @@ -1830,7 +1869,7 @@ class Client * * @return array containing known sysinfo data */ - public function stat_sysinfo() + public function stat_sysinfo(): array { return $this->fetch_results('/api/s/' . $this->site . '/stat/sysinfo'); } @@ -1843,7 +1882,7 @@ class Client * * @return bool true upon success (controller is online) */ - public function stat_status() + public function stat_status(): bool { return $this->fetch_results_boolean('/status', null, false); } @@ -1859,6 +1898,7 @@ class Client public function stat_full_status() { $this->fetch_results_boolean('/status', null, false); + return json_decode($this->get_last_results_raw()); } @@ -1873,6 +1913,7 @@ class Client public function list_device_name_mappings() { $this->fetch_results_boolean('/dl/firmware/bundles.json', null, false); + return json_decode($this->get_last_results_raw()); } @@ -1881,7 +1922,7 @@ class Client * * @return array containing information about the logged-in user */ - public function list_self() + public function list_self(): array { return $this->fetch_results('/api/s/' . $this->site . '/self'); } @@ -1889,36 +1930,38 @@ class Client /** * Fetch vouchers * - * @param int $create_time optional, create time of the vouchers to fetch in Unix timestamp in seconds + * @param int|null $create_time optional, create time of the vouchers to fetch in Unix timestamp in seconds * @return array containing hotspot voucher objects */ - public function stat_voucher($create_time = null) + public function stat_voucher(int $create_time = null): array { $payload = isset($create_time) ? ['create_time' => intval($create_time)] : []; + return $this->fetch_results('/api/s/' . $this->site . '/stat/voucher', $payload); } /** * Fetch payments * - * @param int $within optional, number of hours to go back to fetch payments + * @param int|null $within optional, number of hours to go back to fetch payments * @return array containing hotspot payments */ - public function stat_payment($within = null) + public function stat_payment(int $within = null): array { $path_suffix = isset($within) ? '?within=' . intval($within) : ''; + return $this->fetch_results('/api/s/' . $this->site . '/stat/payment' . $path_suffix); } /** * Create hotspot operator (using REST) * - * @param string $name name for the hotspot operator + * @param string $name name for the hotspot operator * @param string $x_password clear text password for the hotspot operator - * @param string $note optional, note to attach to the hotspot operator + * @param string $note optional, note to attach to the hotspot operator * @return bool true upon success */ - public function create_hotspotop($name, $x_password, $note = '') + public function create_hotspotop(string $name, string $x_password, string $note = ''): bool { $payload = ['name' => $name, 'x_password' => $x_password]; if (!empty($note)) { @@ -1933,7 +1976,7 @@ class Client * * @return array containing hotspot operators */ - public function list_hotspotop() + public function list_hotspotop(): array { return $this->fetch_results('/api/s/' . $this->site . '/rest/hotspotop'); } @@ -1943,25 +1986,26 @@ class Client * * NOTES: please use the stat_voucher() method/function to retrieve the newly created voucher(s) by create_time * - * @param int $minutes minutes the voucher is valid after activation (expiration time) - * @param int $count number of vouchers to create, default value is 1 - * @param int $quota single-use or multi-use vouchers, value '0' is for multi-use, '1' is for single-use, + * @param int $minutes minutes the voucher is valid after activation (expiration time) + * @param int $count number of vouchers to create, default value is 1 + * @param int $quota single-use or multi-use vouchers, value '0' is for multi-use, '1' is for single-use, * 'n' is for multi-use n times - * @param string $note note text to add to voucher when printing - * @param int $up upload speed limit in kbps - * @param int $down download speed limit in kbps - * @param int $megabytes data transfer limit in MB + * @param string $note note text to add to voucher when printing + * @param int|null $up upload speed limit in kbps + * @param int|null $down download speed limit in kbps + * @param int|null $megabytes data transfer limit in MB * @return array containing a single object which contains the create_time(stamp) of the voucher(s) created */ public function create_voucher( - $minutes, - $count = 1, - $quota = 0, - $note = '', - $up = null, - $down = null, - $megabytes = null - ) { + int $minutes, + int $count = 1, + int $quota = 0, + string $note = '', + int $up = null, + int $down = null, + int $megabytes = null + ): array + { $payload = [ 'cmd' => 'create-voucher', 'expire' => intval($minutes), @@ -1994,9 +2038,10 @@ class Client * @param string $voucher_id _id value of the voucher to revoke * @return bool true on success */ - public function revoke_voucher($voucher_id) + public function revoke_voucher(string $voucher_id): bool { $payload = ['_id' => $voucher_id, 'cmd' => 'delete-voucher']; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/hotspot', $payload); } @@ -2006,7 +2051,7 @@ class Client * @param string $guest_id _id value of the guest to extend the authorization for * @return bool true on success */ - public function extend_guest_validity($guest_id) + public function extend_guest_validity(string $guest_id): bool { $payload = ['_id' => $guest_id, 'cmd' => 'extend']; return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/hotspot', $payload); @@ -2017,7 +2062,7 @@ class Client * * @return array containing port forwarding stats */ - public function list_portforward_stats() + public function list_portforward_stats(): array { return $this->fetch_results('/api/s/' . $this->site . '/stat/portforward'); } @@ -2027,7 +2072,7 @@ class Client * * @return array containing DPI stats */ - public function list_dpi_stats() + public function list_dpi_stats(): array { return $this->fetch_results('/api/s/' . $this->site . '/stat/dpi'); } @@ -2035,13 +2080,13 @@ class Client /** * Fetch filtered DPI stats * - * @param string $type optional, whether to returns stats by app or by category, valid values: + * @param string $type optional, whether to returns stats by app or by category, valid values: * 'by_cat' or 'by_app' - * @param array $cat_filter optional, array containing numeric category ids to filter by, + * @param array|null $cat_filter optional, array containing numeric category ids to filter by, * only to be combined with a "by_app" value for $type * @return array|false containing filtered DPI stats */ - public function list_dpi_stats_filtered($type = 'by_cat', array $cat_filter = null) + public function list_dpi_stats_filtered(string $type = 'by_cat', array $cat_filter = null) { if (!in_array($type, ['by_cat', 'by_app'])) { return false; @@ -2061,7 +2106,7 @@ class Client * * @return array containing currently allowed channels */ - public function list_current_channels() + public function list_current_channels(): array { return $this->fetch_results('/api/s/' . $this->site . '/stat/current-channel'); } @@ -2075,7 +2120,7 @@ class Client * * @return array containing available country codes */ - public function list_country_codes() + public function list_country_codes(): array { return $this->fetch_results('/api/s/' . $this->site . '/stat/ccode'); } @@ -2085,7 +2130,7 @@ class Client * * @return array containing port forwarding settings */ - public function list_portforwarding() + public function list_portforwarding(): array { return $this->fetch_results('/api/s/' . $this->site . '/list/portforward'); } @@ -2095,7 +2140,7 @@ class Client * * @return array containing port configurations */ - public function list_portconf() + public function list_portconf(): array { return $this->fetch_results('/api/s/' . $this->site . '/list/portconf'); } @@ -2105,7 +2150,7 @@ class Client * * @return array containing VoIP extensions */ - public function list_extension() + public function list_extension(): array { return $this->fetch_results('/api/s/' . $this->site . '/list/extension'); } @@ -2115,7 +2160,7 @@ class Client * * @return array containing site configuration settings */ - public function list_settings() + public function list_settings(): array { return $this->fetch_results('/api/s/' . $this->site . '/get/setting'); } @@ -2126,7 +2171,7 @@ class Client * @param string $mac device MAC address * @return bool true on success */ - public function adopt_device($mac) + public function adopt_device(string $mac): bool { $payload = ['mac' => strtolower($mac), 'cmd' => 'adopt']; return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); @@ -2135,16 +2180,24 @@ class Client /** * Adopt a device using custom SSH credentials * - * @param string $mac device MAC address - * @param string $ip IP to use for SSH connection - * @param string $username SSH username - * @param string $password SSH password - * @param string $url inform URL to point the device to - * @param int $port optional, SSH port - * @param bool $ssh_key_verify optional, whether to verify device SSH key + * @param string $mac device MAC address + * @param string $ip IP to use for SSH connection + * @param string $username SSH username + * @param string $password SSH password + * @param string $url inform URL to point the device to + * @param int $port optional, SSH port + * @param bool $ssh_key_verify optional, whether to verify device SSH key * @return bool true on success */ - public function advanced_adopt_device($mac, $ip, $username, $password, $url, $port = 22, $ssh_key_verify = true) + public function advanced_adopt_device( + string $mac, + string $ip, + string $username, + string $password, + string $url, + int $port = 22, + bool $ssh_key_verify = true + ): bool { $payload = [ 'cmd' => 'adv-adopt', @@ -2156,13 +2209,14 @@ class Client 'port' => $port, 'sshKeyVerify' => $ssh_key_verify, ]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); } /** * Reboot a device * - * @param string $mac device MAC address + * @param string $mac device MAC address * @param string $reboot_type optional, two options: 'soft' or 'hard', defaults to soft * soft can be used for all devices, requests a plain restart of that device * hard is special for PoE switches and besides the restart also requests a @@ -2170,9 +2224,10 @@ class Client * does *NOT* trigger a factory-reset. * @return bool true on success */ - public function restart_device($mac, $reboot_type = 'soft') + public function restart_device(string $mac, string $reboot_type = 'soft'): bool { $payload = ['cmd' => 'restart', 'mac' => strtolower($mac)]; + if (!empty($reboot_type) && in_array($reboot_type, ['soft', 'hard'])) { $payload['reboot_type'] = strtolower($reboot_type); } @@ -2181,14 +2236,15 @@ class Client } /** - * Force provision of a device + * Force the provision of a device * * @param string $mac device MAC address * @return bool true on success */ - public function force_provision($mac) + public function force_provision(string $mac): bool { $payload = ['mac' => strtolower($mac), 'cmd' => 'force-provision']; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); } @@ -2200,9 +2256,10 @@ class Client * * @return bool true on success */ - public function reboot_cloudkey() + public function reboot_cloudkey(): bool { $payload = ['cmd' => 'reboot']; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/system', $payload); } @@ -2214,18 +2271,16 @@ class Client * - appears to only be supported for access points * - available since controller versions 5.2.X * - * @param string $ap_id value of _id for the access point which can be obtained from the device list - * @param bool $disable true disables the device, false enables the device + * @param string $ap_id value of _id for the access point which can be obtained from the device list + * @param bool $disable true disables the device, false enables the device * @return bool true on success */ - public function disable_ap($ap_id, $disable) + public function disable_ap(string $ap_id, bool $disable): bool { - if (!is_bool($disable)) { - return false; - } - $this->curl_method = 'PUT'; - $payload = ['disabled' => $disable]; + + $payload = ['disabled' => $disable]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/device/' . trim($ap_id), $payload); } @@ -2235,20 +2290,22 @@ class Client * NOTES: * - available since controller versions 5.2.X * - * @param string $device_id value of _id for the device which can be obtained from the device list + * @param string $device_id value of _id for the device which can be obtained from the device list * @param string $override_mode off/on/default; "off" disables the LED of the device, * "on" enables the LED of the device, * "default" applies the site-wide setting for device LEDs * @return bool true on success */ - public function led_override($device_id, $override_mode) + public function led_override(string $device_id, string $override_mode): bool { if (!in_array($override_mode, ['off', 'on', 'default'])) { return false; } $this->curl_method = 'PUT'; - $payload = ['led_override' => $override_mode]; + + $payload = ['led_override' => $override_mode]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/device/' . trim($device_id), $payload); } @@ -2258,18 +2315,16 @@ class Client * NOTES: * replaces the old set_locate_ap() and unset_locate_ap() methods/functions * - * @param string $mac device MAC address - * @param bool $enable true enables flashing LED, false disables flashing LED + * @param string $mac device MAC address + * @param bool $enable true enables flashing LED, false disables flashing LED * @return bool true on success */ - public function locate_ap($mac, $enable) + public function locate_ap(string $mac, bool $enable): bool { - if (!is_bool($enable)) { - return false; - } + $cmd = $enable ? 'set-locate' : 'unset-locate'; - $cmd = $enable ? 'set-locate' : 'unset-locate'; $payload = ['cmd' => $cmd, 'mac' => strtolower($mac)]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); } @@ -2279,13 +2334,10 @@ class Client * @param bool $enable true switches LEDs of all the access points ON, false switches them OFF * @return bool true on success */ - public function site_leds($enable) + public function site_leds(bool $enable): bool { - if (!is_bool($enable)) { - return false; - } - $payload = ['led_enabled' => $enable]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/set/setting/mgmt', $payload); } @@ -2295,15 +2347,15 @@ class Client * NOTES: * - only supported on pre-5.X.X controller versions * - * @param string $ap_id the "_id" value for the access point you wish to update - * @param string $radio radio to update, default=ng - * @param int $channel channel to apply - * @param int $ht channel width, default=20 + * @param string $ap_id the "_id" value for the access point you wish to update + * @param string $radio radio to update, default=ng + * @param int $channel channel to apply + * @param int $ht channel width, default=20 * @param string $tx_power_mode power level, "low", "medium", or "high" - * @param int $tx_power transmit power level, default=0 + * @param int $tx_power transmit power level, default=0 * @return bool true on success */ - public function set_ap_radiosettings($ap_id, $radio, $channel, $ht, $tx_power_mode, $tx_power) + public function set_ap_radiosettings(string $ap_id, string $radio, int $channel, int $ht, string $tx_power_mode, int $tx_power): bool { $payload = [ 'radio_table' => [ @@ -2314,18 +2366,19 @@ class Client 'tx_power' => $tx_power, ], ]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/upd/device/' . trim($ap_id), $payload); } /** * Assign access point to another WLAN group * - * @param string $type_id WLAN type, can be either 'ng' (for WLANs 2G (11n/b/g)) or 'na' (WLANs 5G (11n/a/ac)) + * @param string $type_id WLAN type, can be either 'ng' (for WLANs 2G (11n/b/g)) or 'na' (WLANs 5G (11n/a/ac)) * @param string $device_id _id value of the access point to be modified - * @param string $group_id _id value of the WLAN group to assign device to + * @param string $group_id _id value of the WLAN group to assign device to * @return bool true on success */ - public function set_ap_wlangroup($type_id, $device_id, $group_id) + public function set_ap_wlangroup(string $type_id, string $device_id, string $group_id): bool { if (!in_array($type_id, ['ng', 'na'])) { return false; @@ -2335,6 +2388,7 @@ class Client 'wlan_overrides' => [], 'wlangroup_id_' . $type_id => $group_id, ]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/upd/device/' . trim($device_id), $payload); } @@ -2344,27 +2398,28 @@ class Client * NOTES: * - both portal parameters are set to the same value! * - * @param bool $portal_enabled enable/disable the captive portal - * @param bool $portal_customized enable/disable captive portal customizations - * @param bool $redirect_enabled enable/disable captive portal redirect - * @param string $redirect_url url to redirect to, must include the http/https prefix, no trailing slashes - * @param string $x_password the captive portal (simple) password - * @param int $expire_number number of units for the authorization expiry - * @param int $expire_unit number of minutes within a unit (a value 60 is required for hours) - * @param string $section_id value of _id for the site settings section where key = "guest_access", settings + * @param bool $portal_enabled enable/disable the captive portal + * @param bool $portal_customized enable/disable captive portal customizations + * @param bool $redirect_enabled enable/disable captive portal redirect + * @param string $redirect_url url to redirect to, must include the http/https prefix, no trailing slashes + * @param string $x_password the captive portal (simple) password + * @param int $expire_number number of units for the authorization expiry + * @param int $expire_unit number of minutes within a unit (a value 60 is required for hours) + * @param string $section_id value of _id for the site settings section where key = "guest_access", settings * can be obtained using the list_settings() function * @return bool true on success */ public function set_guestlogin_settings( - $portal_enabled, - $portal_customized, - $redirect_enabled, - $redirect_url, - $x_password, - $expire_number, - $expire_unit, - $section_id - ) { + bool $portal_enabled, + bool $portal_customized, + bool $redirect_enabled, + string $redirect_url, + string $x_password, + int $expire_number, + int $expire_unit, + string $section_id + ): bool + { $payload = [ 'portal_enabled' => $portal_enabled, 'portal_customized' => $portal_customized, @@ -2384,11 +2439,12 @@ class Client * Update guest login settings, base * * @param object|array $payload stdClass object or associative array containing the configuration to apply to the - * guest login, must be a (partial) object/array structured in the same manner as is + * guest logins, must be a (partial) object/array structured in the same manner as is * returned by list_settings() for the "guest_access" section. + * @param string $section_id * @return bool true on success */ - public function set_guestlogin_settings_base($payload, $section_id = '') + public function set_guestlogin_settings_base($payload, string $section_id = ''): bool { if (!empty($section_id)) { $section_id = '/' . $section_id; @@ -2406,7 +2462,7 @@ class Client * list_settings() for the "ips" section. * @return bool true on success */ - public function set_ips_settings_base($payload) + public function set_ips_settings_base($payload): bool { return $this->fetch_results_boolean('/api/s/' . $this->site . '/set/setting/ips', $payload); } @@ -2414,14 +2470,14 @@ class Client /** * Update "Super Management" settings, base * - * @param string $settings_id value of _id for the site settings section where key = "super_mgmt", settings + * @param string $settings_id value of _id for the site settings section where key = "super_mgmt", settings * can be obtained using the list_settings() function - * @param object|array $payload stdClass object or associative array containing the "Super Management" settings + * @param object|array $payload stdClass object or associative array containing the "Super Management" settings * to apply, must be a (partial) object/array structured in the same manner as is * returned by list_settings() for the "super_mgmt" section. * @return bool true on success */ - public function set_super_mgmt_settings_base($settings_id, $payload) + public function set_super_mgmt_settings_base(string $settings_id, $payload): bool { return $this->fetch_results_boolean('/api/s/' . $this->site . '/set/setting/super_mgmt/' . trim($settings_id), $payload); @@ -2430,14 +2486,14 @@ class Client /** * Update "Super SMTP" settings, base * - * @param string $settings_id value of _id for the site settings section where key = "super_smtp", settings + * @param string $settings_id value of _id for the site settings section where key = "super_smtp", settings * can be obtained using the list_settings() function - * @param object|array $payload stdClass object or associative array containing the "Super SMTP" settings to + * @param object|array $payload stdClass object or associative array containing the "Super SMTP" settings to * apply, must be a (partial) object/array structured in the same manner as is * returned by list_settings() for the "super_smtp" section. * @return bool true on success */ - public function set_super_smtp_settings_base($settings_id, $payload) + public function set_super_smtp_settings_base(string $settings_id, $payload): bool { return $this->fetch_results_boolean('/api/s/' . $this->site . '/set/setting/super_smtp/' . trim($settings_id), $payload); @@ -2446,14 +2502,14 @@ class Client /** * Update "Super Controller Identity" settings, base * - * @param string $settings_id value of _id for the site settings section where key = "super_identity", + * @param string $settings_id value of _id for the site settings section where key = "super_identity", * settings can be obtained using the list_settings() function - * @param object|array $payload stdClass object or associative array containing the "Super Controller Identity" + * @param object|array $payload stdClass object or associative array containing the "Super Controller Identity" * settings to apply, must be a (partial) object/array structured in the same * manner as is returned by list_settings() for the "super_identity" section. * @return bool true on success */ - public function set_super_identity_settings_base($settings_id, $payload) + public function set_super_identity_settings_base(string $settings_id, $payload): bool { return $this->fetch_results_boolean('/api/s/' . $this->site . '/set/setting/super_identity/' . trim($settings_id), $payload); @@ -2462,26 +2518,28 @@ class Client /** * Rename access point * - * @param string $ap_id _id of the access point to rename - * @param string $apname new name to assign to the access point + * @param string $ap_id _id of the access point to rename + * @param string $ap_name new name to assign to the access point * @return bool true on success */ - public function rename_ap($ap_id, $apname) + public function rename_ap(string $ap_id, string $ap_name): bool { - $payload = ['name' => $apname]; + $payload = ['name' => $ap_name]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/upd/device/' . trim($ap_id), $payload); } /** * Move a device to another site * - * @param string $mac MAC address of the device to move + * @param string $mac MAC address of the device to move * @param string $site_id _id (24 char string) of the site to move the device to * @return bool true on success */ - public function move_device($mac, $site_id) + public function move_device(string $mac, string $site_id): bool { $payload = ['site' => $site_id, 'mac' => strtolower($mac), 'cmd' => 'move-device']; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/sitemgr', $payload); } @@ -2491,9 +2549,10 @@ class Client * @param string $mac MAC address of the device to delete * @return bool true on success */ - public function delete_device($mac) + public function delete_device(string $mac): bool { $payload = ['mac' => strtolower($mac), 'cmd' => 'delete-device']; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/sitemgr', $payload); } @@ -2502,7 +2561,7 @@ class Client * * @return array containing dynamic DNS settings */ - public function list_dynamicdns() + public function list_dynamicdns(): array { return $this->fetch_results('/api/s/' . $this->site . '/rest/dynamicdns'); } @@ -2516,7 +2575,7 @@ class Client * list_dynamicdns() for the site. * @return bool true on success */ - public function create_dynamicdns($payload) + public function create_dynamicdns($payload): bool { return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/dynamicdns', $payload); } @@ -2524,16 +2583,17 @@ class Client /** * Update site dynamic DNS, base (using REST) * - * @param string $dynamicdns_id _id of the settings which can be found with the list_dynamicdns() function - * @param object|array $payload stdClass object or associative array containing the configuration to apply to + * @param string $dynamicdns_id _id of the settings which can be found with the list_dynamicdns() function + * @param object|array $payload stdClass object or associative array containing the configuration to apply to * the site, must be a * (partial) object/array structured in the same manner as is returned by * list_dynamicdns() for the site. * @return bool true on success */ - public function set_dynamicdns($dynamicdns_id, $payload) + public function set_dynamicdns(string $dynamicdns_id, $payload): bool { $this->curl_method = 'PUT'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/dynamicdns/' . trim($dynamicdns_id), $payload); } @@ -2544,7 +2604,7 @@ class Client * @param string $network_id optional, _id value of the network to get settings for * @return array containing (non-wireless) networks and their settings */ - public function list_networkconf($network_id = '') + public function list_networkconf(string $network_id = ''): array { return $this->fetch_results('/api/s/' . $this->site . '/rest/networkconf/' . trim($network_id)); } @@ -2566,15 +2626,16 @@ class Client /** * Update network settings, base (using REST) * - * @param string $network_id the "_id" value for the network you wish to update - * @param object|array $payload stdClass object or associative array containing the configuration to apply to + * @param string $network_id the "_id" value for the network you wish to update + * @param object|array $payload stdClass object or associative array containing the configuration to apply to * the network, must be a (partial) object/array structured in the same manner as * is returned by list_networkconf() for the network. * @return bool true on success */ - public function set_networksettings_base($network_id, $payload) + public function set_networksettings_base(string $network_id, $payload): bool { $this->curl_method = 'PUT'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/networkconf/' . trim($network_id), $payload); } @@ -2585,9 +2646,10 @@ class Client * @param string $network_id _id value of the network which can be found with the list_networkconf() function * @return bool true on success */ - public function delete_network($network_id) + public function delete_network(string $network_id): bool { $this->curl_method = 'DELETE'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/networkconf/' . trim($network_id)); } @@ -2598,7 +2660,7 @@ class Client * @return array containing wireless networks and their settings, or an array containing a single wireless network * when using the parameter */ - public function list_wlanconf($wlan_id = '') + public function list_wlanconf(string $wlan_id = ''): array { return $this->fetch_results('/api/s/' . $this->site . '/rest/wlanconf/' . trim($wlan_id)); } @@ -2606,48 +2668,49 @@ class Client /** * Create a WLAN * - * @param string $name SSID - * @param string $x_passphrase new pre-shared key, minimal length is 8 characters, maximum length is 63, + * @param string $name SSID + * @param string $x_passphrase new pre-shared key, minimal length is 8 characters, maximum length is 63, * assign a value of null when security = 'open' - * @param string $usergroup_id user group id that can be found using the list_usergroups() function - * @param string $wlangroup_id wlan group id that can be found using the list_wlan_groups() function - * @param boolean $enabled optional, enable/disable wlan - * @param boolean $hide_ssid optional, hide/unhide wlan SSID - * @param boolean $is_guest optional, apply guest policies or not - * @param string $security optional, security type (open, wep, wpapsk, wpaeap) - * @param string $wpa_mode optional, wpa mode (wpa, wpa2, ..) - * @param string $wpa_enc optional, encryption (auto, ccmp) - * @param boolean $vlan_enabled optional, enable/disable VLAN for this wlan (is ignored as of 1.1.73) - * @param string $vlan_id optional, "_id" value of the VLAN to assign to this WLAN, can be found using + * @param string $usergroup_id user group id that can be found using the list_usergroups() function + * @param string $wlangroup_id wlan group id that can be found using the list_wlan_groups() function + * @param boolean $enabled optional, enable/disable wlan + * @param boolean $hide_ssid optional, hide/unhide wlan SSID + * @param boolean $is_guest optional, apply guest policies or not + * @param string $security optional, security type (open, wep, wpapsk, wpaeap) + * @param string $wpa_mode optional, wpa mode (wpa, wpa2, ..) + * @param string $wpa_enc optional, encryption (auto, ccmp) + * @param boolean $vlan_enabled optional, enable/disable VLAN for this wlan (is ignored as of 1.1.73) + * @param string|null $vlan_id optional, "_id" value of the VLAN to assign to this WLAN, can be found using * list_networkconf() - * @param boolean $uapsd_enabled optional, enable/disable Unscheduled Automatic Power Save Delivery + * @param boolean $uapsd_enabled optional, enable/disable Unscheduled Automatic Power Save Delivery * @param boolean $schedule_enabled optional, enable/disable wlan schedule - * @param array $schedule optional, schedule rules - * @param array $ap_group_ids optional, array of ap group ids, required for UniFi controller versions 6.0.X + * @param array $schedule optional, schedule rules + * @param array|null $ap_group_ids optional, array of ap group ids, required for UniFi controller versions 6.0.X * and higher - * @param array $payload optional, array of additional parameters (wlan_bands, wpa3_support, etc.) + * @param array $payload optional, array of additional parameters (wlan_bands, wpa3_support, etc.) * @return bool true on success */ public function create_wlan( - $name, - $x_passphrase, - $usergroup_id, - $wlangroup_id, - $enabled = true, - $hide_ssid = false, - $is_guest = false, - $security = 'open', - $wpa_mode = 'wpa2', - $wpa_enc = 'ccmp', - $vlan_enabled = null, - $vlan_id = null, - $uapsd_enabled = false, - $schedule_enabled = false, - $schedule = [], - $ap_group_ids = null, - $payload = [] - ) { - $payload = array_merge($payload,[ + string $name, + string $x_passphrase, + string $usergroup_id, + string $wlangroup_id, + bool $enabled = true, + bool $hide_ssid = false, + bool $is_guest = false, + string $security = 'open', + string $wpa_mode = 'wpa2', + string $wpa_enc = 'ccmp', + bool $vlan_enabled = null, + string $vlan_id = null, + bool $uapsd_enabled = false, + bool $schedule_enabled = false, + array $schedule = [], + array $ap_group_ids = null, + array $payload = [] + ): bool + { + $payload = array_merge($payload, [ 'name' => trim($name), 'usergroup_id' => trim($usergroup_id), 'wlangroup_id' => trim($wlangroup_id), @@ -2680,28 +2743,29 @@ class Client /** * Update wlan settings, base (using REST) * - * @param string $wlan_id the "_id" value for the WLAN which can be found with the list_wlanconf() function + * @param string $wlan_id the "_id" value for the WLAN which can be found with the list_wlanconf() function * @param object|array $payload stdClass object or associative array containing the configuration to apply to the * wlan, must be a (partial) object/array structured in the same manner as is returned * by list_wlanconf() for the wlan. * @return bool true on success */ - public function set_wlansettings_base($wlan_id, $payload) + public function set_wlansettings_base(string $wlan_id, $payload): bool { $this->curl_method = 'PUT'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/wlanconf/' . trim($wlan_id), $payload); } /** * Update basic wlan settings * - * @param string $wlan_id the "_id" value for the WLAN which can be found with the list_wlanconf() function + * @param string $wlan_id the "_id" value for the WLAN which can be found with the list_wlanconf() function * @param string $x_passphrase new pre-shared key, minimal length is 8 characters, maximum length is 63, * is ignored if set to null - * @param string $name optional, SSID + * @param string $name optional, SSID * @return bool true on success */ - public function set_wlansettings($wlan_id, $x_passphrase, $name = '') + public function set_wlansettings(string $wlan_id, string $x_passphrase, string $name = ''): bool { $payload = []; $payload['x_passphrase'] = trim($x_passphrase); @@ -2717,17 +2781,14 @@ class Client * Disable/Enable wlan * * @param string $wlan_id the "_id" value for the WLAN which can be found with the list_wlanconf() function - * @param bool $disable true disables the wlan, false enables it + * @param bool $disable true disables the wlan, false enables it * @return bool true on success */ - public function disable_wlan($wlan_id, $disable) + public function disable_wlan(string $wlan_id, bool $disable): bool { - if (!is_bool($disable)) { - return false; - } - $action = !$disable; $payload = ['enabled' => $action]; + return $this->set_wlansettings_base($wlan_id, $payload); } @@ -2737,7 +2798,7 @@ class Client * @param string $wlan_id the "_id" value for the WLAN which can be found with the list_wlanconf() function * @return bool true on success */ - public function delete_wlan($wlan_id) + public function delete_wlan(string $wlan_id): bool { $this->curl_method = 'DELETE'; return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/wlanconf/' . trim($wlan_id)); @@ -2746,28 +2807,25 @@ class Client /** * Update MAC filter for a wlan * - * @param string $wlan_id the "_id" value for the WLAN which can be found with the list_wlanconf() + * @param string $wlan_id the "_id" value for the WLAN which can be found with the list_wlanconf() * function - * @param string $mac_filter_policy string, "allow" or "deny"; default MAC policy to apply - * @param bool $mac_filter_enabled true enables the policy, false disables it - * @param array $macs must contain valid MAC strings to be placed in the MAC filter list, + * @param string $mac_filter_policy string, "allow" or "deny"; default MAC policy to apply + * @param bool $mac_filter_enabled true enables the policy, false disables it + * @param array $macs must contain valid MAC strings to be placed in the MAC filter list, * replacing existing values. Existing MAC filter list can be obtained * through list_wlanconf(). * @return bool true on success */ - public function set_wlan_mac_filter($wlan_id, $mac_filter_policy, $mac_filter_enabled, array $macs) + public function set_wlan_mac_filter(string $wlan_id, string $mac_filter_policy, bool $mac_filter_enabled, array $macs): bool { - if (!is_bool($mac_filter_enabled)) { - return false; - } - if (!in_array($mac_filter_policy, ['allow', 'deny'])) { return false; } - $macs = array_map('strtolower', $macs); + $macs = array_map('strtolower', $macs); + $payload = [ - 'mac_filter_enabled' => (bool) $mac_filter_enabled, + 'mac_filter_enabled' => (bool)$mac_filter_enabled, 'mac_filter_policy' => $mac_filter_policy, 'mac_filter_list' => $macs, ]; @@ -2779,12 +2837,12 @@ class Client * Fetch events * * @param integer $historyhours optional, hours to go back, default value is 720 hours - * @param integer $start optional, which event number to start with (useful for paging of results), default + * @param integer $start optional, which event number to start with (useful for paging of results), default * value is 0 - * @param integer $limit optional, number of events to return, default value is 3000 + * @param integer $limit optional, number of events to return, default value is 3000 * @return array containing known events */ - public function list_events($historyhours = 720, $start = 0, $limit = 3000) + public function list_events(int $historyhours = 720, int $start = 0, int $limit = 3000): array { $payload = [ '_sort' => '-time', @@ -2793,6 +2851,7 @@ class Client '_start' => intval($start), '_limit' => intval($limit), ]; + return $this->fetch_results('/api/s/' . $this->site . '/stat/event', $payload); } @@ -2804,7 +2863,7 @@ class Client * return only unarchived for a specific key * @return array containing known alarms */ - public function list_alarms($payload = []) + public function list_alarms(array $payload = []): array { return $this->fetch_results('/api/s/' . $this->site . '/list/alarm', $payload); } @@ -2812,13 +2871,14 @@ class Client /** * Count alarms * - * @param bool $archived optional, if true all alarms are counted, if false only non-archived (active) alarms are + * @param bool|null $archived optional, if true all alarms are counted, if false only non-archived (active) alarms are * counted, by default all alarms are counted * @return array containing the alarm count */ - public function count_alarms($archived = null) + public function count_alarms(bool $archived = null): array { $path_suffix = $archived === false ? '?archived=false' : null; + return $this->fetch_results('/api/s/' . $this->site . '/cnt/alarm' . $path_suffix); } @@ -2829,9 +2889,10 @@ class Client * by default all alarms are archived * @return bool true on success */ - public function archive_alarm($alarm_id = '') + public function archive_alarm(string $alarm_id = ''): bool { $payload = ['cmd' => 'archive-all-alarms']; + if (!empty($alarm_id)) { $payload = ['_id' => $alarm_id, 'cmd' => 'archive-alarm']; } @@ -2861,9 +2922,10 @@ class Client * * @return bool returns true upon success */ - public function check_firmware_update() + public function check_firmware_update(): bool { $payload = ['cmd' => 'check-firmware-update']; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/productinfo', $payload); } @@ -2876,9 +2938,10 @@ class Client * @param string $device_mac MAC address of the device to upgrade * @return bool returns true upon success */ - public function upgrade_device($device_mac) + public function upgrade_device(string $device_mac): bool { $payload = ['mac' => strtolower($device_mac)]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr/upgrade', $payload); } @@ -2890,12 +2953,13 @@ class Client * - please take great care to select a valid firmware file for the device! * * @param string $firmware_url URL for the firmware file to upgrade the device to - * @param string $device_mac MAC address of the device to upgrade + * @param string $device_mac MAC address of the device to upgrade * @return bool returns true upon success */ - public function upgrade_device_external($firmware_url, $device_mac) + public function upgrade_device_external(string $firmware_url, string $device_mac): bool { $payload = ['url' => filter_var($firmware_url, FILTER_SANITIZE_URL), 'mac' => strtolower($device_mac)]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr/upgrade-external', $payload); } @@ -2908,9 +2972,10 @@ class Client * * @return bool returns true upon success */ - public function start_rolling_upgrade() + public function start_rolling_upgrade(): bool { $payload = ['cmd' => 'set-rollupgrade']; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); } @@ -2919,9 +2984,10 @@ class Client * * @return bool returns true upon success */ - public function cancel_rolling_upgrade() + public function cancel_rolling_upgrade(): bool { $payload = ['cmd' => 'unset-rollupgrade']; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); } @@ -2932,13 +2998,14 @@ class Client * default value is "available" * @return array|false containing firmware versions */ - public function list_firmware($type = 'available') + public function list_firmware(string $type = 'available') { if (!in_array($type, ['available', 'cached'])) { return false; } $payload = ['cmd' => 'list-' . $type]; + return $this->fetch_results('/api/s/' . $this->site . '/cmd/firmware', $payload); } @@ -2950,12 +3017,13 @@ class Client * - port must be actually providing power * * @param string $switch_mac main MAC address of the switch - * @param int $port_idx port number/index of the port to be affected + * @param int $port_idx port number/index of the port to be affected * @return bool returns true upon success */ - public function power_cycle_switch_port($switch_mac, $port_idx) + public function power_cycle_switch_port(string $switch_mac, int $port_idx): bool { $payload = ['mac' => strtolower($switch_mac), 'port_idx' => intval($port_idx), 'cmd' => 'power-cycle']; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); } @@ -2965,7 +3033,7 @@ class Client * @param string $ap_mac MAC address of the AP * @return bool returns true upon success */ - public function spectrum_scan($ap_mac) + public function spectrum_scan(string $ap_mac): bool { $payload = ['cmd' => 'spectrum-scan', 'mac' => strtolower($ap_mac)]; return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); @@ -2978,7 +3046,7 @@ class Client * @return array|bool containing relevant information (results if available) regarding the RF scanning state of the * AP */ - public function spectrum_scan_state($ap_mac) + public function spectrum_scan_state(string $ap_mac): array { return $this->fetch_results('/api/s/' . $this->site . '/stat/spectrum-scan/' . strtolower(trim($ap_mac))); } @@ -2986,16 +3054,17 @@ class Client /** * Update device settings, base (using REST) * - * @param string $device_id _id of the device which can be found with the list_devices() function - * @param object|array $payload stdClass object or associative array containing the configuration to apply to the + * @param string $device_id _id of the device which can be found with the list_devices() function + * @param object|array $payload stdClass object or associative array containing the configuration to apply to the * device, must be a * (partial) object/array structured in the same manner as is returned by * list_devices() for the device. * @return bool true on success */ - public function set_device_settings_base($device_id, $payload) + public function set_device_settings_base(string $device_id, $payload): bool { $this->curl_method = 'PUT'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/device/' . trim($device_id), $payload); } @@ -3007,7 +3076,7 @@ class Client * * @return array objects containing all Radius profiles for the current site */ - public function list_radius_profiles() + public function list_radius_profiles(): array { return $this->fetch_results('/api/s/' . $this->site . '/rest/radiusprofile'); } @@ -3020,7 +3089,7 @@ class Client * * @return array objects containing all Radius accounts for the current site */ - public function list_radius_accounts() + public function list_radius_accounts(): array { return $this->fetch_results('/api/s/' . $this->site . '/rest/account'); } @@ -3031,9 +3100,9 @@ class Client * NOTES: * - this function/method is only supported on controller versions 5.5.19 and later * - * @param string $name name for the new account - * @param string $x_password password for the new account - * @param int $tunnel_type optional, must be one of the following values: + * @param string $name name for the new account + * @param string $x_password password for the new account + * @param int|null $tunnel_type optional, must be one of the following values: * 1 Point-to-Point Tunneling Protocol (PPTP) * 2 Layer Two Forwarding (L2F) * 3 Layer Two Tunneling Protocol (L2TP) @@ -3047,7 +3116,7 @@ class Client * 11 Bay Dial Virtual Services (DVS) * 12 IP-in-IP Tunneling * 13 Virtual LANs (VLAN) - * @param int $tunnel_medium_type optional, must be one of the following values: + * @param int|null $tunnel_medium_type optional, must be one of the following values: * 1 IPv4 (IP version 4) * 2 IPv6 (IP version 6) * 3 NSAP @@ -3063,14 +3132,22 @@ class Client * 13 Decnet IV * 14 Banyan Vines * 15 E.164 with NSAP format subaddress - * @param int $vlan optional, VLAN to assign to the account + * @param int|null $vlan optional, VLAN to assign to the account * @return bool|array containing a single object for the newly created account upon success, else returns false */ - public function create_radius_account($name, $x_password, $tunnel_type = null, $tunnel_medium_type = null, $vlan = null) + public function create_radius_account( + string $name, + string $x_password, + int $tunnel_type = null, + int $tunnel_medium_type = null, + int $vlan = null + ) { $tunnel_type_values = [null, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; $tunnel_medium_type_values = [null, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; - if (!in_array($tunnel_type, $tunnel_type_values) || !in_array($tunnel_medium_type, $tunnel_medium_type_values) || ($tunnel_type xor $tunnel_medium_type)) { + + if (!in_array($tunnel_type, $tunnel_type_values) || !in_array($tunnel_medium_type, + $tunnel_medium_type_values) || ($tunnel_type xor $tunnel_medium_type)) { return false; } @@ -3080,15 +3157,15 @@ class Client ]; if (!is_null($tunnel_type)) { - $payload['tunnel_type'] = (int) $tunnel_type; + $payload['tunnel_type'] = (int)$tunnel_type; } if (!is_null($tunnel_medium_type)) { - $payload['tunnel_medium_type'] = (int) $tunnel_medium_type; + $payload['tunnel_medium_type'] = (int)$tunnel_medium_type; } if (!is_null($vlan)) { - $payload['vlan'] = (string) $vlan; + $payload['vlan'] = (string)$vlan; } return $this->fetch_results('/api/s/' . $this->site . '/rest/account', $payload); @@ -3100,15 +3177,16 @@ class Client * NOTES: * - this function/method is only supported on controller versions 5.5.19 and later * - * @param string $account_id _id of the account which can be found with the list_radius_accounts() function - * @param object|array $payload stdClass object or associative array containing the new profile to apply to the + * @param string $account_id _id of the account which can be found with the list_radius_accounts() function + * @param object|array $payload stdClass object or associative array containing the new profile to apply to the * account, must be a (partial) object/array structured in the same manner as is * returned by list_radius_accounts() for the account. * @return bool true on success */ - public function set_radius_account_base($account_id, $payload) + public function set_radius_account_base(string $account_id, $payload): bool { $this->curl_method = 'PUT'; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/account/' . trim($account_id), $payload); } @@ -3121,7 +3199,7 @@ class Client * @param string $account_id _id of the account which can be found with the list_radius_accounts() function * @return bool true on success */ - public function delete_radius_account($account_id) + public function delete_radius_account(string $account_id): bool { $this->curl_method = 'DELETE'; return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/account/' . trim($account_id)); @@ -3135,13 +3213,14 @@ class Client * to be extended in the future * @return bool true on success */ - public function cmd_stat($command) + public function cmd_stat(string $command): bool { if ($command != 'reset-dpi') { return false; } $payload = ['cmd' => trim($command)]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/stat', $payload); } @@ -3151,13 +3230,14 @@ class Client * @param bool $enable true enables Element Adoption, false disables Element Adoption * @return bool true on success */ - public function set_element_adoption($enable) + public function set_element_adoption(bool $enable): bool { if (!is_bool($enable)) { return false; } $payload = ['enabled' => $enable]; + return $this->fetch_results_boolean('/api/s/' . $this->site . '/set/setting/element_adopt', $payload); } @@ -3170,7 +3250,7 @@ class Client * * @return array containing translations of UniFi device "state" values to humanized form */ - public function list_device_states() + public function list_device_states(): array { return [ 0 => 'offline', @@ -3193,16 +3273,16 @@ class Client * Only use this method when you fully understand the behavior of the UniFi controller API. No input validation is * performed, to be used with care! * - * @param string $path suffix of the URL (following the port number) to pass request to, *must* start with + * @param string $path suffix of the URL (following the port number) to pass request to, *must* start with * a "/" character - * @param string $method optional, HTTP request type, can be GET (default), POST, PUT, PATCH, or DELETE - * @param object|array $payload optional, stdClass object or associative array containing the payload to pass - * @param string $return optional, string; determines how to return results, when "boolean" the method must + * @param string $method optional, HTTP request type, can be GET (default), POST, PUT, PATCH, or DELETE + * @param object|array|null $payload optional, stdClass object or associative array containing the payload to pass + * @param string $return optional, string; determines how to return results, when "boolean" the method must * return a boolean result (true/false) or "array" when the method must return an * array * @return bool|array returns results as requested, returns false on incorrect parameters */ - public function custom_api_request($path, $method = 'GET', $payload = null, $return = 'array') + public function custom_api_request(string $path, string $method = 'GET', $payload = null, string $return = 'array') { if (!in_array($method, $this->curl_methods_allowed)) { return false; @@ -3234,10 +3314,10 @@ class Client * NOTE: * changed function/method name to fit its purpose * - * @param string $device_mac optional, the MAC address of a single device for which the call must be made + * @param string|null $device_mac optional, the MAC address of a single device for which the call must be made * @return array containing known device objects (or a single device when using the parameter) */ - public function list_aps($device_mac = null) + public function list_aps(string $device_mac = null): array { trigger_error( 'Function list_aps() has been deprecated, use list_devices() instead.', @@ -3253,7 +3333,7 @@ class Client * @param string $mac device MAC address * @return bool true on success */ - public function set_locate_ap($mac) + public function set_locate_ap(string $mac): bool { trigger_error( 'Function set_locate_ap() has been deprecated, use locate_ap() instead.', @@ -3269,7 +3349,7 @@ class Client * @param string $mac device MAC address * @return bool true on success */ - public function unset_locate_ap($mac) + public function unset_locate_ap(string $mac): bool { trigger_error( 'Function unset_locate_ap() has been deprecated, use locate_ap() instead.', @@ -3284,7 +3364,7 @@ class Client * * @return bool true on success */ - public function site_ledson() + public function site_ledson(): bool { trigger_error( 'Function site_ledson() has been deprecated, use site_leds() instead.', @@ -3299,7 +3379,7 @@ class Client * * @return bool true on success */ - public function site_ledsoff() + public function site_ledsoff(): bool { trigger_error( 'Function site_ledsoff() has been deprecated, use site_leds() instead.', @@ -3315,7 +3395,7 @@ class Client * @param string $mac device MAC address * @return bool true on success */ - public function restart_ap($mac) + public function restart_ap(string $mac): bool { trigger_error( 'Function restart_ap() has been deprecated, use restart_device() instead.', @@ -3339,10 +3419,12 @@ class Client * provided credentials have access * @return string the new (short) site name */ - public function set_site($site) + public function set_site(string $site): string { $this->check_site($site); + $this->site = trim($site); + return $this->site; } @@ -3351,7 +3433,7 @@ class Client * * @return string the current (short) site name */ - public function get_site() + public function get_site(): string { return $this->site; } @@ -3362,16 +3444,11 @@ class Client * @param bool $enable true enables debug mode, false disables debug mode * @return bool false when a non-boolean parameter was passed */ - public function set_debug($enable) + public function set_debug(bool $enable): bool { - if ($enable === true || $enable === false) { - $this->debug = $enable; - return true; - } + $this->debug = $enable; - trigger_error('Error: the parameter for set_debug() must be boolean'); - - return false; + return true; } /** @@ -3379,7 +3456,7 @@ class Client * * @return bool the current boolean value for $debug */ - public function get_debug() + public function get_debug(): bool { return $this->debug; } @@ -3391,7 +3468,7 @@ class Client * false returns PHP stdClass Object format (default) * @return false|string|object|null the raw results as returned by the controller API */ - public function get_last_results_raw($return_json = false) + public function get_last_results_raw(bool $return_json = false) { if (!is_null($this->last_results_raw)) { if ($return_json) { @@ -3405,12 +3482,12 @@ class Client } /** - * Get last error message + * Get the last error message * * @return string the error message of the last method called in PHP stdClass Object format, an empty string when * none available */ - public function get_last_error_message() + public function get_last_error_message(): string { return $this->last_error_message; } @@ -3419,32 +3496,32 @@ class Client * Get Cookie from UniFi controller (singular and plural) * * NOTES: - * - when the results from this method are stored in $_SESSION['unificookie'], the Class initially does not + * - when the results from this method are stored in $_SESSION[$this->unificookie_name], the Class initially does not * log in to the controller when a subsequent request is made using a new instance. This speeds up the * overall request considerably. Only when a subsequent request fails (e.g. cookies have expired) is a new login - * executed and the value of $_SESSION['unificookie'] updated. + * executed and the value of $_SESSION[$this->unificookie_name] updated. * - to force the Class instance to log out automatically upon destruct, simply call logout() or unset - * $_SESSION['unificookie'] at the end of your code + * $_SESSION[$this->unificookie_name] at the end of your code * * @return string the UniFi controller cookie */ - public function get_cookie() + public function get_cookie(): string { return $this->cookies; } - public function get_cookies() + public function get_cookies(): string { return $this->cookies; } /** - * Get version of the Class + * Get the version of the Class * * @return string semver compatible version of this class * https://semver.org/ */ - public function get_class_version() + public function get_class_version(): string { return self::CLASS_VERSION; } @@ -3454,17 +3531,27 @@ class Client * * @param string $cookies_value new value for $cookies */ - public function set_cookies($cookies_value) + public function set_cookies(string $cookies_value) { $this->cookies = $cookies_value; } + /** + * Get the current value of the private property $unificookie_name + * + * @return string current value of $unificookie_name + */ + public function get_unificookie_name(): string + { + return $this->unificookie_name; + } + /** * Get current request method * * @return string request type */ - public function get_curl_method() + public function get_curl_method(): string { return $this->curl_method; } @@ -3473,9 +3560,9 @@ class Client * Set request method * * @param string $curl_method a valid HTTP request method - * @return bool whether request was successful or not + * @return bool whether the request was successful or not */ - public function set_curl_method($curl_method) + public function set_curl_method(string $curl_method): bool { if (!in_array($curl_method, $this->curl_methods_allowed)) { @@ -3494,7 +3581,7 @@ class Client * * @return bool value of private property $ssl_verify_peer (cURL option CURLOPT_SSL_VERIFYPEER) */ - public function get_curl_ssl_verify_peer() + public function get_curl_ssl_verify_peer(): bool { return $this->curl_ssl_verify_peer; } @@ -3504,14 +3591,11 @@ class Client * * https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html * - * @param int|bool $curl_ssl_verify_peer should be 0/false or 1/true + * @param bool $curl_ssl_verify_peer should be 0/false or 1/true + * @return bool whether the request was successful or not */ - public function set_curl_ssl_verify_peer($curl_ssl_verify_peer) + public function set_curl_ssl_verify_peer(bool $curl_ssl_verify_peer): bool { - if (!in_array($curl_ssl_verify_peer, [0, false, 1, true])) { - return false; - } - $this->curl_ssl_verify_peer = $curl_ssl_verify_peer; return true; @@ -3522,9 +3606,9 @@ class Client * * https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html * - * @return bool value of private property $ssl_verify_peer (cURL option CURLOPT_SSL_VERIFYHOST) + * @return int value of private property $ssl_verify_peer (cURL option CURLOPT_SSL_VERIFYHOST) */ - public function get_curl_ssl_verify_host() + public function get_curl_ssl_verify_host(): int { return $this->curl_ssl_verify_host; } @@ -3534,11 +3618,12 @@ class Client * * https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html * - * @param int|bool $curl_ssl_verify_host should be 0/false or 2 + * @param int $curl_ssl_verify_host should be 0, 1 or 2 + * @return bool whether the request was successful or not */ - public function set_curl_ssl_verify_host($curl_ssl_verify_host) + public function set_curl_ssl_verify_host(int $curl_ssl_verify_host): bool { - if (!in_array($curl_ssl_verify_host, [0, false, 2])) { + if (!in_array($curl_ssl_verify_host, [0, 1, 2])) { return false; } @@ -3550,9 +3635,9 @@ class Client /** * Is current controller UniFi OS-based * - * @return bool whether current controller is UniFi OS-based + * @return bool whether the current controller is UniFi OS-based or not */ - public function get_is_unifi_os() + public function get_is_unifi_os(): bool { return $this->is_unifi_os; } @@ -3560,15 +3645,11 @@ class Client /** * Set value for private property $is_unifi_os * - * @param bool|int $is_unifi_os new value, must be 0, 1, true or false - * @return bool whether request was successful or not + * @param bool $is_unifi_os the new value + * @return bool whether the request was successful or not */ - public function set_is_unifi_os($is_unifi_os) + public function set_is_unifi_os(bool $is_unifi_os): bool { - if (!in_array($is_unifi_os, [0, false, 1, true])) { - return false; - } - $this->is_unifi_os = $is_unifi_os; return true; @@ -3578,18 +3659,21 @@ class Client * Set value for the private property $connect_timeout * * @param int $timeout new value for $connect_timeout in seconds + * @return bool whether the request was successful or not */ - public function set_connection_timeout($timeout) + public function set_connection_timeout(int $timeout): bool { $this->curl_connect_timeout = $timeout; + + return true; } /** - * Get current value of the private property $connect_timeout + * Get the current value of the private property $connect_timeout * * @return int current value of $connect_timeout */ - public function get_connection_timeout() + public function get_connection_timeout(): int { return $this->curl_connect_timeout; } @@ -3598,18 +3682,21 @@ class Client * Set value for the private property $request_timeout * * @param int $timeout new value for $request_timeout in seconds + * @return bool whether the request was successful or not */ - public function set_curl_request_timeout($timeout) + public function set_curl_request_timeout(int $timeout): bool { $this->curl_request_timeout = $timeout; + + return true; } /** - * Get current value of the private property $request_timeout + * Get the current value of the private property $request_timeout * * @return int current value of $request_timeout */ - public function get_curl_request_timeout() + public function get_curl_request_timeout(): int { return $this->curl_request_timeout; } @@ -3623,21 +3710,24 @@ class Client * * @param int $http_version new value for $curl_http_version, CURL_HTTP_VERSION_1_1 int(2) or * CURL_HTTP_VERSION_2TLS int(4) are recommended + * @return bool whether the request was successful or not * @see https://curl.se/libcurl/c/CURLOPT_HTTP_VERSION.html */ - public function set_curl_http_version($http_version) + public function set_curl_http_version(int $http_version): bool { $this->curl_http_version = $http_version; + + return true; } /** * Get current value of the private property $curl_http_version * - * @return int current value of $request_timeout, can be CURL_HTTP_VERSION_1_1 int(2) or + * @return int the current value of $request_timeout, can be CURL_HTTP_VERSION_1_1 int(2) or * CURL_HTTP_VERSION_2TLS int(4) * @see https://curl.se/libcurl/c/CURLOPT_HTTP_VERSION.html */ - public function get_curl_http_version() + public function get_curl_http_version(): int { return $this->curl_http_version; } @@ -3649,17 +3739,22 @@ class Client /** * Fetch results * - * execute the cURL request and return results + * Execute the cURL request and return results * - * @param string $path request path - * @param object|array $payload optional, PHP associative array or stdClass Object, payload to pass with the - * request - * @param boolean $boolean optional, whether the method should return a boolean result, else return - * the "data" array - * @param boolean $login_required optional, whether the method requires to be logged in or not - * @return bool|array [description] + * @param string $path request path + * @param object|array|null $payload optional, PHP associative array or stdClass Object, payload to pass with the + * request + * @param boolean $boolean optional, whether the method should return a boolean result, else return + * the "data" array + * @param boolean $login_required optional, whether the method requires to be logged in or not + * @return bool|array returns an array with the "data" array on success, else returns false */ - protected function fetch_results($path, $payload = null, $boolean = false, $login_required = true) + protected function fetch_results( + string $path, + $payload = null, + bool $boolean = false, + bool $login_required = true + ) { /** * guard clause to check if logged in when needed @@ -3723,13 +3818,13 @@ class Client * * execute the cURL request and return a boolean value * - * @param string $path request path - * @param object|array $payload optional, PHP associative array or stdClass Object, payload to pass with the - * request - * @param bool $login_required optional, whether the method requires to be logged in or not + * @param string $path request path + * @param object|array|null $payload optional, PHP associative array or stdClass Object, payload to pass with the + * request + * @param bool $login_required optional, whether the method requires to be logged in or not * @return bool [description] */ - protected function fetch_results_boolean($path, $payload = null, $login_required = true) + protected function fetch_results_boolean(string $path, $payload = null, bool $login_required = true): bool { return $this->fetch_results($path, $payload, true, $login_required); } @@ -3739,7 +3834,7 @@ class Client * * @return bool returns true upon success, false upon failure */ - protected function catch_json_last_error() + protected function catch_json_last_error(): bool { if ($this->debug) { $error = 'Unknown JSON error occurred'; @@ -3804,7 +3899,7 @@ class Client * @param string $baseurl the base URL to validate * @return bool true if base URL is a valid URL, else returns false */ - protected function check_base_url($baseurl) + protected function check_base_url(string $baseurl): bool { if (!filter_var($baseurl, FILTER_VALIDATE_URL) || substr($baseurl, -1) === '/') { trigger_error('The URL provided is incomplete, invalid or ends with a / character!'); @@ -3820,9 +3915,9 @@ class Client * @param string $site the (short) site name to check * @return bool true if (short) site name is valid, else returns false */ - protected function check_site($site) + protected function check_site(string $site): bool { - if ($this->debug && preg_match("/\s/", $site)) { + if ($this->debug && preg_match('/\s/', $site)) { trigger_error('The provided (short) site name may not contain any spaces'); return false; } @@ -3833,12 +3928,12 @@ class Client /** * Update the unificookie if sessions are enabled * - * @return bool true when unificookie was updated, else returns false + * @return bool returns true when unificookie was updated, else returns false */ - protected function update_unificookie() + protected function update_unificookie(): bool { - if (session_status() === PHP_SESSION_ACTIVE && isset($_SESSION['unificookie']) && !empty($_SESSION['unificookie'])) { - $this->cookies = $_SESSION['unificookie']; + if (session_status() === PHP_SESSION_ACTIVE && isset($_SESSION[$this->unificookie_name]) && !empty($_SESSION[$this->unificookie_name])) { + $this->cookies = $_SESSION[$this->unificookie_name]; /** * if the cookie contains a JWT this is a UniFi OS controller @@ -3878,11 +3973,11 @@ class Client /** * Callback function for cURL to extract and store cookies as needed * - * @param object|resource $ch the cURL instance - * @param int $header_line the response header line number + * @param object|resource $ch the cURL instance + * @param string $header_line the response header line number * @return int length of the header line */ - protected function response_header_callback($ch, $header_line) + protected function response_header_callback($ch, string $header_line): int { if (strpos($header_line, 'unifises') !== false || strpos($header_line, 'TOKEN') !== false) { $cookie = trim(str_replace(['set-cookie: ', 'Set-Cookie: '], '', $header_line)); @@ -3915,11 +4010,11 @@ class Client /** * Execute the cURL request * - * @param string $path path for the request - * @param object|array $payload optional, payload to pass with the request + * @param string $path path for the request + * @param object|array|null $payload optional, payload to pass with the request * @return bool|string response returned by the controller API, false upon error */ - protected function exec_curl($path, $payload = null) + protected function exec_curl(string $path, $payload = null) { if (!in_array($this->curl_method, $this->curl_methods_allowed)) { trigger_error('an invalid HTTP request type was used: ' . $this->curl_method); @@ -4019,8 +4114,8 @@ class Client /** * explicitly clear the expired Cookie/Token, update other properties and log out before logging in again */ - if (isset($_SESSION['unificookie'])) { - $_SESSION['unificookie'] = ''; + if (isset($_SESSION[$this->unificookie_name])) { + $_SESSION[$this->unificookie_name] = ''; } $this->is_logged_in = false;