Skip to content

Commit e8c867d

Browse files
authored
fix: circular dependencies disable all involved extensions (#3785)
1 parent 1247a7f commit e8c867d

5 files changed

Lines changed: 77 additions & 1 deletion

File tree

framework/core/locale/core.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,7 @@ core:
605605

606606
# These translations are displayed as error messages.
607607
error:
608+
circular_dependencies_message: "Circular dependencies detected: {extensions}. Aborting. Please disable one of the extensions and try again."
608609
dependent_extensions_message: "Cannot disable {extension} until the following dependent extensions are disabled: {extensions}"
609610
extension_initialiation_failed_message: "{extension} failed to initialize, check the browser console for further information."
610611
generic_message: "Oops! Something went wrong. Please reload the page and try again."
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of Flarum.
5+
*
6+
* For detailed copyright and license information, please view the
7+
* LICENSE file that was distributed with this source code.
8+
*/
9+
10+
namespace Flarum\Extension\Exception;
11+
12+
use Exception;
13+
use Flarum\Extension\ExtensionManager;
14+
15+
class CircularDependenciesException extends Exception
16+
{
17+
public $circular_dependencies;
18+
19+
public function __construct(array $circularDependencies)
20+
{
21+
$this->circular_dependencies = $circularDependencies;
22+
23+
parent::__construct('Circular dependencies detected: '.implode(', ', ExtensionManager::pluckTitles($circularDependencies)).' - aborting. Please fix this by disabling the extensions that are causing the circular dependencies.');
24+
}
25+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* This file is part of Flarum.
5+
*
6+
* For detailed copyright and license information, please view the
7+
* LICENSE file that was distributed with this source code.
8+
*/
9+
10+
namespace Flarum\Extension\Exception;
11+
12+
use Flarum\Extension\ExtensionManager;
13+
use Flarum\Foundation\ErrorHandling\HandledError;
14+
15+
class CircularDependenciesExceptionHandler
16+
{
17+
public function handle(CircularDependenciesException $e): HandledError
18+
{
19+
return (new HandledError(
20+
$e,
21+
'circular_dependencies',
22+
409
23+
))->withDetails($this->errorDetails($e));
24+
}
25+
26+
protected function errorDetails(CircularDependenciesException $e): array
27+
{
28+
return [[
29+
'extensions' => ExtensionManager::pluckTitles($e->circular_dependencies),
30+
]];
31+
}
32+
}

framework/core/src/Extension/ExtensionManager.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Flarum\Extension\Event\Enabled;
1616
use Flarum\Extension\Event\Enabling;
1717
use Flarum\Extension\Event\Uninstalled;
18+
use Flarum\Extension\Exception\CircularDependenciesException;
1819
use Flarum\Foundation\Paths;
1920
use Flarum\Settings\SettingsRepositoryInterface;
2021
use Illuminate\Contracts\Container\Container;
@@ -157,6 +158,13 @@ public function getExtensions()
157158
return $this->extensions;
158159
}
159160

161+
public function getExtensionsById(array $ids): Collection
162+
{
163+
return $this->getExtensions()->filter(function (Extension $extension) use ($ids) {
164+
return in_array($extension->getId(), $ids);
165+
});
166+
}
167+
160168
/**
161169
* Loads an Extension with all information.
162170
*
@@ -397,10 +405,19 @@ public function getEnabled()
397405
* Persist the currently enabled extensions.
398406
*
399407
* @param array $enabledExtensions
408+
* @throws CircularDependenciesException
400409
*/
401410
protected function setEnabledExtensions(array $enabledExtensions)
402411
{
403-
$sortedEnabled = static::resolveExtensionOrder($enabledExtensions)['valid'];
412+
$resolved = static::resolveExtensionOrder($enabledExtensions);
413+
414+
if (! empty($resolved['circularDependencies'])) {
415+
throw new Exception\CircularDependenciesException(
416+
$this->getExtensionsById($resolved['circularDependencies'])->values()->all()
417+
);
418+
}
419+
420+
$sortedEnabled = $resolved['valid'];
404421

405422
$sortedEnabledIds = array_map(function (Extension $extension) {
406423
return $extension->getId();

framework/core/src/Foundation/ErrorServiceProvider.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public function register()
5858
return [
5959
IlluminateValidationException::class => Handling\ExceptionHandler\IlluminateValidationExceptionHandler::class,
6060
ValidationException::class => Handling\ExceptionHandler\ValidationExceptionHandler::class,
61+
ExtensionException\CircularDependenciesException::class => ExtensionException\CircularDependenciesExceptionHandler::class,
6162
ExtensionException\DependentExtensionsException::class => ExtensionException\DependentExtensionsExceptionHandler::class,
6263
ExtensionException\MissingDependenciesException::class => ExtensionException\MissingDependenciesExceptionHandler::class,
6364
];

0 commit comments

Comments
 (0)