Skip to content

Instantly share code, notes, and snippets.

@kellymears
Created August 1, 2019 17:07
Show Gist options
  • Save kellymears/1e94c9d11172d9a609540f4964cdb8f7 to your computer and use it in GitHub Desktop.
Save kellymears/1e94c9d11172d9a609540f4964cdb8f7 to your computer and use it in GitHub Desktop.
Roots\Acorn\Console\Scheduling\Schedule
<?php
namespace Roots\Acorn\Console\Scheduling;
use \DateTimeZone;
use \DateTimeInterface;
use Illuminate\Support\ProcessUtils;
use Illuminate\Support\Collection;
use Illuminate\Console\Scheduling\Event;
use Illuminate\Console\Scheduling\EventMutex;
use Illuminate\Console\Scheduling\CallbackEvent;
use Illuminate\Console\Scheduling\CacheEventMutex;
use Illuminate\Console\Scheduling\CacheSchedulingMutex;
use Illuminate\Console\Scheduling\Schedule as ScheduleBase;
use Symfony\Component\Process\PhpExecutableFinder;
use Roots\Acorn\Application;
class Schedule extends ScheduleBase
{
/**
* 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;
/**
* Create a new schedule instance.
*
* @param \DateTimeZone|string|null $timezone
* @return void
*/
public function __construct($timezone = null)
{
$this->timezone = $timezone;
$container = Application::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
);
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 = Application::getInstance()->make($command)->getName();
}
return $this->exec(
self::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)
{
return $this->call(function () use ($job, $queue, $connection) {
$job = is_string($job) ? resolve($job) : $job;
if ($job instanceof ShouldQueue) {
dispatch($job)
->onConnection($connection ?? $job->connection)
->onQueue($queue ?? $job->queue);
} else {
dispatch_now($job);
}
})->name(is_string($job) ? $job : get_class($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);
return $event;
}
/**
* Compile parameters for a command.
*
* @param array $parameters
* @return string
*/
protected function compileParameters(array $parameters)
{
return Collection::make($parameters)->map(function ($value, $key) {
if (is_array($value)) {
$value = Collection::make($value)->map(function ($value) {
return ProcessUtils::escapeArgument($value);
})->implode(' ');
} elseif (! is_numeric($value) && ! preg_match('/^(-.$|--.*)/i', $value)) {
$value = ProcessUtils::escapeArgument($value);
}
return is_numeric($key) ? $value : "{$key}={$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->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 Collection::make($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 CacheEventMutex) {
$this->eventMutex->useStore($store);
}
if ($this->schedulingMutex instanceof CacheSchedulingMutex) {
$this->schedulingMutex->useStore($store);
}
return $this;
}
/**
* 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', self::phpBinary(), self::artisanBinary(), $string);
}
/**
* Determine the proper PHP executable.
*
* @return string
*/
public static function phpBinary()
{
return ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false));
}
/**
* Determine the proper Artisan executable.
*
* @return string
*/
public static function artisanBinary()
{
return defined('ARTISAN_BINARY') ? ProcessUtils::escapeArgument(ARTISAN_BINARY) : 'artisan';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment