Passed
Push — master ( 0bf991...cb753f )
by Timothy
57s queued 10s
created

LogLevelConfiguration::getApplicableLogLevel()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
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 1
                $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
        return count($this->logLevelMapping) > 0 ? $this->determineApplicableLogLevel($durationInSeconds) : null;
59
    }
60
61 25
    private function determineApplicableLogLevel(float $durationInSeconds) : ?string
62
    {
63 25
        $durationInMilliseconds = $durationInSeconds * 1000;
64
65
        //Acquire a common / non-associative array with all the thresholds
66 25
        $durationThresholds = array_values($this->logLevelMapping);
67
68
        //Append the incoming query duration in milliseconds to the array of duration thresholds
69 25
        $durationThresholds[] = $durationInMilliseconds;
70
71
        //Sort the array from low to high: the provided duration will end up somewhere between the thresholds
72 25
        asort($durationThresholds, SORT_NUMERIC);
73
74
        //A re-index is required after sorting
75 25
        $durationThresholds = array_values($durationThresholds);
76
77
        //Determine at which position the duration ended up after sorting
78 25
        $key = array_search($durationInMilliseconds, $durationThresholds, true);
79
80 25
        $logLevels = array_keys($this->logLevelMapping);
81
82 25
        return $logLevels[$key - 1] ?? null;
83
    }
84
}
85