feature: Laravel 13 support (#19514)

* feature: Laravel 13 support

* Swap VerifyCsrfToken out for PreventRequestForgery

* Replace capture directive

* Update TestCase.php

* Remove EloquentSerialize package
This commit is contained in:
Dan Harrin
2026-03-17 19:37:33 +00:00
committed by GitHub
parent e8034d6d78
commit 2a67f4c6a4
28 changed files with 1249 additions and 822 deletions
+6 -1
View File
@@ -15,9 +15,11 @@ jobs:
fail-fast: false
matrix:
php: [8.5, 8.4, 8.3, 8.2]
laravel: [12.*, 11.*]
laravel: [13.*, 12.*, 11.*]
dependency-version: [prefer-stable]
include:
- laravel: 13.*
testbench: 11.*
- laravel: 12.*
testbench: 10.*
- laravel: 11.*
@@ -34,6 +36,9 @@ jobs:
- php: 8.2
pest: ^3.7
pest-plugin-laravel: ^3.0
exclude:
- laravel: 13.*
php: 8.2
name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }}
steps:
- uses: actions/checkout@v4
+5 -1
View File
@@ -15,15 +15,19 @@ jobs:
fail-fast: true
matrix:
php: [8.5, 8.4, 8.3]
laravel: [12.*, 11.*]
laravel: [13.*, 12.*, 11.*]
db: [sqlite, mysql, pgsql]
dependency-version: [prefer-stable]
include:
- laravel: 13.*
testbench: 11.*
- laravel: 12.*
testbench: 10.*
- laravel: 11.*
testbench: 9.*
exclude:
- laravel: 13.*
php: 8.2
- laravel: 11.*
php: 8.5
name: P${{ matrix.php }} - L${{ matrix.laravel }} - DB:${{ matrix.db }}
+1 -2
View File
@@ -8,7 +8,6 @@
"ext-intl": "*"
},
"require-dev": {
"anourvalar/eloquent-serialize": "^1.2",
"chillerlan/php-qrcode": "^5.0",
"filament/support": "*",
"larastan/larastan": "^3.0",
@@ -18,7 +17,7 @@
"league/flysystem-aws-s3-v3": "^3.0",
"nunomaduro/termwind": "^2.0",
"openspout/openspout": "^4.23",
"orchestra/testbench": "^9.0|^10.0",
"orchestra/testbench": "^9.0|^10.0|^11.0",
"pestphp/pest": "^3.7|^4.0",
"pestphp/pest-plugin-browser": "^4.1",
"pestphp/pest-plugin-laravel": "^3.0|^4.0",
Generated
+603 -791
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -9,7 +9,6 @@
},
"require": {
"php": "^8.2",
"anourvalar/eloquent-serialize": "^1.2",
"filament/forms": "self.version",
"filament/infolists": "self.version",
"filament/notifications": "self.version",
@@ -2,7 +2,6 @@
namespace Filament\Actions\Concerns;
use AnourValar\EloquentSerialize\Facades\EloquentSerializeFacade;
use Closure;
use Filament\Actions\Action;
use Filament\Actions\ExportAction;
@@ -24,6 +23,7 @@ use Filament\Schemas\Components\Fieldset;
use Filament\Schemas\Components\Flex;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Filament\Support\EloquentSerializer\EloquentSerializer;
use Filament\Support\Enums\Size;
use Filament\Support\Enums\Width;
use Filament\Support\Facades\FilamentIcon;
@@ -294,7 +294,7 @@ trait CanExportRecords
$hasCsv = in_array(ExportFormat::Csv, $formats);
$hasXlsx = in_array(ExportFormat::Xlsx, $formats);
$serializedQuery = EloquentSerializeFacade::serialize($query);
$serializedQuery = app(EloquentSerializer::class)->serialize($query);
$job = $action->getJob();
$jobQueue = $exporter->getJobQueue();
@@ -2,10 +2,10 @@
namespace Filament\Actions\Exports\Jobs;
use AnourValar\EloquentSerialize\Facades\EloquentSerializeFacade;
use Carbon\CarbonInterface;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
use Filament\Support\EloquentSerializer\EloquentSerializer;
use Illuminate\Bus\Batchable;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Auth\Authenticatable;
@@ -74,7 +74,7 @@ class ExportCsv implements ShouldQueue
$csv = Writer::from(new SplTempFileObject);
$csv->setDelimiter($this->exporter::getCsvDelimiter());
$query = EloquentSerializeFacade::unserialize($this->query);
$query = app(EloquentSerializer::class)->unserialize($this->query);
foreach ($this->exporter->getCachedColumns() as $column) {
$column->applyRelationshipAggregates($query);
@@ -2,9 +2,9 @@
namespace Filament\Actions\Exports\Jobs;
use AnourValar\EloquentSerialize\Facades\EloquentSerializeFacade;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
use Filament\Support\EloquentSerializer\EloquentSerializer;
use Illuminate\Bus\Batchable;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Filesystem\Filesystem;
@@ -60,7 +60,7 @@ class PrepareCsvExport implements ShouldQueue
$filePath = $this->export->getFileDirectory() . DIRECTORY_SEPARATOR . 'headers.csv';
$this->export->getFileDisk()->put($filePath, $csv->toString(), Filesystem::VISIBILITY_PRIVATE);
$query = EloquentSerializeFacade::unserialize($this->query);
$query = app(EloquentSerializer::class)->unserialize($this->query);
$keyName = $query->getModel()->getKeyName();
$qualifiedKeyName = $query->getModel()->getQualifiedKeyName();
@@ -96,8 +96,11 @@ class PrepareCsvExport implements ShouldQueue
$firstOrder = $originalOrders->first();
if (($firstOrder['type'] ?? null) === 'Raw') {
/** @var literal-string $sql */
$sql = $firstOrder['sql'];
$query->reorder();
$query->orderByRaw($firstOrder['sql']);
$query->orderByRaw($sql);
} else {
$query->reorder($firstOrder['column'], $firstOrder['direction']);
}
@@ -109,7 +112,10 @@ class PrepareCsvExport implements ShouldQueue
foreach ($originalOrders as $order) {
if (($order['type'] ?? null) === 'Raw') {
$query->orderByRaw($order['sql']);
/** @var literal-string $orderSql */
$orderSql = $order['sql'];
$query->orderByRaw($orderSql);
} elseif (filled($order['column'] ?? null) && filled($order['direction'] ?? null)) {
$query->orderBy($order['column'], $order['direction']);
}
@@ -15,6 +15,7 @@ use Filament\Widgets\AccountWidget;
use Filament\Widgets\FilamentInfoWidget;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
@@ -54,7 +55,7 @@ class PanelProviderClassGenerator extends ClassGenerator
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
$this->getCsrfMiddlewareClass(),
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
@@ -138,7 +139,7 @@ class PanelProviderClassGenerator extends ClassGenerator
{$this->simplifyFqn(StartSession::class)}::class,
{$this->simplifyFqn(AuthenticateSession::class)}::class,
{$this->simplifyFqn(ShareErrorsFromSession::class)}::class,
{$this->simplifyFqn(VerifyCsrfToken::class)}::class,
{$this->simplifyFqn($this->getCsrfMiddlewareClass())}::class,
{$this->simplifyFqn(SubstituteBindings::class)}::class,
{$this->simplifyFqn(DisableBladeIconComponents::class)}::class,
{$this->simplifyFqn(DispatchServingFilamentEvent::class)}::class,
@@ -167,4 +168,14 @@ class PanelProviderClassGenerator extends ClassGenerator
{
return $this->isDefault;
}
/**
* @return class-string
*/
protected function getCsrfMiddlewareClass(): string
{
return class_exists(PreventRequestForgery::class)
? PreventRequestForgery::class
: VerifyCsrfToken::class;
}
}
+2 -3
View File
@@ -12,16 +12,15 @@
"ext-intl": "*",
"blade-ui-kit/blade-heroicons": "^2.5",
"danharrin/livewire-rate-limiting": "^2.0",
"illuminate/contracts": "^11.28|^12.0",
"illuminate/contracts": "^11.28|^12.0|^13.0",
"kirschbaum-development/eloquent-power-joins": "^4.0",
"league/uri-components": "^7.0",
"livewire/livewire": "^3.5",
"nette/php-generator": "^4.0",
"ryangjchandler/blade-capture-directive": "^1.0",
"spatie/invade": "^2.0",
"spatie/laravel-package-tools": "^1.9",
"symfony/html-sanitizer": "^7.0|^8.0",
"symfony/console": "^7.0"
"symfony/console": "^7.0|^8.0"
},
"autoload": {
"files": [
@@ -0,0 +1,76 @@
<?php
namespace Filament\Support\EloquentSerializer;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use Illuminate\Database\Eloquent\Relations\Relation;
use LogicException;
use RuntimeException;
class EloquentSerializer
{
use Grammars\EloquentBuilderGrammar;
use Grammars\ModelGrammar;
use Grammars\QueryBuilderGrammar;
/**
* @throws RuntimeException
*/
public function serialize(Builder | Relation $builder): string
{
if (
$builder instanceof HasOne
|| $builder instanceof HasMany
|| $builder instanceof BelongsTo // as well as `MorphTo`
|| $builder instanceof MorphOne
) {
$builder = $builder->getQuery(); // chaperone/inverse is not supported!
}
if ($builder instanceof Relation) {
throw new RuntimeException(get_class($builder) . ' cannot be packed.');
}
$package = $this->pack($builder);
return serialize($package); // important!
}
/**
* @throws LogicException
*/
public function unserialize(Package | string $package): Builder
{
// Prepare data
if (is_string($package)) {
$oldClass = 'AnourValar\EloquentSerialize\Package';
$newClass = Package::class;
// Replace the class reference in the serialized object header (`O:36:"..."`)
$package = str_replace(
'O:' . strlen($oldClass) . ':"' . $oldClass . '"',
'O:' . strlen($newClass) . ':"' . $newClass . '"',
$package,
);
// Replace the class prefix in serialized private properties (`s:42:"\0...\0data"`)
$package = str_replace(
's:' . (strlen($oldClass) + 6) . ':"' . "\0" . $oldClass . "\0" . 'data"',
's:' . (strlen($newClass) + 6) . ':"' . "\0" . $newClass . "\0" . 'data"',
$package,
);
$package = unserialize($package);
}
if (! ($package instanceof Package)) {
throw new LogicException('Incorrect argument.');
}
// Unpack
return $this->unpack($package);
}
}
@@ -0,0 +1,154 @@
<?php
namespace Filament\Support\EloquentSerializer\Grammars;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Laravel\SerializableClosure\SerializableClosure;
trait EloquentBuilderGrammar
{
/**
* @param array<class-string>|null $parentModels
* @return array<string, mixed>
*/
protected function packEloquentBuilder(EloquentBuilder $builder, ?array $parentModels = null): array
{
return [
'with' => $this->getEagers($builder, $parentModels ?? []), // preloaded ("eager") relations
'removed_scopes' => $builder->removedScopes(), // global scopes
'casts' => $builder->getModel()->getCasts(),
];
}
/**
* @param array<string, mixed> $data
*/
protected function unpackEloquentBuilder(array $data, EloquentBuilder &$builder): void
{
// Preloaded ("eager") relations
$this->setEagers($builder, $data['with']);
// Global scopes
if ($data['removed_scopes']) {
$builder->withoutGlobalScopes($data['removed_scopes']);
}
// Casts
$builder->getModel()->mergeCasts($data['casts']);
}
/**
* @param array<class-string> $parentModels
* @return array<string, mixed>
*/
private function getEagers(EloquentBuilder $builder, array $parentModels): array
{
$result = [];
foreach ($builder->getEagerLoads() as $name => $value) {
$relation = $builder;
foreach (explode('.', $name) as $part) {
$relation = $relation->getRelation($part); // get a relation without "constraints"
}
$referenceRelation = clone $relation;
if (count(array_filter($parentModels, fn ($item) => $item == get_class($referenceRelation->getModel()))) > 1) {
$result[$name] = ['closure' => serialize(new SerializableClosure($value))]; // recursion detected...
continue;
}
$parentModels[] = get_class($builder->getModel());
$value($relation); // apply closure
$result[$name] = [
'query' => $this->packQueryBuilder($relation->getQuery()->getQuery()),
'eloquent' => $this->packEloquentBuilder($relation->getQuery(), $parentModels),
'extra' => $this->getExtraRelationParameters($relation),
];
$relation->getQuery()->getModel()->newInstance()->with($name)->getEagerLoads()[$name]($referenceRelation);
$this->cleanStaticConstraints($result[$name]['query'], $this->packQueryBuilder($referenceRelation->getQuery()->getQuery()));
}
return $result;
}
/**
* @param array<string, mixed> $eagers
*/
private function setEagers(EloquentBuilder $builder, array $eagers): void
{
foreach ($eagers as &$value) {
if (isset($value['closure'])) {
$value = unserialize($value['closure'])->getClosure();
continue;
}
$value = function ($query) use ($value) {
if (isset($value['extra']) && $query instanceof Relation) {
$this->setExtraRelationParameters($query, $value['extra']);
}
// Input argument may be different depends on context
while (! ($query instanceof EloquentBuilder)) {
$query = $query->getQuery();
}
if (isset($value['eloquent'])) {
$this->unpackEloquentBuilder($value['eloquent'], $query);
}
// Input argument may be different depends on context
while (! ($query instanceof QueryBuilder)) {
$query = $query->getQuery();
}
$this->unpackQueryBuilder(isset($value['query']) ? $value['query'] : $value, $query);
};
}
unset($value);
$builder->setEagerLoads($eagers);
}
/**
* @param array<string, mixed> $packedQueryBuilder
* @param array<string, mixed> $packedReferenceQueryBuilder
*/
private function cleanStaticConstraints(array &$packedQueryBuilder, array $packedReferenceQueryBuilder): void
{
$properties = [
'aggregate', 'columns', 'distinct', 'wheres', 'groups', 'havings', 'orders', 'limit', 'offset', 'unions',
'unionLimit', 'unionOffset', 'unionOrders', 'joins', 'groupLimit',
];
foreach ($properties as $property) {
if (! is_array($packedQueryBuilder[$property] ?? null)) {
continue;
}
foreach ($packedQueryBuilder[$property] as $key => $item) {
if (in_array($item, (array) ($packedReferenceQueryBuilder[$property] ?? null), true)) {
unset($packedQueryBuilder[$property][$key]);
}
}
}
foreach ($packedQueryBuilder['bindings'] as $binding => $data) {
if (! is_array($data)) {
continue;
}
foreach ($data as $key => $value) {
if (
isset($packedReferenceQueryBuilder['bindings'][$binding][$key])
&& $packedReferenceQueryBuilder['bindings'][$binding][$key] === $value
) {
unset($packedQueryBuilder['bindings'][$binding][$key]);
}
}
}
}
}
@@ -0,0 +1,148 @@
<?php
namespace Filament\Support\EloquentSerializer\Grammars;
use Filament\Support\EloquentSerializer\Package;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\HasOneOrMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\Relation;
use RuntimeException;
use function Livewire\invade;
trait ModelGrammar
{
protected function pack(Builder $builder): Package
{
// Global scopes handle
$builder = $builder->applyScopes();
/** @var array<string, object> $scopes */
$scopes = invade($builder)->scopes;
$builder->withoutGlobalScopes(array_keys($scopes));
return new Package([
'model' => get_class($builder->getModel()),
'connection' => $builder->getModel()->getConnectionName(),
'eloquent' => $this->packEloquentBuilder($builder),
'query' => $this->packQueryBuilder($builder->getQuery()),
]);
}
protected function unpack(Package $package): Builder
{
$builder = $package->get('model');
$builder = $builder::on($package->get('connection'));
$this->unpackEloquentBuilder($package->get('eloquent'), $builder);
$this->unpackQueryBuilder($package->get('query'), $builder->getQuery());
return $builder;
}
/**
* @return array<string, mixed>|null
*/
private function getExtraRelationParameters(Relation $relation): ?array
{
if ($relation instanceof MorphTo) {
$invaded = invade($relation);
return [
'morphableEagerLoads' => $this->serializeMorphableEager($invaded->morphableEagerLoads),
'morphableEagerLoadCounts' => $this->serializeMorphableEager($invaded->morphableEagerLoadCounts),
'morphableConstraints' => $invaded->morphableConstraints,
];
}
if ($relation instanceof HasOneOrMany) {
return [
'inverseRelationship' => invade($relation)->inverseRelationship,
];
}
return null;
}
/**
* @param array<string, mixed>|null $params
*/
private function setExtraRelationParameters(Relation $relation, ?array $params): void
{
if ($params === null) {
return;
}
$invaded = invade($relation);
foreach ($params as $key => $value) {
if ($key === 'morphableEagerLoads' || $key === 'morphableEagerLoadCounts') {
$value = $this->unserializeMorphableEager($value);
}
$invaded->{$key} = $value;
}
}
/**
* @param array<class-string, array<string, mixed>> $value
* @return array<class-string, array<string, mixed>>
*/
private function serializeMorphableEager(array $value): array
{
foreach ($value as $class => &$items) {
foreach ($items as $relation => &$item) {
if (! is_callable($item)) {
continue;
}
if (! method_exists($class, $relation)) {
throw new RuntimeException("Serialization error. Does relation '{$relation}' exists in the model '{$class}' ?");
}
$eloquentBuilder = (new $class)->{$relation}()->getModel()->newQuery();
$item($eloquentBuilder);
$item = [
'eloquent' => $this->packEloquentBuilder($eloquentBuilder),
'builder' => $this->packQueryBuilder($eloquentBuilder->getQuery()),
];
}
unset($item);
}
unset($items);
return $value;
}
/**
* @param array<class-string, array<string, mixed>> $value
* @return array<class-string, array<string, mixed>>
*/
private function unserializeMorphableEager(array $value): array
{
foreach ($value as &$items) {
foreach ($items as &$item) {
if (! is_array($item)) {
continue;
}
$item = function ($query) use ($item) {
if ($query instanceof Builder) {
$this->unpackEloquentBuilder($item['eloquent'], $query);
$this->unpackQueryBuilder($item['builder'], $query->getQuery());
} else {
$eloquent = $query->getQuery();
$this->unpackEloquentBuilder($item['eloquent'], $eloquent);
$this->unpackQueryBuilder($item['builder'], $query->getBaseQuery());
}
};
}
unset($item);
}
unset($items);
return $value;
}
}
@@ -0,0 +1,163 @@
<?php
namespace Filament\Support\EloquentSerializer\Grammars;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Query\JoinClause;
trait QueryBuilderGrammar
{
/**
* @return array<string, mixed>
*/
protected function packQueryBuilder(Builder $builder): array
{
return array_filter([
'bindings' => $builder->bindings,
'aggregate' => $builder->aggregate,
'columns' => $builder->columns,
'distinct' => $builder->distinct,
'from' => $builder->from,
'wheres' => $this->packWheres($builder->wheres),
'groups' => $builder->groups,
'havings' => $this->packWheres($builder->havings),
'groupLimit' => $builder->groupLimit ?? null,
'orders' => $builder->orders,
'limit' => $builder->limit,
'offset' => $builder->offset,
'unions' => $this->packUnions($builder->unions),
'unionLimit' => $builder->unionLimit,
'unionOffset' => $builder->unionOffset,
'unionOrders' => $builder->unionOrders,
'lock' => $builder->lock,
'joins' => $this->packJoins($builder->joins), // must be the last
], fn ($item) => isset($item));
}
/**
* @param array<string, mixed> $data
*/
protected function unpackQueryBuilder(array $data, Builder $builder): Builder
{
foreach ($data as $key => $value) {
if (in_array($key, ['wheres', 'havings'])) {
$value = $this->unpackWheres($value, $builder);
}
if ($key == 'unions') {
$value = $this->unpackUnions($value);
}
if ($key == 'joins') {
$value = $this->unpackJoins($value, $builder);
}
if (is_array($builder->$key) && is_array($value)) {
$builder->$key = array_merge_recursive($builder->$key, $value);
} else {
$builder->$key = $value;
}
}
return $builder;
}
private function packWheres(mixed $wheres): mixed
{
if (is_null($wheres)) {
return $wheres;
}
foreach ($wheres as &$item) {
if (isset($item['query'])) {
$item['query'] = $this->packQueryBuilder($item['query']);
}
}
unset($item);
return $wheres;
}
private function packUnions(mixed $unions): mixed
{
if (! is_array($unions)) {
return $unions;
}
foreach ($unions as &$item) {
if (isset($item['query'])) {
$item['query'] = $this->pack($item['query']);
}
}
unset($item);
return $unions;
}
private function packJoins(mixed $joins): mixed
{
if (! is_array($joins)) {
return $joins;
}
foreach ($joins as &$item) {
$item = array_replace(
['type' => $item->type, 'table' => $item->table],
$this->packQueryBuilder($item)
);
}
unset($item);
return $joins;
}
private function unpackWheres(mixed $wheres, Builder $builder): mixed
{
if (is_null($wheres)) {
return $wheres;
}
foreach ($wheres as &$item) {
if (isset($item['query'])) {
$item['query'] = $this->unpackQueryBuilder($item['query'], $builder->newQuery());
}
}
unset($item);
return $wheres;
}
private function unpackUnions(mixed $unions): mixed
{
if (! is_array($unions)) {
return $unions;
}
foreach ($unions as &$item) {
if (isset($item['query'])) {
$item['query'] = $this->unpack($item['query']);
}
}
unset($item);
return $unions;
}
private function unpackJoins(mixed $joins, Builder $builder): mixed
{
if (! is_array($joins)) {
return $joins;
}
foreach ($joins as &$item) {
$parentQuery = new JoinClause($builder, $item['type'], $item['table']);
unset($item['type'], $item['table']);
$item = $this->unpackQueryBuilder($item, $parentQuery);
}
unset($item);
return $joins;
}
}
@@ -0,0 +1,22 @@
<?php
namespace Filament\Support\EloquentSerializer;
class Package
{
/**
* @param array<string, mixed> $data
*/
public function __construct(
private array $data,
) {}
public function get(?string $key = null): mixed
{
if (is_null($key)) {
return $this->data;
}
return $this->data[$key] ?? null;
}
}
@@ -153,6 +153,26 @@ class SupportServiceProvider extends PackageServiceProvider
Js::make('support', __DIR__ . '/../dist/index.js'),
], 'filament/support');
Blade::directive('capture', function (string $expression): string {
[$name, $arguments] = str_contains($expression, ',') ?
array_map('trim', explode(',', $expression, 2)) :
[$expression, ''];
return "
<?php {$name} = (function (\$args) {
return function ({$arguments}) use (\$args) {
extract(\$args, EXTR_SKIP);
ob_start(); ?>
";
});
Blade::directive('endcapture', function (): string {
return "
<?php return new \Illuminate\Support\HtmlString(ob_get_clean()); };
})(get_defined_vars()); ?>
";
});
Blade::directive('captureSlots', function (string $expression): string {
return "<?php \$slotContents = get_defined_vars(); \$slots = collect({$expression})->mapWithKeys(fn (string \$slot): array => [\$slot => \$slotContents[\$slot] ?? null])->all(); unset(\$slotContents) ?>";
});
@@ -42,6 +42,7 @@ use Filament\Tests\Fixtures\Resources\Users\Resources\UserPostResource;
use Filament\Tests\Fixtures\Resources\Users\UserResource;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
@@ -102,7 +103,7 @@ class AdminPanelProvider extends PanelProvider
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
class_exists(PreventRequestForgery::class) ? PreventRequestForgery::class : VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
@@ -11,6 +11,7 @@ use Filament\Panel;
use Filament\PanelProvider;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
@@ -34,7 +35,7 @@ class AppAuthenticationPanelProvider extends PanelProvider
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
class_exists(PreventRequestForgery::class) ? PreventRequestForgery::class : VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
@@ -13,6 +13,7 @@ use Filament\Tests\Fixtures\Pages\ConfigurableSettings;
use Filament\Tests\Fixtures\Resources\Posts\ConfigurablePostResource;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
@@ -69,7 +70,7 @@ class ConfigurationPanelProvider extends PanelProvider
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
class_exists(PreventRequestForgery::class) ? PreventRequestForgery::class : VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
@@ -10,6 +10,7 @@ use Filament\Panel;
use Filament\PanelProvider;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
@@ -31,7 +32,7 @@ class CustomPanelProvider extends PanelProvider
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
class_exists(PreventRequestForgery::class) ? PreventRequestForgery::class : VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
@@ -19,6 +19,7 @@ use Filament\Tests\Fixtures\Resources\Shop\Products\ProductResource;
use Filament\Tests\Fixtures\Resources\Users\UserResource;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
@@ -54,7 +55,7 @@ class DomainTenancyPanelProvider extends PanelProvider
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
class_exists(PreventRequestForgery::class) ? PreventRequestForgery::class : VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
@@ -11,6 +11,7 @@ use Filament\Panel;
use Filament\PanelProvider;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
@@ -34,7 +35,7 @@ class EmailAuthenticationPanelProvider extends PanelProvider
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
class_exists(PreventRequestForgery::class) ? PreventRequestForgery::class : VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
@@ -17,6 +17,7 @@ use Filament\Tests\Fixtures\Resources\Shop\Products\ProductResource;
use Filament\Tests\Fixtures\Resources\Users\UserResource;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
@@ -50,7 +51,7 @@ class SingleDomainPanel extends PanelProvider
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
class_exists(PreventRequestForgery::class) ? PreventRequestForgery::class : VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
@@ -17,6 +17,7 @@ use Filament\Tests\Fixtures\Resources\Shop\Products\ProductResource;
use Filament\Tests\Fixtures\Resources\Users\UserResource;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
@@ -50,7 +51,7 @@ class MultiDomainPanel extends PanelProvider
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
class_exists(PreventRequestForgery::class) ? PreventRequestForgery::class : VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
@@ -13,6 +13,7 @@ use Filament\Panel;
use Filament\PanelProvider;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
@@ -41,7 +42,7 @@ class RequiredMultiFactorAuthenticationPanelProvider extends PanelProvider
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
class_exists(PreventRequestForgery::class) ? PreventRequestForgery::class : VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
@@ -12,6 +12,7 @@ use Filament\Panel;
use Filament\PanelProvider;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
@@ -54,7 +55,7 @@ class SlugsPanelProvider extends PanelProvider
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
class_exists(PreventRequestForgery::class) ? PreventRequestForgery::class : VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
@@ -21,6 +21,7 @@ use Filament\Tests\Fixtures\Resources\Tenancy\TenantScopedUsers\TenantScopedUser
use Filament\Tests\Fixtures\Resources\Users\UserResource;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
@@ -57,7 +58,7 @@ class TenancyPanelProvider extends PanelProvider
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
class_exists(PreventRequestForgery::class) ? PreventRequestForgery::class : VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
-2
View File
@@ -39,7 +39,6 @@ use Orchestra\Testbench\Concerns\WithWorkbench;
use Orchestra\Testbench\TestCase as BaseTestCase;
use PDO;
use PDOException;
use RyanChandler\BladeCaptureDirective\BladeCaptureDirectiveServiceProvider;
abstract class TestCase extends BaseTestCase
{
@@ -50,7 +49,6 @@ abstract class TestCase extends BaseTestCase
{
$providers = [
ActionsServiceProvider::class,
BladeCaptureDirectiveServiceProvider::class,
BladeHeroiconsServiceProvider::class,
BladeIconsServiceProvider::class,
FilamentServiceProvider::class,