Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- Fixed some errors that could occur when running Craft through Laravel Octane ([#18921](https://github.com/craftcms/cms/pull/18921))
- Fixed an error that occurred when Updates were cached and deserialized.

## 6.0.0-alpha.4 - 2026-05-19
Expand Down
13 changes: 13 additions & 0 deletions src/Http/Middleware/RequireCpRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
namespace CraftCms\Cms\Http\Middleware;

use Closure;
use CraftCms\Cms\Support\Facades\TemplateHooks;
use CraftCms\Cms\View\Hooks\PrepareElementIndexVariables;
use CraftCms\Cms\View\Hooks\PrepareElementSourcesVariables;
use CraftCms\Cms\View\Hooks\PrepareElementToolbarVariables;
use CraftCms\Cms\View\TemplateMode;
use Illuminate\Http\Request;

Expand All @@ -18,6 +22,15 @@ public function handle(Request $request, Closure $next): mixed

TemplateMode::set(TemplateMode::Cp);

$this->registerCpTemplateHooks();

return $next($request);
}

public function registerCpTemplateHooks(): void
{
TemplateHooks::register('cp.layouts.elementindex', PrepareElementIndexVariables::class);
TemplateHooks::register('cp.elements.toolbar', PrepareElementToolbarVariables::class);
TemplateHooks::register('cp.elements.sources', PrepareElementSourcesVariables::class);
}
}
24 changes: 24 additions & 0 deletions src/View/TemplateMode.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use CraftCms\Cms\View\Events\CpTemplateRootsResolving;
use CraftCms\Cms\View\Events\SiteTemplateRootsResolving;
use Illuminate\Support\Facades\Context;
use Illuminate\View\FileViewFinder;

enum TemplateMode: string
{
Expand All @@ -31,6 +32,29 @@ public static function get(): self
public static function set(self $mode): void
{
Context::addHidden(self::class, $mode);

if ($mode === self::Cp) {
/**
* Prepend the Craft CMS Control panel views when
* we're in CP Template mode. This makes view()
* work without a 'craftcms::' prefix.
*/
if (TemplateMode::is(TemplateMode::Cp)) {
$templates = dirname(__DIR__, 2).'/resources/templates';
$views = dirname(__DIR__, 2).'/resources/views';

/** @var FileViewFinder $finder */
$finder = view()->getFinder();

if (! in_array($templates, $finder->getPaths())) {
$finder->prependLocation($templates);
}

if (! in_array($views, $finder->getPaths())) {
$finder->prependLocation($views);
}
}
}
}

public static function is(self $mode): bool
Expand Down
32 changes: 1 addition & 31 deletions src/View/ViewServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
namespace CraftCms\Cms\View;

use CraftCms\Cms\View\Events\ViewAssetsRendering;
use CraftCms\Cms\View\Hooks\PrepareElementIndexVariables;
use CraftCms\Cms\View\Hooks\PrepareElementSourcesVariables;
use CraftCms\Cms\View\Hooks\PrepareElementToolbarVariables;
use CraftCms\Cms\View\LegacyAssets\InternalAssetRegistry;
use Illuminate\Contracts\View\Factory as ViewFactory;
use Illuminate\Support\Facades\Event;
Expand All @@ -33,7 +30,7 @@ public function register(): void
);
}

