Subversion Repositories Sites.obs-saisons.fr

Rev

Rev 31 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 31 Rev 284
1
<?php
1
<?php
2
// In : utf8 url_encoded (get et post)
2
// In : utf8 url_encoded (get et post)
3
// Out : utf8
3
// Out : utf8
4
 
4
 
5
// TODO : gerer les retours : dans ce controleur : code retour et envoi ...
5
// TODO : gerer les retours : dans ce controleur : code retour et envoi ...
6
class JRest {
6
class JRest {
7
 
7
 
8
 	/** Parsed configuration file */
8
 	/** Parsed configuration file */
9
    private $config;
9
    private $config;
10
 
10
 
11
	/** The HTTP request method used. */
11
	/** The HTTP request method used. */
12
	private $method = 'GET';
12
	private $method = 'GET';
13
 
13
 
14
	/** The HTTP request data sent (if any). */
14
	/** The HTTP request data sent (if any). */
15
	private $requestData = NULL;
15
	private $requestData = NULL;
16
 
16
 
17
	/** Array of strings to convert into the HTTP response. */
17
	/** Array of strings to convert into the HTTP response. */
18
	private $output = array();
18
	private $output = array();
19
 
19
 
20
	/** Nom resource. */
20
	/** Nom resource. */
21
	private $resource = NULL;
21
	private $resource = NULL;
22
 
22
 
23
	/** Identifiant unique resource. */
23
	/** Identifiant unique resource. */
24
	private $uid = NULL;
24
	private $uid = NULL;
25
 
25
 
26
	/**
26
	/**
27
	 * Constructor. Parses the configuration file "JRest.ini", grabs any request data sent, records the HTTP
27
	 * Constructor. Parses the configuration file "JRest.ini", grabs any request data sent, records the HTTP
28
	 * request method used and parses the request URL to find out the requested resource
28
	 * request method used and parses the request URL to find out the requested resource
29
	 * @param str iniFile Configuration file to use
29
	 * @param str iniFile Configuration file to use
30
	 */
30
	 */
31
	public function JRest($iniFile = 'jrest.ini.php') {
31
	public function JRest($iniFile = 'jrest.ini.php') {
32
		$this->config = parse_ini_file($iniFile, TRUE);
32
		$this->config = parse_ini_file($iniFile, TRUE);
33
		if (isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && isset($_SERVER['QUERY_STRING'])) {
33
		if (isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && isset($_SERVER['QUERY_STRING'])) {
34
			if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 0) {
34
			if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 0) {
35
				$this->requestData = '';
35
				$this->requestData = '';
36
				$httpContent = fopen('php://input', 'r');
36
				$httpContent = fopen('php://input', 'r');
37
				while ($data = fread($httpContent, 1024)) {
37
				while ($data = fread($httpContent, 1024)) {
38
					$this->requestData .= $data;
38
					$this->requestData .= $data;
39
				}
39
				}
40
				fclose($httpContent);
40
				fclose($httpContent);
41
			}
41
			}
42
			if (strlen($_SERVER['QUERY_STRING']) == 0) {
42
			if (strlen($_SERVER['QUERY_STRING']) == 0) {
43
				$len = strlen($_SERVER['REQUEST_URI']);
43
				$len = strlen($_SERVER['REQUEST_URI']);
44
			} else {
44
			} else {
45
				$len = -(strlen($_SERVER['QUERY_STRING']) + 1);
45
				$len = -(strlen($_SERVER['QUERY_STRING']) + 1);
46
			}
46
			}
47
			$urlString = substr($_SERVER['REQUEST_URI'], strlen($this->config['settings']['baseURL']), $len);
47
			$urlString = substr($_SERVER['REQUEST_URI'], strlen($this->config['settings']['baseURL']), $len);
48
 
48
 
49
			$urlParts = explode('/', $urlString);
49
			$urlParts = explode('/', $urlString);
50
 
50
 
51
			if (isset($urlParts[0])) $this->resource = $urlParts[0];
51
			if (isset($urlParts[0])) $this->resource = $urlParts[0];
52
			if (count($urlParts) > 1 && $urlParts[1] != '') {
52
			if (count($urlParts) > 1 && $urlParts[1] != '') {
53
				array_shift($urlParts);
53
				array_shift($urlParts);
54
				foreach ($urlParts as $uid) {
54
				foreach ($urlParts as $uid) {
55
					if ($uid != '') {
55
					if ($uid != '') {
56
						$this->uid[] = urldecode($uid);
56
						$this->uid[] = urldecode($uid);
57
					}
57
					}
58
				}
58
				}
59
			}
59
			}
60
 
60
 
61
			$this->method = $_SERVER['REQUEST_METHOD'];
61
			$this->method = $_SERVER['REQUEST_METHOD'];
62
		} else {
62
		} else {
63
			trigger_error('I require the server variables REQUEST_URI, REQUEST_METHOD and QUERY_STRING to work.', E_USER_ERROR);
63
			trigger_error('I require the server variables REQUEST_URI, REQUEST_METHOD and QUERY_STRING to work.', E_USER_ERROR);
64
		}
64
		}
65
	}
65
	}
