/vendor/laravel/framework/src/Illuminate/Console/Scheduling/Event.php
PHP | 635 lines | 522 code | 21 blank | 92 comment | 1 complexity | 084068e31690d0bc3d3bb4ba4f2969c8 MD5 | raw file
Possible License(s): BSD-3-Clause
- <?php
- namespace Illuminate\Console\Scheduling;
- use Closure;
- use Carbon\Carbon;
- use Cron\CronExpression;
- use GuzzleHttp\Client as HttpClient;
- use Illuminate\Contracts\Mail\Mailer;
- use Symfony\Component\Process\Process;
- use Illuminate\Support\Traits\Macroable;
- use Illuminate\Contracts\Container\Container;
- use Illuminate\Contracts\Cache\Repository as Cache;
- class Event
- {
- use Macroable, ManagesFrequencies;
- /**
- * The cache store implementation.
- *
- * @var \Illuminate\Contracts\Cache\Repository
- */
- protected $cache;
- /**
- * The command string.
- *
- * @var string
- */
- public $command;
- /**
- * The cron expression representing the event's frequency.
- *
- * @var string
- */
- public $expression = '* * * * * *';
- /**
- * The timezone the date should be evaluated on.
- *
- * @var \DateTimeZone|string
- */
- public $timezone;
- /**
- * The user the command should run as.
- *
- * @var string
- */
- 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 run in 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 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 human readable description of the event.
- *
- * @var string
- */
- public $description;
- /**
- * Create a new event instance.
- *
- * @param \Illuminate\Contracts\Cache\Repository $cache
- * @param string $command
- * @return void
- */
- public function __construct(Cache $cache, $command)
- {
- $this->cache = $cache;
- $this->command = $command;
- $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
- */
- public function run(Container $container)
- {
- if ($this->withoutOverlapping) {
- $this->cache->put($this->mutexName(), true, 1440);
- }
- $this->runInBackground
- ? $this->runCommandInBackground($container)
- : $this->runCommandInForeground($container);
- }
- /**
- * Get the mutex name for the scheduled command.
- *
- * @return string
- */
- public function mutexName()
- {
- return 'framework'.DIRECTORY_SEPARATOR.'schedule-'.sha1($this->expression.$this->command);
- }
- /**
- * Run the command in the foreground.
- *
- * @param \Illuminate\Contracts\Container\Container $container
- * @return void
- */
- protected function runCommandInForeground(Container $container)
- {
- $this->callBeforeCallbacks($container);
- (new Process(
- $this->buildCommand(), base_path(), null, null, null
- ))->run();
- $this->callAfterCallbacks($container);
- }
- /**
- * Run the command in the background.
- *
- * @param \Illuminate\Contracts\Container\Container $container
- * @return void
- */
- protected function runCommandInBackground(Container $container)
- {
- $this->callBeforeCallbacks($container);
- (new Process(
- $this->buildCommand(), base_path(), null, null, null
- ))->run();
- }
- /**
- * 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 = Carbon::now();
- if ($this->timezone) {
- $date->setTimezone($this->timezone);
- }
- return CronExpression::factory($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)
- {
- foreach ($this->filters as $callback) {
- if (! $app->call($callback)) {
- return false;
- }
- }
- foreach ($this->rejects as $callback) {
- if ($app->call($callback)) {
- return false;
- }
- }
- return true;
- }
- /**
- * 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->ensureOutputIsBeingCapturedForEmail();
- $addresses = is_array($addresses) ? $addresses : func_get_args();
- 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);
- }
- /**
- * Ensure that output is being captured for email.
- *
- * @return void
- */
- protected function ensureOutputIsBeingCapturedForEmail()
- {
- 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 = 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';
- }
- /**
- * Register a callback to ping a given URL before the job runs.
- *
- * @param string $url
- * @return $this
- */
- public function pingBefore($url)
- {
- return $this->before(function () use ($url) {
- (new HttpClient)->get($url);
- });
- }
- /**
- * Register a callback to ping a given URL after the job runs.
- *
- * @param string $url
- * @return $this
- */
- public function thenPing($url)
- {
- return $this->then(function () use ($url) {
- (new HttpClient)->get($url);
- });
- }
- /**
- * State that the command should run in background.
- *
- * @return $this
- */
- public function runInBackground()
- {
- $this->runInBackground = true;
- return $this;
- }
- /**
- * 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.
- *
- * @return $this
- */
- public function withoutOverlapping()
- {
- $this->withoutOverlapping = true;
- return $this->then(function () {
- $this->cache->forget($this->mutexName());
- })->skip(function () {
- return $this->cache->has($this->mutexName());
- });
- }
- /**
- * Register a callback to further filter the schedule.
- *
- * @param \Closure $callback
- * @return $this
- */
- public function when(Closure $callback)
- {
- $this->filters[] = $callback;
- return $this;
- }
- /**
- * Register a callback to further filter the schedule.
- *
- * @param \Closure $callback
- * @return $this
- */
- public function skip(Closure $callback)
- {
- $this->rejects[] = $callback;
- return $this;
- }
- /**
- * 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)
- {
- $this->afterCallbacks[] = $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;
- }
- /**
- * Get the summary of the event for display.
- *
- * @return string
- */
- public function getSummaryForDisplay()
- {
- if (is_string($this->description)) {
- return $this->description;
- }
- return $this->buildCommand();
- }
- /**
- * Get the Cron expression for the event.
- *
- * @return string
- */
- public function getExpression()
- {
- return $this->expression;
- }
- }