$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; }