Вход Регистрация
Файл: vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php
Строк: 731
<?php

namespace IlluminateFoundationConsole;

use 
CarbonCarbonInterval;
use 
Closure;
use 
DateTimeInterface;
use 
IlluminateConsoleApplication as Artisan;
use 
IlluminateConsoleCommand;
use 
IlluminateConsoleEventsCommandFinished;
use 
IlluminateConsoleEventsCommandStarting;
use 
IlluminateConsoleSchedulingSchedule;
use 
IlluminateContractsConsoleKernel as KernelContract;
use 
IlluminateContractsDebugExceptionHandler;
use 
IlluminateContractsEventsDispatcher;
use 
IlluminateContractsFoundationApplication;
use 
IlluminateSupportArr;
use 
IlluminateSupportCarbon;
use 
IlluminateSupportEnv;
use 
IlluminateSupportInteractsWithTime;
use 
IlluminateSupportStr;
use 
ReflectionClass;
use 
SplFileInfo;
use 
SymfonyComponentConsoleConsoleEvents;
use 
SymfonyComponentConsoleEventConsoleCommandEvent;
use 
SymfonyComponentConsoleEventConsoleTerminateEvent;
use 
SymfonyComponentEventDispatcherEventDispatcher;
use 
SymfonyComponentFinderFinder;
use 
Throwable;

