diff --git a/composer.json b/composer.json index 815fb7f..ceca3a6 100644 --- a/composer.json +++ b/composer.json @@ -11,29 +11,29 @@ ], "require": { "php": ">=8.1", - "doctrine/annotations": "^1.14", + "doctrine/annotations": "^2.0", "doctrine/doctrine-bundle": "^2.8", - "doctrine/orm": "^2.14", + "doctrine/orm": "^2.2", "elasticsearch/elasticsearch": "^7.1", - "symfony/dotenv": "6.4.*", - "symfony/expression-language": "6.4.*", - "symfony/framework-bundle": "^6.4", - "symfony/messenger": "6.4.*", - "symfony/property-info": "6.4.*", - "symfony/runtime": "6.4.*", - "symfony/serializer": "6.4.*", - "symfony/validator": "6.4.*", - "symfony/yaml": "6.4.*", + "symfony/dotenv": "7.2.*", + "symfony/expression-language": "7.2.*", + "symfony/framework-bundle": "^7.2", + "symfony/messenger": "7.2.*", + "symfony/property-info": "7.2.*", + "symfony/runtime": "7.2.*", + "symfony/serializer": "7.2.*", + "symfony/validator": "7.2.*", + "symfony/yaml": "7.2.*", "ext-simplexml": "*", - "symfony/security-bundle": "^6.4", - "symfony/finder": "^6.4" + "symfony/security-bundle": "^7.2", + "symfony/finder": "^7.2" }, "require-dev": { - "symfony/browser-kit": "6.4.*", - "symfony/css-selector": "6.4.*", - "symfony/console": "6.4.*", - "symfony/phpunit-bridge": "^6.4", - "symfony/test-pack": "^1.1" + "symfony/browser-kit": "7.2.*", + "symfony/css-selector": "7.2.*", + "symfony/console": "7.2.*", + "symfony/phpunit-bridge": "^7.2", + "symfony/test-pack": "1.1.0" }, "prefer-stable": true, "autoload": { @@ -48,7 +48,7 @@ "dev-master": "1.0-dev" }, "symfony": { - "require": "6.4.*" + "require": "7.2.*" } }, "conflict": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index da43e2d..05bacd4 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -9,6 +9,7 @@ + diff --git a/src/Identifier/LogIdentifierExtractor.php b/src/Identifier/LogIdentifierExtractor.php index c964001..9302eb2 100644 --- a/src/Identifier/LogIdentifierExtractor.php +++ b/src/Identifier/LogIdentifierExtractor.php @@ -2,7 +2,6 @@ namespace Locastic\Loggastic\Identifier; -use Doctrine\Common\Util\ClassUtils; use Doctrine\ORM\EntityManagerInterface; use Doctrine\Persistence\Mapping\MappingException; use Symfony\Component\Messenger\Exception\HandlerFailedException; @@ -17,7 +16,10 @@ public function __construct(private readonly EntityManagerInterface $entityManag public function getIdentifierValue(object $object): int|string|null { try { - $identifier = $this->entityManager->getClassMetadata(ClassUtils::getClass($object))->getSingleIdentifierFieldName(); + $metadata = $this->entityManager->getClassMetadata(get_class($object)); + $entityClass = $metadata->getName(); + + $identifier = $this->entityManager->getClassMetadata($entityClass)->getSingleIdentifierFieldName(); $identifierGetter = 'get' . $identifier; return $object->$identifierGetter(); diff --git a/src/Metadata/LoggableContext/Factory/AttributeLoggableContextCollectionFactory.php b/src/Metadata/LoggableContext/Factory/AttributeLoggableContextCollectionFactory.php new file mode 100644 index 0000000..031e358 --- /dev/null +++ b/src/Metadata/LoggableContext/Factory/AttributeLoggableContextCollectionFactory.php @@ -0,0 +1,52 @@ +loggablePaths) === 0) { + return new LoggableContextCollection([]); + } + + $classes = []; + + if ($this->decorated) { + foreach ($this->decorated->create() as $loggableClass => $config) { + $classes[$loggableClass] = $config; + } + } + + foreach (RecursiveClassIterator::getReflectionClasses($this->loggablePaths) as $className => $reflectionClass) { + if ($loggable = $this->getLoggableAttribute($reflectionClass)) { + $classes[$className] = ['groups' => $loggable->getGroups()]; + } + } + + return new LoggableContextCollection($classes); + } + + private function getLoggableAttribute(\ReflectionClass $reflectionClass): ?Loggable + { + foreach ($reflectionClass->getAttributes() as $attribute) { + if (is_a($attribute->getName(), Loggable::class, true)) { + return $attribute->newInstance(); + } + } + + return null; + } +} diff --git a/src/Resources/config/context.yaml b/src/Resources/config/context.yaml index 16a83b8..9807064 100644 --- a/src/Resources/config/context.yaml +++ b/src/Resources/config/context.yaml @@ -26,12 +26,11 @@ services: - '@locastic_activity_logs.metadata.loggable_class_extractor.yaml' - '@.inner' - locastic_activity_log.metadata.loggable.context_collection_factory.annotation: - class: Locastic\ActivityLog\Metadata\LoggableContext\Factory\AnnotationLoggableContextCollectionFactory + locastic_activity_log.metadata.loggable.context_collection_factory.attribute: + class: Locastic\ActivityLog\Metadata\LoggableContext\Factory\AttributeLoggableContextCollectionFactory decorates: 'locastic_activity_log.metadata.loggable.context_collection_factory' arguments: - '@.inner' - - '@annotations.reader' - '%locastic_activity_log.dir.loggable_classes%' Locastic\ActivityLog\Metadata\LoggableContext\Factory\LoggableContextFactoryInterface: diff --git a/src/Resources/config/loggable_context.yaml b/src/Resources/config/loggable_context.yaml index 6a05e01..9a2ae49 100644 --- a/src/Resources/config/loggable_context.yaml +++ b/src/Resources/config/loggable_context.yaml @@ -26,12 +26,11 @@ services: - '@Locastic\Loggastic\Metadata\Extractor\YamlLoggableExtractor' - '@.inner' - locastic_activity_log.metadata.loggable.context_collection_factory.annotation: - class: Locastic\Loggastic\Metadata\LoggableContext\Factory\AnnotationLoggableContextCollectionFactory + locastic_activity_log.metadata.loggable.context_collection_factory.attribute: + class: Locastic\Loggastic\Metadata\LoggableContext\Factory\AttributeLoggableContextCollectionFactory decorates: 'locastic_activity_log.metadata.loggable.context_collection_factory' arguments: - '@.inner' - - '@annotations.reader' - '%locastic_activity_log.dir.loggable_classes%' Locastic\Loggastic\Metadata\LoggableContext\Factory\LoggableContextFactoryInterface: diff --git a/src/Serializer/ActivityLogCollectionNormalizer.php b/src/Serializer/ActivityLogCollectionNormalizer.php index 2c83b39..6fc8b55 100644 --- a/src/Serializer/ActivityLogCollectionNormalizer.php +++ b/src/Serializer/ActivityLogCollectionNormalizer.php @@ -19,12 +19,12 @@ public function __construct( { } - public function normalize($object, string $format = null, array $context = []): array + public function normalize($data, string $format = null, array $context = []): array { - $data = []; + $collection = []; if ($this->useIdentifierExtractor) { - foreach ($object as $item) { + foreach ($data as $item) { $normalizedItem = $this->decorated->normalize($item, 'array', $context); $logId = $this->logIdentifierExtractor->getIdentifierValue($item); @@ -32,20 +32,34 @@ public function normalize($object, string $format = null, array $context = []): continue; } - $data[$logId] = $normalizedItem; + $collection[$logId] = $normalizedItem; } } else { - foreach ($object as $item) { + foreach ($data as $item) { $normalizedItem = $this->decorated->normalize($item, 'array', $context); - $data[] = $normalizedItem; + $collection[] = $normalizedItem; } } - return $data; + return $collection; } public function supportsNormalization($data, string $format = null, array $context = []): bool { return $data instanceof Collection && self::FORMAT === $format; } + + public function getSupportedTypes(?string $format): array + { + if (self::FORMAT !== $format) { + return []; + } + + return [ + Collection::class => true, + 'array' => true, + 'object' => true, + 'Locastic\Loggastic\Model\Output\ActivityLogInterface' => true, + ]; + } } diff --git a/tests/Fixtures/app/Model/DummyBlogPost.php b/tests/Fixtures/app/Model/DummyBlogPost.php index b2accac..0a43943 100644 --- a/tests/Fixtures/app/Model/DummyBlogPost.php +++ b/tests/Fixtures/app/Model/DummyBlogPost.php @@ -7,29 +7,27 @@ use Locastic\Loggastic\Annotation\Loggable; use Symfony\Component\Serializer\Annotation\Groups; -/** - * @Loggable(groups={"dummy_blog_post_log"}) - */ +#[Loggable(groups: ['dummy_blog_post_log'])] class DummyBlogPost { private int $id; - /** @Groups({"dummy_blog_post_log"}) */ + #[Groups(['dummy_blog_post_log'])] private ?string $title; - /** @Groups({"dummy_blog_post_log"}) */ + #[Groups(['dummy_blog_post_log'])] private array $tags = []; - /** @Groups({"dummy_blog_post_log"}) */ + #[Groups(['dummy_blog_post_log'])] private int $position = 0; - /** @Groups({"dummy_blog_post_log"}) */ + #[Groups(['dummy_blog_post_log'])] private ?\DateTime $publishAt; - /** @Groups({"dummy_blog_post_log"}) */ + #[Groups(['dummy_blog_post_log'])] private bool $enabled; - /** @Groups({"dummy_blog_post_log"}) */ + #[Groups(['dummy_blog_post_log'])] private Collection $photos; public function __construct()