private function dispatch() { try { $this->call = self::$req->scheme(); $action = self::$req->action; // the request action (method) $obj = $this->call->class; $method = $this->call->method; $preflight = $this->call->preflight; $type = self::$req->type; $model = null; $res = $this->call->resource; // the root resource presto_lib::_trace('REQUEST', "[{$this->call->file}] {$obj}::{$method} ({$this->call->type})", json_encode($this->call->params), json_encode($this->call->options)); // Create an an instance of the API subclass (autoloaded) autoload_delegate($this->call); if (!class_exists($obj)) { throw new Exception("API class not found for {$obj}::{$method}", 404); } // Start the response setup self::$resp = new response($this->call); API::attach($this->call, self::$resp, self::$req); $o = new $obj(); // Verify the request if ($obj == 'error') { // disallow root component access throw new Exception('Root access not allowed', 403); } if (!method_exists($obj, $preflight)) { if (method_exists($obj, 'autoload_model')) { // try a default model autoloader "preflight" $model = $o->autoload_model($this->call->params, $this->call->options, self::$req->body(), $this->call->type); } else { // skip + trace missing preflight functions (data will be passed as standard HTTP params) presto_lib::_trace('PREFLIGHT', 'skipped', "[{$this->call->file}] {$obj}::{$preflight} ({$this->call->type})", json_encode($this->call->params), json_encode($this->call->options)); } } else { // attempt a custom "preflight" model autoload call $model = $o->{$preflight}($this->call->params, $this->call->options, self::$req->body(), $this->call->type); } if (!method_exists($obj, $method)) { // valid route? throw new Exception("Resource {$obj}->{$method} not found.", 404); } $this->call->exists = true; // Perform the actual sub delegation if (isset($model)) { $this->call->data = $o->{$method}($model, $this->call->type); } else { $this->call->data = $o->{$method}($this->call->params, $this->call->options, self::$req->body(), $this->call->type); } // Produce a response for the client presto_lib::_trace(PRESTO_TRACE_KEY, json_encode(Presto::trace_info())); $profiles = Profiler::profiles(); // add any process profiling to trace if (!empty($profiles)) { presto_lib::_trace(PROFILER_TRACE_KEY, json_encode($profiles)); } $encode = is_object($this->call->data) || is_array($this->call->data); return self::$resp->ok($this->call, $encode, $o->status(), $o->headers()); } catch (Exception $e) { if (self::$resp === null) { self::$resp = new response(); } self::$resp->hdr($e->getCode()); throw $e; } }