Issues (590)

src/Behaviors/Versionable.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Bdf\Prime\Behaviors;
4
5
use Bdf\Prime\Mapper\Builder\FieldBuilder;
6
use Bdf\Prime\Repository\RepositoryEventsSubscriberInterface;
7
use Bdf\Prime\Repository\RepositoryInterface;
8
9
/**
10
 * Versionable
11
 *
12
 * The versionable behavior allows you to keep an history of your model objects.
13
 *
14
 * @template E as object
15
 * @extends Behavior<E>
16
 */
17
class Versionable extends Behavior
18
{
19
    public const COLUMN_NAME = 'version';
20
21
    /**
22
     * The version repository className
23
     *
24
     * @var string
25
     */
26
    protected $versionClass;
27
28
    /**
29
     * Allow version deletion
30
     *
31
     * @var boolean
32
     */
33
    protected $allowDeletion;
34
35
    /**
36
     * Version table name
37
     *
38
     * @var string
39
     */
40
    protected $tableName;
41
42
    /**
43
     * Versionable constructor.
44
     *
45
     * @param string $versionClass
46
     * @param bool   $allowDeletion
47
     */
48 1
    public function __construct($versionClass, $allowDeletion = false)
49
    {
50 1
        $this->versionClass = $versionClass;
51 1
        $this->allowDeletion = $allowDeletion;
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57 1
    public function changeSchema(FieldBuilder $builder): void
58
    {
59 1
        $builder->integer(self::COLUMN_NAME, 0);
60
    }
61
62
    /**
63
     * Before insert
64
     *
65
     * we increment version number on entity
66
     *
67
     * @param E $entity
0 ignored issues
show
The type Bdf\Prime\Behaviors\E was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
68
     * @param RepositoryInterface<E> $repository
69
     *
70
     * @return void
71
     */
72 6
    public function beforeInsert($entity, RepositoryInterface $repository): void
73
    {
74 6
        $this->incrementVersion($entity, $repository);
75
    }
76
77
    /**
78
     * After insert
79
     *
80
     * we historicize entity
81
     *
82
     * @param E $entity
83
     * @param RepositoryInterface<E> $repository
84
     * @param int $count
85
     *
86
     * @return void
87
     */
88 6
    public function afterInsert($entity, RepositoryInterface $repository, int $count): void
89
    {
90 6
        if ($count != 0) {
91 6
            $this->insertVersion($entity, $repository);
92
        }
93
    }
94
95
    /**
96
     * Before update
97
     *
98
     * we increment version number on entity
99
     *
100
     * @param E $entity
101
     * @param RepositoryInterface<E> $repository
102
     * @param null|\ArrayObject $attributes
103
     *
104
     * @return void
105
     */
106 5
    public function beforeUpdate($entity, RepositoryInterface $repository, $attributes): void
107
    {
108 5
        if ($attributes !== null) {
109 1
            $attributes[] = self::COLUMN_NAME;
110
        }
111
112 5
        $this->incrementVersion($entity, $repository);
113
    }
114
115
    /**
116
     * After update
117
     *
118
     * we historicize entity
119
     *
120
     * @param E $entity
121
     * @param RepositoryInterface<E> $repository
122
     * @param int $count
123
     *
124
     * @return void
125
     */
126 5
    public function afterUpdate($entity, RepositoryInterface $repository, int $count): void
127
    {
128 5
        if ($count != 0) {
129 5
            $this->insertVersion($entity, $repository);
130
        }
131
    }
132
133
    /**
134
     * Remove entity versions
135
     *
136
     * @param E $entity
137
     * @param RepositoryInterface<E> $repository
138
     *
139
     * @return void
140
     */
141 1
    public function deleteAllVersions($entity, RepositoryInterface $repository): void
142
    {
143 1
        $queries = $repository->repository($this->versionClass)->queries();
144 1
        $criteria = $repository->mapper()->primaryCriteria($entity);
145
146 1
        if ($query = $queries->keyValue($criteria)) {
147 1
            $query->delete();
148
        } else {
149
            $queries->builder()->where($criteria)->delete();
150
        }
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156 1
    public function subscribe(RepositoryEventsSubscriberInterface $notifier): void
157
    {
158 1
        $notifier->inserting([$this, 'beforeInsert']);
159 1
        $notifier->inserted([$this, 'afterInsert']);
160
161 1
        $notifier->updating([$this, 'beforeUpdate']);
162 1
        $notifier->updated([$this, 'afterUpdate']);
163
164 1
        if ($this->allowDeletion) {
165 1
            $notifier->deleted([$this, 'deleteAllVersions']);
166
        }
167
    }
168
169
    /**
170
     * Increment version number on entity
171
     *
172
     * @param E $entity
173
     * @param RepositoryInterface<E> $repository
174
     *
175
     * @return void
176
     */
177 6
    protected function incrementVersion($entity, RepositoryInterface $repository): void
178
    {
179 6
        $mapper = $repository->mapper();
180
181 6
        $mapper->hydrateOne(
182 6
            $entity,
183 6
            self::COLUMN_NAME,
184 6
            $mapper->extractOne($entity, self::COLUMN_NAME) + 1
185 6
        );
186
    }
187
188
    /**
189
     * Historicize entity
190
     *
191
     * @param E $entity
192
     * @param RepositoryInterface<E> $repository
193
     *
194
     * @return void
195
     */
196 6
    protected function insertVersion($entity, RepositoryInterface $repository): void
197
    {
198 6
        $repository->repository($this->versionClass)->insert($entity);
199
    }
200
}
201