Skip to content

Commit

Permalink
Include task scheduler in core
Browse files Browse the repository at this point in the history
  • Loading branch information
askvortsov1 committed Mar 19, 2021
1 parent 9429ca2 commit 8db8538
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 5 deletions.
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
"components/font-awesome": "^5.14.0",
"dflydev/fig-cookies": "^3.0.0",
"doctrine/dbal": "^2.7",
"dragonmantank/cron-expression": "^3.1.0",
"franzl/whoops-middleware": "^2.0.0",
"illuminate/bus": "^8.0",
"illuminate/cache": "^8.0",
"illuminate/config": "^8.0",
"illuminate/console": "^8.0",
"illuminate/container": "^8.0",
"illuminate/contracts": "^8.0",
"illuminate/database": "^8.0",
Expand Down
32 changes: 32 additions & 0 deletions src/Console/ConsoleServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
use Flarum\Foundation\AbstractServiceProvider;
use Flarum\Foundation\Console\CacheClearCommand;
use Flarum\Foundation\Console\InfoCommand;
use Illuminate\Console\Scheduling\Schedule as LaravelSchedule;
use Illuminate\Console\Scheduling\ScheduleListCommand;
use Illuminate\Console\Scheduling\ScheduleRunCommand;

class ConsoleServiceProvider extends AbstractServiceProvider
{
Expand All @@ -22,13 +25,42 @@ class ConsoleServiceProvider extends AbstractServiceProvider
*/
public function register()
{
// Used by Laravel to proxy artisan commands to its binary.
// Flarum uses a similar binary, but it's called flarum.
if (! defined('ARTISAN_BINARY')) {
define('ARTISAN_BINARY', 'flarum');
}

$this->container->singleton(LaravelSchedule::class, function () {
return $this->container->make(Schedule::class);
});

$this->container->singleton('flarum.console.commands', function () {
return [
CacheClearCommand::class,
InfoCommand::class,
MigrateCommand::class,
ResetCommand::class,
ScheduleListCommand::class,
ScheduleRunCommand::class
];
});

$this->container->singleton('flarum.console.scheduled', function () {
return [];
});
}

/**
* {@inheritDoc}
*/
public function boot()
{
$schedule = $this->container->make(LaravelSchedule::class);

foreach ($this->container->make('flarum.console.scheduled') as $scheduled) {
$event = $schedule->command($scheduled['command'], $scheduled['args']);
$scheduled['callback']($event);
}
}
}
40 changes: 40 additions & 0 deletions src/Console/Schedule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/

namespace Flarum\Console;

use Flarum\Foundation\Config;
use Illuminate\Console\Scheduling\Schedule as LaravelSchedule;
use Illuminate\Support\Collection;

class Schedule extends LaravelSchedule
{
public function dueEvents($container)
{
return (new Collection($this->events))->filter->isDue(new FakeApp($container));
}
}

