GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Headers   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 271
Duplicated Lines 7.38 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 20
loc 271
rs 9.6
c 0
b 0
f 0
wmc 32
lcom 1
cbo 1

11 Methods

Rating   Name   Duplication   Size   Complexity  
A normalize_field_name() 0 4 1
B __construct() 20 29 6
A __clone() 0 12 3
A __toString() 0 18 3
A __invoke() 0 14 3
A send_header() 0 4 1
A offsetExists() 0 4 1
A offsetGet() 0 16 4
C offsetSet() 0 48 8
A offsetUnset() 0 4 1
A getIterator() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/*
4
 * This file is part of the ICanBoogie package.
5
 *
6
 * (c) Olivier Laviale <[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 ICanBoogie\HTTP;
13
14
/**
15
 * HTTP Header field definitions.
16
 *
17
 * Instances of this class are used to collect and manipulate HTTP header field definitions.
18
 * Header field instances are used to handle the definition of complex header fields such as
19
 * `Content-Type` and `Cache-Control`. For instance a {@link Headers\CacheControl} instance
20
 * is used to handle the directives of the `Cache-Control` header field.
21
 *
22
 * @see http://tools.ietf.org/html/rfc2616#section-14
23
 */
24
class Headers implements \ArrayAccess, \IteratorAggregate
25
{
26
	static private $mapping = [
27
28
		'Cache-Control'       => Headers\CacheControl::class,
29
		'Content-Disposition' => Headers\ContentDisposition::class,
30
		'Content-Type'        => Headers\ContentType::class,
31
		'Date'                => Headers\Date::class,
32
		'Expires'             => Headers\Date::class,
33
		'If-Modified-Since'   => Headers\Date::class,
34
		'If-Unmodified-Since' => Headers\Date::class,
35
		'Last-Modified'       => Headers\Date::class
36
37
	];
38
39
	/**
40
	 * Normalizes field name.
41
	 *
42
	 * @param string $name
43
	 *
44
	 * @return string
45
	 */
46
	static private function normalize_field_name($name)
47
	{
48
		return mb_convert_case(strtr(substr($name, 5), '_', '-'), MB_CASE_TITLE);
49
	}
50
51
	/**
52
	 * Header fields.
53
	 *
54
	 * @var array
55
	 */
56
	protected $fields = [];
57
58
	/**
59
	 * If the `REQUEST_URI` key is found in the header fields they are considered coming from the
60
	 * super global `$_SERVER` array in which case they are filtered to keep only keys
61
	 * starting with the `HTTP_` prefix. Also, header field names are normalized. For instance,
62
	 * `HTTP_CONTENT_TYPE` becomes `Content-Type`.
63
	 *
64
	 * @param array $fields The initial headers.
65
	 */
66
	public function __construct(array $fields = [])
67
	{
68
		if (isset($fields['REQUEST_URI']))
69
		{
70 View Code Duplication
			foreach ($fields as $field => $value)
71
			{
72
				if (strpos($field, 'HTTP_') !== 0)
73
				{
74
					continue;
75
				}
76
77
				$field = self::normalize_field_name($field);
78
79
				$this[$field] = $value;
80
			}
81
		}
82
		else
83
		{
84 View Code Duplication
			foreach ($fields as $field => $value)
85
			{
86
				if (strpos($field, 'HTTP_') === 0)
87
				{
88
					$field = self::normalize_field_name($field);
89
				}
90
91
				$this[$field] = $value;
92
			}
93
		}
94
	}
95
96
	/**
97
	 * Clone instantiated fields.
98
	 */
99
	public function __clone()
100
	{
101
		foreach ($this->fields as &$field)
102
		{
103
			if (!is_object($field))
104
			{
105
				continue;
106
			}
107
108
			$field = clone $field;
109
		}
110
	}
111
112
	/**
113
	 * Returns the header as a string.
114
	 *
115
	 * Header fields with empty string values are discarded.
116
	 *
117
	 * @return string
118
	 */
119
	public function __toString()
120
	{
121
		$header = '';
122
123
		foreach ($this->fields as $field => $value)
124
		{
125
			$value = (string) $value;
126
127
			if ($value === '')
128
			{
129
				continue;
130
			}
131
132
			$header .= "$field: $value\r\n";
133
		}
134
135
		return $header;
136
	}
137
138
	/**
139
	 * Sends header fields using the {@link header()} function.
140
	 *
141
	 * Header fields with empty string values are discarded.
142
	 */
143
	public function __invoke()
144
	{
145
		foreach ($this->fields as $field => $value)
146
		{
147
			$value = (string) $value;
148
149
			if ($value === '')
150
			{
151
				continue;
152
			}
153
154
			$this->send_header($field, $value);
155
		}
156
	}
157
158
	/**
159
	 * Send header field.
160
	 *
161
	 * Note: The only reason for this method is testing.
162
	 *
163
	 * @param string $field
164
	 * @param string $value
165
	 */
166
	// @codeCoverageIgnoreStart
167
	protected function send_header($field, $value)
168
	{
169
		header("$field: $value");
170
	}
171
	// @codeCoverageIgnoreEnd
172
173
	/**
174
	 * Checks if a header field exists.
175
	 *
176
	 * @param mixed $field
177
	 *
178
	 * @return boolean
179
	 */
180
	public function offsetExists($field)
181
	{
182
		return isset($this->fields[(string) $field]);
183
	}
184
185
	/**
186
	 * Returns a header.
187
	 *
188
	 * @param mixed $field
189
	 *
190
	 * @return string|null The header field value or null if it is not defined.
191
	 */
192
	public function offsetGet($field)
193
	{
194
		if (isset(self::$mapping[$field]))
195
		{
196
			if (empty($this->fields[$field]))
197
			{
198
				/* @var $class Headers\Header|string */
199
				$class = self::$mapping[$field];
200
				$this->fields[$field] = $class::from(null);
201
			}
202
203
			return $this->fields[$field];
204
		}
205
206
		return $this->offsetExists($field) ? $this->fields[$field] : null;
207
	}
208
209
	/**
210
	 * Sets a header field.
211
	 *
212
	 * Note: Setting a header field to `null` removes it, just like unset() would.
213
	 *
214
	 * ## Date, Expires, Last-Modified
215
	 *
216
	 * The `Date`, `Expires` and `Last-Modified` header fields can be provided as a Unix
217
	 * timestamp, a string or a {@link \DateTime} object.
218
	 *
219
	 * ## Cache-Control, Content-Disposition and Content-Type
220
	 *
221
	 * Instances of the {@link Headers\CacheControl}, {@link Headers\ContentDisposition} and
222
	 * {@link Headers\ContentType} are used to handle the values of the `Cache-Control`,
223
	 * `Content-Disposition` and `Content-Type` header fields.
224
	 *
225
	 * @param string $field The header field to set.
226
	 * @param mixed $value The value of the header field.
227
	 */
228
	public function offsetSet($field, $value)
229
	{
230
		if ($value === null)
231
		{
232
			unset($this[$field]);
233
234
			return;
235
		}
236
237
		switch ($field)
238
		{
239
			# http://tools.ietf.org/html/rfc2616#section-14.25
240
			case 'If-Modified-Since':
241
			{
242
				#
243
				# Removes the ";length=xxx" string added by Internet Explorer.
244
				# http://stackoverflow.com/questions/12626699/if-modified-since-http-header-passed-by-ie9-includes-length
245
				#
246
247
				if (is_string($value))
248
				{
249
					$pos = strpos($value, ';');
250
251
					if ($pos)
252
					{
253
						$value = substr($value, 0, $pos);
254
					}
255
				}
256
			}
257
			break;
258
259
			# http://tools.ietf.org/html/rfc2616#section-14.37
260
			case 'Retry-After':
261
			{
262
				$value = is_numeric($value) ? $value : Headers\Date::from($value);
263
			}
264
			break;
265
		}
266
267
		if (isset(self::$mapping[$field]))
268
		{
269
			/* @var $class Headers\Header|string */
270
			$class = self::$mapping[$field];
271
			$value = $class::from($value);
272
		}
273
274
		$this->fields[$field] = $value;
275
	}
276
277
	/**
278
	 * Removes a header field.
279
	 *
280
	 * @param mixed $field
281
	 */
282
	public function offsetUnset($field)
283
	{
284
		unset($this->fields[$field]);
285
	}
286
287
	/**
288
	 * Returns an iterator for the header fields.
289
	 */
290
	public function getIterator()
291
	{
292
		return new \ArrayIterator($this->fields);
293
	}
294
}
295