66
 
66
 
67
	/**
67
	/**
68
	 * Execute the request.
68
	 * Execute the request.
69
	 */
69
	 */
70
	function exec() {
70
	function exec() {
71
		switch ($this->method) {
71
		switch ($this->method) {
72
			case 'GET':
72
			case 'GET':
73
				$this->get();
73
				$this->get();
74
				break;
74
				break;
75
			case 'POST':
75
			case 'POST':
76
				$this->post();
76
				$this->post();
77
				break;
77
				break;
78
			case 'DELETE':
78
			case 'DELETE':
79
				$this->delete();
79
				$this->delete();
80
				break;
80
				break;
81
			case 'PUT':
81
			case 'PUT':
82
				$this->add();
82
				$this->add();
83
				break;
83
				break;
84
		}
84
		}
85
	}
85
	}
86
 
86
 
87
	/**
87
	/**
88
	 * Execute a GET request. A GET request fetches a list of resource when no resource name is given, a list of element
88
	 * Execute a GET request. A GET request fetches a list of resource when no resource name is given, a list of element
89
	 * when a resource name is given, or a resource element when a resource and resource unique identifier are given. It does not change the
89
	 * when a resource name is given, or a resource element when a resource and resource unique identifier are given. It does not change the
90
	 * database contents.
90
	 * database contents.
91
	 */
91
	 */
92
	private function get() {
92
	private function get() {
93
		if ($this->resource) {
93
		if ($this->resource) {
94
			$resource_file = 'services/'.ucfirst($this->resource).'.php';
94
			$resource_file = 'services/'.ucfirst($this->resource).'.php';
95
			$resource_class = ucfirst($this->resource);
95
			$resource_class = ucfirst($this->resource);
96
			if (file_exists($resource_file))  {
96
			if (file_exists($resource_file))  {
97
				include_once $resource_file;
97
				include_once $resource_file;
98
				if (class_exists($resource_class)) {
98
				if (class_exists($resource_class)) {
99
					$service = new $resource_class($this->config);
99
					$service = new $resource_class($this->config);
100
					if ($this->uid) { // get a resource element
100
					if ($this->uid) { // get a resource element
101
						if (method_exists($service, 'getElement')) {
101
						if (method_exists($service, 'getElement')) {
102
							$service->getElement($this->uid);
102
							$service->getElement($this->uid);
103
						}
103
						}
104
					} elseif (method_exists($service, 'getRessource')) { // get all elements of a ressource
104
					} elseif (method_exists($service, 'getRessource')) { // get all elements of a ressource
105
						$service->getRessource();
105
						$service->getRessource();
106
					}
106
					}
107
				}
107
				}
108
			}
108
			}
109
		} else { // get resources
109
		} else { // get resources
110
			// include set.jrest.php, instanticiation et appel
110
			// include set.jrest.php, instanticiation et appel
111
		}
111
		}
112
	}
112
	}
113
 
113
 
