-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c32ef14
commit a6e6f9b
Showing
14 changed files
with
380 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?php | ||
|
||
namespace App; | ||
|
||
use Illuminate\Filesystem\Filesystem; | ||
use Illuminate\Support\Str; | ||
|
||
trait FindsWildcardViews | ||
{ | ||
/** | ||
* Attempt to find a wildcard multi-segment view at the given directory. | ||
*/ | ||
protected function findWildcardMultiSegmentView(string $directory): ?string | ||
{ | ||
return $this->findViewWith($directory, '[...', ']'); | ||
} | ||
|
||
/** | ||
* Attempt to find a wildcard view at the given directory. | ||
*/ | ||
protected function findWildcardView(string $directory): ?string | ||
{ | ||
return $this->findViewWith($directory, '[', ']'); | ||
} | ||
|
||
/** | ||
* Attempt to find a wildcard view at the given directory with the given beginning and ending strings. | ||
*/ | ||
protected function findViewWith(string $directory, $startsWith, $endsWith): ?string | ||
{ | ||
$files = (new Filesystem)->files($directory); | ||
|
||
return collect($files)->first(function ($file) use ($startsWith, $endsWith) { | ||
$filename = Str::of($file->getFilename()); | ||
|
||
if (! $filename->endsWith('.blade.php') && ! $filename->endsWith('.php')) { | ||
return; | ||
} | ||
|
||
$filename = $filename->contains('.blade.php') | ||
? $filename->beforeLast('.blade.php') | ||
: $filename->beforeLast('.php'); | ||
|
||
return $filename->startsWith($startsWith) && | ||
$filename->endsWith($endsWith); | ||
})?->getFilename(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
namespace App; | ||
|
||
use Illuminate\Support\Facades\Facade; | ||
|
||
/** | ||
* @method static \App\FolioManager route(?string $path = null, ?string $uri = '/', array $middleware = []) | ||
*/ | ||
class Folio extends Facade | ||
{ | ||
/** | ||
* {@inheritDoc} . | ||
*/ | ||
public static function getFacadeAccessor(): string | ||
{ | ||
return FolioManager::class; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
namespace App; | ||
|
||
use Closure; | ||
use Illuminate\Http\Request; | ||
use Laravel\Folio\FolioManager as BaseFolioManager; | ||
use Laravel\Folio\MountPath; | ||
use Laravel\Folio\Pipeline\MatchedView; | ||
|
||
class FolioManager extends BaseFolioManager | ||
{ | ||
/** | ||
* Get the Folio request handler function. | ||
*/ | ||
protected function handler(MountPath $mountPath): Closure | ||
{ | ||
return function (Request $request, string $uri = '/') use ($mountPath) { | ||
return (new RequestHandler( | ||
$mountPath, | ||
$this->renderUsing, | ||
fn (MatchedView $matchedView) => $this->lastMatchedView = $matchedView, | ||
))($request, $uri); | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
|
||
namespace App; | ||
|
||
use Closure; | ||
use Laravel\Folio\Pipeline\MatchDirectoryIndexViews as BaseMatchDirectoryIndexViews; | ||
use Laravel\Folio\Pipeline\MatchedView; | ||
use Laravel\Folio\Pipeline\State; | ||
|
||
class MatchDirectoryIndexViews extends BaseMatchDirectoryIndexViews | ||
{ | ||
/** | ||
* Invoke the routing pipeline handler. | ||
*/ | ||
public function __invoke(State $state, Closure $next): mixed | ||
{ | ||
return $state->onLastUriSegment() && | ||
$state->currentUriSegmentIsDirectory() && | ||
file_exists($path = $state->currentUriSegmentDirectory().'/index.blade.php') || file_exists($path = $state->currentUriSegmentDirectory().'/index.php') | ||
? new MatchedView($path, $state->data) | ||
: $next($state); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
namespace App; | ||
|
||
use Closure; | ||
use Laravel\Folio\Pipeline\MatchedView; | ||
use Laravel\Folio\Pipeline\State; | ||
use Laravel\Folio\Pipeline\MatchLiteralViews as BaseMatchLiteralViews; | ||
|
||
class MatchLiteralViews extends BaseMatchLiteralViews | ||
{ | ||
/** | ||
* Invoke the routing pipeline handler. | ||
*/ | ||
public function __invoke(State $state, Closure $next): mixed | ||
{ | ||
return $state->onLastUriSegment() && | ||
file_exists($path = $state->currentDirectory().'/'.$state->currentUriSegment().'.blade.php') || file_exists($path = $state->currentDirectory().'/'.$state->currentUriSegment().'.php') | ||
? new MatchedView($path, $state->data) | ||
: $next($state); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
namespace App; | ||
|
||
use Closure; | ||
use Laravel\Folio\Pipeline\MatchedView; | ||
use Laravel\Folio\Pipeline\MatchRootIndex as BaseMatchRootIndex; | ||
use Laravel\Folio\Pipeline\State; | ||
use Laravel\Folio\Pipeline\StopIterating; | ||
|
||
class MatchRootIndex extends BaseMatchRootIndex | ||
{ | ||
/** | ||
* Invoke the routing pipeline handler. | ||
*/ | ||
public function __invoke(State $state, Closure $next): mixed | ||
{ | ||
if (trim($state->uri) === '/') { | ||
return file_exists($path = $state->mountPath.'/index.blade.php') || file_exists($path = $state->mountPath.'/index.php') | ||
? new MatchedView($path, $state->data) | ||
: new StopIterating; | ||
} | ||
|
||
return $next($state); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?php | ||
|
||
namespace App; | ||
|
||
use Closure; | ||
use Illuminate\Support\Str; | ||
use Laravel\Folio\Pipeline\MatchedView; | ||
use Laravel\Folio\Pipeline\MatchWildcardViews as BaseMatchWildcardViews; | ||
use Laravel\Folio\Pipeline\State; | ||
|
||
class MatchWildcardViews | ||
{ | ||
use FindsWildcardViews; | ||
|
||
/** | ||
* Invoke the routing pipeline handler. | ||
*/ | ||
public function __invoke(State $state, Closure $next): mixed | ||
{ | ||
if ($state->onLastUriSegment() && | ||
$path = $this->findWildcardView($state->currentDirectory())) { | ||
return Str::of($path)->contains('.blade.php') | ||
? $this->matchedView($state, $path, '.blade.php') | ||
: $this->matchedView($state, $path, '.php'); | ||
} | ||
|
||
return $next($state); | ||
} | ||
|
||
protected function matchedView(State $state, string $path, string $extension): MatchedView | ||
{ | ||
return new MatchedView($state->currentDirectory().'/'.$path, $state->withData( | ||
Str::of($path) | ||
->before($extension) | ||
->match('/\[(.*)\]/')->value(), | ||
$state->currentUriSegment(), | ||
)->data); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?php | ||
|
||
namespace App; | ||
|
||
use Closure; | ||
use Illuminate\Support\Str; | ||
use Laravel\Folio\Pipeline\MatchedView; | ||
use Laravel\Folio\Pipeline\MatchWildcardViewsThatCaptureMultipleSegments as BaseMatchWildcardViewsThatCaptureMultipleSegments; | ||
use Laravel\Folio\Pipeline\State; | ||
|
||
class MatchWildcardViewsThatCaptureMultipleSegments extends BaseMatchWildcardViewsThatCaptureMultipleSegments | ||
{ | ||
use FindsWildcardViews; | ||
|
||
/** | ||
* Invoke the routing pipeline handler. | ||
*/ | ||
public function __invoke(State $state, Closure $next): mixed | ||
{ | ||
if ($path = $this->findWildcardMultiSegmentView($state->currentDirectory())) { | ||
return Str::of($path)->contains('.blade.php') | ||
? $this->matchedView($state, $path, '.blade.php') | ||
: $this->matchedView($state, $path, '.php'); | ||
} | ||
|
||
return $next($state); | ||
} | ||
|
||
protected function matchedView(State $state, string $path, string $extention): MatchedView | ||
{ | ||
return new MatchedView($state->currentDirectory().'/'.$path, $state->withData( | ||
Str::of($path) | ||
->before($extention) | ||
->match('/\[\.\.\.(.*)\]/')->value(), | ||
array_slice( | ||
$state->segments, | ||
$state->currentIndex, | ||
$state->uriSegmentCount() | ||
) | ||
)->data); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
namespace App; | ||
|
||
use Illuminate\Http\Request; | ||
use Illuminate\Routing\Pipeline; | ||
use Laravel\Folio\RequestHandler as BaseRequestHandler; | ||
|
||
class RequestHandler extends BaseRequestHandler | ||
{ | ||
/** | ||
* Handle the incoming request using Folio. | ||
*/ | ||
public function __invoke(Request $request, string $uri): mixed | ||
{ | ||
$matchedView = (new Router( | ||
$this->mountPath->path | ||
))->match($request, $uri) ?? abort(404); | ||
|
||
return (new Pipeline(app())) | ||
->send($request) | ||
->through($this->middleware($matchedView)) | ||
->then(function (Request $request) use ($matchedView) { | ||
if ($this->onViewMatch) { | ||
($this->onViewMatch)($matchedView); | ||
} | ||
|
||
return $this->renderUsing | ||
? ($this->renderUsing)($request, $matchedView) | ||
: $this->toResponse($matchedView); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<?php | ||
|
||
namespace App; | ||
|
||
use Illuminate\Http\Request; | ||
use Illuminate\Pipeline\Pipeline; | ||
use Laravel\Folio\Pipeline\ContinueIterating; | ||
use Laravel\Folio\Pipeline\EnsureNoDirectoryTraversal; | ||
use Laravel\Folio\Pipeline\MatchedView; | ||
use Laravel\Folio\Pipeline\MatchLiteralDirectories; | ||
use Laravel\Folio\Pipeline\MatchWildcardDirectories; | ||
use Laravel\Folio\Pipeline\SetMountPathOnMatchedView; | ||
use Laravel\Folio\Pipeline\State; | ||
use Laravel\Folio\Pipeline\StopIterating; | ||
use Laravel\Folio\Router as BaseRouter; | ||
|
||
class Router extends BaseRouter | ||
{ | ||
/** | ||
* Resolve the given URI via page based routing at the given mount path. | ||
*/ | ||
protected function matchAtPath(string $mountPath, Request $request, string $uri): ?MatchedView | ||
{ | ||
$state = new State( | ||
uri: $uri, | ||
mountPath: $mountPath, | ||
segments: explode('/', $uri) | ||
); | ||
|
||
for ($i = 0; $i < $state->uriSegmentCount(); $i++) { | ||
$value = (new Pipeline) | ||
->send($state->forIteration($i)) | ||
->through([ | ||
new EnsureNoDirectoryTraversal, | ||
new TransformModelBindings($request), | ||
new SetMountPathOnMatchedView, | ||
// ... | ||
new MatchRootIndex, | ||
new MatchDirectoryIndexViews, | ||
new MatchWildcardViewsThatCaptureMultipleSegments, | ||
new MatchLiteralDirectories, | ||
new MatchWildcardDirectories, | ||
new MatchLiteralViews, | ||
new MatchWildcardViews, | ||
])->then(fn () => new StopIterating); | ||
|
||
if ($value instanceof MatchedView) { | ||
return $value; | ||
} elseif ($value instanceof ContinueIterating) { | ||
$state = $value->state; | ||
|
||
continue; | ||
} elseif ($value instanceof StopIterating) { | ||
break; | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
} |
Oops, something went wrong.