diff --git a/framework/core/js/src/admin/components/StatusWidget.js b/framework/core/js/src/admin/components/StatusWidget.js
index 34ef12579..91e045c46 100644
--- a/framework/core/js/src/admin/components/StatusWidget.js
+++ b/framework/core/js/src/admin/components/StatusWidget.js
@@ -5,6 +5,7 @@ import ItemList from '../../common/utils/ItemList';
import Dropdown from '../../common/components/Dropdown';
import Button from '../../common/components/Button';
import LoadingModal from './LoadingModal';
+import LinkButton from '../../common/components/LinkButton';
export default class StatusWidget extends DashboardWidget {
className() {
@@ -30,9 +31,26 @@ export default class StatusWidget extends DashboardWidget {
);
- items.add('version-flarum', [Flarum,
, app.forum.attribute('version')]);
- items.add('version-php', [PHP,
, app.data.phpVersion]);
- items.add('version-mysql', [MySQL,
, app.data.mysqlVersion]);
+ items.add('version-flarum', [Flarum,
, app.forum.attribute('version')], 100);
+ items.add('version-php', [PHP,
, app.data.phpVersion], 90);
+ items.add('version-mysql', [MySQL,
, app.data.mysqlVersion], 80);
+ if (app.data.schedulerStatus) {
+ items.add(
+ 'schedule-status',
+ [
+
+ Scheduler{' '}
+
+ ,
+
,
+ app.data.schedulerStatus,
+ ],
+ 70
+ );
+ }
+
+ items.add('queue-driver', [Queue Driver,
, app.data.queueDriver], 60);
+ items.add('session-driver', [Session Driver,
, app.data.sessionDriver], 50);
return items;
}
diff --git a/framework/core/locale/core.yml b/framework/core/locale/core.yml
index c0e43a849..e21745c5a 100644
--- a/framework/core/locale/core.yml
+++ b/framework/core/locale/core.yml
@@ -56,6 +56,11 @@ core:
clear_cache_button: Clear Cache
description: Your forum at a glance.
io_error_message: "Could not write to filesystem. Check your filesystem permissions and try again. Or try running from the command line."
+ status:
+ scheduler:
+ active: Active
+ inactive: Inactive
+ never-run: Never run
title: Dashboard
tools_button: Tools
diff --git a/framework/core/src/Admin/Content/AdminPayload.php b/framework/core/src/Admin/Content/AdminPayload.php
index ef570b0b7..4b45fc711 100644
--- a/framework/core/src/Admin/Content/AdminPayload.php
+++ b/framework/core/src/Admin/Content/AdminPayload.php
@@ -10,6 +10,7 @@
namespace Flarum\Admin\Content;
use Flarum\Extension\ExtensionManager;
+use Flarum\Foundation\ApplicationInfoProvider;
use Flarum\Foundation\Config;
use Flarum\Frontend\Document;
use Flarum\Group\Permission;
@@ -54,6 +55,11 @@ class AdminPayload
*/
protected $config;
+ /**
+ * @var ApplicationInfoProvider
+ */
+ protected $appInfo;
+
/**
* @param Container $container
* @param SettingsRepositoryInterface $settings
@@ -61,6 +67,7 @@ class AdminPayload
* @param ConnectionInterface $db
* @param Dispatcher $events
* @param Config $config
+ * @param ApplicationInfoProvider $appInfo
*/
public function __construct(
Container $container,
@@ -68,7 +75,8 @@ class AdminPayload
ExtensionManager $extensions,
ConnectionInterface $db,
Dispatcher $events,
- Config $config
+ Config $config,
+ ApplicationInfoProvider $appInfo
) {
$this->container = $container;
$this->settings = $settings;
@@ -76,6 +84,7 @@ class AdminPayload
$this->db = $db;
$this->events = $events;
$this->config = $config;
+ $this->appInfo = $appInfo;
}
public function __invoke(Document $document, Request $request)
@@ -95,10 +104,17 @@ class AdminPayload
return array_keys($resourceDrivers);
}, $this->container->make('flarum.http.slugDrivers'));
- $document->payload['phpVersion'] = PHP_VERSION;
- $document->payload['mysqlVersion'] = $this->db->selectOne('select version() as version')->version;
+ $document->payload['phpVersion'] = $this->appInfo->identifyPHPVersion();
+ $document->payload['mysqlVersion'] = $this->appInfo->identifyDatabaseVersion();
$document->payload['debugEnabled'] = Arr::get($this->config, 'debug');
+ if ($this->appInfo->scheduledTasksRegistered()) {
+ $document->payload['schedulerStatus'] = $this->appInfo->getSchedulerStatus();
+ }
+
+ $document->payload['queueDriver'] = $this->appInfo->identifyQueueDriver();
+ $document->payload['sessionDriver'] = $this->appInfo->identifySessionDriver();
+
/**
* Used in the admin user list. Implemented as this as it matches the API in flarum/statistics.
* If flarum/statistics ext is enabled, it will override this data with its own stats.
diff --git a/framework/core/src/Console/ConsoleServiceProvider.php b/framework/core/src/Console/ConsoleServiceProvider.php
index 439f85175..8252f78a0 100644
--- a/framework/core/src/Console/ConsoleServiceProvider.php
+++ b/framework/core/src/Console/ConsoleServiceProvider.php
@@ -16,12 +16,12 @@ use Flarum\Foundation\AbstractServiceProvider;
use Flarum\Foundation\Console\AssetsPublishCommand;
use Flarum\Foundation\Console\CacheClearCommand;
use Flarum\Foundation\Console\InfoCommand;
+use Flarum\Foundation\Console\ScheduleRunCommand;
use Illuminate\Console\Scheduling\CacheEventMutex;
use Illuminate\Console\Scheduling\CacheSchedulingMutex;
use Illuminate\Console\Scheduling\EventMutex;
use Illuminate\Console\Scheduling\Schedule as LaravelSchedule;
use Illuminate\Console\Scheduling\ScheduleListCommand;
-use Illuminate\Console\Scheduling\ScheduleRunCommand;
use Illuminate\Console\Scheduling\SchedulingMutex;
use Illuminate\Contracts\Container\Container;
diff --git a/framework/core/src/Foundation/ApplicationInfoProvider.php b/framework/core/src/Foundation/ApplicationInfoProvider.php
new file mode 100644
index 000000000..e032540ae
--- /dev/null
+++ b/framework/core/src/Foundation/ApplicationInfoProvider.php
@@ -0,0 +1,212 @@
+settings = $settings;
+ $this->translator = $translator;
+ $this->schedule = $schedule;
+ $this->db = $db;
+ $this->config = $config;
+ $this->session = $session;
+ $this->sessionHandler = $sessionHandler;
+ $this->queue = $queue;
+ }
+
+ /**
+ * Identify if any tasks are registered with the scheduler.
+ *
+ * @return bool
+ */
+ public function scheduledTasksRegistered(): bool
+ {
+ return count($this->schedule->events()) > 0;
+ }
+
+ /**
+ * Gets the current status of the scheduler.
+ *
+ * @return string
+ */
+ public function getSchedulerStatus(): string
+ {
+ $status = $this->settings->get('schedule.last_run');
+
+ if (! $status) {
+ return $this->translator->trans('core.admin.dashboard.status.scheduler.never-run');
+ }
+
+ // If the schedule has not run in the last 5 minutes, mark it as inactive.
+ return Carbon::parse($status) > Carbon::now()->subMinutes(5)
+ ? $this->translator->trans('core.admin.dashboard.status.scheduler.active')
+ : $this->translator->trans('core.admin.status.scheduler.inactive');
+ }
+
+ /**
+ * Identify the queue driver in use.
+ *
+ * @return string
+ */
+ public function identifyQueueDriver(): string
+ {
+ // Get class name
+ $queue = get_class($this->queue);
+ // Drop the namespace
+ $queue = Str::afterLast($queue, '\\');
+ // Lowercase the class name
+ $queue = strtolower($queue);
+ // Drop everything like queue SyncQueue, RedisQueue
+ $queue = str_replace('queue', '', $queue);
+
+ return $queue;
+ }
+
+ /**
+ * Identify the version of the database we are connected to.
+ *
+ * @return string
+ */
+ public function identifyDatabaseVersion(): string
+ {
+ return $this->db->selectOne('select version() as version')->version;
+ }
+
+ /**
+ * Reports on the session driver in use based on three scenarios:
+ * 1. If the configured session driver is valid and in use, it will be returned.
+ * 2. If the configured session driver is invalid, fallback to the default one and mention it.
+ * 3. If the actual used driver (i.e `session.handler`) is different from the current one (configured or default), mention it.
+ */
+ public function identifySessionDriver(): string
+ {
+ /*
+ * Get the configured driver and fallback to the default one.
+ */
+ $defaultDriver = $this->session->getDefaultDriver();
+ $configuredDriver = Arr::get($this->config, 'session.driver', $defaultDriver);
+ $driver = $configuredDriver;
+
+ try {
+ // Try to get the configured driver instance.
+ // Driver instances are created on demand.
+ $this->session->driver($configuredDriver);
+ } catch (InvalidArgumentException $e) {
+ // An exception is thrown if the configured driver is not a valid driver.
+ // So we fallback to the default driver.
+ $driver = $defaultDriver;
+ }
+
+ /*
+ * Get actual driver name from its class name.
+ * And compare that to the current configured driver.
+ */
+ // Get class name
+ $handlerName = get_class($this->sessionHandler);
+ // Drop the namespace
+ $handlerName = Str::afterLast($handlerName, '\\');
+ // Lowercase the class name
+ $handlerName = strtolower($handlerName);
+ // Drop everything like sessionhandler FileSessionHandler, DatabaseSessionHandler ..etc
+ $handlerName = str_replace('sessionhandler', '', $handlerName);
+
+ if ($driver !== $handlerName) {
+ return "$handlerName (Code override. Configured to $configuredDriver>)";
+ }
+
+ if ($driver !== $configuredDriver) {
+ return "$driver (Fallback default driver. Configured to invalid driver $configuredDriver>)";
+ }
+
+ return $driver;
+ }
+
+ /**
+ * Identifiy the current PHP version.
+ *
+ * @return string
+ */
+ public function identifyPHPVersion(): string
+ {
+ return PHP_VERSION;
+ }
+}
diff --git a/framework/core/src/Foundation/Console/InfoCommand.php b/framework/core/src/Foundation/Console/InfoCommand.php
index f7bd3e80b..34001b2e7 100644
--- a/framework/core/src/Foundation/Console/InfoCommand.php
+++ b/framework/core/src/Foundation/Console/InfoCommand.php
@@ -12,16 +12,10 @@ namespace Flarum\Foundation\Console;
use Flarum\Console\AbstractCommand;
use Flarum\Extension\ExtensionManager;
use Flarum\Foundation\Application;
+use Flarum\Foundation\ApplicationInfoProvider;
use Flarum\Foundation\Config;
use Flarum\Settings\SettingsRepositoryInterface;
-use Flarum\User\SessionManager;
-use Illuminate\Contracts\Queue\Queue;
use Illuminate\Database\ConnectionInterface;
-use Illuminate\Support\Arr;
-use Illuminate\Support\Str;
-use InvalidArgumentException;
-use PDO;
-use SessionHandlerInterface;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableStyle;
@@ -48,36 +42,22 @@ class InfoCommand extends AbstractCommand
protected $db;
/**
- * @var Queue
+ * @var ApplicationInfoProvider
*/
- private $queue;
-
- /**
- * @var SessionManager
- */
- private $session;
-
- /**
- * @var SessionHandlerInterface
- */
- private $sessionHandler;
+ private $appInfo;
public function __construct(
ExtensionManager $extensions,
Config $config,
SettingsRepositoryInterface $settings,
ConnectionInterface $db,
- Queue $queue,
- SessionManager $session,
- SessionHandlerInterface $sessionHandler
+ ApplicationInfoProvider $appInfo
) {
$this->extensions = $extensions;
$this->config = $config;
$this->settings = $settings;
$this->db = $db;
- $this->queue = $queue;
- $this->session = $session;
- $this->sessionHandler = $sessionHandler;
+ $this->appInfo = $appInfo;
parent::__construct();
}
@@ -98,10 +78,10 @@ class InfoCommand extends AbstractCommand
protected function fire()
{
$coreVersion = $this->findPackageVersion(__DIR__.'/../../../', Application::VERSION);
- $this->output->writeln("Flarum core $coreVersion");
+ $this->output->writeln("Flarum core: $coreVersion");
- $this->output->writeln('PHP version: '.PHP_VERSION);
- $this->output->writeln('MySQL version: '.$this->identifyDatabaseVersion());
+ $this->output->writeln('PHP version: '.$this->appInfo->identifyPHPVersion());
+ $this->output->writeln('MySQL version: '.$this->appInfo->identifyDatabaseVersion());
$phpExtensions = implode(', ', get_loaded_extensions());
$this->output->writeln("Loaded extensions: $phpExtensions");
@@ -110,8 +90,13 @@ class InfoCommand extends AbstractCommand
$this->output->writeln('Base URL: '.$this->config->url());
$this->output->writeln('Installation path: '.getcwd());
- $this->output->writeln('Queue driver: '.$this->identifyQueueDriver());
- $this->output->writeln('Session driver: '.$this->identifySessionDriver());
+ $this->output->writeln('Queue driver: '.$this->appInfo->identifyQueueDriver());
+ $this->output->writeln('Session driver: '.$this->appInfo->identifySessionDriver());
+
+ if ($this->appInfo->scheduledTasksRegistered()) {
+ $this->output->writeln('Scheduler status: '.$this->appInfo->getSchedulerStatus());
+ }
+
$this->output->writeln('Mail driver: '.$this->settings->get('mail_driver', 'unknown'));
$this->output->writeln('Debug mode: '.($this->config->inDebugMode() ? 'ON' : 'off'));
@@ -169,72 +154,4 @@ class InfoCommand extends AbstractCommand
return $fallback;
}
-
- private function identifyQueueDriver(): string
- {
- // Get class name
- $queue = get_class($this->queue);
- // Drop the namespace
- $queue = Str::afterLast($queue, '\\');
- // Lowercase the class name
- $queue = strtolower($queue);
- // Drop everything like queue SyncQueue, RedisQueue
- $queue = str_replace('queue', '', $queue);
-
- return $queue;
- }
-
- private function identifyDatabaseVersion(): string
- {
- return $this->db->getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION);
- }
-
- /**
- * Reports on the session driver in use based on three scenarios:
- * 1. If the configured session driver is valid and in use, it will be returned.
- * 2. If the configured session driver is invalid, fallback to the default one and mention it.
- * 3. If the actual used driver (i.e `session.handler`) is different from the current one (configured or default), mention it.
- */
- private function identifySessionDriver(): string
- {
- /*
- * Get the configured driver and fallback to the default one.
- */
- $defaultDriver = $this->session->getDefaultDriver();
- $configuredDriver = Arr::get($this->config, 'session.driver', $defaultDriver);
- $driver = $configuredDriver;
-
- try {
- // Try to get the configured driver instance.
- // Driver instances are created on demand.
- $this->session->driver($configuredDriver);
- } catch (InvalidArgumentException $e) {
- // An exception is thrown if the configured driver is not a valid driver.
- // So we fallback to the default driver.
- $driver = $defaultDriver;
- }
-
- /*
- * Get actual driver name from its class name.
- * And compare that to the current configured driver.
- */
- // Get class name
- $handlerName = get_class($this->sessionHandler);
- // Drop the namespace
- $handlerName = Str::afterLast($handlerName, '\\');
- // Lowercase the class name
- $handlerName = strtolower($handlerName);
- // Drop everything like sessionhandler FileSessionHandler, DatabaseSessionHandler ..etc
- $handlerName = str_replace('sessionhandler', '', $handlerName);
-
- if ($driver !== $handlerName) {
- return "$handlerName (Code override. Configured to $configuredDriver>)";
- }
-
- if ($driver !== $configuredDriver) {
- return "$driver (Fallback default driver. Configured to invalid driver $configuredDriver>)";
- }
-
- return $driver;
- }
}
diff --git a/framework/core/src/Foundation/Console/ScheduleRunCommand.php b/framework/core/src/Foundation/Console/ScheduleRunCommand.php
new file mode 100644
index 000000000..45b2779d2
--- /dev/null
+++ b/framework/core/src/Foundation/Console/ScheduleRunCommand.php
@@ -0,0 +1,43 @@
+settings = $settings;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function handle(Schedule $schedule, Dispatcher $dispatcher, ExceptionHandler $handler)
+ {
+ parent::handle($schedule, $dispatcher, $handler);
+
+ $this->settings->set('schedule.last_run', $this->startedAt);
+ }
+}