Subversion Repositories Applications.projet

Rev

Rev 363 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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