MessageFormatter::setTemplate()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace Guzzle\Log;
4
5
use Guzzle\Http\Curl\CurlHandle;
6
use Guzzle\Http\Message\RequestInterface;
7
use Guzzle\Http\Message\EntityEnclosingRequestInterface;
8
use Guzzle\Http\Message\Response;
9
10
/**
11
 * Message formatter used in various places in the framework
12
 *
13
 * Format messages using a template that can contain the the following variables:
14
 *
15
 * - {request}:       Full HTTP request message
16
 * - {response}:      Full HTTP response message
17
 * - {ts}:            Timestamp
18
 * - {host}:          Host of the request
19
 * - {method}:        Method of the request
20
 * - {url}:           URL of the request
21
 * - {host}:          Host of the request
22
 * - {protocol}:      Request protocol
23
 * - {version}:       Protocol version
24
 * - {resource}:      Resource of the request (path + query + fragment)
25
 * - {port}:          Port of the request
26
 * - {hostname}:      Hostname of the machine that sent the request
27
 * - {code}:          Status code of the response (if available)
28
 * - {phrase}:        Reason phrase of the response  (if available)
29
 * - {curl_error}:    Curl error message (if available)
30
 * - {curl_code}:     Curl error code (if available)
31
 * - {curl_stderr}:   Curl standard error (if available)
32
 * - {connect_time}:  Time in seconds it took to establish the connection (if available)
33
 * - {total_time}:    Total transaction time in seconds for last transfer (if available)
34
 * - {req_header_*}:  Replace `*` with the lowercased name of a request header to add to the message
35
 * - {res_header_*}:  Replace `*` with the lowercased name of a response header to add to the message
36
 * - {req_body}:      Request body
37
 * - {res_body}:      Response body
38
 */
39
class MessageFormatter
40
{
41
    const DEFAULT_FORMAT = "{hostname} {req_header_User-Agent} - [{ts}] \"{method} {resource} {protocol}/{version}\" {code} {res_header_Content-Length}";
42
    const DEBUG_FORMAT = ">>>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{curl_stderr}";
43
    const SHORT_FORMAT = '[{ts}] "{method} {resource} {protocol}/{version}" {code}';
44
45
    /**
46
     * @var string Template used to format log messages
47
     */
48
    protected $template;
49
50
    /**
51
     * @param string $template Log message template
52
     */
53
    public function __construct($template = self::DEFAULT_FORMAT)
54
    {
55
        $this->template = $template ?: self::DEFAULT_FORMAT;
56
    }
57
58
    /**
59
     * Set the template to use for logging
60
     *
61
     * @param string $template Log message template
62
     *
63
     * @return self
64
     */
65
    public function setTemplate($template)
66
    {
67
        $this->template = $template;
68
69
        return $this;
70
    }
71
72
    /**
73
     * Returns a formatted message
74
     *
75
     * @param RequestInterface $request    Request that was sent
76
     * @param Response         $response   Response that was received
77
     * @param CurlHandle       $handle     Curl handle associated with the message
78
     * @param array            $customData Associative array of custom template data
79
     *
80
     * @return string
81
     */
82
    public function format(
83
        RequestInterface $request,
84
        Response $response = null,
85
        CurlHandle $handle = null,
86
        array $customData = array()
87
    ) {
88
        $cache = $customData;
89
90
        return preg_replace_callback(
91
            '/{\s*([A-Za-z_\-\.0-9]+)\s*}/',
92
            function (array $matches) use ($request, $response, $handle, &$cache) {
93
94
                if (array_key_exists($matches[1], $cache)) {
95
                    return $cache[$matches[1]];
96
                }
97
98
                $result = '';
99
                switch ($matches[1]) {
100
                    case 'request':
101
                        $result = (string) $request;
102
                        break;
103
                    case 'response':
104
                        $result = (string) $response;
105
                        break;
106
                    case 'req_body':
107
                        $result = $request instanceof EntityEnclosingRequestInterface
108
                            ? (string) $request->getBody() : '';
109
                        break;
110
                    case 'res_body':
111
                        $result = $response ? $response->getBody(true) : '';
112
                        break;
113
                    case 'ts':
114
                        $result = gmdate('c');
115
                        break;
116
                    case 'method':
117
                        $result = $request->getMethod();
118
                        break;
119
                    case 'url':
120
                        $result = (string) $request->getUrl();
121
                        break;
122
                    case 'resource':
123
                        $result = $request->getResource();
124
                        break;
125
                    case 'protocol':
126
                        $result = 'HTTP';
127
                        break;
128
                    case 'version':
129
                        $result = $request->getProtocolVersion();
130
                        break;
131
                    case 'host':
132
                        $result = $request->getHost();
133
                        break;
134
                    case 'hostname':
135
                        $result = gethostname();
136
                        break;
137
                    case 'port':
138
                        $result = $request->getPort();
139
                        break;
140
                    case 'code':
141
                        $result = $response ? $response->getStatusCode() : '';
142
                        break;
143
                    case 'phrase':
144
                        $result = $response ? $response->getReasonPhrase() : '';
145
                        break;
146 View Code Duplication
                    case 'connect_time':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
147
                        $result = $handle && $handle->getInfo(CURLINFO_CONNECT_TIME)
148
                            ? $handle->getInfo(CURLINFO_CONNECT_TIME)
149
                            : ($response ? $response->getInfo('connect_time') : '');
150
                        break;
151 View Code Duplication
                    case 'total_time':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
152
                        $result = $handle && $handle->getInfo(CURLINFO_TOTAL_TIME)
153
                            ? $handle->getInfo(CURLINFO_TOTAL_TIME)
154
                            : ($response ? $response->getInfo('total_time') : '');
155
                        break;
156
                    case 'curl_error':
157
                        $result = $handle ? $handle->getError() : '';
158
                        break;
159
                    case 'curl_code':
160
                        $result = $handle ? $handle->getErrorNo() : '';
161
                        break;
162
                    case 'curl_stderr':
163
                        $result =  $handle ? $handle->getStderr() : '';
164
                        break;
165
                    default:
166
                        if (strpos($matches[1], 'req_header_') === 0) {
167
                            $result = $request->getHeader(substr($matches[1], 11));
168
                        } elseif ($response && strpos($matches[1], 'res_header_') === 0) {
169
                            $result = $response->getHeader(substr($matches[1], 11));
170
                        }
171
                }
172
173
                $cache[$matches[1]] = $result;
174
                return $result;
175
            },
176
            $this->template
177
        );
178
    }
179
}
180