Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
61.11% covered (warning)
61.11%
22 / 36
37.50% covered (danger)
37.50%
3 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
AuditLog
61.11% covered (warning)
61.11%
22 / 36
37.50% covered (danger)
37.50%
3 / 8
40.23
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 getDescription
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
 getEvent
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
3.14
 getCreatedBy
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
3.04
 getRequiredPermissions
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 getId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getReference
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getData
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
1<?php
2namespace Apie\Common\Other;
3
4use Apie\Common\Enums\AuditLogEvent;
5use Apie\Common\Other\Audit\AuditCreate;
6use Apie\Common\Other\Audit\AuditEvent;
7use Apie\Common\Other\Audit\AuditMethodCalled;
8use Apie\Common\Other\Audit\AuditMigration;
9use Apie\Common\Other\Audit\AuditModified;
10use Apie\Common\Other\Audit\AuditRead;
11use Apie\Common\Other\Audit\AuditRemoved;
12use Apie\Core\Attributes\AlwaysDisabled;
13use Apie\Core\Attributes\Context;
14use Apie\Core\Attributes\FakeCount;
15use Apie\Core\Attributes\SearchFilterOption;
16use Apie\Core\Attributes\StaticCheck;
17use Apie\Core\Context\ApieContext;
18use Apie\Core\Entities\EntityInterface;
19use Apie\Core\Lists\PermissionList;
20use Apie\Core\Permissions\RequiresPermissionsInterface;
21use Apie\Core\Translator\ApieTranslatorInterface;
22use Apie\Core\Translator\ValueObjects\TranslationString;
23use Apie\Core\ValueObjects\IdFriendlyEntityReference;
24use Apie\Core\ValueObjects\NonEmptyString;
25use Apie\Core\ValueObjects\Utils;
26use Apie\Serializer\ValueObjects\SerializedPhpObject;
27
28#[FakeCount(0)]
29class AuditLog implements EntityInterface, RequiresPermissionsInterface
30{
31    private AuditLogIdentifier $id;
32
33    private PermissionList $permissionSnapshot;
34
35    private EntitySnapshotInstance $snapshot;
36
37    // separate properties for optimization in the database
38    private readonly ?AuditCreate $createEvent;
39    private readonly ?AuditModified $modifiedEvent;
40    private readonly ?AuditRemoved $removedEvent;
41    private readonly ?AuditRead $readEvent;
42    private readonly ?AuditMethodCalled $methodCalledEvent;
43    private readonly ?AuditMigration $migrationEvent;
44
45    private const EVENT_MAPPING = [
46        AuditCreate::class => 'createEvent',
47        AuditModified::class => 'modifiedEvent',
48        AuditRemoved::class => 'removedEvent',
49        AuditRead::class => 'readEvent',
50        AuditMethodCalled::class=> 'methodCalledEvent',
51        AuditMigration::class => 'migrationEvent'
52    ];
53
54    #[StaticCheck(new AlwaysDisabled())]
55    public function __construct(
56        private readonly IdFriendlyEntityReference $reference,
57        private readonly SerializedPhpObject $serializedProperties,
58        AuditEvent $event,
59        #[Context('_ignored')]
60        private readonly ?SerializedPhpObject $createdBy = null,
61    ) {
62        $this->id = new AuditLogIdentifier($reference, microtime(true));
63        $object = $serializedProperties->toPhpObject();
64
65        $this->snapshot = EntitySnapshot::createFrom($object);
66        $this->permissionSnapshot = $object instanceof RequiresPermissionsInterface ? $object->getRequiredPermissions() : new PermissionList();
67        foreach (self::EVENT_MAPPING as $class => $property) {
68            $this->$property = ($event instanceof $class) ? $event : null;
69        }
70    }
71
72    #[SearchFilterOption(enabled: false)]
73    public function getDescription(
74        ApieTranslatorInterface $translator,
75        ApieContext $context
76    ): NonEmptyString {
77        $context = $context->withContext(AuditLog::class, $this);
78        foreach (self::EVENT_MAPPING as $property) {
79            if ($this->$property !== null) {
80                return $this->$property->getTranslation($translator, $context);
81            }
82        }
83        return NonEmptyString::fromNative(
84            $translator->getGeneralTranslation(
85                $context,
86                new TranslationString('audit_log.unknown_event')
87            )
88        );
89    }
90
91    public function getEvent(): AuditLogEvent
92    {
93        foreach (self::EVENT_MAPPING as $property) {
94            if ($this->$property !== null) {
95                return $this->$property->getEvent();
96            }
97        }
98        throw new \LogicException('Unknown event type');
99    }
100
101    public function getCreatedBy(): ?NonEmptyString
102    {
103        $object = $this->createdBy?->toPhpObject();
104        if ($object === null) {
105            return null;
106        }
107        if ($object instanceof EntityInterface) {
108            return NonEmptyString::fromNative(Utils::toString($object->getId()));
109        }
110
111        return NonEmptyString::fromNative(Utils::toString($object));
112
113    }
114
115    public function getRequiredPermissions(): PermissionList
116    {
117        $object = $this->serializedProperties->toPhpObject();
118        if ($object instanceof RequiresPermissionsInterface) {
119            return $object->getRequiredPermissions();
120        }
121
122        return $this->permissionSnapshot;
123    }
124
125    public function getId(): AuditLogIdentifier
126    {
127        return $this->id;
128    }
129
130    public function getReference(): IdFriendlyEntityReference
131    {
132        return $this->reference;
133    }
134
135    public function getData(): EntityInterface|EntitySnapshotInstance
136    {
137        $entity = $this->serializedProperties->toPhpObject();
138        if ($entity instanceof EntityInterface) {
139            return $entity;
140        }
141        return $this->snapshot;
142    }
143}