diff --git a/src/Security/EntityListeners/ElementPermissionListener.php b/src/Security/EntityListeners/ElementPermissionListener.php index f19b88c2..a60216a8 100644 --- a/src/Security/EntityListeners/ElementPermissionListener.php +++ b/src/Security/EntityListeners/ElementPermissionListener.php @@ -52,6 +52,7 @@ class ElementPermissionListener protected $disabled; protected $perm_cache; + protected $annotation_cache; public function __construct(Security $security, Reader $reader, EntityManagerInterface $em, KernelInterface $kernel) { @@ -61,6 +62,7 @@ class ElementPermissionListener //Disable security when the current program is running from CLI $this->disabled = $this->isRunningFromCLI(); $this->perm_cache = []; + $this->annotation_cache = []; } /** @@ -106,7 +108,25 @@ class ElementPermissionListener } return $this->perm_cache[$mode][get_class($element)][$operation]; + } + /** + * Gets the ColumnSecurity Annotation for a given and its property. + * Adds an additional cache layer, where AnnotationReader::gerPropertyAnnotation is only called once for a class. + * @param DBElement $element The element for which the annotation should be determined. + * @param \ReflectionProperty $property The property on which the annotation should be determined. + * @return ColumnSecurity|null + */ + protected function getAnnotation(DBElement $element, \ReflectionProperty $property) : ?ColumnSecurity + { + if (!isset($this->annotation_cache[get_class($element)][$property->getName()])) { + $this->annotation_cache[get_class($element)][$property->getName()] = $this->reader->getPropertyAnnotation( + $property, + ColumnSecurity::class + ); + } + + return $this->annotation_cache[get_class($element)][$property->getName()]; } /** @@ -134,10 +154,7 @@ class ElementPermissionListener /** * @var ColumnSecurity */ - $annotation = $this->reader->getPropertyAnnotation( - $property, - ColumnSecurity::class - ); + $annotation = $this->getAnnotation($element, $property); //Check if user is allowed to read info, otherwise apply placeholder if ((null !== $annotation) && !$this->isGranted('read', $annotation, $element)) { @@ -176,10 +193,7 @@ class ElementPermissionListener $old_data = $unitOfWork->getOriginalEntityData($element); foreach ($properties as $property) { - $annotation = $this->reader->getPropertyAnnotation( - $property, - ColumnSecurity::class - ); + $annotation = $this->getAnnotation($element, $property); $changed = false; @@ -189,7 +203,7 @@ class ElementPermissionListener //If the user is not allowed to edit or read this property, reset all values. if ((!$this->isGranted('read', $annotation, $element) - || !$this->isGranted('edit', $annotation->getReadOperationName(), $element))) { + || !$this->isGranted('edit', $annotation, $element))) { //Set value to old value, so that there a no change to this property if (isset($old_data[$property->getName()])) { $property->setValue($element, $old_data[$property->getName()]);