Split up Application and Container

- Stop trying to implement Laravel's Application contract, which
  has no value for us.
- Stop inheriting from the Container, injecting one works equally
  well and does not clutter up the interfaces.
- Inject the Paths collection instead of unwrapping it again, for
  better encapsulation.

This brings us one step closer toward upgrading our Laravel
components (#2055), because we no longer need to adopt the changes
to the Application contract.
This commit is contained in:
Franz Liedke 2020-05-01 09:53:55 +00:00
parent d0ae2839f0
commit 41a56c4ad1
No known key found for this signature in database
GPG Key ID: 9A0231A879B055F4
16 changed files with 110 additions and 453 deletions

View File

@ -12,7 +12,6 @@ namespace Flarum\Admin;
use Flarum\Extension\Event\Disabled; use Flarum\Extension\Event\Disabled;
use Flarum\Extension\Event\Enabled; use Flarum\Extension\Event\Enabled;
use Flarum\Foundation\AbstractServiceProvider; use Flarum\Foundation\AbstractServiceProvider;
use Flarum\Foundation\Application;
use Flarum\Foundation\ErrorHandling\Registry; use Flarum\Foundation\ErrorHandling\Registry;
use Flarum\Foundation\ErrorHandling\Reporter; use Flarum\Foundation\ErrorHandling\Reporter;
use Flarum\Foundation\ErrorHandling\ViewFormatter; use Flarum\Foundation\ErrorHandling\ViewFormatter;
@ -60,14 +59,14 @@ class AdminServiceProvider extends AbstractServiceProvider
]; ];
}); });
$this->app->singleton('flarum.admin.handler', function (Application $app) { $this->app->singleton('flarum.admin.handler', function () {
$pipe = new MiddlewarePipe; $pipe = new MiddlewarePipe;
// All requests should first be piped through our global error handler // All requests should first be piped through our global error handler
$pipe->pipe(new HttpMiddleware\HandleErrors( $pipe->pipe(new HttpMiddleware\HandleErrors(
$app->make(Registry::class), $this->app->make(Registry::class),
$app->inDebugMode() ? $app->make(WhoopsFormatter::class) : $app->make(ViewFormatter::class), $this->app['flarum']->inDebugMode() ? $this->app->make(WhoopsFormatter::class) : $this->app->make(ViewFormatter::class),
$app->tagged(Reporter::class) $this->app->tagged(Reporter::class)
)); ));
foreach ($this->app->make('flarum.admin.middleware') as $middleware) { foreach ($this->app->make('flarum.admin.middleware') as $middleware) {

View File

@ -15,7 +15,6 @@ use Flarum\Api\Serializer\BasicDiscussionSerializer;
use Flarum\Api\Serializer\NotificationSerializer; use Flarum\Api\Serializer\NotificationSerializer;
use Flarum\Event\ConfigureNotificationTypes; use Flarum\Event\ConfigureNotificationTypes;
use Flarum\Foundation\AbstractServiceProvider; use Flarum\Foundation\AbstractServiceProvider;
use Flarum\Foundation\Application;
use Flarum\Foundation\ErrorHandling\JsonApiFormatter; use Flarum\Foundation\ErrorHandling\JsonApiFormatter;
use Flarum\Foundation\ErrorHandling\Registry; use Flarum\Foundation\ErrorHandling\Registry;
use Flarum\Foundation\ErrorHandling\Reporter; use Flarum\Foundation\ErrorHandling\Reporter;
@ -56,13 +55,13 @@ class ApiServiceProvider extends AbstractServiceProvider
]; ];
}); });
$this->app->singleton('flarum.api.handler', function (Application $app) { $this->app->singleton('flarum.api.handler', function () {
$pipe = new MiddlewarePipe; $pipe = new MiddlewarePipe;
$pipe->pipe(new HttpMiddleware\HandleErrors( $pipe->pipe(new HttpMiddleware\HandleErrors(
$app->make(Registry::class), $this->app->make(Registry::class),
new JsonApiFormatter($app->inDebugMode()), new JsonApiFormatter($this->app['flarum']->inDebugMode()),
$app->tagged(Reporter::class) $this->app->tagged(Reporter::class)
)); ));
foreach ($this->app->make('flarum.api.middleware') as $middleware) { foreach ($this->app->make('flarum.api.middleware') as $middleware) {

View File

@ -24,7 +24,7 @@ class DatabaseServiceProvider extends AbstractServiceProvider
$this->app->singleton(Manager::class, function ($app) { $this->app->singleton(Manager::class, function ($app) {
$manager = new Manager($app); $manager = new Manager($app);
$config = $app->config('database'); $config = $this->app['flarum']->config('database');
$config['engine'] = 'InnoDB'; $config['engine'] = 'InnoDB';
$config['prefix_indexes'] = true; $config['prefix_indexes'] = true;

View File

@ -10,7 +10,6 @@
namespace Flarum\Database; namespace Flarum\Database;
use Flarum\Foundation\AbstractServiceProvider; use Flarum\Foundation\AbstractServiceProvider;
use Flarum\Foundation\Application;
use Illuminate\Filesystem\Filesystem; use Illuminate\Filesystem\Filesystem;
class MigrationServiceProvider extends AbstractServiceProvider class MigrationServiceProvider extends AbstractServiceProvider
@ -24,8 +23,11 @@ class MigrationServiceProvider extends AbstractServiceProvider
return new DatabaseMigrationRepository($app['flarum.db'], 'migrations'); return new DatabaseMigrationRepository($app['flarum.db'], 'migrations');
}); });
$this->app->bind(MigrationCreator::class, function (Application $app) { $this->app->bind(MigrationCreator::class, function () {
return new MigrationCreator($app->make(Filesystem::class), $app->basePath()); return new MigrationCreator(
$this->app->make(Filesystem::class),
$this->app->basePath()
);
}); });
} }
} }

View File

@ -11,7 +11,6 @@ namespace Flarum\Extension;
use Flarum\Extension\Event\Disabling; use Flarum\Extension\Event\Disabling;
use Flarum\Foundation\AbstractServiceProvider; use Flarum\Foundation\AbstractServiceProvider;
use Illuminate\Contracts\Container\Container;
class ExtensionServiceProvider extends AbstractServiceProvider class ExtensionServiceProvider extends AbstractServiceProvider
{ {
@ -27,8 +26,8 @@ class ExtensionServiceProvider extends AbstractServiceProvider
// listener on the app rather than in the service provider's boot method // listener on the app rather than in the service provider's boot method
// below, so that extensions have a chance to register things on the // below, so that extensions have a chance to register things on the
// container before the core boots up (and starts resolving services). // container before the core boots up (and starts resolving services).
$this->app->booting(function (Container $app) { $this->app['flarum']->booting(function () {
$app->make('flarum.extensions')->extend($app); $this->app->make('flarum.extensions')->extend($this->app);
}); });
} }

View File

@ -24,7 +24,7 @@ class FormatterServiceProvider extends AbstractServiceProvider
return new Formatter( return new Formatter(
new Repository($container->make('cache.filestore')), new Repository($container->make('cache.filestore')),
$container->make('events'), $container->make('events'),
$this->app->storagePath().'/formatter' $this->app['flarum']->storagePath().'/formatter'
); );
}); });

