. */ declare(strict_types=1); namespace Fisharebest\Webtrees\Http\Middleware; use Closure; use Fisharebest\Webtrees\Module\ModuleThemeInterface; use Fisharebest\Webtrees\Module\WebtreesTheme; use Fisharebest\Webtrees\Services\ModuleService; use Fisharebest\Webtrees\Session; use Fisharebest\Webtrees\Site; use Fisharebest\Webtrees\Tree; use Generator; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Throwable; /** * Middleware to set a global theme. */ class UseTheme implements MiddlewareInterface { /** @var ModuleService */ private $module_service; /** @var Tree|null */ private $tree; /** * UseTheme constructor. * * @param ModuleService $module_service * @param Tree|null $tree */ public function __construct(ModuleService $module_service, ?Tree $tree) { $this->module_service = $module_service; $this->tree = $tree; } /** * @param Request $request * @param Closure $next * * @return Response * @throws Throwable */ public function handle(Request $request, Closure $next): Response { foreach ($this->themes() as $theme) { if ($theme instanceof ModuleThemeInterface) { // Bind this theme into the container app()->instance(ModuleThemeInterface::class, $theme); // Remember this setting Session::put('theme_id', $theme->name()); break; } } return $next($request); } /** * The theme can be chosen in various ways. * * @return Generator */ private function themes(): Generator { $themes = $this->module_service->findByInterface(ModuleThemeInterface::class); // Last theme used yield $themes->get(Session::get('theme_id', '')); // Default for tree if ($this->tree instanceof Tree) { yield $themes->get($this->tree->getPreference('THEME_DIR')); } // Default for site yield $themes->get(Site::getPreference('THEME_DIR')); // Default for application yield app()->make(WebtreesTheme::class); } }