114
	private function post() {
114
	private function post() {
115
	   	$pairs = array();
115
	   	$pairs = array();
116
		// Récupération des paramètres passés dans le contenu de la requête HTTP (= POST)
116
		// Récupération des paramètres passés dans le contenu de la requête HTTP (= POST)
117
	   	if ($this->requestData) {
117
	   	if ($this->requestData) {
118
			$pairs = $this->parseRequestData();
118
			$pairs = $this->parseRequestData();
119
		}
119
		}
120
 
120
 
121
		// Ajout des informations concernant l'upload de fichier passées dans la variable $_FILE
121
		// Ajout des informations concernant l'upload de fichier passées dans la variable $_FILE
122
		if(isset($_FILES)) {
122
		if(isset($_FILES)) {
123
			foreach ($_FILES as $v) {
123
			foreach ($_FILES as $v) {
124
				$pairs[$v['name']] = $v;
124
				$pairs[$v['name']] = $v;
125
			}
125
			}
126
 
126
 
127
			// Ne pas effacer cette ligne ! Elle est indispensable pour les services du Carnet en ligne
127
			// Ne pas effacer cette ligne ! Elle est indispensable pour les services du Carnet en ligne
128
			// qui n'utilisent que le tableau pairs dans les posts
128
			// qui n'utilisent que le tableau pairs dans les posts
129
			$pairs = array_merge($pairs, $_POST);
129
			$pairs = array_merge($pairs, $_POST);
130
		}
130
		}
131
 
131
 
132
		// gestion du contenu du post
132
		// gestion du contenu du post
133
		if(isset($_POST))
133
		if(isset($_POST))
134
		{
134
		{
135
			// Safari ne sait pas envoyer des DELETE avec gwt...
135
			// Safari ne sait pas envoyer des DELETE avec gwt...
136
			// Nous utilisons le parametre "action" passé dans le POST qui doit contenir DELETE pour lancer la supression
136
			// Nous utilisons le parametre "action" passé dans le POST qui doit contenir DELETE pour lancer la supression
137
			if ($pairs['action'] == 'DELETE') {
137
			if (isset($pairs['action']) && $pairs['action'] == 'DELETE') {
138
				$this->delete();
138
				$this->delete();
139
				return;
139
				return;
140
			}
140
			}
141
 
141
 
142
			if (count($pairs) != 0) {
142
			if (count($pairs) != 0) {
143
				if ($this->uid) { // get a resource element
143
				if ($this->uid) { // get a resource element
144
					$resource_file = 'services/'.ucfirst($this->resource).'.php';
144
					$resource_file = 'services/'.ucfirst($this->resource).'.php';
145
					$resource_class = ucfirst($this->resource);
145
					$resource_class = ucfirst($this->resource);
146
					if (file_exists($resource_file)) {
146
					if (file_exists($resource_file)) {
147
						include_once $resource_file;
147
						include_once $resource_file;
148
						if (class_exists($resource_class)) {
148
						if (class_exists($resource_class)) {
149
							$service = new $resource_class($this->config);
149
							$service = new $resource_class($this->config);
150
							if (method_exists($service,'updateElement')) { // Update element
150
							if (method_exists($service,'updateElement')) { // Update element
151
								// TODO : a voir le retour ...
151
								// TODO : a voir le retour ...
152
								if ($service->updateElement($this->uid, $pairs)) {
152
								if ($service->updateElement($this->uid, $pairs)) {
153
									$this->created();
153
									$this->created();
154
								}
154
								}
155
							}
155
							}
156
						}
156
						}
157
					}
157
					}
158
				} else { // get all elements of a ressource
158
				} else { // get all elements of a ressource
159
					$this->add($pairs);
159
					$this->add($pairs);
160
				}
160
				}
161
			} else {
161
			} else {
162
				$this->lengthRequired();
162
				$this->lengthRequired();
163
			}
163
			}
164
		}
164
		}
165
	}
165
	}
166
 
166
 
