将自定义方法添加到Laravel 5调度程序

3
我想知道添加周末等可用时间限制的最佳方法,如何实现呢?
Illuminate\Console\Scheduling\Event.php
public function weekdays()
{
    return $this->spliceIntoPosition(5, '1-5');
}

以及它的逻辑反义:

public function weekends()
{
        return $this->days(array( '0','6'));
}

我应该把这些东西放在哪里,以便它们不会在框架更新时被覆盖?

3个回答

3
首先,如果你只需要缺失的weekends()方法,你可以在事件上调用days(6,7)来实现。
如果你需要为调度程序添加更多逻辑,请继续阅读。
我看了一下代码,虽然Laravel没有提供一种扩展Scheduler及其预定Events的方法,但仍然可以从你的Kernel::schedule()应用附加约束。
根据你的需求,有两种方法可以实现。
  1. If you want to set some custom CRON expression for an event, you can simply use its cron() method:

    protected function schedule(Schedule $schedule)
    {
        $schedule->call(function () {
            //scheduled code
        })->cron('0 1 2 * * *')->daily();
    }
    
  2. If you need to apply some CRON constraints using existing methods, but need to modify it later the way weekdays() does using spliceIntoPosition, you can access it by calling getExpression(), modify it, and then set using cron().

    protected function schedule(Schedule $schedule)
    {
        $event = $schedule->call(function () {
            //scheduled code
        });
    
        $scheduledAt = $event->getExpression(); //get cron expression
    
        ...; //modify the $scheduledAt expression
    
        $event->cron($scheduledAt); // set the new schedule for that even
    }
    

如果您想要为多个事件重复使用逻辑,可以在您的 Kernel.php 中添加帮助函数,例如:

    protected function specialSchedule(\Illuminate\Console\Scheduling\Event $event) {
      $scheduledAt = $event->getExpression();

      ...; // modify $scheduledAt expression

      $event->cron($scheduledAt);

      return $event;
    }

那么在定义计划时,您可以重复使用该逻辑:

    protected function schedule(Schedule $schedule)
    {
        $this->specialSchedule($schedule->call(function () {
            //scheduled code
        }));
    }

更新:

还有一种更加复杂但也更加灵活的方法可以实现此功能,需要你提供自己的Schedule和Event类。

首先,实现你自己的Event类,并添加以下新方法:

    class CustomEvent extends \Illuminate\Console\Scheduling\CallbackEvent {
      public function weekends() {
        return $this->days(6,7);
      }
    }

接下来是您自己的Schedule类,使其创建CustomEvent对象:

    class CustomSchedule extends \Illuminate\Console\Scheduling\Schedule 
    {
      public function call($callback, array $parameters = [])
      {
        $this->events[] = $event = new CustomEvent($callback, $parameters);

         return $event;
      }

      public function exec($command, array $parameters = [])
      {
        if (count($parameters)) {
          $command .= ' '.$this->compileParameters($parameters);
        }

        $this->events[] = $event = new Event($command);

        return $event;
      }
   }

最后,在您的Kernel.php中,您需要确保使用您的新调度类进行调度:
    protected function defineConsoleSchedule()
    {
      $this->app->instance(
        'Illuminate\Console\Scheduling\Schedule', $schedule = new Schedule
      );

      $this->schedule($schedule);
    }

是的,我非常清楚内置的cron方法,我只是想知道在哪里可以创建一个->weekends()方法,或者特别针对我的用途:->holiday(),当然这将是许多不总是以数字方式静态存在的天数,例如感恩节,或者不总是在固定日期(12月25日)。我希望找到一种像正常的->weekdays()命令一样调用它们的方法。 - Ben W

0

Illuminate\Console\Scheduling\Event 类使用 Macroable 特性。这意味着您可以在不继承该类的情况下动态地向其添加方法。

首先,您必须在 boot 方法中注册它:

use Illuminate\Console\Scheduling\Event;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Event::macro(
            'weekends',
            function () {
                /** @var Event $this */
                return $this->days([0, 6]);
            }
        );
    }
}

然后您可以像使用其他方法一样使用它:

$schedule->command('do-work')->weekends();

如需了解有关宏的更多详细信息,请参阅https://asklagbox.com/blog/laravel-macros


0
根据@jedrzej.kurylo的回答,我在laravel 5.8上进行了以下操作: < p > < code > php artisan make:model CustomCallbackEvent

< p > < code > php artisan make:model CustomEvent

< p > < code > php artisan make:model CustomSchedule

在CustomCallbackEvent中:
use Illuminate\Console\Scheduling\CallbackEvent;
use Illuminate\Console\Scheduling\EventMutex;

class CustomCallbackEvent extends CallbackEvent
{
    public function __construct(EventMutex $mutex, $callback, array $parameters = [])
    {
        parent::__construct($mutex, $callback, $parameters);
    }
}

在CustomSchedule中:
use Illuminate\Console\Scheduling\Schedule;

class CustomSchedule extends Schedule
{
    public function call($callback, array $parameters = [])
    {
        $this->events[] = $event = new CustomCallbackEvent(
            $this->eventMutex,
            $callback,
            $parameters
        );

        return $event;
    }

    public function exec($command, array $parameters = [])
    {
        if (count($parameters)) {
            $command .= ' '.$this->compileParameters($parameters);
        }

        $this->events[] = $event = new CustomEvent($this->eventMutex, $command, $this->timezone);

        return $event;
    }
}

在CustomEvent中:

use Illuminate\Console\Scheduling\Event;

class CustomEvent extends Event
{
    public function myFunction()
    {
        //your logic here
    }
}

在 Kernel.php 中:

protected function defineConsoleSchedule()
    {
      $this->app->instance(
        'Illuminate\Console\Scheduling\Schedule', $schedule = new CustomSchedule
      );

      $this->schedule($schedule);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接