Passed
Push — master ( 4b3d26...06dcf5 )
by Enjoys
12:36 queued 13s
created

Multiline::looksLikeMultilineStart()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 3
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
6
namespace Enjoys\Dotenv\Parser\Lines;
7
8
9
final class Multiline
10
{
11
12
    /**
13
     * @var string[]
14
     */
15
    private array $output = [];
16
17
    /**
18
     * @param string[] $rawLines
19
     */
20 53
    private function __construct(private array $rawLines)
21
    {
22
    }
23
24
    /**
25
     * @param string[] $rawLines
26
     * @return string[]
27
     */
28 53
    public static function handle(array $rawLines): array
29
    {
30 53
        $linesHandler = new self($rawLines);
31 53
        $linesHandler->process();
32 53
        return $linesHandler->getOutput();
33
    }
34
35
36
    /**
37
     * @return string[]
38
     */
39 53
    private function getOutput(): array
40
    {
41 53
        return $this->output;
42
    }
43
44 53
    private function process(): void
45
    {
46 53
        $multiline = false;
47 53
        $multilineBuffer = [];
48
49 53
        foreach ($this->rawLines as $line) {
50
            /** @psalm-suppress MixedArgumentTypeCoercion */
51 53
            [$multiline, $line, $multilineBuffer] = $this->multilineProcess($multiline, $line, $multilineBuffer);
52
53 53
            if (!$multiline) {
54 53
                $this->output[] = $line;
55
            }
56
        }
57
    }
58
59
    /**
60
     * @param bool $multiline
61
     * @param string $line
62
     * @param string[] $buffer
63
     * @return array{0: bool, 1: string, 2: array}
64
     */
65 53
    private function multilineProcess(bool $multiline, string $line, array $buffer): array
66
    {
67 53
        $_started = false;
68
69 53
        if ($multiline === false && $_started = $this->looksLikeMultilineStart($line)) {
70 4
            $multiline = true;
71
        }
72
73 53
        if ($multiline) {
74 4
            $buffer[] = $line;
75
76 4
            if ($this->looksLikeMultilineStop($line, $_started)) {
77 4
                $multiline = false;
78 4
                $line = \implode("\\n", $buffer);
79 4
                $buffer = [];
80
            }
81
        }
82
83 53
        return [$multiline, $line, $buffer];
84
    }
85
86 53
    private function looksLikeMultilineStart(string $line): bool
87
    {
88 53
        if (str_contains($line, '="') && !$this->looksLikeMultilineStop($line, true)) {
89 4
            return true;
90
        }
91 53
        return false;
92
    }
93
94 18
    private function looksLikeMultilineStop(string $line, bool $started): bool
95
    {
96 18
        if ($line === '"') {
97 1
            return true;
98
        }
99
100 18
        $result = \preg_match_all('/(?=([^\\\\]"))/', \str_replace('\\\\', '', $line));
101 18
        return $started ? $result > 1 : $result >= 1;
102
    }
103
104
}
105