Completed
Pull Request — master (#410)
by
unknown
07:24
created

CurlLogger::logResponse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 3
crap 1
1
<?php
2
/**
3
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
4
 *
5
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
6
 * use, copy, modify, and distribute this software in source code or binary
7
 * form for use in connection with the web services and APIs provided by
8
 * Facebook.
9
 *
10
 * As with any software that integrates with the Facebook platform, your use
11
 * of this software is subject to the Facebook Developer Principles and
12
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
13
 * shall be included in all copies or substantial portions of the software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * DEALINGS IN THE SOFTWARE.
22
 *
23
 */
24
25
namespace FacebookAds\Logger;
26
27
use FacebookAds\Http\FileParameter;
28
use FacebookAds\Http\Parameters;
29
use FacebookAds\Http\RequestInterface;
30
use FacebookAds\Http\ResponseInterface;
31
use FacebookAds\Logger\CurlLogger\JsonAwareParameters;
32
33
class CurlLogger implements LoggerInterface {
34
35
  /**
36
   * @var string
37
   */
38
  const PARAM_DEFAULT_FLAG = 'd';
39
40
  /**
41
   * @var string
42
   */
43
  const PARAM_URLENCODE_FLAG = '-data-urlencode';
44
45
  /**
46
   * @var string
47
   */
48
  const PARAM_POST_FLAG = 'F';
49
50
  /**
51
   * @var string
52
   */
53
  const METHOD_DEFAULT_FLAG = '';
54
55
  /**
56
   * @var string
57
   */
58
  const METHOD_GET_FLAG = 'G';
59
60
  /**
61
   * @var string
62
   */
63
  const METHOD_PUT_FLAG = 'X PUT';
64
65
  /**
66
   * @var string
67
   */
68
  const METHOD_DELETE_FLAG = 'X DELETE';
69
70
  /**
71
   * @var resource
72
   */
73
  protected $handle;
74
75
  /**
76
   * @var bool
77
   */
78
  protected $jsonPrettyPrint = false;
79
80
  /**
81
   * @param resource $handle
82
   */
83 7
  public function __construct($handle = null) {
84
    
85 7
    if (!defined('STDOUT')) {
86
        define('STDOUT', fopen('php://stdout', 'w'));
87
    }
88
 
89 7
    $this->handle = is_resource($handle) ? $handle : STDOUT;
90 7
  }
91
92
  /**
93
   * @return bool
94
   */
95 5
  public function isJsonPrettyPrint() {
96 5
    return $this->jsonPrettyPrint;
97
  }
98
99
  /**
100
   * @param bool $json_pretty_print
101
   * @return $this
102
   */
103 1
  public function setJsonPrettyPrint($json_pretty_print) {
104 1
    $this->jsonPrettyPrint = $json_pretty_print;
105 1
    return $this;
106
  }
107
108
  /**
109
   * @param string $method
110
   * @return string
111
   */
112 5
  public static function getMethodFlag($method) {
113
    switch ($method) {
114 5
      case RequestInterface::METHOD_GET:
115 1
        return static::METHOD_GET_FLAG;
116 4
      case RequestInterface::METHOD_PUT:
117 1
        return static::METHOD_PUT_FLAG;
118 3
      case RequestInterface::METHOD_DELETE:
119 1
        return static::METHOD_DELETE_FLAG;
120
    }
121
122 2
    return static::METHOD_DEFAULT_FLAG;
123
  }
124
125
  /**
126
   * @param string $method
127
   * @param string $value
128
   * @return string
129
   */
130 5
  public static function getParamFlag($method, $value) {
131
    return $method === RequestInterface::METHOD_POST
132 5
      ? static::PARAM_POST_FLAG
133 5
      : (strstr($value, "\n")
134 4
        ? static::PARAM_URLENCODE_FLAG
135 5
        : static::PARAM_DEFAULT_FLAG);
136
  }
137
138
  /**
139
   * @param string $string
140
   * @param int $indent
141
   * @return string
142
   */
143 1
  protected function indent($string, $indent) {
144 1
    return str_replace("\n", " \n".str_repeat(' ', $indent), $string);
145
  }
146
147
  /**
148
   * @param Parameters $params
149
   * @param string $method
150
   * @param bool $is_file
151
   * @return string
152
   */
153 5
  protected function processParams(Parameters $params, $method, $is_file) {
154 5
    $chunks = array();
155 5
    if ($this->isJsonPrettyPrint()) {
156 1
      $params = new JsonAwareParameters($params);
157 1
    }
158 5
    foreach ($params->export() as $name => $value) {
159 5
      if ($is_file && $params->offsetGet($name) instanceof FileParameter) {
160
        $value = "@" . $this->normalizeFileParam($params->offsetGet($name));
161
      } else {
162 5
        $value = addcslashes(
163 5
          strpos($value, "\n") !== false
164 5
            ? $this->indent($value, 2)
165 5
            : $value,
166 5
          '\'');
167
      }
168 5
      $chunks[$name] = sprintf(
169 5
        '-%s \'%s=%s\'',
170 5
        $this->getParamFlag($method, $value),
171 5
        $name,
172 5
        $value);
173 5
    }
174
175 5
    return $chunks;
176
  }
177
178
  /**
179
   * @param FileParameter $file_param
180
   * @return string
181
   */
182
  protected function normalizeFileParam(FileParameter $file_param) {
183
    return sprintf('%s%s%s%s%s',
184
      $file_param->getPath(),
185
      $file_param->getMimeType() != null ? ";type=" : "",
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $file_param->getMimeType() of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
186
      $file_param->getMimeType(),
187
      $file_param->getName() != null ? ";name=" : "",
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $file_param->getName() of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
188
      $file_param->getName());
189
  }
190
191
  /**
192
   * @param RequestInterface $request
193
   * @return string
194
   */
195 5
  protected function processUrl(RequestInterface $request) {
196 5
    return $request->getProtocol().$request->getDomain()
197 5
      .'/v'.$request->getGraphVersion().$request->getPath();
198
  }
199
200
  /**
201
   * @param string $buffer
202
   */
203 5
  protected function flush($buffer) {
204 5
    fwrite($this->handle, $buffer.PHP_EOL.PHP_EOL);
205 5
  }
206
207
  /**
208
   * @param mixed $level
209
   * @param string $message
210
   * @param array $context
211
   */
212 1
  public function log($level, $message, array $context = array()) {
213
    // We only care about requests
214 1
  }
215
216
  /**
217
   * @param array $array
218
   * @param mixed $key
219
   * @return mixed
220
   */
221 5
  protected function removeArrayKey(array &$array, $key) {
222 5
    if (array_key_exists($key, $array)) {
223 4
      $value = $array[$key];
224 4
      unset($array[$key]);
225 4
      return $value;
226
    } else {
227 1
      return null;
228
    }
229
  }
230
231
  /**
232
   * @param array $params
233
   * @return array
234
   */
235 5
  protected function sortParams(array $params) {
236 5
    $access_token = $this->removeArrayKey($params, 'access_token');
237 5
    $appsecret_proof = $this->removeArrayKey($params, 'appsecret_proof');
238 5
    $access_token !== null && $params['access_token'] = $access_token;
239 5
    $appsecret_proof !== null && $params['appsecret_proof'] = $appsecret_proof;
240
241 5
    return $params;
242
  }
243
244
  /**
245
   * @param string $level
246
   * @param RequestInterface $request
247
   * @param array $context
248
   */
249 5
  public function logRequest(
250
    $level, RequestInterface $request, array $context = array()) {
251
252 5
    $new_line = ' \\'.PHP_EOL.'  ';
253 5
    $method = $request->getMethod();
254 5
    $method_flag = static::getMethodFlag($method);
255 5
    $params = $this->sortParams(array_merge(
256 5
      $this->processParams($request->getQueryParams(), $method, false),
257 5
      $this->processParams($request->getBodyParams(), $method, false),
258 5
      $this->processParams($request->getFileParams(), $method, true)));
259
260 5
    $buffer = 'curl'.($method_flag ? ' -'.$method_flag : '');
261 5
    foreach ($params as $param) {
262 5
      $buffer .= $new_line.$param;
263 5
    }
264 5
    $buffer .= $new_line.$this->processUrl($request);
265
266 5
    $this->flush($buffer);
267 5
  }
268
269
  /**
270
   * @param string $level
271
   * @param ResponseInterface $response
272
   * @param array $context
273
   */
274 1
  public function logResponse(
275
    $level, ResponseInterface $response, array $context = array()) {
276
    // We only care about requests
277 1
  }
278
}
279