params[$name]) ? $this->params[$name] : ''; } public function apiCall($route) { if (!in_array($route, ['nodes', 'packs'], true)) { throw new \InvalidArgumentException('Ruta de API no permitida.'); } $base = Config::url(Config::load(), 'vpsmanager_api_url', false); if (!function_exists('curl_init')) { throw new \RuntimeException('Transporte del módulo no disponible.'); } $ch = curl_init($base . '/' . $route); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 3, CURLOPT_TIMEOUT => 10, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_FOLLOWLOCATION => false, ]); try { $body = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); } finally { curl_close($ch); } if ($body === false || $status < 200 || $status >= 300) { throw new \RuntimeException('API del módulo no disponible.'); } $data = json_decode($body, true); if (!is_array($data)) { throw new \RuntimeException('Respuesta de API no válida.'); } return $data; } }