Compare commits

...

10 Commits

Author SHA1 Message Date
malle-pietje
a5ca53a5b8 - applied changes from PR #258, contributed by @mvarian 2024-12-19 11:52:19 +01:00
malle-pietje
19dc76ddfb consistent use of "PHP DocBlocks" 2024-11-28 12:24:35 +01:00
malle-pietje
3a1d1ff0cd minor tweak to example 2024-11-28 12:21:42 +01:00
malle-pietje
8eeeb447c9 reformatted Exception handling example 2024-11-28 12:19:33 +01:00
malle-pietje
8acaa694ca - updated the README file
- updated @throws tags in the doc blocks to reflect the correct exception classes where necessary, in other cases "Exception" is mentioned
- minor changes
- bumped version to 2.0.2
2024-11-28 12:11:08 +01:00
malle-pietje
d81a371239 further improvements to the README.md file and the list_alarms.php example 2024-11-26 12:04:10 +01:00
malle-pietje
7a47bda1c0 updates to README.md to explain how to get older 1.x versions. 2024-11-26 11:53:59 +01:00
malle-pietje
fb493f4dc8 updated the PHP example in the README to include the Exception classes imports 2024-11-26 11:27:06 +01:00
malle-pietje
1f19891d90 updated the README file
updated the `examples/list_alarms.php` file to demonstrate Exception handling
2024-11-25 17:56:06 +01:00
malle-pietje
9a2432f067 added Exception classes
implement Exceptions in the main class
2024-11-25 17:34:18 +01:00
15 changed files with 940 additions and 683 deletions

361
README.md
View File

