/** * Execute the router. * * @return ResponseInterface * @throws AppException * @throws RuntimeException * @throws UnexpectedValueException */ public function exec() { global $CONFIG; $this->response = $this->response->withHeader('Content-Type', $this->getOutputContentType()); $routeMethod = $this->route->getMethod(); $requestMethod = strtolower($this->request->getMethod()); // OPTIONS request, don't response if ($requestMethod == 'options') { return $this->response; } $mode = 0; //error_log('[exec] >>>>>>>'.$routeMethod.'####'.$requestMethod); if (!is_null($routeMethod) && $routeMethod != $requestMethod) { if ($CONFIG->strict) { throw new AppException('Request method does not match the route request method.'); } else { error_log(sprintf('[WARING] Request method `%s` does not match the route request method `%s`.', $requestMethod, $routeMethod)); } } else { $mode = $requestMethod == 'get' ? 1 : 2; } if ($this->hasAction()) { $params = $this->getFilteredParams($mode); if (count($this->invalid)) { error_log('Invalid inputs: ' . var_export($this->invalid, true)); $invalidKeys = array_map(function ($item) { return $item['name'] . ' - ' . $item['code']; }, $this->invalid); throw new RuntimeException('Invalid inputs : ' . implode(',', array_values($invalidKeys))); } $context = new Context($this->request); $params = array_merge(array('_CONTEXT_' => $context), $params); //$result = call_user_func_array(array($this->controller, $this->getNormalizedAction()), $params); $closure = $this->controllerClosure; $result = $closure($this->getNormalizedAction(), $params); error_log('###############' . var_export($result, true)); if ($CONFIG->strict && (is_null($result) || !is_numeric($result))) { throw new UnexpectedValueException('Controller must return numeric value.'); } $statusMessage = $this->controller->getStatusMessage(); if (!is_null($result)) { $statusCode = $result; } else { $statusCode = $this->controller->getStatusCode(); if (is_null($result)) { $statusCode = Constants::SYS_SUCCESS; error_log('[WARNING] ' . $this->controllerClassName . ' ' . $this->getNormalizedAction() . ' has not return code, use default return code.'); } } $outputs = $this->controller->getOutputs(); $json = array('status' => (int) $statusCode, 'msg' => (string) $statusMessage); if (!empty($outputs)) { $json['data'] = $outputs; } return $this->processResponse($json, $this->response); } else { throw new AppException(sprintf('Action %s not found in Controller %s', $this->getNormalizedAction(), $this->getControllerClassName())); } }