/** * @param string $method_name * @param array $arg_list */ public final function __call($method_name, $arg_list) { $execution_record = []; $execution_id = Debug::addExecutionRecord($execution_record); Debug::pushExecutionId($execution_id); try { $execution_record = $this->prepareExecutionRecord($method_name, $arg_list); $class_name = $execution_record['class']; $input = $execution_record['input']; $method_accessibility = $execution_record['method_accessibility']; $handler_prefix = $execution_record['handler_prefix']; $handler_suffix = $execution_record['handler_suffix']; Debug::updateExecutionRecord($execution_id, $execution_record); if (FALSE === $method_accessibility) { throw new UserException("Handler({$class_name} :: {$method_name}) is not accessible.", $execution_record); } $config_model_name = $this->configModelName; if (TRUE === is_null($config_model_name) or TRUE === is_null($this->{$config_model_name})) { throw new UserException("Config model({$config_model_name}) not loaded in {$class_name}."); } // Method validateModelPrivilege should throw exception if the validation fails. $execution_record['validateModelPrivilege'] = $this->{$config_model_name}->validateModelPrivilege($handler_suffix, $method_name); $data_model_name = $this->dataModelName; if (TRUE === is_null($data_model_name) or TRUE === is_null($this->{$data_model_name})) { throw new UserException("Data model({$data_model_name}) not loaded in {$class_name}."); } // Method validateInput should throw exception if the validation fails, // and it should load the config model and fetch the config info itself. $input_validation_result = $execution_record['validateInput'] = $this->{$data_model_name}->validateInput($method_name, $input); // Now the validation passed. $execution_record['is_time_consuming'] = $is_time_consuming = $arg_list[0]; if (TRUE === $is_time_consuming) { $this->succeedRequest(NULL, NULL, TRUE); } // Method sanitizeInput should load the config model and fetch the config info itself. $input_sanitization_result = $execution_record['sanitizeInput'] = $this->{$data_model_name}->sanitizeInput($method_name, $input, $input_validation_result); $this->{$method_name}($input_sanitization_result); $service_result = $execution_record['service_result'] = Kit::extract($this->result, ['data', 'status']); $code = $this->getCode(); if (TRUE === is_null($code)) { $this->fail(); } $code = $this->getCode(); if (FALSE === Kit::in($code, [1, 2])) { throw new UserException('Invalid code after service has finished.', $code); } if (1 === $code) { $this->succeedRequest($execution_id, $execution_record); } // END NOW // Now code must be 2. // Method validateServiceResult should throw exception if the validation fails, // and it should load the config model and fetch the config info itself. // @CAUTION $service_result_validation_result = $execution_record['validateServiceResult'] = $this->{$data_model_name}->validateServiceResult($method_name, $service_result); // Now the validation passed. // Method sanitizeServiceResult should load the config model // and fetch the config info itself. $service_result_sanitization_result = $execution_record['sanitizeServiceResult'] = $this->{$data_model_name}->sanitizeServiceResult($method_name, $service_result, $service_result_validation_result); // $service_result_validation_result should contains // and only contains three fields: code, data, status. $this->result['data'] = $computation_data = $service_result_sanitization_result['data']; $this->result['status'] = $operation_status = $service_result_sanitization_result['status']; // $this->loadLog('Request'); // $this->RequestLog->addRequestLog( // $execution_record['class'], // $execution_record['method'], // $input, // $code, // $operation_status // ); $this->succeedRequest($execution_id, $execution_record); } catch (Exception $e) { $this->failRequest($execution_id, $execution_record, new UserException('Service execution failed.', $execution_record, $e)); } }