Completed
Pull Request — 5.6 (#2830)
by Jeroen
14:14
created

Service/EntityVersionLockService.php (1 issue)

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\EntityVersionLock;
8
use Kunstmaan\AdminListBundle\Entity\LockableEntity;
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 int
21
     */
22
    private $threshold;
23
24
    /**
25
     * @var bool
26
     */
27
    private $lockEnabled;
28
29 6
    public function __construct(ObjectManager $em, $threshold, $lockEnabled)
30
    {
31 6
        $this->setObjectManager($em);
32 6
        $this->setThreshold($threshold);
33 6
        $this->setLockEnabled($lockEnabled);
34 6
    }
35
36
    /**
37
     * @return bool
38
     */
39 3
    public function isEntityBelowThreshold(LockableEntityInterface $entity)
40
    {
41
        /** @var LockableEntity $lockable */
42 3
        $lockable = $this->getLockableEntity($entity, false);
43
44 3
        if ($this->lockEnabled && $lockable->getId() !== null) {
45 2
            $now = new \DateTime();
46 2
            $thresholdDate = clone $lockable->getUpdated();
47 2
            $thresholdDate->add(new \DateInterval('PT' . $this->threshold . 'S'));
48
49 2
            return $thresholdDate > $now;
50
        }
51
52 1
        return false;
53
    }
54
55
    /**
56
     * @return bool
57
     */
58 2
    public function isEntityLocked(User $user, LockableEntityInterface $entity)
59
    {
60
        /** @var LockableEntity $lockable */
61 2
        $lockable = $this->getLockableEntity($entity);
62
63 2
        if ($this->lockEnabled) {
64 2
            $this->removeExpiredLocks($lockable);
65 2
            $locks = $this->getEntityVersionLocksByLockableEntity($lockable, $user);
66
67 2
            if ($locks === null || !\count($locks)) {
68 1
                $this->createEntityVersionLock($user, $lockable);
69
70 1
                $lockable->setUpdated(new \DateTime());
71 1
                $this->objectManager->flush();
72
73 1
                return false;
74
            }
75
76 1
            return true;
77
        }
78
79
        return false;
80
    }
81
82
    /**
83
     * When editing the entity, create a new entity translation lock.
84
     */
85 1
    protected function createEntityVersionLock(User $user, LockableEntity $entity)
86
    {
87
        /** @var EntityVersionLock $lock */
88 1
        $lock = $this->objectManager->getRepository(EntityVersionLock::class)->findOneBy([
89 1
            'owner' => $user->getUsername(),
90 1
            'lockableEntity' => $entity,
91
        ]);
92 1
        if (!$lock) {
93
            $lock = new EntityVersionLock();
94
        }
95 1
        $lock->setOwner($user->getUsername());
96 1
        $lock->setLockableEntity($entity);
97 1
        $lock->setCreatedAt(new \DateTime());
98 1
        $this->objectManager->persist($lock);
99 1
        $this->objectManager->flush();
100 1
    }
101
102
    /**
103
     * @param User $userToExclude
104
     *
105
     * @return array
106
     */
107 1
    public function getUsersWithEntityVersionLock(LockableEntityInterface $entity, User $userToExclude = null)
108
    {
109
        /** @var LockableEntity $lockable */
110 1
        $lockable = $this->getLockableEntity($entity);
111
112 1
        return  array_reduce(
113 1
            $this->getEntityVersionLocksByLockableEntity($lockable, $userToExclude),
114
            function ($return, EntityVersionLock $item) {
115 1
                $return[] = $item->getOwner();
116
117 1
                return $return;
118 1
            },
119 1
            []
120
        );
121
    }
122
123 2
    protected function removeExpiredLocks(LockableEntity $entity)
124
    {
125 2
        $locks = $this->objectManager->getRepository(EntityVersionLock::class)->getExpiredLocks($entity, $this->threshold);
126 2
        foreach ($locks as $lock) {
127 2
            $this->objectManager->remove($lock);
128
        }
129 2
    }
130
131
    /**
132
     * When editing an entity, check if there is a lock for this entity.
133
     *
134
     * @param User $userToExclude
135
     *
136
     * @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...
137
     */
138 3
    protected function getEntityVersionLocksByLockableEntity(LockableEntity $entity, User $userToExclude = null)
139
    {
140
        /** @var EntityVersionLockRepository $objectRepository */
141 3
        $objectRepository = $this->objectManager->getRepository(EntityVersionLock::class);
142
143 3
        return $objectRepository->getLocksForLockableEntity($entity, $this->threshold, $userToExclude);
144
    }
145
146
    /**
147
     * Get or create a LockableEntity for an entity with LockableEntityInterface
148
     *
149
     * @return LockableEntity
150
     */
151 6
    protected function getLockableEntity(LockableEntityInterface $entity, $create = true)
152
    {
153
        /** @var LockableEntity $lockable */
154 6
        $lockable = $this->objectManager->getRepository(LockableEntity::class)->getOrCreate($entity->getId(), \get_class($entity));
155
156 6
        if ($create === true && $lockable->getId() === null) {
157
            $this->objectManager->persist($lockable);
158
            $this->objectManager->flush();
159
        }
160
161 6
        return $lockable;
162
    }
163
164
    /**
165
     * @param ObjectManager $objectManager
166
     */
167 6
    public function setObjectManager($objectManager)
168
    {
169 6
        $this->objectManager = $objectManager;
170 6
    }
171
172
    /**
173
     * @param int $threshold
174
     */
175 6
    public function setThreshold($threshold)
176
    {
177 6
        $this->threshold = $threshold;
178 6
    }
179
180
    /**
181
     * @param bool lockEnabled
182
     */
183 6
    public function setLockEnabled($lockEnabled)
184
    {
185 6
        $this->lockEnabled = $lockEnabled;
186 6
    }
187
}
188