ar_httpClientStream::headers()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
ccs 0
cts 7
cp 0
crap 6
1
<?php
2
3
	ar_pinp::allow( 'ar_http');
4
	ar_pinp::allow( 'ar_httpClientStream' );
5
6
	/*
7
	 * prevent mess detector from warning for the private static fields
8
	 * @SuppressWarnings(PHPMD.UnusedPrivateField)
9
	 */
10
	class ar_http extends arBase {
11
12
		private static $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE;  //needed to make __get() work
0 ignored issues
show
Unused Code introduced by
The property $_GET is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
Unused Code introduced by
The property $_POST is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
Unused Code introduced by
The property $_REQUEST is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
Unused Code introduced by
The property $_SERVER is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
Unused Code introduced by
The property $_COOKIE is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
13
		public static $tainting = true;
14
15
		public function __get($var) {
16
			switch ($var) {
17
				case '_GET' :
18
					return $this->getvar( null, 'GET');
19
				break;
20
				case '_POST' :
21
					return $this->getvar( null, 'POST');
22
				break;
23
				case '_REQUEST' :
24
					return $this->getvar();
25
				break;
26
				case '_SERVER' :
27
					return $this->getvar( null, 'SERVER');
28
				break;
29
				case '_COOKIE' :
30
					return $this->getvar( null, 'COOKIE');
31
				break;
32
				case 'tainting' :
33
					return self::$tainting;
34
				break;
35
			}
36
		}
37
38
		public function __set( $var, $value ) {
39
			if ($var=='tainting') {
40
				self::$tainting = (bool) $value;
41
			}
42
		}
43
44 6
		public static function getvar( $name = null, $method = null) {
0 ignored issues
show
Coding Style introduced by
getvar uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
getvar uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
getvar uses the super-global variable $_COOKIE which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
getvar uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
getvar uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
45
			/*
46
				The full list of field-name characters that PHP converts to _ (underscore) is the following (not just dot):
47
48
				chr(32) ( ) (space)
49
				chr(46) (.) (dot)
50
				chr(91) ([) (open square bracket)
51
				chr(128) - chr(159) (various)
52
				PHP irreversibly modifies field names containing these characters in an attempt to maintain compatibility with the deprecated register_globals feature.
53
			*/
54 6
			if (isset($name) ) {
55 6
				$name = preg_replace("/[ \.\[\x80-\x9f]/", "_", $name);
56 6
			}
57
58
			switch($method) {
59 6
				case 'GET' :
60
					$result = isset($name) ? $_GET[$name] : $_GET;
61
				break;
62 6
				case 'POST' :
63
					$result = isset($name) ? $_POST[$name] : $_POST;
64
				break;
65 6
				case 'COOKIE' :
66
					$result = isset($name) ? $_COOKIE[$name] : $_COOKIE;
67
				break;
68 6
				case 'SERVER' :
69
					$result = isset($name) ? $_SERVER[$name] : $_SERVER;
70
				break;
71 6
				default :
72 6
					$result = !isset($name) ? $_REQUEST :
73 6
						( isset($_POST[$name]) ? $_POST[$name] : $_GET[$name] );
74 6
				break;
75 6
			}
76 6
			if (self::$tainting) {
77 6
				ar::taint( $result );
78 6
			}
79 6
			return $result;
80
		}
81
82
		public static function request( $method = null, $url = null, $postdata = null, $options = array() ) {
83
			$client = new ar_httpClientStream(); //$method, $url, $postdata, $port);
84
			return $client->send( $method, $url, $postdata, $options );
85
		}
86
87
		public static function client( $options = array() ) {
88
			return new ar_httpClientStream( $options );
89
		}
90
91
		public static function configure( $option, $value ) {
92
			switch ( $option ) {
93
				case 'tainting' :
94
					self::$tainting = $value;
95
				break;
96
			}
97
		}
98
99
		public static function header( $header ) {
100
			return ar_http_headers::header( $header );
101
		}
102
103
		public static function get( $url, $request = null, $options = array() ) {
104
			return self::request( 'GET', $url, $request, $options);
105
		}
106
107
		public static function post( $url, $request = null, $options = array() ) {
108
			return self::request( 'POST', $url, $request, $options);
109
		}
110
111
	}
