1: <?php
2: /**
3: * Pry Framework
4: * @copyright 2007-2011 Prynel
5: * @author Olivier ROGER <roger.olivier@gmail.com>
6: * @category Pry
7: * @package Net
8: * @version $Revision: 248 $
9: */
10:
11: /**
12: * Server REST pour webservice
13: * @category Pry
14: * @package Net
15: * @subpackage REST
16: * @version 0.1.0
17: * @author Olivier ROGER <roger.olivier@gmail.com>
18: * @copyright 2007-2011 Prynel
19: * @abstract
20: *
21: */
22: class Net_REST_Server
23: {
24: /**
25: * Méthode utiliser pour la requête (POST,GET,PUT,DELETE)
26: * @var string
27: */
28: private $method;
29:
30: /**
31: * URL complète
32: * @var string
33: */
34: private $path;
35:
36: /**
37: * Liste des méthodes supportée par le webservice
38: * @var array
39: */
40: private $supportedMethods = array();
41:
42: /**
43: * Objet métier gérant les requêtes
44: * @var Net_REST_Components
45: */
46: private $businessLogic = null;
47:
48: /**
49: * Action à appeler
50: * @var string
51: */
52: private $action;
53:
54: /**
55: * Les arguments présents dans l'url après l'action
56: * @var array
57: */
58: private $args;
59:
60: /**
61: * Les données passées dans la requêtes via query string
62: * @var array
63: */
64: private $datas;
65:
66: /**
67: * Constructeur
68: * @param array $methods Liste des méthodes supportée
69: * @param Net_REST_Components $objetMetier
70: */
71: public function __construct(array $methods,$objetMetier)
72: {
73: if(!empty($methods))
74: $this->supportedMethods = $methods;
75: else
76: $this->supportedMethods = array('GET','PUT','DELETE','POST');
77:
78: $this->path = $_SERVER['REQUEST_URI'];
79: $this->method = $_SERVER['REQUEST_METHOD'];
80: $this->datas = array();
81: $this->businessLogic = $objetMetier;
82: }
83:
84: /**
85: * Défini un sous dossier si jamais le webservice n'est pas dans un vhost
86: * @param string $sub
87: */
88: public function setSubFolder($sub)
89: {
90: if(!empty($sub))
91: $this->path = str_replace($sub,'',$this->path);
92: }
93:
94: /**
95: * Appèles les méthodes de l'objet métier en fonction des requêtes
96: */
97: public function handleRequest()
98: {
99: if(in_array($this->method,$this->supportedMethods))
100: {
101: $method = strtolower($this->method);
102: $this->processUrl();
103: $toCall = $this->businessLogic->$method($this->action,$this->args,$this->datas);
104: if($toCall)
105: header('OK', true, 200);
106: else
107: $this->errorBusiness();
108: }
109: else
110: {
111: $this->errorMethod();
112: }
113: }
114:
115: /**
116: * Parse l'url et les données.
117: */
118: private function processUrl()
119: {
120: $items = explode('/',$this->path);
121: $this->clearEmptyValue($items);
122: if(!empty($items))
123: {
124: $this->action = array_shift($items);
125: $this->args = $items;
126:
127: //Si methode != de get ou post on récupères les données dans le stream php://input
128: if($this->method == 'GET')
129: $this->datas = $_GET;
130: elseif($this->method == 'POST')
131: $this->datas = $_POST;
132: else
133: parse_str(file_get_contents('php://input'),$this->datas);
134: }
135: }
136:
137: /**
138: * Nettoie un tableau de ses éléments vide
139: * @param array $array
140: */
141: private function clearEmptyValue(&$array)
142: {
143: foreach($array as $key => $value) {
144: if (empty($value))
145: unset($array[$key]);
146: }
147: }
148:
149: /**
150: * Envoi d'une requête avec une méthode non supportée
151: */
152: private function errorMethod()
153: {
154: $methods = implode(',',$this->supportedMethods);
155: header('Allow: ' . $methods, true, 405);
156: }
157:
158: /**
159: * Appel d'une action innexistante
160: */
161: private function errorBusiness()
162: {
163: header('HTTP/1.1 404 Not Found', true, 404);
164: }
165: }
166: ?>
167: