WP_Http_Cookie::__construct()   D
last analyzed

Complexity

Conditions 15
Paths 256

Size

Total Lines 52
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
eloc 34
nc 256
nop 2
dl 0
loc 52
rs 4.409
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * HTTP API: WP_Http_Cookie class
4
 *
5
 * @package WordPress
6
 * @subpackage HTTP
7
 * @since 4.4.0
8
 */
9
10
/**
11
 * Core class used to encapsulate a single cookie object for internal use.
12
 *
13
 * Returned cookies are represented using this class, and when cookies are set, if they are not
14
 * already a WP_Http_Cookie() object, then they are turned into one.
15
 *
16
 * @todo The WordPress convention is to use underscores instead of camelCase for function and method
17
 * names. Need to switch to use underscores instead for the methods.
18
 *
19
 * @since 2.8.0
20
 */
21
class WP_Http_Cookie {
22
23
	/**
24
	 * Cookie name.
25
	 *
26
	 * @since 2.8.0
27
	 * @var string
28
	 */
29
	public $name;
30
31
	/**
32
	 * Cookie value.
33
	 *
34
	 * @since 2.8.0
35
	 * @var string
36
	 */
37
	public $value;
38
39
	/**
40
	 * When the cookie expires.
41
	 *
42
	 * @since 2.8.0
43
	 * @var string
44
	 */
45
	public $expires;
46
47
	/**
48
	 * Cookie URL path.
49
	 *
50
	 * @since 2.8.0
51
	 * @var string
52
	 */
53
	public $path;
54
55
	/**
56
	 * Cookie Domain.
57
	 *
58
	 * @since 2.8.0
59
	 * @var string
60
	 */
61
	public $domain;
62
63
	/**
64
	 * Sets up this cookie object.
65
	 *
66
	 * The parameter $data should be either an associative array containing the indices names below
67
	 * or a header string detailing it.
68
	 *
69
	 * @since 2.8.0
70
	 * @access public
71
	 *
72
	 * @param string|array $data {
73
	 *     Raw cookie data as header string or data array.
74
	 *
75
	 *     @type string     $name    Cookie name.
76
	 *     @type mixed      $value   Value. Should NOT already be urlencoded.
77
	 *     @type string|int $expires Optional. Unix timestamp or formatted date. Default null.
78
	 *     @type string     $path    Optional. Path. Default '/'.
79
	 *     @type string     $domain  Optional. Domain. Default host of parsed $requested_url.
80
	 *     @type int        $port    Optional. Port. Default null.
81
	 * }
82
	 * @param string       $requested_url The URL which the cookie was set on, used for default $domain
83
	 *                                    and $port values.
84
	 */
85
	public function __construct( $data, $requested_url = '' ) {
86
		if ( $requested_url )
87
			$arrURL = @parse_url( $requested_url );
88
		if ( isset( $arrURL['host'] ) )
89
			$this->domain = $arrURL['host'];
90
		$this->path = isset( $arrURL['path'] ) ? $arrURL['path'] : '/';
91
		if (  '/' != substr( $this->path, -1 ) )
92
			$this->path = dirname( $this->path ) . '/';
93
94
		if ( is_string( $data ) ) {
95
			// Assume it's a header string direct from a previous request.
96
			$pairs = explode( ';', $data );
97
98
			// Special handling for first pair; name=value. Also be careful of "=" in value.
99
			$name  = trim( substr( $pairs[0], 0, strpos( $pairs[0], '=' ) ) );
100
			$value = substr( $pairs[0], strpos( $pairs[0], '=' ) + 1 );
101
			$this->name  = $name;
102
			$this->value = urldecode( $value );
103
104
			// Removes name=value from items.
105
			array_shift( $pairs );
106
107
			// Set everything else as a property.
108
			foreach ( $pairs as $pair ) {
109
				$pair = rtrim($pair);
110
111
				// Handle the cookie ending in ; which results in a empty final pair.
112
				if ( empty($pair) )
113
					continue;
114
115
				list( $key, $val ) = strpos( $pair, '=' ) ? explode( '=', $pair ) : array( $pair, '' );
116
				$key = strtolower( trim( $key ) );
117
				if ( 'expires' == $key )
118
					$val = strtotime( $val );
119
				$this->$key = $val;
120
			}
121
		} else {
122
			if ( !isset( $data['name'] ) )
123
				return;
124
125
			// Set properties based directly on parameters.
126
			foreach ( array( 'name', 'value', 'path', 'domain', 'port' ) as $field ) {
127
				if ( isset( $data[ $field ] ) )
128
					$this->$field = $data[ $field ];
129
			}
130
131
			if ( isset( $data['expires'] ) )
132
				$this->expires = is_int( $data['expires'] ) ? $data['expires'] : strtotime( $data['expires'] );
0 ignored issues
show
Documentation Bug introduced by
The property $expires was declared of type string, but is_int($data['expires'])...otime($data['expires']) is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
133
			else
134
				$this->expires = null;
135
		}
136
	}
137
138
	/**
139
	 * Confirms that it's OK to send this cookie to the URL checked against.
140
	 *
141
	 * Decision is based on RFC 2109/2965, so look there for details on validity.
142
	 *
143
	 * @access public
144
	 * @since 2.8.0
145
	 *
146
	 * @param string $url URL you intend to send this cookie to
147
	 * @return bool true if allowed, false otherwise.
148
	 */
149
	public function test( $url ) {
150
		if ( is_null( $this->name ) )
151
			return false;
152
153
		// Expires - if expired then nothing else matters.
154
		if ( isset( $this->expires ) && time() > $this->expires )
155
			return false;
156
157
		// Get details on the URL we're thinking about sending to.
158
		$url = parse_url( $url );
159
		$url['port'] = isset( $url['port'] ) ? $url['port'] : ( 'https' == $url['scheme'] ? 443 : 80 );
160
		$url['path'] = isset( $url['path'] ) ? $url['path'] : '/';
161
162
		// Values to use for comparison against the URL.
163
		$path   = isset( $this->path )   ? $this->path   : '/';
164
		$port   = isset( $this->port )   ? $this->port   : null;
0 ignored issues
show
Bug introduced by
The property port does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
165
		$domain = isset( $this->domain ) ? strtolower( $this->domain ) : strtolower( $url['host'] );
166
		if ( false === stripos( $domain, '.' ) )
167
			$domain .= '.local';
168
169
		// Host - very basic check that the request URL ends with the domain restriction (minus leading dot).
170
		$domain = substr( $domain, 0, 1 ) == '.' ? substr( $domain, 1 ) : $domain;
171
		if ( substr( $url['host'], -strlen( $domain ) ) != $domain )
172
			return false;
173
174
		// Port - supports "port-lists" in the format: "80,8000,8080".
175
		if ( !empty( $port ) && !in_array( $url['port'], explode( ',', $port) ) )
176
			return false;
177
178
		// Path - request path must start with path restriction.
179
		if ( substr( $url['path'], 0, strlen( $path ) ) != $path )
180
			return false;
181
182
		return true;
183
	}
184
185
	/**
186
	 * Convert cookie name and value back to header string.
187
	 *
188
	 * @access public
189
	 * @since 2.8.0
190
	 *
191
	 * @return string Header encoded cookie name and value.
192
	 */
193
	public function getHeaderValue() {
194
		if ( ! isset( $this->name ) || ! isset( $this->value ) )
195
			return '';
196
197
		/**
198
		 * Filters the header-encoded cookie value.
199
		 *
200
		 * @since 3.4.0
201
		 *
202
		 * @param string $value The cookie value.
203
		 * @param string $name  The cookie name.
204
		 */
205
		return $this->name . '=' . apply_filters( 'wp_http_cookie_value', $this->value, $this->name );
206
	}
207
208
	/**
209
	 * Retrieve cookie header for usage in the rest of the WordPress HTTP API.
210
	 *
211
	 * @access public
212
	 * @since 2.8.0
213
	 *
214
	 * @return string
215
	 */
216
	public function getFullHeader() {
217
		return 'Cookie: ' . $this->getHeaderValue();
218
	}
219
220
	/**
221
	 * Retrieves cookie attributes.
222
	 *
223
	 * @since 4.6.0
224
	 * @access public
225
	 *
226
	 * @return array {
227
	 *    List of attributes.
228
	 *
229
	 *    @type string $expires When the cookie expires.
230
	 *    @type string $path    Cookie URL path.
231
	 *    @type string $domain  Cookie domain.
232
	 * }
233
	 */
234
	public function get_attributes() {
235
		return array(
236
			'expires' => $this->expires,
237
			'path'    => $this->path,
238
			'domain'  => $this->domain,
239
		);
240
	}
241
}
242