diff --git a/.travis.yml b/.travis.yml index 905480ea..abc18f1c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,10 @@ php: - 7.1 - hhvm +matrix: + allow_failures: + - hhvm + before_script: - composer self-update - composer install --no-interaction diff --git a/config/autoload/database.global.php b/config/autoload/database.global.php index 4e3b00e3..62733f22 100644 --- a/config/autoload/database.global.php +++ b/config/autoload/database.global.php @@ -5,7 +5,7 @@ return [ 'driver' => 'pdo_mysql', 'user' => getenv('DB_USER'), 'password' => getenv('DB_PASSWORD'), - 'dbname' => getenv('DB_NAME') ?: 'acelaya_url_shortener', + 'dbname' => getenv('DB_NAME') ?: 'shlink', 'charset' => 'utf8', 'driverOptions' => [ PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8' diff --git a/config/autoload/errorhandler.local.php.dist b/config/autoload/errorhandler.local.php.dist index 92a92497..d6de56d7 100644 --- a/config/autoload/errorhandler.local.php.dist +++ b/config/autoload/errorhandler.local.php.dist @@ -1,14 +1,14 @@ [ 'invokables' => [ 'Zend\Expressive\Whoops' => Whoops\Run::class, 'Zend\Expressive\WhoopsPageHandler' => Whoops\Handler\PrettyPageHandler::class, ], - 'factories' => [ - 'Zend\Expressive\FinalHandler' => Zend\Expressive\Container\WhoopsErrorHandlerFactory::class, - ], ], 'whoops' => [ @@ -18,4 +18,12 @@ return [ 'ajax_only' => true, ], ], + + 'error_handler' => [ + 'plugins' => [ + 'factories' => [ + ContentBasedErrorHandler::DEFAULT_CONTENT => WhoopsErrorHandlerFactory::class, + ], + ], + ], ]; diff --git a/config/autoload/services.global.php b/config/autoload/services.global.php index dc99033c..d7f56ed6 100644 --- a/config/autoload/services.global.php +++ b/config/autoload/services.global.php @@ -1,4 +1,6 @@ InvokableFactory::class, // View - 'Zend\Expressive\FinalHandler' => Container\TemplatedErrorHandlerFactory::class, + 'Zend\Expressive\FinalHandler' => ContentBasedErrorHandlerFactory::class, Template\TemplateRendererInterface::class => Twig\TwigRendererFactory::class, ], 'aliases' => [ diff --git a/module/Common/config/error-handler.config.php b/module/Common/config/error-handler.config.php new file mode 100644 index 00000000..a6165fa2 --- /dev/null +++ b/module/Common/config/error-handler.config.php @@ -0,0 +1,22 @@ + [ + 'plugins' => [ + 'invokables' => [ + 'text/plain' => FinalHandler::class, + ], + 'factories' => [ + ContentBasedErrorHandler::DEFAULT_CONTENT => TemplatedErrorHandlerFactory::class, + ], + 'aliases' => [ + 'application/xhtml+xml' => ContentBasedErrorHandler::DEFAULT_CONTENT, + ], + ], + ], + +]; diff --git a/module/Common/src/Expressive/ContentBasedErrorHandler.php b/module/Common/src/Expressive/ContentBasedErrorHandler.php new file mode 100644 index 00000000..f0d4bc04 --- /dev/null +++ b/module/Common/src/Expressive/ContentBasedErrorHandler.php @@ -0,0 +1,64 @@ +resolveErrorHandlerFromAcceptHeader($request); + return $errorHandler($request, $response, $err); + } + + /** + * Tries to resolve + * + * @param Request $request + * @return callable + */ + protected function resolveErrorHandlerFromAcceptHeader(Request $request) + { + $accepts = $request->hasHeader('Accept') ? $request->getHeaderLine('Accept') : self::DEFAULT_CONTENT; + $accepts = explode(',', $accepts); + foreach ($accepts as $accept) { + if (! $this->has($accept)) { + continue; + } + + return $this->get($accept); + } + + throw new InvalidArgumentException(sprintf( + 'It wasn\'t possible to find an error handler for ' + )); + } +} diff --git a/module/Common/src/Expressive/ContentBasedErrorHandlerFactory.php b/module/Common/src/Expressive/ContentBasedErrorHandlerFactory.php new file mode 100644 index 00000000..f262d320 --- /dev/null +++ b/module/Common/src/Expressive/ContentBasedErrorHandlerFactory.php @@ -0,0 +1,30 @@ +get('config')['error_handler']; + $plugins = isset($config['plugins']) ? $config['plugins'] : []; + return new ContentBasedErrorHandler($container, $plugins); + } +} diff --git a/module/Common/src/Expressive/ErrorHandlerInterface.php b/module/Common/src/Expressive/ErrorHandlerInterface.php new file mode 100644 index 00000000..0c787a09 --- /dev/null +++ b/module/Common/src/Expressive/ErrorHandlerInterface.php @@ -0,0 +1,18 @@ + [ + 'plugins' => [ + 'invokables' => [ + 'application/json' => JsonErrorHandler::class, + ], + 'aliases' => [ + 'application/x-json' => 'application/json', + 'text/json' => 'application/json', + ], + ], + ], + +]; diff --git a/module/Rest/lang/es.mo b/module/Rest/lang/es.mo index 2a8d4431..1bfa9aef 100644 Binary files a/module/Rest/lang/es.mo and b/module/Rest/lang/es.mo differ diff --git a/module/Rest/lang/es.po b/module/Rest/lang/es.po index fdfb2ed5..62f76e1d 100644 --- a/module/Rest/lang/es.po +++ b/module/Rest/lang/es.po @@ -1,9 +1,9 @@ msgid "" msgstr "" "Project-Id-Version: Shlink 1.0\n" -"POT-Creation-Date: 2016-07-21 16:39+0200\n" -"PO-Revision-Date: 2016-07-21 16:40+0200\n" -"Last-Translator: \n" +"POT-Creation-Date: 2016-07-27 08:53+0200\n" +"PO-Revision-Date: 2016-07-27 08:53+0200\n" +"Last-Translator: Alejandro Celaya \n" "Language-Team: \n" "Language: es_ES\n" "MIME-Version: 1.0\n" @@ -52,9 +52,12 @@ msgid "" "Missing or invalid auth token provided. Perform a new authentication request " "and send provided token on every new request on the \"%s\" header" msgstr "" -"No se ha proporcionado token de autenticación o este es inválido. Realia una " -"nueva petición de autenticación y envía el token proporcionado en cada nueva " -"petición en la cabecera \"%s\"" +"No se ha proporcionado token de autenticación o este es inválido. Realiza " +"una nueva petición de autenticación y envía el token proporcionado en cada " +"nueva petición en la cabecera \"%s\"" + +msgid "Requested route does not exist." +msgstr "La ruta solicitada no existe." #~ msgid "RestToken not found for token \"%s\"" #~ msgstr "No se ha encontrado un RestToken para el token \"%s\"" diff --git a/module/Rest/src/Expressive/JsonErrorHandler.php b/module/Rest/src/Expressive/JsonErrorHandler.php new file mode 100644 index 00000000..0d02c45b --- /dev/null +++ b/module/Rest/src/Expressive/JsonErrorHandler.php @@ -0,0 +1,39 @@ +getStatusCode(); + $responsePhrase = $status < 400 ? 'Internal Server Error' : $response->getReasonPhrase(); + $status = $status < 400 ? 500 : $status; + + return new JsonResponse([ + 'error' => $this->responsePhraseToCode($responsePhrase), + 'message' => $responsePhrase, + ], $status); + } + + /** + * @param string $responsePhrase + * @return string + */ + protected function responsePhraseToCode($responsePhrase) + { + return strtoupper(str_replace(' ', '_', $responsePhrase)); + } +}