diff --git a/Plugin/usr/local/emhttp/plugins/varaverk/include/scheduler.php b/Plugin/usr/local/emhttp/plugins/varaverk/include/scheduler.php index b869e83..88b36d2 100644 --- a/Plugin/usr/local/emhttp/plugins/varaverk/include/scheduler.php +++ b/Plugin/usr/local/emhttp/plugins/varaverk/include/scheduler.php @@ -79,21 +79,34 @@ function vv_job_tree(): array { return $orchs; } -// Parse an orchestrator script to find which child scripts it calls +// Parse an orchestrator script to find which child scripts it calls. +// Handles two common patterns: +// $SCRIPT_DIR/../Category/script.sh (relative via variable) +// $SCRIPTS_ROOT/Category/script.sh (absolute root via variable) +// Root-level files (load_config.sh, etc.) are excluded — must be in a subdirectory. +// Validates each candidate against the filesystem to filter false positives. function vv_script_children(string $orchPath, array $schedule): array { $scriptsDir = SCRIPTS_DIR; $content = file_get_contents($orchPath) ?: ''; $children = []; + $seen = []; + + // Match $ANY_VAR/../Category/script.sh or $ANY_VAR/Category/script.sh + // Capture only the Category/script.sh portion (requires at least one subdirectory) + preg_match_all( + '/\$[A-Z_]+\/(?:\.\.\/)?([A-Za-z][A-Za-z0-9_.\-]*\/[A-Za-z0-9_.\-]+\.sh)/', + $content, + $m + ); - // Match: bash "path/to/script.sh" or source path/to/script.sh - preg_match_all('/(?:bash|source|\.)\s+"?([^"\s]+\.sh)"?/m', $content, $m); foreach ($m[1] as $rel) { - // Normalise relative paths - $rel = ltrim(str_replace($scriptsDir . '/', '', $rel), './'); - $id = $rel; - $entry = $schedule[$id] ?? ['enabled' => false, 'cron' => '']; + if (isset($seen[$rel])) continue; + if (!file_exists("$scriptsDir/$rel")) continue; + $seen[$rel] = true; + + $entry = $schedule[$rel] ?? ['enabled' => false, 'cron' => '']; $children[] = [ - 'id' => $id, + 'id' => $rel, 'label' => basename($rel, '.sh'), 'type' => 'script', 'enabled' => (bool)($entry['enabled'] ?? false),