class 
Kernel implements KernelContract
{
    use 
InteractsWithTime;

    
/**
     * The application implementation.
     *
     * @var IlluminateContractsFoundationApplication
     */
    
protected $app;

    
/**
     * The event dispatcher implementation.
     *
     * @var IlluminateContractsEventsDispatcher
     */
    
protected $events;

    
/**
     * The Symfony event dispatcher implementation.
     *
     * @var SymfonyContractsEventDispatcherEventDispatcherInterface|null
     */
    
protected $symfonyDispatcher;

    
/**
     * The Artisan application instance.
     *
     * @var IlluminateConsoleApplication|null
     */
    
protected $artisan;

    
/**
     * The Artisan commands provided by the application.
     *
     * @var array
     */
    
protected $commands = [];

    
/**
     * Indicates if the Closure commands have been loaded.
     *
     * @var bool
     */
    
protected $commandsLoaded false;

    
/**
     * All of the registered command duration handlers.
     *
     * @var array
     */
    
protected $commandLifecycleDurationHandlers = [];

    
/**
     * When the currently handled command started.
     *
     * @var IlluminateSupportCarbon|null
     */
    
protected $commandStartedAt;

    
/**
     * The bootstrap classes for the application.
     *
     * @var string[]
     */
    
protected $bootstrappers = [
        
IlluminateFoundationBootstrapLoadEnvironmentVariables::class,
        
IlluminateFoundationBootstrapLoadConfiguration::class,
        
IlluminateFoundationBootstrapHandleExceptions::class,
        
IlluminateFoundationBootstrapRegisterFacades::class,
        
IlluminateFoundationBootstrapSetRequestForConsole::class,
        
IlluminateFoundationBootstrapRegisterProviders::class,
        
IlluminateFoundationBootstrapBootProviders::class,
    ];

    
/**
     * Create a new console kernel instance.
     *
     * @param  IlluminateContractsFoundationApplication  $app
     * @param  IlluminateContractsEventsDispatcher  $events
     * @return void
     */
    
public function __construct(Application $appDispatcher $events)
    {
        if (! 
defined('ARTISAN_BINARY')) {
            
define('ARTISAN_BINARY''artisan');
        }

        
$this->app $app;
        
$this->events $events;

        
$this->app->booted(function () {
            if (! 
$this->app->runningUnitTests()) {
                
$this->rerouteSymfonyCommandEvents();
            }

            
$this->defineConsoleSchedule();
        });
    }

    
/**
     * Re-route the Symfony command events to their Laravel counterparts.
     *
     * @internal
     *
     * @return $this
     */
    
public function rerouteSymfonyCommandEvents()
    {
        if (
is_null($this->symfonyDispatcher)) {
            
$this->symfonyDispatcher = new EventDispatcher;

            
$this->symfonyDispatcher->addListener(ConsoleEvents::COMMAND, function (ConsoleCommandEvent $event) {
                
$this->events->dispatch(
                    new 
CommandStarting($event->getCommand()->getName(), $event->getInput(), $event->getOutput())
                );
            });

            
$this->symfonyDispatcher->addListener(ConsoleEvents::TERMINATE, function (ConsoleTerminateEvent $event) {
                
$this->events->dispatch(
                    new 
CommandFinished($event->getCommand()->getName(), $event->getInput(), $event->getOutput(), $event->getExitCode())
                );
            });
        }

        return 
$this;
    }

    
/**
     * Define the application's command schedule.
     *
     * @return void
     */
    
protected function defineConsoleSchedule()
    {
        
$this->app->singleton(Schedule::class, function ($app) {
            return 
tap(new Schedule($this->scheduleTimezone()), function ($schedule) {
                
$this->schedule($schedule->useCache($this->scheduleCache()));
            });
        });
    }

    
/**
     * Get the name of the cache store that should manage scheduling mutexes.
     *
     * @return string
     */
    
protected function scheduleCache()
    {
        return 
$this->app['config']->get('cache.schedule_store'Env::get('SCHEDULE_CACHE_DRIVER'));
    }

    
/**
     * Run the console application.
     *
     * @param  SymfonyComponentConsoleInputInputInterface  $input
     * @param  SymfonyComponentConsoleOutputOutputInterface|null  $output
     * @return int
     */
    
public function handle($input$output null)
    {
        
$this->commandStartedAt Carbon::now();

        try {
            if (
in_array($input->getFirstArgument(), ['env:encrypt''env:decrypt'], true)) {
                
$this->bootstrapWithoutBootingProviders();
            }

            
$this->bootstrap();

            return 
$this->getArtisan()->run($input$output);
        } catch (
Throwable $e) {
            
$this->reportException($e);

            
$this->renderException($output$e);

            return 
1;
        }
    }

    
/**
     * Terminate the application.
     *
     * @param  SymfonyComponentConsoleInputInputInterface  $input
     * @param  int  $status
     * @return void
     */
    
public function terminate($input$status)
    {
        
$this->app->terminate();

        if (
$this->commandStartedAt === null) {
            return;
        }

        
$this->commandStartedAt->setTimezone($this->app['config']->get('app.timezone') ?? 'UTC');

        foreach (
$this->commandLifecycleDurationHandlers as ['threshold' => $threshold'handler' => $handler]) {
            
$end ??= Carbon::now();

            if (
$this->commandStartedAt->diffInMilliseconds($end) > $threshold) {
                
$handler($this->commandStartedAt$input$status);
            }
        }

        
$this->commandStartedAt null;
    }

    
/**
     * Register a callback to be invoked when the command lifecycle duration exceeds a given amount of time.
     *
     * @param  DateTimeInterface|CarbonCarbonInterval|float|int  $threshold
     * @param  callable  $handler
     * @return void
     */
    
public function whenCommandLifecycleIsLongerThan($threshold$handler)
    {
        
$threshold $threshold instanceof DateTimeInterface
            
$this->secondsUntil($threshold) * 1000
            
$threshold;

        
$threshold $threshold instanceof CarbonInterval
            
$threshold->totalMilliseconds
            
$threshold;

        
$this->commandLifecycleDurationHandlers[] = [
            
'threshold' => $threshold,
            
'handler' => $handler,
        ];
    }

    
/**
     * When the command being handled started.
     *
     * @return IlluminateSupportCarbon|null
     */
    
public function commandStartedAt()
    {
        return 
$this->commandStartedAt;
    }

    
/**
     * Define the application's command schedule.
     *
     * @param  IlluminateConsoleSchedulingSchedule  $schedule
     * @return void
     */
    
protected function schedule(Schedule $schedule)
    {
        
//
    
}

    
/**
     * Get the timezone that should be used by default for scheduled events.
     *
     * @return DateTimeZone|string|null
     */
    
protected function scheduleTimezone()
    {
        
$config $this->app['config'];

        return 
$config->get('app.schedule_timezone'$config->get('app.timezone'));
    }

    
/**
     * Register the commands for the application.
     *
     * @return void
     */
    
protected function commands()
    {
        
//
    
}

    
/**
     * Register a Closure based command with the application.
     *
     * @param  string  $signature
     * @param  Closure  $callback
     * @return IlluminateFoundationConsoleClosureCommand
     */
    
public function command($signatureClosure $callback)
    {
        
$command = new ClosureCommand($signature$callback);

        
Artisan::starting(function ($artisan) use ($command) {
            
$artisan->add($command);
        });

        return 
$command;
    }

    
/**
     * Register all of the commands in the given directory.
     *
     * @param  array|string  $paths
     * @return void
     */
    
protected function load($paths)
    {
        
$paths array_unique(Arr::wrap($paths));

        
$paths array_filter($paths, function ($path) {
            return 
is_dir($path);
        });

        if (empty(
$paths)) {
            return;
        }

        
$namespace $this->app->getNamespace();

        foreach (
Finder::create()->in($paths)->files() as $file) {
            
$command $this->commandClassFromFile($file$namespace);

            if (
is_subclass_of($commandCommand::class) &&
                ! (new 
ReflectionClass($command))->isAbstract()) {
                
Artisan::starting(function ($artisan) use ($command) {
                    
$artisan->resolve($command);
                });
            }
        }
    }

    
/**
     * Extract the command class name from the given file path.
     *
     * @param  SplFileInfo  $file
     * @param  string  $namespace
     * @return string
     */
    
protected function commandClassFromFile(SplFileInfo $filestring $namespace): string
    
{
        return 
$namespace.str_replace(
            [
'/''.php'],
            [
'\', ''],
            Str::after($file->getRealPath(), realpath(app_path()).DIRECTORY_SEPARATOR)
        );
    }

    /**
     * Register the given command with the console application.
     *
     * @param  SymfonyComponentConsoleCommandCommand  $command
     * @return void
     */
    public function registerCommand($command)
    {
        $this->getArtisan()->add($command);
    }

    /**
     * Run an Artisan console command by name.
     *
     * @param  string  $command
     * @param  array  $parameters
     * @param  SymfonyComponentConsoleOutputOutputInterface|null  $outputBuffer
     * @return int
     *
     * @throws SymfonyComponentConsoleExceptionCommandNotFoundException
     */
    public function call($command, array $parameters = [], $outputBuffer = null)
    {
        if (in_array($command, ['
env:encrypt', 'env:decrypt'], true)) {
            $this->bootstrapWithoutBootingProviders();
        }

        $this->bootstrap();

        return $this->getArtisan()->call($command, $parameters, $outputBuffer);
    }

    /**
     * Queue the given console command.
     *
     * @param  string  $command
     * @param  array  $parameters
     * @return IlluminateFoundationBusPendingDispatch
     */
    public function queue($command, array $parameters = [])
    {
        return QueuedCommand::dispatch(func_get_args());
    }

    /**
     * Get all of the commands registered with the console.
     *
     * @return array
     */
    public function all()
    {
        $this->bootstrap();

        return $this->getArtisan()->all();
    }

    /**
     * Get the output for the last run command.
     *
     * @return string
     */
    public function output()
    {
        $this->bootstrap();

        return $this->getArtisan()->output();
    }

    /**
     * Bootstrap the application for artisan commands.
     *
     * @return void
     */
    public function bootstrap()
    {
        if (! $this->app->hasBeenBootstrapped()) {
            $this->app->bootstrapWith($this->bootstrappers());
        }

        $this->app->loadDeferredProviders();

        if (! $this->commandsLoaded) {
            $this->commands();

            $this->commandsLoaded = true;
        }
    }

    /**
     * Bootstrap the application without booting service providers.
     *
     * @return void
     */
    public function bootstrapWithoutBootingProviders()
    {
        $this->app->bootstrapWith(
            collect($this->bootstrappers())->reject(function ($bootstrapper) {
                return $bootstrapper === IlluminateFoundationBootstrapBootProviders::class;
            })->all()
        );
    }

    /**
     * Get the Artisan application instance.
     *
     * @return IlluminateConsoleApplication
     */
    protected function getArtisan()
    {
        if (is_null($this->artisan)) {
            $this->artisan = (new Artisan($this->app, $this->events, $this->app->version()))
                                    ->resolveCommands($this->commands)
                                    ->setContainerCommandLoader();

            if ($this->symfonyDispatcher instanceof EventDispatcher) {
                $this->artisan->setDispatcher($this->symfonyDispatcher);
                $this->artisan->setSignalsToDispatchEvent();
            }
        }

        return $this->artisan;
    }

    /**
     * Set the Artisan application instance.
     *
     * @param  IlluminateConsoleApplication|null  $artisan
     * @return void
     */
    public function setArtisan($artisan)
    {
        $this->artisan = $artisan;
    }

    /**
     * Get the bootstrap classes for the application.
     *
     * @return array
     */
    protected function bootstrappers()
    {
        return $this->bootstrappers;
    }

    /**
     * Report the exception to the exception handler.
     *
     * @param  Throwable  $e
     * @return void
     */
    protected function reportException(Throwable $e)
    {
        $this->app[ExceptionHandler::class]->report($e);
    }

    /**
     * Render the given exception.
     *
     * @param  SymfonyComponentConsoleOutputOutputInterface  $output
     * @param  Throwable  $e
     * @return void
     */
    protected function renderException($output, Throwable $e)
    {
        $this->app[ExceptionHandler::class]->renderForConsole($output, $e);
    }
}
Онлайн: 0
Реклама