Created
August 28, 2017 10:05
-
-
Save OJezu/0d8f6db59aa77dcd44589b5f306c82a2 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
<?php | |
namespace OJezu\FormatResponseBundle\Annotation\Controller; | |
/** | |
* @Annotation | |
*/ | |
class FormatResponse | |
{ | |
} |
This file contains hidden or 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
<?php | |
namespace OJezu\FormatResponseBundle\Listener; | |
use Doctrine\Common\Annotations\Reader; | |
use OJezu\FormatResponseBundle\Annotation\Controller\FormatResponse; | |
use OJezu\Common\Exception\BaseException; | |
use Symfony\Component\HttpFoundation\RedirectResponse; | |
use Symfony\Component\HttpFoundation\Response; | |
use Symfony\Component\HttpKernel\Controller\ControllerResolver; | |
use Symfony\Component\HttpKernel\Event\FilterResponseEvent; | |
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; | |
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; | |
use Symfony\Component\HttpKernel\Event\KernelEvent; | |
use Symfony\Component\HttpKernel\Exception\HttpException; | |
class FormatResponseAnnotationListener | |
{ | |
/** | |
* @var Reader | |
*/ | |
private $reader; | |
/** | |
* @var ControllerResolver | |
*/ | |
private $controllerResolver; | |
/** | |
* @param Reader $reader | |
* @param ControllerResolver $controllerResolver | |
*/ | |
public function __construct(Reader $reader, ControllerResolver $controllerResolver) | |
{ | |
$this->reader = $reader; | |
$this->controllerResolver = $controllerResolver; | |
} | |
/** | |
* @param GetResponseForExceptionEvent $responseEvent | |
*/ | |
public function onResponseExceptionEvent(GetResponseForExceptionEvent $responseEvent) | |
{ | |
$exception = $responseEvent->getException(); | |
if ($this->isActionAnnotated($responseEvent)) { | |
if ($exception instanceof BaseException) { | |
// this response will pass through onResponseEvent too | |
$responseEvent->setResponse($exception->response()); | |
} elseif ($exception instanceof HttpException) { | |
$responseEvent->setResponse(new Response(json_encode([ | |
'code' => $exception->getStatusCode(), | |
'error' => [ | |
'messageId' => 'http-status.'.$exception->getStatusCode(), | |
'message' => $exception->getMessage(), | |
'data' => [], | |
], | |
]), 200, ['X-Status-Code' => 200])); | |
} | |
} | |
} | |
/** | |
* @param GetResponseForControllerResultEvent $responseEvent | |
*/ | |
public function onControllerResultEvent(GetResponseForControllerResultEvent $responseEvent) | |
{ | |
if($this->isActionAnnotated($responseEvent)) { | |
$responseEvent->setControllerResult([ | |
'code' => 200, | |
'response' => $responseEvent->getControllerResult(), | |
]); | |
} | |
} | |
/** | |
* @param FilterResponseEvent $responseEvent | |
*/ | |
public function onResponseEvent(FilterResponseEvent $responseEvent) | |
{ | |
if($this->isActionAnnotated($responseEvent)) { | |
$response = $responseEvent->getResponse(); | |
if ($response instanceof RedirectResponse) { | |
$responseEvent->setResponse(new Response(json_encode([ | |
'code' => $response->getStatusCode(), | |
'redirect' => [ | |
'url' => $response->getTargetUrl(), | |
], | |
]), 200)); | |
} | |
} | |
} | |
/** | |
* @param KernelEvent $responseEvent | |
* | |
* @return bool | |
*/ | |
private function isActionAnnotated(KernelEvent $responseEvent) : bool | |
{ | |
$hasAnnotation = false; | |
$callableController = $this->controllerResolver->getController($responseEvent->getRequest()); | |
if ($callableController) { | |
$classReflection = new \ReflectionClass($callableController[0]); | |
$hasAnnotation = (bool)$this->reader->getClassAnnotation($classReflection, FormatResponse::class); | |
if (!$hasAnnotation) { | |
$methodReflection = $classReflection->getMethod($callableController[1]); | |
$hasAnnotation = (bool)$this->reader->getMethodAnnotation($methodReflection, FormatResponse::class); | |
} | |
} | |
return $hasAnnotation; | |
} | |
} |
This file contains hidden or 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
ojezu.format_response.listener.format_response: | |
class: 'OJezu\FormatResponseBundle\Listener\FormatResponseAnnotationListener' | |
arguments: | |
- '@annotation_reader' | |
- '@controller_resolver' | |
tags: | |
- name: 'kernel.event_listener' | |
event: 'kernel.view' | |
method: 'onControllerResultEvent' | |
priority: 110 | |
- name: 'kernel.event_listener' | |
event: 'kernel.response' | |
method: 'onResponseEvent' | |
priority: 100 | |
- name: 'kernel.event_listener' | |
event: 'kernel.exception' | |
method: 'onResponseExceptionEvent' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment