JsonDecoderLogger::jsonDecode()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 12
nc 4
nop 1
dl 0
loc 23
ccs 13
cts 13
cp 1
crap 5
rs 9.5555
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpCfdi\Finkok\Helpers;
6
7
use Psr\Log\AbstractLogger;
8
use Psr\Log\LoggerInterface;
9
10
/**
11
 * Esta clase es un adaptador para convertir un mensaje de registro (log) que está
12
 * en formato Json y es decodificado y convertido en texto a través de la función
13
 * print_r, luego pasa el mensaje al logger con el que fue construido el objeto.
14
 *
15
 * Si el mensaje no es un Json no válido entonces pasa sin convertirse.
16
 *
17
 * Tiene algunas opciones:
18
 * - alsoLogJsonMessage: Envía los dos mensajes, tanto el texto como el json al logger.
19
 * - useJsonValidateIfAvailable: Usa \json_validate() si está disponible.
20
 */
21
final class JsonDecoderLogger extends AbstractLogger implements LoggerInterface
22
{
23
    /** @var LoggerInterface */
24
    private $logger;
25
26
    /** @var bool */
27
    private $useJsonValidateIfAvailable = true;
28
29
    /** @var bool */
30
    private $alsoLogJsonMessage = false;
31
32
    /** @var bool */
33
    private $lastMessageWasJsonValid = false;
34
35 8
    public function __construct(LoggerInterface $logger)
36
    {
37 8
        $this->logger = $logger;
38
    }
39
40
    /**
41
     * Define si se utilizará la función \json_validate en caso de estar disponible.
42
     *
43
     * @param bool|null $value El nuevo estado, si se establece NULL entonces solo devuelve el espado previo.
44
     * @return bool El estado previo
45
     */
46 5
    public function setUseJsonValidateIfAvailable(bool $value = null): bool
47
    {
48 5
        $previous = $this->useJsonValidateIfAvailable;
49 5
        if (null !== $value) {
50 5
            $this->useJsonValidateIfAvailable = $value;
51
        }
52 5
        return $previous;
53
    }
54
55
    /**
56
     * Define si también se mandará el mensaje JSON al Logger.
57
     *
58
     * @param bool|null $value El nuevo estado, si se establece NULL entonces solo devuelve el espado previo.
59
     * @return bool El estado previo
60
     */
61 2
    public function setAlsoLogJsonMessage(bool $value = null): bool
62
    {
63 2
        $previous = $this->alsoLogJsonMessage;
64 2
        if (null !== $value) {
65 2
            $this->alsoLogJsonMessage = $value;
66
        }
67 2
        return $previous;
68
    }
69
70 5
    public function lastMessageWasJsonValid(): bool
71
    {
72 5
        return $this->lastMessageWasJsonValid;
73
    }
74
75
    /**
76
     * @inheritDoc
77
     * @param string|\Stringable $message
78
     * @param mixed[] $context
79
     */
80 5
    public function log($level, $message, array $context = []): void
81
    {
82 5
        $this->logger->log($level, $this->jsonDecode($message), $context);
83 5
        if ($this->lastMessageWasJsonValid && $this->alsoLogJsonMessage) {
84 1
            $this->logger->log($level, $message, $context);
85
        }
86
    }
87
88
    /** @param string|\Stringable $string */
89 5
    private function jsonDecode($string): string
90
    {
91 5
        $this->lastMessageWasJsonValid = false;
92 5
        $string = strval($string);
93
94
        // json_validate and json_decode
95 5
        if ($this->useJsonValidateIfAvailable && function_exists('\json_validate')) {
96 3
            if (\json_validate($string)) {
0 ignored issues
show
Bug introduced by
The function json_validate was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

96
            if (/** @scrutinizer ignore-call */ \json_validate($string)) {
Loading history...
97 2
                $this->lastMessageWasJsonValid = true;
98 2
                return $this->varDump(json_decode($string));
99
            }
100
101 1
            return $string;
102
        }
103
104
        // json_decode only
105 2
        $decoded = json_decode($string);
106 2
        if (JSON_ERROR_NONE === json_last_error()) {
107 1
            $this->lastMessageWasJsonValid = true;
108 1
            return $this->varDump($decoded);
109
        }
110
111 1
        return $string;
112
    }
113
114
    /** @param mixed $var */
115 3
    private function varDump($var): string
116
    {
117 3
        return print_r($var, true);
0 ignored issues
show
Bug Best Practice introduced by
The expression return print_r($var, true) could return the type true which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
118
    }
119
}
120