1 <?php
2
3 namespace Docolight\Rest\Http;
4
5 use Yii;
6 use Exception;
7 use CController;
8 use Docolight\Http\Response;
9
10 /**
11 * A restful controller.
12 *
13 * @author Krisan Alfa Timur <krisanalfa@docotel.co.id>
14 */
15 abstract class RestFulController extends CController
16 {
17 /**
18 * Data stored in this implementation. This data will be rendered as json response later in `afterAction` method.
19 *
20 * @var array
21 */
22 protected $data;
23
24 /**
25 * Exception stored in this implementation. When exception raised, the controller stored the exception in it.
26 *
27 * @var \Exception
28 */
29 protected $error;
30
31 /**
32 * Headers to be sent in HTTP response.
33 *
34 * @var array
35 */
36 protected $headers = [
37 'Powered-By' => 'PT. Docotel Teknologi',
38 ];
39
40 /**
41 * Handling 404 error.
42 *
43 * @param string $action
44 */
45 public function missingAction($action)
46 {
47 return response('json', 404, fluent([
48 'status' => 404,
49 'message' => 'Not Found',
50 'value' => "Request to [".Yii::app()->request->getPathInfo()."] has no resource.",
51 ]), $this->headers)->send();
52 }
53
54 /**
55 * Set an exception publicly.
56 *
57 * @param \Exception $error
58 */
59 public function setError($error)
60 {
61 // Remove the data
62 $this->data = null;
63
64 // Set new error
65 $this->error = $error;
66 }
67
68 /**
69 * After action.
70 *
71 * @param \CInlineAction $action Action from controller
72 *
73 * @return \Docolight\Http\Response
74 */
75 public function afterAction($action)
76 {
77 parent::afterAction($action);
78
79 // Basic data template
80 $statusCode = 200;
81 $data = array(
82 'status' => $statusCode,
83 'message' => 'Success',
84 'value' => $this->data,
85 );
86
87 // Let's find an error
88 if ($this->error instanceof Exception) {
89 // throw $this->error;
90
91 // Basic data template for an exception
92 $statusCode = 500;
93 $data = [
94 'status' => $statusCode,
95 'message' => 'Error',
96 'value' => [
97 'code' => $this->error->getCode(),
98 'message' => $this->error->getMessage(),
99 ],
100 ];
101
102 // If exception code is an HTTP resoponse code
103 if ($message = Response::getMessageForCode($this->error->getCode())) {
104 $statusCode = $this->error->getCode();
105 $data['status'] = $statusCode;
106 $data['message'] = preg_replace('/^\d+ /', '', $message);
107 }
108 // If not, this is a system failure
109 // Trace the error if YII_DEBUG is defined
110 else {
111 if (YII_DEBUG) {
112 $data['value']['stack_trace'] = $this->error->getTrace();
113 }
114 }
115 }
116 // If the data is a Reponse instance, send the response
117 elseif ($this->data instanceof Response) {
118 return $this->data->send();
119 }
120
121 return response('json', $statusCode, collect($data), $this->headers)->send();
122 }
123 }
124