112
113
	interface ar_httpClient {
114
115
		public function get( $url, $request = null, $options = array() );
116
117
		public function post( $url, $request = null, $options = array() );
118
119
		public function put( $url, $request = null, $options = array() );
120
121
		public function delete( $url, $request = null, $options = array() );
122
123
		public function send( $type, $url, $request = null, $options = array() );
124
125
		public function headers( $headers );
126
127
	}
128
129
	class ar_httpClientStream extends arBase implements ar_httpClient {
130
131
		private $options = array();
132
133
		public $responseHeaders = null;
134
135
		/* FIXME: function not used, is it still relevant?
136
		private function parseRequestURL( $url ) {
137
			$request = explode( '?', (string) $url );
138
			if ( isset($request[1]) ) {
139
				return $request[1];
140
			} else {
141
				return null;
142
			}
143
		}
144
		*/
145
146
		private function compileRequest( array $request ) {
147
			$result = "";
148
			foreach ( $request as $key => $value ) {
149
				if ( !is_integer( $key ) ) {
150
					$result .= urlencode($key) . "=" . urlencode($value) . "&";
151
				}
152
			}
153
			return substr( $result, 0, -1);
154
		}
155
156
		private function mergeOptions( ) {
157
			$args = func_get_args();
158
			array_unshift( $args, $this->options );
159
			return call_user_func_array( 'array_merge', $args );
160
		}
161
162
		public function send( $type, $url, $request = null, $options = array() ) {
163
			if ( is_array( $request ) ) {
164
				$request = $this->compileRequest( $request );
165
			}
166
			$options = $this->mergeOptions( array(
167
				'method' => $type,
168
				'content' => $request
169
			), $options );
170
171
			if ( $options['method'] == 'GET' && $options['content'] ) {
172
				if ( strpos( $url, '?' ) === false ) {
173
					$url = $url . '?' . $options['content'];
174
				} else {
175
					$url = $url . '&' . $options['content'];
176
				}
177
				$options['content'] = '';
178
			}
179
			$context = stream_context_create( array( 'http' => $options ) );
180
			$result = @file_get_contents( (string) $url, false, $context );
181
182
			$this->responseHeaders = $http_response_header; //magic php variable set by file_get_contents.
183
			if (is_array($this->responseHeaders) && isset($this->responseHeaders[0])) {
184
				$statusLine = explode(" ", $this->responseHeaders[0]);
185
				$this->statusCode = $statusLine[1];
0 ignored issues
show
Bug introduced by
The property statusCode 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...
186
			}
187
188
			$this->requestHeaders = $options['header'];
0 ignored issues
show
Bug introduced by
The property requestHeaders 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...
189
			return $result;
190
		}
191
192
		public function __construct( $options = array() ) {
193
			$this->options = $options;
194
		}
195
196
		public function get( $url, $request = null, $options = array() ) {
197
			return $this->send( 'GET', $url, $request, $options );
198
		}
199
200
		public function post( $url, $request = null, $options = array() ) {
201
			return $this->send( 'POST', $url, $request, $options );
202
		}
203
204
		public function put( $url, $request = null, $options = array() ) {
205
			return $this->send( 'PUT', $url, $request, $options );
206
		}
207
208
		public function delete( $url, $request = null, $options = array() ) {
209
			return $this->send( 'DELETE', $url, $request, $options );
210
		}
211
212
		public function headers( $headers ) {
213
			if (is_array($headers)) {
214
				$headers = join("\r\n", $headers);
215
			}
216
			$this->options['header'] = $this->options['headers'].$headers;
217
			return $this;
218
		}
219
	}
220