ElasticaLoggableListener::getConfiguration()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 2
dl 0
loc 9
ccs 0
cts 5
cp 0
crap 6
rs 9.6666
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Basster\ElasticaLoggable\Listener;
5
6
use Basster\ElasticaLoggable\Entity\Activity;
7
use Doctrine\Common\EventArgs;
8
use Doctrine\Common\Persistence\ObjectManager;
9
use Elastica\Document;
10
use Elastica\Type;
11
use Gedmo\Loggable\LoggableListener;
12
use Gedmo\Loggable\Mapping\Event\LoggableAdapter;
13
use Gedmo\Tool\Wrapper\AbstractWrapper;
14
15
/**
16
 * Class ElasticaLoggableListener.
17
 */
18
class ElasticaLoggableListener extends LoggableListener
19
{
20
    /** @var \Elastica\Type */
21
    private $type;
22
23
    /** @var   */
24
    private $activities;
25
26
    /**
27
     * ElasticaLoggableListener constructor.
28
     *
29
     * @param \Elastica\Type $type
30
     */
31
    public function __construct(Type $type)
32
    {
33
        parent::__construct();
34
        $this->type = $type;
35
        $this->activities = [];
36
    }
37
38
    public function getSubscribedEvents(): array
39
    {
40
        $subscribedEvents = parent::getSubscribedEvents();
41
        $subscribedEvents[] = 'postFlush';
42
43
        return $subscribedEvents;
44
    }
45
46
    public function postFlush(): void
47
    {
48
        foreach ($this->activities as $activity) {
49
            $this->persist($activity);
50
        }
51
    }
52
53
    /** {@inheritdoc} */
54
    public function getConfiguration(ObjectManager $objectManager, $class): array
55
    {
56
        if ($config = parent::getConfiguration($objectManager, $class)) {
57
            $config = array_merge($config, [
58
                'logEntryClass' => Activity::class,
59
            ]);
60
        }
61
62
        return $config;
63
    }
64
65
    public function postPersist(EventArgs $args): void
66
    {
67
        $ea = $this->getEventAdapter($args);
68
        $object = $ea->getObject();
69
        $om = $ea->getObjectManager();
70
        $oid = spl_object_hash($object);
71
        $uow = $om->getUnitOfWork();
0 ignored issues
show
Bug introduced by
The method getUnitOfWork() does not exist on Doctrine\Common\Persistence\ObjectManager. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

71
        /** @scrutinizer ignore-call */ 
72
        $uow = $om->getUnitOfWork();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
72
        if ($this->pendingLogEntryInserts && array_key_exists($oid, $this->pendingLogEntryInserts)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->pendingLogEntryInserts of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
73
            $wrapped = AbstractWrapper::wrap($object, $om);
74
75
            /** @var Activity $logEntry */
76
            $logEntry = $this->pendingLogEntryInserts[$oid];
77
78
            $id = $wrapped->getIdentifier();
79
            $logEntry->setObjectId($id);
80
            $ea->setOriginalObjectProperty($uow, spl_object_hash($logEntry), 'objectId', $id);
81
            unset($this->pendingLogEntryInserts[$oid]);
82
        }
83
        if ($this->pendingRelatedObjects && array_key_exists($oid, $this->pendingRelatedObjects)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->pendingRelatedObjects of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
84
            $wrapped = AbstractWrapper::wrap($object, $om);
85
            $identifiers = $wrapped->getIdentifier(false);
86
            foreach ($this->pendingRelatedObjects[$oid] as $props) {
87
                /** @var Activity $logEntry */
88
                $logEntry = $props['log'];
89
                $data[$props['field']] = $identifiers;
90
91
                $logEntry->setData($data);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $data seems to be defined later in this foreach loop on line 89. Are you sure it is defined here?
Loading history...
92
93
                $ea->setOriginalObjectProperty($uow, spl_object_hash($logEntry), 'data', $data);
94
            }
95
            unset($this->pendingRelatedObjects[$oid]);
96
        }
97
    }
98
99
    protected function createLogEntry($action, $object, LoggableAdapter $ea)
100
    {
101
        $om = $ea->getObjectManager();
102
        $wrapped = AbstractWrapper::wrap($object, $om);
103
        $meta = $wrapped->getMetadata();
104
105
        // Filter embedded documents
106
        if (isset($meta->isEmbeddedDocument) && $meta->isEmbeddedDocument) {
107
            return null;
108
        }
109
110
        if ($config = $this->getConfiguration($om, $meta->name)) {
111
            $logEntry = new Activity($action, $this->username, $meta->name);
112
113
            // check for the availability of the primary key
114
            if (self::ACTION_CREATE === $action && $ea->isPostInsertGenerator($meta)) {
115
                $this->pendingLogEntryInserts[spl_object_hash($object)] = $logEntry;
116
            } else {
117
                $logEntry->setObjectId($wrapped->getIdentifier());
118
            }
119
            $newValues = [];
120
            if (self::ACTION_REMOVE !== $action && isset($config['versioned'])) {
121
                $logEntry->setChangeSet($ea->getObjectChangeSet($om->getUnitOfWork(), $object));
122
                $newValues = $this->getObjectChangeSetData($ea, $object, $logEntry);
123
                $logEntry->setData($newValues);
124
            }
125
126
            if (self::ACTION_UPDATE === $action && 0 === count($newValues)) {
127
                return null;
128
            }
129
130
            $this->prePersistLogEntry($logEntry, $object);
131
132
            $this->store($logEntry);
133
134
            return $logEntry;
135
        }
136
137
        return null;
138
    }
139
140
    private function store(Activity $activity)
141
    {
142
        $this->activities[] = $activity;
143
    }
144
145
    private function persist(Activity $logEntry)
146
    {
147
        $document = new Document();
148
        $document->setData($logEntry->toArray());
149
150
        $this->type->addDocument($document);
151
        $this->type->getIndex()->refresh();
152
    }
153
}
154