-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathunifi-client-alias-sync.php
799 lines (681 loc) · 21.8 KB
/
unifi-client-alias-sync.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
<?php
namespace UniFi_Client_Alias_Sync;
/**
* A PHP script to synchronize client aliases between all sites managed by a UniFi Controller.
*
* See README.md for usage instructions.
*
* Copyright (c) 2018 by Scott Reilly (aka coffee2code)
*
* @package UniFi_Client_Alias_Sync
* @author Scott Reilly
* @version 1.0
*/
// UniFi API client library.
require_once 'vendor/unifi-api-client.php';
/**
* Class for syncing client aliases across a UniFi controllers sites.
*/
class Syncer {
/**
* Full path to config file.
*
* @var string
*/
const CONFIG_FILE = __DIR__ . DIRECTORY_SEPARATOR . 'config.php';
/**
* Required configuration options and their descriptions.
*
* @var array
*/
const REQUIRED_CONFIG = [
'UNIFI_ALIAS_SYNC_CONTROLLER' => 'Domain (or fully qualified URL) of the UniFi controller.',
'UNIFI_ALIAS_SYNC_USER' => 'Username of admin user.',
'UNIFI_ALIAS_SYNC_PASSWORD' => 'Password for admin user.',
];
/**
* Optional configuration options and their default values.
*
* @var array
*/
const OPTIONAL_CONFIG = [
'UNIFI_ALIAS_SYNC_PORT' => 8443,
'UNIFI_ALIAS_SYNC_VERIFY_SSL' => true,
'UNIFI_ALIAS_SYNC_DRY_RUN' => true,
'UNIFI_ALIAS_SYNC_DEBUG' => false,
'UNIFI_ALIAS_SYNC_ALIASES' => [],
'UNIFI_ALIAS_SYNC_ALLOW_OVERWRITES' => false,
'UNIFI_ALIAS_SYNC_EXCLUDE_SITES' => [],
'UNIFI_ALIAS_SYNC_EXCLUDE_CLIENTS' => [],
'UNIFI_ALIAS_SYNC_PRIORITIZED_SITES' => [],
// Not for general use.
'UNIFI_ALIAS_SYNC_TESTING' => false,
];
/**
* The UniFi Controller client object.
*
* @var array
* @access private
*/
private static $unifi_connection;
/**
* Memoized storage for sites.
*
* @var array
* @access protected
*/
protected static $sites;
/**
* Memoized storage for clients per site.
*
* @var array
* @access protected
*/
protected static $clients;
/**
* Memoized storage for client aliases by site.
*
* @var array
* @access protected
*/
protected static $client_aliases;
/**
* Memoized storage for configuration settings.
*
* @var array
* @access protected
*/
protected static $config = [];
/**
* The singleton instantiation of the class.
*
* @access protected
* @var Syncer
*/
protected static $instance;
/**
* Returns the singleton instance of this class, creating one if necessary.
*
* @access public
*
* @return Syncer
*/
public static function get_instance() {
if ( ! self::$instance ) {
self::$instance = new static();
}
return self::$instance;
}
/**
* Syncs client aliases across a controller's sites.
*
* @access public
*/
public function sync() {
try {
// Perform initialization.
$this->init();
// Get all of the sites on the controller.
$sites = $this->get_sites();
// Exceptions are made if aliases are defined via config.
$has_config_aliases = (bool) count( $this->get_config( 'UNIFI_ALIAS_SYNC_ALIASES' ) );
// Bail if there are less than two sites since that is the minimum needed in order to be able to sync client aliases across sites.
switch ( count( $sites ) ) {
case 0:
$this->bail( "Error: No sites found." );
case 1:
// Bail unless there are aliases defined via config.
if ( ! $has_config_aliases ) {
$this->bail( "Notice: Only one site found so there is no need to sync aliases across any other sites." );
}
}
$this->status( 'Sites found: ' . count( $sites ) );
// Report on client aliases defined via config.
if ( $has_config_aliases ) {
$this->status( "\tUNIFI_ALIAS_SYNC_ALIASES has " . count( $this->get_config( 'UNIFI_ALIAS_SYNC_ALIASES' ) ) . ' client aliases defined.' );
foreach ( $this->get_config( 'UNIFI_ALIAS_SYNC_ALIASES' ) as $mac => $alias ) {
$this->status( "\t\t'{$mac}' => '{$alias}'" );
}
}
// Get a list of aliased clients per site.
$client_aliases = $this->get_aliased_clients();
// Bail if there are no aliased clients on any site and no aliases defined
// via config since there is nothing to sync.
if ( ! $client_aliases && ! $has_config_aliases ) {
$this->bail( "Notice: There are no clients with an alias on any site." );
}
// Sync client aliases across sites.
$this->sync_aliases();
$this->status( 'Done.' );
} catch ( \Exception $e ) {
// Do nothing; error message has already been displayed and script is ending.
} // end try/catch
}
/**
* Performs initialization checks and actions.
*
* @access protected
*/
protected function init() {
$this->verify_environment();
if ( ! $this->is_testing() ) {
require self::CONFIG_FILE;
}
$this->verify_config();
$this->status( 'Environment and config file have been verified.' );
if ( $this->get_config( 'UNIFI_ALIAS_SYNC_DRY_RUN' ) ) {
$this->status( "UNIFI_ALIAS_SYNC_DRY_RUN mode enabled; aliases won't actually get synchronized." );
}
// Check for controller URL.
$controller_url = $this->get_controller_url();
if ( ! $this->is_testing() ) {
self::$unifi_connection = new \UniFi_API\Client(
$this->get_config( 'UNIFI_ALIAS_SYNC_USER' ),
$this->get_config( 'UNIFI_ALIAS_SYNC_PASSWORD' ),
$controller_url,
'default',
'',
$this->get_config( 'UNIFI_ALIAS_SYNC_VERIFY_SSL' )
);
if ( $this->is_debug() ) {
self::$unifi_connection->set_debug( true );
}
self::$unifi_connection->login();
}
}
/**
* Returns the fully qualified URL for the UniFi controller.
*
* @access protected
*
* @return string
*/
protected function get_controller_url() {
$controller = rtrim( $this->get_config( 'UNIFI_ALIAS_SYNC_CONTROLLER' ), '/' );
// If protocol was omitted, add it.
if ( 0 !== strpos( $controller, 'https://' ) ) {
$controller = 'https://' . $controller;
}
// If controller URL includes port number, that takes precedence over
// UNIFI_ALIAS_SYNC_PORT.
if ( preg_match( '~(.+):([0-9]+)$~', $controller, $matches ) ) {
$controller = $matches[1];
$port = $matches[2];
} else {
$port = $this->get_config( 'UNIFI_ALIAS_SYNC_PORT' );
}
return $controller . ':' . $port;
}
/**
* Determines if debug mode is enabled.
*
* @access protected
*
* @return bool True if debug is enabled, false otherwise.
*/
protected function is_debug() {
return (bool) $this->get_config( 'UNIFI_ALIAS_SYNC_DEBUG' );
}
/**
* Determines if testing mode is enabled.
*
* @access protected
*
* @return bool True if testing is enabled, false otherwise.
*/
protected function is_testing() {
return (bool) $this->get_config( 'UNIFI_ALIAS_SYNC_TESTING' );
}
/**
* Verifies that the running environment is sufficient for the script to run
* and terminates the script with an error message if not.
*
* Checks that:
* - The config file exists
* - The PHP directive 'allow_url_fopen' is enabled.
*
* @access protected
*/
protected function verify_environment() {
// Bail if the config file doesn't exist (unless unit testing).
if ( ! $this->is_testing() && ! file_exists( self::CONFIG_FILE ) ) {
$this->bail( "Error: Unable to locate config file: {self::CONFIG_FILE}\nCopy config-sample.php to that filename and customize." );
}
// Bail if 'allow_url_fopen' is not enabled.
if ( ! ini_get( 'allow_url_fopen' ) ) {
$this->bail( "Error: The PHP directive 'allow_url_fopen' is not enabled on this system." );
}
}
/**
* Verifies that required constants are defined in config file and that
* optional constants get defined with default values if they aren't
* defined.
*
* @access protected
*/
protected function verify_config() {
// Flag for determining if an error was encountered.
$bail = false;
// Check that required constants are defined. Don't bail immediately though,
// so multiple missing constants can be reported to user at once.
foreach ( self::REQUIRED_CONFIG as $constant => $description ) {
$value = $this->get_config( $constant );
// Required settings cannot be null or an empty string.
if ( is_null( $value ) || '' === $value ) {
$this->status( "Error: Required constant {$constant} was not defined: {$description}" );
$bail = true;
}
}
// Check that aliases are defined properly.
$aliases = $this->get_config( 'UNIFI_ALIAS_SYNC_ALIASES' );
if ( ! is_null( $aliases ) ) {
if ( ! is_array( $aliases ) ) {
$this->status( "Error: Invalid format for UNIFI_ALIAS_SYNC_ALIASES: {$aliases}" );
$bail = true;
} else {
foreach ( $aliases as $mac => $alias ) {
// Check MAC address.
if ( ! preg_match( '/^(?:[[:xdigit:]]{2}([-:]))(?:[[:xdigit:]]{2}\1){4}[[:xdigit:]]{2}$/', $mac ) ) {
$this->status( "Error: Invalid MAC address supplied in UNIFI_ALIAS_SYNC_ALIASES: {$mac}" );
$bail = true;
}
}
}
}
// Check that UNIFI_ALIAS_SYNC_PORT, if present, is a non-zero integer.
$port = $this->get_config( 'UNIFI_ALIAS_SYNC_PORT' );
if ( ! is_null( $port ) && ( ! is_numeric( $port ) || ! $port ) ) {
$this->status( "Error: Invalid format for UNIFI_ALIAS_SYNC_PORT (must be integer): {$port}" );
$bail = true;
}
// Check that UNIFI_ALIAS_SYNC_ALLOW_OVERWRITES, if present, is a boolean.
$allow_overwrites = $this->get_config( 'UNIFI_ALIAS_SYNC_ALLOW_OVERWRITES' );
if ( ! is_null( $allow_overwrites ) && ! is_bool( $allow_overwrites ) ) {
$this->status( "Error: Invalid format for UNIFI_ALIAS_SYNC_ALLOW_OVERWRITES (must be boolean): {$allow_overwrites}" );
$bail = true;
}
// Check that array settings, if present, are arrays.
$arrays = [ 'UNIFI_ALIAS_SYNC_EXCLUDE_CLIENTS', 'UNIFI_ALIAS_SYNC_EXCLUDE_SITES', 'UNIFI_ALIAS_SYNC_PRIORITIZED_SITES' ];
foreach ( $arrays as $array ) {
$value = $this->get_config( $array );
if ( ! is_null( $value ) && ! is_array( $value ) ) {
$this->status( "Error: Invalid format for {$array} (must be array): {$value}" );
$bail = true;
}
}
// Truly bail if an error was encountered.
if ( $bail ) {
$this->bail( 'Terminating script for invalid config file.' );
}
}
/**
* Returns list of sites for the controller.
*
* @access protected
*
* @return array Associative array of sites with site names as keys and site
* objects as values, ordered in descending order by priority.
*/
protected function get_sites() {
if ( self::$sites ) {
$sites = self::$sites;
} elseif ( $this->is_testing() ) {
$sites = [];
} else {
$sites = [];
$sites_resp = self::$unifi_connection->list_sites();
foreach ( (array) $sites_resp as $site ) {
if ( ! empty( $site->name ) ) {
$sites[ $site->name ] = $site;
}
}
self::$sites = $sites;
}
// Exclude any excluded sites.
$excluded_sites = $this->get_config( 'UNIFI_ALIAS_SYNC_EXCLUDE_SITES' );
if ( $excluded_sites ) {
foreach ( $excluded_sites as $site ) {
unset( $sites[ $site ] );
}
}
return $this->prioritize_sites( $sites );
}
/**
* Prioritizes a list of sites by precendence.
*
* @access protected
*
* @param array $sites Associative array of sites with site names as keys and
* site objects as values.
* @return array
*/
protected function prioritize_sites( $sites ) {
// Get explicitly prioritized sites.
$priority_sites = [];
foreach ( $this->get_config( 'UNIFI_ALIAS_SYNC_PRIORITIZED_SITES' ) as $site ) {
if ( isset( $sites[ $site ] ) ) {
$priority_sites[ $site ] = $sites[ $site ];
// Remove priority site from regular consideration.
unset( $sites[ $site ] );
}
}
// The site named 'default', if present, should take precedence.
$default_site = $sites[ 'default' ] ?? '';
unset( $sites['default'] );
// Sort remaining sites alphabetically by site name.
ksort( $sites );
// Give precedence to default site over alphabetically prioritized sites.
if ( $default_site ) {
$sites = array_merge( [ 'default' => $default_site ], $sites );
}
// Give overall precedence to explicitly prioritized sites.
if ( $priority_sites ) {
$sites = array_merge( $priority_sites, $sites );
}
return $sites;
}
/**
* Returns the clients for a given site.
*
* @access protected
*
* @param string $site_name The name of the site.
* @return array Array of the site's clients.
*/
protected function get_clients( $site_name ) {
// If not already memoized, make the request for the site's clients.
if ( ! empty( self::$clients[ $site_name ] ) ) {
$clients = self::$clients[ $site_name ];
} elseif ( $this->is_testing() ) {
$clients = [];
} else {
self::$unifi_connection->set_site( $site_name );
$clients = self::$unifi_connection->stat_allusers();
// Memoize full list of clients.
self::$clients[ $site_name ] = $clients;
}
// Exclude any excluded clients.
$clients = array_filter( $clients, function( $client ) {
return ! in_array( $client->mac, $this->get_config( 'UNIFI_ALIAS_SYNC_EXCLUDE_CLIENTS' ) );
} );
return $clients;
}
/**
* Returns the aliased clients for each site.
*
* @access protected
*
* @return array Associative array of site names and their respective arrays
* of aliased clients.
*/
protected function get_aliased_clients() {
// Return value if memoized.
if ( self::$client_aliases ) {
return self::$client_aliases;
}
$client_aliases = [];
$sites = $this->get_sites();
// For each site, get a list of all clients with an alias.
foreach ( $sites as $site ) {
$clients = $this->get_clients( $site->name );
// The client alias, if defined, is stored as "name".
$aliased_clients = array_filter( $clients, function( $client ) {
return ! empty( $client->name );
} );
if ( $aliased_clients ) {
$client_aliases[ $site->name ] = $aliased_clients;
}
$this->status( sprintf(
"\tSite %s has %d clients, %d of which are aliased.",
$site->name,
count( $clients ),
count( $aliased_clients )
) );
foreach ( $aliased_clients as $ac ) {
$this->status( "\t\t\"{$ac->mac}\" => \"{$ac->name}\"" );
}
}
return self::$client_aliases = $client_aliases;
}
/**
* Returns the client aliases applicable to the given site.
*
* @access protected
*
* @param string $site_name Name of the site.
* @return array
*/
protected function get_client_aliases_for_site( $site_name ) {
$macs = [];
// Bail if unknown site name.
if ( ! array_key_exists( $site_name, $this->get_sites() ) ) {
return $macs;
}
// Get a list of aliased clients per site.
$client_aliases = $this->get_aliased_clients();
// Get an associative array of site names and their aliases (as arrays).
$site_names = array_keys( $client_aliases );
$site_names_with_aliases = [];
foreach ( $client_aliases as $alias_site_name => $aliases ) {
$a = [];
foreach ( $aliases as $alias ) {
$a[ $alias->mac ] = $alias->name;
}
$site_names_with_aliases[ $alias_site_name ] = $a;
}
// Position relative to other sites for the current site.
$site_pos = array_search( $site_name, $site_names );
// Get a list of all aliases that apply to the site.
foreach ( $client_aliases as $alias_site_name => $aliases ) {
// Skip site's own list of aliases.
if ( $alias_site_name === $site_name ) {
continue;
}
// Store the MAC address and alias mapping.
foreach ( $aliases as $alias ) {
// Only accept alias for aliased client from higher priority sites.
if ( $site_pos > array_search( $alias_site_name, $site_names ) ) {
// ...but only if an alias hasn't already been found.
if ( empty( $macs[ $alias->mac ] ) ) {
$macs[ $alias->mac ] = $alias->name;
}
}
// Else if it the site already has an aliases for this client, do nothing.
elseif ( ! empty( $site_names_with_aliases[ $site_name ][ $alias->mac ] ) ) {
// Do nothing
}
// Else if an alias hasn't already been found.
elseif ( empty( $macs[ $alias->mac ] ) ) {
$macs[ $alias->mac ] = $alias->name;
}
}
}
// Aliases defined via constant take precedence and apply to all sites.
foreach ( $this->get_config( 'UNIFI_ALIAS_SYNC_ALIASES' ) as $mac => $alias ) {
$macs[ $mac ] = $alias;
}
return $macs;
}
/**
* Syncs client aliases across all sites.
*
* @access protected
*/
protected function sync_aliases() {
// Get sites.
$sites = $this->get_sites();
// Report on excluded sites.
$excluded_sites = $this->get_config( 'UNIFI_ALIAS_SYNC_EXCLUDE_SITES' );
if ( $excluded_sites ) {
foreach ( $excluded_sites as $site ) {
$this->status( "Excluding site {$site}" );
}
}
// Iterate through all sites.
foreach ( $sites as $site ) {
$this->status( "About to assign client aliases to site {$site->name}..." );
// The number of clients on the site that were assigned an alias.
$assigned_alias = 0;
// Get MAC address to alias mappings.
$macs = $this->get_client_aliases_for_site( $site->name );
// Get clients for the site being iterated.
$clients = $this->get_clients( $site->name );
foreach ( $clients as $client ) {
// Set the current site.
if ( self::$unifi_connection ) {
self::$unifi_connection->set_site( $site->name );
}
// If there is an alias for the client
if ( isset( $macs[ $client->mac ] ) ) {
// If client already has the given alias.
if ( ! empty( $client->name ) && $client->name === $macs[ $client->mac ] ) {
$this->status( "\tClient {$client->mac} already has the alias \"{$client->name}\"." );
}
// Elseif if the client doesn't already have an alias or its name can be overwritten
elseif ( empty( $client->name ) || $this->get_config( 'UNIFI_ALIAS_SYNC_ALLOW_OVERWRITES' ) ) {
$assigned_alias++;
// Actually set the client alias unless doing a dry run.
if ( $this->get_config( 'UNIFI_ALIAS_SYNC_DRY_RUN' ) ) {
if ( empty( $client->name ) ) {
$this->status( "\tWould have set alias for {$client->mac} to \"{$macs[ $client->mac ]}\"." );
} else {
$this->status( sprintf(
"\tWould have set alias for %s to \"%s\" (overwriting existing alias of \"%s\").",
$client->mac,
$macs[ $client->mac ],
$client->name
) );
}
} else {
if ( $this->is_testing() ) {
// When testing, pretend setting client alias is successful.
$result = true;
} elseif ( self::$unifi_connection ) {
self::$unifi_connection->set_sta_name( $client->_id, $macs[ $client->mac ] );
}
if ( ! $result ) {
$this->status( sprintf(
"\tWarning: Unable to set alias for %s to \"%s\" (%s).",
$client->mac,
$macs[ $client->mac ],
self::$unifi_connection ? self::$unifi_connection->get_last_error_message() : 'No connection to controller'
) );
$assigned_alias--;
} elseif ( $this->get_config( 'UNIFI_ALIAS_SYNC_ALLOW_OVERWRITES' ) ) {
$this->status( sprintf(
"\tSetting alias for %s to \"%s\" (overwriting existing alias of \"%s\").",
$client->mac,
$macs[ $client->mac ],
$client->name
) );
} else {
$this->status( "\tSetting alias for {$client->mac} to \"{$macs[ $client->mac ]}\"." );
}
}
// Else an alias cannot be overridden.
} else {
$this->status( sprintf(
"\tClient %s already aliased as \"%s\" (thus not getting aliased as \"%s\").",
$client->mac,
$client->name,
$macs[ $client->mac ]
) );
}
}
}
if ( $assigned_alias ) {
$this->status( "\tClients assigned an alias: {$assigned_alias}." );
} else {
$this->status( "\tNo clients assigned an alias." );
}
}
}
/**
* Outputs a status message.
*
* Auto-appends a newline to the message.
*
* @access protected
*
* @param string $message The message to output.
*/
protected function status( $message ) {
if ( ! $this->get_config( 'UNIFI_ALIAS_SYNC_DISABLE_STATUS' ) ) {
echo $message . "\n";
}
return $message;
}
/**
* Outputs a message and throws an exception.
*
* @access protected
*
* @param string $message The message to output. No need to append newline.
* Default is ''.
*/
protected function bail( $message = '' ) {
// Terminate the UniFi controller connection.
if ( self::$unifi_connection ) {
self::$unifi_connection->logout();
}
// Append a newline if a message was supplied.
if ( $message ) {
$this->status( $message );
}
throw new \Exception( $message );
}
/**
* Returns the value of a config option.
*
* If the config option wasn't explicitly defined, return the default value if
* that has been defined.
*
* @access protected
*
* @param string @config_name Name of the config option.
* @return mixed
*/
public function get_config( $config_name ) {
// Return memoized value, if already set.
if ( isset( self::$config[ $config_name ] ) ) {
return self::$config[ $config_name ];
}
$value = defined( $config_name ) ? constant( $config_name ) : null;
if ( is_null( $value ) ) {
$value = self::OPTIONAL_CONFIG[ $config_name ] ?? null;
}
return $this->set_config( $config_name, $value );
}
/**
* Sets the value of a config option.
*
* @access protected
*
* @param string $config_name Name of the config option.
* @param mixed $value Value for the config option.
* @return mixed The value for the config option.
*/
public function set_config( $config_name, $value ) {
return self::$config[ $config_name ] = $value;
}
/**
* Clears the value for a setting (or all settings if a specific one wasn't
* specified).
*
* @access public
*
* @param string $config The name of the setting to clear. If not provided or
* an empty string, then all settings will be cleared.
*/
public function clear_config( $config = '' ) {
if ( $config ) {
unset( self::$config[ $config ] );
} else {
self::$config = [];
}
}
}
// Immediately invoke the script when executed from the command line.
if ( isset( $argv ) && $argv[0] === basename( __FILE__ ) ) {
Syncer::get_instance()->sync();
}