generated from vormkracht10/laravel-package-template
-
-
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
30e9450
commit 0848b10
Showing
9 changed files
with
269 additions
and
9 deletions.
There are no files selected for viewing
Empty file.
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,45 @@ | ||
<?php | ||
|
||
namespace Vormkracht10\TrailingSlash\Middleware; | ||
|
||
use Closure; | ||
|
||
class EnsureTrailingSlash | ||
{ | ||
public function handle($request, Closure $next) | ||
{ | ||
if (! in_array($request->getMethod(), ['GET', 'HEAD', 'OPTIONS'])) { | ||
return $next($request); | ||
} | ||
|
||
// parse our own constructed url, Laravel is known for letting the trailing slash out in some cases | ||
$url = parse_url($request->getScheme().'://'.$request->getHost().$request->server('REQUEST_URI')); | ||
|
||
$url['path'] ??= '/'; | ||
|
||
// don't mess with urls already ending on trailing slash | ||
if (str_ends_with($url['path'], '/')) { | ||
return $next($request); | ||
} | ||
|
||
// when a file is requested (but probably 404 as it came here), don't mess with trailing slash | ||
if (str_contains($url['path'], '.')) { | ||
return $next($request); | ||
} | ||
|
||
// ajax or pjax shouldn't need redirection | ||
if ($request->server('HTTP_X_REQUESTED_WITH')) { | ||
return $next($request); | ||
} | ||
|
||
return $this->redirect($url['path'].'/'); | ||
} | ||
|
||
protected function redirect(string $url) | ||
{ | ||
/* @var $redirector \Illuminate\Routing\Redirector */ | ||
$redirector = app('redirect'); | ||
|
||
return $redirector->to($url, 301); | ||
} | ||
} |
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,47 @@ | ||
<?php | ||
|
||
namespace Vormkracht10\TrailingSlash\Middleware; | ||
|
||
use Closure; | ||
|
||
class EnsureWithoutTrailingSlash | ||
{ | ||
public function handle($request, Closure $next) | ||
{ | ||
if (! in_array($request->getMethod(), ['GET', 'HEAD', 'OPTIONS'])) { | ||
return $next($request); | ||
} | ||
|
||
// parse our own constructed url, Laravel is known for letting the trailing slash out in some cases | ||
$url = parse_url($request->getScheme().'://'.$request->getHost().$request->server('REQUEST_URI')); | ||
|
||
$url['path'] ??= '/'; | ||
|
||
// don't mess with urls already ending on trailing slash | ||
if (str_ends_with($url['path'], '/')) { | ||
return $next($request); | ||
} | ||
|
||
// when a file is requested (but probably 404 as it came here), don't mess with trailing slash | ||
if (str_contains($url['path'], '.')) { | ||
return $next($request); | ||
} | ||
|
||
// ajax or pjax shouldn't need redirection | ||
if ($request->server('HTTP_X_REQUESTED_WITH')) { | ||
return $next($request); | ||
} | ||
|
||
$url['path'] = rtrim($url['path'], '/'); | ||
|
||
return $this->redirect($request->getScheme().'://'.$request->getHost().$url['path'].$url['query']); | ||
} | ||
|
||
protected function redirect(string $url) | ||
{ | ||
/* @var $redirector \Illuminate\Routing\Redirector */ | ||
$redirector = app('redirect'); | ||
|
||
return $redirector->to($url, 301); | ||
} | ||
} |
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,56 @@ | ||
<?php | ||
|
||
namespace Vormkracht10\TrailingSlash; | ||
|
||
use Illuminate\Routing\RoutingServiceProvider as BaseRoutingServiceProvider; | ||
|
||
class RoutingServiceProvider extends BaseRoutingServiceProvider | ||
{ | ||
public function register(): void | ||
{ | ||
$this->registerUrlGenerator(); | ||
} | ||
|
||
protected function registerUrlGenerator(): void | ||
{ | ||
$this->app->singleton('url', function ($app) { | ||
$routes = $app['router']->getRoutes(); | ||
|
||
// The URL generator needs the route collection that exists on the router. | ||
// Keep in mind this is an object, so we're passing by references here | ||
// and all the registered routes will be available to the generator. | ||
$app->instance('routes', $routes); | ||
|
||
$url = new UrlGenerator( | ||
$routes, | ||
$app->rebinding( | ||
'request', | ||
function ($app, $request) { | ||
$app['url']->setRequest($request); | ||
} | ||
), | ||
$app['config']['app.asset_url'] | ||
); | ||
|
||
// Next we will set a few service resolvers on the URL generator, so it can | ||
// get the information it needs to function. This just provides some of | ||
// the convenience features to this URL generator like "signed" URLs. | ||
$url->setSessionResolver(function () use ($app) { | ||
return $app['session'] ?? null; | ||
}); | ||
|
||
$url->setKeyResolver(function () use ($app) { | ||
return $app->make('config')->get('app.key'); | ||
}); | ||
|
||
// If the route collection is "rebound", for example, when the routes stay | ||
// cached for the application, we will need to rebind the routes on the | ||
// URL generator instance so it has the latest version of the routes. | ||
$app->rebinding('routes', function ($app, $routes) { | ||
$app['url']->setRoutes($routes); | ||
}); | ||
|
||
return $url; | ||
}); | ||
} | ||
} |
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,23 @@ | ||
<?php | ||
|
||
namespace Vormkracht10\TrailingSlash; | ||
|
||
use Illuminate\Routing\UrlGenerator as BaseUrlGenerator; | ||
use Illuminate\Support\Str; | ||
|
||
class UrlGenerator extends BaseUrlGenerator | ||
{ | ||
/** | ||
* Format the given URL segments into a single URL. | ||
* | ||
* @param string $root | ||
* @param string $path | ||
* @param \Illuminate\Routing\Route|null $route | ||
*/ | ||
public function format($root, $path, $route = null): string | ||
{ | ||
$trailingSlash = (Str::contains($path, '#') ? '' : '/'); | ||
|
||
return rtrim(parent::format($root, $path, $route), '/').$trailingSlash; | ||
} | ||
} |
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 |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<?php | ||
|
||
arch('it will not use debugging functions') | ||
->expect(['dd', 'dump', 'ray']) | ||
->each->not->toBeUsed(); | ||
//arch('it will not use debugging functions') | ||
// ->expect(['dd', 'dump']) | ||
// ->each->not->toBeUsed(); |
This file was deleted.
Oops, something went wrong.
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,46 @@ | ||
<?php | ||
|
||
use Illuminate\Http\Response; | ||
use Illuminate\Support\Facades\Request; | ||
use Vormkracht10\TrailingSlash\Middleware\EnsureWithoutTrailingSlash; | ||
|
||
it('can access root url', function () { | ||
Route::get('/', fn() => 'Hello World'); | ||
Route::get('route-without-trailing-slash', fn() => 'Hello World'); | ||
|
||
$this->get('/')->assertOk(); | ||
}); | ||
|
||
it('ensure url is with trailing slash', function () { | ||
$request = Request::create('/without-trailing-slash'); | ||
|
||
$next = function () { | ||
return response('This is a secret place'); | ||
}; | ||
|
||
$middleware = new \Vormkracht10\TrailingSlash\Middleware\EnsureTrailingSlash(); | ||
$response = $middleware->handle($request, $next); | ||
|
||
$this->assertEquals(Response::HTTP_MOVED_PERMANENTLY, $response->getStatusCode()); | ||
|
||
$request = Request::create('/with-trailing-slash/'); | ||
|
||
$next = function () { | ||
return response('This is a secret place'); | ||
}; | ||
|
||
$middleware = new \Vormkracht10\TrailingSlash\Middleware\EnsureTrailingSlash(); | ||
$response = $middleware->handle($request, $next); | ||
|
||
$this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); | ||
}); | ||
|
||
|
||
it('ensure url is without trailing slash', function () { | ||
Route::get('/with-trailing-slash', fn() => ''); | ||
|
||
$this->withMiddleware( | ||
EnsureWithoutTrailingSlash::class, | ||
)->get('/with-trailing-slash/') | ||
->assertMovedPermanently(); | ||
}); |