forked from telabotanica/ezmlm-php
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBaseService.php
More file actions
191 lines (170 loc) · 4.94 KB
/
Copy pathBaseService.php
File metadata and controls
191 lines (170 loc) · 4.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
<?php
/*
* Base class for REST services
* @author mathias@tela-botanica.org
* @date 08/2015
*/
class BaseService {
/** JSON config */
protected $config = array();
public static $CONFIG_PATH = "config/service.json";
/** HTTP verb received (GET, POST, PUT, DELETE, OPTIONS) */
protected $verb;
/** Resources (URI elements) */
protected $resources = array();
/** Request parameters (GET or POST) */
protected $params = array();
/** Domain root (to build URIs) */
protected $domainRoot;
/** Base URI (to parse resources) */
protected $baseURI;
public function __construct() {
// config
if (file_exists(self::$CONFIG_PATH)) {
$this->config = json_decode(file_get_contents(self::$CONFIG_PATH), true);
} else {
throw new Exception("file " . self::$CHEMIN_CONFIG . " doesn't exist");
}
// HTTP method
$this->verb = $_SERVER['REQUEST_METHOD'];
// server config
$this->domainRoot = $this->config['domain_root'];
$this->baseURI = $this->config['base_uri'];
// initialization
$this->getResources();
$this->getParams();
$this->init();
}
/** Post-constructor adjustments */
protected function init() {
}
/**
* Reads the request and runs the appropriate method; catches library
* exceptions and turns them into HTTP errors with message
*/
public function run() {
try {
switch($this->verb) {
case "GET":
$this->get();
break;
case "POST":
$this->post();
break;
case "PUT":
$this->put();
break;
case "DELETE":
$this->delete();
break;
case "OPTIONS":
$this->options();
break;
default:
$this->sendError("unsupported method: $this->verb");
}
} catch(Exception $e) {
// catches lib exceptions and turns them into error 500
$this->sendError($e->getMessage(), 500);
}
}
/**
* Sends a JSON message indicating a success and exits the program
* @param type $json the message
* @param type $code defaults to 200 (HTTP OK)
*/
protected function sendJson($json, $code=200) {
header('Content-type: application/json');
http_response_code($code);
echo json_encode($json, JSON_UNESCAPED_UNICODE);
exit;
}
/**
* Sends a JSON message indicating an error and exits the program
* @param type $error a string explaining the reason for this error
* @param type $code defaults to 400 (HTTP Bad Request)
*/
protected function sendError($error, $code=400) {
header('Content-type: application/json');
http_response_code($code);
echo json_encode(array("error" => $error));
exit;
}
/**
* Compares request URI to base URI to extract URI elements (resources)
*/
protected function getResources() {
$uri = $_SERVER['REQUEST_URI'];
// slicing URI
$baseURI = $this->baseURI . "/";
if ((strlen($uri) > strlen($baseURI)) && (strpos($uri, $baseURI) !== false)) {
$baseUriLength = strlen($baseURI);
$posQM = strpos($uri, '?');
if ($posQM != false) {
$resourcesString = substr($uri, $baseUriLength, $posQM - $baseUriLength);
} else {
$resourcesString = substr($uri, $baseUriLength);
}
// decoding special characters
$resourcesString = urldecode($resourcesString);
//echo "Resources: $resourcesString" . PHP_EOL;
$this->resources = explode("/", $resourcesString);
// in case of a final /, gets rid of the last empty resource
$nbRessources = count($this->resources);
if (empty($this->resources[$nbRessources - 1])) {
unset($this->resources[$nbRessources - 1]);
}
}
}
/**
* Gets the GET or POST request parameters
*/
protected function getParams() {
$this->params = $_REQUEST;
}
/**
* Searches for parameter $name in $this->params; if defined (even if
* empty), returns its value; if undefined, returns $default; if
* $collection is a non-empty array, parameters will be searched among
* it rather than among $this->params (2-in-1-dirty-mode)
*/
protected function getParam($name, $default=null, $collection=null) {
$arrayToSearch = $this->params;
if (is_array($collection) && !empty($collection)) {
$arrayToSearch = $collection;
}
if (isset($arrayToSearch[$name])) {
return $arrayToSearch[$name];
} else {
return $default;
}
}
/**
* Reads and returns request body contents
*/
protected function readRequestBody() {
// @TODO beware of memory consumption
$contents = file_get_contents('php://input');
return $contents;
}
protected function sendFile($file, $name, $size, $mimetype='application/octet-stream') {
if (! file_exists($file)) {
$this->sendError("file does not exist");
}
header('Content-Type: ' . $mimetype);
header('Content-Disposition: attachment; filename="' . $name . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . $size);
// progressive sending
// http://www.media-division.com/the-right-way-to-handle-file-downloads-in-php/
set_time_limit(0);
$f = @fopen($file,"rb");
while(!feof($f)) {
print(fread($f, 1024*8));
ob_flush();
flush();
}
}
}