Implemented routable redirect middleware

This commit is contained in:
Alejandro Celaya 2016-04-30 18:59:03 +02:00
parent 577ad146a4
commit b2615d0de6
8 changed files with 92 additions and 50 deletions

View File

@ -14,10 +14,10 @@
"php": "^5.5 || ^7.0",
"zendframework/zend-expressive": "^1.0",
"zendframework/zend-expressive-helpers": "^2.0",
"zendframework/zend-stdlib": "^2.7",
"zendframework/zend-expressive-aurarouter": "^1.0",
"zendframework/zend-servicemanager": "^3.0",
"zendframework/zend-expressive-fastroute": "^1.1",
"zendframework/zend-expressive-twigrenderer": "^1.0",
"zendframework/zend-stdlib": "^2.7",
"zendframework/zend-servicemanager": "^3.0",
"doctrine/orm": "^2.5",
"guzzlehttp/guzzle": "^6.2",
"acelaya/zsm-annotated-services": "^0.2.0"

View File

@ -1,14 +1,15 @@
<?php
use Acelaya\UrlShortener\Middleware\Routable;
return [
'routes' => [
// [
// 'name' => 'home',
// 'path' => '/',
// 'middleware' => '',
// 'allowed_methods' => ['GET'],
// ],
[
'name' => 'long-url-redirect',
'path' => '/{shortCode}',
'middleware' => Routable\RedirectMiddleware::class,
'allowed_methods' => ['GET'],
],
],
];

View File

@ -25,7 +25,7 @@ return [
Helper\ServerUrlMiddleware::class => Helper\ServerUrlMiddlewareFactory::class,
Helper\UrlHelperMiddleware::class => Helper\UrlHelperMiddlewareFactory::class,
Helper\ServerUrlHelper::class => InvokableFactory::class,
Router\AuraRouter::class => InvokableFactory::class,
Router\FastRouteRouter::class => InvokableFactory::class,
// View
'Zend\Expressive\FinalHandler' => Container\TemplatedErrorHandlerFactory::class,
@ -39,12 +39,13 @@ return [
// Middleware
Middleware\CliRoutable\GenerateShortcodeMiddleware::class => AnnotatedFactory::class,
Middleware\Routable\RedirectMiddleware::class => AnnotatedFactory::class,
Middleware\CliParamsMiddleware::class => Middleware\Factory\CliParamsMiddlewareFactory::class,
],
'aliases' => [
'em' => EntityManager::class,
'httpClient' => GuzzleHttp\Client::class,
Router\RouterInterface::class => Router\AuraRouter::class,
Router\RouterInterface::class => Router\FastRouteRouter::class,
]
],

View File

@ -46,7 +46,7 @@ class CliParamsMiddleware implements MiddlewareInterface
public function __invoke(Request $request, Response $response, callable $out = null)
{
// When not in CLI, just call next middleware
if (! php_sapi_name() === 'cli') {
if (php_sapi_name() !== 'cli') {
return $out($request, $response);
}

View File

@ -24,6 +24,6 @@ class CliParamsMiddlewareFactory implements FactoryInterface
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new CliParamsMiddleware($_SERVER['argv']);
return new CliParamsMiddleware(isset($_SERVER['argv']) ? $_SERVER['argv'] : []);
}
}

View File

@ -0,0 +1,75 @@
<?php
namespace Acelaya\UrlShortener\Middleware\Routable;
use Acelaya\UrlShortener\Service\UrlShortener;
use Acelaya\UrlShortener\Service\UrlShortenerInterface;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Zend\Diactoros\Response\RedirectResponse;
use Zend\Stratigility\MiddlewareInterface;
class RedirectMiddleware implements MiddlewareInterface
{
/**
* @var UrlShortenerInterface
*/
private $urlShortener;
/**
* RedirectMiddleware constructor.
* @param UrlShortenerInterface|UrlShortener $urlShortener
*
* @Inject({UrlShortener::class})
*/
public function __construct(UrlShortenerInterface $urlShortener)
{
$this->urlShortener = $urlShortener;
}
/**
* Process an incoming request and/or response.
*
* Accepts a server-side request and a response instance, and does
* something with them.
*
* If the response is not complete and/or further processing would not
* interfere with the work done in the middleware, or if the middleware
* wants to delegate to another process, it can use the `$out` callable
* if present.
*
* If the middleware does not return a value, execution of the current
* request is considered complete, and the response instance provided will
* be considered the response to return.
*
* Alternately, the middleware may return a response instance.
*
* Often, middleware will `return $out();`, with the assumption that a
* later middleware will return a response.
*
* @param Request $request
* @param Response $response
* @param null|callable $out
* @return null|Response
*/
public function __invoke(Request $request, Response $response, callable $out = null)
{
$shortCode = $request->getAttribute('shortCode', '');
try {
$longUrl = $this->urlShortener->shortCodeToUrl($shortCode);
// If provided shortCode does not belong to a valid long URL, dispatch next middleware, which is 404
// middleware
if (! isset($longUrl)) {
return $out($request, $response);
}
// Return a redirect response to the long URL
return new RedirectResponse($longUrl, 301);
} catch (\Exception $e) {
// In case of error, dispatch 404 error
return $out($request, $response);
}
}
}

View File

@ -7,7 +7,6 @@
<h2>This is awkward.</h2>
<p>We encountered a 404 Not Found error.</p>
<p>
You are looking for something that doesn't exist or may have moved. Check out one of the links on this page
or head back to <a href="{{ path('home') }}">Home</a>.
You are looking for something that doesn't exist or may have moved.
</p>
{% endblock %}

View File

@ -17,40 +17,6 @@
{% block stylesheets %}{% endblock %}
</head>
<body class="app">
<header class="app-header">
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{{ path('home') }}">
<img src="{{ asset('zf-logo.png') }}" alt="Zend Expressive" />
</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li>
<a href="https://zendframework.github.io/zend-expressive/" target="_blank">
<i class="fa fa-book"></i> Docs
</a>
</li>
<li>
<a href="https://github.com/zendframework/zend-expressive" target="_blank">
<i class="fa fa-wrench"></i> Contribute
</a>
</li>
<li>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="app-content">
<main class="container">
{% block content %}{% endblock %}
@ -62,7 +28,7 @@
<hr />
{% block footer %}
<p>
&copy; 2005 - {{ "now"|date("Y") }} by Zend Technologies Ltd. All rights reserved.
&copy; {{ "now" | date("Y") }} by Alejandro Celaya.
</p>
{% endblock %}
</div>