167
	private function delete() {
167
	private function delete() {
168
		$resource_file = 'services/'.ucfirst($this->resource).'.php';
168
		$resource_file = 'services/'.ucfirst($this->resource).'.php';
169
		$resource_class = ucfirst($this->resource);
169
		$resource_class = ucfirst($this->resource);
170
		if (file_exists($resource_file)) {
170
		if (file_exists($resource_file)) {
171
			include_once $resource_file;
171
			include_once $resource_file;
172
			if (class_exists($resource_class)) {
172
			if (class_exists($resource_class)) {
173
				$service = new $resource_class($this->config);
173
				$service = new $resource_class($this->config);
174
				if ($this->uid) { // get a resource element
174
				if ($this->uid) { // get a resource element
175
		 			if (method_exists($service, 'deleteElement')) { // Delete element
175
		 			if (method_exists($service, 'deleteElement')) { // Delete element
176
						if ($service->deleteElement($this->uid)) {
176
						if ($service->deleteElement($this->uid)) {
177
							$this->noContent();
177
							$this->noContent();
178
						}
178
						}
179
	 				}
179
	 				}
180
				}
180
				}
181
			}
181
			}
182
		}
182
		}
183
	}
183
	}
184
 
184
 
185
	private function add($pairs = null) {
185
	private function add($pairs = null) {
186
		if (is_null($pairs)) {
186
		if (is_null($pairs)) {
187
			$pairs = array();
187
			$pairs = array();
188
			// Récupération des paramètres passés dans le contenu de la requête HTTP (= POST)
188
			// Récupération des paramètres passés dans le contenu de la requête HTTP (= POST)
189
			// FIXME : vérifier que l'on récupère bien les données passées par PUT
189
			// FIXME : vérifier que l'on récupère bien les données passées par PUT
190
		   	if ($this->requestData) {
190
		   	if ($this->requestData) {
191
				$pairs = $this->parseRequestData();
191
				$pairs = $this->parseRequestData();
192
			}
192
			}
193
		}
193
		}
194
 
194
 
195
		if (count($pairs) != 0) {
195
		if (count($pairs) != 0) {
196
			$resource_file = 'services/'.ucfirst($this->resource).'.php';
196
			$resource_file = 'services/'.ucfirst($this->resource).'.php';
197
			$resource_class = ucfirst($this->resource);
197
			$resource_class = ucfirst($this->resource);
198
			if (file_exists($resource_file)) {
198
			if (file_exists($resource_file)) {
199
				include_once $resource_file;
199
				include_once $resource_file;
200
				if (class_exists($resource_class)) {
200
				if (class_exists($resource_class)) {
201
					$service = new $resource_class($this->config);
201
					$service = new $resource_class($this->config);
202
					if (method_exists($service,'createElement')) { // Create a new element
202
					if (method_exists($service,'createElement')) { // Create a new element
203
						if ($service->createElement($pairs)) {
203
						if ($service->createElement($pairs)) {
204
							$this->created();
204
							$this->created();
205
						}
205
						}
206
					}
206
					}
207
				}
207
				}
208
			}
208
			}
209
		} else {
209
		} else {
210
			$this->lengthRequired();
210
			$this->lengthRequired();
211
		}
211
		}
212
	}
212
	}
213
 
213
 
214
	/**
214
	/**
215
	 * Parse the HTTP request data.
215
	 * Parse the HTTP request data.
216
	 * @return str[] Array of name value pairs
216
	 * @return str[] Array of name value pairs
217
	 */
217
	 */
218
	private function parseRequestData() {
218
	private function parseRequestData() {
219
		$values = array();
219
		$values = array();
220
		$pairs = explode('&', $this->requestData);
220
		$pairs = explode('&', $this->requestData);
221
		foreach ($pairs as $pair) {
221
		foreach ($pairs as $pair) {
222
			$parts = explode('=', $pair);
222
			$parts = explode('=', $pair);
223
			if (isset($parts[0]) && isset($parts[1])) {
223
			if (isset($parts[0]) && isset($parts[1])) {
224
				$parts[1] = rtrim(urldecode($parts[1]));
224
				$parts[1] = rtrim(urldecode($parts[1]));
225
				$values[$parts[0]] = $parts[1];
225
				$values[$parts[0]] = $parts[1];
226
			}
226
			}
227
		}
227
		}
228
		return $values;
228
		return $values;
229
	}
229
	}
230
 
230
 
