Skip to content

Commit e60ffb2

Browse files
committed
first take at implementing API client class version 2.0.*
1 parent 170aa92 commit e60ffb2

21 files changed

+1073
-755
lines changed

ajax/fetch_collection.php

Lines changed: 108 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@
1616
use Kint\Renderer\TextRenderer;
1717
use Kint\Renderer\RichRenderer;
1818
use UniFi_API\Client as ApiClient;
19+
use UniFi_API\Exceptions\CurlExtensionNotLoadedException;
20+
use UniFi_API\Exceptions\CurlGeneralErrorException;
21+
use UniFi_API\Exceptions\CurlTimeoutException;
22+
use UniFi_API\Exceptions\InvalidBaseUrlException;
23+
use UniFi_API\Exceptions\InvalidSiteNameException;
24+
use UniFi_API\Exceptions\JsonDecodeException;
25+
use UniFi_API\Exceptions\LoginFailedException;
26+
use UniFi_API\Exceptions\LoginRequiredException;
1927

2028
/**
2129
* Load the configuration file if readable.
@@ -127,101 +135,130 @@
127135
/**
128136
* Create an instance of the Unifi API client class, log in to the controller and pull the requested data.
129137
*/
130-
$unifi_connection = new ApiClient(
131-
trim($controller['user']),
132-
trim($controller['password']),
133-
trim(rtrim($controller['url'], "/")),
134-
$site_id
135-
);
136138

137-
$login_results = $unifi_connection->login();
139+
try {
140+
$unifi_connection = new ApiClient(
141+
trim($controller['user']),
142+
trim($controller['password']),
143+
trim(rtrim($controller['url'], "/")),
144+
$site_id
145+
);
146+
147+
$login_results = $unifi_connection->login();
148+
} catch (CurlExtensionNotLoadedException $e) {
149+
$results['state'] = 'error';
150+
$results['message'] = 'cURL is not available in your PHP installation!';
151+
return;
152+
} catch (CurlGeneralErrorException $e) {
153+
$results['state'] = 'error';
154+
$results['message'] = 'We have encountered a general cURL error! Please check the logs';
155+
return;
156+
} catch (CurlTimeoutException $e) {
157+
$results['state'] = 'error';
158+
$results['message'] = 'UniFi controller connection timeout!';
159+
return;
160+
} catch (InvalidBaseUrlException $e) {
161+
$results['state'] = 'error';
162+
$results['message'] = 'UniFi controller login failure, base URL is invalid!';
163+
return;
164+
} catch (InvalidSiteNameException $e) {
165+
$results['state'] = 'error';
166+
$results['message'] = 'UniFi controller login failure, site name is invalid!';
167+
return;
168+
} catch (LoginFailedException $e) {
169+
$results['state'] = 'error';
170+
$results['message'] = 'UniFi controller login failure, please check your credentials in config/config.php!';
171+
return;
172+
}
173+
174+
/**
175+
* We can safely continue.
176+
*/
177+
$time_1 = microtime(true);
178+
$time_after_login = $time_1 - $time_start;
138179

