3 && is_array($settingValue) == true) { foreach ($settingValue as $val) { $temp .= "'" . encode_single_quotes($val) . "',"; } $temp = substr_replace($temp, "", -1); // remove last comma ',' } $temp = '['.$temp.']'; // wrap brackets $txt .= $setKey . "=" . $temp . "\n"; } else { $txt .= $setKey . "='⭕Not handled⭕'\n"; } } } } $txt = $txt."\n\n"; $txt = $txt."#-------------------IMPORTANT INFO-------------------#\n"; $txt = $txt."# This file is ingested by a python script, so if #\n"; $txt = $txt."# modified it needs to use python syntax #\n"; $txt = $txt."#-------------------IMPORTANT INFO-------------------#\n"; // open new file and write the new configuration // Backup the original file if (file_exists($fullConfPath)) { copy($fullConfPath, $fullConfPath . ".bak"); } // Detect whether the frontend needs to block-wait for backend reload $requiresReloadWait = getReloadWaitRequired($decodedSettings); // Open the file for writing without changing permissions $file = fopen($fullConfPath, "w") or die("Unable to open file!"); fwrite($file, $txt); fclose($file); echo json_encode(['success' => true, 'requiresReloadWait' => $requiresReloadWait]); } // ------------------------------------------------------------------------------------------- // Determines if the frontend must wait (block) for the backend to finish reloading after a // settings save. Blocking is required when LOADED_PLUGINS changes or UI_WAIT_FOR_SETTINGS // is explicitly enabled. Defaults to true (safe) on any parsing error. function getReloadWaitRequired($decodedSettings) { $newLoadedPlugins = null; $uiWaitForSettings = false; foreach ($decodedSettings as $setting) { if ($setting[1] === 'LOADED_PLUGINS') { $newLoadedPlugins = $setting[3]; } if ($setting[1] === 'UI_WAIT_FOR_SETTINGS') { $uiWaitForSettings = ($setting[3] === true || $setting[3] === 1 || strtolower((string)$setting[3]) === 'true'); } } if ($uiWaitForSettings) { return true; } $oldLoadedPlugins = getSettingValue('LOADED_PLUGINS'); // If the old value couldn't be read, default to blocking (safe). if (strpos((string)$oldLoadedPlugins, 'Could not') !== false) { return true; } return normalizePluginList($oldLoadedPlugins) !== normalizePluginList($newLoadedPlugins); } // ------------------------------------------------------------------------------------------- // Normalise a plugin list value (PHP array, JSON array, or Python-style list) to a sorted // JSON string for reliable equality comparison. function normalizePluginList($value) { if ($value === null || $value === '') { return '[]'; } if (is_array($value)) { $arr = $value; } else { $arr = json_decode($value, true); if (!is_array($arr)) { // Handle Python-style single-quoted lists: ['A','B'] $jsonStr = str_replace("'", '"', (string)$value); $arr = json_decode($jsonStr, true); } if (!is_array($arr)) { return trim((string)$value); } } sort($arr); return json_encode($arr); } // ------------------------------------------------------------------------------------------- // 🔺----- API ENDPOINTS SUPERSEDED -----🔺 // check server/api_server/api_server_start.py for equivalents // equivalent: /settings/ // 🔺----- API ENDPOINTS SUPERSEDED -----🔺 function getSettingValue($setKey) { // Define the JSON endpoint URL $apiRoot = rtrim(getenv('NETALERTX_API') ?: '/tmp/api', '/'); $url = $apiRoot . '/table_settings.json'; // Fetch the JSON data $json = file_get_contents($url); // Check if the JSON data was successfully fetched if ($json === false) { return 'Could not get json data'; } // Decode the JSON data $data = json_decode($json, true); // Check if the JSON decoding was successful if (json_last_error() !== JSON_ERROR_NONE) { return 'Could not decode json data'; } // Search for the setting by setKey foreach ($data['data'] as $setting) { if ($setting['setKey'] === $setKey) { return $setting['setValue']; } } // Return false if the setting was not found return 'Could not find setting '.$setKey; } // ------------------------------------------------------------------------------------------- function encode_single_quotes ($val) { $result = str_replace ('\'','{s-quote}',$val); return $result; } // ------------------------------------------------------------------------------------------- // Helper function to send notifications via the backend API endpoint // ------------------------------------------------------------------------------------------- function displayInAppNoti($message, $level = 'error') { try { $apiBase = getSettingValue('BACKEND_API_URL') ?: 'http://localhost:20212'; $apiToken = getSettingValue('API_TOKEN') ?: ''; if (empty($apiToken)) { // If no token available, silently fail (don't break the application) return; } $url = rtrim($apiBase, '/') . '/messaging/in-app/write'; $payload = json_encode([ 'message' => $message, 'level' => $level ]); $ch = curl_init($url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Authorization: Bearer ' . $apiToken, 'Content-Length: ' . strlen($payload) ]); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_exec($ch); curl_close($ch); } catch (Exception $e) { // Silently fail if notification sending fails } } ?>