Skip to content

Commit

Permalink
add fallback resource
Browse files Browse the repository at this point in the history
  • Loading branch information
zareismail committed Jul 28, 2023
1 parent 2ad0560 commit 2176550
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 9 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- [Grouping Resources](#grouping-resources)
- [Bounded Resources](#bounded-resources)
- [Wildcard Resources](#wildcard-resources)
- [Fallback Resource](#fallback-resource)
- [Resolving Resources](#resolving-resources)
### [Widgets](#widgets)
- [Defining Widgets](#defining-widgets)
Expand Down Expand Up @@ -93,6 +94,22 @@ public static function wildcard(): bool
When `wildcard` returns `true`, Flexi dispatches all paths prefixed by the resource's `uriKey`. As a result, you can access the ungrouped wildcard `Post` resource using the `http://localhost/posts/ANYTHING` URL, where `ANYTHING` can be any string combined with the URL path separator.
### Wildcard Resources
Laravel's fallback routes allow you to handle undefined routes or 404 errors gracefully by redirecting them to a specific route or controller action. With the new feature added to the "Flexi" package, you can now specify a fallback resource, which is a Flexi resource, to handle these fallback routes within your Laravel application.
If you want to determine a resource as fallback, override the `fallback` method of the resource:
```bash
/**
* Determine if the resource is a fallback resource.
*/
public static function fallback(): bool
{
return true;
}
```
This feature is handy when you want to customize the behavior of the fallback routes and provide a user-friendly experience when users encounter undefined routes or pages. pay attention that a `wildcard` `ungrouped` `unbounded` resource, also can work like a `fallback` resource.
### Resolving Resources
Each resource generated by the Flexi command contains a `resolve` method that allows you to customize data retrieval and attach it to the resource after it is resolved by the request. For example, if you need to retrieve a model from the database for the requested resource, you can do so using the following approach:
Expand Down
6 changes: 3 additions & 3 deletions src/Collections/ResourceCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ public function find(string $key, mixed $default = null): ?string
}

/**
* Find first wildcard resource in the collection.
* Find first fallback resource in the collection.
*/
public function wildcard(): ?string
public function fallback(): ?string
{
return $this->first(fn ($resource) => $resource::wildcard());
return $this->first(fn ($resource) => $resource::fallback());
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/Flexi.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,11 @@ public static function resourceForKey(string $key): ?string
}

/**
* Get the wildcard resource class name.
* Get the fallback resource class name.
*/
public static function wildcardResource(): ?string
public static function fallbackResource(): ?string
{
return static::resourceCollection()->wildcard();
return static::resourceCollection()->fallback();
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Http/Requests/InteractsWithResources.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function newResource()
*/
public function resource()
{
return tap($this->matchedResource() ?? Flexi::wildcardResource(), function ($resource) {
return tap($this->matchedResource() ?? Flexi::fallbackResource(), function ($resource) {
abort_if(is_null($resource), 404);
});
}
Expand Down
5 changes: 5 additions & 0 deletions src/PendingRouteRegistration.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public function mapWebRoutes(): void
->each(function ($resources, $group) {
Route::prefix($group)->group(function ($router) use ($resources) {
collect($resources)
->reject(fn ($resource) => $resource === Flexi::fallbackResource())
->sortBy(fn ($resource) => intval($resource::wildcard()) - intval($resource::bounded()))
->each(function ($resource) use ($router) {
$path = '/';
Expand All @@ -82,6 +83,10 @@ public function mapWebRoutes(): void
});
});
});
// handle fallbacks
if ($fallbackResource = Flexi::fallbackResource()) {
Route::fallback([ResourceController::class, 'handle'])->name($fallbackResource::uriKey());
}
}

/**
Expand Down
8 changes: 8 additions & 0 deletions src/Resource.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ public static function bounded(): bool
return true;
}

/**
* Determine if the resource is a fallback resource.
*/
public static function fallback(): bool
{
return false;
}

/**
* Get the resource name.
*/
Expand Down
15 changes: 13 additions & 2 deletions tests/Feature/APITest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
use Flexi\Events\ResourceMatched;
use Flexi\Events\WidgetRendered;
use Flexi\Flexi;
use Flexi\Tests\Fixtures\Fallback;
use Flexi\Tests\Fixtures\Grouped;
use Flexi\Tests\Fixtures\GroupedWildcard;
use Flexi\Tests\Fixtures\GroupedUnbounded;
use Flexi\Tests\Fixtures\GroupedUnboundedWildcard;
use Flexi\Tests\Fixtures\GroupedWildcard;
use Flexi\Tests\Fixtures\Ungrouped;
use Flexi\Tests\Fixtures\UngroupedWildcard;
use Flexi\Tests\Fixtures\UngroupedUnbounded;
use Flexi\Tests\Fixtures\UngroupedUnboundedWildcard;
use Flexi\Tests\Fixtures\UngroupedWildcard;
use Flexi\Tests\Fixtures\Widgetized;
use Flexi\Tests\Fixtures\Widgets\TestWidget;
use Illuminate\Support\Facades\Event;
Expand Down Expand Up @@ -101,3 +102,13 @@
Event::assertDispatched(ResourceMatched::class, fn ($event) => $event->resource->uriKey() === Widgetized::uriKey());
Event::assertDispatched(WidgetRendered::class, fn ($event) => $event->widget instanceof TestWidget);
});

// test fallback resource
it('find fallback resource', function () {
Event::fake();

Flexi::replaceResources([Fallback::class]);

$this->get(time())->assertStatus(200);
Event::assertDispatched(ResourceMatched::class, fn ($event) => $event->resource->uriKey() === Fallback::uriKey());
});
25 changes: 25 additions & 0 deletions tests/Fixtures/Fallback.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Flexi\Tests\Fixtures;

use Flexi\Http\Requests\FlexiRequest;
use Flexi\Resource;

class Fallback extends Resource
{
/**
* Determine if the resource is a fallback resource.
*/
public static function fallback(): bool
{
return true;
}

/**
* Resolve the resource for incoming request.
*/
public function resolve(FlexiRequest $request)
{

}
}

0 comments on commit 2176550

Please sign in to comment.