LogLevelConfiguration::getAllowedLogLevels()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 2
1
<?php
2
3
namespace Abacaphiliac\Doctrine;
4
5
use InvalidArgumentException;
6
use Psr\Log\LogLevel;
7
use ReflectionClass;
8
use function asort;
9
use function array_keys;
10
use function array_search;
11
use function array_values;
12
use function print_r;
13
use function count;
14
15
final class LogLevelConfiguration
16
{
17
    /** @var array<string, int> */
18
    private $logLevelMapping = [];
19
20 26
    public function __construct(array $logLevelMapping)
21
    {
22 26
        foreach ($logLevelMapping as $logLevel => $durationThresholdInMilliseconds) {
23 26
            $this->addLogLevelThreshold($logLevel, $durationThresholdInMilliseconds);
24
        }
25 26
    }
26
27 26
    private function addLogLevelThreshold(string $logLevel, int $durationThresholdInMilliseconds) : void
28
    {
29 26
        $this->validateLogLevel($logLevel);
30 26
        $this->logLevelMapping[$logLevel] = $durationThresholdInMilliseconds;
31 26
    }
32
33 26
    private function validateLogLevel(string $logLevel): void
34
    {
35 26
        if (! $this->isAllowedLogLevel($logLevel)) {
36 1
            throw new InvalidArgumentException(sprintf(
37 1
                'invalid LogLevel detected: "%s", please choose from: "%s"',
38
                $logLevel,
39 1
                print_r($this->getAllowedLogLevels(), true)
40
            ));
41
        }
42 26
    }
43
    
44 26
    private function isAllowedLogLevel(string $logLevel): bool
45
    {
46 26
        return in_array($logLevel, $this->getAllowedLogLevels(), true);
47
    }
48
49 26
    private function getAllowedLogLevels(): array
50
    {
51 26
        static $allowedConstants;
52
53 26
        return $allowedConstants ?: $allowedConstants = (new ReflectionClass(LogLevel::class))->getConstants();
54
    }
55
56 25
    public function getApplicableLogLevel(float $durationInSeconds): ?string
57
    {
58 25
        if ($durationInSeconds <= 0) {
59 2
            return null;
60
        }
61
62 23
        return count($this->logLevelMapping) > 0 ? $this->determineApplicableLogLevel($durationInSeconds) : null;
63
    }
64
65 23
    private function determineApplicableLogLevel(float $durationInSeconds) : ?string
66
    {
67 23
        $durationInMilliseconds = $durationInSeconds * 1000;
68
69
        //Acquire a common / non-associative array with all the thresholds
70 23
        $durationThresholds = array_values($this->logLevelMapping);
71
72
        //Append the incoming query duration in milliseconds to the array of duration thresholds
73 23
        $durationThresholds[] = $durationInMilliseconds;
74
75
        //Sort the array from low to high: the provided duration will end up somewhere between the thresholds
76 23
        asort($durationThresholds, SORT_NUMERIC);
77
78
        //A re-index is required after sorting
79 23
        $durationThresholds = array_values($durationThresholds);
80
81
        //Determine at which position the duration ended up after sorting
82 23
        $key = array_search($durationInMilliseconds, $durationThresholds, true);
83
84 23
        $logLevels = array_keys($this->logLevelMapping);
85
86 23
        return $logLevels[$key - 1] ?? null;
87
    }
88
}
89