139180
/**
140-
* Check for login errors.
181+
* We then determine which method is required and which parameters to pass.
182+
* https://stackoverflow.com/questions/1005857/how-to-call-a-function-from-a-string-stored-in-a-variable
141183
*/
142-
if ($login_results === 400) {
184+
try {
185+
if (count($params) === 0) {
186+
$request_results = $unifi_connection->{$method}();
187+
} else {
188+
$request_results = $unifi_connection->{$method}(...$params);
189+
}
190+
} catch (JsonDecodeException $e) {
143191
$results['state'] = 'error';
144-
$results['message'] = 'UniFi controller login failure, please check your credentials in config/config.php!';
145-
} else {
192+
$results['message'] = 'JSON decode error!';
193+
return;
194+
} catch (LoginRequiredException $e) {
195+
$results['state'] = 'error';
196+
$results['message'] = 'Login is required for this endpoint';
197+
return;
198+
}
199+
200+
if (!empty($request_results)) {
146201
/**
147-
* We can safely continue.
202+
* Count the array items and inject $data_array into $results.
148203
*/
149-
$time_1 = microtime(true);
150-
$time_after_login = $time_1 - $time_start;
204+
if (is_array($request_results)) {
205+
$results['count'] = count($request_results);
206+
}
151207

152208
/**
153-
* We then determine which method is required and which parameters to pass.
154-
* https://stackoverflow.com/questions/1005857/how-to-call-a-function-from-a-string-stored-in-a-variable
209+
* For results returned from API v2, the $request_results are an object, and we need to check for the
210+
* 'data' property and count items in that array.
155211
*/
156-
if (count($params) === 0) {
157-
$request_results = $unifi_connection->{$method}();
158-
} else {
159-
$request_results = $unifi_connection->{$method}(...$params);
212+
if (is_object($request_results) && property_exists($request_results, 'data',)) {
213+
$results['count'] = count($request_results->data);
160214
}
161215

162-
if (!empty($request_results)) {
163-
/**
164-
* Count the array items and inject $data_array into $results.
165-
*/
166-
if (is_array($request_results)) {
167-
$results['count'] = count($request_results);
168-
}
216+
if ($debug) {
217+
error_log('DEBUG: ' . $results['count'] . ' objects collected');
218+
}
169219

220+
if ($output_method === 'kint') {
170221
/**
171-
* For results returned from API v2, the $request_results are an object, and we need to check for the
172-
* 'data' property and count items in that array.
222+
* For Kint, we need to return the results in a slightly different manner.
223+
*
224+
* @note using Rich render mode
173225
*/
174-
if(is_object($request_results) && property_exists($request_results, 'data', )) {
175-
$results['count'] = count($request_results->data);
176-
}
177-
178-
if ($debug) {
179-
error_log('DEBUG: ' . $results['count'] . ' objects collected');
180-
}
181-
182-
if ($output_method === 'kint') {
226+
Kint::$display_called_from = false;
227+
RichRenderer::$folder = false;
228+
$results['data'] = @d($request_results);
229+
} else {
230+
if ($output_method === 'kint_plain') {
183231
/**
184-
* For Kint, we need to return the results in a slightly different manner.
185-
*
186-
* @note using Rich render mode
232+
* @note using Plain render mode
187233
*/
188234
Kint::$display_called_from = false;
189235
RichRenderer::$folder = false;
190-
$results['data'] = @d($request_results);
236+
TextRenderer::$decorations = false;
237+
$results['data'] = @s($request_results);
191238
} else {
192-
if ($output_method === 'kint_plain') {
193-
/**
194-
* @note using Plain render mode
195-
*/
196-
Kint::$display_called_from = false;
197-
RichRenderer::$folder = false;
198-
TextRenderer::$decorations = false;
199-
$results['data'] = @s($request_results);
200-
} else {
201-
$results['data'] = $request_results;
202-
}
239+
$results['data'] = $request_results;
203240
}
204241
}
242+
}
205243

206-
/**
207-
* Execute timing of data collection from UniFi controller.
208-
*/
209-
$time_2 = microtime(true);
210-
$time_after_load = $time_2 - $time_start;
244+
/**
245+
* Execute timing of data collection from UniFi controller.
246+
*/
247+
$time_2 = microtime(true);
248+
$time_after_load = $time_2 - $time_start;
211249

212-
/**
213-
* Calculate all the timings/percentages.
214-
*/
215-
$time_end = microtime(true);
216-
$time_total = $time_end - $time_start;
217-
$login_percentage = ($time_after_login / $time_total) * 100;
218-
$load_percentage = (($time_after_load - $time_after_login) / $time_total) * 100;
219-
220-
$results['timings']['login'] = $time_after_login;
221-
$results['timings']['load'] = $time_after_load;
222-
$results['timings']['login_perc'] = $login_percentage;
223-
$results['timings']['load_perc'] = $load_percentage;
224-
}
250+
/**
251+
* Calculate all the timings/percentages.
252+
*/
253+
$time_end = microtime(true);
254+
$time_total = $time_end - $time_start;
255+
$login_percentage = ($time_after_login / $time_total) * 100;
256+
$load_percentage = (($time_after_load - $time_after_login) / $time_total) * 100;
257+
258+
$results['timings']['login'] = $time_after_login;
259+
$results['timings']['load'] = $time_after_load;
260+
$results['timings']['login_perc'] = $login_percentage;
261+
$results['timings']['load_perc'] = $load_percentage;
225262
}
226263
}
227264

ajax/fetch_sites.php

Lines changed: 93 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@
1212
*
1313
* @var string $unknown_string
1414
*/
15+
16+
use UniFi_API\Exceptions\CurlExtensionNotLoadedException;
17+
use UniFi_API\Exceptions\CurlGeneralErrorException;
18+
use UniFi_API\Exceptions\CurlTimeoutException;
19+
use UniFi_API\Exceptions\InvalidBaseUrlException;
20+
use UniFi_API\Exceptions\InvalidSiteNameException;
21+
use UniFi_API\Exceptions\JsonDecodeException;
22+
use UniFi_API\Exceptions\LoginFailedException;
23+
use UniFi_API\Exceptions\LoginRequiredException;
24+
1525
require_once '../common.php';
1626
require_once '../collections.php';
1727

@@ -66,72 +76,99 @@
6676
*/
6777
fclose($fp);
6878

69-
/**
70-
* Create an instance of the Unifi API client class, log in to the controller and pull the requested data.
71-
*/
72-
$unifi_connection = new UniFi_API\Client(
73-
trim($controller['user']),
74-
trim($controller['password']),
75-
trim(rtrim($controller['url'], "/")),
76-
'default'
77-
);
78-
79-
$login_results = $unifi_connection->login();
79+
try {
80+
/**
81+
* Create an instance of the Unifi API client class, log in to the controller and pull the requested data.
82+
*/
83+
$unifi_connection = new UniFi_API\Client(
84+
trim($controller['user']),
85+
trim($controller['password']),
86+
trim(rtrim($controller['url'], "/")),
87+
'default'
88+
);
89+
$login_results = $unifi_connection->login();
90+
} catch (CurlExtensionNotLoadedException $e) {
91+
$results['state'] = 'error';
92+
$results['message'] = 'cURL is not available in your PHP installation!';
93+
return;
94+
} catch (CurlGeneralErrorException $e) {
95+
$results['state'] = 'error';
96+
$results['message'] = 'We have encountered a general cURL error! Please check the logs';
97+
return;
98+
} catch (CurlTimeoutException $e) {
99+
$results['state'] = 'error';
100+
$results['message'] = 'UniFi controller connection timeout!';
101+
return;
102+
} catch (InvalidBaseUrlException $e) {
103+
$results['state'] = 'error';
104+
$results['message'] = 'UniFi controller login failure, base URL is invalid!';
105+
return;
106+
} catch (InvalidSiteNameException $e) {
107+
$results['state'] = 'error';
108+
$results['message'] = 'UniFi controller login failure, site name is invalid!';
109+
return;
110+
} catch (LoginFailedException $e) {
111+
$results['state'] = 'error';
112+
$results['message'] = 'UniFi controller login failure, please check your credentials in config/config.php!';
113+
return;
114+
}
80115

81116
/**
82-
* Check for login errors.
117+
* We can safely continue.
83118
*/
84-
if ($login_results === 400) {
119+
try {
120+
$sites_array = $unifi_connection->list_sites();
121+
} catch (JsonDecodeException $e) {
85122
$results['state'] = 'error';
86-
$results['message'] = 'UniFi controller login failure, please check your credentials in config/config.php!';
87-
} else {
123+
$results['message'] = 'JSON decode error!';
124+
return;
125+
} catch (LoginRequiredException $e) {
126+
$results['state'] = 'error';
127+
$results['message'] = 'Login is required for this endpoint';
128+
return;
129+
}
130+
131+
if (!empty($sites_array)) {
132+
if ($debug) {
133+
error_log('DEBUG: ' . count($sites_array) . ' sites collected');
134+
}
135+
88136
/**
89-
* We can safely continue.
137+
* Store the cookies from the controller for faster reconnecting.
90138
*/
91-
$sites_array = $unifi_connection->list_sites();
139+
$_SESSION['unificookie'] = $unifi_connection->get_cookie();
92140

93-
if (!empty($sites_array)) {
94-
if ($debug) {
95-
error_log('DEBUG: ' . count($sites_array) . ' sites collected');
96-
}
141+
/**
142+
* Loop through the fetched sites.
143+
*/
144+
foreach ($sites_array as $site) {
145+
$results['data'][] = [
146+
'site_id' => $site->name ?? $unknown_string,
147+
'site_full_name' => $site->desc ?? $unknown_string,
148+
];
149+
}
97150

98-
/**
99-
* Store the cookies from the controller for faster reconnecting.
100-
*/
101-
$_SESSION['unificookie'] = $unifi_connection->get_cookie();
102-
103-
/**
104-
* Loop through the fetched sites.
105-
*/
106-
foreach ($sites_array as $site) {
107-
$results['data'][] = [
108-
'site_id' => $site->name ?? $unknown_string,
109-
'site_full_name' => $site->desc ?? $unknown_string,
110-
];
151+
/**
152+
* Sort the site array by full name.
153+
*/
154+
usort($results['data'], function ($a, $b) {
155+
if ($a['site_full_name'] == $b['site_full_name']) {
156+
return 0;
111157
}
112158

113-
/**
114-
* Sort the site array by full name.
115-
*/
116-
usort($results['data'], function ($a, $b) {
117-
if ($a['site_full_name'] == $b['site_full_name']) {
118-
return 0;
119-
}
120-
121-
return ($a['site_full_name'] < $b['site_full_name']) ? -1 : 1;
122-
});
123-
124-
/**
125-
* Get the first site from the $results array, just to be sure we use a valid site.
126-
*/
127-
$switch_site = $unifi_connection->set_site(($results['data'][0]['site_id']));
128-
$site_info = $unifi_connection->stat_sysinfo();
129-
130-
if (!empty($site_info) && isset($site_info[0]->version)) {
131-
$_SESSION['controller']['detected_version'] = $site_info[0]->version;
132-
} else {
133-
$_SESSION['controller']['detected_version'] = 'undetected';
134-
}
159+
return ($a['site_full_name'] < $b['site_full_name']) ? -1 : 1;
160+
});
161+
162+
/**
163+
* Get the first site from the $results array, just to be sure we use a valid site.
164+
*/
165+
$switch_site = $unifi_connection->set_site(($results['data'][0]['site_id']));
166+
$site_info = $unifi_connection->stat_sysinfo();
167+
168+
if (!empty($site_info) && isset($site_info[0]->version)) {
169+
$_SESSION['controller']['detected_version'] = $site_info[0]->version;
170+
} else {
171+
$_SESSION['controller']['detected_version'] = 'undetected';
135172
}
136173
}
137174
}

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"require": {
33
"twig/twig": ">=2.16.1",
44
"kint-php/kint": "3.*",
5-
"art-of-wifi/unifi-api-client": "^1.1",
5+
"art-of-wifi/unifi-api-client": "^2.0.0",
66
"php": ">=7.4.0",
77
"ext-curl": "*",
88
"ext-json": "*"

0 commit comments

Comments
 (0)