From 03de742fb9dc12c478f1ab67d2ea2c824dd9fef5 Mon Sep 17 00:00:00 2001 From: Andreas Ferber Date: Fri, 10 Jun 2016 00:55:42 +0200 Subject: [PATCH 1/2] Allow object methods as custom labeler Use call_user_func() instead of calling the labeler directly, which allows more variation on what can be used as a custom labeler. --- src/DataDog/AuditBundle/EventSubscriber/AuditSubscriber.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataDog/AuditBundle/EventSubscriber/AuditSubscriber.php b/src/DataDog/AuditBundle/EventSubscriber/AuditSubscriber.php index 0057227..21eedb1 100644 --- a/src/DataDog/AuditBundle/EventSubscriber/AuditSubscriber.php +++ b/src/DataDog/AuditBundle/EventSubscriber/AuditSubscriber.php @@ -335,7 +335,7 @@ private function typ($className) private function label(EntityManager $em, $entity) { if (is_callable($this->labeler)) { - return $this->labeler($entity); + return call_user_func($this->labeler, $entity); } $meta = $em->getClassMetadata(get_class($entity)); switch (true) { From 53e10f3a18054e133741e10c03df6874571a1ec8 Mon Sep 17 00:00:00 2001 From: Andreas Ferber Date: Fri, 10 Jun 2016 00:47:42 +0200 Subject: [PATCH 2/2] Allow disabling audit log for certain entities Add configuration options to disable audit logging for particular entities. --- README.md | 10 +++++ .../DependencyInjection/Configuration.php | 36 +++++++++++++++ .../DataDogAuditExtension.php | 8 ++++ .../EventSubscriber/AuditSubscriber.php | 44 +++++++++++++++++++ 4 files changed, 98 insertions(+) create mode 100644 src/DataDog/AuditBundle/DependencyInjection/Configuration.php diff --git a/README.md b/README.md index 4329422..f47ff89 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,16 @@ symfony application. **audit** entities will be mapped automatically if you run schema update or similar. And all the database changes will be reflected in the audit log afterwards. +### Unaudited Entities + +Sometimes, you might not want to create audit log entries for particular entities. +You can achieve this by listing those entities under the `unaudired_entities` configuuration +key in your `config.yml`, for example: + + data_dog_audit: + unaudited_entities: + - AppBundle\Entity\NoAuditForThis + ## Screenshots All paginated audit log: diff --git a/src/DataDog/AuditBundle/DependencyInjection/Configuration.php b/src/DataDog/AuditBundle/DependencyInjection/Configuration.php new file mode 100644 index 0000000..08cc724 --- /dev/null +++ b/src/DataDog/AuditBundle/DependencyInjection/Configuration.php @@ -0,0 +1,36 @@ +root('data_dog_audit'); + + $rootNode + ->children() + ->arrayNode('unaudited_entities') + ->canBeUnset() + ->performNoDeepMerging() + ->prototype('scalar')->end() + ->end() + ->end() + ; + + return $treeBuilder; + } + +} diff --git a/src/DataDog/AuditBundle/DependencyInjection/DataDogAuditExtension.php b/src/DataDog/AuditBundle/DependencyInjection/DataDogAuditExtension.php index b75cc35..f6bf84b 100644 --- a/src/DataDog/AuditBundle/DependencyInjection/DataDogAuditExtension.php +++ b/src/DataDog/AuditBundle/DependencyInjection/DataDogAuditExtension.php @@ -14,7 +14,15 @@ class DataDogAuditExtension extends Extension */ public function load(array $configs, ContainerBuilder $container) { + $configuration = new Configuration(); + $config = $this->processConfiguration($configuration, $configs); + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('services.yml'); + + if (isset($config['unaudited_entities'])) { + $auditSubscriber = $container->getDefinition('datadog.event_subscriber.audit'); + $auditSubscriber->addMethodCall('addUnauditedEntities', array($config['unaudited_entities'])); + } } } diff --git a/src/DataDog/AuditBundle/EventSubscriber/AuditSubscriber.php b/src/DataDog/AuditBundle/EventSubscriber/AuditSubscriber.php index 21eedb1..7e49fcf 100644 --- a/src/DataDog/AuditBundle/EventSubscriber/AuditSubscriber.php +++ b/src/DataDog/AuditBundle/EventSubscriber/AuditSubscriber.php @@ -31,6 +31,8 @@ class AuditSubscriber implements EventSubscriber */ protected $securityTokenStorage; + private $unauditedEntities = []; + private $inserted = []; // [$source, $changeset] private $updated = []; // [$source, $changeset] private $removed = []; // [$source, $id] @@ -56,6 +58,24 @@ public function getLabeler() return $this->labeler; } + public function addUnauditedEntities(array $unauditedEntities) + { + // use entity names as array keys for easier lookup + foreach ($unauditedEntities as $unauditedEntity) { + $this->unauditedEntities[$unauditedEntity] = true; + } + } + + public function getUnauditedEntities() + { + return array_keys($this->unauditedEntities); + } + + private function isEntityUnaudited($entity) + { + return isset($this->unauditedEntities[get_class($entity)]); + } + public function onFlush(OnFlushEventArgs $args) { $em = $args->getEntityManager(); @@ -73,33 +93,57 @@ public function onFlush(OnFlushEventArgs $args) $em->getConnection()->getConfiguration()->setSQLLogger($new); foreach ($uow->getScheduledEntityUpdates() as $entity) { + if ($this->isEntityUnaudited($entity)) { + continue; + } $this->updated[] = [$entity, $uow->getEntityChangeSet($entity)]; } foreach ($uow->getScheduledEntityInsertions() as $entity) { + if ($this->isEntityUnaudited($entity)) { + continue; + } $this->inserted[] = [$entity, $ch = $uow->getEntityChangeSet($entity)]; } foreach ($uow->getScheduledEntityDeletions() as $entity) { + if ($this->isEntityUnaudited($entity)) { + continue; + } $uow->initializeObject($entity); $this->removed[] = [$entity, $this->id($em, $entity)]; } foreach ($uow->getScheduledCollectionUpdates() as $collection) { + if ($this->isEntityUnaudited($collection->getOwner())) { + continue; + } $mapping = $collection->getMapping(); if (!$mapping['isOwningSide'] || $mapping['type'] !== ClassMetadataInfo::MANY_TO_MANY) { continue; // ignore inverse side or one to many relations } foreach ($collection->getInsertDiff() as $entity) { + if ($this->isEntityUnaudited($entity)) { + continue; + } $this->associated[] = [$collection->getOwner(), $entity, $mapping]; } foreach ($collection->getDeleteDiff() as $entity) { + if ($this->isEntityUnaudited($entity)) { + continue; + } $this->dissociated[] = [$collection->getOwner(), $entity, $this->id($em, $entity), $mapping]; } } foreach ($uow->getScheduledCollectionDeletions() as $collection) { + if ($this->isEntityUnaudited($collection->getOwner())) { + continue; + } $mapping = $collection->getMapping(); if (!$mapping['isOwningSide'] || $mapping['type'] !== ClassMetadataInfo::MANY_TO_MANY) { continue; // ignore inverse side or one to many relations } foreach ($collection->toArray() as $entity) { + if ($this->isEntityUnaudited($entity)) { + continue; + } $this->dissociated[] = [$collection->getOwner(), $entity, $this->id($em, $entity), $mapping]; } }