Passed
Push — master ( eb071b...46772c )
by Jan
05:07
created

EventLogger::log()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 24
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 7
eloc 12
c 3
b 0
f 0
nc 8
nop 1
dl 0
loc 24
rs 8.8333
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\Services\LogSystem;
26
27
use App\Entity\LogSystem\AbstractLogEntry;
28
use App\Entity\UserSystem\User;
29
use Doctrine\ORM\EntityManagerInterface;
30
use Symfony\Component\Security\Core\Security;
31
32
class EventLogger
33
{
34
    protected $minimum_log_level;
35
    protected $blacklist;
36
    protected $whitelist;
37
    protected $em;
38
    protected $security;
39
40
    public function __construct(int $minimum_log_level, array $blacklist, array $whitelist, EntityManagerInterface $em, Security $security)
41
    {
42
        $this->minimum_log_level = $minimum_log_level;
43
        $this->blacklist = $blacklist;
44
        $this->whitelist = $whitelist;
45
        $this->em = $em;
46
        $this->security = $security;
47
    }
48
49
    /**
50
     * Adds the given log entry to the Log, if the entry fullfills the global configured criterias.
51
     * The change will not be flushed yet.
52
     *
53
     * @return bool Returns true, if the event was added to log.
54
     */
55
    public function log(AbstractLogEntry $logEntry): bool
56
    {
57
        $user = $this->security->getUser();
58
        //If the user is not specified explicitly, set it to the current user
59
        if ((null === $user || $user instanceof User) && null === $logEntry->getUser()) {
60
            if (null === $user) {
0 ignored issues
show
introduced by
The condition null === $user is always true.
Loading history...
61
                $repo = $this->em->getRepository(User::class);
62
                $user = $repo->getAnonymousUser();
63
            }
64
65
            //If no anonymous user is available skip the log (needed for data fixtures)
66
            if (null === $user) {
67
                return false;
68
            }
69
            $logEntry->setUser($user);
70
        }
71
72
        if ($this->shouldBeAdded($logEntry)) {
73
            $this->em->persist($logEntry);
74
75
            return true;
76
        }
77
78
        return false;
79
    }
80
81
    /**
82
     * Adds the given log entry to the Log, if the entry fullfills the global configured criterias and flush afterwards.
83
     *
84
     * @return bool Returns true, if the event was added to log.
85
     */
86
    public function logAndFlush(AbstractLogEntry $logEntry): bool
87
    {
88
        $tmp = $this->log($logEntry);
89
        $this->em->flush();
90
91
        return $tmp;
92
    }
93
94
    public function shouldBeAdded(
95
        AbstractLogEntry $logEntry,
96
        ?int $minimum_log_level = null,
97
        ?array $blacklist = null,
98
        ?array $whitelist = null
99
    ): bool {
100
        //Apply the global settings, if nothing was specified
101
        $minimum_log_level = $minimum_log_level ?? $this->minimum_log_level;
102
        $blacklist = $blacklist ?? $this->blacklist;
103
        $whitelist = $whitelist ?? $this->whitelist;
104
105
        //Dont add the entry if it does not reach the minimum level
106
        if ($logEntry->getLevel() > $minimum_log_level) {
107
            return false;
108
        }
109
110
        //Check if the event type is black listed
111
        if (! empty($blacklist) && $this->isObjectClassInArray($logEntry, $blacklist)) {
112
            return false;
113
        }
114
115
        //Check for whitelisting
116
        if (! empty($whitelist) && ! $this->isObjectClassInArray($logEntry, $whitelist)) {
117
            return false;
118
        }
119
120
        // By default all things should be added
121
        return true;
122
    }
123
124
    /**
125
     * Check if the object type is given in the classes array. This also works for inherited types.
126
     *
127
     * @param object   $object  The object which should be checked
128
     * @param string[] $classes The list of class names that should be used for checking.
129
     *
130
     * @return bool
131
     */
132
    protected function isObjectClassInArray(object $object, array $classes): bool
133
    {
134
        //Check if the class is directly in the classes array
135
        if (in_array(get_class($object), $classes, true)) {
136
            return true;
137
        }
138
139
        //Iterate over all classes and check for inheritance
140
        foreach ($classes as $class) {
141
            if (is_a($object, $class)) {
142
                return true;
143
            }
144
        }
145
146
        return false;
147
    }
148
}
149