Subversion Repositories eFlore/Applications.cel

Rev

Rev 1065 | Details | Compare with Previous | Last modification | View Log | RSS feed

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