public function boot(TemplateHooks $hooks): void
public function boot(): void
{
Event::listen(function (ViewAssetsRendering $event) {
app(InternalAssetRegistry::class)->flush();
Expand All @@ -48,23 +45,6 @@ public function boot(TemplateHooks $hooks): void

$this->registerTemplateRoots();
$this->registerTemplateGlobals();

$hooks->register('cp.layouts.elementindex', PrepareElementIndexVariables::class);
$hooks->register('cp.elements.toolbar', PrepareElementToolbarVariables::class);
$hooks->register('cp.elements.sources', PrepareElementSourcesVariables::class);

$this->app->booted(function () {
/**
* This ensures that when Laravel tries to find an error view,
* it will look in the CP templates for it as well.
*/
if (request()->isCpRequest()) {
config()->set('view.paths', array_merge(
config('view.paths'),
[dirname(__DIR__, 2).'/resources/templates']
));
}
});
}

private function registerTemplateGlobals(): void
Expand All @@ -82,16 +62,6 @@ private function registerTemplateRoots(): void
/** @var Factory $factory */
$factory = $this->app->make(ViewFactory::class);

/**
* Prepend the Craft CMS Control panel views when
* we're in CP Template mode. This makes view()
* work without a 'craftcms::' prefix.
*/
if (TemplateMode::is(TemplateMode::Cp)) {
$factory->prependLocation("{$this->root}/resources/templates");
$factory->prependLocation("{$this->root}/resources/views");
}

foreach (TemplateMode::get()->templateRoots() as $namespace => $roots) {
$factory->addNamespace($namespace, $roots);

Expand Down
3 changes: 3 additions & 0 deletions tests/Feature/Cp/ElementIndexHtmlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@

use CraftCms\Cms\Cp\Html\ElementIndexHtml;
use CraftCms\Cms\Entry\Elements\Entry;
use CraftCms\Cms\Http\Middleware\RequireCpRequest;
use CraftCms\Cms\User\Elements\User;

use function Pest\Laravel\actingAs;

beforeEach(function () {
actingAs(User::findOne());

app(RequireCpRequest::class)->registerCpTemplateHooks();
});

it('renders an element index shell with toolbar and elements container', function () {
Expand Down
15 changes: 15 additions & 0 deletions yii2-adapter/src/Http/LegacyMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public function handle(Request $request, Closure $next): mixed
$this->restoreEmptyStrings($request);

try {
$this->ensureCraftApp();

/** @var \craft\web\Request $yiiRequest */
$yiiRequest = Craft::createObject(App::webRequestConfig());
$yiiRequest->csrfCookie = Craft::cookieConfig([], $yiiRequest);
Expand Down Expand Up @@ -128,6 +130,19 @@ public static function cleanup(): void
});
}

private function ensureCraftApp(): void
{
if (class_exists(Craft::class, false) && Craft::$app) {
return;
}

$craftApp = $this->app->make('Craft');

if (!Craft::$app) {
Craft::$app = $craftApp;
}
}

private function restoreEmptyStrings(Request $request): void
{
$parameters = $request->isJson()
Expand Down
53 changes: 53 additions & 0 deletions yii2-adapter/src/Http/PrepareLegacyCraftApp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace CraftCms\Yii2Adapter\Http;

use Closure;
use Craft;
use craft\helpers\App;
use Illuminate\Foundation\Application;
use Illuminate\Http\Request;

readonly class PrepareLegacyCraftApp
{
public function __construct(
private Application $app,
) {
}

public function handle(Request $request, Closure $next): mixed
{
$this->restoreCraftApp();
$this->refreshRequestScopedComponents($request);

return $next($request);
}

private function restoreCraftApp(): void
{
if (class_exists(Craft::class, false) && Craft::$app) {
return;
}

$craftApp = $this->app->make('Craft');

if (!Craft::$app) {
Craft::$app = $craftApp;
}
}

private function refreshRequestScopedComponents(Request $request): void
{
$this->app->instance('request', $request);

/** @var \craft\web\Request $yiiRequest */
$yiiRequest = Craft::createObject(App::webRequestConfig());
$yiiRequest->csrfCookie = Craft::cookieConfig([], $yiiRequest);

Craft::$app->set('request', $yiiRequest);
Craft::$app->set('view', Craft::createObject(App::viewConfig()));
Craft::$app->set('user', Craft::createObject(App::userConfig()));
}
}
3 changes: 3 additions & 0 deletions yii2-adapter/src/Yii2ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@
use CraftCms\Yii2Adapter\HtmlPurifier\LegacyHtmlPurifierConfigRegistrar;
use CraftCms\Yii2Adapter\Http\CaptureOriginalActionRequestUri;
use CraftCms\Yii2Adapter\Http\LegacyMiddleware;
use CraftCms\Yii2Adapter\Http\PrepareLegacyCraftApp;
use CraftCms\Yii2Adapter\I18N\I18NCompatibility;
use CraftCms\Yii2Adapter\Mail\TestToEmailAddressCompatibility;
use CraftCms\Yii2Adapter\Mixins\CraftVariableMixin;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Illuminate\Contracts\Http\Kernel as HttpKernel;
use Illuminate\Foundation\Exceptions\Handler;
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Event;
Expand Down Expand Up @@ -182,6 +184,7 @@ private function toLegacyException(Throwable $exception): Throwable
public function boot(): void
{
$this->app->make(HttpKernel::class)->prependMiddleware(CaptureOriginalActionRequestUri::class);
$this->app->make(Router::class)->pushMiddlewareToGroup('craft', PrepareLegacyCraftApp::class);

$this->commands([
AddCategoriesSupportCommand::class,
Expand Down
Loading