hasOption('context') && true === $input->getOption('context')) { Config::save('logs.context', true); } if ($input->hasOption('no-context') && true === $input->getOption('no-context')) { Config::save('logs.context', false); } if ($input->hasOption('trace') && true === $input->getOption('trace')) { Config::save('logs.context', true); } if (!$input->hasOption('profile') || !$input->getOption('profile')) { return $this->runCommand($input, $output); } $profiler = new Profiler(Config::get('debug.profiler.options', [])); $profiler->enable(); $status = $this->runCommand($input, $output); $data = $profiler->disable(); if (empty($data)) { throw new RuntimeException('The profiler run was unsuccessful. No data was returned.'); } $removeKeys = [ 'HTTP_USER_AGENT', 'PHP_AUTH_USER', 'REMOTE_USER', 'UNIQUE_ID' ]; $appVersion = getAppVersion(); $inContainer = inContainer(); $url = '/cli/' . $this->getName(); $data['meta']['url'] = $data['meta']['simple_url'] = $url; $data['meta']['get'] = $data['meta']['env'] = []; $data['meta']['SERVER'] = array_replace_recursive($data['meta']['SERVER'], [ 'APP_VERSION' => $appVersion, 'PHP_VERSION' => PHP_VERSION, 'PHP_VERSION_ID' => PHP_VERSION_ID, 'PHP_OS' => PHP_OS, 'CONTAINER' => $inContainer ? 'Yes' : 'No', 'SYSTEM' => php_uname('s') . ' ' . php_uname('r') . ' ' . php_uname('v') . ' ' . php_uname('m'), 'DOCUMENT_ROOT' => $inContainer ? '/container/' : '/cli', 'REMOTE_ADDR' => '127.0.0.1', 'SERVER_ADDR' => '127.0.0.1', 'SERVER_NAME' => ($inContainer ? 'container' : 'cli') . '.watchstate.' . $appVersion ]); foreach ($removeKeys as $key) { if (isset($data['meta'][$key])) { unset($data['meta'][$key]); } } $profiler->save($data); return $status; } protected function single(\Closure $closure, OutputInterface $output): int { try { if (!$this->lock(getAppVersion() . ':' . $this->getName())) { $output->writeln( sprintf( 'The command \'%s\' is already running in another process.', $this->getName() ) ); return self::SUCCESS; } return $closure(); } finally { $this->release(); } } protected function runCommand(InputInterface $input, OutputInterface $output): int { return self::SUCCESS; } /** * Check Given backends file. * * @param string $config custom servers.yaml file. * @return string * * @throws RuntimeException if there is problem with given config. */ protected function checkCustomBackendsFile(string $config): string { if (!file_exists($config) || !is_file($config)) { throw new RuntimeException( r('Config file [{config}] does not exists.', [ 'config' => $config ]) ); } if (!is_readable($config)) { throw new RuntimeException( r('Unable to read config file [{config}]. (Check Permissions)', [ 'config' => $config ]) ); } if (!is_writable($config)) { throw new RuntimeException( r('Unable to edit config file [{config}]. (Check Permissions)', [ 'config' => $config ]) ); } return $config; } protected function getBackend(string $name, array $config = []): iClient { if (null === Config::get("servers.{$name}.type", null)) { throw new RuntimeException(r('No backend named [{backend}] was found.', ['backend' => $name])); } $default = Config::get("servers.{$name}"); $default['name'] = $name; return makeBackend(array_replace_recursive($default, $config), $name); } protected function displayContent(array $content, OutputInterface $output, string $mode = 'json'): void { switch ($mode) { case 'json': $output->writeln( json_encode( value: $content, flags: JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_IGNORE ) ); break; case 'table': $list = []; foreach ($content as $_ => $item) { if (false === is_array($item)) { $item = [$_ => $item]; } $subItem = []; foreach ($item as $key => $leaf) { if (true === is_array($leaf)) { continue; } $subItem[$key] = $leaf; } $list[] = $subItem; $list[] = new TableSeparator(); } if (!empty($list)) { array_pop($list); (new Table($output)) ->setStyle(name: 'box') ->setHeaders( array_map( callback: fn($title) => is_string($title) ? ucfirst($title) : $title, array: array_keys($list[0]) ) ) ->setRows(rows: $list) ->render(); } break; case 'yaml': default: $output->writeln(Yaml::dump(input: $content, inline: 8, indent: 2)); break; } } public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void { if ($input->mustSuggestOptionValuesFor('config')) { $currentValue = $input->getCompletionValue(); $suggest = []; foreach (new DirectoryIterator(getcwd()) as $name) { if (!$name->isFile()) { continue; } if (empty($currentValue) || str_starts_with($name->getFilename(), $currentValue)) { $suggest[] = $name->getFilename(); } } $suggestions->suggestValues($suggest); } if ($input->mustSuggestOptionValuesFor('select-backends') || $input->mustSuggestArgumentValuesFor('backend')) { $currentValue = $input->getCompletionValue(); $suggest = []; foreach (array_keys(Config::get('servers', [])) as $name) { if (true === str_contains($currentValue, ',')) { $text = explode(',', $currentValue); $currentValue = array_pop($text); } if (empty($currentValue) || str_starts_with($name, $currentValue)) { $suggest[] = $name; } } $suggestions->suggestValues($suggest); } if ($input->mustSuggestOptionValuesFor('output')) { $currentValue = $input->getCompletionValue(); $suggest = []; foreach (static::DISPLAY_OUTPUT as $name) { if (empty($currentValue) || str_starts_with($name, $currentValue)) { $suggest[] = $name; } } $suggestions->suggestValues($suggest); } } }