mirror of
https://github.com/flarum/core.git
synced 2025-08-10 18:35:56 +02:00
wip
This commit is contained in:
@@ -63,6 +63,7 @@ class AdminServiceProvider extends AbstractServiceProvider
|
|||||||
HttpMiddleware\ReferrerPolicyHeader::class,
|
HttpMiddleware\ReferrerPolicyHeader::class,
|
||||||
HttpMiddleware\ContentTypeOptionsHeader::class,
|
HttpMiddleware\ContentTypeOptionsHeader::class,
|
||||||
Middleware\DisableBrowserCache::class,
|
Middleware\DisableBrowserCache::class,
|
||||||
|
Middleware\GatherDebugInformation::class,
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Admin\Middleware;
|
||||||
|
|
||||||
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
use Psr\Http\Server\MiddlewareInterface as Middleware;
|
||||||
|
use Psr\Http\Server\RequestHandlerInterface as Handler;
|
||||||
|
|
||||||
|
class GatherDebugInformation implements Middleware
|
||||||
|
{
|
||||||
|
public function __construct(protected SettingsRepositoryInterface $settings)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function process(Request $request, Handler $handler): Response
|
||||||
|
{
|
||||||
|
// Read current web user, so we can compare that against CLI executions,
|
||||||
|
// these often cause file permission issues.
|
||||||
|
$user = $this->settings->get('core.debug.web_user');
|
||||||
|
$currentUser = get_current_user();
|
||||||
|
if ($user !== $currentUser) {
|
||||||
|
$this->settings->set(
|
||||||
|
"core.web_user",
|
||||||
|
$currentUser
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the opcache situation, this is only visible in web.
|
||||||
|
$opcache = $this->settings->get('core.debug.opcache_enabled');
|
||||||
|
$opcacheStatus = function_exists('opcache_get_configuration')
|
||||||
|
&& opcache_get_configuration() !== false;
|
||||||
|
if ($opcache !== $opcacheStatus) {
|
||||||
|
$this->settings->set(
|
||||||
|
'core.debug.opcache_enabled',
|
||||||
|
$opcacheStatus
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $handler->handle($request);
|
||||||
|
}
|
||||||
|
}
|
@@ -40,18 +40,21 @@ class ApplicationInfoProvider
|
|||||||
return count($this->schedule->events()) > 0;
|
return count($this->schedule->events()) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSchedulerStatus(): string
|
public function getSchedulerStatus(bool $translated = true): string
|
||||||
{
|
{
|
||||||
$status = $this->settings->get('schedule.last_run');
|
$status = $this->settings->get('schedule.last_run');
|
||||||
|
|
||||||
if (! $status) {
|
$key = match(true) {
|
||||||
return $this->translator->trans('core.admin.dashboard.status.scheduler.never-run');
|
! $status => 'never-run',
|
||||||
|
Carbon::parse($status) > Carbon::now()->subMinutes(5) => 'active',
|
||||||
|
default => 'inactive'
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($translated) {
|
||||||
|
return $this->translator->trans("core.admin.dashboard.status.scheduler.$key");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the schedule has not run in the last 5 minutes, mark it as inactive.
|
return $key;
|
||||||
return Carbon::parse($status) > Carbon::now()->subMinutes(5)
|
|
||||||
? $this->translator->trans('core.admin.dashboard.status.scheduler.active')
|
|
||||||
: $this->translator->trans('core.admin.dashboard.status.scheduler.inactive');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function identifyQueueDriver(): string
|
public function identifyQueueDriver(): string
|
||||||
|
@@ -14,7 +14,10 @@ use Flarum\Extension\ExtensionManager;
|
|||||||
use Flarum\Foundation\Application;
|
use Flarum\Foundation\Application;
|
||||||
use Flarum\Foundation\ApplicationInfoProvider;
|
use Flarum\Foundation\ApplicationInfoProvider;
|
||||||
use Flarum\Foundation\Config;
|
use Flarum\Foundation\Config;
|
||||||
|
use Flarum\Foundation\Info\Renderer\CliRenderer;
|
||||||
|
use Flarum\Foundation\Info\Report;
|
||||||
use Flarum\Settings\SettingsRepositoryInterface;
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
|
use Illuminate\Contracts\Container\Container;
|
||||||
use Illuminate\Database\ConnectionInterface;
|
use Illuminate\Database\ConnectionInterface;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Helper\Table;
|
use Symfony\Component\Console\Helper\Table;
|
||||||
@@ -23,11 +26,7 @@ use Symfony\Component\Console\Helper\TableStyle;
|
|||||||
class InfoCommand extends AbstractCommand
|
class InfoCommand extends AbstractCommand
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected ExtensionManager $extensions,
|
protected Container $container
|
||||||
protected Config $config,
|
|
||||||
protected SettingsRepositoryInterface $settings,
|
|
||||||
protected ConnectionInterface $db,
|
|
||||||
protected ApplicationInfoProvider $appInfo
|
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
@@ -41,83 +40,13 @@ class InfoCommand extends AbstractCommand
|
|||||||
|
|
||||||
protected function fire(): int
|
protected function fire(): int
|
||||||
{
|
{
|
||||||
$coreVersion = $this->findPackageVersion(__DIR__.'/../../../', Application::VERSION);
|
$report = new Report(
|
||||||
$this->output->writeln("<info>Flarum core:</info> $coreVersion");
|
new CliRenderer($this->output),
|
||||||
|
$this->container
|
||||||
|
);
|
||||||
|
|
||||||
$this->output->writeln('<info>PHP version:</info> '.$this->appInfo->identifyPHPVersion());
|
$report->render();
|
||||||
$this->output->writeln('<info>'.$this->appInfo->identifyDatabaseDriver().' version:</info> '.$this->appInfo->identifyDatabaseVersion());
|
|
||||||
|
|
||||||
$phpExtensions = implode(', ', get_loaded_extensions());
|
|
||||||
$this->output->writeln("<info>Loaded extensions:</info> $phpExtensions");
|
|
||||||
|
|
||||||
$this->getExtensionTable()->render();
|
|
||||||
|
|
||||||
$this->output->writeln('<info>Base URL:</info> '.$this->config->url());
|
|
||||||
$this->output->writeln('<info>Installation path:</info> '.getcwd());
|
|
||||||
$this->output->writeln('<info>Queue driver:</info> '.$this->appInfo->identifyQueueDriver());
|
|
||||||
$this->output->writeln('<info>Session driver:</info> '.$this->appInfo->identifySessionDriver());
|
|
||||||
|
|
||||||
if ($this->appInfo->scheduledTasksRegistered()) {
|
|
||||||
$this->output->writeln('<info>Scheduler status:</info> '.$this->appInfo->getSchedulerStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->output->writeln('<info>Mail driver:</info> '.$this->settings->get('mail_driver', 'unknown'));
|
|
||||||
$this->output->writeln('<info>Debug mode:</info> '.($this->config->inDebugMode() ? '<error>ON</error>' : 'off'));
|
|
||||||
|
|
||||||
if ($this->config->inDebugMode()) {
|
|
||||||
$this->output->writeln('');
|
|
||||||
$this->error(
|
|
||||||
"Don't forget to turn off debug mode! It should never be turned on in a production system."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Command::SUCCESS;
|
return Command::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getExtensionTable(): Table
|
|
||||||
{
|
|
||||||
$table = (new Table($this->output))
|
|
||||||
->setHeaders([
|
|
||||||
['Flarum Extensions'],
|
|
||||||
['ID', 'Version', 'Commit']
|
|
||||||
])->setStyle(
|
|
||||||
(new TableStyle)->setCellHeaderFormat('<info>%s</info>')
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($this->extensions->getEnabledExtensions() as $extension) {
|
|
||||||
$table->addRow([
|
|
||||||
$extension->getId(),
|
|
||||||
$extension->getVersion(),
|
|
||||||
$this->findPackageVersion($extension->getPath())
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $table;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Try to detect a package's exact version.
|
|
||||||
*
|
|
||||||
* If the package seems to be a Git version, we extract the currently
|
|
||||||
* checked out commit using the command line.
|
|
||||||
*/
|
|
||||||
private function findPackageVersion(string $path, ?string $fallback = null): ?string
|
|
||||||
{
|
|
||||||
if (file_exists("$path/.git")) {
|
|
||||||
$cwd = getcwd();
|
|
||||||
chdir($path);
|
|
||||||
|
|
||||||
$output = [];
|
|
||||||
$status = null;
|
|
||||||
exec('git rev-parse HEAD 2>&1', $output, $status);
|
|
||||||
|
|
||||||
chdir($cwd);
|
|
||||||
|
|
||||||
if ($status == 0) {
|
|
||||||
return isset($fallback) ? "$fallback ($output[0])" : $output[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $fallback;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Foundation\Info\Concerns;
|
||||||
|
|
||||||
|
trait PackageVersionFromPath
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Try to detect a package's exact version.
|
||||||
|
*
|
||||||
|
* If the package seems to be a Git version, we extract the currently
|
||||||
|
* checked out commit using the command line.
|
||||||
|
*/
|
||||||
|
private function findPackageVersion(string $path, ?string $fallback = null): ?string
|
||||||
|
{
|
||||||
|
if (file_exists("$path/.git")) {
|
||||||
|
$cwd = getcwd();
|
||||||
|
chdir($path);
|
||||||
|
|
||||||
|
$output = [];
|
||||||
|
$status = null;
|
||||||
|
exec('git rev-parse HEAD 2>&1', $output, $status);
|
||||||
|
|
||||||
|
chdir($cwd);
|
||||||
|
|
||||||
|
if ($status == 0) {
|
||||||
|
return isset($fallback) ? "$fallback ($output[0])" : $output[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fallback;
|
||||||
|
}
|
||||||
|
}
|
46
framework/core/src/Foundation/Info/Renderer/CliRenderer.php
Normal file
46
framework/core/src/Foundation/Info/Renderer/CliRenderer.php
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Foundation\Info\Renderer;
|
||||||
|
|
||||||
|
use Flarum\Foundation\Info\RendererInterface;
|
||||||
|
use Symfony\Component\Console\Helper\Table;
|
||||||
|
use Symfony\Component\Console\Helper\TableStyle;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class CliRenderer implements RendererInterface
|
||||||
|
{
|
||||||
|
public function __construct(protected OutputInterface $output)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public function heading(string $title): void
|
||||||
|
{
|
||||||
|
$this->output->writeln("<bg=gray,options=bold>$title</>");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function keyValue(string $key, mixed $value): void
|
||||||
|
{
|
||||||
|
$this->output->writeln("<info>$key:</info> $value");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function table(array $headers, array $rows): void
|
||||||
|
{
|
||||||
|
$table = (new Table($this->output))
|
||||||
|
->setHeaders($headers)->setStyle(
|
||||||
|
(new TableStyle)->setCellHeaderFormat('<info>%s</info>')
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$table->addRow($row);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function open(): void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function close(): void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
17
framework/core/src/Foundation/Info/RendererInterface.php
Normal file
17
framework/core/src/Foundation/Info/RendererInterface.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Foundation\Info;
|
||||||
|
|
||||||
|
interface RendererInterface
|
||||||
|
{
|
||||||
|
public function heading(string $title): void;
|
||||||
|
|
||||||
|
public function keyValue(string $key, mixed $value): void;
|
||||||
|
|
||||||
|
public function table(array $headers, array $rows): void;
|
||||||
|
|
||||||
|
public function open(): void;
|
||||||
|
|
||||||
|
public function close(): void;
|
||||||
|
|
||||||
|
}
|
37
framework/core/src/Foundation/Info/Report.php
Normal file
37
framework/core/src/Foundation/Info/Report.php
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Foundation\Info;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Container\Container;
|
||||||
|
|
||||||
|
class Report
|
||||||
|
{
|
||||||
|
protected array $sections = [
|
||||||
|
Section\CoreVersion::class,
|
||||||
|
Section\PHP::class,
|
||||||
|
Section\EnabledExtensions::class,
|
||||||
|
Section\Features::class,
|
||||||
|
Section\Debug::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
protected RendererInterface $renderer,
|
||||||
|
protected Container $container
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public function render(): void
|
||||||
|
{
|
||||||
|
$sections = $this->sections;
|
||||||
|
|
||||||
|
$this->renderer->open();
|
||||||
|
|
||||||
|
foreach($sections as &$section) {
|
||||||
|
$section = $this->container->make($section);
|
||||||
|
|
||||||
|
$section($this->renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->renderer->close();
|
||||||
|
}
|
||||||
|
}
|
21
framework/core/src/Foundation/Info/Section/CoreVersion.php
Normal file
21
framework/core/src/Foundation/Info/Section/CoreVersion.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Foundation\Info\Section;
|
||||||
|
|
||||||
|
use Flarum\Foundation\Application;
|
||||||
|
use Flarum\Foundation\Info\Concerns\PackageVersionFromPath;
|
||||||
|
use Flarum\Foundation\Info\RendererInterface;
|
||||||
|
use Flarum\Foundation\Info\SectionInterface;
|
||||||
|
|
||||||
|
class CoreVersion implements SectionInterface
|
||||||
|
{
|
||||||
|
use PackageVersionFromPath;
|
||||||
|
|
||||||
|
public function __invoke(RendererInterface $renderer): void
|
||||||
|
{
|
||||||
|
$renderer->keyValue(
|
||||||
|
'Flarum Core',
|
||||||
|
$this->findPackageVersion(__DIR__.'/../../../../', Application::VERSION)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
26
framework/core/src/Foundation/Info/Section/Debug.php
Normal file
26
framework/core/src/Foundation/Info/Section/Debug.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Foundation\Info\Section;
|
||||||
|
|
||||||
|
use Flarum\Foundation\Config;
|
||||||
|
use Flarum\Foundation\Info\RendererInterface;
|
||||||
|
use Flarum\Foundation\Info\SectionInterface;
|
||||||
|
|
||||||
|
class Debug implements SectionInterface
|
||||||
|
{
|
||||||
|
public function __construct(protected Config $config)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke(RendererInterface $renderer): void
|
||||||
|
{
|
||||||
|
$renderer->keyValue(
|
||||||
|
'Debug mode',
|
||||||
|
$this->config->inDebugMode() ? 'on' : 'off'
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($this->config->inDebugMode()) {
|
||||||
|
$renderer->heading("Debug mode should not be enabled in production; this will cause javascript and stylesheets to be recompiled on each visit.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Foundation\Info\Section;
|
||||||
|
|
||||||
|
use Flarum\Extension\Extension;
|
||||||
|
use Flarum\Extension\ExtensionManager;
|
||||||
|
use Flarum\Foundation\Info\Concerns\PackageVersionFromPath;
|
||||||
|
use Flarum\Foundation\Info\RendererInterface;
|
||||||
|
use Flarum\Foundation\Info\SectionInterface;
|
||||||
|
|
||||||
|
class EnabledExtensions implements SectionInterface
|
||||||
|
{
|
||||||
|
use PackageVersionFromPath;
|
||||||
|
|
||||||
|
public function __construct(protected ExtensionManager $extensions)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke(RendererInterface $renderer): void
|
||||||
|
{
|
||||||
|
$rows = collect($this->extensions->getEnabledExtensions())
|
||||||
|
->map(fn (Extension $extension) => [
|
||||||
|
$extension->getId(),
|
||||||
|
$this->findPackageVersion($extension->getPath(), $extension->getVersion())
|
||||||
|
])
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$renderer->table([
|
||||||
|
['Flarum Extensions'],
|
||||||
|
['ID', 'Version']
|
||||||
|
], $rows);
|
||||||
|
}
|
||||||
|
}
|
59
framework/core/src/Foundation/Info/Section/Features.php
Normal file
59
framework/core/src/Foundation/Info/Section/Features.php
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Foundation\Info\Section;
|
||||||
|
|
||||||
|
use Flarum\Foundation\ApplicationInfoProvider;
|
||||||
|
use Flarum\Foundation\Info\RendererInterface;
|
||||||
|
use Flarum\Foundation\Info\SectionInterface;
|
||||||
|
use Flarum\Mail\NullDriver;
|
||||||
|
use Illuminate\Contracts\Container\Container;
|
||||||
|
|
||||||
|
class Features implements SectionInterface
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
protected ApplicationInfoProvider $appInfo,
|
||||||
|
protected Container $container
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke(RendererInterface $renderer): void
|
||||||
|
{
|
||||||
|
$renderer->keyValue(
|
||||||
|
'Scheduler required',
|
||||||
|
$this->appInfo->scheduledTasksRegistered() ? 'yes' : 'no'
|
||||||
|
);
|
||||||
|
|
||||||
|
$renderer->keyValue(
|
||||||
|
'Scheduler status',
|
||||||
|
$this->appInfo->getSchedulerStatus(translated: false)
|
||||||
|
);
|
||||||
|
|
||||||
|
$renderer->keyValue(
|
||||||
|
'Queue driver',
|
||||||
|
$this->appInfo->identifyQueueDriver()
|
||||||
|
);
|
||||||
|
|
||||||
|
$renderer->keyValue(
|
||||||
|
'Session driver',
|
||||||
|
$this->appInfo->identifySessionDriver()
|
||||||
|
);
|
||||||
|
|
||||||
|
$renderer->keyValue(
|
||||||
|
'Mail driver',
|
||||||
|
$this->mail()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function mail()
|
||||||
|
{
|
||||||
|
$driver = $this->container->make('mail.driver');
|
||||||
|
$configured = $this->container->make('flarum.mail.configured_driver');
|
||||||
|
|
||||||
|
if ($driver instanceof NullDriver) {
|
||||||
|
$configured .= " (not active)";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $configured;
|
||||||
|
}
|
||||||
|
}
|
27
framework/core/src/Foundation/Info/Section/PHP.php
Normal file
27
framework/core/src/Foundation/Info/Section/PHP.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Foundation\Info\Section;
|
||||||
|
|
||||||
|
use Flarum\Foundation\ApplicationInfoProvider;
|
||||||
|
use Flarum\Foundation\Info\RendererInterface;
|
||||||
|
use Flarum\Foundation\Info\SectionInterface;
|
||||||
|
|
||||||
|
class PHP implements SectionInterface
|
||||||
|
{
|
||||||
|
public function __construct(protected ApplicationInfoProvider $appInfo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke(RendererInterface $renderer): void
|
||||||
|
{
|
||||||
|
$renderer->keyValue(
|
||||||
|
'PHP version',
|
||||||
|
$this->appInfo->identifyPHPVersion()
|
||||||
|
);
|
||||||
|
|
||||||
|
$renderer->keyValue(
|
||||||
|
'PHP extensions',
|
||||||
|
implode(', ', get_loaded_extensions())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
8
framework/core/src/Foundation/Info/SectionInterface.php
Normal file
8
framework/core/src/Foundation/Info/SectionInterface.php
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Foundation\Info;
|
||||||
|
|
||||||
|
interface SectionInterface
|
||||||
|
{
|
||||||
|
public function __invoke(RendererInterface $renderer): void;
|
||||||
|
}
|
Reference in New Issue
Block a user