231
	/**
231
	/**
232
	 * Send a HTTP 201 response header.
232
	 * Send a HTTP 201 response header.
233
	 */
233
	 */
234
	private function created($url = FALSE) {
234
	private function created($url = FALSE) {
235
		header('HTTP/1.0 201 Created');
235
		header('HTTP/1.0 201 Created');
236
		if ($url) {
236
		if ($url) {
237
			header('Location: '.$url);
237
			header('Location: '.$url);
238
		}
238
		}
239
	}
239
	}
240
 
240
 
241
	/**
241
	/**
242
	 * Send a HTTP 204 response header.
242
	 * Send a HTTP 204 response header.
243
	 */
243
	 */
244
	private function noContent() {
244
	private function noContent() {
245
		header('HTTP/1.0 204 No Content');
245
		header('HTTP/1.0 204 No Content');
246
	}
246
	}
247
 
247
 
248
	/**
248
	/**
249
	 * Send a HTTP 400 response header.
249
	 * Send a HTTP 400 response header.
250
	 */
250
	 */
251
	private function badRequest() {
251
	private function badRequest() {
252
		header('HTTP/1.0 400 Bad Request');
252
		header('HTTP/1.0 400 Bad Request');
253
	}
253
	}
254
 
254
 
255
	/**
255
	/**
256
	 * Send a HTTP 401 response header.
256
	 * Send a HTTP 401 response header.
257
	 */
257
	 */
258
	private function unauthorized($realm = 'JRest') {
258
	private function unauthorized($realm = 'JRest') {
259
		if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
259
		if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
260
			header('WWW-Authenticate: Basic realm="'.$realm.'"');
260
			header('WWW-Authenticate: Basic realm="'.$realm.'"');
261
		}
261
		}
262
		header('HTTP/1.0 401 Unauthorized');
262
		header('HTTP/1.0 401 Unauthorized');
263
	}
263
	}
264
 
264
 
265
	/**
265
	/**
266
	 * Send a HTTP 404 response header.
266
	 * Send a HTTP 404 response header.
267
	 */
267
	 */
268
	private function notFound() {
268
	private function notFound() {
269
		header('HTTP/1.0 404 Not Found');
269
		header('HTTP/1.0 404 Not Found');
270
	}
270
	}
271
 
271
 
272
	/**
272
	/**
273
	 * Send a HTTP 405 response header.
273
	 * Send a HTTP 405 response header.
274
	 */
274
	 */
275
	private function methodNotAllowed($allowed = 'GET, HEAD') {
275
	private function methodNotAllowed($allowed = 'GET, HEAD') {
276
		header('HTTP/1.0 405 Method Not Allowed');
276
		header('HTTP/1.0 405 Method Not Allowed');
277
		header('Allow: '.$allowed);
277
		header('Allow: '.$allowed);
278
	}
278
	}
279
 
279
 
280
	/**
280
	/**
281
	 * Send a HTTP 406 response header.
281
	 * Send a HTTP 406 response header.
282
	 */
282
	 */
283
	private function notAcceptable() {
283
	private function notAcceptable() {
284
		header('HTTP/1.0 406 Not Acceptable');
284
		header('HTTP/1.0 406 Not Acceptable');
285
		echo join(', ', array_keys($this->config['renderers']));
285
		echo join(', ', array_keys($this->config['renderers']));
286
	}
286
	}
287
 
287
 
288
	/**
288
	/**
289
	 * Send a HTTP 411 response header.
289
	 * Send a HTTP 411 response header.
290
	 */
290
	 */
291
	private function lengthRequired() {
291
	private function lengthRequired() {
292
		header('HTTP/1.0 411 Length Required');
292
		header('HTTP/1.0 411 Length Required');
293
	}
293
	}
294
 
294
 
295
	/**
295
	/**
296
	 * Send a HTTP 500 response header.
296
	 * Send a HTTP 500 response header.
297
	 */
297
	 */
298
	private function internalServerError() {
298
	private function internalServerError() {
299
		header('HTTP/1.0 500 Internal Server Error');
299
		header('HTTP/1.0 500 Internal Server Error');
300
	}
300
	}
301
}
301
}
302
?>
302
?>