Completed
Pull Request — 5.0 (#2104)
by Kevin
13:45 queued 04:21
created

Service/EntityVersionLockService.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\AdminListBundle\Service;
4
5
use Doctrine\Common\Persistence\ObjectManager;
6
use FOS\UserBundle\Model\User;
7
use Kunstmaan\AdminListBundle\Entity\LockableEntity;
8
use Kunstmaan\AdminListBundle\Entity\EntityVersionLock;
9
use Kunstmaan\AdminListBundle\Entity\LockableEntityInterface;
10
use Kunstmaan\AdminListBundle\Repository\EntityVersionLockRepository;
11
12
class EntityVersionLockService
13
{
14
    /**
15
     * @var ObjectManager
16
     */
17
    private $objectManager;
18
19
    /**
20
     * @var integer
21
     */
22
    private $threshold;
23
24
    /**
25
     * @var boolean
26
     */
27
    private $lockEnabled;
28
29
    public function __construct(ObjectManager $em, $threshold, $lockEnabled)
30
    {
31
        $this->setObjectManager($em);
32
        $this->setThreshold($threshold);
33
        $this->setLockEnabled($lockEnabled);
34
    }
35
36
    /**
37
     * @param LockableEntityInterface $entity
38
     * @return bool
39
     */
40
    public function isEntityBelowThreshold(LockableEntityInterface $entity)
41
    {
42
        /** @var LockableEntity $lockable */
43
        $lockable = $this->getLockableEntity($entity, false);
44
45
        if ($this->lockEnabled && $lockable->getId() !== null) {
46
            $now = new \DateTime();
47
            $thresholdDate = clone $lockable->getUpdated();
48
            $thresholdDate->add(new \DateInterval("PT".$this->threshold."S"));
49
50
            return $thresholdDate > $now;
51
        }
52
        return false;
53
    }
54
55
    /**
56
     * @param User $user
57
     * @param LockableEntityInterface $entity
58
     * @return bool
59
     */
60
    public function isEntityLocked(User $user, LockableEntityInterface $entity)
61
    {
62
        /** @var LockableEntity $lockable */
63
        $lockable = $this->getLockableEntity($entity);
64
65
        if ($this->lockEnabled) {
66
            $this->removeExpiredLocks($lockable);
67
            $locks = $this->getEntityVersionLocksByLockableEntity($lockable, $user);
68
69
            if($locks === null || !count($locks)) {
70
                $this->createEntityVersionLock($user, $lockable);
71
72
                $lockable->setUpdated(new \DateTime());
73
                $this->objectManager->flush();
74
75
                return false;
76
            }
77
            return true;
78
        }
79
        return false;
80
    }
81
82
    /**
83
     * When editing the entity, create a new entity translation lock.
84
     *
85
     * @param User $user
86
     * @param LockableEntity $entity
87
     */
88
    protected function createEntityVersionLock(User $user, LockableEntity $entity)
89
    {
90
        /** @var EntityVersionLock $lock */
91
        $lock = $this->objectManager->getRepository('KunstmaanAdminListBundle:EntityVersionLock')->findOneBy([
92
            'owner' => $user->getUsername(),
93
            'lockableEntity' => $entity
94
        ]);
95
        if (! $lock) {
96
            $lock = new EntityVersionLock();
97
        }
98
        $lock->setOwner($user->getUsername());
99
        $lock->setLockableEntity($entity);
100
        $lock->setCreatedAt(new \DateTime());
101
        $this->objectManager->persist($lock);
102
        $this->objectManager->flush();
103
    }
104
105
    /**
106
     * @param LockableEntityInterface $entity
107
     * @param User $userToExclude
0 ignored issues
show
Should the type for parameter $userToExclude not be null|User?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
108
     * @return array
109
     */
110
    public function getUsersWithEntityVersionLock(LockableEntityInterface $entity, User $userToExclude = null)
111
    {
112
        /** @var LockableEntity $lockable */
113
        $lockable = $this->getLockableEntity($entity);
114
115
        return  array_reduce(
116
            $this->getEntityVersionLocksByLockableEntity($lockable, $userToExclude),
117
            function ($return, EntityVersionLock $item) {
118
                $return[] = $item->getOwner();
119
                return $return;
120
            },
121
            []
122
        );
123
    }
124
125
    /**
126
     * @param LockableEntity $entity
127
     */
128
    protected function removeExpiredLocks(LockableEntity $entity)
129
    {
130
        $locks = $this->objectManager->getRepository('KunstmaanAdminListBundle:EntityVersionLock')->getExpiredLocks($entity, $this->threshold);
131
        foreach ($locks as $lock) {
132
            $this->objectManager->remove($lock);
133
        }
134
    }
135
136
    /**
137
     * When editing an entity, check if there is a lock for this entity.
138
     *
139
     * @param LockableEntity $entity
140
     * @param User $userToExclude
0 ignored issues
show
Should the type for parameter $userToExclude not be null|User?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
141
     * @return EntityVersionLock[]
0 ignored issues
show
Should the return type not be \Kunstmaan\AdminListBund...ory\EntityVersionLock[]?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
142
     */
143
    protected function getEntityVersionLocksByLockableEntity(LockableEntity $entity, User $userToExclude = null)
144
    {
145
        /** @var EntityVersionLockRepository $objectRepository */
146
        $objectRepository = $this->objectManager->getRepository('KunstmaanAdminListBundle:EntityVersionLock');
147
        return $objectRepository->getLocksForLockableEntity($entity, $this->threshold, $userToExclude);
148
    }
149
150
    /**
151
     * Get or create a LockableEntity for an entity with LockableEntityInterface
152
     *
153
     * @param LockableEntityInterface $entity
154
     *
155
     * @return LockableEntity
156
     */
157
    protected function getLockableEntity(LockableEntityInterface $entity, $create = true)
158
    {
159
        /** @var LockableEntity $lockable */
160
        $lockable = $this->objectManager->getRepository('KunstmaanAdminListBundle:LockableEntity')->getOrCreate($entity->getId(), get_class($entity));
161
162
        if ($create === true && $lockable->getId() === null) {
163
            $this->objectManager->persist($lockable);
164
            $this->objectManager->flush();
165
        }
166
167
        return $lockable;
168
    }
169
170
    /**
171
     * @param ObjectManager $objectManager
172
     */
173
    public function setObjectManager($objectManager)
174
    {
175
        $this->objectManager = $objectManager;
176
    }
177
178
    /**
179
     * @param integer $threshold
180
     */
181
    public function setThreshold($threshold)
182
    {
183
        $this->threshold = $threshold;
184
    }
185
186
    /**
187
     * @param boolean lockEnabled
188
     */
189
    public function setLockEnabled($lockEnabled)
190
    {
191
        $this->lockEnabled = $lockEnabled;
192
    }
193
}
194