Initial commit
This commit is contained in:
321
vendor/laravel/framework/src/Illuminate/Console/Application.php
vendored
Executable file
321
vendor/laravel/framework/src/Illuminate/Console/Application.php
vendored
Executable file
@@ -0,0 +1,321 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Console\Events\ArtisanStarting;
|
||||
use Illuminate\Contracts\Console\Application as ApplicationContract;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Support\ProcessUtils;
|
||||
use Symfony\Component\Console\Application as SymfonyApplication;
|
||||
use Symfony\Component\Console\Command\Command as SymfonyCommand;
|
||||
use Symfony\Component\Console\Exception\CommandNotFoundException;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputDefinition;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\StringInput;
|
||||
use Symfony\Component\Console\Output\BufferedOutput;
|
||||
|
||||
use function Illuminate\Support\php_binary;
|
||||
|
||||
class Application extends SymfonyApplication implements ApplicationContract
|
||||
{
|
||||
/**
|
||||
* The Laravel application instance.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Container\Container
|
||||
*/
|
||||
protected $laravel;
|
||||
|
||||
/**
|
||||
* The event dispatcher instance.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Events\Dispatcher
|
||||
*/
|
||||
protected $events;
|
||||
|
||||
/**
|
||||
* The output from the previous command.
|
||||
*
|
||||
* @var \Symfony\Component\Console\Output\BufferedOutput
|
||||
*/
|
||||
protected $lastOutput;
|
||||
|
||||
/**
|
||||
* The console application bootstrappers.
|
||||
*
|
||||
* @var array<array-key, \Closure($this): void>
|
||||
*/
|
||||
protected static $bootstrappers = [];
|
||||
|
||||
/**
|
||||
* A map of command names to classes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $commandMap = [];
|
||||
|
||||
/**
|
||||
* Create a new Artisan console application.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Container\Container $laravel
|
||||
* @param \Illuminate\Contracts\Events\Dispatcher $events
|
||||
* @param string $version
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Container $laravel, Dispatcher $events, $version)
|
||||
{
|
||||
parent::__construct('Laravel Framework', $version);
|
||||
|
||||
$this->laravel = $laravel;
|
||||
$this->events = $events;
|
||||
$this->setAutoExit(false);
|
||||
$this->setCatchExceptions(false);
|
||||
|
||||
$this->events->dispatch(new ArtisanStarting($this));
|
||||
|
||||
$this->bootstrap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the proper PHP executable.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function phpBinary()
|
||||
{
|
||||
return ProcessUtils::escapeArgument(php_binary());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the proper Artisan executable.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function artisanBinary()
|
||||
{
|
||||
return ProcessUtils::escapeArgument(defined('ARTISAN_BINARY') ? ARTISAN_BINARY : 'artisan');
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given command as a fully-qualified executable command.
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public static function formatCommandString($string)
|
||||
{
|
||||
return sprintf('%s %s %s', static::phpBinary(), static::artisanBinary(), $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a console "starting" bootstrapper.
|
||||
*
|
||||
* @param \Closure($this): void $callback
|
||||
* @return void
|
||||
*/
|
||||
public static function starting(Closure $callback)
|
||||
{
|
||||
static::$bootstrappers[] = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap the console application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function bootstrap()
|
||||
{
|
||||
foreach (static::$bootstrappers as $bootstrapper) {
|
||||
$bootstrapper($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the console application bootstrappers.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function forgetBootstrappers()
|
||||
{
|
||||
static::$bootstrappers = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Run an Artisan console command by name.
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $parameters
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface|null $outputBuffer
|
||||
* @return int
|
||||
*
|
||||
* @throws \Symfony\Component\Console\Exception\CommandNotFoundException
|
||||
*/
|
||||
public function call($command, array $parameters = [], $outputBuffer = null)
|
||||
{
|
||||
[$command, $input] = $this->parseCommand($command, $parameters);
|
||||
|
||||
if (! $this->has($command)) {
|
||||
throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $command));
|
||||
}
|
||||
|
||||
return $this->run(
|
||||
$input, $this->lastOutput = $outputBuffer ?: new BufferedOutput
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the incoming Artisan command and its input.
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function parseCommand($command, $parameters)
|
||||
{
|
||||
if (is_subclass_of($command, SymfonyCommand::class)) {
|
||||
$callingClass = true;
|
||||
|
||||
$command = $this->laravel->make($command)->getName();
|
||||
}
|
||||
|
||||
if (! isset($callingClass) && empty($parameters)) {
|
||||
$command = $this->getCommandName($input = new StringInput($command));
|
||||
} else {
|
||||
array_unshift($parameters, $command);
|
||||
|
||||
$input = new ArrayInput($parameters);
|
||||
}
|
||||
|
||||
return [$command, $input];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the output for the last run command.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
return $this->lastOutput && method_exists($this->lastOutput, 'fetch')
|
||||
? $this->lastOutput->fetch()
|
||||
: '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a command to the console.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Command\Command $command
|
||||
* @return \Symfony\Component\Console\Command\Command|null
|
||||
*/
|
||||
#[\Override]
|
||||
public function add(SymfonyCommand $command): ?SymfonyCommand
|
||||
{
|
||||
if ($command instanceof Command) {
|
||||
$command->setLaravel($this->laravel);
|
||||
}
|
||||
|
||||
return $this->addToParent($command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the command to the parent instance.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Command\Command $command
|
||||
* @return \Symfony\Component\Console\Command\Command
|
||||
*/
|
||||
protected function addToParent(SymfonyCommand $command)
|
||||
{
|
||||
return parent::add($command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a command, resolving through the application.
|
||||
*
|
||||
* @param \Illuminate\Console\Command|string $command
|
||||
* @return \Symfony\Component\Console\Command\Command|null
|
||||
*/
|
||||
public function resolve($command)
|
||||
{
|
||||
if (is_subclass_of($command, SymfonyCommand::class) && ($commandName = $command::getDefaultName())) {
|
||||
foreach (explode('|', $commandName) as $name) {
|
||||
$this->commandMap[$name] = $command;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($command instanceof Command) {
|
||||
return $this->add($command);
|
||||
}
|
||||
|
||||
return $this->add($this->laravel->make($command));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve an array of commands through the application.
|
||||
*
|
||||
* @param array|mixed $commands
|
||||
* @return $this
|
||||
*/
|
||||
public function resolveCommands($commands)
|
||||
{
|
||||
$commands = is_array($commands) ? $commands : func_get_args();
|
||||
|
||||
foreach ($commands as $command) {
|
||||
$this->resolve($command);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the container command loader for lazy resolution.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setContainerCommandLoader()
|
||||
{
|
||||
$this->setCommandLoader(new ContainerCommandLoader($this->laravel, $this->commandMap));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default input definition for the application.
|
||||
*
|
||||
* This is used to add the --env option to every available command.
|
||||
*
|
||||
* @return \Symfony\Component\Console\Input\InputDefinition
|
||||
*/
|
||||
#[\Override]
|
||||
protected function getDefaultInputDefinition(): InputDefinition
|
||||
{
|
||||
return tap(parent::getDefaultInputDefinition(), function ($definition) {
|
||||
$definition->addOption($this->getEnvironmentOption());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the global environment option for the definition.
|
||||
*
|
||||
* @return \Symfony\Component\Console\Input\InputOption
|
||||
*/
|
||||
protected function getEnvironmentOption()
|
||||
{
|
||||
$message = 'The environment the command should run under';
|
||||
|
||||
return new InputOption('--env', null, InputOption::VALUE_OPTIONAL, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Laravel application instance.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Foundation\Application
|
||||
*/
|
||||
public function getLaravel()
|
||||
{
|
||||
return $this->laravel;
|
||||
}
|
||||
}
|
||||
42
vendor/laravel/framework/src/Illuminate/Console/BufferedConsoleOutput.php
vendored
Normal file
42
vendor/laravel/framework/src/Illuminate/Console/BufferedConsoleOutput.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Symfony\Component\Console\Output\ConsoleOutput;
|
||||
|
||||
class BufferedConsoleOutput extends ConsoleOutput
|
||||
{
|
||||
/**
|
||||
* The current buffer.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $buffer = '';
|
||||
|
||||
/**
|
||||
* Empties the buffer and returns its content.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function fetch()
|
||||
{
|
||||
return tap($this->buffer, function () {
|
||||
$this->buffer = '';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\Override]
|
||||
protected function doWrite(string $message, bool $newline): void
|
||||
{
|
||||
$this->buffer .= $message;
|
||||
|
||||
if ($newline) {
|
||||
$this->buffer .= \PHP_EOL;
|
||||
}
|
||||
|
||||
parent::doWrite($message, $newline);
|
||||
}
|
||||
}
|
||||
141
vendor/laravel/framework/src/Illuminate/Console/CacheCommandMutex.php
vendored
Normal file
141
vendor/laravel/framework/src/Illuminate/Console/CacheCommandMutex.php
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Carbon\CarbonInterval;
|
||||
use Illuminate\Cache\DynamoDbStore;
|
||||
use Illuminate\Contracts\Cache\Factory as Cache;
|
||||
use Illuminate\Contracts\Cache\LockProvider;
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
|
||||
class CacheCommandMutex implements CommandMutex
|
||||
{
|
||||
use InteractsWithTime;
|
||||
|
||||
/**
|
||||
* The cache factory implementation.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Cache\Factory
|
||||
*/
|
||||
public $cache;
|
||||
|
||||
/**
|
||||
* The cache store that should be used.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $store = null;
|
||||
|
||||
/**
|
||||
* Create a new command mutex.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Cache\Factory $cache
|
||||
*/
|
||||
public function __construct(Cache $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to obtain a command mutex for the given command.
|
||||
*
|
||||
* @param \Illuminate\Console\Command $command
|
||||
* @return bool
|
||||
*/
|
||||
public function create($command)
|
||||
{
|
||||
$store = $this->cache->store($this->store);
|
||||
|
||||
$expiresAt = method_exists($command, 'isolationLockExpiresAt')
|
||||
? $command->isolationLockExpiresAt()
|
||||
: CarbonInterval::hour();
|
||||
|
||||
if ($this->shouldUseLocks($store->getStore())) {
|
||||
return $store->getStore()->lock(
|
||||
$this->commandMutexName($command),
|
||||
$this->secondsUntil($expiresAt)
|
||||
)->get();
|
||||
}
|
||||
|
||||
return $store->add($this->commandMutexName($command), true, $expiresAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a command mutex exists for the given command.
|
||||
*
|
||||
* @param \Illuminate\Console\Command $command
|
||||
* @return bool
|
||||
*/
|
||||
public function exists($command)
|
||||
{
|
||||
$store = $this->cache->store($this->store);
|
||||
|
||||
if ($this->shouldUseLocks($store->getStore())) {
|
||||
$lock = $store->getStore()->lock($this->commandMutexName($command));
|
||||
|
||||
return tap(! $lock->get(), function ($exists) use ($lock) {
|
||||
if ($exists) {
|
||||
$lock->release();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return $this->cache->store($this->store)->has($this->commandMutexName($command));
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the mutex for the given command.
|
||||
*
|
||||
* @param \Illuminate\Console\Command $command
|
||||
* @return bool
|
||||
*/
|
||||
public function forget($command)
|
||||
{
|
||||
$store = $this->cache->store($this->store);
|
||||
|
||||
if ($this->shouldUseLocks($store->getStore())) {
|
||||
return $store->getStore()->lock($this->commandMutexName($command))->forceRelease();
|
||||
}
|
||||
|
||||
return $this->cache->store($this->store)->forget($this->commandMutexName($command));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the isolatable command mutex name.
|
||||
*
|
||||
* @param \Illuminate\Console\Command $command
|
||||
* @return string
|
||||
*/
|
||||
protected function commandMutexName($command)
|
||||
{
|
||||
$baseName = 'framework'.DIRECTORY_SEPARATOR.'command-'.$command->getName();
|
||||
|
||||
return method_exists($command, 'isolatableId')
|
||||
? $baseName.'-'.$command->isolatableId()
|
||||
: $baseName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the cache store that should be used.
|
||||
*
|
||||
* @param string|null $store
|
||||
* @return $this
|
||||
*/
|
||||
public function useStore($store)
|
||||
{
|
||||
$this->store = $store;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given store should use locks for command mutexes.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Cache\Store $store
|
||||
* @return bool
|
||||
*/
|
||||
protected function shouldUseLocks($store)
|
||||
{
|
||||
return $store instanceof LockProvider && ! $store instanceof DynamoDbStore;
|
||||
}
|
||||
}
|
||||
327
vendor/laravel/framework/src/Illuminate/Console/Command.php
vendored
Executable file
327
vendor/laravel/framework/src/Illuminate/Console/Command.php
vendored
Executable file
@@ -0,0 +1,327 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Illuminate\Console\View\Components\Factory;
|
||||
use Illuminate\Contracts\Console\Isolatable;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Symfony\Component\Console\Command\Command as SymfonyCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Throwable;
|
||||
|
||||
class Command extends SymfonyCommand
|
||||
{
|
||||
use Concerns\CallsCommands,
|
||||
Concerns\ConfiguresPrompts,
|
||||
Concerns\HasParameters,
|
||||
Concerns\InteractsWithIO,
|
||||
Concerns\InteractsWithSignals,
|
||||
Concerns\PromptsForMissingInput,
|
||||
Macroable;
|
||||
|
||||
/**
|
||||
* The Laravel application instance.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Foundation\Application
|
||||
*/
|
||||
protected $laravel;
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature;
|
||||
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $description;
|
||||
|
||||
/**
|
||||
* The console command help text.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $help;
|
||||
|
||||
/**
|
||||
* Indicates whether the command should be shown in the Artisan command list.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $hidden = false;
|
||||
|
||||
/**
|
||||
* Indicates whether only one instance of the command can run at any given time.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isolated = false;
|
||||
|
||||
/**
|
||||
* The default exit code for isolated commands.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $isolatedExitCode = self::SUCCESS;
|
||||
|
||||
/**
|
||||
* The console command name aliases.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $aliases;
|
||||
|
||||
/**
|
||||
* Create a new console command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// We will go ahead and set the name, description, and parameters on console
|
||||
// commands just to make things a little easier on the developer. This is
|
||||
// so they don't have to all be manually specified in the constructors.
|
||||
if (isset($this->signature)) {
|
||||
$this->configureUsingFluentDefinition();
|
||||
} else {
|
||||
parent::__construct($this->name);
|
||||
}
|
||||
|
||||
// Once we have constructed the command, we'll set the description and other
|
||||
// related properties of the command. If a signature wasn't used to build
|
||||
// the command we'll set the arguments and the options on this command.
|
||||
if (! isset($this->description)) {
|
||||
$this->setDescription((string) static::getDefaultDescription());
|
||||
} else {
|
||||
$this->setDescription((string) $this->description);
|
||||
}
|
||||
|
||||
$this->setHelp((string) $this->help);
|
||||
|
||||
$this->setHidden($this->isHidden());
|
||||
|
||||
if (isset($this->aliases)) {
|
||||
$this->setAliases((array) $this->aliases);
|
||||
}
|
||||
|
||||
if (! isset($this->signature)) {
|
||||
$this->specifyParameters();
|
||||
}
|
||||
|
||||
if ($this instanceof Isolatable) {
|
||||
$this->configureIsolation();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the console command using a fluent definition.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function configureUsingFluentDefinition()
|
||||
{
|
||||
[$name, $arguments, $options] = Parser::parse($this->signature);
|
||||
|
||||
parent::__construct($this->name = $name);
|
||||
|
||||
// After parsing the signature we will spin through the arguments and options
|
||||
// and set them on this command. These will already be changed into proper
|
||||
// instances of these "InputArgument" and "InputOption" Symfony classes.
|
||||
$this->getDefinition()->addArguments($arguments);
|
||||
$this->getDefinition()->addOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the console command for isolation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function configureIsolation()
|
||||
{
|
||||
$this->getDefinition()->addOption(new InputOption(
|
||||
'isolated',
|
||||
null,
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'Do not run the command if another instance of the command is already running',
|
||||
$this->isolated
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the console command.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return int
|
||||
*/
|
||||
#[\Override]
|
||||
public function run(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$this->output = $output instanceof OutputStyle ? $output : $this->laravel->make(
|
||||
OutputStyle::class, ['input' => $input, 'output' => $output]
|
||||
);
|
||||
|
||||
$this->components = $this->laravel->make(Factory::class, ['output' => $this->output]);
|
||||
|
||||
$this->configurePrompts($input);
|
||||
|
||||
try {
|
||||
return parent::run(
|
||||
$this->input = $input, $this->output
|
||||
);
|
||||
} finally {
|
||||
$this->untrap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
*/
|
||||
#[\Override]
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
if ($this instanceof Isolatable && $this->option('isolated') !== false &&
|
||||
! $this->commandIsolationMutex()->create($this)) {
|
||||
$this->comment(sprintf(
|
||||
'The [%s] command is already running.', $this->getName()
|
||||
));
|
||||
|
||||
return (int) (is_numeric($this->option('isolated'))
|
||||
? $this->option('isolated')
|
||||
: $this->isolatedExitCode);
|
||||
}
|
||||
|
||||
$method = method_exists($this, 'handle') ? 'handle' : '__invoke';
|
||||
|
||||
try {
|
||||
return (int) $this->laravel->call([$this, $method]);
|
||||
} catch (ManuallyFailedException $e) {
|
||||
$this->components->error($e->getMessage());
|
||||
|
||||
return static::FAILURE;
|
||||
} finally {
|
||||
if ($this instanceof Isolatable && $this->option('isolated') !== false) {
|
||||
$this->commandIsolationMutex()->forget($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a command isolation mutex instance for the command.
|
||||
*
|
||||
* @return \Illuminate\Console\CommandMutex
|
||||
*/
|
||||
protected function commandIsolationMutex()
|
||||
{
|
||||
return $this->laravel->bound(CommandMutex::class)
|
||||
? $this->laravel->make(CommandMutex::class)
|
||||
: $this->laravel->make(CacheCommandMutex::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the console command instance for the given command.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Command\Command|string $command
|
||||
* @return \Symfony\Component\Console\Command\Command
|
||||
*/
|
||||
protected function resolveCommand($command)
|
||||
{
|
||||
if (is_string($command)) {
|
||||
if (! class_exists($command)) {
|
||||
return $this->getApplication()->find($command);
|
||||
}
|
||||
|
||||
$command = $this->laravel->make($command);
|
||||
}
|
||||
|
||||
if ($command instanceof SymfonyCommand) {
|
||||
$command->setApplication($this->getApplication());
|
||||
}
|
||||
|
||||
if ($command instanceof self) {
|
||||
$command->setLaravel($this->getLaravel());
|
||||
}
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fail the command manually.
|
||||
*
|
||||
* @param \Throwable|string|null $exception
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Console\ManuallyFailedException|\Throwable
|
||||
*/
|
||||
public function fail(Throwable|string|null $exception = null)
|
||||
{
|
||||
if (is_null($exception)) {
|
||||
$exception = 'Command failed manually.';
|
||||
}
|
||||
|
||||
if (is_string($exception)) {
|
||||
$exception = new ManuallyFailedException($exception);
|
||||
}
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
#[\Override]
|
||||
public function isHidden(): bool
|
||||
{
|
||||
return $this->hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\Override]
|
||||
public function setHidden(bool $hidden = true): static
|
||||
{
|
||||
parent::setHidden($this->hidden = $hidden);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Laravel application instance.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Foundation\Application
|
||||
*/
|
||||
public function getLaravel()
|
||||
{
|
||||
return $this->laravel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Laravel application instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Container\Container $laravel
|
||||
* @return void
|
||||
*/
|
||||
public function setLaravel($laravel)
|
||||
{
|
||||
$this->laravel = $laravel;
|
||||
}
|
||||
}
|
||||
30
vendor/laravel/framework/src/Illuminate/Console/CommandMutex.php
vendored
Normal file
30
vendor/laravel/framework/src/Illuminate/Console/CommandMutex.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
interface CommandMutex
|
||||
{
|
||||
/**
|
||||
* Attempt to obtain a command mutex for the given command.
|
||||
*
|
||||
* @param \Illuminate\Console\Command $command
|
||||
* @return bool
|
||||
*/
|
||||
public function create($command);
|
||||
|
||||
/**
|
||||
* Determine if a command mutex exists for the given command.
|
||||
*
|
||||
* @param \Illuminate\Console\Command $command
|
||||
* @return bool
|
||||
*/
|
||||
public function exists($command);
|
||||
|
||||
/**
|
||||
* Release the mutex for the given command.
|
||||
*
|
||||
* @param \Illuminate\Console\Command $command
|
||||
* @return bool
|
||||
*/
|
||||
public function forget($command);
|
||||
}
|
||||
111
vendor/laravel/framework/src/Illuminate/Console/Concerns/CallsCommands.php
vendored
Normal file
111
vendor/laravel/framework/src/Illuminate/Console/Concerns/CallsCommands.php
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Concerns;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Output\NullOutput;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
trait CallsCommands
|
||||
{
|
||||
/**
|
||||
* Resolve the console command instance for the given command.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Command\Command|string $command
|
||||
* @return \Symfony\Component\Console\Command\Command
|
||||
*/
|
||||
abstract protected function resolveCommand($command);
|
||||
|
||||
/**
|
||||
* Call another console command.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Command\Command|string $command
|
||||
* @param array $arguments
|
||||
* @return int
|
||||
*/
|
||||
public function call($command, array $arguments = [])
|
||||
{
|
||||
return $this->runCommand($command, $arguments, $this->output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call another console command without output.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Command\Command|string $command
|
||||
* @param array $arguments
|
||||
* @return int
|
||||
*/
|
||||
public function callSilent($command, array $arguments = [])
|
||||
{
|
||||
return $this->runCommand($command, $arguments, new NullOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call another console command without output.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Command\Command|string $command
|
||||
* @param array $arguments
|
||||
* @return int
|
||||
*/
|
||||
public function callSilently($command, array $arguments = [])
|
||||
{
|
||||
return $this->callSilent($command, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the given console command.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Command\Command|string $command
|
||||
* @param array $arguments
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return int
|
||||
*/
|
||||
protected function runCommand($command, array $arguments, OutputInterface $output)
|
||||
{
|
||||
$arguments['command'] = $command;
|
||||
|
||||
$result = $this->resolveCommand($command)->run(
|
||||
$this->createInputFromArguments($arguments), $output
|
||||
);
|
||||
|
||||
$this->restorePrompts();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an input instance from the given arguments.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @return \Symfony\Component\Console\Input\ArrayInput
|
||||
*/
|
||||
protected function createInputFromArguments(array $arguments)
|
||||
{
|
||||
return tap(new ArrayInput(array_merge($this->context(), $arguments)), function ($input) {
|
||||
if ($input->getParameterOption('--no-interaction')) {
|
||||
$input->setInteractive(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the context passed to the command.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function context()
|
||||
{
|
||||
return (new Collection($this->option()))
|
||||
->only([
|
||||
'ansi',
|
||||
'no-ansi',
|
||||
'no-interaction',
|
||||
'quiet',
|
||||
'verbose',
|
||||
])
|
||||
->filter()
|
||||
->mapWithKeys(fn ($value, $key) => ["--{$key}" => $value])
|
||||
->all();
|
||||
}
|
||||
}
|
||||
290
vendor/laravel/framework/src/Illuminate/Console/Concerns/ConfiguresPrompts.php
vendored
Normal file
290
vendor/laravel/framework/src/Illuminate/Console/Concerns/ConfiguresPrompts.php
vendored
Normal file
@@ -0,0 +1,290 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Concerns;
|
||||
|
||||
use Illuminate\Console\PromptValidationException;
|
||||
use Laravel\Prompts\ConfirmPrompt;
|
||||
use Laravel\Prompts\MultiSearchPrompt;
|
||||
use Laravel\Prompts\MultiSelectPrompt;
|
||||
use Laravel\Prompts\PasswordPrompt;
|
||||
use Laravel\Prompts\PausePrompt;
|
||||
use Laravel\Prompts\Prompt;
|
||||
use Laravel\Prompts\SearchPrompt;
|
||||
use Laravel\Prompts\SelectPrompt;
|
||||
use Laravel\Prompts\SuggestPrompt;
|
||||
use Laravel\Prompts\TextareaPrompt;
|
||||
use Laravel\Prompts\TextPrompt;
|
||||
use stdClass;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
||||
trait ConfiguresPrompts
|
||||
{
|
||||
/**
|
||||
* Configure the prompt fallbacks.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @return void
|
||||
*/
|
||||
protected function configurePrompts(InputInterface $input)
|
||||
{
|
||||
Prompt::setOutput($this->output);
|
||||
|
||||
Prompt::interactive(($input->isInteractive() && defined('STDIN') && stream_isatty(STDIN)) || $this->laravel->runningUnitTests());
|
||||
|
||||
Prompt::validateUsing(fn (Prompt $prompt) => $this->validatePrompt($prompt->value(), $prompt->validate));
|
||||
|
||||
Prompt::fallbackWhen(windows_os() || $this->laravel->runningUnitTests());
|
||||
|
||||
TextPrompt::fallbackUsing(fn (TextPrompt $prompt) => $this->promptUntilValid(
|
||||
fn () => $this->components->ask($prompt->label, $prompt->default ?: null) ?? '',
|
||||
$prompt->required,
|
||||
$prompt->validate
|
||||
));
|
||||
|
||||
TextareaPrompt::fallbackUsing(fn (TextareaPrompt $prompt) => $this->promptUntilValid(
|
||||
fn () => $this->components->ask($prompt->label, $prompt->default ?: null, multiline: true) ?? '',
|
||||
$prompt->required,
|
||||
$prompt->validate
|
||||
));
|
||||
|
||||
PasswordPrompt::fallbackUsing(fn (PasswordPrompt $prompt) => $this->promptUntilValid(
|
||||
fn () => $this->components->secret($prompt->label) ?? '',
|
||||
$prompt->required,
|
||||
$prompt->validate
|
||||
));
|
||||
|
||||
PausePrompt::fallbackUsing(fn (PausePrompt $prompt) => $this->promptUntilValid(
|
||||
function () use ($prompt) {
|
||||
$this->components->ask($prompt->message, $prompt->value());
|
||||
|
||||
return $prompt->value();
|
||||
},
|
||||
$prompt->required,
|
||||
$prompt->validate
|
||||
));
|
||||
|
||||
ConfirmPrompt::fallbackUsing(fn (ConfirmPrompt $prompt) => $this->promptUntilValid(
|
||||
fn () => $this->components->confirm($prompt->label, $prompt->default),
|
||||
$prompt->required,
|
||||
$prompt->validate
|
||||
));
|
||||
|
||||
SelectPrompt::fallbackUsing(fn (SelectPrompt $prompt) => $this->promptUntilValid(
|
||||
fn () => $this->selectFallback($prompt->label, $prompt->options, $prompt->default),
|
||||
false,
|
||||
$prompt->validate
|
||||
));
|
||||
|
||||
MultiSelectPrompt::fallbackUsing(fn (MultiSelectPrompt $prompt) => $this->promptUntilValid(
|
||||
fn () => $this->multiselectFallback($prompt->label, $prompt->options, $prompt->default, $prompt->required),
|
||||
$prompt->required,
|
||||
$prompt->validate
|
||||
));
|
||||
|
||||
SuggestPrompt::fallbackUsing(fn (SuggestPrompt $prompt) => $this->promptUntilValid(
|
||||
fn () => $this->components->askWithCompletion($prompt->label, $prompt->options, $prompt->default ?: null) ?? '',
|
||||
$prompt->required,
|
||||
$prompt->validate
|
||||
));
|
||||
|
||||
SearchPrompt::fallbackUsing(fn (SearchPrompt $prompt) => $this->promptUntilValid(
|
||||
function () use ($prompt) {
|
||||
$query = $this->components->ask($prompt->label);
|
||||
|
||||
$options = ($prompt->options)($query);
|
||||
|
||||
return $this->selectFallback($prompt->label, $options);
|
||||
},
|
||||
false,
|
||||
$prompt->validate
|
||||
));
|
||||
|
||||
MultiSearchPrompt::fallbackUsing(fn (MultiSearchPrompt $prompt) => $this->promptUntilValid(
|
||||
function () use ($prompt) {
|
||||
$query = $this->components->ask($prompt->label);
|
||||
|
||||
$options = ($prompt->options)($query);
|
||||
|
||||
return $this->multiselectFallback($prompt->label, $options, required: $prompt->required);
|
||||
},
|
||||
$prompt->required,
|
||||
$prompt->validate
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user until the given validation callback passes.
|
||||
*
|
||||
* @param \Closure $prompt
|
||||
* @param bool|string $required
|
||||
* @param \Closure|null $validate
|
||||
* @return mixed
|
||||
*/
|
||||
protected function promptUntilValid($prompt, $required, $validate)
|
||||
{
|
||||
while (true) {
|
||||
$result = $prompt();
|
||||
|
||||
if ($required && ($result === '' || $result === [] || $result === false)) {
|
||||
$this->components->error(is_string($required) ? $required : 'Required.');
|
||||
|
||||
if ($this->laravel->runningUnitTests()) {
|
||||
throw new PromptValidationException;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$error = is_callable($validate) ? $validate($result) : $this->validatePrompt($result, $validate);
|
||||
|
||||
if (is_string($error) && strlen($error) > 0) {
|
||||
$this->components->error($error);
|
||||
|
||||
if ($this->laravel->runningUnitTests()) {
|
||||
throw new PromptValidationException;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the given prompt value using the validator.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param mixed $rules
|
||||
* @return ?string
|
||||
*/
|
||||
protected function validatePrompt($value, $rules)
|
||||
{
|
||||
if ($rules instanceof stdClass) {
|
||||
$messages = $rules->messages ?? [];
|
||||
$attributes = $rules->attributes ?? [];
|
||||
$rules = $rules->rules ?? null;
|
||||
}
|
||||
|
||||
if (! $rules) {
|
||||
return;
|
||||
}
|
||||
|
||||
$field = 'answer';
|
||||
|
||||
if (is_array($rules) && ! array_is_list($rules)) {
|
||||
[$field, $rules] = [key($rules), current($rules)];
|
||||
}
|
||||
|
||||
return $this->getPromptValidatorInstance(
|
||||
$field, $value, $rules, $messages ?? [], $attributes ?? []
|
||||
)->errors()->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validator instance that should be used to validate prompts.
|
||||
*
|
||||
* @param mixed $field
|
||||
* @param mixed $value
|
||||
* @param mixed $rules
|
||||
* @param array $messages
|
||||
* @param array $attributes
|
||||
* @return \Illuminate\Validation\Validator
|
||||
*/
|
||||
protected function getPromptValidatorInstance($field, $value, $rules, array $messages = [], array $attributes = [])
|
||||
{
|
||||
return $this->laravel['validator']->make(
|
||||
[$field => $value],
|
||||
[$field => $rules],
|
||||
empty($messages) ? $this->validationMessages() : $messages,
|
||||
empty($attributes) ? $this->validationAttributes() : $attributes,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation messages that should be used during prompt validation.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function validationMessages()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation attributes that should be used during prompt validation.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function validationAttributes()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the prompts output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function restorePrompts()
|
||||
{
|
||||
Prompt::setOutput($this->output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select fallback.
|
||||
*
|
||||
* @param string $label
|
||||
* @param array $options
|
||||
* @param string|int|null $default
|
||||
* @return string|int
|
||||
*/
|
||||
private function selectFallback($label, $options, $default = null)
|
||||
{
|
||||
$answer = $this->components->choice($label, $options, $default);
|
||||
|
||||
if (! array_is_list($options) && $answer === (string) (int) $answer) {
|
||||
return (int) $answer;
|
||||
}
|
||||
|
||||
return $answer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multi-select fallback.
|
||||
*
|
||||
* @param string $label
|
||||
* @param array $options
|
||||
* @param array $default
|
||||
* @param bool|string $required
|
||||
* @return array
|
||||
*/
|
||||
private function multiselectFallback($label, $options, $default = [], $required = false)
|
||||
{
|
||||
$default = $default !== [] ? implode(',', $default) : null;
|
||||
|
||||
if ($required === false && ! $this->laravel->runningUnitTests()) {
|
||||
$options = array_is_list($options)
|
||||
? ['None', ...$options]
|
||||
: ['' => 'None'] + $options;
|
||||
|
||||
if ($default === null) {
|
||||
$default = 'None';
|
||||
}
|
||||
}
|
||||
|
||||
$answers = $this->components->choice($label, $options, $default, null, true);
|
||||
|
||||
if (! array_is_list($options)) {
|
||||
$answers = array_map(fn ($value) => $value === (string) (int) $value ? (int) $value : $value, $answers);
|
||||
}
|
||||
|
||||
if ($required === false) {
|
||||
return array_is_list($options)
|
||||
? array_values(array_filter($answers, fn ($value) => $value !== 'None'))
|
||||
: array_filter($answers, fn ($value) => $value !== '');
|
||||
}
|
||||
|
||||
return $answers;
|
||||
}
|
||||
}
|
||||
45
vendor/laravel/framework/src/Illuminate/Console/Concerns/CreatesMatchingTest.php
vendored
Normal file
45
vendor/laravel/framework/src/Illuminate/Console/Concerns/CreatesMatchingTest.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Concerns;
|
||||
|
||||
use Illuminate\Support\Stringable;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
trait CreatesMatchingTest
|
||||
{
|
||||
/**
|
||||
* Add the standard command options for generating matching tests.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function addTestOptions()
|
||||
{
|
||||
foreach (['test' => 'Test', 'pest' => 'Pest', 'phpunit' => 'PHPUnit'] as $option => $name) {
|
||||
$this->getDefinition()->addOption(new InputOption(
|
||||
$option,
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
"Generate an accompanying {$name} test for the {$this->type}"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the matching test case if requested.
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
protected function handleTestCreation($path)
|
||||
{
|
||||
if (! $this->option('test') && ! $this->option('pest') && ! $this->option('phpunit')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->call('make:test', [
|
||||
'name' => (new Stringable($path))->after($this->laravel['path'])->beforeLast('.php')->append('Test')->replace('\\', '/'),
|
||||
'--pest' => $this->option('pest'),
|
||||
'--phpunit' => $this->option('phpunit'),
|
||||
]) == 0;
|
||||
}
|
||||
}
|
||||
56
vendor/laravel/framework/src/Illuminate/Console/Concerns/HasParameters.php
vendored
Normal file
56
vendor/laravel/framework/src/Illuminate/Console/Concerns/HasParameters.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Concerns;
|
||||
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
trait HasParameters
|
||||
{
|
||||
/**
|
||||
* Specify the arguments and options on the command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function specifyParameters()
|
||||
{
|
||||
// We will loop through all of the arguments and options for the command and
|
||||
// set them all on the base command instance. This specifies what can get
|
||||
// passed into these commands as "parameters" to control the execution.
|
||||
foreach ($this->getArguments() as $arguments) {
|
||||
if ($arguments instanceof InputArgument) {
|
||||
$this->getDefinition()->addArgument($arguments);
|
||||
} else {
|
||||
$this->addArgument(...$arguments);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->getOptions() as $options) {
|
||||
if ($options instanceof InputOption) {
|
||||
$this->getDefinition()->addOption($options);
|
||||
} else {
|
||||
$this->addOption(...$options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command arguments.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getArguments()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
463
vendor/laravel/framework/src/Illuminate/Console/Concerns/InteractsWithIO.php
vendored
Normal file
463
vendor/laravel/framework/src/Illuminate/Console/Concerns/InteractsWithIO.php
vendored
Normal file
@@ -0,0 +1,463 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Concerns;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Console\OutputStyle;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
|
||||
trait InteractsWithIO
|
||||
{
|
||||
/**
|
||||
* The console components factory.
|
||||
*
|
||||
* @var \Illuminate\Console\View\Components\Factory
|
||||
*
|
||||
* @internal This property is not meant to be used or overwritten outside the framework.
|
||||
*/
|
||||
protected $components;
|
||||
|
||||
/**
|
||||
* The input interface implementation.
|
||||
*
|
||||
* @var \Symfony\Component\Console\Input\InputInterface
|
||||
*/
|
||||
protected $input;
|
||||
|
||||
/**
|
||||
* The output interface implementation.
|
||||
*
|
||||
* @var \Illuminate\Console\OutputStyle
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* The default verbosity of output commands.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $verbosity = OutputInterface::VERBOSITY_NORMAL;
|
||||
|
||||
/**
|
||||
* The mapping between human readable verbosity levels and Symfony's OutputInterface.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $verbosityMap = [
|
||||
'v' => OutputInterface::VERBOSITY_VERBOSE,
|
||||
'vv' => OutputInterface::VERBOSITY_VERY_VERBOSE,
|
||||
'vvv' => OutputInterface::VERBOSITY_DEBUG,
|
||||
'quiet' => OutputInterface::VERBOSITY_QUIET,
|
||||
'normal' => OutputInterface::VERBOSITY_NORMAL,
|
||||
];
|
||||
|
||||
/**
|
||||
* Determine if the given argument is present.
|
||||
*
|
||||
* @param string|int $name
|
||||
* @return bool
|
||||
*/
|
||||
public function hasArgument($name)
|
||||
{
|
||||
return $this->input->hasArgument($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a command argument.
|
||||
*
|
||||
* @param string|null $key
|
||||
* @return array|string|bool|null
|
||||
*/
|
||||
public function argument($key = null)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
return $this->input->getArguments();
|
||||
}
|
||||
|
||||
return $this->input->getArgument($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the arguments passed to the command.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function arguments()
|
||||
{
|
||||
return $this->argument();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given option is present.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function hasOption($name)
|
||||
{
|
||||
return $this->input->hasOption($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a command option.
|
||||
*
|
||||
* @param string|null $key
|
||||
* @return string|array|bool|null
|
||||
*/
|
||||
public function option($key = null)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
return $this->input->getOptions();
|
||||
}
|
||||
|
||||
return $this->input->getOption($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the options passed to the command.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function options()
|
||||
{
|
||||
return $this->option();
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm a question with the user.
|
||||
*
|
||||
* @param string $question
|
||||
* @param bool $default
|
||||
* @return bool
|
||||
*/
|
||||
public function confirm($question, $default = false)
|
||||
{
|
||||
return $this->output->confirm($question, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for input.
|
||||
*
|
||||
* @param string $question
|
||||
* @param string|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function ask($question, $default = null)
|
||||
{
|
||||
return $this->output->ask($question, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for input with auto completion.
|
||||
*
|
||||
* @param string $question
|
||||
* @param array|callable $choices
|
||||
* @param string|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function anticipate($question, $choices, $default = null)
|
||||
{
|
||||
return $this->askWithCompletion($question, $choices, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for input with auto completion.
|
||||
*
|
||||
* @param string $question
|
||||
* @param array|callable $choices
|
||||
* @param string|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function askWithCompletion($question, $choices, $default = null)
|
||||
{
|
||||
$question = new Question($question, $default);
|
||||
|
||||
is_callable($choices)
|
||||
? $question->setAutocompleterCallback($choices)
|
||||
: $question->setAutocompleterValues($choices);
|
||||
|
||||
return $this->output->askQuestion($question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for input but hide the answer from the console.
|
||||
*
|
||||
* @param string $question
|
||||
* @param bool $fallback
|
||||
* @return mixed
|
||||
*/
|
||||
public function secret($question, $fallback = true)
|
||||
{
|
||||
$question = new Question($question);
|
||||
|
||||
$question->setHidden(true)->setHiddenFallback($fallback);
|
||||
|
||||
return $this->output->askQuestion($question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the user a single choice from an array of answers.
|
||||
*
|
||||
* @param string $question
|
||||
* @param array $choices
|
||||
* @param string|int|null $default
|
||||
* @param mixed|null $attempts
|
||||
* @param bool $multiple
|
||||
* @return string|array
|
||||
*/
|
||||
public function choice($question, array $choices, $default = null, $attempts = null, $multiple = false)
|
||||
{
|
||||
$question = new ChoiceQuestion($question, $choices, $default);
|
||||
|
||||
$question->setMaxAttempts($attempts)->setMultiselect($multiple);
|
||||
|
||||
return $this->output->askQuestion($question);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format input to textual table.
|
||||
*
|
||||
* @param array $headers
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|array $rows
|
||||
* @param \Symfony\Component\Console\Helper\TableStyle|string $tableStyle
|
||||
* @param array $columnStyles
|
||||
* @return void
|
||||
*/
|
||||
public function table($headers, $rows, $tableStyle = 'default', array $columnStyles = [])
|
||||
{
|
||||
$table = new Table($this->output);
|
||||
|
||||
if ($rows instanceof Arrayable) {
|
||||
$rows = $rows->toArray();
|
||||
}
|
||||
|
||||
$table->setHeaders((array) $headers)->setRows($rows)->setStyle($tableStyle);
|
||||
|
||||
foreach ($columnStyles as $columnIndex => $columnStyle) {
|
||||
$table->setColumnStyle($columnIndex, $columnStyle);
|
||||
}
|
||||
|
||||
$table->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a given callback while advancing a progress bar.
|
||||
*
|
||||
* @param iterable|int $totalSteps
|
||||
* @param \Closure $callback
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function withProgressBar($totalSteps, Closure $callback)
|
||||
{
|
||||
$bar = $this->output->createProgressBar(
|
||||
is_iterable($totalSteps) ? count($totalSteps) : $totalSteps
|
||||
);
|
||||
|
||||
$bar->start();
|
||||
|
||||
if (is_iterable($totalSteps)) {
|
||||
foreach ($totalSteps as $key => $value) {
|
||||
$callback($value, $bar, $key);
|
||||
|
||||
$bar->advance();
|
||||
}
|
||||
} else {
|
||||
$callback($bar);
|
||||
}
|
||||
|
||||
$bar->finish();
|
||||
|
||||
if (is_iterable($totalSteps)) {
|
||||
return $totalSteps;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as information output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function info($string, $verbosity = null)
|
||||
{
|
||||
$this->line($string, 'info', $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as standard output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string|null $style
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function line($string, $style = null, $verbosity = null)
|
||||
{
|
||||
$styled = $style ? "<$style>$string</$style>" : $string;
|
||||
|
||||
$this->output->writeln($styled, $this->parseVerbosity($verbosity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as comment output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function comment($string, $verbosity = null)
|
||||
{
|
||||
$this->line($string, 'comment', $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as question output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function question($string, $verbosity = null)
|
||||
{
|
||||
$this->line($string, 'question', $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as error output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function error($string, $verbosity = null)
|
||||
{
|
||||
$this->line($string, 'error', $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string as warning output.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function warn($string, $verbosity = null)
|
||||
{
|
||||
if (! $this->output->getFormatter()->hasStyle('warning')) {
|
||||
$style = new OutputFormatterStyle('yellow');
|
||||
|
||||
$this->output->getFormatter()->setStyle('warning', $style);
|
||||
}
|
||||
|
||||
$this->line($string, 'warning', $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string in an alert box.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int|string|null $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function alert($string, $verbosity = null)
|
||||
{
|
||||
$length = Str::length(strip_tags($string)) + 12;
|
||||
|
||||
$this->comment(str_repeat('*', $length), $verbosity);
|
||||
$this->comment('* '.$string.' *', $verbosity);
|
||||
$this->comment(str_repeat('*', $length), $verbosity);
|
||||
|
||||
$this->comment('', $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a blank line.
|
||||
*
|
||||
* @param int $count
|
||||
* @return $this
|
||||
*/
|
||||
public function newLine($count = 1)
|
||||
{
|
||||
$this->output->newLine($count);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the input interface implementation.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @return void
|
||||
*/
|
||||
public function setInput(InputInterface $input)
|
||||
{
|
||||
$this->input = $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the output interface implementation.
|
||||
*
|
||||
* @param \Illuminate\Console\OutputStyle $output
|
||||
* @return void
|
||||
*/
|
||||
public function setOutput(OutputStyle $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the verbosity level.
|
||||
*
|
||||
* @param string|int $level
|
||||
* @return void
|
||||
*/
|
||||
protected function setVerbosity($level)
|
||||
{
|
||||
$this->verbosity = $this->parseVerbosity($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the verbosity level in terms of Symfony's OutputInterface level.
|
||||
*
|
||||
* @param string|int|null $level
|
||||
* @return int
|
||||
*/
|
||||
protected function parseVerbosity($level = null)
|
||||
{
|
||||
if (isset($this->verbosityMap[$level])) {
|
||||
$level = $this->verbosityMap[$level];
|
||||
} elseif (! is_int($level)) {
|
||||
$level = $this->verbosity;
|
||||
}
|
||||
|
||||
return $level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the output implementation.
|
||||
*
|
||||
* @return \Illuminate\Console\OutputStyle
|
||||
*/
|
||||
public function getOutput()
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the output component factory implementation.
|
||||
*
|
||||
* @return \Illuminate\Console\View\Components\Factory
|
||||
*/
|
||||
public function outputComponents()
|
||||
{
|
||||
return $this->components;
|
||||
}
|
||||
}
|
||||
53
vendor/laravel/framework/src/Illuminate/Console/Concerns/InteractsWithSignals.php
vendored
Normal file
53
vendor/laravel/framework/src/Illuminate/Console/Concerns/InteractsWithSignals.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Concerns;
|
||||
|
||||
use Illuminate\Console\Signals;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
trait InteractsWithSignals
|
||||
{
|
||||
/**
|
||||
* The signal registrar instance.
|
||||
*
|
||||
* @var \Illuminate\Console\Signals|null
|
||||
*/
|
||||
protected $signals;
|
||||
|
||||
/**
|
||||
* Define a callback to be run when the given signal(s) occurs.
|
||||
*
|
||||
* @template TSignals of iterable<array-key, int>|int
|
||||
*
|
||||
* @param (\Closure():(TSignals))|TSignals $signals
|
||||
* @param callable(int $signal): void $callback
|
||||
* @return void
|
||||
*/
|
||||
public function trap($signals, $callback)
|
||||
{
|
||||
Signals::whenAvailable(function () use ($signals, $callback) {
|
||||
$this->signals ??= new Signals(
|
||||
$this->getApplication()->getSignalRegistry(),
|
||||
);
|
||||
|
||||
Collection::wrap(value($signals))
|
||||
->each(fn ($signal) => $this->signals->register($signal, $callback));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Untrap signal handlers set within the command's handler.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function untrap()
|
||||
{
|
||||
if (! is_null($this->signals)) {
|
||||
$this->signals->unregister();
|
||||
|
||||
$this->signals = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
109
vendor/laravel/framework/src/Illuminate/Console/Concerns/PromptsForMissingInput.php
vendored
Normal file
109
vendor/laravel/framework/src/Illuminate/Console/Concerns/PromptsForMissingInput.php
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Concerns;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Console\PromptsForMissingInput as PromptsForMissingInputContract;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use function Laravel\Prompts\text;
|
||||
|
||||
trait PromptsForMissingInput
|
||||
{
|
||||
/**
|
||||
* Interact with the user before validating the input.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return void
|
||||
*/
|
||||
protected function interact(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
parent::interact($input, $output);
|
||||
|
||||
if ($this instanceof PromptsForMissingInputContract) {
|
||||
$this->promptForMissingArguments($input, $output);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for any missing arguments.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return void
|
||||
*/
|
||||
protected function promptForMissingArguments(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$prompted = (new Collection($this->getDefinition()->getArguments()))
|
||||
->reject(fn (InputArgument $argument) => $argument->getName() === 'command')
|
||||
->filter(fn (InputArgument $argument) => $argument->isRequired() && match (true) {
|
||||
$argument->isArray() => empty($input->getArgument($argument->getName())),
|
||||
default => is_null($input->getArgument($argument->getName())),
|
||||
})
|
||||
->each(function (InputArgument $argument) use ($input) {
|
||||
$label = $this->promptForMissingArgumentsUsing()[$argument->getName()] ??
|
||||
'What is '.lcfirst($argument->getDescription() ?: ('the '.$argument->getName())).'?';
|
||||
|
||||
if ($label instanceof Closure) {
|
||||
return $input->setArgument($argument->getName(), $argument->isArray() ? Arr::wrap($label()) : $label());
|
||||
}
|
||||
|
||||
if (is_array($label)) {
|
||||
[$label, $placeholder] = $label;
|
||||
}
|
||||
|
||||
$answer = text(
|
||||
label: $label,
|
||||
placeholder: $placeholder ?? '',
|
||||
validate: fn ($value) => empty($value) ? "The {$argument->getName()} is required." : null,
|
||||
);
|
||||
|
||||
$input->setArgument($argument->getName(), $argument->isArray() ? [$answer] : $answer);
|
||||
})
|
||||
->isNotEmpty();
|
||||
|
||||
if ($prompted) {
|
||||
$this->afterPromptingForMissingArguments($input, $output);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt for missing input arguments using the returned questions.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function promptForMissingArgumentsUsing()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform actions after the user was prompted for missing arguments.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return void
|
||||
*/
|
||||
protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the input contains any options that differ from the default values.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @return bool
|
||||
*/
|
||||
protected function didReceiveOptions(InputInterface $input)
|
||||
{
|
||||
return (new Collection($this->getDefinition()->getOptions()))
|
||||
->reject(fn ($option) => $input->getOption($option->getName()) === $option->getDefault())
|
||||
->isNotEmpty();
|
||||
}
|
||||
}
|
||||
54
vendor/laravel/framework/src/Illuminate/Console/ConfirmableTrait.php
vendored
Normal file
54
vendor/laravel/framework/src/Illuminate/Console/ConfirmableTrait.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use function Laravel\Prompts\confirm;
|
||||
|
||||
trait ConfirmableTrait
|
||||
{
|
||||
/**
|
||||
* Confirm before proceeding with the action.
|
||||
*
|
||||
* This method only asks for confirmation in production.
|
||||
*
|
||||
* @param string $warning
|
||||
* @param \Closure|bool|null $callback
|
||||
* @return bool
|
||||
*/
|
||||
public function confirmToProceed($warning = 'Application In Production', $callback = null)
|
||||
{
|
||||
$callback = is_null($callback) ? $this->getDefaultConfirmCallback() : $callback;
|
||||
|
||||
$shouldConfirm = value($callback);
|
||||
|
||||
if ($shouldConfirm) {
|
||||
if ($this->hasOption('force') && $this->option('force')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->components->alert($warning);
|
||||
|
||||
$confirmed = confirm('Are you sure you want to run this command?', default: false);
|
||||
|
||||
if (! $confirmed) {
|
||||
$this->components->warn('Command cancelled.');
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default confirmation callback.
|
||||
*
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function getDefaultConfirmCallback()
|
||||
{
|
||||
return function () {
|
||||
return $this->getLaravel()->environment() === 'production';
|
||||
};
|
||||
}
|
||||
}
|
||||
76
vendor/laravel/framework/src/Illuminate/Console/ContainerCommandLoader.php
vendored
Normal file
76
vendor/laravel/framework/src/Illuminate/Console/ContainerCommandLoader.php
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\CommandLoader\CommandLoaderInterface;
|
||||
use Symfony\Component\Console\Exception\CommandNotFoundException;
|
||||
|
||||
class ContainerCommandLoader implements CommandLoaderInterface
|
||||
{
|
||||
/**
|
||||
* The container instance.
|
||||
*
|
||||
* @var \Psr\Container\ContainerInterface
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* A map of command names to classes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $commandMap;
|
||||
|
||||
/**
|
||||
* Create a new command loader instance.
|
||||
*
|
||||
* @param \Psr\Container\ContainerInterface $container
|
||||
* @param array $commandMap
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(ContainerInterface $container, array $commandMap)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->commandMap = $commandMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a command from the container.
|
||||
*
|
||||
* @param string $name
|
||||
* @return \Symfony\Component\Console\Command\Command
|
||||
*
|
||||
* @throws \Symfony\Component\Console\Exception\CommandNotFoundException
|
||||
*/
|
||||
public function get(string $name): Command
|
||||
{
|
||||
if (! $this->has($name)) {
|
||||
throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name));
|
||||
}
|
||||
|
||||
return $this->container->get($this->commandMap[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a command exists.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function has(string $name): bool
|
||||
{
|
||||
return $name && isset($this->commandMap[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the command names.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNames(): array
|
||||
{
|
||||
return array_keys($this->commandMap);
|
||||
}
|
||||
}
|
||||
22
vendor/laravel/framework/src/Illuminate/Console/Contracts/NewLineAware.php
vendored
Normal file
22
vendor/laravel/framework/src/Illuminate/Console/Contracts/NewLineAware.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Contracts;
|
||||
|
||||
interface NewLineAware
|
||||
{
|
||||
/**
|
||||
* How many trailing newlines were written.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function newLinesWritten();
|
||||
|
||||
/**
|
||||
* Whether a newline has already been written.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated use newLinesWritten
|
||||
*/
|
||||
public function newLineWritten();
|
||||
}
|
||||
24
vendor/laravel/framework/src/Illuminate/Console/Events/ArtisanStarting.php
vendored
Normal file
24
vendor/laravel/framework/src/Illuminate/Console/Events/ArtisanStarting.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Events;
|
||||
|
||||
class ArtisanStarting
|
||||
{
|
||||
/**
|
||||
* The Artisan application instance.
|
||||
*
|
||||
* @var \Illuminate\Console\Application
|
||||
*/
|
||||
public $artisan;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \Illuminate\Console\Application $artisan
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($artisan)
|
||||
{
|
||||
$this->artisan = $artisan;
|
||||
}
|
||||
}
|
||||
54
vendor/laravel/framework/src/Illuminate/Console/Events/CommandFinished.php
vendored
Normal file
54
vendor/laravel/framework/src/Illuminate/Console/Events/CommandFinished.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Events;
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class CommandFinished
|
||||
{
|
||||
/**
|
||||
* The command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $command;
|
||||
|
||||
/**
|
||||
* The console input implementation.
|
||||
*
|
||||
* @var \Symfony\Component\Console\Input\InputInterface|null
|
||||
*/
|
||||
public $input;
|
||||
|
||||
/**
|
||||
* The command output implementation.
|
||||
*
|
||||
* @var \Symfony\Component\Console\Output\OutputInterface|null
|
||||
*/
|
||||
public $output;
|
||||
|
||||
/**
|
||||
* The command exit code.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $exitCode;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param string $command
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @param int $exitCode
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($command, InputInterface $input, OutputInterface $output, $exitCode)
|
||||
{
|
||||
$this->input = $input;
|
||||
$this->output = $output;
|
||||
$this->command = $command;
|
||||
$this->exitCode = $exitCode;
|
||||
}
|
||||
}
|
||||
45
vendor/laravel/framework/src/Illuminate/Console/Events/CommandStarting.php
vendored
Normal file
45
vendor/laravel/framework/src/Illuminate/Console/Events/CommandStarting.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Events;
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class CommandStarting
|
||||
{
|
||||
/**
|
||||
* The command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $command;
|
||||
|
||||
/**
|
||||
* The console input implementation.
|
||||
*
|
||||
* @var \Symfony\Component\Console\Input\InputInterface|null
|
||||
*/
|
||||
public $input;
|
||||
|
||||
/**
|
||||
* The command output implementation.
|
||||
*
|
||||
* @var \Symfony\Component\Console\Output\OutputInterface|null
|
||||
*/
|
||||
public $output;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param string $command
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($command, InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->input = $input;
|
||||
$this->output = $output;
|
||||
$this->command = $command;
|
||||
}
|
||||
}
|
||||
26
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledBackgroundTaskFinished.php
vendored
Normal file
26
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledBackgroundTaskFinished.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Events;
|
||||
|
||||
use Illuminate\Console\Scheduling\Event;
|
||||
|
||||
class ScheduledBackgroundTaskFinished
|
||||
{
|
||||
/**
|
||||
* The scheduled event that ran.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\Event
|
||||
*/
|
||||
public $task;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $task
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Event $task)
|
||||
{
|
||||
$this->task = $task;
|
||||
}
|
||||
}
|
||||
36
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskFailed.php
vendored
Normal file
36
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskFailed.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Events;
|
||||
|
||||
use Illuminate\Console\Scheduling\Event;
|
||||
use Throwable;
|
||||
|
||||
class ScheduledTaskFailed
|
||||
{
|
||||
/**
|
||||
* The scheduled event that failed.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\Event
|
||||
*/
|
||||
public $task;
|
||||
|
||||
/**
|
||||
* The exception that was thrown.
|
||||
*
|
||||
* @var \Throwable
|
||||
*/
|
||||
public $exception;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $task
|
||||
* @param \Throwable $exception
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Event $task, Throwable $exception)
|
||||
{
|
||||
$this->task = $task;
|
||||
$this->exception = $exception;
|
||||
}
|
||||
}
|
||||
35
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskFinished.php
vendored
Normal file
35
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskFinished.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Events;
|
||||
|
||||
use Illuminate\Console\Scheduling\Event;
|
||||
|
||||
class ScheduledTaskFinished
|
||||
{
|
||||
/**
|
||||
* The scheduled event that ran.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\Event
|
||||
*/
|
||||
public $task;
|
||||
|
||||
/**
|
||||
* The runtime of the scheduled event.
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $runtime;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $task
|
||||
* @param float $runtime
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Event $task, $runtime)
|
||||
{
|
||||
$this->task = $task;
|
||||
$this->runtime = $runtime;
|
||||
}
|
||||
}
|
||||
26
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskSkipped.php
vendored
Normal file
26
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskSkipped.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Events;
|
||||
|
||||
use Illuminate\Console\Scheduling\Event;
|
||||
|
||||
class ScheduledTaskSkipped
|
||||
{
|
||||
/**
|
||||
* The scheduled event being run.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\Event
|
||||
*/
|
||||
public $task;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $task
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Event $task)
|
||||
{
|
||||
$this->task = $task;
|
||||
}
|
||||
}
|
||||
26
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskStarting.php
vendored
Normal file
26
vendor/laravel/framework/src/Illuminate/Console/Events/ScheduledTaskStarting.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Events;
|
||||
|
||||
use Illuminate\Console\Scheduling\Event;
|
||||
|
||||
class ScheduledTaskStarting
|
||||
{
|
||||
/**
|
||||
* The scheduled event being run.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\Event
|
||||
*/
|
||||
public $task;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $task
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Event $task)
|
||||
{
|
||||
$this->task = $task;
|
||||
}
|
||||
}
|
||||
534
vendor/laravel/framework/src/Illuminate/Console/GeneratorCommand.php
vendored
Normal file
534
vendor/laravel/framework/src/Illuminate/Console/GeneratorCommand.php
vendored
Normal file
@@ -0,0 +1,534 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Illuminate\Console\Concerns\CreatesMatchingTest;
|
||||
use Illuminate\Contracts\Console\PromptsForMissingInput;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
abstract class GeneratorCommand extends Command implements PromptsForMissingInput
|
||||
{
|
||||
/**
|
||||
* The filesystem instance.
|
||||
*
|
||||
* @var \Illuminate\Filesystem\Filesystem
|
||||
*/
|
||||
protected $files;
|
||||
|
||||
/**
|
||||
* The type of class being generated.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* Reserved names that cannot be used for generation.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $reservedNames = [
|
||||
'__halt_compiler',
|
||||
'abstract',
|
||||
'and',
|
||||
'array',
|
||||
'as',
|
||||
'break',
|
||||
'callable',
|
||||
'case',
|
||||
'catch',
|
||||
'class',
|
||||
'clone',
|
||||
'const',
|
||||
'continue',
|
||||
'declare',
|
||||
'default',
|
||||
'die',
|
||||
'do',
|
||||
'echo',
|
||||
'else',
|
||||
'elseif',
|
||||
'empty',
|
||||
'enddeclare',
|
||||
'endfor',
|
||||
'endforeach',
|
||||
'endif',
|
||||
'endswitch',
|
||||
'endwhile',
|
||||
'enum',
|
||||
'eval',
|
||||
'exit',
|
||||
'extends',
|
||||
'false',
|
||||
'final',
|
||||
'finally',
|
||||
'fn',
|
||||
'for',
|
||||
'foreach',
|
||||
'function',
|
||||
'global',
|
||||
'goto',
|
||||
'if',
|
||||
'implements',
|
||||
'include',
|
||||
'include_once',
|
||||
'instanceof',
|
||||
'insteadof',
|
||||
'interface',
|
||||
'isset',
|
||||
'list',
|
||||
'match',
|
||||
'namespace',
|
||||
'new',
|
||||
'or',
|
||||
'parent',
|
||||
'print',
|
||||
'private',
|
||||
'protected',
|
||||
'public',
|
||||
'readonly',
|
||||
'require',
|
||||
'require_once',
|
||||
'return',
|
||||
'self',
|
||||
'static',
|
||||
'switch',
|
||||
'throw',
|
||||
'trait',
|
||||
'true',
|
||||
'try',
|
||||
'unset',
|
||||
'use',
|
||||
'var',
|
||||
'while',
|
||||
'xor',
|
||||
'yield',
|
||||
'__CLASS__',
|
||||
'__DIR__',
|
||||
'__FILE__',
|
||||
'__FUNCTION__',
|
||||
'__LINE__',
|
||||
'__METHOD__',
|
||||
'__NAMESPACE__',
|
||||
'__TRAIT__',
|
||||
];
|
||||
|
||||
/**
|
||||
* Create a new generator command instance.
|
||||
*
|
||||
* @param \Illuminate\Filesystem\Filesystem $files
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Filesystem $files)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
if (in_array(CreatesMatchingTest::class, class_uses_recursive($this))) {
|
||||
$this->addTestOptions();
|
||||
}
|
||||
|
||||
$this->files = $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stub file for the generator.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getStub();
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return bool|null
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// First we need to ensure that the given name is not a reserved word within the PHP
|
||||
// language and that the class name will actually be valid. If it is not valid we
|
||||
// can error now and prevent from polluting the filesystem using invalid files.
|
||||
if ($this->isReservedName($this->getNameInput())) {
|
||||
$this->components->error('The name "'.$this->getNameInput().'" is reserved by PHP.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$name = $this->qualifyClass($this->getNameInput());
|
||||
|
||||
$path = $this->getPath($name);
|
||||
|
||||
// Next, We will check to see if the class already exists. If it does, we don't want
|
||||
// to create the class and overwrite the user's code. So, we will bail out so the
|
||||
// code is untouched. Otherwise, we will continue generating this class' files.
|
||||
if ((! $this->hasOption('force') ||
|
||||
! $this->option('force')) &&
|
||||
$this->alreadyExists($this->getNameInput())) {
|
||||
$this->components->error($this->type.' already exists.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Next, we will generate the path to the location where this class' file should get
|
||||
// written. Then, we will build the class and make the proper replacements on the
|
||||
// stub files so that it gets the correctly formatted namespace and class name.
|
||||
$this->makeDirectory($path);
|
||||
|
||||
$this->files->put($path, $this->sortImports($this->buildClass($name)));
|
||||
|
||||
$info = $this->type;
|
||||
|
||||
if (in_array(CreatesMatchingTest::class, class_uses_recursive($this))) {
|
||||
$this->handleTestCreation($path);
|
||||
}
|
||||
|
||||
if (windows_os()) {
|
||||
$path = str_replace('/', '\\', $path);
|
||||
}
|
||||
|
||||
$this->components->info(sprintf('%s [%s] created successfully.', $info, $path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the class name and format according to the root namespace.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function qualifyClass($name)
|
||||
{
|
||||
$name = ltrim($name, '\\/');
|
||||
|
||||
$name = str_replace('/', '\\', $name);
|
||||
|
||||
$rootNamespace = $this->rootNamespace();
|
||||
|
||||
if (Str::startsWith($name, $rootNamespace)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return $this->qualifyClass(
|
||||
$this->getDefaultNamespace(trim($rootNamespace, '\\')).'\\'.$name
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Qualify the given model class base name.
|
||||
*
|
||||
* @param string $model
|
||||
* @return string
|
||||
*/
|
||||
protected function qualifyModel(string $model)
|
||||
{
|
||||
$model = ltrim($model, '\\/');
|
||||
|
||||
$model = str_replace('/', '\\', $model);
|
||||
|
||||
$rootNamespace = $this->rootNamespace();
|
||||
|
||||
if (Str::startsWith($model, $rootNamespace)) {
|
||||
return $model;
|
||||
}
|
||||
|
||||
return is_dir(app_path('Models'))
|
||||
? $rootNamespace.'Models\\'.$model
|
||||
: $rootNamespace.$model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of possible model names.
|
||||
*
|
||||
* @return array<int, string>
|
||||
*/
|
||||
protected function possibleModels()
|
||||
{
|
||||
$modelPath = is_dir(app_path('Models')) ? app_path('Models') : app_path();
|
||||
|
||||
return (new Collection(Finder::create()->files()->depth(0)->in($modelPath)))
|
||||
->map(fn ($file) => $file->getBasename('.php'))
|
||||
->sort()
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of possible event names.
|
||||
*
|
||||
* @return array<int, string>
|
||||
*/
|
||||
protected function possibleEvents()
|
||||
{
|
||||
$eventPath = app_path('Events');
|
||||
|
||||
if (! is_dir($eventPath)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return (new Collection(Finder::create()->files()->depth(0)->in($eventPath)))
|
||||
->map(fn ($file) => $file->getBasename('.php'))
|
||||
->sort()
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default namespace for the class.
|
||||
*
|
||||
* @param string $rootNamespace
|
||||
* @return string
|
||||
*/
|
||||
protected function getDefaultNamespace($rootNamespace)
|
||||
{
|
||||
return $rootNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the class already exists.
|
||||
*
|
||||
* @param string $rawName
|
||||
* @return bool
|
||||
*/
|
||||
protected function alreadyExists($rawName)
|
||||
{
|
||||
return $this->files->exists($this->getPath($this->qualifyClass($rawName)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the destination class path.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function getPath($name)
|
||||
{
|
||||
$name = Str::replaceFirst($this->rootNamespace(), '', $name);
|
||||
|
||||
return $this->laravel['path'].'/'.str_replace('\\', '/', $name).'.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the directory for the class if necessary.
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
protected function makeDirectory($path)
|
||||
{
|
||||
if (! $this->files->isDirectory(dirname($path))) {
|
||||
$this->files->makeDirectory(dirname($path), 0777, true, true);
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the class with the given name.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
|
||||
*/
|
||||
protected function buildClass($name)
|
||||
{
|
||||
$stub = $this->files->get($this->getStub());
|
||||
|
||||
return $this->replaceNamespace($stub, $name)->replaceClass($stub, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the namespace for the given stub.
|
||||
*
|
||||
* @param string $stub
|
||||
* @param string $name
|
||||
* @return $this
|
||||
*/
|
||||
protected function replaceNamespace(&$stub, $name)
|
||||
{
|
||||
$searches = [
|
||||
['DummyNamespace', 'DummyRootNamespace', 'NamespacedDummyUserModel'],
|
||||
['{{ namespace }}', '{{ rootNamespace }}', '{{ namespacedUserModel }}'],
|
||||
['{{namespace}}', '{{rootNamespace}}', '{{namespacedUserModel}}'],
|
||||
];
|
||||
|
||||
foreach ($searches as $search) {
|
||||
$stub = str_replace(
|
||||
$search,
|
||||
[$this->getNamespace($name), $this->rootNamespace(), $this->userProviderModel()],
|
||||
$stub
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full namespace for a given class, without the class name.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function getNamespace($name)
|
||||
{
|
||||
return trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the class name for the given stub.
|
||||
*
|
||||
* @param string $stub
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function replaceClass($stub, $name)
|
||||
{
|
||||
$class = str_replace($this->getNamespace($name).'\\', '', $name);
|
||||
|
||||
return str_replace(['DummyClass', '{{ class }}', '{{class}}'], $class, $stub);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alphabetically sorts the imports for the given stub.
|
||||
*
|
||||
* @param string $stub
|
||||
* @return string
|
||||
*/
|
||||
protected function sortImports($stub)
|
||||
{
|
||||
if (preg_match('/(?P<imports>(?:^use [^;{]+;$\n?)+)/m', $stub, $match)) {
|
||||
$imports = explode("\n", trim($match['imports']));
|
||||
|
||||
sort($imports);
|
||||
|
||||
return str_replace(trim($match['imports']), implode("\n", $imports), $stub);
|
||||
}
|
||||
|
||||
return $stub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the desired class name from the input.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getNameInput()
|
||||
{
|
||||
$name = trim($this->argument('name'));
|
||||
|
||||
if (Str::endsWith($name, '.php')) {
|
||||
return Str::substr($name, 0, -4);
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the root namespace for the class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function rootNamespace()
|
||||
{
|
||||
return $this->laravel->getNamespace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the model for the default guard's user provider.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function userProviderModel()
|
||||
{
|
||||
$config = $this->laravel['config'];
|
||||
|
||||
$provider = $config->get('auth.guards.'.$config->get('auth.defaults.guard').'.provider');
|
||||
|
||||
return $config->get("auth.providers.{$provider}.model");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given name is reserved.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
protected function isReservedName($name)
|
||||
{
|
||||
return in_array(
|
||||
strtolower($name),
|
||||
(new Collection($this->reservedNames))
|
||||
->transform(fn ($name) => strtolower($name))
|
||||
->all()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first view directory path from the application configuration.
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
protected function viewPath($path = '')
|
||||
{
|
||||
$views = $this->laravel['config']['view.paths'][0] ?? resource_path('views');
|
||||
|
||||
return $views.($path ? DIRECTORY_SEPARATOR.$path : $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command arguments.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getArguments()
|
||||
{
|
||||
return [
|
||||
['name', InputArgument::REQUIRED, 'The name of the '.strtolower($this->type)],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt for missing input arguments using the returned questions.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function promptForMissingArgumentsUsing()
|
||||
{
|
||||
return [
|
||||
'name' => [
|
||||
'What should the '.strtolower($this->type).' be named?',
|
||||
match ($this->type) {
|
||||
'Cast' => 'E.g. Json',
|
||||
'Channel' => 'E.g. OrderChannel',
|
||||
'Console command' => 'E.g. SendEmails',
|
||||
'Component' => 'E.g. Alert',
|
||||
'Controller' => 'E.g. UserController',
|
||||
'Event' => 'E.g. PodcastProcessed',
|
||||
'Exception' => 'E.g. InvalidOrderException',
|
||||
'Factory' => 'E.g. PostFactory',
|
||||
'Job' => 'E.g. ProcessPodcast',
|
||||
'Listener' => 'E.g. SendPodcastNotification',
|
||||
'Mailable' => 'E.g. OrderShipped',
|
||||
'Middleware' => 'E.g. EnsureTokenIsValid',
|
||||
'Model' => 'E.g. Flight',
|
||||
'Notification' => 'E.g. InvoicePaid',
|
||||
'Observer' => 'E.g. UserObserver',
|
||||
'Policy' => 'E.g. PostPolicy',
|
||||
'Provider' => 'E.g. ElasticServiceProvider',
|
||||
'Request' => 'E.g. StorePodcastRequest',
|
||||
'Resource' => 'E.g. UserResource',
|
||||
'Rule' => 'E.g. Uppercase',
|
||||
'Scope' => 'E.g. TrendingScope',
|
||||
'Seeder' => 'E.g. UserSeeder',
|
||||
'Test' => 'E.g. UserTest',
|
||||
default => '',
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
21
vendor/laravel/framework/src/Illuminate/Console/LICENSE.md
vendored
Normal file
21
vendor/laravel/framework/src/Illuminate/Console/LICENSE.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Taylor Otwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
10
vendor/laravel/framework/src/Illuminate/Console/ManuallyFailedException.php
vendored
Normal file
10
vendor/laravel/framework/src/Illuminate/Console/ManuallyFailedException.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class ManuallyFailedException extends RuntimeException
|
||||
{
|
||||
//
|
||||
}
|
||||
110
vendor/laravel/framework/src/Illuminate/Console/MigrationGeneratorCommand.php
vendored
Normal file
110
vendor/laravel/framework/src/Illuminate/Console/MigrationGeneratorCommand.php
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
|
||||
use function Illuminate\Filesystem\join_paths;
|
||||
|
||||
abstract class MigrationGeneratorCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The filesystem instance.
|
||||
*
|
||||
* @var \Illuminate\Filesystem\Filesystem
|
||||
*/
|
||||
protected $files;
|
||||
|
||||
/**
|
||||
* Create a new migration generator command instance.
|
||||
*
|
||||
* @param \Illuminate\Filesystem\Filesystem $files
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Filesystem $files)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->files = $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the migration table name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function migrationTableName();
|
||||
|
||||
/**
|
||||
* Get the path to the migration stub file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function migrationStubFile();
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$table = $this->migrationTableName();
|
||||
|
||||
if ($this->migrationExists($table)) {
|
||||
$this->components->error('Migration already exists.');
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->replaceMigrationPlaceholders(
|
||||
$this->createBaseMigration($table), $table
|
||||
);
|
||||
|
||||
$this->components->info('Migration created successfully.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a base migration file for the table.
|
||||
*
|
||||
* @param string $table
|
||||
* @return string
|
||||
*/
|
||||
protected function createBaseMigration($table)
|
||||
{
|
||||
return $this->laravel['migration.creator']->create(
|
||||
'create_'.$table.'_table', $this->laravel->databasePath('/migrations')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the placeholders in the generated migration file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $table
|
||||
* @return void
|
||||
*/
|
||||
protected function replaceMigrationPlaceholders($path, $table)
|
||||
{
|
||||
$stub = str_replace(
|
||||
'{{table}}', $table, $this->files->get($this->migrationStubFile())
|
||||
);
|
||||
|
||||
$this->files->put($path, $stub);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether a migration for the table already exists.
|
||||
*
|
||||
* @param string $table
|
||||
* @return bool
|
||||
*/
|
||||
protected function migrationExists($table)
|
||||
{
|
||||
return count($this->files->glob(
|
||||
join_paths($this->laravel->databasePath('migrations'), '*_*_*_*_create_'.$table.'_table.php')
|
||||
)) !== 0;
|
||||
}
|
||||
}
|
||||
197
vendor/laravel/framework/src/Illuminate/Console/OutputStyle.php
vendored
Normal file
197
vendor/laravel/framework/src/Illuminate/Console/OutputStyle.php
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Illuminate\Console\Contracts\NewLineAware;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
class OutputStyle extends SymfonyStyle implements NewLineAware
|
||||
{
|
||||
/**
|
||||
* The output instance.
|
||||
*
|
||||
* @var \Symfony\Component\Console\Output\OutputInterface
|
||||
*/
|
||||
private $output;
|
||||
|
||||
/**
|
||||
* The number of trailing new lines written by the last output.
|
||||
*
|
||||
* This is initialized as 1 to account for the new line written by the shell after executing a command.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $newLinesWritten = 1;
|
||||
|
||||
/**
|
||||
* If the last output written wrote a new line.
|
||||
*
|
||||
* @var bool
|
||||
*
|
||||
* @deprecated use $newLinesWritten
|
||||
*/
|
||||
protected $newLineWritten = false;
|
||||
|
||||
/**
|
||||
* Create a new Console OutputStyle instance.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Input\InputInterface $input
|
||||
* @param \Symfony\Component\Console\Output\OutputInterface $output
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
|
||||
parent::__construct($input, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\Override]
|
||||
public function askQuestion(Question $question): mixed
|
||||
{
|
||||
try {
|
||||
return parent::askQuestion($question);
|
||||
} finally {
|
||||
$this->newLinesWritten++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\Override]
|
||||
public function write(string|iterable $messages, bool $newline = false, int $options = 0): void
|
||||
{
|
||||
$this->newLinesWritten = $this->trailingNewLineCount($messages) + (int) $newline;
|
||||
$this->newLineWritten = $this->newLinesWritten > 0;
|
||||
|
||||
parent::write($messages, $newline, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\Override]
|
||||
public function writeln(string|iterable $messages, int $type = self::OUTPUT_NORMAL): void
|
||||
{
|
||||
$this->newLinesWritten = $this->trailingNewLineCount($messages) + 1;
|
||||
$this->newLineWritten = true;
|
||||
|
||||
parent::writeln($messages, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\Override]
|
||||
public function newLine(int $count = 1): void
|
||||
{
|
||||
$this->newLinesWritten += $count;
|
||||
$this->newLineWritten = $this->newLinesWritten > 0;
|
||||
|
||||
parent::newLine($count);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function newLinesWritten()
|
||||
{
|
||||
if ($this->output instanceof static) {
|
||||
return $this->output->newLinesWritten();
|
||||
}
|
||||
|
||||
return $this->newLinesWritten;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated use newLinesWritten
|
||||
*/
|
||||
public function newLineWritten()
|
||||
{
|
||||
if ($this->output instanceof static && $this->output->newLineWritten()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->newLineWritten;
|
||||
}
|
||||
|
||||
/*
|
||||
* Count the number of trailing new lines in a string.
|
||||
*
|
||||
* @param string|iterable $messages
|
||||
* @return int
|
||||
*/
|
||||
protected function trailingNewLineCount($messages)
|
||||
{
|
||||
if (is_iterable($messages)) {
|
||||
$string = '';
|
||||
|
||||
foreach ($messages as $message) {
|
||||
$string .= $message.PHP_EOL;
|
||||
}
|
||||
} else {
|
||||
$string = $messages;
|
||||
}
|
||||
|
||||
return strlen($string) - strlen(rtrim($string, PHP_EOL));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether verbosity is quiet (-q).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isQuiet(): bool
|
||||
{
|
||||
return $this->output->isQuiet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether verbosity is verbose (-v).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isVerbose(): bool
|
||||
{
|
||||
return $this->output->isVerbose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether verbosity is very verbose (-vv).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isVeryVerbose(): bool
|
||||
{
|
||||
return $this->output->isVeryVerbose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether verbosity is debug (-vvv).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDebug(): bool
|
||||
{
|
||||
return $this->output->isDebug();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the underlying Symfony output implementation.
|
||||
*
|
||||
* @return \Symfony\Component\Console\Output\OutputInterface
|
||||
*/
|
||||
public function getOutput()
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
}
|
||||
141
vendor/laravel/framework/src/Illuminate/Console/Parser.php
vendored
Normal file
141
vendor/laravel/framework/src/Illuminate/Console/Parser.php
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
class Parser
|
||||
{
|
||||
/**
|
||||
* Parse the given console command definition into an array.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return array
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function parse(string $expression)
|
||||
{
|
||||
$name = static::name($expression);
|
||||
|
||||
if (preg_match_all('/\{\s*(.*?)\s*\}/', $expression, $matches) && count($matches[1])) {
|
||||
return array_merge([$name], static::parameters($matches[1]));
|
||||
}
|
||||
|
||||
return [$name, [], []];
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the name of the command from the expression.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected static function name(string $expression)
|
||||
{
|
||||
if (! preg_match('/[^\s]+/', $expression, $matches)) {
|
||||
throw new InvalidArgumentException('Unable to determine command name from signature.');
|
||||
}
|
||||
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract all parameters from the tokens.
|
||||
*
|
||||
* @param array $tokens
|
||||
* @return array
|
||||
*/
|
||||
protected static function parameters(array $tokens)
|
||||
{
|
||||
$arguments = [];
|
||||
|
||||
$options = [];
|
||||
|
||||
foreach ($tokens as $token) {
|
||||
if (preg_match('/^-{2,}(.*)/', $token, $matches)) {
|
||||
$options[] = static::parseOption($matches[1]);
|
||||
} else {
|
||||
$arguments[] = static::parseArgument($token);
|
||||
}
|
||||
}
|
||||
|
||||
return [$arguments, $options];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an argument expression.
|
||||
*
|
||||
* @param string $token
|
||||
* @return \Symfony\Component\Console\Input\InputArgument
|
||||
*/
|
||||
protected static function parseArgument(string $token)
|
||||
{
|
||||
[$token, $description] = static::extractDescription($token);
|
||||
|
||||
switch (true) {
|
||||
case str_ends_with($token, '?*'):
|
||||
return new InputArgument(trim($token, '?*'), InputArgument::IS_ARRAY, $description);
|
||||
case str_ends_with($token, '*'):
|
||||
return new InputArgument(trim($token, '*'), InputArgument::IS_ARRAY | InputArgument::REQUIRED, $description);
|
||||
case str_ends_with($token, '?'):
|
||||
return new InputArgument(trim($token, '?'), InputArgument::OPTIONAL, $description);
|
||||
case preg_match('/(.+)\=\*(.+)/', $token, $matches):
|
||||
return new InputArgument($matches[1], InputArgument::IS_ARRAY, $description, preg_split('/,\s?/', $matches[2]));
|
||||
case preg_match('/(.+)\=(.+)/', $token, $matches):
|
||||
return new InputArgument($matches[1], InputArgument::OPTIONAL, $description, $matches[2]);
|
||||
default:
|
||||
return new InputArgument($token, InputArgument::REQUIRED, $description);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an option expression.
|
||||
*
|
||||
* @param string $token
|
||||
* @return \Symfony\Component\Console\Input\InputOption
|
||||
*/
|
||||
protected static function parseOption(string $token)
|
||||
{
|
||||
[$token, $description] = static::extractDescription($token);
|
||||
|
||||
$matches = preg_split('/\s*\|\s*/', $token, 2);
|
||||
|
||||
$shortcut = null;
|
||||
|
||||
if (isset($matches[1])) {
|
||||
$shortcut = $matches[0];
|
||||
$token = $matches[1];
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
case str_ends_with($token, '='):
|
||||
return new InputOption(trim($token, '='), $shortcut, InputOption::VALUE_OPTIONAL, $description);
|
||||
case str_ends_with($token, '=*'):
|
||||
return new InputOption(trim($token, '=*'), $shortcut, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $description);
|
||||
case preg_match('/(.+)\=\*(.+)/', $token, $matches):
|
||||
return new InputOption($matches[1], $shortcut, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $description, preg_split('/,\s?/', $matches[2]));
|
||||
case preg_match('/(.+)\=(.+)/', $token, $matches):
|
||||
return new InputOption($matches[1], $shortcut, InputOption::VALUE_OPTIONAL, $description, $matches[2]);
|
||||
default:
|
||||
return new InputOption($token, $shortcut, InputOption::VALUE_NONE, $description);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the token into its token and description segments.
|
||||
*
|
||||
* @param string $token
|
||||
* @return array
|
||||
*/
|
||||
protected static function extractDescription(string $token)
|
||||
{
|
||||
$parts = preg_split('/\s+:\s+/', trim($token), 2);
|
||||
|
||||
return count($parts) === 2 ? $parts : [$token, ''];
|
||||
}
|
||||
}
|
||||
43
vendor/laravel/framework/src/Illuminate/Console/Prohibitable.php
vendored
Normal file
43
vendor/laravel/framework/src/Illuminate/Console/Prohibitable.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
trait Prohibitable
|
||||
{
|
||||
/**
|
||||
* Indicates if the command should be prohibited from running.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $prohibitedFromRunning = false;
|
||||
|
||||
/**
|
||||
* Indicate whether the command should be prohibited from running.
|
||||
*
|
||||
* @param bool $prohibit
|
||||
* @return void
|
||||
*/
|
||||
public static function prohibit($prohibit = true)
|
||||
{
|
||||
static::$prohibitedFromRunning = $prohibit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the command is prohibited from running and display a warning if so.
|
||||
*
|
||||
* @param bool $quiet
|
||||
* @return bool
|
||||
*/
|
||||
protected function isProhibited(bool $quiet = false)
|
||||
{
|
||||
if (! static::$prohibitedFromRunning) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $quiet) {
|
||||
$this->components->warn('This command is prohibited from running in this environment.');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
9
vendor/laravel/framework/src/Illuminate/Console/PromptValidationException.php
vendored
Normal file
9
vendor/laravel/framework/src/Illuminate/Console/PromptValidationException.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class PromptValidationException extends RuntimeException
|
||||
{
|
||||
}
|
||||
86
vendor/laravel/framework/src/Illuminate/Console/QuestionHelper.php
vendored
Normal file
86
vendor/laravel/framework/src/Illuminate/Console/QuestionHelper.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
use Illuminate\Console\View\Components\TwoColumnDetail;
|
||||
use Illuminate\Support\Stringable;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatter;
|
||||
use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
use Symfony\Component\Console\Question\ConfirmationQuestion;
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
|
||||
class QuestionHelper extends SymfonyQuestionHelper
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[\Override]
|
||||
protected function writePrompt(OutputInterface $output, Question $question): void
|
||||
{
|
||||
$text = OutputFormatter::escapeTrailingBackslash($question->getQuestion());
|
||||
|
||||
$text = $this->ensureEndsWithPunctuation($text);
|
||||
|
||||
$text = " <fg=default;options=bold>$text</></>";
|
||||
|
||||
$default = $question->getDefault();
|
||||
|
||||
if ($question->isMultiline()) {
|
||||
$text .= sprintf(' (press %s to continue)', 'Windows' == PHP_OS_FAMILY
|
||||
? '<comment>Ctrl+Z</comment> then <comment>Enter</comment>'
|
||||
: '<comment>Ctrl+D</comment>');
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
case null === $default:
|
||||
$text = sprintf('<info>%s</info>', $text);
|
||||
|
||||
break;
|
||||
|
||||
case $question instanceof ConfirmationQuestion:
|
||||
$text = sprintf('<info>%s (yes/no)</info> [<comment>%s</comment>]', $text, $default ? 'yes' : 'no');
|
||||
|
||||
break;
|
||||
|
||||
case $question instanceof ChoiceQuestion:
|
||||
$choices = $question->getChoices();
|
||||
$text = sprintf('<info>%s</info> [<comment>%s</comment>]', $text, OutputFormatter::escape($choices[$default] ?? $default));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$text = sprintf('<info>%s</info> [<comment>%s</comment>]', $text, OutputFormatter::escape($default));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$output->writeln($text);
|
||||
|
||||
if ($question instanceof ChoiceQuestion) {
|
||||
foreach ($question->getChoices() as $key => $value) {
|
||||
with(new TwoColumnDetail($output))->render($value, $key);
|
||||
}
|
||||
}
|
||||
|
||||
$output->write('<options=bold>❯ </>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the given string ends with punctuation.
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
protected function ensureEndsWithPunctuation($string)
|
||||
{
|
||||
if (! (new Stringable($string))->endsWith(['?', ':', '!', '.'])) {
|
||||
return "$string:";
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
14
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheAware.php
vendored
Normal file
14
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheAware.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
interface CacheAware
|
||||
{
|
||||
/**
|
||||
* Specify the cache store that should be used.
|
||||
*
|
||||
* @param string $store
|
||||
* @return $this
|
||||
*/
|
||||
public function useStore($store);
|
||||
}
|
||||
114
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheEventMutex.php
vendored
Normal file
114
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheEventMutex.php
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Cache\DynamoDbStore;
|
||||
use Illuminate\Contracts\Cache\Factory as Cache;
|
||||
use Illuminate\Contracts\Cache\LockProvider;
|
||||
|
||||
class CacheEventMutex implements EventMutex, CacheAware
|
||||
{
|
||||
/**
|
||||
* The cache repository implementation.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Cache\Factory
|
||||
*/
|
||||
public $cache;
|
||||
|
||||
/**
|
||||
* The cache store that should be used.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $store;
|
||||
|
||||
/**
|
||||
* Create a new overlapping strategy.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Cache\Factory $cache
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Cache $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to obtain an event mutex for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return bool
|
||||
*/
|
||||
public function create(Event $event)
|
||||
{
|
||||
if ($this->shouldUseLocks($this->cache->store($this->store)->getStore())) {
|
||||
return $this->cache->store($this->store)->getStore()
|
||||
->lock($event->mutexName(), $event->expiresAt * 60)
|
||||
->acquire();
|
||||
}
|
||||
|
||||
return $this->cache->store($this->store)->add(
|
||||
$event->mutexName(), true, $event->expiresAt * 60
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an event mutex exists for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(Event $event)
|
||||
{
|
||||
if ($this->shouldUseLocks($this->cache->store($this->store)->getStore())) {
|
||||
return ! $this->cache->store($this->store)->getStore()
|
||||
->lock($event->mutexName(), $event->expiresAt * 60)
|
||||
->get(fn () => true);
|
||||
}
|
||||
|
||||
return $this->cache->store($this->store)->has($event->mutexName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the event mutex for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return void
|
||||
*/
|
||||
public function forget(Event $event)
|
||||
{
|
||||
if ($this->shouldUseLocks($this->cache->store($this->store)->getStore())) {
|
||||
$this->cache->store($this->store)->getStore()
|
||||
->lock($event->mutexName(), $event->expiresAt * 60)
|
||||
->forceRelease();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->cache->store($this->store)->forget($event->mutexName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given store should use locks for cache event mutexes.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Cache\Store $store
|
||||
* @return bool
|
||||
*/
|
||||
protected function shouldUseLocks($store)
|
||||
{
|
||||
return $store instanceof LockProvider && ! $store instanceof DynamoDbStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the cache store that should be used.
|
||||
*
|
||||
* @param string $store
|
||||
* @return $this
|
||||
*/
|
||||
public function useStore($store)
|
||||
{
|
||||
$this->store = $store;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
75
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheSchedulingMutex.php
vendored
Normal file
75
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheSchedulingMutex.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Illuminate\Contracts\Cache\Factory as Cache;
|
||||
|
||||
class CacheSchedulingMutex implements SchedulingMutex, CacheAware
|
||||
{
|
||||
/**
|
||||
* The cache factory implementation.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Cache\Factory
|
||||
*/
|
||||
public $cache;
|
||||
|
||||
/**
|
||||
* The cache store that should be used.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $store;
|
||||
|
||||
/**
|
||||
* Create a new scheduling strategy.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Cache\Factory $cache
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Cache $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to obtain a scheduling mutex for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @param \DateTimeInterface $time
|
||||
* @return bool
|
||||
*/
|
||||
public function create(Event $event, DateTimeInterface $time)
|
||||
{
|
||||
return $this->cache->store($this->store)->add(
|
||||
$event->mutexName().$time->format('Hi'), true, 3600
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a scheduling mutex exists for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @param \DateTimeInterface $time
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(Event $event, DateTimeInterface $time)
|
||||
{
|
||||
return $this->cache->store($this->store)->has(
|
||||
$event->mutexName().$time->format('Hi')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the cache store that should be used.
|
||||
*
|
||||
* @param string $store
|
||||
* @return $this
|
||||
*/
|
||||
public function useStore($store)
|
||||
{
|
||||
$this->store = $store;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
203
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CallbackEvent.php
vendored
Normal file
203
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CallbackEvent.php
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Support\Reflector;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
class CallbackEvent extends Event
|
||||
{
|
||||
/**
|
||||
* The callback to call.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $callback;
|
||||
|
||||
/**
|
||||
* The parameters to pass to the method.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $parameters;
|
||||
|
||||
/**
|
||||
* The result of the callback's execution.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $result;
|
||||
|
||||
/**
|
||||
* The exception that was thrown when calling the callback, if any.
|
||||
*
|
||||
* @var \Throwable|null
|
||||
*/
|
||||
protected $exception;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\EventMutex $mutex
|
||||
* @param string|callable $callback
|
||||
* @param array $parameters
|
||||
* @param \DateTimeZone|string|null $timezone
|
||||
* @return void
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(EventMutex $mutex, $callback, array $parameters = [], $timezone = null)
|
||||
{
|
||||
if (! is_string($callback) && ! Reflector::isCallable($callback)) {
|
||||
throw new InvalidArgumentException(
|
||||
'Invalid scheduled callback event. Must be a string or callable.'
|
||||
);
|
||||
}
|
||||
|
||||
$this->mutex = $mutex;
|
||||
$this->callback = $callback;
|
||||
$this->parameters = $parameters;
|
||||
$this->timezone = $timezone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the callback event.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Container\Container $container
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function run(Container $container)
|
||||
{
|
||||
parent::run($container);
|
||||
|
||||
if ($this->exception) {
|
||||
throw $this->exception;
|
||||
}
|
||||
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the event should skip because another process is overlapping.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldSkipDueToOverlapping()
|
||||
{
|
||||
return $this->description && parent::shouldSkipDueToOverlapping();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the callback should run in the background.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function runInBackground()
|
||||
{
|
||||
throw new RuntimeException('Scheduled closures can not be run in the background.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the callback.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Container\Container $container
|
||||
* @return int
|
||||
*/
|
||||
protected function execute($container)
|
||||
{
|
||||
try {
|
||||
$this->result = is_object($this->callback)
|
||||
? $container->call([$this->callback, '__invoke'], $this->parameters)
|
||||
: $container->call($this->callback, $this->parameters);
|
||||
|
||||
return $this->result === false ? 1 : 0;
|
||||
} catch (Throwable $e) {
|
||||
$this->exception = $e;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not allow the event to overlap each other.
|
||||
*
|
||||
* The expiration time of the underlying cache lock may be specified in minutes.
|
||||
*
|
||||
* @param int $expiresAt
|
||||
* @return $this
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function withoutOverlapping($expiresAt = 1440)
|
||||
{
|
||||
if (! isset($this->description)) {
|
||||
throw new LogicException(
|
||||
"A scheduled event name is required to prevent overlapping. Use the 'name' method before 'withoutOverlapping'."
|
||||
);
|
||||
}
|
||||
|
||||
return parent::withoutOverlapping($expiresAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow the event to only run on one server for each cron expression.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function onOneServer()
|
||||
{
|
||||
if (! isset($this->description)) {
|
||||
throw new LogicException(
|
||||
"A scheduled event name is required to only run on one server. Use the 'name' method before 'onOneServer'."
|
||||
);
|
||||
}
|
||||
|
||||
return parent::onOneServer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the summary of the event for display.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSummaryForDisplay()
|
||||
{
|
||||
if (is_string($this->description)) {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
return is_string($this->callback) ? $this->callback : 'Callback';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mutex name for the scheduled command.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function mutexName()
|
||||
{
|
||||
return 'framework/schedule-'.sha1($this->description ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the mutex for the event.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function removeMutex()
|
||||
{
|
||||
if ($this->description) {
|
||||
parent::removeMutex();
|
||||
}
|
||||
}
|
||||
}
|
||||
75
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CommandBuilder.php
vendored
Normal file
75
vendor/laravel/framework/src/Illuminate/Console/Scheduling/CommandBuilder.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Console\Application;
|
||||
use Illuminate\Support\ProcessUtils;
|
||||
|
||||
class CommandBuilder
|
||||
{
|
||||
/**
|
||||
* Build the command for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return string
|
||||
*/
|
||||
public function buildCommand(Event $event)
|
||||
{
|
||||
if ($event->runInBackground) {
|
||||
return $this->buildBackgroundCommand($event);
|
||||
}
|
||||
|
||||
return $this->buildForegroundCommand($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the command for running the event in the foreground.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return string
|
||||
*/
|
||||
protected function buildForegroundCommand(Event $event)
|
||||
{
|
||||
$output = ProcessUtils::escapeArgument($event->output);
|
||||
|
||||
return laravel_cloud()
|
||||
? $this->ensureCorrectUser($event, $event->command.' 2>&1 | tee '.($event->shouldAppendOutput ? '-a ' : '').$output)
|
||||
: $this->ensureCorrectUser($event, $event->command.($event->shouldAppendOutput ? ' >> ' : ' > ').$output.' 2>&1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the command for running the event in the background.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return string
|
||||
*/
|
||||
protected function buildBackgroundCommand(Event $event)
|
||||
{
|
||||
$output = ProcessUtils::escapeArgument($event->output);
|
||||
|
||||
$redirect = $event->shouldAppendOutput ? ' >> ' : ' > ';
|
||||
|
||||
$finished = Application::formatCommandString('schedule:finish').' "'.$event->mutexName().'"';
|
||||
|
||||
if (windows_os()) {
|
||||
return 'start /b cmd /v:on /c "('.$event->command.' & '.$finished.' ^!ERRORLEVEL^!)'.$redirect.$output.' 2>&1"';
|
||||
}
|
||||
|
||||
return $this->ensureCorrectUser($event,
|
||||
'('.$event->command.$redirect.$output.' 2>&1 ; '.$finished.' "$?") > '
|
||||
.ProcessUtils::escapeArgument($event->getDefaultOutput()).' 2>&1 &'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize the event's command syntax with the correct user.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @param string $command
|
||||
* @return string
|
||||
*/
|
||||
protected function ensureCorrectUser(Event $event, $command)
|
||||
{
|
||||
return $event->user && ! windows_os() ? 'sudo -u '.$event->user.' -- sh -c \''.$command.'\'' : $command;
|
||||
}
|
||||
}
|
||||
860
vendor/laravel/framework/src/Illuminate/Console/Scheduling/Event.php
vendored
Normal file
860
vendor/laravel/framework/src/Illuminate/Console/Scheduling/Event.php
vendored
Normal file
@@ -0,0 +1,860 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Closure;
|
||||
use Cron\CronExpression;
|
||||
use GuzzleHttp\Client as HttpClient;
|
||||
use GuzzleHttp\ClientInterface as HttpClientInterface;
|
||||
use GuzzleHttp\Exception\TransferException;
|
||||
use Illuminate\Console\Application;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Contracts\Debug\ExceptionHandler;
|
||||
use Illuminate\Contracts\Mail\Mailer;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Date;
|
||||
use Illuminate\Support\Stringable;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Illuminate\Support\Traits\ReflectsClosures;
|
||||
use Illuminate\Support\Traits\Tappable;
|
||||
use Psr\Http\Client\ClientExceptionInterface;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Throwable;
|
||||
|
||||
class Event
|
||||
{
|
||||
use Macroable, ManagesAttributes, ManagesFrequencies, ReflectsClosures, Tappable;
|
||||
|
||||
/**
|
||||
* The command string.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $command;
|
||||
|
||||
/**
|
||||
* The location that output should be sent to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $output = '/dev/null';
|
||||
|
||||
/**
|
||||
* Indicates whether output should be appended.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $shouldAppendOutput = false;
|
||||
|
||||
/**
|
||||
* The array of callbacks to be run before the event is started.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $beforeCallbacks = [];
|
||||
|
||||
/**
|
||||
* The array of callbacks to be run after the event is finished.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $afterCallbacks = [];
|
||||
|
||||
/**
|
||||
* The event mutex implementation.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\EventMutex
|
||||
*/
|
||||
public $mutex;
|
||||
|
||||
/**
|
||||
* The mutex name resolver callback.
|
||||
*
|
||||
* @var \Closure|null
|
||||
*/
|
||||
public $mutexNameResolver;
|
||||
|
||||
/**
|
||||
* The last time the event was checked for eligibility to run.
|
||||
*
|
||||
* Utilized by sub-minute repeated events.
|
||||
*
|
||||
* @var \Illuminate\Support\Carbon|null
|
||||
*/
|
||||
protected $lastChecked;
|
||||
|
||||
/**
|
||||
* The exit status code of the command.
|
||||
*
|
||||
* @var int|null
|
||||
*/
|
||||
public $exitCode;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\EventMutex $mutex
|
||||
* @param string $command
|
||||
* @param \DateTimeZone|string|null $timezone
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(EventMutex $mutex, $command, $timezone = null)
|
||||
{
|
||||
$this->mutex = $mutex;
|
||||
$this->command = $command;
|
||||
$this->timezone = $timezone;
|
||||
|
||||
$this->output = $this->getDefaultOutput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default output depending on the OS.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultOutput()
|
||||
{
|
||||
return (DIRECTORY_SEPARATOR === '\\') ? 'NUL' : '/dev/null';
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the given event.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Container\Container $container
|
||||
* @return void
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function run(Container $container)
|
||||
{
|
||||
if ($this->shouldSkipDueToOverlapping()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$exitCode = $this->start($container);
|
||||
|
||||
if (! $this->runInBackground) {
|
||||
$this->finish($container, $exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the event should skip because another process is overlapping.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldSkipDueToOverlapping()
|
||||
{
|
||||
return $this->withoutOverlapping && ! $this->mutex->create($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the event has been configured to repeat multiple times per minute.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isRepeatable()
|
||||
{
|
||||
return ! is_null($this->repeatSeconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the event is ready to repeat.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldRepeatNow()
|
||||
{
|
||||
return $this->isRepeatable()
|
||||
&& $this->lastChecked?->diffInSeconds() >= $this->repeatSeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the command process.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Container\Container $container
|
||||
* @return int
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
protected function start($container)
|
||||
{
|
||||
try {
|
||||
$this->callBeforeCallbacks($container);
|
||||
|
||||
return $this->execute($container);
|
||||
} catch (Throwable $exception) {
|
||||
$this->removeMutex();
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the command process.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Container\Container $container
|
||||
* @return int
|
||||
*/
|
||||
protected function execute($container)
|
||||
{
|
||||
return Process::fromShellCommandline(
|
||||
$this->buildCommand(), base_path(), null, null, null
|
||||
)->run(
|
||||
laravel_cloud()
|
||||
? fn ($type, $line) => fwrite($type === 'out' ? STDOUT : STDERR, $line)
|
||||
: fn () => true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the command process as finished and run callbacks/cleanup.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Container\Container $container
|
||||
* @param int $exitCode
|
||||
* @return void
|
||||
*/
|
||||
public function finish(Container $container, $exitCode)
|
||||
{
|
||||
$this->exitCode = (int) $exitCode;
|
||||
|
||||
try {
|
||||
$this->callAfterCallbacks($container);
|
||||
} finally {
|
||||
$this->removeMutex();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call all of the "before" callbacks for the event.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Container\Container $container
|
||||
* @return void
|
||||
*/
|
||||
public function callBeforeCallbacks(Container $container)
|
||||
{
|
||||
foreach ($this->beforeCallbacks as $callback) {
|
||||
$container->call($callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call all of the "after" callbacks for the event.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Container\Container $container
|
||||
* @return void
|
||||
*/
|
||||
public function callAfterCallbacks(Container $container)
|
||||
{
|
||||
foreach ($this->afterCallbacks as $callback) {
|
||||
$container->call($callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the command string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function buildCommand()
|
||||
{
|
||||
return (new CommandBuilder)->buildCommand($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given event should run based on the Cron expression.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Foundation\Application $app
|
||||
* @return bool
|
||||
*/
|
||||
public function isDue($app)
|
||||
{
|
||||
if (! $this->runsInMaintenanceMode() && $app->isDownForMaintenance()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->expressionPasses() &&
|
||||
$this->runsInEnvironment($app->environment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the event runs in maintenance mode.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function runsInMaintenanceMode()
|
||||
{
|
||||
return $this->evenInMaintenanceMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the Cron expression passes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function expressionPasses()
|
||||
{
|
||||
$date = Date::now();
|
||||
|
||||
if ($this->timezone) {
|
||||
$date = $date->setTimezone($this->timezone);
|
||||
}
|
||||
|
||||
return (new CronExpression($this->expression))->isDue($date->toDateTimeString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the event runs in the given environment.
|
||||
*
|
||||
* @param string $environment
|
||||
* @return bool
|
||||
*/
|
||||
public function runsInEnvironment($environment)
|
||||
{
|
||||
return empty($this->environments) || in_array($environment, $this->environments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the filters pass for the event.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Foundation\Application $app
|
||||
* @return bool
|
||||
*/
|
||||
public function filtersPass($app)
|
||||
{
|
||||
$this->lastChecked = Date::now();
|
||||
|
||||
foreach ($this->filters as $callback) {
|
||||
if (! $app->call($callback)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->rejects as $callback) {
|
||||
if ($app->call($callback)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the output is stored on disk in a log file.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function storeOutput()
|
||||
{
|
||||
$this->ensureOutputIsBeingCaptured();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the output of the command to a given location.
|
||||
*
|
||||
* @param string $location
|
||||
* @param bool $append
|
||||
* @return $this
|
||||
*/
|
||||
public function sendOutputTo($location, $append = false)
|
||||
{
|
||||
$this->output = $location;
|
||||
|
||||
$this->shouldAppendOutput = $append;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the output of the command to a given location.
|
||||
*
|
||||
* @param string $location
|
||||
* @return $this
|
||||
*/
|
||||
public function appendOutputTo($location)
|
||||
{
|
||||
return $this->sendOutputTo($location, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* E-mail the results of the scheduled operation.
|
||||
*
|
||||
* @param array|mixed $addresses
|
||||
* @param bool $onlyIfOutputExists
|
||||
* @return $this
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function emailOutputTo($addresses, $onlyIfOutputExists = false)
|
||||
{
|
||||
$this->ensureOutputIsBeingCaptured();
|
||||
|
||||
$addresses = Arr::wrap($addresses);
|
||||
|
||||
return $this->then(function (Mailer $mailer) use ($addresses, $onlyIfOutputExists) {
|
||||
$this->emailOutput($mailer, $addresses, $onlyIfOutputExists);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* E-mail the results of the scheduled operation if it produces output.
|
||||
*
|
||||
* @param array|mixed $addresses
|
||||
* @return $this
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function emailWrittenOutputTo($addresses)
|
||||
{
|
||||
return $this->emailOutputTo($addresses, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* E-mail the results of the scheduled operation if it fails.
|
||||
*
|
||||
* @param array|mixed $addresses
|
||||
* @return $this
|
||||
*/
|
||||
public function emailOutputOnFailure($addresses)
|
||||
{
|
||||
$this->ensureOutputIsBeingCaptured();
|
||||
|
||||
$addresses = Arr::wrap($addresses);
|
||||
|
||||
return $this->onFailure(function (Mailer $mailer) use ($addresses) {
|
||||
$this->emailOutput($mailer, $addresses, false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the command output is being captured.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function ensureOutputIsBeingCaptured()
|
||||
{
|
||||
if (is_null($this->output) || $this->output == $this->getDefaultOutput()) {
|
||||
$this->sendOutputTo(storage_path('logs/schedule-'.sha1($this->mutexName()).'.log'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* E-mail the output of the event to the recipients.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Mail\Mailer $mailer
|
||||
* @param array $addresses
|
||||
* @param bool $onlyIfOutputExists
|
||||
* @return void
|
||||
*/
|
||||
protected function emailOutput(Mailer $mailer, $addresses, $onlyIfOutputExists = false)
|
||||
{
|
||||
$text = is_file($this->output) ? file_get_contents($this->output) : '';
|
||||
|
||||
if ($onlyIfOutputExists && empty($text)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$mailer->raw($text, function ($m) use ($addresses) {
|
||||
$m->to($addresses)->subject($this->getEmailSubject());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the e-mail subject line for output results.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getEmailSubject()
|
||||
{
|
||||
if ($this->description) {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
return "Scheduled Job Output For [{$this->command}]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to ping a given URL before the job runs.
|
||||
*
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function pingBefore($url)
|
||||
{
|
||||
return $this->before($this->pingCallback($url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to ping a given URL before the job runs if the given condition is true.
|
||||
*
|
||||
* @param bool $value
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function pingBeforeIf($value, $url)
|
||||
{
|
||||
return $value ? $this->pingBefore($url) : $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to ping a given URL after the job runs.
|
||||
*
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function thenPing($url)
|
||||
{
|
||||
return $this->then($this->pingCallback($url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to ping a given URL after the job runs if the given condition is true.
|
||||
*
|
||||
* @param bool $value
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function thenPingIf($value, $url)
|
||||
{
|
||||
return $value ? $this->thenPing($url) : $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to ping a given URL if the operation succeeds.
|
||||
*
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function pingOnSuccess($url)
|
||||
{
|
||||
return $this->onSuccess($this->pingCallback($url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to ping a given URL if the operation succeeds and if the given condition is true.
|
||||
*
|
||||
* @param bool $value
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function pingOnSuccessIf($value, $url)
|
||||
{
|
||||
return $value ? $this->onSuccess($this->pingCallback($url)) : $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to ping a given URL if the operation fails.
|
||||
*
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function pingOnFailure($url)
|
||||
{
|
||||
return $this->onFailure($this->pingCallback($url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to ping a given URL if the operation fails and if the given condition is true.
|
||||
*
|
||||
* @param bool $value
|
||||
* @param string $url
|
||||
* @return $this
|
||||
*/
|
||||
public function pingOnFailureIf($value, $url)
|
||||
{
|
||||
return $value ? $this->onFailure($this->pingCallback($url)) : $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the callback that pings the given URL.
|
||||
*
|
||||
* @param string $url
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function pingCallback($url)
|
||||
{
|
||||
return function (Container $container) use ($url) {
|
||||
try {
|
||||
$this->getHttpClient($container)->request('GET', $url);
|
||||
} catch (ClientExceptionInterface|TransferException $e) {
|
||||
$container->make(ExceptionHandler::class)->report($e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Guzzle HTTP client to use to send pings.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Container\Container $container
|
||||
* @return \GuzzleHttp\ClientInterface
|
||||
*/
|
||||
protected function getHttpClient(Container $container)
|
||||
{
|
||||
return match (true) {
|
||||
$container->bound(HttpClientInterface::class) => $container->make(HttpClientInterface::class),
|
||||
$container->bound(HttpClient::class) => $container->make(HttpClient::class),
|
||||
default => new HttpClient([
|
||||
'connect_timeout' => 10,
|
||||
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,
|
||||
'timeout' => 30,
|
||||
]),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be called before the operation.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function before(Closure $callback)
|
||||
{
|
||||
$this->beforeCallbacks[] = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be called after the operation.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function after(Closure $callback)
|
||||
{
|
||||
return $this->then($callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be called after the operation.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function then(Closure $callback)
|
||||
{
|
||||
$parameters = $this->closureParameterTypes($callback);
|
||||
|
||||
if (Arr::get($parameters, 'output') === Stringable::class) {
|
||||
return $this->thenWithOutput($callback);
|
||||
}
|
||||
|
||||
$this->afterCallbacks[] = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback that uses the output after the job runs.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param bool $onlyIfOutputExists
|
||||
* @return $this
|
||||
*/
|
||||
public function thenWithOutput(Closure $callback, $onlyIfOutputExists = false)
|
||||
{
|
||||
$this->ensureOutputIsBeingCaptured();
|
||||
|
||||
return $this->then($this->withOutputCallback($callback, $onlyIfOutputExists));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be called if the operation succeeds.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function onSuccess(Closure $callback)
|
||||
{
|
||||
$parameters = $this->closureParameterTypes($callback);
|
||||
|
||||
if (Arr::get($parameters, 'output') === Stringable::class) {
|
||||
return $this->onSuccessWithOutput($callback);
|
||||
}
|
||||
|
||||
return $this->then(function (Container $container) use ($callback) {
|
||||
if ($this->exitCode === 0) {
|
||||
$container->call($callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback that uses the output if the operation succeeds.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param bool $onlyIfOutputExists
|
||||
* @return $this
|
||||
*/
|
||||
public function onSuccessWithOutput(Closure $callback, $onlyIfOutputExists = false)
|
||||
{
|
||||
$this->ensureOutputIsBeingCaptured();
|
||||
|
||||
return $this->onSuccess($this->withOutputCallback($callback, $onlyIfOutputExists));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be called if the operation fails.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function onFailure(Closure $callback)
|
||||
{
|
||||
$parameters = $this->closureParameterTypes($callback);
|
||||
|
||||
if (Arr::get($parameters, 'output') === Stringable::class) {
|
||||
return $this->onFailureWithOutput($callback);
|
||||
}
|
||||
|
||||
return $this->then(function (Container $container) use ($callback) {
|
||||
if ($this->exitCode !== 0) {
|
||||
$container->call($callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback that uses the output if the operation fails.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param bool $onlyIfOutputExists
|
||||
* @return $this
|
||||
*/
|
||||
public function onFailureWithOutput(Closure $callback, $onlyIfOutputExists = false)
|
||||
{
|
||||
$this->ensureOutputIsBeingCaptured();
|
||||
|
||||
return $this->onFailure($this->withOutputCallback($callback, $onlyIfOutputExists));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a callback that provides output.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param bool $onlyIfOutputExists
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function withOutputCallback(Closure $callback, $onlyIfOutputExists = false)
|
||||
{
|
||||
return function (Container $container) use ($callback, $onlyIfOutputExists) {
|
||||
$output = $this->output && is_file($this->output) ? file_get_contents($this->output) : '';
|
||||
|
||||
return $onlyIfOutputExists && empty($output)
|
||||
? null
|
||||
: $container->call($callback, ['output' => new Stringable($output)]);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the summary of the event for display.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSummaryForDisplay()
|
||||
{
|
||||
if (is_string($this->description)) {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
return $this->buildCommand();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the next due date for an event.
|
||||
*
|
||||
* @param \DateTimeInterface|string $currentTime
|
||||
* @param int $nth
|
||||
* @param bool $allowCurrentDate
|
||||
* @return \Illuminate\Support\Carbon
|
||||
*/
|
||||
public function nextRunDate($currentTime = 'now', $nth = 0, $allowCurrentDate = false)
|
||||
{
|
||||
return Date::instance((new CronExpression($this->getExpression()))
|
||||
->getNextRunDate($currentTime, $nth, $allowCurrentDate, $this->timezone));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Cron expression for the event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getExpression()
|
||||
{
|
||||
return $this->expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the event mutex implementation to be used.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\EventMutex $mutex
|
||||
* @return $this
|
||||
*/
|
||||
public function preventOverlapsUsing(EventMutex $mutex)
|
||||
{
|
||||
$this->mutex = $mutex;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mutex name for the scheduled command.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function mutexName()
|
||||
{
|
||||
$mutexNameResolver = $this->mutexNameResolver;
|
||||
|
||||
if (! is_null($mutexNameResolver) && is_callable($mutexNameResolver)) {
|
||||
return $mutexNameResolver($this);
|
||||
}
|
||||
|
||||
return 'framework'.DIRECTORY_SEPARATOR.'schedule-'.
|
||||
sha1($this->expression.$this->normalizeCommand($this->command ?? ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mutex name or name resolver callback.
|
||||
*
|
||||
* @param \Closure|string $mutexName
|
||||
* @return $this
|
||||
*/
|
||||
public function createMutexNameUsing(Closure|string $mutexName)
|
||||
{
|
||||
$this->mutexNameResolver = is_string($mutexName) ? fn () => $mutexName : $mutexName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the mutex for the event.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function removeMutex()
|
||||
{
|
||||
if ($this->withoutOverlapping) {
|
||||
$this->mutex->forget($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given command string with a normalized PHP binary path.
|
||||
*
|
||||
* @param string $command
|
||||
* @return string
|
||||
*/
|
||||
public static function normalizeCommand($command)
|
||||
{
|
||||
return str_replace([
|
||||
Application::phpBinary(),
|
||||
Application::artisanBinary(),
|
||||
], [
|
||||
'php',
|
||||
preg_replace("#['\"]#", '', Application::artisanBinary()),
|
||||
], $command);
|
||||
}
|
||||
}
|
||||
30
vendor/laravel/framework/src/Illuminate/Console/Scheduling/EventMutex.php
vendored
Normal file
30
vendor/laravel/framework/src/Illuminate/Console/Scheduling/EventMutex.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
interface EventMutex
|
||||
{
|
||||
/**
|
||||
* Attempt to obtain an event mutex for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return bool
|
||||
*/
|
||||
public function create(Event $event);
|
||||
|
||||
/**
|
||||
* Determine if an event mutex exists for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(Event $event);
|
||||
|
||||
/**
|
||||
* Clear the event mutex for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return void
|
||||
*/
|
||||
public function forget(Event $event);
|
||||
}
|
||||
233
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ManagesAttributes.php
vendored
Normal file
233
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ManagesAttributes.php
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Support\Reflector;
|
||||
|
||||
trait ManagesAttributes
|
||||
{
|
||||
/**
|
||||
* The cron expression representing the event's frequency.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $expression = '* * * * *';
|
||||
|
||||
/**
|
||||
* How often to repeat the event during a minute.
|
||||
*
|
||||
* @var int|null
|
||||
*/
|
||||
public $repeatSeconds = null;
|
||||
|
||||
/**
|
||||
* The timezone the date should be evaluated on.
|
||||
*
|
||||
* @var \DateTimeZone|string
|
||||
*/
|
||||
public $timezone;
|
||||
|
||||
/**
|
||||
* The user the command should run as.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* The list of environments the command should run under.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $environments = [];
|
||||
|
||||
/**
|
||||
* Indicates if the command should run in maintenance mode.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $evenInMaintenanceMode = false;
|
||||
|
||||
/**
|
||||
* Indicates if the command should not overlap itself.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $withoutOverlapping = false;
|
||||
|
||||
/**
|
||||
* Indicates if the command should only be allowed to run on one server for each cron expression.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $onOneServer = false;
|
||||
|
||||
/**
|
||||
* The number of minutes the mutex should be valid.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $expiresAt = 1440;
|
||||
|
||||
/**
|
||||
* Indicates if the command should run in the background.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $runInBackground = false;
|
||||
|
||||
/**
|
||||
* The array of filter callbacks.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $filters = [];
|
||||
|
||||
/**
|
||||
* The array of reject callbacks.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $rejects = [];
|
||||
|
||||
/**
|
||||
* The human readable description of the event.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $description;
|
||||
|
||||
/**
|
||||
* Set which user the command should run as.
|
||||
*
|
||||
* @param string $user
|
||||
* @return $this
|
||||
*/
|
||||
public function user($user)
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit the environments the command should run in.
|
||||
*
|
||||
* @param array|mixed $environments
|
||||
* @return $this
|
||||
*/
|
||||
public function environments($environments)
|
||||
{
|
||||
$this->environments = is_array($environments) ? $environments : func_get_args();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* State that the command should run even in maintenance mode.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function evenInMaintenanceMode()
|
||||
{
|
||||
$this->evenInMaintenanceMode = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not allow the event to overlap each other.
|
||||
* The expiration time of the underlying cache lock may be specified in minutes.
|
||||
*
|
||||
* @param int $expiresAt
|
||||
* @return $this
|
||||
*/
|
||||
public function withoutOverlapping($expiresAt = 1440)
|
||||
{
|
||||
$this->withoutOverlapping = true;
|
||||
|
||||
$this->expiresAt = $expiresAt;
|
||||
|
||||
return $this->skip(function () {
|
||||
return $this->mutex->exists($this);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow the event to only run on one server for each cron expression.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function onOneServer()
|
||||
{
|
||||
$this->onOneServer = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* State that the command should run in the background.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function runInBackground()
|
||||
{
|
||||
$this->runInBackground = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to further filter the schedule.
|
||||
*
|
||||
* @param \Closure|bool $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function when($callback)
|
||||
{
|
||||
$this->filters[] = Reflector::isCallable($callback) ? $callback : function () use ($callback) {
|
||||
return $callback;
|
||||
};
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to further filter the schedule.
|
||||
*
|
||||
* @param \Closure|bool $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function skip($callback)
|
||||
{
|
||||
$this->rejects[] = Reflector::isCallable($callback) ? $callback : function () use ($callback) {
|
||||
return $callback;
|
||||
};
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the human-friendly description of the event.
|
||||
*
|
||||
* @param string $description
|
||||
* @return $this
|
||||
*/
|
||||
public function name($description)
|
||||
{
|
||||
return $this->description($description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the human-friendly description of the event.
|
||||
*
|
||||
* @param string $description
|
||||
* @return $this
|
||||
*/
|
||||
public function description($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
667
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ManagesFrequencies.php
vendored
Normal file
667
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ManagesFrequencies.php
vendored
Normal file
@@ -0,0 +1,667 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use InvalidArgumentException;
|
||||
|
||||
trait ManagesFrequencies
|
||||
{
|
||||
/**
|
||||
* The Cron expression representing the event's frequency.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return $this
|
||||
*/
|
||||
public function cron($expression)
|
||||
{
|
||||
$this->expression = $expression;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run between start and end time.
|
||||
*
|
||||
* @param string $startTime
|
||||
* @param string $endTime
|
||||
* @return $this
|
||||
*/
|
||||
public function between($startTime, $endTime)
|
||||
{
|
||||
return $this->when($this->inTimeInterval($startTime, $endTime));
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to not run between start and end time.
|
||||
*
|
||||
* @param string $startTime
|
||||
* @param string $endTime
|
||||
* @return $this
|
||||
*/
|
||||
public function unlessBetween($startTime, $endTime)
|
||||
{
|
||||
return $this->skip($this->inTimeInterval($startTime, $endTime));
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run between start and end time.
|
||||
*
|
||||
* @param string $startTime
|
||||
* @param string $endTime
|
||||
* @return \Closure
|
||||
*/
|
||||
private function inTimeInterval($startTime, $endTime)
|
||||
{
|
||||
[$now, $startTime, $endTime] = [
|
||||
Carbon::now($this->timezone),
|
||||
Carbon::parse($startTime, $this->timezone),
|
||||
Carbon::parse($endTime, $this->timezone),
|
||||
];
|
||||
|
||||
if ($endTime->lessThan($startTime)) {
|
||||
if ($startTime->greaterThan($now)) {
|
||||
$startTime = $startTime->subDay(1);
|
||||
} else {
|
||||
$endTime = $endTime->addDay(1);
|
||||
}
|
||||
}
|
||||
|
||||
return fn () => $now->between($startTime, $endTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every second.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everySecond()
|
||||
{
|
||||
return $this->repeatEvery(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every two seconds.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyTwoSeconds()
|
||||
{
|
||||
return $this->repeatEvery(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every five seconds.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyFiveSeconds()
|
||||
{
|
||||
return $this->repeatEvery(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every ten seconds.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyTenSeconds()
|
||||
{
|
||||
return $this->repeatEvery(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every fifteen seconds.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyFifteenSeconds()
|
||||
{
|
||||
return $this->repeatEvery(15);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every twenty seconds.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyTwentySeconds()
|
||||
{
|
||||
return $this->repeatEvery(20);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every thirty seconds.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyThirtySeconds()
|
||||
{
|
||||
return $this->repeatEvery(30);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run multiple times per minute.
|
||||
*
|
||||
* @param int $seconds
|
||||
* @return $this
|
||||
*/
|
||||
protected function repeatEvery($seconds)
|
||||
{
|
||||
if (60 % $seconds !== 0) {
|
||||
throw new InvalidArgumentException("The seconds [$seconds] are not evenly divisible by 60.");
|
||||
}
|
||||
|
||||
$this->repeatSeconds = $seconds;
|
||||
|
||||
return $this->everyMinute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every minute.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyMinute()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, '*');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every two minutes.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyTwoMinutes()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, '*/2');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every three minutes.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyThreeMinutes()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, '*/3');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every four minutes.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyFourMinutes()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, '*/4');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every five minutes.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyFiveMinutes()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, '*/5');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every ten minutes.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyTenMinutes()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, '*/10');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every fifteen minutes.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyFifteenMinutes()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, '*/15');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every thirty minutes.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function everyThirtyMinutes()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, '*/30');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run hourly.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function hourly()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run hourly at a given offset in the hour.
|
||||
*
|
||||
* @param array|string|int $offset
|
||||
* @return $this
|
||||
*/
|
||||
public function hourlyAt($offset)
|
||||
{
|
||||
return $this->hourBasedSchedule($offset, '*');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every odd hour.
|
||||
*
|
||||
* @param array|string|int $offset
|
||||
* @return $this
|
||||
*/
|
||||
public function everyOddHour($offset = 0)
|
||||
{
|
||||
return $this->hourBasedSchedule($offset, '1-23/2');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every two hours.
|
||||
*
|
||||
* @param array|string|int $offset
|
||||
* @return $this
|
||||
*/
|
||||
public function everyTwoHours($offset = 0)
|
||||
{
|
||||
return $this->hourBasedSchedule($offset, '*/2');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every three hours.
|
||||
*
|
||||
* @param array|string|int $offset
|
||||
* @return $this
|
||||
*/
|
||||
public function everyThreeHours($offset = 0)
|
||||
{
|
||||
return $this->hourBasedSchedule($offset, '*/3');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every four hours.
|
||||
*
|
||||
* @param array|string|int $offset
|
||||
* @return $this
|
||||
*/
|
||||
public function everyFourHours($offset = 0)
|
||||
{
|
||||
return $this->hourBasedSchedule($offset, '*/4');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run every six hours.
|
||||
*
|
||||
* @param array|string|int $offset
|
||||
* @return $this
|
||||
*/
|
||||
public function everySixHours($offset = 0)
|
||||
{
|
||||
return $this->hourBasedSchedule($offset, '*/6');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run daily.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function daily()
|
||||
{
|
||||
return $this->hourBasedSchedule(0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the command at a given time.
|
||||
*
|
||||
* @param string $time
|
||||
* @return $this
|
||||
*/
|
||||
public function at($time)
|
||||
{
|
||||
return $this->dailyAt($time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run daily at a given time (10:00, 19:30, etc).
|
||||
*
|
||||
* @param string $time
|
||||
* @return $this
|
||||
*/
|
||||
public function dailyAt($time)
|
||||
{
|
||||
$segments = explode(':', $time);
|
||||
|
||||
return $this->hourBasedSchedule(
|
||||
count($segments) === 2 ? (int) $segments[1] : '0',
|
||||
(int) $segments[0]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run twice daily.
|
||||
*
|
||||
* @param int $first
|
||||
* @param int $second
|
||||
* @return $this
|
||||
*/
|
||||
public function twiceDaily($first = 1, $second = 13)
|
||||
{
|
||||
return $this->twiceDailyAt($first, $second, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run twice daily at a given offset.
|
||||
*
|
||||
* @param int $first
|
||||
* @param int $second
|
||||
* @param int $offset
|
||||
* @return $this
|
||||
*/
|
||||
public function twiceDailyAt($first = 1, $second = 13, $offset = 0)
|
||||
{
|
||||
$hours = $first.','.$second;
|
||||
|
||||
return $this->hourBasedSchedule($offset, $hours);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run at the given minutes and hours.
|
||||
*
|
||||
* @param array|string|int $minutes
|
||||
* @param array|string|int $hours
|
||||
* @return $this
|
||||
*/
|
||||
protected function hourBasedSchedule($minutes, $hours)
|
||||
{
|
||||
$minutes = is_array($minutes) ? implode(',', $minutes) : $minutes;
|
||||
|
||||
$hours = is_array($hours) ? implode(',', $hours) : $hours;
|
||||
|
||||
return $this->spliceIntoPosition(1, $minutes)
|
||||
->spliceIntoPosition(2, $hours);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run only on weekdays.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function weekdays()
|
||||
{
|
||||
return $this->days(Schedule::MONDAY.'-'.Schedule::FRIDAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run only on weekends.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function weekends()
|
||||
{
|
||||
return $this->days(Schedule::SATURDAY.','.Schedule::SUNDAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run only on Mondays.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function mondays()
|
||||
{
|
||||
return $this->days(Schedule::MONDAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run only on Tuesdays.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function tuesdays()
|
||||
{
|
||||
return $this->days(Schedule::TUESDAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run only on Wednesdays.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function wednesdays()
|
||||
{
|
||||
return $this->days(Schedule::WEDNESDAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run only on Thursdays.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function thursdays()
|
||||
{
|
||||
return $this->days(Schedule::THURSDAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run only on Fridays.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function fridays()
|
||||
{
|
||||
return $this->days(Schedule::FRIDAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run only on Saturdays.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function saturdays()
|
||||
{
|
||||
return $this->days(Schedule::SATURDAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run only on Sundays.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function sundays()
|
||||
{
|
||||
return $this->days(Schedule::SUNDAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run weekly.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function weekly()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, 0)
|
||||
->spliceIntoPosition(2, 0)
|
||||
->spliceIntoPosition(5, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run weekly on a given day and time.
|
||||
*
|
||||
* @param array|mixed $dayOfWeek
|
||||
* @param string $time
|
||||
* @return $this
|
||||
*/
|
||||
public function weeklyOn($dayOfWeek, $time = '0:0')
|
||||
{
|
||||
$this->dailyAt($time);
|
||||
|
||||
return $this->days($dayOfWeek);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run monthly.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function monthly()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, 0)
|
||||
->spliceIntoPosition(2, 0)
|
||||
->spliceIntoPosition(3, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run monthly on a given day and time.
|
||||
*
|
||||
* @param int $dayOfMonth
|
||||
* @param string $time
|
||||
* @return $this
|
||||
*/
|
||||
public function monthlyOn($dayOfMonth = 1, $time = '0:0')
|
||||
{
|
||||
$this->dailyAt($time);
|
||||
|
||||
return $this->spliceIntoPosition(3, $dayOfMonth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run twice monthly at a given time.
|
||||
*
|
||||
* @param int $first
|
||||
* @param int $second
|
||||
* @param string $time
|
||||
* @return $this
|
||||
*/
|
||||
public function twiceMonthly($first = 1, $second = 16, $time = '0:0')
|
||||
{
|
||||
$daysOfMonth = $first.','.$second;
|
||||
|
||||
$this->dailyAt($time);
|
||||
|
||||
return $this->spliceIntoPosition(3, $daysOfMonth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run on the last day of the month.
|
||||
*
|
||||
* @param string $time
|
||||
* @return $this
|
||||
*/
|
||||
public function lastDayOfMonth($time = '0:0')
|
||||
{
|
||||
$this->dailyAt($time);
|
||||
|
||||
return $this->spliceIntoPosition(3, Carbon::now()->endOfMonth()->day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run quarterly.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function quarterly()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, 0)
|
||||
->spliceIntoPosition(2, 0)
|
||||
->spliceIntoPosition(3, 1)
|
||||
->spliceIntoPosition(4, '1-12/3');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run quarterly on a given day and time.
|
||||
*
|
||||
* @param int $dayOfQuarter
|
||||
* @param string $time
|
||||
* @return $this
|
||||
*/
|
||||
public function quarterlyOn($dayOfQuarter = 1, $time = '0:0')
|
||||
{
|
||||
$this->dailyAt($time);
|
||||
|
||||
return $this->spliceIntoPosition(3, $dayOfQuarter)
|
||||
->spliceIntoPosition(4, '1-12/3');
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run yearly.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function yearly()
|
||||
{
|
||||
return $this->spliceIntoPosition(1, 0)
|
||||
->spliceIntoPosition(2, 0)
|
||||
->spliceIntoPosition(3, 1)
|
||||
->spliceIntoPosition(4, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the event to run yearly on a given month, day, and time.
|
||||
*
|
||||
* @param int $month
|
||||
* @param int|string $dayOfMonth
|
||||
* @param string $time
|
||||
* @return $this
|
||||
*/
|
||||
public function yearlyOn($month = 1, $dayOfMonth = 1, $time = '0:0')
|
||||
{
|
||||
$this->dailyAt($time);
|
||||
|
||||
return $this->spliceIntoPosition(3, $dayOfMonth)
|
||||
->spliceIntoPosition(4, $month);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the days of the week the command should run on.
|
||||
*
|
||||
* @param array|mixed $days
|
||||
* @return $this
|
||||
*/
|
||||
public function days($days)
|
||||
{
|
||||
$days = is_array($days) ? $days : func_get_args();
|
||||
|
||||
return $this->spliceIntoPosition(5, implode(',', $days));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the timezone the date should be evaluated on.
|
||||
*
|
||||
* @param \DateTimeZone|string $timezone
|
||||
* @return $this
|
||||
*/
|
||||
public function timezone($timezone)
|
||||
{
|
||||
$this->timezone = $timezone;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splice the given value into the given position of the expression.
|
||||
*
|
||||
* @param int $position
|
||||
* @param string $value
|
||||
* @return $this
|
||||
*/
|
||||
protected function spliceIntoPosition($position, $value)
|
||||
{
|
||||
$segments = preg_split("/\s+/", $this->expression);
|
||||
|
||||
$segments[$position - 1] = $value;
|
||||
|
||||
return $this->cron(implode(' ', $segments));
|
||||
}
|
||||
}
|
||||
93
vendor/laravel/framework/src/Illuminate/Console/Scheduling/PendingEventAttributes.php
vendored
Normal file
93
vendor/laravel/framework/src/Illuminate/Console/Scheduling/PendingEventAttributes.php
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
/**
|
||||
* @mixin \Illuminate\Console\Scheduling\Schedule
|
||||
*/
|
||||
class PendingEventAttributes
|
||||
{
|
||||
use ManagesAttributes, ManagesFrequencies;
|
||||
|
||||
/**
|
||||
* Create a new pending event attributes instance.
|
||||
*/
|
||||
public function __construct(
|
||||
protected Schedule $schedule,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not allow the event to overlap each other.
|
||||
*
|
||||
* The expiration time of the underlying cache lock may be specified in minutes.
|
||||
*
|
||||
* @param int $expiresAt
|
||||
* @return $this
|
||||
*/
|
||||
public function withoutOverlapping($expiresAt = 1440)
|
||||
{
|
||||
$this->withoutOverlapping = true;
|
||||
|
||||
$this->expiresAt = $expiresAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the current attributes into the given event.
|
||||
*/
|
||||
public function mergeAttributes(Event $event): void
|
||||
{
|
||||
$event->expression = $this->expression;
|
||||
$event->repeatSeconds = $this->repeatSeconds;
|
||||
|
||||
if ($this->description !== null) {
|
||||
$event->name($this->description);
|
||||
}
|
||||
|
||||
if ($this->timezone !== null) {
|
||||
$event->timezone($this->timezone);
|
||||
}
|
||||
|
||||
if ($this->user !== null) {
|
||||
$event->user = $this->user;
|
||||
}
|
||||
|
||||
if (! empty($this->environments)) {
|
||||
$event->environments($this->environments);
|
||||
}
|
||||
|
||||
if ($this->evenInMaintenanceMode) {
|
||||
$event->evenInMaintenanceMode();
|
||||
}
|
||||
|
||||
if ($this->withoutOverlapping) {
|
||||
$event->withoutOverlapping($this->expiresAt);
|
||||
}
|
||||
|
||||
if ($this->onOneServer) {
|
||||
$event->onOneServer();
|
||||
}
|
||||
|
||||
if ($this->runInBackground) {
|
||||
$event->runInBackground();
|
||||
}
|
||||
|
||||
foreach ($this->filters as $filter) {
|
||||
$event->when($filter);
|
||||
}
|
||||
|
||||
foreach ($this->rejects as $reject) {
|
||||
$event->skip($reject);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy missing methods onto the underlying schedule.
|
||||
*/
|
||||
public function __call(string $method, array $parameters): mixed
|
||||
{
|
||||
return $this->schedule->{$method}(...$parameters);
|
||||
}
|
||||
}
|
||||
473
vendor/laravel/framework/src/Illuminate/Console/Scheduling/Schedule.php
vendored
Normal file
473
vendor/laravel/framework/src/Illuminate/Console/Scheduling/Schedule.php
vendored
Normal file
@@ -0,0 +1,473 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Closure;
|
||||
use DateTimeInterface;
|
||||
use Illuminate\Bus\UniqueLock;
|
||||
use Illuminate\Console\Application;
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Contracts\Bus\Dispatcher;
|
||||
use Illuminate\Contracts\Cache\Repository as Cache;
|
||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Queue\CallQueuedClosure;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\ProcessUtils;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* @mixin \Illuminate\Console\Scheduling\PendingEventAttributes
|
||||
*/
|
||||
class Schedule
|
||||
{
|
||||
use Macroable {
|
||||
__call as macroCall;
|
||||
}
|
||||
|
||||
const SUNDAY = 0;
|
||||
|
||||
const MONDAY = 1;
|
||||
|
||||
const TUESDAY = 2;
|
||||
|
||||
const WEDNESDAY = 3;
|
||||
|
||||
const THURSDAY = 4;
|
||||
|
||||
const FRIDAY = 5;
|
||||
|
||||
const SATURDAY = 6;
|
||||
|
||||
/**
|
||||
* All of the events on the schedule.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\Event[]
|
||||
*/
|
||||
protected $events = [];
|
||||
|
||||
/**
|
||||
* The event mutex implementation.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\EventMutex
|
||||
*/
|
||||
protected $eventMutex;
|
||||
|
||||
/**
|
||||
* The scheduling mutex implementation.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\SchedulingMutex
|
||||
*/
|
||||
protected $schedulingMutex;
|
||||
|
||||
/**
|
||||
* The timezone the date should be evaluated on.
|
||||
*
|
||||
* @var \DateTimeZone|string
|
||||
*/
|
||||
protected $timezone;
|
||||
|
||||
/**
|
||||
* The job dispatcher implementation.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Bus\Dispatcher
|
||||
*/
|
||||
protected $dispatcher;
|
||||
|
||||
/**
|
||||
* The cache of mutex results.
|
||||
*
|
||||
* @var array<string, bool>
|
||||
*/
|
||||
protected $mutexCache = [];
|
||||
|
||||
/**
|
||||
* The attributes to pass to the event.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\PendingEventAttributes|null
|
||||
*/
|
||||
protected $attributes;
|
||||
|
||||
/**
|
||||
* The schedule group attributes stack.
|
||||
*
|
||||
* @var array<int, PendingEventAttributes>
|
||||
*/
|
||||
protected array $groupStack = [];
|
||||
|
||||
/**
|
||||
* Create a new schedule instance.
|
||||
*
|
||||
* @param \DateTimeZone|string|null $timezone
|
||||
* @return void
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct($timezone = null)
|
||||
{
|
||||
$this->timezone = $timezone;
|
||||
|
||||
if (! class_exists(Container::class)) {
|
||||
throw new RuntimeException(
|
||||
'A container implementation is required to use the scheduler. Please install the illuminate/container package.'
|
||||
);
|
||||
}
|
||||
|
||||
$container = Container::getInstance();
|
||||
|
||||
$this->eventMutex = $container->bound(EventMutex::class)
|
||||
? $container->make(EventMutex::class)
|
||||
: $container->make(CacheEventMutex::class);
|
||||
|
||||
$this->schedulingMutex = $container->bound(SchedulingMutex::class)
|
||||
? $container->make(SchedulingMutex::class)
|
||||
: $container->make(CacheSchedulingMutex::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new callback event to the schedule.
|
||||
*
|
||||
* @param string|callable $callback
|
||||
* @param array $parameters
|
||||
* @return \Illuminate\Console\Scheduling\CallbackEvent
|
||||
*/
|
||||
public function call($callback, array $parameters = [])
|
||||
{
|
||||
$this->events[] = $event = new CallbackEvent(
|
||||
$this->eventMutex, $callback, $parameters, $this->timezone
|
||||
);
|
||||
|
||||
$this->mergePendingAttributes($event);
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new Artisan command event to the schedule.
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $parameters
|
||||
* @return \Illuminate\Console\Scheduling\Event
|
||||
*/
|
||||
public function command($command, array $parameters = [])
|
||||
{
|
||||
if (class_exists($command)) {
|
||||
$command = Container::getInstance()->make($command);
|
||||
|
||||
return $this->exec(
|
||||
Application::formatCommandString($command->getName()), $parameters,
|
||||
)->description($command->getDescription());
|
||||
}
|
||||
|
||||
return $this->exec(
|
||||
Application::formatCommandString($command), $parameters
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new job callback event to the schedule.
|
||||
*
|
||||
* @param object|string $job
|
||||
* @param string|null $queue
|
||||
* @param string|null $connection
|
||||
* @return \Illuminate\Console\Scheduling\CallbackEvent
|
||||
*/
|
||||
public function job($job, $queue = null, $connection = null)
|
||||
{
|
||||
$jobName = $job;
|
||||
|
||||
if (! is_string($job)) {
|
||||
$jobName = method_exists($job, 'displayName')
|
||||
? $job->displayName()
|
||||
: $job::class;
|
||||
}
|
||||
|
||||
return $this->name($jobName)->call(function () use ($job, $queue, $connection) {
|
||||
$job = is_string($job) ? Container::getInstance()->make($job) : $job;
|
||||
|
||||
if ($job instanceof ShouldQueue) {
|
||||
$this->dispatchToQueue($job, $queue ?? $job->queue, $connection ?? $job->connection);
|
||||
} else {
|
||||
$this->dispatchNow($job);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch the given job to the queue.
|
||||
*
|
||||
* @param object $job
|
||||
* @param string|null $queue
|
||||
* @param string|null $connection
|
||||
* @return void
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function dispatchToQueue($job, $queue, $connection)
|
||||
{
|
||||
if ($job instanceof Closure) {
|
||||
if (! class_exists(CallQueuedClosure::class)) {
|
||||
throw new RuntimeException(
|
||||
'To enable support for closure jobs, please install the illuminate/queue package.'
|
||||
);
|
||||
}
|
||||
|
||||
$job = CallQueuedClosure::create($job);
|
||||
}
|
||||
|
||||
if ($job instanceof ShouldBeUnique) {
|
||||
return $this->dispatchUniqueJobToQueue($job, $queue, $connection);
|
||||
}
|
||||
|
||||
$this->getDispatcher()->dispatch(
|
||||
$job->onConnection($connection)->onQueue($queue)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch the given unique job to the queue.
|
||||
*
|
||||
* @param object $job
|
||||
* @param string|null $queue
|
||||
* @param string|null $connection
|
||||
* @return void
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function dispatchUniqueJobToQueue($job, $queue, $connection)
|
||||
{
|
||||
if (! Container::getInstance()->bound(Cache::class)) {
|
||||
throw new RuntimeException('Cache driver not available. Scheduling unique jobs not supported.');
|
||||
}
|
||||
|
||||
if (! (new UniqueLock(Container::getInstance()->make(Cache::class)))->acquire($job)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->getDispatcher()->dispatch(
|
||||
$job->onConnection($connection)->onQueue($queue)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch the given job right now.
|
||||
*
|
||||
* @param object $job
|
||||
* @return void
|
||||
*/
|
||||
protected function dispatchNow($job)
|
||||
{
|
||||
$this->getDispatcher()->dispatchNow($job);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new command event to the schedule.
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $parameters
|
||||
* @return \Illuminate\Console\Scheduling\Event
|
||||
*/
|
||||
public function exec($command, array $parameters = [])
|
||||
{
|
||||
if (count($parameters)) {
|
||||
$command .= ' '.$this->compileParameters($parameters);
|
||||
}
|
||||
|
||||
$this->events[] = $event = new Event($this->eventMutex, $command, $this->timezone);
|
||||
|
||||
$this->mergePendingAttributes($event);
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new schedule group.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return void
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function group(Closure $events)
|
||||
{
|
||||
if ($this->attributes === null) {
|
||||
throw new RuntimeException('Invoke an attribute method such as Schedule::daily() before defining a schedule group.');
|
||||
}
|
||||
|
||||
$this->groupStack[] = $this->attributes;
|
||||
|
||||
$events($this);
|
||||
|
||||
array_pop($this->groupStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the current group attributes with the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return void
|
||||
*/
|
||||
protected function mergePendingAttributes(Event $event)
|
||||
{
|
||||
if (isset($this->attributes)) {
|
||||
$this->attributes->mergeAttributes($event);
|
||||
|
||||
$this->attributes = null;
|
||||
}
|
||||
|
||||
if (! empty($this->groupStack)) {
|
||||
$group = end($this->groupStack);
|
||||
|
||||
$group->mergeAttributes($event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile parameters for a command.
|
||||
*
|
||||
* @param array $parameters
|
||||
* @return string
|
||||
*/
|
||||
protected function compileParameters(array $parameters)
|
||||
{
|
||||
return (new Collection($parameters))->map(function ($value, $key) {
|
||||
if (is_array($value)) {
|
||||
return $this->compileArrayInput($key, $value);
|
||||
}
|
||||
|
||||
if (! is_numeric($value) && ! preg_match('/^(-.$|--.*)/i', $value)) {
|
||||
$value = ProcessUtils::escapeArgument($value);
|
||||
}
|
||||
|
||||
return is_numeric($key) ? $value : "{$key}={$value}";
|
||||
})->implode(' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile array input for a command.
|
||||
*
|
||||
* @param string|int $key
|
||||
* @param array $value
|
||||
* @return string
|
||||
*/
|
||||
public function compileArrayInput($key, $value)
|
||||
{
|
||||
$value = (new Collection($value))->map(function ($value) {
|
||||
return ProcessUtils::escapeArgument($value);
|
||||
});
|
||||
|
||||
if (str_starts_with($key, '--')) {
|
||||
$value = $value->map(function ($value) use ($key) {
|
||||
return "{$key}={$value}";
|
||||
});
|
||||
} elseif (str_starts_with($key, '-')) {
|
||||
$value = $value->map(function ($value) use ($key) {
|
||||
return "{$key} {$value}";
|
||||
});
|
||||
}
|
||||
|
||||
return $value->implode(' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the server is allowed to run this event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @param \DateTimeInterface $time
|
||||
* @return bool
|
||||
*/
|
||||
public function serverShouldRun(Event $event, DateTimeInterface $time)
|
||||
{
|
||||
return $this->mutexCache[$event->mutexName()] ??= $this->schedulingMutex->create($event, $time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the events on the schedule that are due.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Foundation\Application $app
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function dueEvents($app)
|
||||
{
|
||||
return (new Collection($this->events))->filter->isDue($app);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the events on the schedule.
|
||||
*
|
||||
* @return \Illuminate\Console\Scheduling\Event[]
|
||||
*/
|
||||
public function events()
|
||||
{
|
||||
return $this->events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the cache store that should be used to store mutexes.
|
||||
*
|
||||
* @param string $store
|
||||
* @return $this
|
||||
*/
|
||||
public function useCache($store)
|
||||
{
|
||||
if ($this->eventMutex instanceof CacheAware) {
|
||||
$this->eventMutex->useStore($store);
|
||||
}
|
||||
|
||||
if ($this->schedulingMutex instanceof CacheAware) {
|
||||
$this->schedulingMutex->useStore($store);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the job dispatcher, if available.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Bus\Dispatcher
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function getDispatcher()
|
||||
{
|
||||
if ($this->dispatcher === null) {
|
||||
try {
|
||||
$this->dispatcher = Container::getInstance()->make(Dispatcher::class);
|
||||
} catch (BindingResolutionException $e) {
|
||||
throw new RuntimeException(
|
||||
'Unable to resolve the dispatcher from the service container. Please bind it or install the illuminate/bus package.',
|
||||
is_int($e->getCode()) ? $e->getCode() : 0, $e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->dispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically handle calls into the schedule instance.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
if (static::hasMacro($method)) {
|
||||
return $this->macroCall($method, $parameters);
|
||||
}
|
||||
|
||||
if (method_exists(PendingEventAttributes::class, $method)) {
|
||||
$this->attributes ??= end($this->groupStack) ?: new PendingEventAttributes($this);
|
||||
|
||||
return $this->attributes->$method(...$parameters);
|
||||
}
|
||||
|
||||
throw new BadMethodCallException(sprintf(
|
||||
'Method %s::%s does not exist.', static::class, $method
|
||||
));
|
||||
}
|
||||
}
|
||||
49
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleClearCacheCommand.php
vendored
Normal file
49
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleClearCacheCommand.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
|
||||
#[AsCommand(name: 'schedule:clear-cache')]
|
||||
class ScheduleClearCacheCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'schedule:clear-cache';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Delete the cached mutex files created by scheduler';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
public function handle(Schedule $schedule)
|
||||
{
|
||||
$mutexCleared = false;
|
||||
|
||||
foreach ($schedule->events($this->laravel) as $event) {
|
||||
if ($event->mutex->exists($event)) {
|
||||
$this->components->info(sprintf('Deleting mutex for [%s]', $event->command));
|
||||
|
||||
$event->mutex->forget($event);
|
||||
|
||||
$mutexCleared = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (! $mutexCleared) {
|
||||
$this->components->info('No mutex files were found.');
|
||||
}
|
||||
}
|
||||
}
|
||||
51
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleFinishCommand.php
vendored
Normal file
51
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleFinishCommand.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Console\Events\ScheduledBackgroundTaskFinished;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Support\Collection;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
|
||||
#[AsCommand(name: 'schedule:finish')]
|
||||
class ScheduleFinishCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'schedule:finish {id} {code=0}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Handle the completion of a scheduled command';
|
||||
|
||||
/**
|
||||
* Indicates whether the command should be shown in the Artisan command list.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $hidden = true;
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
public function handle(Schedule $schedule)
|
||||
{
|
||||
(new Collection($schedule->events()))->filter(function ($value) {
|
||||
return $value->mutexName() == $this->argument('id');
|
||||
})->each(function ($event) {
|
||||
$event->finish($this->laravel, $this->argument('code'));
|
||||
|
||||
$this->laravel->make(Dispatcher::class)->dispatch(new ScheduledBackgroundTaskFinished($event));
|
||||
});
|
||||
}
|
||||
}
|
||||
58
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleInterruptCommand.php
vendored
Normal file
58
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleInterruptCommand.php
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Contracts\Cache\Repository as Cache;
|
||||
use Illuminate\Support\Facades\Date;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
|
||||
#[AsCommand(name: 'schedule:interrupt')]
|
||||
class ScheduleInterruptCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'schedule:interrupt';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Interrupt the current schedule run';
|
||||
|
||||
/**
|
||||
* The cache store implementation.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Cache\Repository
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* Create a new schedule interrupt command.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Cache\Repository $cache
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Cache $cache)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->cache->put('illuminate:schedule:interrupt', true, Date::now()->endOfMinute());
|
||||
|
||||
$this->components->info('Broadcasting schedule interrupt signal.');
|
||||
}
|
||||
}
|
||||
304
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleListCommand.php
vendored
Normal file
304
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleListCommand.php
vendored
Normal file
@@ -0,0 +1,304 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Closure;
|
||||
use Cron\CronExpression;
|
||||
use DateTimeZone;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use ReflectionClass;
|
||||
use ReflectionFunction;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Terminal;
|
||||
|
||||
#[AsCommand(name: 'schedule:list')]
|
||||
class ScheduleListCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'schedule:list
|
||||
{--timezone= : The timezone that times should be displayed in}
|
||||
{--next : Sort the listed tasks by their next due date}
|
||||
';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'List all scheduled tasks';
|
||||
|
||||
/**
|
||||
* The terminal width resolver callback.
|
||||
*
|
||||
* @var \Closure|null
|
||||
*/
|
||||
protected static $terminalWidthResolver;
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function handle(Schedule $schedule)
|
||||
{
|
||||
$events = new Collection($schedule->events());
|
||||
|
||||
if ($events->isEmpty()) {
|
||||
$this->components->info('No scheduled tasks have been defined.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$terminalWidth = self::getTerminalWidth();
|
||||
|
||||
$expressionSpacing = $this->getCronExpressionSpacing($events);
|
||||
|
||||
$repeatExpressionSpacing = $this->getRepeatExpressionSpacing($events);
|
||||
|
||||
$timezone = new DateTimeZone($this->option('timezone') ?? config('app.timezone'));
|
||||
|
||||
$events = $this->sortEvents($events, $timezone);
|
||||
|
||||
$events = $events->map(function ($event) use ($terminalWidth, $expressionSpacing, $repeatExpressionSpacing, $timezone) {
|
||||
return $this->listEvent($event, $terminalWidth, $expressionSpacing, $repeatExpressionSpacing, $timezone);
|
||||
});
|
||||
|
||||
$this->line(
|
||||
$events->flatten()->filter()->prepend('')->push('')->toArray()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the spacing to be used on each event row.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $events
|
||||
* @return array<int, int>
|
||||
*/
|
||||
private function getCronExpressionSpacing($events)
|
||||
{
|
||||
$rows = $events->map(fn ($event) => array_map('mb_strlen', preg_split("/\s+/", $event->expression)));
|
||||
|
||||
return (new Collection($rows[0] ?? []))->keys()->map(fn ($key) => $rows->max($key))->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the spacing to be used on each event row.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $events
|
||||
* @return int
|
||||
*/
|
||||
private function getRepeatExpressionSpacing($events)
|
||||
{
|
||||
return $events->map(fn ($event) => mb_strlen($this->getRepeatExpression($event)))->max();
|
||||
}
|
||||
|
||||
/**
|
||||
* List the given even in the console.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @param int $terminalWidth
|
||||
* @param array $expressionSpacing
|
||||
* @param int $repeatExpressionSpacing
|
||||
* @param \DateTimeZone $timezone
|
||||
* @return array
|
||||
*/
|
||||
private function listEvent($event, $terminalWidth, $expressionSpacing, $repeatExpressionSpacing, $timezone)
|
||||
{
|
||||
$expression = $this->formatCronExpression($event->expression, $expressionSpacing);
|
||||
|
||||
$repeatExpression = str_pad($this->getRepeatExpression($event), $repeatExpressionSpacing);
|
||||
|
||||
$command = $event->command ?? '';
|
||||
|
||||
$description = $event->description ?? '';
|
||||
|
||||
if (! $this->output->isVerbose()) {
|
||||
$command = $event->normalizeCommand($command);
|
||||
}
|
||||
|
||||
if ($event instanceof CallbackEvent) {
|
||||
$command = $event->getSummaryForDisplay();
|
||||
|
||||
if (in_array($command, ['Closure', 'Callback'])) {
|
||||
$command = 'Closure at: '.$this->getClosureLocation($event);
|
||||
}
|
||||
}
|
||||
|
||||
$command = mb_strlen($command) > 1 ? "{$command} " : '';
|
||||
|
||||
$nextDueDateLabel = 'Next Due:';
|
||||
|
||||
$nextDueDate = $this->getNextDueDateForEvent($event, $timezone);
|
||||
|
||||
$nextDueDate = $this->output->isVerbose()
|
||||
? $nextDueDate->format('Y-m-d H:i:s P')
|
||||
: $nextDueDate->diffForHumans();
|
||||
|
||||
$hasMutex = $event->mutex->exists($event) ? 'Has Mutex › ' : '';
|
||||
|
||||
$dots = str_repeat('.', max(
|
||||
$terminalWidth - mb_strlen($expression.$repeatExpression.$command.$nextDueDateLabel.$nextDueDate.$hasMutex) - 8, 0
|
||||
));
|
||||
|
||||
// Highlight the parameters...
|
||||
$command = preg_replace("#(php artisan [\w\-:]+) (.+)#", '$1 <fg=yellow;options=bold>$2</>', $command);
|
||||
|
||||
return [sprintf(
|
||||
' <fg=yellow>%s</> <fg=#6C7280>%s</> %s<fg=#6C7280>%s %s%s %s</>',
|
||||
$expression,
|
||||
$repeatExpression,
|
||||
$command,
|
||||
$dots,
|
||||
$hasMutex,
|
||||
$nextDueDateLabel,
|
||||
$nextDueDate
|
||||
), $this->output->isVerbose() && mb_strlen($description) > 1 ? sprintf(
|
||||
' <fg=#6C7280>%s%s %s</>',
|
||||
str_repeat(' ', mb_strlen($expression) + 2),
|
||||
'⇁',
|
||||
$description
|
||||
) : ''];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the repeat expression for an event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return string
|
||||
*/
|
||||
private function getRepeatExpression($event)
|
||||
{
|
||||
return $event->isRepeatable() ? "{$event->repeatSeconds}s " : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the events by due date if option set.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $events
|
||||
* @param \DateTimeZone $timezone
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
private function sortEvents(\Illuminate\Support\Collection $events, DateTimeZone $timezone)
|
||||
{
|
||||
return $this->option('next')
|
||||
? $events->sortBy(fn ($event) => $this->getNextDueDateForEvent($event, $timezone))
|
||||
: $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next due date for an event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @param \DateTimeZone $timezone
|
||||
* @return \Illuminate\Support\Carbon
|
||||
*/
|
||||
private function getNextDueDateForEvent($event, DateTimeZone $timezone)
|
||||
{
|
||||
$nextDueDate = Carbon::instance(
|
||||
(new CronExpression($event->expression))
|
||||
->getNextRunDate(Carbon::now()->setTimezone($event->timezone))
|
||||
->setTimezone($timezone)
|
||||
);
|
||||
|
||||
if (! $event->isRepeatable()) {
|
||||
return $nextDueDate;
|
||||
}
|
||||
|
||||
$previousDueDate = Carbon::instance(
|
||||
(new CronExpression($event->expression))
|
||||
->getPreviousRunDate(Carbon::now()->setTimezone($event->timezone), allowCurrentDate: true)
|
||||
->setTimezone($timezone)
|
||||
);
|
||||
|
||||
$now = Carbon::now()->setTimezone($event->timezone);
|
||||
|
||||
if (! $now->copy()->startOfMinute()->eq($previousDueDate)) {
|
||||
return $nextDueDate;
|
||||
}
|
||||
|
||||
return $now
|
||||
->endOfSecond()
|
||||
->ceilSeconds($event->repeatSeconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the cron expression based on the spacing provided.
|
||||
*
|
||||
* @param string $expression
|
||||
* @param array<int, int> $spacing
|
||||
* @return string
|
||||
*/
|
||||
private function formatCronExpression($expression, $spacing)
|
||||
{
|
||||
$expressions = preg_split("/\s+/", $expression);
|
||||
|
||||
return (new Collection($spacing))
|
||||
->map(fn ($length, $index) => str_pad($expressions[$index], $length))
|
||||
->implode(' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file and line number for the event closure.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\CallbackEvent $event
|
||||
* @return string
|
||||
*/
|
||||
private function getClosureLocation(CallbackEvent $event)
|
||||
{
|
||||
$callback = (new ReflectionClass($event))->getProperty('callback')->getValue($event);
|
||||
|
||||
if ($callback instanceof Closure) {
|
||||
$function = new ReflectionFunction($callback);
|
||||
|
||||
return sprintf(
|
||||
'%s:%s',
|
||||
str_replace($this->laravel->basePath().DIRECTORY_SEPARATOR, '', $function->getFileName() ?: ''),
|
||||
$function->getStartLine()
|
||||
);
|
||||
}
|
||||
|
||||
if (is_string($callback)) {
|
||||
return $callback;
|
||||
}
|
||||
|
||||
if (is_array($callback)) {
|
||||
$className = is_string($callback[0]) ? $callback[0] : $callback[0]::class;
|
||||
|
||||
return sprintf('%s::%s', $className, $callback[1]);
|
||||
}
|
||||
|
||||
return sprintf('%s::__invoke', $callback::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the terminal width.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getTerminalWidth()
|
||||
{
|
||||
return is_null(static::$terminalWidthResolver)
|
||||
? (new Terminal)->getWidth()
|
||||
: call_user_func(static::$terminalWidthResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback that should be used when resolving the terminal width.
|
||||
*
|
||||
* @param \Closure|null $resolver
|
||||
* @return void
|
||||
*/
|
||||
public static function resolveTerminalWidthUsing($resolver)
|
||||
{
|
||||
static::$terminalWidthResolver = $resolver;
|
||||
}
|
||||
}
|
||||
280
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleRunCommand.php
vendored
Normal file
280
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleRunCommand.php
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Console\Application;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Console\Events\ScheduledTaskFailed;
|
||||
use Illuminate\Console\Events\ScheduledTaskFinished;
|
||||
use Illuminate\Console\Events\ScheduledTaskSkipped;
|
||||
use Illuminate\Console\Events\ScheduledTaskStarting;
|
||||
use Illuminate\Contracts\Cache\Repository as Cache;
|
||||
use Illuminate\Contracts\Debug\ExceptionHandler;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Date;
|
||||
use Illuminate\Support\Sleep;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Throwable;
|
||||
|
||||
#[AsCommand(name: 'schedule:run')]
|
||||
class ScheduleRunCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'schedule:run';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Run the scheduled commands';
|
||||
|
||||
/**
|
||||
* The schedule instance.
|
||||
*
|
||||
* @var \Illuminate\Console\Scheduling\Schedule
|
||||
*/
|
||||
protected $schedule;
|
||||
|
||||
/**
|
||||
* The 24 hour timestamp this scheduler command started running.
|
||||
*
|
||||
* @var \Illuminate\Support\Carbon
|
||||
*/
|
||||
protected $startedAt;
|
||||
|
||||
/**
|
||||
* Check if any events ran.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $eventsRan = false;
|
||||
|
||||
/**
|
||||
* The event dispatcher.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Events\Dispatcher
|
||||
*/
|
||||
protected $dispatcher;
|
||||
|
||||
/**
|
||||
* The exception handler.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Debug\ExceptionHandler
|
||||
*/
|
||||
protected $handler;
|
||||
|
||||
/**
|
||||
* The cache store implementation.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Cache\Repository
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* The PHP binary used by the command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $phpBinary;
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->startedAt = Date::now();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @param \Illuminate\Contracts\Events\Dispatcher $dispatcher
|
||||
* @param \Illuminate\Contracts\Cache\Repository $cache
|
||||
* @param \Illuminate\Contracts\Debug\ExceptionHandler $handler
|
||||
* @return void
|
||||
*/
|
||||
public function handle(Schedule $schedule, Dispatcher $dispatcher, Cache $cache, ExceptionHandler $handler)
|
||||
{
|
||||
$this->schedule = $schedule;
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->cache = $cache;
|
||||
$this->handler = $handler;
|
||||
$this->phpBinary = Application::phpBinary();
|
||||
|
||||
$this->clearInterruptSignal();
|
||||
|
||||
$this->newLine();
|
||||
|
||||
$events = $this->schedule->dueEvents($this->laravel);
|
||||
|
||||
foreach ($events as $event) {
|
||||
if (! $event->filtersPass($this->laravel)) {
|
||||
$this->dispatcher->dispatch(new ScheduledTaskSkipped($event));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($event->onOneServer) {
|
||||
$this->runSingleServerEvent($event);
|
||||
} else {
|
||||
$this->runEvent($event);
|
||||
}
|
||||
|
||||
$this->eventsRan = true;
|
||||
}
|
||||
|
||||
if ($events->contains->isRepeatable()) {
|
||||
$this->repeatEvents($events->filter->isRepeatable());
|
||||
}
|
||||
|
||||
if (! $this->eventsRan) {
|
||||
$this->components->info('No scheduled commands are ready to run.');
|
||||
} else {
|
||||
$this->newLine();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the given single server event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return void
|
||||
*/
|
||||
protected function runSingleServerEvent($event)
|
||||
{
|
||||
if ($this->schedule->serverShouldRun($event, $this->startedAt)) {
|
||||
$this->runEvent($event);
|
||||
} else {
|
||||
$this->components->info(sprintf(
|
||||
'Skipping [%s], as command already run on another server.', $event->getSummaryForDisplay()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @return void
|
||||
*/
|
||||
protected function runEvent($event)
|
||||
{
|
||||
$summary = $event->getSummaryForDisplay();
|
||||
|
||||
$command = $event instanceof CallbackEvent
|
||||
? $summary
|
||||
: trim(str_replace($this->phpBinary, '', $event->command));
|
||||
|
||||
$description = sprintf(
|
||||
'<fg=gray>%s</> Running [%s]%s',
|
||||
Carbon::now()->format('Y-m-d H:i:s'),
|
||||
$command,
|
||||
$event->runInBackground ? ' in background' : '',
|
||||
);
|
||||
|
||||
$this->components->task($description, function () use ($event) {
|
||||
$this->dispatcher->dispatch(new ScheduledTaskStarting($event));
|
||||
|
||||
$start = microtime(true);
|
||||
|
||||
try {
|
||||
$event->run($this->laravel);
|
||||
|
||||
$this->dispatcher->dispatch(new ScheduledTaskFinished(
|
||||
$event,
|
||||
round(microtime(true) - $start, 2)
|
||||
));
|
||||
|
||||
$this->eventsRan = true;
|
||||
} catch (Throwable $e) {
|
||||
$this->dispatcher->dispatch(new ScheduledTaskFailed($event, $e));
|
||||
|
||||
$this->handler->report($e);
|
||||
}
|
||||
|
||||
return $event->exitCode == 0;
|
||||
});
|
||||
|
||||
if (! $event instanceof CallbackEvent) {
|
||||
$this->components->bulletList([
|
||||
$event->getSummaryForDisplay(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the given repeating events.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection<\Illuminate\Console\Scheduling\Event> $events
|
||||
* @return void
|
||||
*/
|
||||
protected function repeatEvents($events)
|
||||
{
|
||||
$hasEnteredMaintenanceMode = false;
|
||||
|
||||
while (Date::now()->lte($this->startedAt->endOfMinute())) {
|
||||
foreach ($events as $event) {
|
||||
if ($this->shouldInterrupt()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $event->shouldRepeatNow()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$hasEnteredMaintenanceMode = $hasEnteredMaintenanceMode || $this->laravel->isDownForMaintenance();
|
||||
|
||||
if ($hasEnteredMaintenanceMode && ! $event->runsInMaintenanceMode()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $event->filtersPass($this->laravel)) {
|
||||
$this->dispatcher->dispatch(new ScheduledTaskSkipped($event));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($event->onOneServer) {
|
||||
$this->runSingleServerEvent($event);
|
||||
} else {
|
||||
$this->runEvent($event);
|
||||
}
|
||||
|
||||
$this->eventsRan = true;
|
||||
}
|
||||
|
||||
Sleep::usleep(100000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the schedule run should be interrupted.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function shouldInterrupt()
|
||||
{
|
||||
return $this->cache->get('illuminate:schedule:interrupt', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the interrupt signal is cleared.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function clearInterruptSignal()
|
||||
{
|
||||
$this->cache->forget('illuminate:schedule:interrupt');
|
||||
}
|
||||
}
|
||||
117
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleTestCommand.php
vendored
Normal file
117
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleTestCommand.php
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Console\Application;
|
||||
use Illuminate\Console\Command;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
|
||||
use function Laravel\Prompts\select;
|
||||
|
||||
#[AsCommand(name: 'schedule:test')]
|
||||
class ScheduleTestCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'schedule:test {--name= : The name of the scheduled command to run}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Run a scheduled command';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
public function handle(Schedule $schedule)
|
||||
{
|
||||
$phpBinary = Application::phpBinary();
|
||||
|
||||
$commands = $schedule->events();
|
||||
|
||||
$commandNames = [];
|
||||
|
||||
foreach ($commands as $command) {
|
||||
$commandNames[] = $command->command ?? $command->getSummaryForDisplay();
|
||||
}
|
||||
|
||||
if (empty($commandNames)) {
|
||||
return $this->components->info('No scheduled commands have been defined.');
|
||||
}
|
||||
|
||||
if (! empty($name = $this->option('name'))) {
|
||||
$commandBinary = $phpBinary.' '.Application::artisanBinary();
|
||||
|
||||
$matches = array_filter($commandNames, function ($commandName) use ($commandBinary, $name) {
|
||||
return trim(str_replace($commandBinary, '', $commandName)) === $name;
|
||||
});
|
||||
|
||||
if (count($matches) !== 1) {
|
||||
$this->components->info('No matching scheduled command found.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$index = key($matches);
|
||||
} else {
|
||||
$index = $this->getSelectedCommandByIndex($commandNames);
|
||||
}
|
||||
|
||||
$event = $commands[$index];
|
||||
|
||||
$summary = $event->getSummaryForDisplay();
|
||||
|
||||
$command = $event instanceof CallbackEvent
|
||||
? $summary
|
||||
: trim(str_replace($phpBinary, '', $event->command));
|
||||
|
||||
$description = sprintf(
|
||||
'Running [%s]%s',
|
||||
$command,
|
||||
$event->runInBackground ? ' in background' : '',
|
||||
);
|
||||
|
||||
$this->components->task($description, fn () => $event->run($this->laravel));
|
||||
|
||||
if (! $event instanceof CallbackEvent) {
|
||||
$this->components->bulletList([$event->getSummaryForDisplay()]);
|
||||
}
|
||||
|
||||
$this->newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selected command name by index.
|
||||
*
|
||||
* @param array $commandNames
|
||||
* @return int
|
||||
*/
|
||||
protected function getSelectedCommandByIndex(array $commandNames)
|
||||
{
|
||||
if (count($commandNames) !== count(array_unique($commandNames))) {
|
||||
// Some commands (likely closures) have the same name, append unique indexes to each one...
|
||||
$uniqueCommandNames = array_map(function ($index, $value) {
|
||||
return "$value [$index]";
|
||||
}, array_keys($commandNames), $commandNames);
|
||||
|
||||
$selectedCommand = select('Which command would you like to run?', $uniqueCommandNames);
|
||||
|
||||
preg_match('/\[(\d+)\]/', $selectedCommand, $choice);
|
||||
|
||||
return (int) $choice[1];
|
||||
} else {
|
||||
return array_search(
|
||||
select('Which command would you like to run?', $commandNames),
|
||||
$commandNames
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
74
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleWorkCommand.php
vendored
Normal file
74
vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleWorkCommand.php
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use Illuminate\Console\Application;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\ProcessUtils;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
#[AsCommand(name: 'schedule:work')]
|
||||
class ScheduleWorkCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'schedule:work {--run-output-file= : The file to direct <info>schedule:run</info> output to}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Start the schedule worker';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->components->info(
|
||||
'Running scheduled tasks.',
|
||||
$this->getLaravel()->environment('local') ? OutputInterface::VERBOSITY_NORMAL : OutputInterface::VERBOSITY_VERBOSE
|
||||
);
|
||||
|
||||
[$lastExecutionStartedAt, $executions] = [Carbon::now()->subMinutes(10), []];
|
||||
|
||||
$command = Application::formatCommandString('schedule:run');
|
||||
|
||||
if ($this->option('run-output-file')) {
|
||||
$command .= ' >> '.ProcessUtils::escapeArgument($this->option('run-output-file')).' 2>&1';
|
||||
}
|
||||
|
||||
while (true) {
|
||||
usleep(100 * 1000);
|
||||
|
||||
if (Carbon::now()->second === 0 &&
|
||||
! Carbon::now()->startOfMinute()->equalTo($lastExecutionStartedAt)) {
|
||||
$executions[] = $execution = Process::fromShellCommandline($command);
|
||||
|
||||
$execution->start();
|
||||
|
||||
$lastExecutionStartedAt = Carbon::now()->startOfMinute();
|
||||
}
|
||||
|
||||
foreach ($executions as $key => $execution) {
|
||||
$output = $execution->getIncrementalOutput().
|
||||
$execution->getIncrementalErrorOutput();
|
||||
|
||||
$this->output->write(ltrim($output, "\n"));
|
||||
|
||||
if (! $execution->isRunning()) {
|
||||
unset($executions[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
26
vendor/laravel/framework/src/Illuminate/Console/Scheduling/SchedulingMutex.php
vendored
Normal file
26
vendor/laravel/framework/src/Illuminate/Console/Scheduling/SchedulingMutex.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\Scheduling;
|
||||
|
||||
use DateTimeInterface;
|
||||
|
||||
interface SchedulingMutex
|
||||
{
|
||||
/**
|
||||
* Attempt to obtain a scheduling mutex for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @param \DateTimeInterface $time
|
||||
* @return bool
|
||||
*/
|
||||
public function create(Event $event, DateTimeInterface $time);
|
||||
|
||||
/**
|
||||
* Determine if a scheduling mutex exists for the given event.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Event $event
|
||||
* @param \DateTimeInterface $time
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(Event $event, DateTimeInterface $time);
|
||||
}
|
||||
152
vendor/laravel/framework/src/Illuminate/Console/Signals.php
vendored
Normal file
152
vendor/laravel/framework/src/Illuminate/Console/Signals.php
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class Signals
|
||||
{
|
||||
/**
|
||||
* The signal registry instance.
|
||||
*
|
||||
* @var \Symfony\Component\Console\SignalRegistry\SignalRegistry
|
||||
*/
|
||||
protected $registry;
|
||||
|
||||
/**
|
||||
* The signal registry's previous list of handlers.
|
||||
*
|
||||
* @var array<int, array<int, callable>>|null
|
||||
*/
|
||||
protected $previousHandlers;
|
||||
|
||||
/**
|
||||
* The current availability resolver, if any.
|
||||
*
|
||||
* @var (callable(): bool)|null
|
||||
*/
|
||||
protected static $availabilityResolver;
|
||||
|
||||
/**
|
||||
* Create a new signal registrar instance.
|
||||
*
|
||||
* @param \Symfony\Component\Console\SignalRegistry\SignalRegistry $registry
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($registry)
|
||||
{
|
||||
$this->registry = $registry;
|
||||
|
||||
$this->previousHandlers = $this->getHandlers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new signal handler.
|
||||
*
|
||||
* @param int $signal
|
||||
* @param callable(int $signal): void $callback
|
||||
* @return void
|
||||
*/
|
||||
public function register($signal, $callback)
|
||||
{
|
||||
$this->previousHandlers[$signal] ??= $this->initializeSignal($signal);
|
||||
|
||||
with($this->getHandlers(), function ($handlers) use ($signal) {
|
||||
$handlers[$signal] ??= $this->initializeSignal($signal);
|
||||
|
||||
$this->setHandlers($handlers);
|
||||
});
|
||||
|
||||
$this->registry->register($signal, $callback);
|
||||
|
||||
with($this->getHandlers(), function ($handlers) use ($signal) {
|
||||
$lastHandlerInserted = array_pop($handlers[$signal]);
|
||||
|
||||
array_unshift($handlers[$signal], $lastHandlerInserted);
|
||||
|
||||
$this->setHandlers($handlers);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the signal's existing handler in array format.
|
||||
*
|
||||
* @return array<int, callable(int $signal): void>
|
||||
*/
|
||||
protected function initializeSignal($signal)
|
||||
{
|
||||
return is_callable($existingHandler = pcntl_signal_get_handler($signal))
|
||||
? [$existingHandler]
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister the current signal handlers.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
$previousHandlers = $this->previousHandlers;
|
||||
|
||||
foreach ($previousHandlers as $signal => $handler) {
|
||||
if (is_null($handler)) {
|
||||
pcntl_signal($signal, SIG_DFL);
|
||||
|
||||
unset($previousHandlers[$signal]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->setHandlers($previousHandlers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the given callback if "signals" should be used and are available.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return void
|
||||
*/
|
||||
public static function whenAvailable($callback)
|
||||
{
|
||||
$resolver = static::$availabilityResolver;
|
||||
|
||||
if ($resolver()) {
|
||||
$callback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the registry's handlers.
|
||||
*
|
||||
* @return array<int, array<int, callable>>
|
||||
*/
|
||||
protected function getHandlers()
|
||||
{
|
||||
return (fn () => $this->signalHandlers)
|
||||
->call($this->registry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the registry's handlers.
|
||||
*
|
||||
* @param array<int, array<int, callable(int $signal):void>> $handlers
|
||||
* @return void
|
||||
*/
|
||||
protected function setHandlers($handlers)
|
||||
{
|
||||
(fn () => $this->signalHandlers = $handlers)
|
||||
->call($this->registry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the availability resolver.
|
||||
*
|
||||
* @param (callable(): bool) $resolver
|
||||
* @return void
|
||||
*/
|
||||
public static function resolveAvailabilityUsing($resolver)
|
||||
{
|
||||
static::$availabilityResolver = $resolver;
|
||||
}
|
||||
}
|
||||
28
vendor/laravel/framework/src/Illuminate/Console/View/Components/Alert.php
vendored
Normal file
28
vendor/laravel/framework/src/Illuminate/Console/View/Components/Alert.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class Alert extends Component
|
||||
{
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function render($string, $verbosity = OutputInterface::VERBOSITY_NORMAL)
|
||||
{
|
||||
$string = $this->mutate($string, [
|
||||
Mutators\EnsureDynamicContentIsHighlighted::class,
|
||||
Mutators\EnsurePunctuation::class,
|
||||
Mutators\EnsureRelativePaths::class,
|
||||
]);
|
||||
|
||||
$this->renderView('alert', [
|
||||
'content' => $string,
|
||||
], $verbosity);
|
||||
}
|
||||
}
|
||||
26
vendor/laravel/framework/src/Illuminate/Console/View/Components/Ask.php
vendored
Normal file
26
vendor/laravel/framework/src/Illuminate/Console/View/Components/Ask.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
|
||||
class Ask extends Component
|
||||
{
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $question
|
||||
* @param string $default
|
||||
* @param bool $multiline
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($question, $default = null, $multiline = false)
|
||||
{
|
||||
return $this->usingQuestionHelper(
|
||||
fn () => $this->output->askQuestion(
|
||||
(new Question($question, $default))
|
||||
->setMultiline($multiline)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
29
vendor/laravel/framework/src/Illuminate/Console/View/Components/AskWithCompletion.php
vendored
Normal file
29
vendor/laravel/framework/src/Illuminate/Console/View/Components/AskWithCompletion.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
|
||||
class AskWithCompletion extends Component
|
||||
{
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $question
|
||||
* @param array|callable $choices
|
||||
* @param string $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($question, $choices, $default = null)
|
||||
{
|
||||
$question = new Question($question, $default);
|
||||
|
||||
is_callable($choices)
|
||||
? $question->setAutocompleterCallback($choices)
|
||||
: $question->setAutocompleterValues($choices);
|
||||
|
||||
return $this->usingQuestionHelper(
|
||||
fn () => $this->output->askQuestion($question)
|
||||
);
|
||||
}
|
||||
}
|
||||
28
vendor/laravel/framework/src/Illuminate/Console/View/Components/BulletList.php
vendored
Normal file
28
vendor/laravel/framework/src/Illuminate/Console/View/Components/BulletList.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class BulletList extends Component
|
||||
{
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param array<int, string> $elements
|
||||
* @param int $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function render($elements, $verbosity = OutputInterface::VERBOSITY_NORMAL)
|
||||
{
|
||||
$elements = $this->mutate($elements, [
|
||||
Mutators\EnsureDynamicContentIsHighlighted::class,
|
||||
Mutators\EnsureNoPunctuation::class,
|
||||
Mutators\EnsureRelativePaths::class,
|
||||
]);
|
||||
|
||||
$this->renderView('bullet-list', [
|
||||
'elements' => $elements,
|
||||
], $verbosity);
|
||||
}
|
||||
}
|
||||
48
vendor/laravel/framework/src/Illuminate/Console/View/Components/Choice.php
vendored
Normal file
48
vendor/laravel/framework/src/Illuminate/Console/View/Components/Choice.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
|
||||
class Choice extends Component
|
||||
{
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $question
|
||||
* @param array<array-key, string> $choices
|
||||
* @param mixed $default
|
||||
* @param int $attempts
|
||||
* @param bool $multiple
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($question, $choices, $default = null, $attempts = null, $multiple = false)
|
||||
{
|
||||
return $this->usingQuestionHelper(
|
||||
fn () => $this->output->askQuestion(
|
||||
$this->getChoiceQuestion($question, $choices, $default)
|
||||
->setMaxAttempts($attempts)
|
||||
->setMultiselect($multiple)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a ChoiceQuestion instance that handles array keys like Prompts.
|
||||
*
|
||||
* @param string $question
|
||||
* @param array $choices
|
||||
* @param mixed $default
|
||||
* @return \Symfony\Component\Console\Question\ChoiceQuestion
|
||||
*/
|
||||
protected function getChoiceQuestion($question, $choices, $default)
|
||||
{
|
||||
return new class($question, $choices, $default) extends ChoiceQuestion
|
||||
{
|
||||
protected function isAssoc(array $array): bool
|
||||
{
|
||||
return ! array_is_list($array);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
123
vendor/laravel/framework/src/Illuminate/Console/View/Components/Component.php
vendored
Normal file
123
vendor/laravel/framework/src/Illuminate/Console/View/Components/Component.php
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Illuminate\Console\OutputStyle;
|
||||
use Illuminate\Console\QuestionHelper;
|
||||
use ReflectionClass;
|
||||
use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
|
||||
|
||||
use function Termwind\render;
|
||||
use function Termwind\renderUsing;
|
||||
|
||||
abstract class Component
|
||||
{
|
||||
/**
|
||||
* The output style implementation.
|
||||
*
|
||||
* @var \Illuminate\Console\OutputStyle
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* The list of mutators to apply on the view data.
|
||||
*
|
||||
* @var array<int, callable(string): string>
|
||||
*/
|
||||
protected $mutators;
|
||||
|
||||
/**
|
||||
* Creates a new component instance.
|
||||
*
|
||||
* @param \Illuminate\Console\OutputStyle $output
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($output)
|
||||
{
|
||||
$this->output = $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the given view.
|
||||
*
|
||||
* @param string $view
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|array $data
|
||||
* @param int $verbosity
|
||||
* @return void
|
||||
*/
|
||||
protected function renderView($view, $data, $verbosity)
|
||||
{
|
||||
renderUsing($this->output);
|
||||
|
||||
render((string) $this->compile($view, $data), $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the given view contents.
|
||||
*
|
||||
* @param string $view
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
protected function compile($view, $data)
|
||||
{
|
||||
extract($data);
|
||||
|
||||
ob_start();
|
||||
|
||||
include __DIR__."/../../resources/views/components/$view.php";
|
||||
|
||||
return tap(ob_get_contents(), function () {
|
||||
ob_end_clean();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutates the given data with the given set of mutators.
|
||||
*
|
||||
* @param array<int, string>|string $data
|
||||
* @param array<int, callable(string): string> $mutators
|
||||
* @return array<int, string>|string
|
||||
*/
|
||||
protected function mutate($data, $mutators)
|
||||
{
|
||||
foreach ($mutators as $mutator) {
|
||||
$mutator = new $mutator;
|
||||
|
||||
if (is_iterable($data)) {
|
||||
foreach ($data as $key => $value) {
|
||||
$data[$key] = $mutator($value);
|
||||
}
|
||||
} else {
|
||||
$data = $mutator($data);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eventually performs a question using the component's question helper.
|
||||
*
|
||||
* @param callable $callable
|
||||
* @return mixed
|
||||
*/
|
||||
protected function usingQuestionHelper($callable)
|
||||
{
|
||||
$property = with(new ReflectionClass(OutputStyle::class))
|
||||
->getParentClass()
|
||||
->getProperty('questionHelper');
|
||||
|
||||
$currentHelper = $property->isInitialized($this->output)
|
||||
? $property->getValue($this->output)
|
||||
: new SymfonyQuestionHelper();
|
||||
|
||||
$property->setValue($this->output, new QuestionHelper);
|
||||
|
||||
try {
|
||||
return $callable();
|
||||
} finally {
|
||||
$property->setValue($this->output, $currentHelper);
|
||||
}
|
||||
}
|
||||
}
|
||||
20
vendor/laravel/framework/src/Illuminate/Console/View/Components/Confirm.php
vendored
Normal file
20
vendor/laravel/framework/src/Illuminate/Console/View/Components/Confirm.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
class Confirm extends Component
|
||||
{
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $question
|
||||
* @param bool $default
|
||||
* @return bool
|
||||
*/
|
||||
public function render($question, $default = false)
|
||||
{
|
||||
return $this->usingQuestionHelper(
|
||||
fn () => $this->output->confirm($question, $default),
|
||||
);
|
||||
}
|
||||
}
|
||||
20
vendor/laravel/framework/src/Illuminate/Console/View/Components/Error.php
vendored
Normal file
20
vendor/laravel/framework/src/Illuminate/Console/View/Components/Error.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class Error extends Component
|
||||
{
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function render($string, $verbosity = OutputInterface::VERBOSITY_NORMAL)
|
||||
{
|
||||
with(new Line($this->output))->render('error', $string, $verbosity);
|
||||
}
|
||||
}
|
||||
62
vendor/laravel/framework/src/Illuminate/Console/View/Components/Factory.php
vendored
Normal file
62
vendor/laravel/framework/src/Illuminate/Console/View/Components/Factory.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @method void alert(string $string, int $verbosity = \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL)
|
||||
* @method mixed ask(string $question, string $default = null, bool $multiline = false)
|
||||
* @method mixed askWithCompletion(string $question, array|callable $choices, string $default = null)
|
||||
* @method void bulletList(array $elements, int $verbosity = \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL)
|
||||
* @method mixed choice(string $question, array $choices, $default = null, int $attempts = null, bool $multiple = false)
|
||||
* @method bool confirm(string $question, bool $default = false)
|
||||
* @method void info(string $string, int $verbosity = \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL)
|
||||
* @method void success(string $string, int $verbosity = \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL)
|
||||
* @method void error(string $string, int $verbosity = \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL)
|
||||
* @method void line(string $style, string $string, int $verbosity = \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL)
|
||||
* @method void secret(string $question, bool $fallback = true)
|
||||
* @method void task(string $description, ?callable $task = null, int $verbosity = \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL)
|
||||
* @method void twoColumnDetail(string $first, ?string $second = null, int $verbosity = \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL)
|
||||
* @method void warn(string $string, int $verbosity = \Symfony\Component\Console\Output\OutputInterface::VERBOSITY_NORMAL)
|
||||
*/
|
||||
class Factory
|
||||
{
|
||||
/**
|
||||
* The output interface implementation.
|
||||
*
|
||||
* @var \Illuminate\Console\OutputStyle
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* Creates a new factory instance.
|
||||
*
|
||||
* @param \Illuminate\Console\OutputStyle $output
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($output)
|
||||
{
|
||||
$this->output = $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically handle calls into the component instance.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
$component = '\Illuminate\Console\View\Components\\'.ucfirst($method);
|
||||
|
||||
throw_unless(class_exists($component), new InvalidArgumentException(sprintf(
|
||||
'Console component [%s] not found.', $method
|
||||
)));
|
||||
|
||||
return with(new $component($this->output))->render(...$parameters);
|
||||
}
|
||||
}
|
||||
20
vendor/laravel/framework/src/Illuminate/Console/View/Components/Info.php
vendored
Normal file
20
vendor/laravel/framework/src/Illuminate/Console/View/Components/Info.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class Info extends Component
|
||||
{
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function render($string, $verbosity = OutputInterface::VERBOSITY_NORMAL)
|
||||
{
|
||||
with(new Line($this->output))->render('info', $string, $verbosity);
|
||||
}
|
||||
}
|
||||
59
vendor/laravel/framework/src/Illuminate/Console/View/Components/Line.php
vendored
Normal file
59
vendor/laravel/framework/src/Illuminate/Console/View/Components/Line.php
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Illuminate\Console\Contracts\NewLineAware;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class Line extends Component
|
||||
{
|
||||
/**
|
||||
* The possible line styles.
|
||||
*
|
||||
* @var array<string, array<string, string>>
|
||||
*/
|
||||
protected static $styles = [
|
||||
'info' => [
|
||||
'bgColor' => 'blue',
|
||||
'fgColor' => 'white',
|
||||
'title' => 'info',
|
||||
],
|
||||
'success' => [
|
||||
'bgColor' => 'green',
|
||||
'fgColor' => 'white',
|
||||
'title' => 'success',
|
||||
],
|
||||
'warn' => [
|
||||
'bgColor' => 'yellow',
|
||||
'fgColor' => 'black',
|
||||
'title' => 'warn',
|
||||
],
|
||||
'error' => [
|
||||
'bgColor' => 'red',
|
||||
'fgColor' => 'white',
|
||||
'title' => 'error',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $style
|
||||
* @param string $string
|
||||
* @param int $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function render($style, $string, $verbosity = OutputInterface::VERBOSITY_NORMAL)
|
||||
{
|
||||
$string = $this->mutate($string, [
|
||||
Mutators\EnsureDynamicContentIsHighlighted::class,
|
||||
Mutators\EnsurePunctuation::class,
|
||||
Mutators\EnsureRelativePaths::class,
|
||||
]);
|
||||
|
||||
$this->renderView('line', array_merge(static::$styles[$style], [
|
||||
'marginTop' => $this->output instanceof NewLineAware ? max(0, 2 - $this->output->newLinesWritten()) : 1,
|
||||
'content' => $string,
|
||||
]), $verbosity);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components\Mutators;
|
||||
|
||||
class EnsureDynamicContentIsHighlighted
|
||||
{
|
||||
/**
|
||||
* Highlight dynamic content within the given string.
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function __invoke($string)
|
||||
{
|
||||
return preg_replace('/\[([^\]]+)\]/', '<options=bold>[$1]</>', (string) $string);
|
||||
}
|
||||
}
|
||||
23
vendor/laravel/framework/src/Illuminate/Console/View/Components/Mutators/EnsureNoPunctuation.php
vendored
Normal file
23
vendor/laravel/framework/src/Illuminate/Console/View/Components/Mutators/EnsureNoPunctuation.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components\Mutators;
|
||||
|
||||
use Illuminate\Support\Stringable;
|
||||
|
||||
class EnsureNoPunctuation
|
||||
{
|
||||
/**
|
||||
* Ensures the given string does not end with punctuation.
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function __invoke($string)
|
||||
{
|
||||
if ((new Stringable($string))->endsWith(['.', '?', '!', ':'])) {
|
||||
return substr_replace($string, '', -1);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
23
vendor/laravel/framework/src/Illuminate/Console/View/Components/Mutators/EnsurePunctuation.php
vendored
Normal file
23
vendor/laravel/framework/src/Illuminate/Console/View/Components/Mutators/EnsurePunctuation.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components\Mutators;
|
||||
|
||||
use Illuminate\Support\Stringable;
|
||||
|
||||
class EnsurePunctuation
|
||||
{
|
||||
/**
|
||||
* Ensures the given string ends with punctuation.
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function __invoke($string)
|
||||
{
|
||||
if (! (new Stringable($string))->endsWith(['.', '?', '!', ':'])) {
|
||||
return "$string.";
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
21
vendor/laravel/framework/src/Illuminate/Console/View/Components/Mutators/EnsureRelativePaths.php
vendored
Normal file
21
vendor/laravel/framework/src/Illuminate/Console/View/Components/Mutators/EnsureRelativePaths.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components\Mutators;
|
||||
|
||||
class EnsureRelativePaths
|
||||
{
|
||||
/**
|
||||
* Ensures the given string only contains relative paths.
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function __invoke($string)
|
||||
{
|
||||
if (function_exists('app') && app()->has('path.base')) {
|
||||
$string = str_replace(base_path().'/', '', $string);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
24
vendor/laravel/framework/src/Illuminate/Console/View/Components/Secret.php
vendored
Normal file
24
vendor/laravel/framework/src/Illuminate/Console/View/Components/Secret.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
|
||||
class Secret extends Component
|
||||
{
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $question
|
||||
* @param bool $fallback
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($question, $fallback = true)
|
||||
{
|
||||
$question = new Question($question);
|
||||
|
||||
$question->setHidden(true)->setHiddenFallback($fallback);
|
||||
|
||||
return $this->usingQuestionHelper(fn () => $this->output->askQuestion($question));
|
||||
}
|
||||
}
|
||||
20
vendor/laravel/framework/src/Illuminate/Console/View/Components/Success.php
vendored
Normal file
20
vendor/laravel/framework/src/Illuminate/Console/View/Components/Success.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class Success extends Component
|
||||
{
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function render($string, $verbosity = OutputInterface::VERBOSITY_NORMAL)
|
||||
{
|
||||
with(new Line($this->output))->render('success', $string, $verbosity);
|
||||
}
|
||||
}
|
||||
61
vendor/laravel/framework/src/Illuminate/Console/View/Components/Task.php
vendored
Normal file
61
vendor/laravel/framework/src/Illuminate/Console/View/Components/Task.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Illuminate\Support\InteractsWithTime;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Throwable;
|
||||
|
||||
use function Termwind\terminal;
|
||||
|
||||
class Task extends Component
|
||||
{
|
||||
use InteractsWithTime;
|
||||
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $description
|
||||
* @param (callable(): bool)|null $task
|
||||
* @param int $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function render($description, $task = null, $verbosity = OutputInterface::VERBOSITY_NORMAL)
|
||||
{
|
||||
$description = $this->mutate($description, [
|
||||
Mutators\EnsureDynamicContentIsHighlighted::class,
|
||||
Mutators\EnsureNoPunctuation::class,
|
||||
Mutators\EnsureRelativePaths::class,
|
||||
]);
|
||||
|
||||
$descriptionWidth = mb_strlen(preg_replace("/\<[\w=#\/\;,:.&,%?]+\>|\\e\[\d+m/", '$1', $description) ?? '');
|
||||
|
||||
$this->output->write(" $description ", false, $verbosity);
|
||||
|
||||
$startTime = microtime(true);
|
||||
|
||||
$result = false;
|
||||
|
||||
try {
|
||||
$result = ($task ?: fn () => true)();
|
||||
} catch (Throwable $e) {
|
||||
throw $e;
|
||||
} finally {
|
||||
$runTime = $task
|
||||
? (' '.$this->runTimeForHumans($startTime))
|
||||
: '';
|
||||
|
||||
$runTimeWidth = mb_strlen($runTime);
|
||||
$width = min(terminal()->width(), 150);
|
||||
$dots = max($width - $descriptionWidth - $runTimeWidth - 10, 0);
|
||||
|
||||
$this->output->write(str_repeat('<fg=gray>.</>', $dots), false, $verbosity);
|
||||
$this->output->write("<fg=gray>$runTime</>", false, $verbosity);
|
||||
|
||||
$this->output->writeln(
|
||||
$result !== false ? ' <fg=green;options=bold>DONE</>' : ' <fg=red;options=bold>FAIL</>',
|
||||
$verbosity,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
vendor/laravel/framework/src/Illuminate/Console/View/Components/TwoColumnDetail.php
vendored
Normal file
36
vendor/laravel/framework/src/Illuminate/Console/View/Components/TwoColumnDetail.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class TwoColumnDetail extends Component
|
||||
{
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $first
|
||||
* @param string|null $second
|
||||
* @param int $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function render($first, $second = null, $verbosity = OutputInterface::VERBOSITY_NORMAL)
|
||||
{
|
||||
$first = $this->mutate($first, [
|
||||
Mutators\EnsureDynamicContentIsHighlighted::class,
|
||||
Mutators\EnsureNoPunctuation::class,
|
||||
Mutators\EnsureRelativePaths::class,
|
||||
]);
|
||||
|
||||
$second = $this->mutate($second, [
|
||||
Mutators\EnsureDynamicContentIsHighlighted::class,
|
||||
Mutators\EnsureNoPunctuation::class,
|
||||
Mutators\EnsureRelativePaths::class,
|
||||
]);
|
||||
|
||||
$this->renderView('two-column-detail', [
|
||||
'first' => $first,
|
||||
'second' => $second,
|
||||
], $verbosity);
|
||||
}
|
||||
}
|
||||
21
vendor/laravel/framework/src/Illuminate/Console/View/Components/Warn.php
vendored
Normal file
21
vendor/laravel/framework/src/Illuminate/Console/View/Components/Warn.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Console\View\Components;
|
||||
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class Warn extends Component
|
||||
{
|
||||
/**
|
||||
* Renders the component using the given arguments.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $verbosity
|
||||
* @return void
|
||||
*/
|
||||
public function render($string, $verbosity = OutputInterface::VERBOSITY_NORMAL)
|
||||
{
|
||||
with(new Line($this->output))
|
||||
->render('warn', $string, $verbosity);
|
||||
}
|
||||
}
|
||||
53
vendor/laravel/framework/src/Illuminate/Console/composer.json
vendored
Executable file
53
vendor/laravel/framework/src/Illuminate/Console/composer.json
vendored
Executable file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"name": "illuminate/console",
|
||||
"description": "The Illuminate Console package.",
|
||||
"license": "MIT",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"ext-mbstring": "*",
|
||||
"illuminate/collections": "^11.0",
|
||||
"illuminate/contracts": "^11.0",
|
||||
"illuminate/macroable": "^11.0",
|
||||
"illuminate/support": "^11.0",
|
||||
"illuminate/view": "^11.0",
|
||||
"laravel/prompts": "^0.1.20|^0.2|^0.3",
|
||||
"nunomaduro/termwind": "^2.0",
|
||||
"symfony/console": "^7.0.3",
|
||||
"symfony/polyfill-php83": "^1.31",
|
||||
"symfony/process": "^7.0.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Console\\": ""
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "11.x-dev"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"ext-pcntl": "Required to use signal trapping.",
|
||||
"dragonmantank/cron-expression": "Required to use scheduler (^3.3.2).",
|
||||
"guzzlehttp/guzzle": "Required to use the ping methods on schedules (^7.8).",
|
||||
"illuminate/bus": "Required to use the scheduled job dispatcher (^11.0).",
|
||||
"illuminate/container": "Required to use the scheduler (^11.0).",
|
||||
"illuminate/filesystem": "Required to use the generator command (^11.0).",
|
||||
"illuminate/queue": "Required to use closures for scheduled jobs (^11.0)."
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
3
vendor/laravel/framework/src/Illuminate/Console/resources/views/components/alert.php
vendored
Normal file
3
vendor/laravel/framework/src/Illuminate/Console/resources/views/components/alert.php
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<div class="w-full mx-2 py-1 mt-1 bg-yellow text-black text-center uppercase">
|
||||
<?php echo htmlspecialchars($content) ?>
|
||||
</div>
|
||||
7
vendor/laravel/framework/src/Illuminate/Console/resources/views/components/bullet-list.php
vendored
Normal file
7
vendor/laravel/framework/src/Illuminate/Console/resources/views/components/bullet-list.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<div>
|
||||
<?php foreach ($elements as $element) { ?>
|
||||
<div class="text-gray mx-2">
|
||||
⇂ <?php echo htmlspecialchars($element) ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
8
vendor/laravel/framework/src/Illuminate/Console/resources/views/components/line.php
vendored
Normal file
8
vendor/laravel/framework/src/Illuminate/Console/resources/views/components/line.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<div class="mx-2 mb-1 mt-<?php echo $marginTop ?>">
|
||||
<span class="px-1 bg-<?php echo $bgColor ?> text-<?php echo $fgColor ?> uppercase"><?php echo $title ?></span>
|
||||
<span class="<?php if ($title) {
|
||||
echo 'ml-1';
|
||||
} ?>">
|
||||
<?php echo htmlspecialchars($content) ?>
|
||||
</span>
|
||||
</div>
|
||||
11
vendor/laravel/framework/src/Illuminate/Console/resources/views/components/two-column-detail.php
vendored
Normal file
11
vendor/laravel/framework/src/Illuminate/Console/resources/views/components/two-column-detail.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<div class="flex mx-2 max-w-150">
|
||||
<span>
|
||||
<?php echo htmlspecialchars($first) ?>
|
||||
</span>
|
||||
<span class="flex-1 content-repeat-[.] text-gray ml-1"></span>
|
||||
<?php if ($second !== '') { ?>
|
||||
<span class="ml-1">
|
||||
<?php echo htmlspecialchars($second) ?>
|
||||
</span>
|
||||
<?php } ?>
|
||||
</div>
|
||||
Reference in New Issue
Block a user