class FakeApp
{
public function __construct($container)
{
$this->config = $container->make(Config::class);
}

public function isDownForMaintenance()
{
return $this->config->inMaintenanceMode();
}

public function environment()
{
return '';
}
}
29 changes: 29 additions & 0 deletions src/Extend/Console.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
class Console implements ExtenderInterface
{
protected $addCommands = [];
protected $scheduled = [];

/**
* Add a command to the console.
Expand All @@ -28,10 +29,38 @@ public function command($command)
return $this;
}

/**
* Schedule a command to run on an interval.
*
* @param string $command ::class attribute of command class, which must extend Flarum\Console\AbstractCommand
* @param callable|string $callback
*
* The callback can be a closure or invokable class, and should accept:
* - \Illuminate\Console\Scheduling\Event $event
*
* The callback should apply relevant methods to $event, and does not need to return anything.
*
* @see https://laravel.com/api/8.x/Illuminate/Console/Scheduling/Event.html
* @see https://laravel.com/docs/8.x/scheduling#schedule-frequency-options
* for more information on available methods and what they do.
*
* @param array $args An array of args to call the command with.
*/
public function schedule(string $command, $callback, $args = [])
{
$this->scheduled[] = compact('args', 'callback', 'command');

return $this;
}

public function extend(Container $container, Extension $extension = null)
{
$container->extend('flarum.console.commands', function ($existingCommands) {
return array_merge($existingCommands, $this->addCommands);
});

$container->extend('flarum.console.scheduled', function ($existingScheduled) {
return array_merge($existingScheduled, $this->scheduled);
});
}
}
10 changes: 9 additions & 1 deletion src/Queue/QueueServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Flarum\Foundation\ErrorHandling\Registry;
use Flarum\Foundation\ErrorHandling\Reporter;
use Flarum\Foundation\Paths;
use Illuminate\Contracts\Cache\Factory as CacheFactory;
use Illuminate\Contracts\Debug\ExceptionHandler as ExceptionHandling;
use Illuminate\Contracts\Queue\Factory;
use Illuminate\Contracts\Queue\Queue;
Expand Down Expand Up @@ -82,7 +83,7 @@ function () use ($config) {

// Bind a simple cache manager that returns the cache store.
$this->container->singleton('cache', function ($container) {
return new class($container) {
return new class($container) implements CacheFactory {
public function __construct($container)
{
$this->container = $container;
Expand All @@ -93,6 +94,13 @@ public function driver()
return $this->container['cache.store'];
}

// We have to define this explicitly
// so that we implement the interface.
public function store($name = null)
{
return $this->__call($name, null);
}

public function __call($name, $arguments)
{
return call_user_func_array([$this->driver(), $name], $arguments);
Expand Down
18 changes: 14 additions & 4 deletions src/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use Flarum\Foundation\Paths;
use Illuminate\Container\Container;
use Illuminate\Contracts\Config\Repository;

if (! function_exists('resolve')) {
/**
Expand All @@ -24,7 +25,6 @@ function resolve($name, $parameters = [])
}
}


// The following are all deprecated perpetually.
// They are needed by some laravel components we use (e.g. task scheduling)
// They should NOT be used in extension code.
Expand All @@ -47,7 +47,7 @@ function app($make = null, $parameters = [])
}
}

if (!function_exists('base_path')) {
if (! function_exists('base_path')) {
/**
* @deprecated perpetually.
*
Expand All @@ -62,7 +62,7 @@ function base_path($path = '')
}
}

if (!function_exists('public_path')) {
if (! function_exists('public_path')) {
/**
* @deprecated perpetually.
*
Expand All @@ -77,7 +77,7 @@ function public_path($path = '')
}
}

if (!function_exists('storage_path')) {
if (! function_exists('storage_path')) {
/**
* @deprecated perpetually.
*
Expand Down Expand Up @@ -108,3 +108,13 @@ function event($event, $payload = [], $halt = false)
return resolve('events')->dispatch($event, $payload, $halt);
}
}

if (! function_exists('config')) {
/**
* @deprecated do not use, will be transferred to flarum/laravel-helpers.
*/
function config(string $key, $default = null)
{
return resolve(Repository::class)->get($key, $default);
}
}
31 changes: 31 additions & 0 deletions tests/integration/extenders/ConsoleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,37 @@ public function custom_command_exists_when_added()

$this->assertEquals('Custom Command.', $this->runCommand($input));
}

/**
* @test
*/
public function scheduled_command_doesnt_exist_by_default()
{
$input = [
'command' => 'schedule:list'
];

$this->assertStringNotContainsString('cache:clear', $this->runCommand($input));
}

/**
* @test
*/
public function scheduled_command_exists_when_added()
{
$this->extend(
(new Extend\Console())
->schedule('cache:clear', function ($event) {
$event->everyMinute();
})
);

$input = [
'command' => 'schedule:list'
];

$this->assertStringContainsString('cache:clear', $this->runCommand($input));
}
}

class CustomCommand extends AbstractCommand
Expand Down

0 comments on commit 8db8538

Please sign in to comment.