vendor/nzo/url-encryptor-bundle/Annotations/AnnotationResolver.php line 32

  1. <?php
  2. /*
  3. * This file is part of the NzoUrlEncryptorBundle package.
  4. *
  5. * (c) Ala Eddine Khefifi <alakfpro@gmail.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Nzo\UrlEncryptorBundle\Annotations;
  11. use Doctrine\Common\Annotations\AnnotationReader;
  12. use Nzo\UrlEncryptorBundle\Encryptor\Encryptor;
  13. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  14. class AnnotationResolver
  15. {
  16. private $encryptor;
  17. private $reader;
  18. public function __construct(Encryptor $encryptor, ?AnnotationReader $reader = null)
  19. {
  20. $this->encryptor = $encryptor;
  21. $this->reader = $reader;
  22. }
  23. public function onKernelController(ControllerEvent $event)
  24. {
  25. if (is_array($controller = $event->getController())) {
  26. $objectController = new \ReflectionObject($controller[0]);
  27. $method = $objectController->getMethod($controller[1]);
  28. } elseif (is_object($controller) && method_exists($controller, '__invoke')) {
  29. $objectController = new \ReflectionObject($controller);
  30. $method = $objectController->getMethod('__invoke');
  31. } else {
  32. return;
  33. }
  34. // Handle PHP8 Attributes
  35. if (class_exists('ReflectionAttribute')) {
  36. if ($this->hasAnnotation($method) && !$this->reader instanceof AnnotationReader) {
  37. throw new \InvalidArgumentException('NzoEncryptor: Annotation service not loaded, PHP Attributes should be used instead.');
  38. }
  39. $annotations = $this->getAnnotation($method);
  40. } elseif ($this->reader instanceof AnnotationReader) { // Handle Annotation only without Attributes
  41. $annotations = $this->reader->getMethodAnnotations($method);
  42. } else {
  43. throw new \InvalidArgumentException('NzoEncryptor: Doctrine Annotation package must be installed, doctrine/annotations.');
  44. }
  45. foreach ($annotations as $configuration) {
  46. // handle php8 attribute
  47. if (class_exists('ReflectionAttribute')) {
  48. $configuration = $this->handleReflectionAttribute($configuration);
  49. }
  50. if ($configuration instanceof ParamEncryptor) {
  51. if (null !== $configuration->getParams()) {
  52. $request = $event->getRequest();
  53. foreach ($configuration->getParams() as $param) {
  54. if ($request->attributes->has($param)) {
  55. $decrypted = $this->encryptor->encrypt($request->attributes->get($param));
  56. $request->attributes->set($param, $decrypted);
  57. } elseif ($request->request->has($param)) {
  58. $decrypted = $this->encryptor->encrypt($request->request->get($param));
  59. $request->request->set($param, $decrypted);
  60. }
  61. }
  62. }
  63. } elseif ($configuration instanceof ParamDecryptor) {
  64. if (null !== $configuration->getParams()) {
  65. $request = $event->getRequest();
  66. foreach ($configuration->getParams() as $param) {
  67. if ($request->attributes->has($param)) {
  68. $decrypted = $this->encryptor->decrypt($request->attributes->get($param));
  69. $request->attributes->set($param, $decrypted);
  70. } elseif ($request->request->has($param)) {
  71. $decrypted = $this->encryptor->decrypt($request->request->get($param));
  72. $request->request->set($param, $decrypted);
  73. }
  74. }
  75. }
  76. }
  77. }
  78. }
  79. private function handleReflectionAttribute($configuration)
  80. {
  81. if ($configuration instanceof \ReflectionAttribute
  82. && \in_array($configuration->getName(), [ParamEncryptor::class, ParamDecryptor::class], true)) {
  83. $class = $configuration->getName();
  84. $arguments = $configuration->getArguments();
  85. $params = \is_array($arguments) && [] !== $arguments && \is_array($arguments[0]) ? $arguments[0] : [];
  86. return new $class($params);
  87. }
  88. return $configuration;
  89. }
  90. /**
  91. * @return array|mixed
  92. */
  93. private function getAnnotation($method)
  94. {
  95. return $this->reader instanceof AnnotationReader && !empty($this->reader->getMethodAnnotations($method))
  96. ? $this->reader->getMethodAnnotations($method)
  97. : $method->getAttributes();
  98. }
  99. /**
  100. * @param \ReflectionMethod $method
  101. *
  102. * @return bool
  103. */
  104. private function hasAnnotation($method)
  105. {
  106. $docComment = $method->getDocComment();
  107. return false !== $docComment && (false !== strpos($docComment, '@ParamEncryptor') || false !== strpos($docComment, '@ParamDecryptor'));
  108. }
  109. }