Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
37.50% |
3 / 8 |
CRAP | |
50.00% |
15 / 30 |
| APIManager | |
0.00% |
0 / 1 |
|
37.50% |
3 / 8 |
53.12 | |
50.00% |
15 / 30 |
| __construct | |
0.00% |
0 / 1 |
2.03 | |
80.00% |
4 / 5 |
|||
| getInstance | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
| runAutoUpdate | |
0.00% |
0 / 1 |
13.15 | |
41.67% |
5 / 12 |
|||
| loadAPIConfig | |
100.00% |
1 / 1 |
2 | |
100.00% |
2 / 2 |
|||
| getEndpointsFromRegistry | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 3 |
|||
| updateEndpointsRegistry | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| updateEndpointData | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| getEndpointData | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| 1 | <?php |
| 2 | |
| 3 | namespace CeculaSyncApiClient; |
| 4 | |
| 5 | use Requests; |
| 6 | |
| 7 | class APIManager |
| 8 | { |
| 9 | private static APIManager $obj; |
| 10 | public string $endpointData; |
| 11 | private static string $endpointsRegister = "endpoints.json"; |
| 12 | |
| 13 | |
| 14 | private function __construct() |
| 15 | { |
| 16 | // Load Configuration |
| 17 | $this->loadAPIConfig(); |
| 18 | |
| 19 | // Check when last the registry was updated. |
| 20 | // If registry file has not been updated in the last 24 hours update the file |
| 21 | if (!file_exists(__DIR__."/../".self::$endpointsRegister)) { |
| 22 | self::updateEndpointsRegistry($this->endpointData); |
| 23 | } else { |
| 24 | // Auto Update Register |
| 25 | $this->runAutoUpdate(); |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | /** |
| 30 | * @return APIManager |
| 31 | */ |
| 32 | public static function getInstance(): APIManager |
| 33 | { |
| 34 | if (!isset(self::$obj)) { |
| 35 | self::$obj = new APIManager(); |
| 36 | } |
| 37 | return self::$obj; |
| 38 | } |
| 39 | |
| 40 | |
| 41 | /** |
| 42 | * Run Auto-Update |
| 43 | * This method is invoked on class load to check for updates to API and effect the changes on client. |
| 44 | * |
| 45 | * @return void |
| 46 | */ |
| 47 | private function runAutoUpdate(): void |
| 48 | { |
| 49 | $localData = json_decode($this->endpointData); |
| 50 | |
| 51 | // Disable last update check if last check time is not registered |
| 52 | if (empty($localData->lastUpdateCheck) || !is_numeric($localData->lastUpdateCheck)) { |
| 53 | $localData->lastUpdateCheck = time() - (10 + $localData->updateInterval); |
| 54 | } |
| 55 | |
| 56 | if ((time() - filemtime(__DIR__."/../".self::$endpointsRegister) > $localData->updateInterval) && (time() - $localData->lastUpdateCheck > $localData->updateInterval)) { |
| 57 | $remoteDataString = $this->getEndpointsFromRegistry(); |
| 58 | $remoteData = json_decode($remoteDataString); |
| 59 | if ($localData->version == $remoteData->version) { |
| 60 | $localData->lastUpdateCheck = time(); |
| 61 | self::updateEndpointsRegistry($this->endpointData); |
| 62 | } else { |
| 63 | self::updateEndpointsRegistry($remoteDataString); |
| 64 | $this->updateEndpointData($remoteDataString); |
| 65 | } |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | /** |
| 70 | * Load API Configuration |
| 71 | * This method checks if API Configuration file exists on client. If file is not found, it reads configuration |
| 72 | * from the API Server. |
| 73 | * |
| 74 | * @return void |
| 75 | */ |
| 76 | private function loadAPIConfig(): void |
| 77 | { |
| 78 | // Load endpoints from the remote register if the local version is not found. |
| 79 | $this->endpointData = file_exists(__DIR__."/../".self::$endpointsRegister) ? file_get_contents(__DIR__."/../".self::$endpointsRegister) : $this->getEndpointsFromRegistry(); |
| 80 | } |
| 81 | |
| 82 | |
| 83 | /** |
| 84 | * Get Endpoints From Registry |
| 85 | * This method reads endpoints from the API server |
| 86 | * |
| 87 | * @return string |
| 88 | */ |
| 89 | private function getEndpointsFromRegistry(): string |
| 90 | { |
| 91 | $endpointData = !is_null($this->endpointData) ? json_decode($this->endpointData) : json_decode(""); |
| 92 | $serviceConfig = Requests::get($endpointData->serviceAPIs ?? "https://cecula.com/sync/api/endpoints.json"); |
| 93 | return $serviceConfig->body; |
| 94 | } |
| 95 | |
| 96 | |
| 97 | /** |
| 98 | * Update Endpoint Registry |
| 99 | * This method is used to update the local endpoint registry with values from the remote server. |
| 100 | * |
| 101 | * @param string $newData A JSON string of the API endpoints |
| 102 | * @return void |
| 103 | */ |
| 104 | private static function updateEndpointsRegistry(string $newData): void |
| 105 | { |
| 106 | file_put_contents(__DIR__."/../".self::$endpointsRegister, $newData); |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Update Endpoint Data |
| 111 | * A setter for loading the endpoints into memory. |
| 112 | * |
| 113 | * @param string $data A JSON string of the API endpoints |
| 114 | * @return void |
| 115 | */ |
| 116 | public function updateEndpointData(string $data): void |
| 117 | { |
| 118 | $this->endpointData = $data; |
| 119 | } |
| 120 | |
| 121 | |
| 122 | /** |
| 123 | * Get Endpoint Data |
| 124 | * A getter method for loading the API endpoints |
| 125 | * |
| 126 | * @return string |
| 127 | */ |
| 128 | public function getEndpointData(): string |
| 129 | { |
| 130 | return $this->endpointData; |
| 131 | } |
| 132 | } |