1 | <?php |
||
20 | class ModuleEntryPoint { |
||
21 | |||
22 | /** |
||
23 | * @var RequestHandler |
||
24 | */ |
||
25 | private $requestHandler; |
||
26 | |||
27 | /** |
||
28 | * @param RequestHandler $requestHandler |
||
29 | */ |
||
30 | 7 | public function __construct(RequestHandler $requestHandler) { |
|
33 | |||
34 | /** |
||
35 | * Main function |
||
36 | */ |
||
37 | 7 | public function exec() { |
|
38 | try { |
||
39 | 7 | $this->filterRequestMethod(); |
|
40 | 7 | $request = $this->getRequest(); |
|
41 | 6 | $responses = $this->requestHandler->buildResponse($request); |
|
42 | 5 | $this->outputResponse($this->serializeResponse($this->cleanResponses($responses, $request))); |
|
43 | 7 | } catch(HttpException $e) { |
|
44 | 1 | $this->outputHttpException($e); |
|
45 | 2 | } catch(Exception $e) { |
|
46 | 1 | $this->outputHttpException(new HttpException($e->getMessage(), 500, $e)); |
|
47 | } |
||
48 | 7 | } |
|
49 | |||
50 | 7 | private function filterRequestMethod() { |
|
|
|||
51 | 7 | if(!array_key_exists('REQUEST_METHOD', $_SERVER)) { |
|
52 | 7 | return; |
|
53 | } |
||
54 | if($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { |
||
55 | exit(); |
||
56 | } |
||
57 | if($_SERVER['REQUEST_METHOD'] !== 'POST') { |
||
58 | new HttpException('Bad request method: ' . $_SERVER['REQUEST_METHOD'], 405); |
||
59 | } |
||
60 | } |
||
61 | |||
62 | /** |
||
63 | * @return ModuleRequest |
||
64 | */ |
||
65 | 7 | private function getRequest() { |
|
66 | 7 | $requestJson = json_decode($this->getRequestBody(), true); |
|
67 | try { |
||
68 | 7 | return $this->buildRequestDeserializer()->deserialize($requestJson); |
|
69 | 1 | } catch(DeserializationException $e) { |
|
70 | 1 | throw new HttpException($e->getMessage(), 400, $e); |
|
71 | } |
||
72 | } |
||
73 | |||
74 | public function getRequestBody() { |
||
77 | |||
78 | 5 | private function cleanResponses(array $responses, ModuleRequest $request) { |
|
79 | 5 | $cleanedResponses = array(); |
|
80 | |||
81 | /** @var ModuleResponse $response */ |
||
82 | 5 | foreach($responses as $response) { |
|
83 | 4 | if($request->getSentenceTree()->equals($response->getSentenceTree())) { |
|
84 | continue; |
||
85 | } |
||
86 | |||
87 | /** @var ModuleResponse $existingResponse */ |
||
88 | 4 | foreach($cleanedResponses as $existingResponse) { |
|
89 | 1 | if($existingResponse->getSentenceTree()->equals($response->getSentenceTree())) { |
|
90 | 1 | continue 2; |
|
91 | } |
||
92 | 4 | } |
|
93 | |||
94 | 4 | $cleanedResponses[] = new ModuleResponse( |
|
95 | 4 | $response->getLanguageCode(), |
|
96 | 4 | $response->getSentenceTree(), |
|
97 | 4 | $response->getMeasures() + $request->getMeasures(), |
|
98 | 4 | $response->getTrace() |
|
99 | 4 | ); |
|
100 | 5 | } |
|
101 | |||
102 | 5 | return $cleanedResponses; |
|
103 | } |
||
104 | |||
105 | 5 | private function outputResponse($serialization) { |
|
109 | |||
110 | 5 | private function serializeResponse(array $responses) { |
|
111 | 5 | $serialization = array(); |
|
112 | 5 | foreach($responses as $response) { |
|
113 | 4 | $serialization[] = $this->buildResponseSerializer()->serialize($response); |
|
114 | 5 | } |
|
115 | 5 | return $serialization; |
|
116 | } |
||
117 | |||
118 | 7 | private function buildRequestDeserializer() { |
|
122 | |||
123 | 4 | private function buildResponseSerializer() { |
|
127 | |||
128 | 2 | private function outputHttpException(HttpException $exception) { |
|
132 | |||
133 | 2 | private function setHttpResponseCode($code) { |
|
134 | 2 | if(function_exists('http_response_code')) { |
|
135 | 2 | @http_response_code($code); |
|
136 | 2 | } else { |
|
137 | @header('X-PHP-Response-Code: '. $code, true, $code); |
||
140 | } |
||
141 |
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: