Wordpress 4.6
[autoinstalls/wordpress.git] / wp-includes / Requests / Session.php
1 <?php
2 /**
3  * Session handler for persistent requests and default parameters
4  *
5  * @package Requests
6  * @subpackage Session Handler
7  */
8
9 /**
10  * Session handler for persistent requests and default parameters
11  *
12  * Allows various options to be set as default values, and merges both the
13  * options and URL properties together. A base URL can be set for all requests,
14  * with all subrequests resolved from this. Base options can be set (including
15  * a shared cookie jar), then overridden for individual requests.
16  *
17  * @package Requests
18  * @subpackage Session Handler
19  */
20 class Requests_Session {
21         /**
22          * Base URL for requests
23          *
24          * URLs will be made absolute using this as the base
25          * @var string|null
26          */
27         public $url = null;
28
29         /**
30          * Base headers for requests
31          * @var array
32          */
33         public $headers = array();
34
35         /**
36          * Base data for requests
37          *
38          * If both the base data and the per-request data are arrays, the data will
39          * be merged before sending the request.
40          *
41          * @var array
42          */
43         public $data = array();
44
45         /**
46          * Base options for requests
47          *
48          * The base options are merged with the per-request data for each request.
49          * The only default option is a shared cookie jar between requests.
50          *
51          * Values here can also be set directly via properties on the Session
52          * object, e.g. `$session->useragent = 'X';`
53          *
54          * @var array
55          */
56         public $options = array();
57
58         /**
59          * Create a new session
60          *
61          * @param string|null $url Base URL for requests
62          * @param array $headers Default headers for requests
63          * @param array $data Default data for requests
64          * @param array $options Default options for requests
65          */
66         public function __construct($url = null, $headers = array(), $data = array(), $options = array()) {
67                 $this->url = $url;
68                 $this->headers = $headers;
69                 $this->data = $data;
70                 $this->options = $options;
71
72                 if (empty($this->options['cookies'])) {
73                         $this->options['cookies'] = new Requests_Cookie_Jar();
74                 }
75         }
76
77         /**
78          * Get a property's value
79          *
80          * @param string $key Property key
81          * @return mixed|null Property value, null if none found
82          */
83         public function __get($key) {
84                 if (isset($this->options[$key])) {
85                         return $this->options[$key];
86                 }
87
88                 return null;
89         }
90
91         /**
92          * Set a property's value
93          *
94          * @param string $key Property key
95          * @param mixed $value Property value
96          */
97         public function __set($key, $value) {
98                 $this->options[$key] = $value;
99         }
100
101         /**
102          * Remove a property's value
103          *
104          * @param string $key Property key
105          */
106         public function __isset($key) {
107                 return isset($this->options[$key]);
108         }
109
110         /**
111          * Remove a property's value
112          *
113          * @param string $key Property key
114          */
115         public function __unset($key) {
116                 if (isset($this->options[$key])) {
117                         unset($this->options[$key]);
118                 }
119         }
120
121         /**#@+
122          * @see request()
123          * @param string $url
124          * @param array $headers
125          * @param array $options
126          * @return Requests_Response
127          */
128         /**
129          * Send a GET request
130          */
131         public function get($url, $headers = array(), $options = array()) {
132                 return $this->request($url, $headers, null, Requests::GET, $options);
133         }
134
135         /**
136          * Send a HEAD request
137          */
138         public function head($url, $headers = array(), $options = array()) {
139                 return $this->request($url, $headers, null, Requests::HEAD, $options);
140         }
141
142         /**
143          * Send a DELETE request
144          */
145         public function delete($url, $headers = array(), $options = array()) {
146                 return $this->request($url, $headers, null, Requests::DELETE, $options);
147         }
148         /**#@-*/
149
150         /**#@+
151          * @see request()
152          * @param string $url
153          * @param array $headers
154          * @param array $data
155          * @param array $options
156          * @return Requests_Response
157          */
158         /**
159          * Send a POST request
160          */
161         public function post($url, $headers = array(), $data = array(), $options = array()) {
162                 return $this->request($url, $headers, $data, Requests::POST, $options);
163         }
164
165         /**
166          * Send a PUT request
167          */
168         public function put($url, $headers = array(), $data = array(), $options = array()) {
169                 return $this->request($url, $headers, $data, Requests::PUT, $options);
170         }
171
172         /**
173          * Send a PATCH request
174          *
175          * Note: Unlike {@see post} and {@see put}, `$headers` is required, as the
176          * specification recommends that should send an ETag
177          *
178          * @link https://tools.ietf.org/html/rfc5789
179          */
180         public function patch($url, $headers, $data = array(), $options = array()) {
181                 return $this->request($url, $headers, $data, Requests::PATCH, $options);
182         }
183         /**#@-*/
184
185         /**
186          * Main interface for HTTP requests
187          *
188          * This method initiates a request and sends it via a transport before
189          * parsing.
190          *
191          * @see Requests::request()
192          *
193          * @throws Requests_Exception On invalid URLs (`nonhttp`)
194          *
195          * @param string $url URL to request
196          * @param array $headers Extra headers to send with the request
197          * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
198          * @param string $type HTTP request type (use Requests constants)
199          * @param array $options Options for the request (see {@see Requests::request})
200          * @return Requests_Response
201          */
202         public function request($url, $headers = array(), $data = array(), $type = Requests::GET, $options = array()) {
203                 $request = $this->merge_request(compact('url', 'headers', 'data', 'options'));
204
205                 return Requests::request($request['url'], $request['headers'], $request['data'], $type, $request['options']);
206         }
207
208         /**
209          * Send multiple HTTP requests simultaneously
210          *
211          * @see Requests::request_multiple()
212          *
213          * @param array $requests Requests data (see {@see Requests::request_multiple})
214          * @param array $options Global and default options (see {@see Requests::request})
215          * @return array Responses (either Requests_Response or a Requests_Exception object)
216          */
217         public function request_multiple($requests, $options = array()) {
218                 foreach ($requests as $key => $request) {
219                         $requests[$key] = $this->merge_request($request, false);
220                 }
221
222                 $options = array_merge($this->options, $options);
223
224                 // Disallow forcing the type, as that's a per request setting
225                 unset($options['type']);
226
227                 return Requests::request_multiple($requests, $options);
228         }
229
230         /**
231          * Merge a request's data with the default data
232          *
233          * @param array $request Request data (same form as {@see request_multiple})
234          * @param boolean $merge_options Should we merge options as well?
235          * @return array Request data
236          */
237         protected function merge_request($request, $merge_options = true) {
238                 if ($this->url !== null) {
239                         $request['url'] = Requests_IRI::absolutize($this->url, $request['url']);
240                         $request['url'] = $request['url']->uri;
241                 }
242
243                 if (empty($request['headers'])) {
244                         $request['headers'] = array();
245                 }
246                 $request['headers'] = array_merge($this->headers, $request['headers']);
247
248                 if (empty($request['data'])) {
249                         if (is_array($this->data)) {
250                                 $request['data'] = $this->data;
251                         }
252                 }
253                 elseif (is_array($request['data']) && is_array($this->data)) {
254                         $request['data'] = array_merge($this->data, $request['data']);
255                 }
256
257                 if ($merge_options !== false) {
258                         $request['options'] = array_merge($this->options, $request['options']);
259
260                         // Disallow forcing the type, as that's a per request setting
261                         unset($request['options']['type']);
262                 }
263
264                 return $request;
265         }
266 }