Subversion Repositories eFlore/Applications.cel

Rev

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