View File

@ -13,7 +13,6 @@ use Flarum\Extension\Event\Disabled;
use Flarum\Extension\Event\Enabled; use Flarum\Extension\Event\Enabled;
use Flarum\Formatter\Formatter; use Flarum\Formatter\Formatter;
use Flarum\Foundation\AbstractServiceProvider; use Flarum\Foundation\AbstractServiceProvider;
use Flarum\Foundation\Application;
use Flarum\Foundation\ErrorHandling\Registry; use Flarum\Foundation\ErrorHandling\Registry;
use Flarum\Foundation\ErrorHandling\Reporter; use Flarum\Foundation\ErrorHandling\Reporter;
use Flarum\Foundation\ErrorHandling\ViewFormatter; use Flarum\Foundation\ErrorHandling\ViewFormatter;
@ -70,14 +69,14 @@ class ForumServiceProvider extends AbstractServiceProvider
]; ];
}); });
$this->app->singleton('flarum.forum.handler', function (Application $app) { $this->app->singleton('flarum.forum.handler', function () {
$pipe = new MiddlewarePipe; $pipe = new MiddlewarePipe;
// All requests should first be piped through our global error handler // All requests should first be piped through our global error handler
$pipe->pipe(new HttpMiddleware\HandleErrors( $pipe->pipe(new HttpMiddleware\HandleErrors(
$app->make(Registry::class), $this->app->make(Registry::class),
$app->inDebugMode() ? $app->make(WhoopsFormatter::class) : $app->make(ViewFormatter::class), $this->app['flarum']->inDebugMode() ? $this->app->make(WhoopsFormatter::class) : $this->app->make(ViewFormatter::class),
$app->tagged(Reporter::class) $this->app->tagged(Reporter::class)
)); ));
foreach ($this->app->make('flarum.forum.middleware') as $middleware) { foreach ($this->app->make('flarum.forum.middleware') as $middleware) {

View File

@ -9,21 +9,22 @@
namespace Flarum\Foundation; namespace Flarum\Foundation;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
abstract class AbstractServiceProvider extends ServiceProvider abstract class AbstractServiceProvider extends ServiceProvider
{ {
/** /**
* @var Application * @var Container
*/ */
protected $app; protected $app;
/** /**
* @param Application $app * @param Container $container
*/ */
public function __construct(Application $app) public function __construct(Container $container)
{ {
parent::__construct($app); $this->app = $container;
} }
/** /**

View File

@ -9,14 +9,12 @@
namespace Flarum\Foundation; namespace Flarum\Foundation;
use Illuminate\Container\Container; use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Foundation\Application as ApplicationContract;
use Illuminate\Events\EventServiceProvider; use Illuminate\Events\EventServiceProvider;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
class Application extends Container implements ApplicationContract class Application
{ {
/** /**
* The Flarum version. * The Flarum version.
@ -26,32 +24,18 @@ class Application extends Container implements ApplicationContract
const VERSION = '0.1.0-beta.13-dev'; const VERSION = '0.1.0-beta.13-dev';
/** /**
* The base path for the Flarum installation. * The IoC container for the Flarum application.
* *
* @var string * @var Container
*/ */
protected $basePath; private $container;
/** /**
* The public path for the Flarum installation. * The paths for the Flarum installation.
* *
* @var string * @var Paths
*/ */
protected $publicPath; protected $paths;
/**
* The custom storage path defined by the developer.
*
* @var string
*/
protected $storagePath;
/**
* A custom vendor path to find dependencies in non-standard environments.
*
* @var string
*/
protected $vendorPath;
/** /**
* Indicates if the application has "booted". * Indicates if the application has "booted".
@ -88,34 +72,22 @@ class Application extends Container implements ApplicationContract
*/ */
protected $loadedProviders = []; protected $loadedProviders = [];
/**
* The deferred services and their providers.
*
* @var array
*/
protected $deferredServices = [];
/** /**
* Create a new Flarum application instance. * Create a new Flarum application instance.
* *
* @param string|null $basePath * @param Container $container
* @param string|null $publicPath * @param Paths $paths
*/ */
public function __construct($basePath = null, $publicPath = null) public function __construct(Container $container, Paths $paths)
{ {
$this->container = $container;
$this->paths = $paths;
$this->registerBaseBindings(); $this->registerBaseBindings();
$this->registerBaseServiceProviders(); $this->registerBaseServiceProviders();
$this->registerCoreContainerAliases(); $this->registerCoreContainerAliases();
if ($basePath) { $this->bindPathsInContainer();
$this->setBasePath($basePath);
}
if ($publicPath) {
$this->setPublicPath($publicPath);
}
} }
/** /**
@ -125,7 +97,7 @@ class Application extends Container implements ApplicationContract
*/ */
public function config($key, $default = null) public function config($key, $default = null)
{ {
return Arr::get($this->make('flarum.config'), $key, $default); return Arr::get($this->container->make('flarum.config'), $key, $default);
} }
/** /**
@ -146,7 +118,7 @@ class Application extends Container implements ApplicationContract
*/ */
public function url($path = null) public function url($path = null)
{ {
$config = $this->make('flarum.config'); $config = $this->container->make('flarum.config');
$url = Arr::get($config, 'url', Arr::get($_SERVER, 'REQUEST_URI')); $url = Arr::get($config, 'url', Arr::get($_SERVER, 'REQUEST_URI'));
if (is_array($url)) { if (is_array($url)) {
@ -164,26 +136,21 @@ class Application extends Container implements ApplicationContract
return $url; return $url;
} }
/**
* Get the version number of the application.
*
* @return string
*/
public function version()
{
return static::VERSION;
}
/** /**
* Register the basic bindings into the container. * Register the basic bindings into the container.
*/ */
protected function registerBaseBindings() protected function registerBaseBindings()
{ {
static::setInstance($this); \Illuminate\Container\Container::setInstance($this->container);
$this->instance('app', $this); $this->container->instance('app', $this->container);
$this->container->alias('app', \Illluminate\Container\Container::class);
$this->instance(Container::class, $this); $this->container->instance('flarum', $this);
$this->container->alias('flarum', self::class);
$this->container->instance('flarum.paths', $this->paths);
$this->container->alias('flarum.paths', Paths::class);
} }
/** /**
@ -191,37 +158,7 @@ class Application extends Container implements ApplicationContract
*/ */
protected function registerBaseServiceProviders() protected function registerBaseServiceProviders()
{ {
$this->register(new EventServiceProvider($this)); $this->register(new EventServiceProvider($this->container));
}
/**
* Set the base path for the application.
*
* @param string $basePath
* @return $this
*/
public function setBasePath($basePath)
{
$this->basePath = rtrim($basePath, '\/');
$this->bindPathsInContainer();
return $this;
}
/**
* Set the public path for the application.
*
* @param string $publicPath
* @return $this
*/
public function setPublicPath($publicPath)
{
$this->publicPath = rtrim($publicPath, '\/');
$this->bindPathsInContainer();
return $this;
} }
/** /**
@ -232,7 +169,7 @@ class Application extends Container implements ApplicationContract
protected function bindPathsInContainer() protected function bindPathsInContainer()
{ {
foreach (['base', 'public', 'storage', 'vendor'] as $path) { foreach (['base', 'public', 'storage', 'vendor'] as $path) {
$this->instance('path.'.$path, $this->{$path.'Path'}()); $this->container->instance('path.'.$path, $this->paths->$path);
} }
} }
@ -243,7 +180,7 @@ class Application extends Container implements ApplicationContract
*/ */
public function basePath() public function basePath()
{ {
return $this->basePath; return $this->paths->base;
} }
/** /**
@ -253,7 +190,7 @@ class Application extends Container implements ApplicationContract
*/ */
public function publicPath() public function publicPath()
{ {
return $this->publicPath; return $this->paths->public;
} }
/** /**
@ -263,7 +200,7 @@ class Application extends Container implements ApplicationContract
*/ */
public function storagePath() public function storagePath()
{ {
return $this->storagePath ?: $this->basePath.DIRECTORY_SEPARATOR.'storage'; return $this->paths->storage;
} }
/** /**
@ -273,89 +210,7 @@ class Application extends Container implements ApplicationContract
*/ */
public function vendorPath() public function vendorPath()
{ {
return $this->vendorPath ?: $this->basePath.DIRECTORY_SEPARATOR.'vendor'; return $this->paths->vendor;
}
/**
* Set the storage directory.
*
* @param string $path
* @return $this
*/
public function useStoragePath($path)
{
$this->storagePath = $path;
$this->instance('path.storage', $path);
return $this;
}
/**
* Set the vendor directory.
*
* @param string $path
* @return $this
*/
public function useVendorPath($path)
{
$this->vendorPath = $path;
$this->instance('path.vendor', $path);
return $this;
}
/**
* Get or check the current application environment.
*
* @param mixed
* @return string
*/
public function environment()
{
if (func_num_args() > 0) {
$patterns = is_array(func_get_arg(0)) ? func_get_arg(0) : func_get_args();
foreach ($patterns as $pattern) {
if (Str::is($pattern, $this['env'])) {
return true;
}
}
return false;
}
return $this['env'];
}
/**
* Determine if we are running in the console.
*
* @return bool
*/
public function runningInConsole()
{
return php_sapi_name() == 'cli';
}
/**
* Determine if we are running unit tests.
*
* @return bool
*/
public function runningUnitTests()
{
return $this['env'] == 'testing';
}
/**
* Register all of the configured providers.
*
* @return void
*/
public function registerConfiguredProviders()
{
} }
/** /**
@ -423,7 +278,7 @@ class Application extends Container implements ApplicationContract
*/ */
public function resolveProviderClass($provider) public function resolveProviderClass($provider)
{ {
return new $provider($this); return new $provider($this->container);
} }
/** /**
@ -434,106 +289,13 @@ class Application extends Container implements ApplicationContract
*/ */
protected function markAsRegistered($provider) protected function markAsRegistered($provider)
{ {
$this['events']->dispatch($class = get_class($provider), [$provider]); $this->container['events']->dispatch($class = get_class($provider), [$provider]);
$this->serviceProviders[] = $provider; $this->serviceProviders[] = $provider;
$this->loadedProviders[$class] = true; $this->loadedProviders[$class] = true;
} }
/**
* Load and boot all of the remaining deferred providers.
*/
public function loadDeferredProviders()
{
// We will simply spin through each of the deferred providers and register each
// one and boot them if the application has booted. This should make each of
// the remaining services available to this application for immediate use.
foreach ($this->deferredServices as $service => $provider) {
$this->loadDeferredProvider($service);
}
$this->deferredServices = [];
}
/**
* Load the provider for a deferred service.
*
* @param string $service
*/
public function loadDeferredProvider($service)
{
if (! isset($this->deferredServices[$service])) {
return;
}
$provider = $this->deferredServices[$service];
// If the service provider has not already been loaded and registered we can
// register it with the application and remove the service from this list
// of deferred services, since it will already be loaded on subsequent.
if (! isset($this->loadedProviders[$provider])) {
$this->registerDeferredProvider($provider, $service);
}
}
/**
* Register a deferred provider and service.
*
* @param string $provider
* @param string $service
*/
public function registerDeferredProvider($provider, $service = null)
{
// Once the provider that provides the deferred service has been registered we
// will remove it from our local list of the deferred services with related
// providers so that this container does not try to resolve it out again.
if ($service) {
unset($this->deferredServices[$service]);
}
$this->register($instance = new $provider($this));
if (! $this->booted) {
$this->booting(function () use ($instance) {
$this->bootProvider($instance);
});
}
}
/**
* Resolve the given type from the container.
*
* (Overriding Container::make)
*
* @param string $abstract
* @param array $parameters
* @return mixed
*/
public function make($abstract, array $parameters = [])
{
$abstract = $this->getAlias($abstract);
if (isset($this->deferredServices[$abstract])) {
$this->loadDeferredProvider($abstract);
}
return parent::make($abstract, $parameters);
}
/**
* Determine if the given abstract type has been bound.
*
* (Overriding Container::bound)
*
* @param string $abstract
* @return bool
*/
public function bound($abstract)
{
return isset($this->deferredServices[$abstract]) || parent::bound($abstract);
}
/** /**
* Determine if the application has booted. * Determine if the application has booted.
* *
@ -578,7 +340,7 @@ class Application extends Container implements ApplicationContract
protected function bootProvider(ServiceProvider $provider) protected function bootProvider(ServiceProvider $provider)
{ {
if (method_exists($provider, 'boot')) { if (method_exists($provider, 'boot')) {
return $this->call([$provider, 'boot']); return $this->container->call([$provider, 'boot']);
} }
} }
@ -621,96 +383,13 @@ class Application extends Container implements ApplicationContract
} }
} }
/**
* Get the path to the cached "compiled.php" file.
*
* @return string
*/
public function getCachedCompilePath()
{
return $this->basePath().'/bootstrap/cache/compiled.php';
}
/**
* Get the path to the cached services.json file.
*
* @return string
*/
public function getCachedServicesPath()
{
return $this->basePath().'/bootstrap/cache/services.json';
}
/**
* Determine if the application is currently down for maintenance.
*
* @return bool
*/
public function isDownForMaintenance()
{
return $this->config('offline');
}
/**
* Get the service providers that have been loaded.
*
* @return array
*/
public function getLoadedProviders()
{
return $this->loadedProviders;
}
/**
* Get the application's deferred services.
*
* @return array
*/
public function getDeferredServices()
{
return $this->deferredServices;
}
/**
* Set the application's deferred services.
*
* @param array $services
* @return void
*/
public function setDeferredServices(array $services)
{
$this->deferredServices = $services;
}
/**
* Add an array of services to the application's deferred services.
*
* @param array $services
* @return void
*/
public function addDeferredServices(array $services)
{
$this->deferredServices = array_merge($this->deferredServices, $services);
}
/**
* Determine if the given service is a deferred service.
*
* @param string $service
* @return bool
*/
public function isDeferredService($service)
{
return isset($this->deferredServices[$service]);
}
/** /**
* Register the core class aliases in the container. * Register the core class aliases in the container.
*/ */
public function registerCoreContainerAliases() public function registerCoreContainerAliases()
{ {
$aliases = [ $aliases = [
'app' => [self::class, \Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class, \Psr\Container\ContainerInterface::class], 'app' => [\Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class, \Psr\Container\ContainerInterface::class],
'blade.compiler' => [\Illuminate\View\Compilers\BladeCompiler::class], 'blade.compiler' => [\Illuminate\View\Compilers\BladeCompiler::class],
'cache' => [\Illuminate\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class], 'cache' => [\Illuminate\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class],
'cache.store' => [\Illuminate\Cache\Repository::class, \Illuminate\Contracts\Cache\Repository::class], 'cache.store' => [\Illuminate\Cache\Repository::class, \Illuminate\Contracts\Cache\Repository::class],
@ -730,36 +409,8 @@ class Application extends Container implements ApplicationContract
foreach ($aliases as $key => $aliases) { foreach ($aliases as $key => $aliases) {
foreach ((array) $aliases as $alias) { foreach ((array) $aliases as $alias) {
$this->alias($key, $alias); $this->container->alias($key, $alias);
} }
} }
} }
/**
* Flush the container of all bindings and resolved instances.
*/
public function flush()
{
parent::flush();
$this->loadedProviders = [];
}
/**
* Get the path to the cached packages.php file.
*
* @return string
*/
public function getCachedPackagesPath()
{
return storage_path('app/cache/packages.php');
}
/**
* @return string
*/
public function resourcePath()
{
return storage_path('resources');
}
} }

View File

@ -95,19 +95,18 @@ class InstalledSite implements SiteInterface
return $this; return $this;
} }
private function bootLaravel(): Application private function bootLaravel(): Container
{ {
$laravel = new Application($this->paths->base, $this->paths->public); $container = new \Illuminate\Container\Container;
$laravel = new Application($container, $this->paths);
$laravel->useStoragePath($this->paths->storage); $container->instance('env', 'production');
$laravel->useVendorPath($this->paths->vendor); $container->instance('flarum.config', $this->config);
$container->instance('flarum.debug', $laravel->inDebugMode());
$container->instance('config', $config = $this->getIlluminateConfig($laravel));
$laravel->instance('env', 'production'); $this->registerLogger($container);
$laravel->instance('flarum.config', $this->config); $this->registerCache($container);
$laravel->instance('config', $config = $this->getIlluminateConfig($laravel));
$this->registerLogger($laravel);
$this->registerCache($laravel);
$laravel->register(AdminServiceProvider::class); $laravel->register(AdminServiceProvider::class);
$laravel->register(ApiServiceProvider::class); $laravel->register(ApiServiceProvider::class);
@ -138,18 +137,18 @@ class InstalledSite implements SiteInterface
$laravel->register(ValidationServiceProvider::class); $laravel->register(ValidationServiceProvider::class);
$laravel->register(ViewServiceProvider::class); $laravel->register(ViewServiceProvider::class);
$laravel->booting(function (Container $app) { $laravel->booting(function () use ($container) {
// Run all local-site extenders before booting service providers // Run all local-site extenders before booting service providers
// (but after those from "real" extensions, which have been set up // (but after those from "real" extensions, which have been set up
// in a service provider above). // in a service provider above).
foreach ($this->extenders as $extension) { foreach ($this->extenders as $extension) {
$extension->extend($app); $extension->extend($container);
} }
}); });
$laravel->boot(); $laravel->boot();
return $laravel; return $container;
} }
/** /**
@ -189,26 +188,26 @@ class InstalledSite implements SiteInterface
]); ]);
} }
private function registerLogger(Application $app) private function registerLogger(Container $container)
{ {
$logPath = $this->paths->storage.'/logs/flarum.log'; $logPath = $this->paths->storage.'/logs/flarum.log';
$handler = new RotatingFileHandler($logPath, Logger::INFO); $handler = new RotatingFileHandler($logPath, Logger::INFO);
$handler->setFormatter(new LineFormatter(null, null, true, true)); $handler->setFormatter(new LineFormatter(null, null, true, true));
$app->instance('log', new Logger($app->environment(), [$handler])); $container->instance('log', new Logger('flarum', [$handler]));
$app->alias('log', LoggerInterface::class); $container->alias('log', LoggerInterface::class);
} }
private function registerCache(Application $app) private function registerCache(Container $container)
{ {
$app->singleton('cache.store', function ($app) { $container->singleton('cache.store', function ($container) {
return new CacheRepository($app->make('cache.filestore')); return new CacheRepository($container->make('cache.filestore'));
}); });
$app->alias('cache.store', Repository::class); $container->alias('cache.store', Repository::class);
$app->singleton('cache.filestore', function () { $container->singleton('cache.filestore', function () {
return new FileStore(new Filesystem, $this->paths->storage.'/cache'); return new FileStore(new Filesystem, $this->paths->storage.'/cache');
}); });
$app->alias('cache.filestore', Store::class); $container->alias('cache.filestore', Store::class);
} }
} }

View File

@ -16,6 +16,7 @@ use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\Settings\UninstalledSettingsRepository; use Flarum\Settings\UninstalledSettingsRepository;
use Flarum\User\SessionServiceProvider; use Flarum\User\SessionServiceProvider;
use Illuminate\Config\Repository as ConfigRepository; use Illuminate\Config\Repository as ConfigRepository;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Filesystem\FilesystemServiceProvider; use Illuminate\Filesystem\FilesystemServiceProvider;
use Illuminate\Validation\ValidationServiceProvider; use Illuminate\Validation\ValidationServiceProvider;
@ -51,18 +52,17 @@ class UninstalledSite implements SiteInterface
); );
} }
private function bootLaravel(): Application private function bootLaravel(): Container
{ {
$laravel = new Application($this->paths->base, $this->paths->public); $container = new \Illuminate\Container\Container;
$laravel = new Application($container, $this->paths);
$laravel->useStoragePath($this->paths->storage); $container->instance('env', 'production');
$laravel->useVendorPath($this->paths->vendor); $container->instance('flarum.config', []);
$container->instance('flarum.debug', $laravel->inDebugMode());
$container->instance('config', $config = $this->getIlluminateConfig());
$laravel->instance('env', 'production'); $this->registerLogger($container);
$laravel->instance('flarum.config', []);
$laravel->instance('config', $config = $this->getIlluminateConfig());
$this->registerLogger($laravel);
$laravel->register(ErrorServiceProvider::class); $laravel->register(ErrorServiceProvider::class);
$laravel->register(LocaleServiceProvider::class); $laravel->register(LocaleServiceProvider::class);
@ -94,7 +94,7 @@ class UninstalledSite implements SiteInterface
$laravel->boot(); $laravel->boot();
return $laravel; return $container;
} }
/** /**
@ -114,13 +114,13 @@ class UninstalledSite implements SiteInterface
]); ]);
} }
private function registerLogger(Application $app) private function registerLogger(Container $container)
{ {
$logPath = $this->paths->storage.'/logs/flarum-installer.log'; $logPath = $this->paths->storage.'/logs/flarum-installer.log';
$handler = new StreamHandler($logPath, Logger::DEBUG); $handler = new StreamHandler($logPath, Logger::DEBUG);
$handler->setFormatter(new LineFormatter(null, null, true, true)); $handler->setFormatter(new LineFormatter(null, null, true, true));
$app->instance('log', new Logger('Flarum Installer', [$handler])); $container->instance('log', new Logger('Flarum Installer', [$handler]));
$app->alias('log', LoggerInterface::class); $container->alias('log', LoggerInterface::class);
} }
} }

View File

@ -24,11 +24,11 @@ class FrontendServiceProvider extends AbstractServiceProvider
$assets = new Assets( $assets = new Assets(
$name, $name,
$this->app->make('filesystem')->disk('flarum-assets'), $this->app->make('filesystem')->disk('flarum-assets'),
$this->app->storagePath() $this->app['flarum']->storagePath()
); );
$assets->setLessImportDirs([ $assets->setLessImportDirs([
$this->app->vendorPath().'/components/font-awesome/less' => '' $this->app['flarum']->vendorPath().'/components/font-awesome/less' => ''
]); ]);
$assets->css([$this, 'addBaseCss']); $assets->css([$this, 'addBaseCss']);

View File

@ -73,6 +73,8 @@ class Server
Flarum encountered a boot error ($type)<br /> Flarum encountered a boot error ($type)<br />
<b>$message</b><br /> <b>$message</b><br />
thrown in <b>$file</b> on line <b>$line</b> thrown in <b>$file</b> on line <b>$line</b>
<pre>$error</pre>
ERROR; ERROR;
} }
} }

View File

@ -18,6 +18,11 @@ class UrlGenerator
*/ */
protected $routes = []; protected $routes = [];
/**
* @var Application
*/
protected $app;
/** /**
* @param Application $app * @param Application $app
*/ */

View File

@ -51,7 +51,7 @@ class LocaleServiceProvider extends AbstractServiceProvider
$this->getDefaultLocale(), $this->getDefaultLocale(),
null, null,
$this->getCacheDir(), $this->getCacheDir(),
$this->app->inDebugMode() $this->app['flarum.debug']
); );
$translator->setFallbackLocales(['en']); $translator->setFallbackLocales(['en']);
@ -73,6 +73,6 @@ class LocaleServiceProvider extends AbstractServiceProvider
private function getCacheDir(): string private function getCacheDir(): string
{ {
return $this->app->storagePath().'/locale'; return $this->app['flarum']->storagePath().'/locale';
} }
} }

View File

@ -11,6 +11,7 @@ namespace Flarum\Tests\integration;
use Flarum\Extend\ExtenderInterface; use Flarum\Extend\ExtenderInterface;
use Flarum\Foundation\InstalledSite; use Flarum\Foundation\InstalledSite;
use Flarum\Foundation\Paths;
use Illuminate\Database\ConnectionInterface; use Illuminate\Database\ConnectionInterface;
use Laminas\Diactoros\ServerRequest; use Laminas\Diactoros\ServerRequest;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
@ -33,12 +34,12 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase
{ {
if (is_null($this->app)) { if (is_null($this->app)) {
$site = new InstalledSite( $site = new InstalledSite(
[ new Paths([
'base' => __DIR__.'/tmp', 'base' => __DIR__.'/tmp',
'vendor' => __DIR__.'/../../vendor', 'vendor' => __DIR__.'/../../vendor',
'public' => __DIR__.'/tmp/public', 'public' => __DIR__.'/tmp/public',
'storage' => __DIR__.'/tmp/storage', 'storage' => __DIR__.'/tmp/storage',
], ]),
include __DIR__.'/tmp/config.php' include __DIR__.'/tmp/config.php'
); );