From 8e1947c70723bc6060084a863758175593612c31 Mon Sep 17 00:00:00 2001 From: Andrii Sobol Date: Sun, 18 Feb 2024 22:12:06 +0200 Subject: [PATCH 1/7] This commit adds support for PHP >=7.4 and support for Symfony 5.X. --- .github/workflows/ci.yaml | 48 ++++++++++++ .github/workflows/code_quality.yml | 25 ------- CHANGELOG.md | 5 ++ Exception/FatalErrorException.php | 75 +++++++++++++++++++ Exception/FatalThrowableError.php | 41 ++++++++++ Listener/RestListener.php | 34 +++++---- RestApi.php | 3 + Security/RoleAndIpStrategy.php | 7 +- Tests/Listener/RestListenerLocaleTest.php | 12 +-- .../RestListenerPathConverterTest.php | 14 ++-- Tests/Listener/RestListenerTest.php | 57 +++++++------- composer.json | 26 +++++-- 12 files changed, 255 insertions(+), 92 deletions(-) create mode 100644 .github/workflows/ci.yaml delete mode 100644 .github/workflows/code_quality.yml create mode 100644 Exception/FatalErrorException.php create mode 100644 Exception/FatalThrowableError.php diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..4f3b8ac --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,48 @@ +name: Tests + +on: + push: + branches: + - master + pull_request: + branches: + - master + - symfony-5-support + +permissions: + contents: read + +jobs: + tests: + runs-on: ${{ matrix.operating-system }} + + strategy: + matrix: + operating-system: + - 'ubuntu-latest' + php: + - '7.4' + - '8.0' + - '8.1' + - '8.2' + dependency: + - 'highest' + + name: PHP ${{ matrix.php }} with ${{ matrix.dependency }} dependencies tests on ${{ matrix.operating-system }} + + steps: + - name: Setup PHP version ${{ matrix.php }} on ${{ matrix.operating-system }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install dependencies + uses: ramsey/composer-install@v2 + with: + dependency-versions: ${{ matrix.dependency }} + + - name: Run all tests + run: composer test diff --git a/.github/workflows/code_quality.yml b/.github/workflows/code_quality.yml deleted file mode 100644 index 5402ce0..0000000 --- a/.github/workflows/code_quality.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Qodana -on: - workflow_dispatch: - pull_request: - push: - branches: - - master - - 'releases/*' - -jobs: - qodana: - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - checks: write - steps: - - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit - fetch-depth: 0 # a full history is required for pull request analysis - - name: 'Qodana Scan' - uses: JetBrains/qodana-action@v2023.2 - env: - QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index ee4d6a1..121cce3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## 5.1.1 +### Added +- Support for PHP >=7.4 +- Support for Symfony 5.X + ## 5.1.0 ### Added - Dockerfiles diff --git a/Exception/FatalErrorException.php b/Exception/FatalErrorException.php new file mode 100644 index 0000000..08daf85 --- /dev/null +++ b/Exception/FatalErrorException.php @@ -0,0 +1,75 @@ +setTrace($trace); + } elseif (null !== $traceOffset) { + if (function_exists('xdebug_get_function_stack') && $trace = @xdebug_get_function_stack()) { + if (0 < $traceOffset) { + array_splice($trace, -$traceOffset); + } + + foreach ($trace as &$frame) { + if (!isset($frame['type'])) { + // XDebug pre 2.1.1 doesn't currently set the call type key http://bugs.xdebug.org/view.php?id=695 + if (isset($frame['class'])) { + $frame['type'] = '::'; + } + } elseif ('dynamic' === $frame['type']) { + $frame['type'] = '->'; + } elseif ('static' === $frame['type']) { + $frame['type'] = '::'; + } + + // XDebug also has a different name for the parameters array + if (!$traceArgs) { + unset($frame['params'], $frame['args']); + } elseif (isset($frame['params']) && !isset($frame['args'])) { + $frame['args'] = $frame['params']; + unset($frame['params']); + } + } + + unset($frame); + $trace = array_reverse($trace); + } else { + $trace = []; + } + + $this->setTrace($trace); + } + } + + protected function setTrace($trace) + { + $traceReflector = new ReflectionProperty(\Exception::class, 'trace'); + $traceReflector->setAccessible(true); + $traceReflector->setValue($this, $trace); + } +} diff --git a/Exception/FatalThrowableError.php b/Exception/FatalThrowableError.php new file mode 100644 index 0000000..82d0ac3 --- /dev/null +++ b/Exception/FatalThrowableError.php @@ -0,0 +1,41 @@ +originalClassName = get_class($e); + + if ($e instanceof ParseError) { + $severity = E_PARSE; + } elseif ($e instanceof \TypeError) { + $severity = E_RECOVERABLE_ERROR; + } else { + $severity = E_ERROR; + } + + ErrorException::__construct( + $e->getMessage(), + $e->getCode(), + $severity, + $e->getFile(), + $e->getLine(), + $e->getPrevious() + ); + + $this->setTrace($e->getTrace()); + } + + public function getOriginalClassName(): string + { + return $this->originalClassName; + } +} diff --git a/Listener/RestListener.php b/Listener/RestListener.php index d8b574b..f9be076 100644 --- a/Listener/RestListener.php +++ b/Listener/RestListener.php @@ -4,6 +4,7 @@ use Exception; use Paysera\Bundle\RestBundle\Cache\ResponseAwareCacheStrategy; +use Paysera\Bundle\RestBundle\Exception\FatalThrowableError; use Paysera\Bundle\RestBundle\Service\ExceptionLogger; use Paysera\Bundle\RestBundle\Service\ParameterToEntityMapBuilder; use Paysera\Bundle\RestBundle\Service\RequestApiResolver; @@ -17,11 +18,11 @@ use Paysera\Component\Serializer\Exception\EncodingException; use Paysera\Bundle\RestBundle\ApiManager; use Paysera\Bundle\RestBundle\Service\RequestLogger; -use Symfony\Component\HttpKernel\Event\FilterControllerEvent; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; -use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; +use Symfony\Component\HttpKernel\Event\KernelEvent; +use Symfony\Component\HttpKernel\Event\RequestEvent; +use Symfony\Component\HttpKernel\Event\ViewEvent; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; +use Symfony\Component\HttpKernel\Event\ExceptionEvent; use Psr\Log\LoggerInterface; class RestListener @@ -64,7 +65,7 @@ public function __construct( $this->loggersCache = array(); } - public function onKernelRequest(GetResponseEvent $event) + public function onKernelRequest(RequestEvent $event) { $request = $event->getRequest(); @@ -92,13 +93,13 @@ public function onKernelRequest(GetResponseEvent $event) /** * Ran on kernel.controller event * - * @param FilterControllerEvent $event + * @param KernelEvent $event * * @throws ApiException * @throws InvalidDataException * @throws Exception */ - public function onKernelController(FilterControllerEvent $event) + public function onKernelController(KernelEvent $event) { /** @var $request Request */ $request = $event->getRequest(); @@ -131,9 +132,9 @@ public function onKernelController(FilterControllerEvent $event) /** * Ran on kernel.view event * - * @param GetResponseForControllerResultEvent $event + * @param ViewEvent $event */ - public function onKernelView(GetResponseForControllerResultEvent $event) + public function onKernelView(ViewEvent $event) { /** @var $request Request */ $request = $event->getRequest(); @@ -228,6 +229,10 @@ public function onKernelView(GetResponseForControllerResultEvent $event) $response->setContent($responseContent); + if ($responseContent === null) { + $responseContent = ''; + } + $response->setEtag($etag === null ? hash('sha256', $responseContent) : $etag); $response->headers->set('X-Frame-Options', 'DENY'); @@ -237,22 +242,23 @@ public function onKernelView(GetResponseForControllerResultEvent $event) /** * Ran on kernel.exception event * - * @param GetResponseForExceptionEvent $event + * @param ExceptionEvent $event */ - public function onKernelException(GetResponseForExceptionEvent $event) + public function onKernelException(ExceptionEvent $event) { /** @var $request Request */ $request = $event->getRequest(); $logger = $this->getLogger($request); + $exception = new FatalThrowableError($event->getThrowable()); + $logger->debug('Handling kernel.exception', array($event)); - $logger->debug($event->getException()); + $logger->debug($exception); - $response = $this->apiManager->getResponseForException($request, $event->getException()); + $response = $this->apiManager->getResponseForException($request, $exception); if ($response !== null) { $event->setResponse($response); $logger->debug('Setting error response', array($response->getContent())); - $exception = $event->getException(); $this->exceptionLogger->log($logger, $response, $exception); } diff --git a/RestApi.php b/RestApi.php index 602b8df..f2d2c7a 100644 --- a/RestApi.php +++ b/RestApi.php @@ -640,6 +640,9 @@ public function getLogger() */ protected function normalizeControllerKey($controllerKey) { + if ($controllerKey === null) { + return null; + } $i = strpos($controllerKey, '\\Controller\\'); if ($i !== false) { $controllerKey = substr($controllerKey, $i + 12); diff --git a/Security/RoleAndIpStrategy.php b/Security/RoleAndIpStrategy.php index a46ede6..cd3f3bf 100644 --- a/Security/RoleAndIpStrategy.php +++ b/Security/RoleAndIpStrategy.php @@ -52,9 +52,10 @@ public function isAllowed(Request $request) return false; } - $availableRoles = array_map(function (Role $role) { - return $role->getRole(); - }, $this->roleHierarchy->getReachableRoles($token->getRoles())); + $availableRoles = array_map( + fn(string $role) => $role, + $this->roleHierarchy->getReachableRoleNames($token->getRoleNames()) + ); $availableRoles = array_unique($availableRoles); diff --git a/Tests/Listener/RestListenerLocaleTest.php b/Tests/Listener/RestListenerLocaleTest.php index 22f1ffb..d6de7fb 100644 --- a/Tests/Listener/RestListenerLocaleTest.php +++ b/Tests/Listener/RestListenerLocaleTest.php @@ -13,20 +13,20 @@ use Paysera\Bundle\RestBundle\Service\RequestLogger; use Paysera\Bundle\RestBundle\Listener\RestListener; use Paysera\Bundle\RestBundle\Service\ExceptionLogger; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Event\RequestEvent; use Paysera\Bundle\RestBundle\Service\ParameterToEntityMapBuilder; use Paysera\Component\Serializer\Factory\ContextAwareNormalizerFactory; class RestListenerLocaleTest extends TestCase { /** - * @var MockInterface|GetResponseEvent + * @var MockInterface|RequestEvent */ - private $responseEvent; + private $requestEvent; public function setUp(): void { - $this->responseEvent = Mockery::mock(GetResponseEvent::class); + $this->requestEvent = Mockery::mock(RequestEvent::class); } /** @@ -46,9 +46,9 @@ public function testCorrectLocaleIsBeingSet(array $acceptedLocales, $expected, $ $request->headers->set('Accept-Language', $acceptLanguage); } - $this->responseEvent->shouldReceive('getRequest')->andReturn($request); + $this->requestEvent->shouldReceive('getRequest')->andReturn($request); - $restListener->onKernelRequest($this->responseEvent); + $restListener->onKernelRequest($this->requestEvent); $this->assertEquals($expected, $request->getLocale()); } diff --git a/Tests/Listener/RestListenerPathConverterTest.php b/Tests/Listener/RestListenerPathConverterTest.php index 13c5d63..a32363c 100644 --- a/Tests/Listener/RestListenerPathConverterTest.php +++ b/Tests/Listener/RestListenerPathConverterTest.php @@ -28,7 +28,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Event\FilterControllerEvent; +use Symfony\Component\HttpKernel\Event\KernelEvent; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; use Symfony\Component\Validator\Validator\ValidatorInterface; @@ -36,13 +36,13 @@ class RestListenerPathConverterTest extends TestCase { /** - * @var MockInterface|FilterControllerEvent + * @var MockInterface|KernelEvent */ - private $filterControllerEvent; + private $kernelEvent; public function setUp(): void { - $this->filterControllerEvent = Mockery::mock(FilterControllerEvent::class); + $this->kernelEvent = Mockery::mock(KernelEvent::class); } public function testOnKernelControllerWithRequestQueryMapperValidationThrowsExceptionWithCamelCasePathConverter() @@ -51,7 +51,7 @@ public function testOnKernelControllerWithRequestQueryMapperValidationThrowsExce try { $this ->createRestListener(new CamelCaseToSnakeCaseConverter()) - ->onKernelController($this->filterControllerEvent) + ->onKernelController($this->kernelEvent) ; } catch (ApiException $apiException) { $exceptionThrown = true; @@ -79,7 +79,7 @@ public function testOnKernelControllerWithRequestQueryMapperValidationThrowsExce { $exceptionThrown = false; try { - $this->createRestListener(new NoOpConverter())->onKernelController($this->filterControllerEvent); + $this->createRestListener(new NoOpConverter())->onKernelController($this->kernelEvent); $this->expectException(ApiException::class); } catch (ApiException $apiException) { $exceptionThrown = true; @@ -128,7 +128,7 @@ private function createRestListener(PropertyPathConverterInterface $pathConverte $request->attributes = $parameterBag; $request->query = $queryParameterBag; - $this->filterControllerEvent->shouldReceive('getRequest')->andReturn($request); + $this->kernelEvent->shouldReceive('getRequest')->andReturn($request); $validator = Mockery::mock(ValidatorInterface::class); diff --git a/Tests/Listener/RestListenerTest.php b/Tests/Listener/RestListenerTest.php index 10bef36..3221b9b 100644 --- a/Tests/Listener/RestListenerTest.php +++ b/Tests/Listener/RestListenerTest.php @@ -22,9 +22,8 @@ use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Event\FilterControllerEvent; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; -use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; +use Symfony\Component\HttpKernel\Event\KernelEvent; +use Symfony\Component\HttpKernel\Event\ViewEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; @@ -63,9 +62,9 @@ class RestListenerTest extends TestCase private $requestLogger; /** - * @var MockInterface|FilterControllerEvent + * @var MockInterface|KernelEvent */ - private $filterControllerEvent; + private $kernelEvent; /** * @var ExceptionLogger @@ -94,7 +93,7 @@ public function setUp(): void $this->requestLogger = Mockery::mock(RequestLogger::class); - $this->filterControllerEvent = Mockery::mock(FilterControllerEvent::class); + $this->kernelEvent = Mockery::mock(KernelEvent::class); $this->exceptionLogger = Mockery::mock(ExceptionLogger::class); @@ -113,7 +112,7 @@ public function testOnKernelControllerNoMappersOnlyParameterToEntityMap() $this->requestApiResolver->shouldReceive('getApiKeyForRequest'); $this->requestApiResolver->shouldReceive('getApiForRequest')->andReturn(null); - $this->filterControllerEvent->shouldReceive('getRequest')->andReturn($request); + $this->kernelEvent->shouldReceive('getRequest')->andReturn($request); $this->apiManager->shouldReceive('getLogger'); $this->apiManager->shouldReceive('getSecurityStrategy')->andReturnNull(); $this->apiManager->shouldReceive('getRequestQueryMapper')->andReturnNull(); @@ -123,7 +122,7 @@ public function testOnKernelControllerNoMappersOnlyParameterToEntityMap() $restListener = $this->createRestListener(); - $restListener->onKernelController($this->filterControllerEvent); + $restListener->onKernelController($this->kernelEvent); $key = key($parameterToEntityMap); $this->assertEquals($parameterToEntityMap[$key], $parameterBag->get($key)); } @@ -146,7 +145,7 @@ public function testOnKernelControllerWithMapperAndParameterToEntityMap() $this->requestApiResolver->shouldReceive('getApiKeyForRequest'); $this->requestApiResolver->shouldReceive('getApiForRequest')->andReturn(null); - $this->filterControllerEvent->shouldReceive('getRequest')->andReturn($request); + $this->kernelEvent->shouldReceive('getRequest')->andReturn($request); $this->apiManager->shouldReceive('getLogger'); $this->apiManager->shouldReceive('getSecurityStrategy')->andReturnNull(); $this->apiManager->shouldReceive('getRequestQueryMapper')->andReturnNull(); @@ -157,7 +156,7 @@ public function testOnKernelControllerWithMapperAndParameterToEntityMap() $restListener = $this->createRestListener(); - $restListener->onKernelController($this->filterControllerEvent); + $restListener->onKernelController($this->kernelEvent); $key = key($parameterToEntityMap); $this->assertEquals($parameterToEntityMap[$key], $parameterBag->get($key)); $this->assertEquals($entity, $parameterBag->get($name)); @@ -180,7 +179,7 @@ public function testOnKernelControllerWithRequestMapperWhenDecodingFails() $this->requestApiResolver->shouldReceive('getApiKeyForRequest'); $this->requestApiResolver->shouldReceive('getApiForRequest')->andReturn(null); - $this->filterControllerEvent->shouldReceive('getRequest')->andReturn($request); + $this->kernelEvent->shouldReceive('getRequest')->andReturn($request); $this->apiManager->shouldReceive('getLogger'); $this->apiManager->shouldReceive('getSecurityStrategy')->andReturnNull(); $this->apiManager->shouldReceive('getDecoder')->andThrow(EncodingException::class); @@ -192,7 +191,7 @@ public function testOnKernelControllerWithRequestMapperWhenDecodingFails() $restListener = $this->createRestListener(); - $restListener->onKernelController($this->filterControllerEvent); + $restListener->onKernelController($this->kernelEvent); } public function testOnKernelControllerWithRequestMapperWhenMappingFails() @@ -212,7 +211,7 @@ public function testOnKernelControllerWithRequestMapperWhenMappingFails() $this->requestApiResolver->shouldReceive('getApiKeyForRequest'); $this->requestApiResolver->shouldReceive('getApiForRequest')->andReturn(null); - $this->filterControllerEvent->shouldReceive('getRequest')->andReturn($request); + $this->kernelEvent->shouldReceive('getRequest')->andReturn($request); $this->apiManager->shouldReceive('getLogger'); $this->apiManager->shouldReceive('getSecurityStrategy')->andReturnNull(); $this->apiManager->shouldReceive('getRequestQueryMapper')->andReturnNull(); @@ -223,7 +222,7 @@ public function testOnKernelControllerWithRequestMapperWhenMappingFails() $restListener = $this->createRestListener(); - $restListener->onKernelController($this->filterControllerEvent); + $restListener->onKernelController($this->kernelEvent); } public function testOnKernelControllerWithRequestMapperWhenMappingSucceedsWithoutValidation() @@ -244,7 +243,7 @@ public function testOnKernelControllerWithRequestMapperWhenMappingSucceedsWithou $this->requestApiResolver->shouldReceive('getApiKeyForRequest'); $this->requestApiResolver->shouldReceive('getApiForRequest')->andReturn(null); - $this->filterControllerEvent->shouldReceive('getRequest')->andReturn($request); + $this->kernelEvent->shouldReceive('getRequest')->andReturn($request); $this->apiManager->shouldReceive('getLogger'); $this->apiManager->shouldReceive('getSecurityStrategy')->andReturnNull(); $this->apiManager->shouldReceive('getRequestQueryMapper')->andReturnNull(); @@ -255,7 +254,7 @@ public function testOnKernelControllerWithRequestMapperWhenMappingSucceedsWithou $restListener = $this->createRestListener(); - $restListener->onKernelController($this->filterControllerEvent); + $restListener->onKernelController($this->kernelEvent); $this->assertEquals($entity, $parameterBag->get($name)); } @@ -277,7 +276,7 @@ public function testOnKernelControllerWithRequestMapperWhenMappingSucceedsWithVa $this->requestApiResolver->shouldReceive('getApiKeyForRequest'); $this->requestApiResolver->shouldReceive('getApiForRequest')->andReturn(null); - $this->filterControllerEvent->shouldReceive('getRequest')->andReturn($request); + $this->kernelEvent->shouldReceive('getRequest')->andReturn($request); $this->apiManager->shouldReceive('getLogger'); $this->apiManager->shouldReceive('getSecurityStrategy')->andReturnNull(); $this->apiManager->shouldReceive('getRequestQueryMapper')->andReturnNull(); @@ -294,7 +293,7 @@ public function testOnKernelControllerWithRequestMapperWhenMappingSucceedsWithVa $restListener = $this->createRestListener(); - $restListener->onKernelController($this->filterControllerEvent); + $restListener->onKernelController($this->kernelEvent); $this->assertEquals($entity, $parameterBag->get($name)); } @@ -317,7 +316,7 @@ public function testOnKernelControllerWithRequestMapperValidationThrowsException $this->requestApiResolver->shouldReceive('getApiKeyForRequest'); $this->requestApiResolver->shouldReceive('getApiForRequest')->andReturn(null); - $this->filterControllerEvent->shouldReceive('getRequest')->andReturn($request); + $this->kernelEvent->shouldReceive('getRequest')->andReturn($request); $this->apiManager->shouldReceive('getLogger'); $this->apiManager->shouldReceive('getSecurityStrategy')->andReturnNull(); $this->apiManager->shouldReceive('getRequestQueryMapper')->andReturnNull(); @@ -333,7 +332,7 @@ public function testOnKernelControllerWithRequestMapperValidationThrowsException $restListener = $this->createRestListener(); - $restListener->onKernelController($this->filterControllerEvent); + $restListener->onKernelController($this->kernelEvent); $this->assertEquals($entity, $parameterBag->get($name)); } @@ -356,7 +355,7 @@ public function testOnKernelControllerWithRequestQueryMapperWhenMappingFails() $this->requestApiResolver->shouldReceive('getApiKeyForRequest'); $this->requestApiResolver->shouldReceive('getApiForRequest')->andReturn(null); - $this->filterControllerEvent->shouldReceive('getRequest')->andReturn($request); + $this->kernelEvent->shouldReceive('getRequest')->andReturn($request); $this->apiManager->shouldReceive('getLogger'); $this->apiManager->shouldReceive('getSecurityStrategy')->andReturnNull(); $this->apiManager->shouldReceive('getRequestQueryMapper')->andReturn($requestMapper); @@ -367,7 +366,7 @@ public function testOnKernelControllerWithRequestQueryMapperWhenMappingFails() $restListener = $this->createRestListener(); - $restListener->onKernelController($this->filterControllerEvent); + $restListener->onKernelController($this->kernelEvent); } public function testOnKernelControllerWithRequestQueryMapperValidationThrowsException() @@ -391,7 +390,7 @@ public function testOnKernelControllerWithRequestQueryMapperValidationThrowsExce $this->requestApiResolver->shouldReceive('getApiKeyForRequest'); $this->requestApiResolver->shouldReceive('getApiForRequest')->andReturn(null); - $this->filterControllerEvent->shouldReceive('getRequest')->andReturn($request); + $this->kernelEvent->shouldReceive('getRequest')->andReturn($request); $this->apiManager->shouldReceive('getLogger'); $this->apiManager->shouldReceive('getSecurityStrategy')->andReturnNull(); $this->apiManager->shouldReceive('getRequestQueryMapper')->andReturn($requestMapper); @@ -407,7 +406,7 @@ public function testOnKernelControllerWithRequestQueryMapperValidationThrowsExce $restListener = $this->createRestListener(); - $restListener->onKernelController($this->filterControllerEvent); + $restListener->onKernelController($this->kernelEvent); $this->assertEquals($entity, $parameterBag->get($name)); } @@ -431,7 +430,7 @@ public function testOnKernelControllerWithRequestQueryMapperWhenMappingSucceedsW $this->requestApiResolver->shouldReceive('getApiKeyForRequest'); $this->requestApiResolver->shouldReceive('getApiForRequest')->andReturn(null); - $this->filterControllerEvent->shouldReceive('getRequest')->andReturn($request); + $this->kernelEvent->shouldReceive('getRequest')->andReturn($request); $this->apiManager->shouldReceive('getLogger'); $this->apiManager->shouldReceive('getSecurityStrategy')->andReturnNull(); $this->apiManager->shouldReceive('getRequestQueryMapper')->andReturn($requestMapper); @@ -448,7 +447,7 @@ public function testOnKernelControllerWithRequestQueryMapperWhenMappingSucceedsW $restListener = $this->createRestListener(); - $restListener->onKernelController($this->filterControllerEvent); + $restListener->onKernelController($this->kernelEvent); $this->assertEquals($entity, $parameterBag->get($name)); } @@ -475,7 +474,7 @@ public function testOnKernelControllerWithRequestQueryMapperValidationThrowsExce $this->requestApiResolver->shouldReceive('getApiKeyForRequest'); $this->requestApiResolver->shouldReceive('getApiForRequest')->andReturn(null); - $this->filterControllerEvent->shouldReceive('getRequest')->andReturn($request); + $this->kernelEvent->shouldReceive('getRequest')->andReturn($request); $this->apiManager->shouldReceive('getLogger'); $this->apiManager->shouldReceive('getSecurityStrategy')->andReturnNull(); $this->apiManager->shouldReceive('getRequestQueryMapper')->andReturn($requestMapper); @@ -502,7 +501,7 @@ public function testOnKernelControllerWithRequestQueryMapperValidationThrowsExce $exceptionThrowed = false; try { - $restListener->onKernelController($this->filterControllerEvent); + $restListener->onKernelController($this->kernelEvent); } catch (ApiException $apiException) { $exceptionThrowed = true; $this->assertEquals( @@ -542,7 +541,7 @@ public function testOnKernelViewResponseHasXFrameOptionsHeader() $httpKernelMock = Mockery::mock(HttpKernelInterface::class); $requestMock = Mockery::mock(Request::class); - $event = new GetResponseForControllerResultEvent( + $event = new ViewEvent( $httpKernelMock, $requestMock, HttpKernelInterface::MASTER_REQUEST, diff --git a/composer.json b/composer.json index 28527c7..793bf95 100644 --- a/composer.json +++ b/composer.json @@ -7,16 +7,16 @@ } }, "require": { - "php": "^7.4 || ^8.0", + "php": ">=7.4", "paysera/lib-serializer": "^3.0", "doctrine/orm": "^2.0", - "symfony/config": "^3.0 || ^4.0", - "symfony/dependency-injection": "^3.0 || ^4.0", - "symfony/validator": "^3.0 || ^4.0", - "symfony/security-core": "^3.0 || ^4.0", - "symfony/routing": "^3.0 || ^4.0", - "symfony/http-foundation": "^3.0 || ^4.0", - "symfony/http-kernel": "^3.0 || ^4.0", + "symfony/config": "^3.0 || ^4.0 || ^5.0", + "symfony/dependency-injection": "^3.0 || ^4.0 || ^5.0", + "symfony/validator": "^3.0 || ^4.0 || ^5.0", + "symfony/security-core": "^3.0 || ^4.0 || ^5.0", + "symfony/routing": "^3.0 || ^4.0 || ^5.0", + "symfony/http-foundation": "^3.0 || ^4.0 || ^5.0", + "symfony/http-kernel": "^3.0 || ^4.0 || ^5.0", "doctrine/persistence": "^3.2" }, "config": { @@ -25,5 +25,15 @@ "require-dev": { "phpunit/phpunit": "^8.0", "mockery/mockery": "^1.2" + }, + "scripts": { + "test": [ + "@test:phpunit" + ], + "test:phpunit": "bin/phpunit" + }, + "scripts-descriptions": { + "test": "Runs all tests", + "test:phpunit": "Runs PHPUnit tests" } } From ec2d4ed910b115c6de449ac72ee487c912352772 Mon Sep 17 00:00:00 2001 From: Andrii Sobol Date: Sun, 18 Feb 2024 22:14:33 +0200 Subject: [PATCH 2/7] This commit adds support for PHP >=7.4 and support for Symfony 5.X. --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4f3b8ac..caeeddc 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -4,10 +4,10 @@ on: push: branches: - master + - symfony-5-support pull_request: branches: - master - - symfony-5-support permissions: contents: read From 520df7b1a7144fc50fe47f6a9ba009e86b9ebd04 Mon Sep 17 00:00:00 2001 From: Andrii Sobol Date: Sun, 18 Feb 2024 22:25:12 +0200 Subject: [PATCH 3/7] This commit adds support for PHP >=7.4 and support for Symfony 5.X. --- PayseraRestBundle.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/PayseraRestBundle.php b/PayseraRestBundle.php index cd85cd2..09ae8e7 100644 --- a/PayseraRestBundle.php +++ b/PayseraRestBundle.php @@ -7,6 +7,9 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; +/** + * @deprecated Use https://github.com/paysera/lib-api-bundle instead. + */ class PayseraRestBundle extends Bundle { /** @@ -21,7 +24,10 @@ class PayseraRestBundle extends Bundle */ public function build(ContainerBuilder $container) { + @trigger_error('Use https://github.com/paysera/lib-api-bundle instead', E_USER_DEPRECATED); + parent::build($container); + $container->addCompilerPass(new ApiCompilerPass()); } } From 94b9d3bf0d33ac23d516034fa0d36d7f083a1216 Mon Sep 17 00:00:00 2001 From: Andrii Sobol Date: Mon, 19 Feb 2024 08:56:16 +0200 Subject: [PATCH 4/7] This commit adds support for PHP >=7.4 and support for Symfony 5.X. --- .github/workflows/ci.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index caeeddc..de3c4b9 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -4,7 +4,6 @@ on: push: branches: - master - - symfony-5-support pull_request: branches: - master From 8e6104f16a769f3fe00b8030d6fe7b4a8e4244d1 Mon Sep 17 00:00:00 2001 From: Andrii Sobol Date: Mon, 19 Feb 2024 14:21:03 +0200 Subject: [PATCH 5/7] This commit adds support for PHP >=7.4 and support for Symfony 5.X., removed support for Symfony 3.X --- CHANGELOG.md | 2 ++ PayseraRestBundle.php | 2 -- README.md | 3 ++- composer.json | 14 +++++++------- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 121cce3..42f85be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Added - Support for PHP >=7.4 - Support for Symfony 5.X +### Removed +- Support for Symfony 3.X ## 5.1.0 ### Added diff --git a/PayseraRestBundle.php b/PayseraRestBundle.php index 09ae8e7..a08e834 100644 --- a/PayseraRestBundle.php +++ b/PayseraRestBundle.php @@ -24,8 +24,6 @@ class PayseraRestBundle extends Bundle */ public function build(ContainerBuilder $container) { - @trigger_error('Use https://github.com/paysera/lib-api-bundle instead', E_USER_DEPRECATED); - parent::build($container); $container->addCompilerPass(new ApiCompilerPass()); diff --git a/README.md b/README.md index 0bf0247..b701127 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ PayseraRestBundle ![](https://travis-ci.org/paysera/lib-rest-bundle.svg?branch=master) ================= -This bundle provides means for rapid API development. +> **Deprecated**, use [https://github.com/paysera/lib-api-bundle](https://github.com/paysera/lib-api-bundle) instead. +This bundle provides means for rapid API development. Installation ------------ diff --git a/composer.json b/composer.json index 793bf95..f804ca7 100644 --- a/composer.json +++ b/composer.json @@ -10,13 +10,13 @@ "php": ">=7.4", "paysera/lib-serializer": "^3.0", "doctrine/orm": "^2.0", - "symfony/config": "^3.0 || ^4.0 || ^5.0", - "symfony/dependency-injection": "^3.0 || ^4.0 || ^5.0", - "symfony/validator": "^3.0 || ^4.0 || ^5.0", - "symfony/security-core": "^3.0 || ^4.0 || ^5.0", - "symfony/routing": "^3.0 || ^4.0 || ^5.0", - "symfony/http-foundation": "^3.0 || ^4.0 || ^5.0", - "symfony/http-kernel": "^3.0 || ^4.0 || ^5.0", + "symfony/config": "^4.0 || ^5.0", + "symfony/dependency-injection": "^4.0 || ^5.0", + "symfony/validator": "^4.0 || ^5.0", + "symfony/security-core": "^4.0 || ^5.0", + "symfony/routing": "^4.0 || ^5.0", + "symfony/http-foundation": "^4.0 || ^5.0", + "symfony/http-kernel": "^4.0 || ^5.0", "doctrine/persistence": "^3.2" }, "config": { From b8828cbdae0f8cab484639ad3b42b2cf8b33aa2e Mon Sep 17 00:00:00 2001 From: Andrii Sobol Date: Wed, 21 Feb 2024 15:40:29 +0200 Subject: [PATCH 6/7] This commit adds support for PHP >=7.4 and support for Symfony 5.X., removed support for Symfony 3.X --- Exception/FatalErrorException.php | 75 ------------------------------- Exception/FatalThrowableError.php | 41 ----------------- Listener/RestListener.php | 8 +++- 3 files changed, 6 insertions(+), 118 deletions(-) delete mode 100644 Exception/FatalErrorException.php delete mode 100644 Exception/FatalThrowableError.php diff --git a/Exception/FatalErrorException.php b/Exception/FatalErrorException.php deleted file mode 100644 index 08daf85..0000000 --- a/Exception/FatalErrorException.php +++ /dev/null @@ -1,75 +0,0 @@ -setTrace($trace); - } elseif (null !== $traceOffset) { - if (function_exists('xdebug_get_function_stack') && $trace = @xdebug_get_function_stack()) { - if (0 < $traceOffset) { - array_splice($trace, -$traceOffset); - } - - foreach ($trace as &$frame) { - if (!isset($frame['type'])) { - // XDebug pre 2.1.1 doesn't currently set the call type key http://bugs.xdebug.org/view.php?id=695 - if (isset($frame['class'])) { - $frame['type'] = '::'; - } - } elseif ('dynamic' === $frame['type']) { - $frame['type'] = '->'; - } elseif ('static' === $frame['type']) { - $frame['type'] = '::'; - } - - // XDebug also has a different name for the parameters array - if (!$traceArgs) { - unset($frame['params'], $frame['args']); - } elseif (isset($frame['params']) && !isset($frame['args'])) { - $frame['args'] = $frame['params']; - unset($frame['params']); - } - } - - unset($frame); - $trace = array_reverse($trace); - } else { - $trace = []; - } - - $this->setTrace($trace); - } - } - - protected function setTrace($trace) - { - $traceReflector = new ReflectionProperty(\Exception::class, 'trace'); - $traceReflector->setAccessible(true); - $traceReflector->setValue($this, $trace); - } -} diff --git a/Exception/FatalThrowableError.php b/Exception/FatalThrowableError.php deleted file mode 100644 index 82d0ac3..0000000 --- a/Exception/FatalThrowableError.php +++ /dev/null @@ -1,41 +0,0 @@ -originalClassName = get_class($e); - - if ($e instanceof ParseError) { - $severity = E_PARSE; - } elseif ($e instanceof \TypeError) { - $severity = E_RECOVERABLE_ERROR; - } else { - $severity = E_ERROR; - } - - ErrorException::__construct( - $e->getMessage(), - $e->getCode(), - $severity, - $e->getFile(), - $e->getLine(), - $e->getPrevious() - ); - - $this->setTrace($e->getTrace()); - } - - public function getOriginalClassName(): string - { - return $this->originalClassName; - } -} diff --git a/Listener/RestListener.php b/Listener/RestListener.php index f9be076..a41b169 100644 --- a/Listener/RestListener.php +++ b/Listener/RestListener.php @@ -4,7 +4,6 @@ use Exception; use Paysera\Bundle\RestBundle\Cache\ResponseAwareCacheStrategy; -use Paysera\Bundle\RestBundle\Exception\FatalThrowableError; use Paysera\Bundle\RestBundle\Service\ExceptionLogger; use Paysera\Bundle\RestBundle\Service\ParameterToEntityMapBuilder; use Paysera\Bundle\RestBundle\Service\RequestApiResolver; @@ -246,11 +245,16 @@ public function onKernelView(ViewEvent $event) */ public function onKernelException(ExceptionEvent $event) { + if (!$event->getThrowable() instanceof Exception) { + return; + } + /** @var $request Request */ $request = $event->getRequest(); $logger = $this->getLogger($request); - $exception = new FatalThrowableError($event->getThrowable()); + /** @var Exception $exception */ + $exception = $event->getThrowable(); $logger->debug('Handling kernel.exception', array($event)); $logger->debug($exception); From 8fa9aa80f416143902649660c2885b715fd85a17 Mon Sep 17 00:00:00 2001 From: Andrii Sobol Date: Wed, 21 Feb 2024 15:43:05 +0200 Subject: [PATCH 7/7] This commit adds support for PHP >=7.4 and support for Symfony 5.X., removed support for Symfony 3.X --- Listener/RestListener.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Listener/RestListener.php b/Listener/RestListener.php index a41b169..e13a1a7 100644 --- a/Listener/RestListener.php +++ b/Listener/RestListener.php @@ -253,10 +253,11 @@ public function onKernelException(ExceptionEvent $event) $request = $event->getRequest(); $logger = $this->getLogger($request); + $logger->debug('Handling kernel.exception', array($event)); + /** @var Exception $exception */ $exception = $event->getThrowable(); - $logger->debug('Handling kernel.exception', array($event)); $logger->debug($exception); $response = $this->apiManager->getResponseForException($request, $exception);