Completed
Push — master ( cdeef2...f03c61 )
by Justin
03:14
created

LineFormatter::convertToString()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 7
nc 4
nop 1
dl 0
loc 15
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the Monolog package.
5
 *
6
 * (c) Jordi Boggiano <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Monolog\Formatter;
13
14
/**
15
 * Formats incoming records into a one-line string
16
 *
17
 * This is especially useful for logging to files
18
 *
19
 * @author Jordi Boggiano <[email protected]>
20
 * @author Christophe Coevoet <[email protected]>
21
 */
22
class LineFormatter extends NormalizerFormatter
23
{
24
    const SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n";
25
26
    protected $format;
27
    protected $allowInlineLineBreaks;
28
    protected $ignoreEmptyContextAndExtra;
29
    protected $includeStacktraces;
30
31
    /**
32
     * @param string $format                     The format of the message
33
     * @param string $dateFormat                 The format of the timestamp: one supported by DateTime::format
34
     * @param bool   $allowInlineLineBreaks      Whether to allow inline line breaks in log entries
35
     * @param bool   $ignoreEmptyContextAndExtra
36
     */
37
    public function __construct($format = null, $dateFormat = null, $allowInlineLineBreaks = false, $ignoreEmptyContextAndExtra = false)
38
    {
39
        $this->format = $format ?: static::SIMPLE_FORMAT;
40
        $this->allowInlineLineBreaks = $allowInlineLineBreaks;
41
        $this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra;
42
        parent::__construct($dateFormat);
43
    }
44
45
    public function includeStacktraces($include = true)
46
    {
47
        $this->includeStacktraces = $include;
48
        if ($this->includeStacktraces) {
49
            $this->allowInlineLineBreaks = true;
50
        }
51
    }
52
53
    public function allowInlineLineBreaks($allow = true)
54
    {
55
        $this->allowInlineLineBreaks = $allow;
56
    }
57
58
    public function ignoreEmptyContextAndExtra($ignore = true)
59
    {
60
        $this->ignoreEmptyContextAndExtra = $ignore;
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    public function format(array $record)
67
    {
68
        $vars = parent::format($record);
69
70
        $output = $this->format;
71
72
        foreach ($vars['extra'] as $var => $val) {
73
            if (false !== strpos($output, '%extra.'.$var.'%')) {
74
                $output = str_replace('%extra.'.$var.'%', $this->stringify($val), $output);
75
                unset($vars['extra'][$var]);
76
            }
77
        }
78
79
80
        foreach ($vars['context'] as $var => $val) {
81
            if (false !== strpos($output, '%context.'.$var.'%')) {
82
                $output = str_replace('%context.'.$var.'%', $this->stringify($val), $output);
83
                unset($vars['context'][$var]);
84
            }
85
        }
86
87
        if ($this->ignoreEmptyContextAndExtra) {
88
            if (empty($vars['context'])) {
89
                unset($vars['context']);
90
                $output = str_replace('%context%', '', $output);
91
            }
92
93
            if (empty($vars['extra'])) {
94
                unset($vars['extra']);
95
                $output = str_replace('%extra%', '', $output);
96
            }
97
        }
98
99
        foreach ($vars as $var => $val) {
100
            if (false !== strpos($output, '%'.$var.'%')) {
101
                $output = str_replace('%'.$var.'%', $this->stringify($val), $output);
102
            }
103
        }
104
105
        // remove leftover %extra.xxx% and %context.xxx% if any
106
        if (false !== strpos($output, '%')) {
107
            $output = preg_replace('/%(?:extra|context)\..+?%/', '', $output);
108
        }
109
110
        return $output;
111
    }
112
113
    public function formatBatch(array $records)
114
    {
115
        $message = '';
116
        foreach ($records as $record) {
117
            $message .= $this->format($record);
118
        }
119
120
        return $message;
121
    }
122
123
    public function stringify($value)
124
    {
125
        return $this->replaceNewlines($this->convertToString($value));
126
    }
127
128
    protected function normalizeException($e)
129
    {
130
        // TODO 2.0 only check for Throwable
131
        if (!$e instanceof \Exception && !$e instanceof \Throwable) {
132
            throw new \InvalidArgumentException('Exception/Throwable expected, got '.gettype($e).' / '.get_class($e));
133
        }
134
135
        $previousText = '';
136
        if ($previous = $e->getPrevious()) {
137
            do {
138
                $previousText .= ', '.get_class($previous).'(code: '.$previous->getCode().'): '.$previous->getMessage().' at '.$previous->getFile().':'.$previous->getLine();
139
            } while ($previous = $previous->getPrevious());
140
        }
141
142
        $str = '[object] ('.get_class($e).'(code: '.$e->getCode().'): '.$e->getMessage().' at '.$e->getFile().':'.$e->getLine().$previousText.')';
143
        if ($this->includeStacktraces) {
144
            $str .= "\n[stacktrace]\n".$e->getTraceAsString()."\n";
145
        }
146
147
        return $str;
148
    }
149
150
    protected function convertToString($data)
151
    {
152
        if (null === $data || is_bool($data)) {
153
            return var_export($data, true);
154
        }
155
156
        if (is_scalar($data)) {
157
            return (string) $data;
158
        }
159
160
        if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
161
            return $this->toJson($data, true);
162
        }
163
164
        return str_replace('\\/', '/', @json_encode($data));
165
    }
166
167
    protected function replaceNewlines($str)
168
    {
169
        if ($this->allowInlineLineBreaks) {
170
            if (0 === strpos($str, '{')) {
171
                return str_replace(array('\r', '\n'), array("\r", "\n"), $str);
172
            }
173
174
            return $str;
175
        }
176
177
        return str_replace(array("\r\n", "\r", "\n"), ' ', $str);
178
    }
179
}
180