Passed
Push — master ( 8a7b90...73c2aa )
by Jan
04:49
created

LogEntryRepository::getLastUser()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 15
c 0
b 0
f 0
nc 2
nop 2
dl 0
loc 23
rs 9.7666
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
7
 *
8
 * Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
9
 *
10
 * This program is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU General Public License
12
 * as published by the Free Software Foundation; either version 2
13
 * of the License, or (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
23
 */
24
25
namespace App\Repository;
26
27
use App\Entity\Base\AbstractDBElement;
28
use App\Entity\LogSystem\AbstractLogEntry;
29
use App\Entity\LogSystem\ElementCreatedLogEntry;
30
use App\Entity\LogSystem\ElementEditedLogEntry;
31
use App\Entity\UserSystem\User;
32
use Doctrine\ORM\EntityRepository;
33
use Doctrine\ORM\QueryBuilder;
34
35
class LogEntryRepository extends EntityRepository
36
{
37
    public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null)
38
    {
39
        //Emulate a target element criteria by splitting it manually in the needed criterias
40
        if (isset($criteria['target']) && $criteria['target'] instanceof AbstractDBElement) {
41
            /** @var AbstractDBElement $element */
42
            $element = $criteria['target'];
43
            $criteria['target_id'] = $element->getID();
44
            $criteria['target_type'] = AbstractLogEntry::targetTypeClassToID(get_class($element));
45
            unset($criteria['target']);
46
        }
47
48
        return parent::findBy($criteria, $orderBy, $limit, $offset); // TODO: Change the autogenerated stub
49
    }
50
51
    /**
52
     * Find log entries associated with the given element (the history of the element).
53
     *
54
     * @param AbstractDBElement $element The element for which the history should be generated
55
     * @param string    $order   By default newest entries are shown first. Change this to ASC to show oldest entries first.
56
     * @param null      $limit
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $limit is correct as it would always require null to be passed?
Loading history...
57
     * @param null      $offset
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $offset is correct as it would always require null to be passed?
Loading history...
58
     *
59
     * @return AbstractLogEntry[]
60
     */
61
    public function getElementHistory(AbstractDBElement $element, $order = 'DESC', $limit = null, $offset = null): array
62
    {
63
        return $this->findBy(['element' => $element], ['timestamp' => $order], $limit, $offset);
64
    }
65
66
    /**
67
     * Gets the last log entries ordered by timestamp.
68
     *
69
     * @param string $order
70
     * @param null   $limit
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $limit is correct as it would always require null to be passed?
Loading history...
71
     * @param null   $offset
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $offset is correct as it would always require null to be passed?
Loading history...
72
     *
73
     * @return array
74
     */
75
    public function getLogsOrderedByTimestamp($order = 'DESC', $limit = null, $offset = null): array
76
    {
77
        return $this->findBy([], ['timestamp' => $order], $limit, $offset);
78
    }
79
80
    /**
81
     * Gets the target element associated with the logentry.
82
     *
83
     * @param  AbstractLogEntry  $logEntry
84
     * @return AbstractDBElement|null Returns the associated DBElement or null if the log either has no target or the element
85
     *                        was deleted from DB.
86
     * @throws \Doctrine\ORM\ORMException
87
     * @throws \Doctrine\ORM\OptimisticLockException
88
     * @throws \Doctrine\ORM\TransactionRequiredException
89
     */
90
    public function getTargetElement(AbstractLogEntry $logEntry): ?AbstractDBElement
91
    {
92
        $class = $logEntry->getTargetClass();
93
        $id = $logEntry->getTargetID();
94
95
        if (null === $class || null === $id) {
96
            return null;
97
        }
98
99
        return $this->getEntityManager()->find($class, $id);
100
    }
101
102
    protected function getLastUser(AbstractDBElement $element, string $class)
103
    {
104
        $qb = $this->createQueryBuilder('log');
105
        $qb->select('log')
106
            //->where('log INSTANCE OF App\Entity\LogSystem\ElementEditedLogEntry')
107
            ->where('log INSTANCE OF ' . $class)
108
            ->andWhere('log.target_type = :target_type')
109
            ->andWhere('log.target_id = :target_id')
110
            ->orderBy('log.timestamp', 'DESC');
111
112
        $qb->setParameters([
113
                               'target_type' => AbstractLogEntry::targetTypeClassToID(get_class($element)),
114
                               'target_id' => $element->getID()
115
                           ]);
116
117
        $query = $qb->getQuery();
118
        $query->setMaxResults(1);
119
        /** @var AbstractLogEntry[] $results */
120
        $results = $query->execute();
121
        if (isset($results[0])) {
122
            return $results[0]->getUser();
123
        }
124
        return null;
125
    }
126
127
    /**
128
     * Returns the last user that has edited the given element.
129
     * @param  AbstractDBElement  $element
130
     * @return User|null A user object, or null if no user could be determined.
131
     */
132
    public function getLastEditingUser(AbstractDBElement $element): ?User
133
    {
134
        return $this->getLastUser($element, ElementEditedLogEntry::class);
135
    }
136
137
    /**
138
     * Returns the user that has created the given element.
139
     * @param  AbstractDBElement  $element
140
     * @return User|null A user object, or null if no user could be determined.
141
     */
142
    public function getCreatingUser(AbstractDBElement $element): ?User
143
    {
144
        return $this->getLastUser($element, ElementCreatedLogEntry::class);
145
    }
146
}
147