These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | require_once('class.FlipSession.php'); |
||
3 | require_once('libs/Slim/Slim/Slim.php'); |
||
4 | require_once('Autoload.php'); |
||
5 | \Slim\Slim::registerAutoloader(); |
||
6 | |||
7 | const SUCCESS = 0; |
||
8 | const UNRECOGNIZED_METHOD = 1; |
||
9 | const INVALID_PARAM = 2; |
||
10 | const ALREADY_LOGGED_IN = 3; |
||
11 | const INVALID_LOGIN = 4; |
||
12 | const ACCESS_DENIED = 5; |
||
13 | const INTERNAL_ERROR = 6; |
||
14 | |||
15 | const UNKNOWN_ERROR = 255; |
||
16 | |||
17 | class OAuth2Auth extends \Slim\Middleware |
||
18 | { |
||
19 | protected $headers = array(); |
||
20 | |||
21 | public function __construct($headers) |
||
22 | { |
||
23 | $this->headers = array_change_key_case($headers); |
||
24 | } |
||
25 | |||
26 | private function getUserFromSession() |
||
27 | { |
||
28 | if(FlipSession::isLoggedIn()) |
||
29 | { |
||
30 | return FlipSession::getUser(); |
||
31 | } |
||
32 | return false; |
||
33 | } |
||
34 | |||
35 | /* |
||
36 | * @SuppressWarnings("Superglobals") |
||
37 | * @SuppressWarnings("StaticAccess") |
||
38 | */ |
||
39 | View Code Duplication | private function getUserFromBasicAuth($header) |
|
0 ignored issues
–
show
|
|||
40 | { |
||
41 | $auth = \AuthProvider::getInstance(); |
||
42 | $auth->login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); |
||
43 | $user = FlipSession::getUser(); |
||
44 | if($user === false) |
||
45 | { |
||
46 | $data = substr($header, 6); |
||
47 | $userpass = explode(':', base64_decode($data)); |
||
48 | $user = $auth->getUserByLogin($userpass[0], $userpass[1]); |
||
49 | } |
||
50 | return $user; |
||
51 | } |
||
52 | |||
53 | /* |
||
54 | * @SuppressWarnings("StaticAccess") |
||
55 | */ |
||
56 | private function getUserFromToken($header) |
||
57 | { |
||
58 | $auth = \AuthProvider::getInstance(); |
||
59 | $key = substr($header, 7); |
||
60 | return $auth->getUserByAccessCode($key); |
||
61 | } |
||
62 | |||
63 | View Code Duplication | private function getUserFromHeader($header) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
64 | { |
||
65 | if(strncmp($header, 'Basic', 5) == 0) |
||
66 | { |
||
67 | return $this->getUserFromBasicAuth($header); |
||
68 | } |
||
69 | return $this->getUserFromToken($header); |
||
70 | } |
||
71 | |||
72 | public function call() |
||
73 | { |
||
74 | // no auth header |
||
75 | if(!isset($this->headers['Authorization'])) |
||
76 | { |
||
77 | $this->app->user = $this->getUserFromSession(); |
||
78 | } |
||
79 | else |
||
80 | { |
||
81 | $header = $this->headers['Authorization']; |
||
82 | $this->app->user = $this->getUserFromHeader($header); |
||
83 | } |
||
84 | |||
85 | if($this->app->user === false) |
||
86 | { |
||
87 | $this->app->getLog()->error("No user found for call"); |
||
88 | } |
||
89 | |||
90 | // this line is required for the application to proceed |
||
91 | $this->next->call(); |
||
92 | } |
||
93 | } |
||
94 | |||
95 | class FlipRESTFormat extends \Slim\Middleware |
||
96 | { |
||
97 | private function fix_encoded_element($key, $value, &$array, $prefix = '') |
||
98 | { |
||
99 | if(is_array($value)) |
||
100 | { |
||
101 | $array[$key] = implode(';', $value); |
||
102 | } |
||
103 | else if($key === '_id' && is_object($value)) |
||
104 | { |
||
105 | $array[$key] = $value->{'$id'}; |
||
106 | } |
||
107 | else if(is_object($value)) |
||
108 | { |
||
109 | $array[$key] = $this->app->request->getUrl().$this->app->request->getPath().$prefix.'/'.$key; |
||
110 | } |
||
111 | else if(strncmp($value, 'data:', 5) === 0) |
||
112 | { |
||
113 | $array[$key] = $this->app->request->getUrl().$this->app->request->getPath().$prefix.'/'.$key; |
||
114 | } |
||
115 | } |
||
116 | |||
117 | private function createCSV(&$array) |
||
118 | { |
||
119 | if(count($array) == 0) |
||
120 | { |
||
121 | return null; |
||
122 | } |
||
123 | ob_start(); |
||
124 | $df = fopen("php://output", 'w'); |
||
125 | if(is_array($array)) |
||
126 | { |
||
127 | $first = reset($array); |
||
128 | $keys = FALSE; |
||
129 | View Code Duplication | if(is_array($first)) |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
130 | { |
||
131 | $keys = array_keys($first); |
||
132 | } |
||
133 | else if(is_object($first)) |
||
134 | { |
||
135 | $keys = array_keys(get_object_vars($first)); |
||
136 | } |
||
137 | fputcsv($df, $keys); |
||
138 | foreach($array as $row) |
||
139 | { |
||
140 | if(is_array($row)) |
||
141 | { |
||
142 | $id = $row[$keys[0]]; |
||
143 | foreach($row as $key=>$value) |
||
144 | { |
||
145 | $this->fix_encoded_element($key, $value, $row, '/'.$id); |
||
146 | } |
||
147 | fputcsv($df, $row); |
||
148 | } |
||
149 | else if(is_object($row)) |
||
150 | { |
||
151 | $keyName = $keys[0]; |
||
152 | $id = $row->$keyName; |
||
153 | if(is_object($id)) |
||
154 | { |
||
155 | $id = $id->{'$id'}; |
||
156 | } |
||
157 | $values = get_object_vars($row); |
||
158 | foreach($values as $key=>$value) |
||
159 | { |
||
160 | $this->fix_encoded_element($key, $value, $values, '/'.$id); |
||
161 | } |
||
162 | fputcsv($df, $values); |
||
163 | } |
||
164 | } |
||
165 | } |
||
166 | else |
||
167 | { |
||
168 | $array = get_object_vars($array); |
||
169 | fputcsv($df, array_keys($array)); |
||
170 | foreach($array as $key=>$value) |
||
171 | { |
||
172 | $this->fix_encoded_element($key, $value, $array); |
||
173 | } |
||
174 | fputcsv($df, $array); |
||
175 | } |
||
176 | fclose($df); |
||
177 | return ob_get_clean(); |
||
178 | } |
||
179 | |||
180 | private function collapseEntityToArray($entity, &$array, $keyPrefix='') |
||
181 | { |
||
182 | if(is_object($entity)) |
||
183 | { |
||
184 | $entity = (array)$entity; |
||
185 | } |
||
186 | if(array_keys($entity) === range(0, count($entity) - 1)) |
||
187 | { |
||
188 | $tmpCount = count($entity); |
||
189 | View Code Duplication | for($i = 0; $i < $tmpCount; $i++) |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
190 | { |
||
191 | $tmpKey = $keyPrefix.'['.$i.']'; |
||
192 | if(is_object($entity[$i]) || is_array($entity[$i])) |
||
193 | { |
||
194 | $this->collapseEntityToArray($entity[$i], $array, $tmpKey); |
||
195 | } |
||
196 | else |
||
197 | { |
||
198 | $array[$tmpKey] = $entity[$i]; |
||
199 | } |
||
200 | } |
||
201 | return; |
||
202 | } |
||
203 | |||
204 | foreach($entity as $key=>$data) |
||
205 | { |
||
206 | if(is_object($data)) |
||
207 | { |
||
208 | $data = get_object_vars($data); |
||
209 | } |
||
210 | |||
211 | if(is_array($data)) |
||
212 | { |
||
213 | if(array_keys($data) !== range(0, count($data) - 1)) |
||
214 | { |
||
215 | //Key array |
||
216 | foreach($data as $childKey=>$childData) |
||
217 | { |
||
218 | $tmpKey = $keyPrefix.$key.'.'.$childKey; |
||
219 | if(is_object($childData) || is_array($childData)) |
||
220 | { |
||
221 | $this->collapseEntityToArray($childData, $array, $tmpKey); |
||
222 | } |
||
223 | else |
||
224 | { |
||
225 | $array[$tmpKey] = $childData; |
||
226 | } |
||
227 | } |
||
228 | } |
||
229 | else |
||
230 | { |
||
231 | //Numeric array |
||
232 | $tmpCount = count($data); |
||
233 | View Code Duplication | for($j = 0; $j < $tmpCount; $j++) |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
234 | { |
||
235 | $tmpKey = $keyPrefix.$key.'['.$j.']'; |
||
236 | if(is_object($data[$j]) || is_array($data[$j])) |
||
237 | { |
||
238 | $this->collapseEntityToArray($data[$j], $array, $tmpKey); |
||
239 | } |
||
240 | else |
||
241 | { |
||
242 | $array[$tmpKey] = $data[$j]; |
||
243 | } |
||
244 | } |
||
245 | } |
||
246 | } |
||
247 | else |
||
248 | { |
||
249 | $array[$keyPrefix.$key] = $data; |
||
250 | } |
||
251 | } |
||
252 | } |
||
253 | |||
254 | private function createCSV2(&$array) |
||
255 | { |
||
256 | if(count($array) == 0) |
||
257 | { |
||
258 | return null; |
||
259 | } |
||
260 | if(is_object($array)) |
||
261 | { |
||
262 | $array = get_object_vars($array); |
||
263 | } |
||
264 | $rowCount = count($array); |
||
265 | $keys = array(); |
||
266 | for($i = 0; $i < $rowCount; $i++) |
||
267 | { |
||
268 | $row = $array[$i]; |
||
269 | if(is_object($row)) |
||
270 | { |
||
271 | $row = get_object_vars($row); |
||
272 | $array[$i] = $row; |
||
273 | } |
||
274 | if(isset($row['_empty_'])) |
||
275 | { |
||
276 | unset($row['_empty_']); |
||
277 | $array[$i] = $row; |
||
278 | } |
||
279 | if(isset($row['_id'])) |
||
280 | { |
||
281 | $row['_id'] = $row['_id']->{'$id'}; |
||
282 | $array[$i] = $row; |
||
283 | } |
||
284 | $newRow = array(); |
||
285 | $this->collapseEntityToArray($row, $newRow); |
||
286 | $row = $newRow; |
||
287 | $array[$i] = $row; |
||
288 | $keys = array_merge($keys, $row); |
||
289 | } |
||
290 | $keys = array_keys($keys); |
||
291 | asort($keys); |
||
292 | ob_start(); |
||
293 | $df = fopen("php://output", 'w'); |
||
294 | fputcsv($df, $keys); |
||
295 | for($i = 0; $i < $rowCount; $i++) |
||
296 | { |
||
297 | $tmp = array_fill_keys($keys, ''); |
||
298 | $row = $array[$i]; |
||
299 | $tmp = array_merge($tmp, $row); |
||
300 | ksort($tmp); |
||
301 | fputcsv($df, $tmp); |
||
302 | } |
||
303 | fclose($df); |
||
304 | return ob_get_clean(); |
||
305 | } |
||
306 | |||
307 | private function create_excel(&$array) |
||
0 ignored issues
–
show
|
|||
308 | { |
||
309 | require_once dirname(__FILE__).'/libs/PHPExcel/Classes/PHPExcel.php'; |
||
310 | $ssheat = new PHPExcel(); |
||
311 | $sheat = $ssheat->setActiveSheetIndex(0); |
||
312 | if(is_array($array)) |
||
313 | { |
||
314 | $first = reset($array); |
||
315 | $keys = false; |
||
316 | View Code Duplication | if(is_array($first)) |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
317 | { |
||
318 | $keys = array_keys($first); |
||
319 | } |
||
320 | else if(is_object($first)) |
||
321 | { |
||
322 | $keys = array_keys(get_object_vars($first)); |
||
323 | } |
||
324 | $col_count = count($keys); |
||
325 | for($i = 0; $i < $col_count; $i++) |
||
326 | { |
||
327 | $sheat->setCellValueByColumnAndRow($i, 1, $keys[$i]); |
||
328 | } |
||
329 | $row_count = count($array); |
||
330 | for($i = 0; $i < $row_count; $i++) |
||
331 | { |
||
332 | $row = $array[$i]; |
||
333 | if(is_object($row)) |
||
334 | { |
||
335 | $row = get_object_vars($row); |
||
336 | } |
||
337 | for($j = 0; $j < $col_count; $j++) |
||
338 | { |
||
339 | $colName = $keys[$j]; |
||
340 | if(isset($row[$colName])) |
||
341 | { |
||
342 | $value = $row[$colName]; |
||
343 | View Code Duplication | if(is_object($value)) |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
344 | { |
||
345 | switch($colName) |
||
346 | { |
||
347 | case '_id': |
||
348 | $value = $value->{'$id'}; |
||
349 | default: |
||
350 | $value = json_encode($value); |
||
351 | break; |
||
352 | } |
||
353 | } |
||
354 | else if(is_array($value)) |
||
355 | { |
||
356 | $value = implode(',', $value); |
||
357 | } |
||
358 | $sheat->setCellValueByColumnAndRow($j, 2 + $i, $value); |
||
359 | } |
||
360 | } |
||
361 | } |
||
362 | } |
||
363 | $writer = PHPExcel_IOFactory::createWriter($ssheat, 'Excel2007'); |
||
364 | ob_start(); |
||
365 | $writer->save('php://output'); |
||
366 | return ob_get_clean(); |
||
367 | } |
||
368 | |||
369 | private function createXML(&$array) |
||
370 | { |
||
371 | $obj = new SerializableObject($array); |
||
372 | return $obj->xmlSerialize(); |
||
373 | } |
||
374 | |||
375 | private function serializeData() |
||
376 | { |
||
377 | $data = json_decode($this->app->response->getBody()); |
||
378 | switch($this->app->fmt) |
||
379 | { |
||
380 | case 'data-table': |
||
381 | $this->app->response->headers->set('Content-Type', 'application/json'); |
||
382 | return json_encode(array('data'=>$data)); |
||
383 | View Code Duplication | case 'csv': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
384 | $this->app->response->headers->set('Content-Type', 'text/csv'); |
||
385 | $path = $this->app->request->getPathInfo(); |
||
386 | $path = strrchr($path, '/'); |
||
387 | $path = substr($path, 1); |
||
388 | $this->app->response->headers->set('Content-Disposition', 'attachment; filename='.$path.'.csv'); |
||
389 | return $this->createCSV($data); |
||
390 | View Code Duplication | case 'csv2': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
391 | $this->app->response->headers->set('Content-Type', 'text/csv'); |
||
392 | $path = $this->app->request->getPathInfo(); |
||
393 | $path = strrchr($path, '/'); |
||
394 | $path = substr($path, 1); |
||
395 | $this->app->response->headers->set('Content-Disposition', 'attachment; filename='.$path.'.csv'); |
||
396 | return $this->createCSV2($data); |
||
397 | case 'xml': |
||
398 | $this->app->response->headers->set('Content-Type', 'application/xml'); |
||
399 | return $this->createXML($data); |
||
400 | case 'passthru': |
||
401 | return $this->app->response->getBody(); |
||
402 | default: |
||
403 | return 'Unknown fmt '.$this->app->fmt; |
||
404 | } |
||
405 | } |
||
406 | |||
407 | private function getFormatFromHeader() |
||
408 | { |
||
409 | $mimeType = $this->app->request->headers->get('Accept'); |
||
410 | if(strstr($mimeType, 'odata.streaming=true')) |
||
411 | { |
||
412 | $this->app->response->setStatus(406); |
||
413 | return 'json'; |
||
414 | } |
||
415 | switch($mimeType) |
||
416 | { |
||
417 | case 'text/csv': |
||
418 | return 'csv'; |
||
419 | case 'text/x-vCard': |
||
420 | return 'vcard'; |
||
421 | default: |
||
422 | return 'json'; |
||
423 | } |
||
424 | } |
||
425 | |||
426 | private function getFormat($params) |
||
427 | { |
||
428 | $fmt = null; |
||
429 | if(isset($params['fmt'])) |
||
430 | { |
||
431 | $fmt = $params['fmt']; |
||
432 | } |
||
433 | if($fmt === null && isset($params['$format'])) |
||
434 | { |
||
435 | $fmt = $params['$format']; |
||
436 | if(strstr($fmt, 'odata.streaming=true')) |
||
437 | { |
||
438 | $this->app->response->setStatus(406); |
||
439 | return false; |
||
440 | } |
||
441 | } |
||
442 | if($fmt === null) |
||
443 | { |
||
444 | $fmt = $this->getFormatFromHeader(); |
||
445 | } |
||
446 | return $fmt; |
||
447 | } |
||
448 | |||
449 | public function call() |
||
450 | { |
||
451 | if($this->app->request->isOptions()) |
||
452 | { |
||
453 | return; |
||
454 | } |
||
455 | $params = $this->app->request->params(); |
||
456 | $fmt = $this->getFormat($params); |
||
457 | if($fmt === false) |
||
458 | { |
||
459 | return; |
||
460 | } |
||
461 | |||
462 | $this->app->fmt = $fmt; |
||
463 | $this->app->odata = new ODataParams($params); |
||
464 | |||
465 | $this->app->isLocal = false; |
||
466 | if($_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR']) |
||
467 | { |
||
468 | $this->app->isLocal = true; |
||
469 | } |
||
470 | |||
471 | $this->next->call(); |
||
472 | |||
473 | if($this->app->response->getStatus() == 200 && $this->app->fmt !== 'json') |
||
474 | { |
||
475 | $text = $this->serializeData(); |
||
476 | $this->app->response->setBody($text); |
||
477 | } |
||
478 | else if($this->app->response->getStatus() == 200) |
||
479 | { |
||
480 | $this->app->response->headers->set('Content-Type', 'application/json;odata.metadata=none'); |
||
481 | } |
||
482 | } |
||
483 | } |
||
484 | |||
485 | class FlipREST extends \Slim\Slim |
||
486 | { |
||
487 | public function __construct() |
||
488 | { |
||
489 | parent::__construct(); |
||
490 | $this->config('debug', false); |
||
491 | $headers = array(); |
||
492 | if(php_sapi_name() !== "cli") |
||
493 | { |
||
494 | $headers = apache_request_headers(); |
||
495 | } |
||
496 | $this->add(new OAuth2Auth($headers)); |
||
497 | $this->add(new FlipRESTFormat()); |
||
498 | $errorHandler = array($this, 'errorHandler'); |
||
499 | $this->error($errorHandler); |
||
500 | } |
||
501 | |||
502 | public function get_json_body($array = false) |
||
503 | { |
||
504 | return $this->getJsonBody($array); |
||
505 | } |
||
506 | |||
507 | public function getJsonBody($array = false) |
||
508 | { |
||
509 | $body = $this->request->getBody(); |
||
510 | return json_decode($body, $array); |
||
511 | } |
||
512 | |||
513 | public function errorHandler($exception) |
||
514 | { |
||
515 | $error = array( |
||
516 | 'code' => $exception->getCode(), |
||
517 | 'message' => $exception->getMessage(), |
||
518 | 'file' => $exception->getFile(), |
||
519 | 'line' => $exception->getLine(), |
||
520 | ); |
||
521 | $this->response->headers->set('Content-Type', 'application/json'); |
||
522 | error_log(print_r($error, true)); |
||
523 | echo json_encode($error); |
||
524 | } |
||
525 | |||
526 | function not_found_handler() |
||
0 ignored issues
–
show
|
|||
527 | { |
||
528 | $accept = $this->request->headers->get('Accept'); |
||
529 | if(strcmp($accept, 'application/json') == 0) |
||
530 | { |
||
531 | $error = array( |
||
532 | 'code' => 404, |
||
533 | 'message' => 'Not Found' |
||
534 | ); |
||
535 | $this->response->headers->set('Content-Type', 'application/json'); |
||
536 | $this->response->setStatus(404); |
||
537 | echo json_encode($error); |
||
538 | } |
||
539 | else |
||
540 | { |
||
541 | $this->defaultNotFound(); |
||
542 | } |
||
543 | } |
||
544 | } |
||
545 | /* vim: set tabstop=4 shiftwidth=4 expandtab: */ |
||
546 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.