$_POST['assetId'] ?? '', 'assetName' => $_POST['assetName'] ?? '', 'param1' => $_POST['param1'] ?? '', 'param2' => $_POST['param2'] ?? '' ]; // Node-RED omgevingen $envFile = __DIR__ . '/../settings/environments.json'; $environments = getNodeRedEnvironments($envFile); $selectedEnv = $_POST['environment'] ?? ''; // Alert template-versie $newVersionAlert = checkNewTemplateVersionAlert($templatePath, $deployDir); // Overzicht deploys $deploys = getDeploysWithVersions($deployDir); // Init variabelen $deployResponse = ''; $newFileName = ''; $envUrl = ''; $successMessage = ''; // Deploy verwerken if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['deploy'])) { $deployResult = deployFlow($parameters, $templatePath, $deployDir, $environments, $selectedEnv); if ($deployResult['success']) { $deployResponse = $deployResult['response']; $newFileName = $deployResult['file']; $envUrl = $deployResult['envUrl']; $successMessage = renderAlert($deployResult['message'], 'success'); } else { $successMessage = renderAlert($deployResult['message'], 'danger'); } } // ------------------------------------------------------ // *** HELPERS *** // ------------------------------------------------------ /** * Verkrijg een overzicht van alle Node-RED omgevingen * * @param string $envFile Pad naar JSON-bestand met omgevingen * @return array */ function getNodeRedEnvironments(string $envFile): array { $json = @file_get_contents($envFile); if (!$json) return []; $data = json_decode($json, true); return is_array($data) ? $data : []; } /** * Vind alle versioned JSON-bestanden in een directory * * @param string $dir * @return array */ function findVersionedJsonFilesInDir(string $dir): array { $matches = []; foreach (scandir($dir) as $file) { if (preg_match('/^version\d+_\d{12}\.json$/', $file)) { $matches[] = ['name' => $file]; } } usort($matches, fn($a, $b) => strcmp($a['name'], $b['name'])); return $matches; } /** * Vind het laatst gedeployde bestand * * @param string $dir * @return string|null */ function findLatestDeployFile(string $dir): ?string { $files = findVersionedJsonFilesInDir($dir); return !empty($files) ? end($files)['name'] : null; } /** * Haal versie uit een JSON-bestand * * @param string $filePath * @return int */ function getVersionFromJson(string $filePath): int { if (!file_exists($filePath)) return 0; $json = json_decode(file_get_contents($filePath), true); return $json[0]['version'] ?? 0; } /** * Haal versie uit een template * * @param string $templatePath * @return int */ function getVersionFromTemplate(string $templatePath): int { if (!file_exists($templatePath)) return 0; preg_match('/"version"\s*:\s*(\d+)/', file_get_contents($templatePath), $m); return $m[1] ?? 0; } /** * Controleer of de template een hogere versie heeft dan de laatste deploy * * @param string $templatePath * @param string $deployDir * @return string|null */ function checkNewTemplateVersionAlert(string $templatePath, string $deployDir): ?string { $templateVersion = getVersionFromTemplate($templatePath); $latestDeployFile = findLatestDeployFile($deployDir); $latestVersion = $latestDeployFile ? getVersionFromJson($deployDir . '/' . $latestDeployFile) : 0; if ($templateVersion > $latestVersion) { return "
Nieuwe template-versie beschikbaar! (Template v$templateVersion > Laatste deploy v$latestVersion)
"; } return null; } /** * Genereer de bestandsnaam voor een nieuwe deploy * * @param int $version * @return string */ function generateNextDeployFileName(int $version): string { return "version{$version}_" . date('YmdHi') . ".json"; } /** * Render een template met placeholders * * @param string $templatePath * @param array $placeholders * @return string */ function renderTemplate(string $templatePath, array $placeholders): string { $content = file_get_contents($templatePath); foreach ($placeholders as $key => $value) { $content = str_replace("{{{$key}}}", $value, $content); } return $content; } /** * Render een standaard alert * * @param string $message * @param string $type * @return string */ function renderAlert(string $message, string $type = 'info'): string { return "
$message
"; } /** * Verkrijg een overzicht van alle deploys inclusief versies * * @param string $dir * @return array */ function getDeploysWithVersions(string $dir): array { $files = findVersionedJsonFilesInDir($dir); return array_map(function ($f) use ($dir) { return [ 'name' => $f['name'], 'version' => getVersionFromJson($dir . '/' . $f['name']) ]; }, array_reverse($files)); } // ------------------------------------------------------ // *** DEPLOY FUNCTIES *** // ------------------------------------------------------ /** * Deploy een JSON-flowbestand naar een Node-RED URL via POST * * @param string $flowPath Pad naar flow JSON * @param string $url Node-RED URL * @return string HTTP status code of foutmelding */ function deployFlowToUrl(string $flowPath, string $url): string { if (!file_exists($flowPath)) { return ''; } $flowJson = file_get_contents($flowPath); $ch = curl_init(rtrim($url, '/') . '/flows'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_POSTFIELDS => $flowJson, ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return $httpCode; } /** * Deploy een flow naar een geselecteerde Node-RED omgeving * * @param array $parameters Asset parameters * @param string $templatePath Pad naar template JSON * @param string $deployDir Deploy directory * @param array $environments Beschikbare Node-RED omgevingen * @param string $selectedEnv Geselecteerde omgeving (IP) * @return array Resultaat van de deploy */ function deployFlow(array $parameters, string $templatePath, string $deployDir, array $environments, string $selectedEnv): array { $result = [ 'success' => false, 'message' => '', 'file' => null, 'envUrl' => null, 'response' => null ]; if (empty($selectedEnv)) { $result['message'] = 'Geen omgeving geselecteerd!'; return $result; } // Template-versie ophalen $templateVersion = getVersionFromTemplate($templatePath); // URL van geselecteerde omgeving $envUrl = ''; foreach ($environments as $env) { if (($env['ip'] ?? '') === $selectedEnv) { $envUrl = $env['ip']; break; } } if (!$envUrl) { $result['message'] = 'Omgeving niet gevonden of URL ontbreekt!'; return $result; } // Placeholders invullen $placeholders = [ 'id' => $parameters['assetId'] ?? '', 'name' => $parameters['assetName'] ?? '', 'version' => $templateVersion, 'param1' => $parameters['param1'] ?? '', 'param2' => $parameters['param2'] ?? '', 'ip' => $envUrl ]; // Template renderen en deploy-bestand schrijven $flowJson = renderTemplate($templatePath, $placeholders); $newFileName = generateNextDeployFileName($templateVersion); $deployFile = $deployDir . '/' . $newFileName; file_put_contents($deployFile, $flowJson); // Deploy naar Node-RED uitvoeren $deployResponse = deployFlowToUrl($deployFile, $envUrl); $result['success'] = true; $result['message'] = "Nieuwe versie $newFileName gedeployed naar $envUrl!"; $result['file'] = $newFileName; $result['envUrl'] = $envUrl; $result['response'] = $deployResponse; return $result; }