Completed
Push — feature-20rc1 ( 008ae2 )
by Rob
16:55
created

AbstractFormat::prefixRootPackage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
/*
4
 * This file is part of the `liip/LiipImagineBundle` project.
5
 *
6
 * (c) https://github.com/liip/LiipImagineBundle/graphs/contributors
7
 *
8
 * For the full copyright and license information, please view the LICENSE.md
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Liip\ImagineBundle\Log\Formatter;
13
14
use SR\Dumper\Transformer\StringTransformer;
15
16
/**
17
 * @internal
18
 *
19
 * @author Rob Frawley 2nd <[email protected]>
20
 */
21
abstract class AbstractFormat implements FormatInterface
22
{
23
    /**
24
     * @var string
25
     */
26
    private const BREAK_SEQUENCE = '[{abc012}]';
27
28
    /**
29
     * @var string
30
     */
31
    private $rootPackageName;
32
33
    /**
34
     * @var int
35
     */
36
    private $baseIndentLevel;
37
38
    /**
39
     * @param string|null $rootPackageName
40
     * @param int         $baseIndentLevel
41
     */
42
    public function __construct(string $rootPackageName = null, int $baseIndentLevel = null)
43
    {
44
        $this->rootPackageName = $rootPackageName ?: 'imagine-bundle';
45
        $this->baseIndentLevel = $baseIndentLevel ?: 0;
46
    }
47
48
    /**
49
     * @param string      $format
50
     * @param array       $replacements
51
     * @param string|null $context
52
     * @param int         $indent
53
     *
54
     * @return string
55
     */
56
    public function format(string $format, array $replacements = [], string $context = null, int $indent = 0): string
57
    {
58
        return $this->contextualize(
59
            $this->interpolate($format, $replacements), $indent, $context
60
        );
61
    }
62
63
    /**
64
     * @param string $message
65
     * @param int    $indentLevel
66
     * @param string $indentBullet
67
     *
68
     * @return string
69
     */
70
    public function indent(string $message, int $indentLevel = 0, string $indentBullet = '>'): string
71
    {
72
        $indent = str_repeat(' ', $indentLevel * 2);
73
74
        if ($indentLevel > 0) {
75
            $indent .= sprintf('%s ', $indentBullet);
76
        }
77
78
        return $indent.$message;
79
    }
80
81
    /**
82
     * @param string $format
83
     * @param array  $replacements
84
     *
85
     * @return string
86
     */
87
    abstract protected function interpolate(string $format, array $replacements): string;
88
89
    /**
90
     * @param string[] $replacements
91
     *
92
     * @return string[]
93
     */
94
    protected function normalizeReplacements(array $replacements): array
95
    {
96
        $transformer = new StringTransformer();
97
98
        return array_map(function ($value) use ($transformer) {
99
            return $transformer($value);
100
        }, $replacements);
101
    }
102
103
    /**
104
     * @param string      $message
105
     * @param int         $indent
106
     * @param string|null $context
107
     *
108
     * @return string
109
     */
110
    private function contextualize(string $message, int $indent, string $context = null): string
111
    {
112
        $contexts = [];
113
        $stripped = $this->removeContexts($this->removeRootPackage($message), $context, $contexts);
114
115
        return $this->prefixRootPackage($this->prefixContexts($this->indent($stripped, $indent), $contexts));
116
    }
117
118
    /**
119
     * @param string      $message
120
     * @param string|null $addition
121
     * @param array       $contexts
122
     *
123
     * @return string
124
     */
125
    private function removeContexts(string $message, string $addition = null, array &$contexts = []): string
126
    {
127
        while (1 === preg_match('{^\[(?<context>[^]]+)\]}', $message, $matched)) {
128
            $message = $this->removeBlock($message, $contexts[] = $matched['context']);
129
        }
130
131
        if (null !== $addition) {
132
            $contexts[] = $addition;
133
        }
134
135
        $contexts = array_unique($contexts);
136
137
        return $message;
138
    }
139
140
    /**
141
     * @param string $message
142
     * @param array  $contexts
143
     *
144
     * @return string
145
     */
146
    private function prefixContexts(string $message, array $contexts): string
147
    {
148
        if (empty($contexts)) {
149
            return $message;
150
        }
151
152
        return sprintf('%s %s', implode(' ', array_map(function (string $c) {
153
            return $this->formatBlock($c);
154
        }, $contexts)), $message);
155
    }
156
157
    /**
158
     * @param string $message
159
     *
160
     * @return string
161
     */
162
    private function removeRootPackage(string $message): string
163
    {
164
        return $this->removeBlock($message, $this->rootPackageName);
165
    }
166
167
    /**
168
     * @param string $message
169
     *
170
     * @return string
171
     */
172
    private function prefixRootPackage(string $message): string
173
    {
174
        return sprintf('%s %s', $this->formatBlock($this->rootPackageName), $message);
175
    }
176
177
    /**
178
     * @param string $message
179
     * @param string $block
180
     *
181
     * @return string
182
     */
183
    private function removeBlock(string $message, string $block): string
184
    {
185
        $block = $this->formatBlock($block);
186
187
        if (0 === mb_strpos($message, $block)) {
188
            $message = mb_substr($message, mb_strlen($block) + 1);
189
        }
190
191
        return $message;
192
    }
193
194
    /**
195
     * @param string $block
196
     *
197
     * @return string
198
     */
199
    private function formatBlock(string $block): string
200
    {
201
        return sprintf('[%s]', trim($block));
202
    }
203
}
204