@@ -1,5 +1,10 @@
## UniFi Controller API client class
[![License](https://img.shields.io/github/license/Art-of-WiFi/UniFi-API-client)](https://github.com/Art-of-WiFi/UniFi-API-client/blob/main/LICENSE)
[![Packagist Version](https://img.shields.io/packagist/v/art-of-wifi/unifi-api-client)](https://packagist.org/packages/art-of-wifi/unifi-api-client)
[![Downloads](https://img.shields.io/packagist/dt/art-of-wifi/unifi-api-client)](https://packagist.org/packages/art-of-wifi/unifi-api-client)
[![PHP Version](https://img.shields.io/packagist/php-v/art-of-wifi/unifi-api-client)](https://packagist.org/packages/art-of-wifi/unifi-api-client)
A PHP class that provides access to Ubiquiti's [**UniFi Network Application**](https://unifi-network.ui.com/) API.
This class is used by our API Browser tool, which can be found
@@ -13,8 +18,8 @@ easy inclusion in your projects. See the [installation instructions](#Installati
| Software | Versions |
|--------------------------------------|-----------------------------------------------------|
| UniFi Network Application/controller | 5.X.X, 6.X.X, 7.X.X, 8.X.X (**8.5.6 is confirmed**) |
| UniFi OS | 3.X, 4.X (**4.1.15 is confirmed**) |
| UniFi Network Application/controller | 5.x.x, 6.x.x, 7.x.x, 8.x.x (**8.6.9 is confirmed**) |
| UniFi OS | 3.x, 4.x (**4.1.9 is confirmed**) |
## Requirements
@@ -22,8 +27,7 @@ easy inclusion in your projects. See the [installation instructions](#Installati
- a server with:
- 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 7.4.27 and cURL 7.60.0 and with PHP 8.3.11 and cURL 7.81.0
- PHP json and PHP cURL modules enabled
- 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 an **account with local access permissions** to access the UniFi Controller API through this class
@@ -32,8 +36,10 @@ easy inclusion in your projects. See the [installation instructions](#Installati
## UniFi OS Support
Support for UniFi OS-based controllers has been added as of version 1.1.47. These devices/services have been verified
to work:
Besides the "software-based" UniFi controllers, this class also supports UniFi OS-based controllers starting from
version **1.1.47**.
These devices/services have been verified to work:
- UniFi Dream Router (UDR)
- UniFi Dream Machine (UDM)
- UniFi Dream Machine Pro (UDM PRO)
@@ -62,40 +68,37 @@ 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
## Upgrading from previous versions
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
When upgrading from a version before **2.0.0**, please:
- change your code to use the new Exceptions that are thrown by the class
- test the client with your code for any breaking changes
- make sure you are using [Composer](#composer) to install the class because the code is no longer held within a single file
## Installation
Use [Composer](#composer), [Git](#git) or simply [Download the Release](#download-the-release) to install the
API client class.
Use [Composer](#composer) or [Git](#git) to install the API client class.
### Composer
The preferred installation method is through [composer](https://getcomposer.org).
Follow these [installation instructions](https://getcomposer.org/doc/00-intro.md) if you don't have composer
The preferred installation method is through [Composer](https://getcomposer.org).
Follow these [installation instructions](https://getcomposer.org/doc/00-intro.md) if you don't have Composer
installed already.
Once composer is installed, simply execute this command from the shell in your project
directory:
Once Composer is installed, execute this command from the shell in your project directory:
```sh
composer require art-of-wifi/unifi-api-client
```
Or manually add the package to your composer.json file:
Or manually add the package to your `composer.json` file:
```javascript
{
"require": {
"art-of-wifi/unifi-api-client": "^1.1"
"art-of-wifi/unifi-api-client": "^2.0"
}
}
```
@@ -109,7 +112,6 @@ Finally, be sure to include the composer autoloader in your code if your framewo
require_once 'vendor/autoload.php';
```
### Git
Execute the following `git` command from the shell in your project directory:
@@ -127,24 +129,9 @@ When git is done cloning, include the file containing the class like so in your
require_once 'path/to/src/Client.php';
```
### Download the Release
If you prefer not to use composer or git,
simply [download the package](https://github.com/Art-of-WiFi/UniFi-API-client/archive/master.zip), unpack the zip
file, then include the file containing the class in your code like so:
```php
/**
* load the class directly instead of using the composer autoloader
*/
require_once 'path/to/src/Client.php';
```
## Example usage
A basic example how to use the class:
A basic example of how to use the class:
```php
/**
@@ -161,21 +148,17 @@ $login = $unifi_connection->login();
$results = $unifi_connection->list_alarms(); // returns a PHP array containing alarm objects
```
Please refer to the `examples/` directory for some more detailed examples which can be used as a starting point for your
own PHP code.
#### IMPORTANT NOTES:
1. In the above example, `$site_id` is the short site "name" (usually 8 characters long) that is visible in the URL when
managing the site in the UniFi Network Controller. For example with this URL:
managing the site in the UniFi Network Controller. For example, with this URL:
`https://<controller IP address or FQDN>:8443/manage/site/jl3z2shm/dashboard`
`jl3z2shm` is the short site "name" and the value to assign to $site_id.
2. The 6th optional parameter that is passed to the constructor in the above example (`true`), enables validation of
the controller's SSL certificate which is otherwise **disabled** by default. It is **highly recommended** to enable
the controller's SSL certificate, which is otherwise **disabled** by default. It is **highly recommended** to enable
this feature in production environments where you have a valid SSL cert installed on the UniFi Controller that is
associated with the FQDN in the `controller_url` parameter. This option was added with API client version 1.1.16.
@@ -186,193 +169,106 @@ own PHP code.
visible for **read-only** administrator accounts.
## Exception handling
The class now throws **Exceptions** for various error conditions instead of using PHP's `trigger_error()` function. This
allows for more granular error handling in your application code.
Here is an example of how to catch these Exceptions:
```php
<?php
/**
* PHP API usage example with Exception handling
*/
use UniFi_API\Exceptions\CurlExtensionNotLoadedException;
use UniFi_API\Exceptions\CurlGeneralErrorException;
use UniFi_API\Exceptions\CurlTimeoutException;
use UniFi_API\Exceptions\InvalidBaseUrlException;
use UniFi_API\Exceptions\InvalidSiteNameException;
use UniFi_API\Exceptions\JsonDecodeException;
use UniFi_API\Exceptions\LoginFailedException;
use UniFi_API\Exceptions\LoginRequiredException;
/**
* load the class using the composer autoloader
*/
require_once 'vendor/autoload.php';
/**
* include the config file (place your credentials etc. there if not already present)
*/
require_once 'config.php';
/**
* initialize the UniFi API connection class, log in to the controller and request the alarms collection
* (this example assumes you have already assigned the correct values to the variables in config.php)
*/
try {
$unifi_connection = new UniFi_API\Client($controller_user, $controller_password, $controller_url, $site_id, $controller_version, true);
$login = $unifi_connection->login();
$results = $unifi_connection->list_alarms(); // returns a PHP array containing alarm objects
} catch (CurlExtensionNotLoadedException $e) {
echo 'CurlExtensionNotLoadedException: ' . $e->getMessage(). PHP_EOL;
} catch (InvalidBaseUrlException $e) {
echo 'InvalidBaseUrlException: ' . $e->getMessage(). PHP_EOL;
} catch (InvalidSiteNameException $e) {
echo 'InvalidSiteNameException: ' . $e->getMessage(). PHP_EOL;
} catch (JsonDecodeException $e) {
echo 'JsonDecodeException: ' . $e->getMessage(). PHP_EOL;
} catch (LoginRequiredException $e) {
echo 'LoginRequiredException: ' . $e->getMessage(). PHP_EOL;
} catch (CurlGeneralErrorException $e) {
echo 'CurlGeneralErrorException: ' . $e->getMessage(). PHP_EOL;
} catch (CurlTimeoutException $e) {
echo 'CurlTimeoutException: ' . $e->getMessage(). PHP_EOL;
} catch (LoginFailedException $e) {
echo 'LoginFailedException: ' . $e->getMessage(). PHP_EOL;
} catch (Exception $e) {
/** catch any other Exceptions that might be thrown */
echo 'General Exception: ' . $e->getMessage(). PHP_EOL;
}
```
Although the PHP DocBlocks for most public methods/functions contain `@throws Exception`, it is recommended to catch
other specific Exceptions that can be thrown by the API Client class to provide more detailed error messages to your
application code.
In most cases, the class will let Exceptions bubble up to the calling code, but in some cases it will catch them and
throw a new Exception with a more specific message.
The `list_alarms.php` example in the `examples/` directory is a good starting point to see how you can implement
Exception handling.
## Functions/methods supported
The class currently supports the following functions/methods to access the UniFi Controller API. This list is sorted
alphabetically. Please refer to the comments in the source code for more details on each of the functions/methods,
The class currently supports a large and growing number of functions/methods to access the UniFi Controller API.
Please refer to the comments/PHP DocBlocks in the source code for more details on each of the functions/methods,
their purpose, and their respective parameters.
- adopt_device()
- advanced_adopt_device()
- archive_alarm()
- assign_existing_admin()
- authorize_guest()
- block_sta()
- cancel_rolling_upgrade()
- check_controller_update()
- check_firmware_update()
- cmd_stat()
- count_alarms()
- create_apgroup()
- create_dynamicdns()
- create_firewallgroup()
- create_hotspotop()
- create_network()
- create_radius_account()
- create_user()
- create_usergroup()
- create_voucher()
- create_wlan()
- custom_api_request()
- delete_apgroup()
- delete_device()
- delete_firewallgroup()
- delete_network()
- delete_radius_account()
- delete_site()
- delete_usergroup()
- delete_wlan()
- disable_ap()
- disable_wlan()
- edit_apgroup()
- edit_client_fixedip()
- edit_client_name()
- edit_firewallgroup()
- edit_usergroup()
- extend_guest_validity()
- forget_sta()
- generate_backup()
- generate_backup_site()
- get_class_version()
- get_cookie()
- get_cookies()
- get_curl_connection_timeout()
- get_curl_http_version()
- get_curl_method()
- get_curl_request_timeout()
- get_curl_request_timeout()
- get_curl_ssl_verify_host()
- get_curl_ssl_verify_peer()
- get_debug()
- get_is_unifi_os()
- get_last_error_message()
- get_last_results_raw()
- get_site()
- invite_admin()
- led_override()
- list_admins()
- list_all_admins()
- list_alarms()
- list_aps()
- list_backups()
- list_clients()
- list_country_codes()
- list_current_channels()
- list_dashboard()
- list_device_name_mappings()
- list_device_states()
- list_devices()
- list_devices_basic()
- list_dynamicdns()
- list_events()
- list_extension()
- list_firewallgroups()
- list_firmware()
- list_guests()
- list_health()
- list_hotspotop()
- list_known_rogueaps()
- list_networkconf()
- list_portconf()
- list_portforward_stats()
- list_portforwarding()
- list_radius_accounts()
- list_radius_profiles()
- list_self()
- list_settings()
- list_sites()
- list_tags()
- list_users()
- list_wlan_groups()
- list_wlanconf()
- locate_ap()
- login()
- logout()
- move_device()
- power_cycle_switch_port()
- reboot_cloudkey()
- rename_ap()
- revoke_admin()
- revoke_voucher()
- set_ap_radiosettings()
- set_ap_wlangroup()
- set_connection_timeout()
- set_cookies()
- set_curl_http_version()
- set_curl_request_timeout()
- set_curl_ssl_verify_host()
- set_curl_ssl_verify_peer()
- set_debug()
- set_device_settings_base()
- set_dynamicdns()
- set_element_adoption()
- set_guestlogin_settings()
- set_guestlogin_settings_base()
- set_ips_settings_base()
- set_is_unifi_os()
- set_locate_ap() (deprecated but still available as alias)
- set_networksettings_base()
- set_radius_account_base()
- set_request_method()
- set_request_timeout()
- set_site()
- set_site_connectivity()
- set_site_country()
- set_site_guest_access()
- set_site_locale()
- set_site_mgmt()
- set_site_name()
- set_site_ntp()
- set_site_snmp()
- set_sta_name()
- set_sta_note()
- set_super_identity_settings_base()
- set_super_mgmt_settings_base()
- set_super_smtp_settings_base()
- set_usergroup()
- set_wlan_mac_filter()
- set_wlansettings()
- set_wlansettings_base()
- site_leds()
- spectrum_scan()
- spectrum_scan_state()
- start_rolling_upgrade()
- stat_5minutes_aps()
- stat_5minutes_gateway()
- stat_5minutes_site()
- stat_5minutes_user()
- stat_allusers()
- stat_auths()
- stat_client()
- stat_daily_aps()
- stat_daily_gateway()
- stat_daily_site()
- stat_daily_user()
- stat_full_status()
- stat_hourly_aps()
- stat_hourly_gateway()
- stat_hourly_site()
- stat_hourly_user()
- stat_ips_events()
- stat_monthly_aps()
- stat_monthly_gateway()
- stat_monthly_site()
- stat_monthly_user()
- stat_payment()
- stat_sessions()
- stat_sites()
- stat_speedtest_results()
- stat_sta_sessions_latest()
- stat_status()
- stat_sysinfo()
- stat_voucher()
- unauthorize_guest()
- unblock_sta()
- unset_locate_ap() (deprecated but still available as alias)
- upgrade_device()
- upgrade_device_external()
If you are using an advanced IDE such as PHPStorm or VS Code, you can use its code completion and other
features to explore the available functions/methods thanks to the extensive PHP DocBlocks throughout the code.
## Looking for version 1.x.x?
With versions 1.x.x of the API client, the code was contained within a single file which can be useful in specific
cases.
This has changed with version 2.0.0 where the code is now split into multiple files and is managed using composer.
If you are looking for the version 1.x.x code, you can tell composer to install that version by using the following
syntax in your `composer.json` file:
```javascript
{
"require": {
"art-of-wifi/unifi-api-client": "^1.1"
}
}
```
Alternatively, you can download the latest 1.x.x code from the [releases page](https://github.com/Art-of-WiFi/UniFi-API-client/releases).
## Need help or have suggestions?
There is still work to be done to add functionality and further improve the usability of
@@ -387,12 +283,6 @@ When encountering issues with the UniFi API using other libraries, cURL or Postm
Please use the [Discussions](https://github.com/Art-of-WiFi/UniFi-API-client/discussions) section instead.
## Contribute
If you would like to contribute code (improvements), please open an issue and include
your code there or else create a pull request.
## Credits
This class is based on the initial work by the following developers:
@@ -402,7 +292,16 @@ This class is based on the initial work by the following developers:
and the API as published by Ubiquiti:
- https://dl.ui.com/unifi/8.0.26/unifi_sh_api
- https://dl.ui.com/unifi/8.6.9/unifi_sh_api
## Contributors
A big thanks to all the contributors who have helped with this project!
[![Contributors](https://img.shields.io/github/contributors/Art-of-WiFi/UniFi-API-client)](https://github.com/Art-of-WiFi/UniFi-API-client/graphs/contributors)
If you would like to contribute to this project, please open an issue and include
your suggestions or code there or else create a pull request.
## Important Disclaimer

View File

@@ -8,7 +8,8 @@
"unifi",
"controller",
"api",
"client"
"client",
"unifi os"
],
"homepage": "https://github.com/Art-of-WiFi/UniFi-API-client",
"license": "MIT",

View File

@@ -3,8 +3,17 @@
* PHP API usage example
*
* contributed by: Art of WiFi
* description: example basic PHP script to pull current alarms from the UniFi controller and output in json format
* description: An example basic PHP script to pull current alarms from the UniFi controller and output in JSON format,
* also demonstrates how to catch exceptions.
*/
use UniFi_API\Exceptions\CurlExtensionNotLoadedException;
use UniFi_API\Exceptions\CurlGeneralErrorException;
use UniFi_API\Exceptions\CurlTimeoutException;
use UniFi_API\Exceptions\InvalidBaseUrlException;
use UniFi_API\Exceptions\InvalidSiteNameException;
use UniFi_API\Exceptions\JsonDecodeException;
use UniFi_API\Exceptions\LoginFailedException;
use UniFi_API\Exceptions\LoginRequiredException;
/**
* using the composer autoloader
@@ -12,8 +21,14 @@
require_once 'vendor/autoload.php';
/**
* include the config file (place your credentials etc. there if not already present)
* see the config.template.php file for an example
* Include the config file (place your credentials etc. there if not already present), see the config.template.php
* file for an example.
*
* @var array $controlleruser
* @var array $controllerpassword
* @var array $controllerurl
* @var array $controllerversion
* @var array $debug
*/
require_once 'config.php';
@@ -25,19 +40,40 @@ $site_id = '<enter your site id here>';
/**
* initialize the UniFi API connection class and log in to the controller and do our thing
*/
$unifi_connection = new UniFi_API\Client(
$controlleruser,
$controllerpassword,
$controllerurl,
$site_id,
$controllerversion
);
try {
$unifi_connection = new UniFi_API\Client(
$controlleruser,
$controllerpassword,
$controllerurl,
$site_id,
$controllerversion
);
$set_debug_mode = $unifi_connection->set_debug($debug);
$loginresults = $unifi_connection->login();
$data = $unifi_connection->list_alarms();
$set_debug_mode = $unifi_connection->set_debug($debug);
$login_results = $unifi_connection->login();
$data = $unifi_connection->list_alarms();
/**
* provide feedback in json format
*/
echo json_encode($data, JSON_PRETTY_PRINT);
/**
* echo the results in JSON format
*/
echo json_encode($data, JSON_PRETTY_PRINT);
} catch (CurlExtensionNotLoadedException $e) {
echo 'CurlExtensionNotLoadedException: ' . $e->getMessage(). PHP_EOL;
} catch (InvalidBaseUrlException $e) {
echo 'InvalidBaseUrlException: ' . $e->getMessage(). PHP_EOL;
} catch (InvalidSiteNameException $e) {
echo 'InvalidSiteNameException: ' . $e->getMessage(). PHP_EOL;
} catch (JsonDecodeException $e) {
echo 'JsonDecodeException: ' . $e->getMessage(). PHP_EOL;
} catch (LoginRequiredException $e) {
echo 'LoginRequiredException: ' . $e->getMessage(). PHP_EOL;
} catch (CurlGeneralErrorException $e) {
echo 'CurlGeneralErrorException: ' . $e->getMessage(). PHP_EOL;
} catch (CurlTimeoutException $e) {
echo 'CurlTimeoutException: ' . $e->getMessage(). PHP_EOL;
} catch (LoginFailedException $e) {
echo 'LoginFailedException: ' . $e->getMessage(). PHP_EOL;
} catch (Exception $e) {
/** catch any other Exceptions that might be thrown */
echo 'General Exception: ' . $e->getMessage(). PHP_EOL;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
<?php
namespace UniFi_API\Exceptions;
use Exception;
class CurlExtensionNotLoadedException extends Exception
{
public function __construct()
{
parent::__construct('The PHP curl extension is not loaded. Please correct this before proceeding!');
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace UniFi_API\Exceptions;
use Exception;
class CurlGeneralErrorException extends Exception
{
/** @var mixed $_http_response_code */
private $_http_response_code;
/** @var mixed $_curl_getinfo_results */
private $_curl_getinfo_results;
public function __construct(string $message, $http_response_code, $_curl_getinfo_results)
{
$this->_http_response_code = $http_response_code;
$this->_curl_getinfo_results = $_curl_getinfo_results;
parent::__construct($message);
}
/**
* Get the HTTP response code.
*
* @return mixed
*/
public function getHttpResponseCode()
{
return $this->_http_response_code;
}
/**
* Get the cURL curl_getinfo results.
*
* @return mixed
*/
public function getCurlGetinfoResults()
{
return $this->_curl_getinfo_results;
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace UniFi_API\Exceptions;
use Exception;
class CurlTimeoutException extends Exception
{
/** @var mixed $_http_response_code */
private $_http_response_code;
/** @var mixed $_curl_getinfo_results */
private $_curl_getinfo_results;
public function __construct(string $message, $http_response_code, $curl_getinfo_results)
{
$this->_http_response_code = $http_response_code;
$this->_curl_getinfo_results = $curl_getinfo_results;
parent::__construct($message);
}
/**
* Get the HTTP response code.
*
* @return mixed
*/
public function getHttpResponseCode()
{
return $this->_http_response_code;
}
/**
* Get the cURL curl_getinfo results.
*
* @return mixed
*/
public function getCurlGetinfoResults()
{
return $this->_curl_getinfo_results;
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace UniFi_API\Exceptions;
use Exception;
class EmailInvalidException extends Exception
{
public function __construct()
{
parent::__construct('Invalid email address provided.');
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace UniFi_API\Exceptions;
use Exception;
class InvalidBaseUrlException extends Exception
{
public function __construct()
{
parent::__construct('The base URL provided is invalid.');
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace UniFi_API\Exceptions;
use Exception;
class InvalidCurlMethodException extends Exception
{
public function __construct()
{
parent::__construct('Invalid cURL method provided.');
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace UniFi_API\Exceptions;
use Exception;
class InvalidSiteNameException extends Exception
{
public function __construct()
{
parent::__construct('Invalid site name provided.');
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace UniFi_API\Exceptions;
use Exception;
class JsonDecodeException extends Exception
{
//
}

View File

@@ -0,0 +1,10 @@
<?php
namespace UniFi_API\Exceptions;
use Exception;
class LoginFailedException extends Exception
{
//
}

View File

@@ -0,0 +1,13 @@
<?php
namespace UniFi_API\Exceptions;
use Exception;
class LoginRequiredException extends Exception
{
public function __construct()
{
parent::__construct('This method requires the API client to be logged in first.');
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace UniFi_API\Exceptions;
use Exception;
class MethodDeprecatedException extends Exception
{
//
}