/** * Match current path and get action. */ protected function service__action() { $action = $this->app->hook('request.route', $this); if (!$action) { // Dynamic assets serving support if (file_exists("{$this->path}.php")) { return new Action(function (Request $request) { return new Response\FileResponse($request, "{$request->path}.php"); }); } throw new Exception\NotFoundHttpException("No route matched path: {$this->method} /{$this->path}."); } return $action; }
protected function service__validators() { $validators = $this->options['validators']; $this->app->hook('form.validators', $this, $validators); if (!is_array($validators)) { $validators = array(); } foreach ($validators as &$validator) { if (is_string($validator)) { $validator = array('type' => $validator); } if (is_array($validator)) { if (empty($validator['type'])) { $json = json_encode($validator); throw new \LogicException("A validator array definition must contain a 'type' element, but {$json} given."); } $method = "validator__{$validator['type']}"; $validator = $this->{$method}($validator); } if ($validator instanceof \Closure) { $validator = new Validator($this, $validator); } elseif (!$validator instanceof Validator) { $json = json_encode($validator); throw new \LogicException("A validator should be either a Closure or Hydra\\Validator class."); } } return $validators; }
function handle(\Exception $exception) { if ($this->app) { try { $exception = $this->app->hook('app.exception', $this, $exception); } catch (\Exception $innerEx) { return $this->_handleNested($exception, $innerEx); } } if ($exception) { if ($this->app && !$this->app->core->debug) { try { $code = $exception instanceof HttpExceptionInterface ? $exception->getStatusCode() : 500; $response = new Response\FancyResponse(new Request\StaticRequest($this->app), array('code' => $code, 'title' => SymfonyResponse::$statusTexts[$code], 'exception' => $exception), 'error.html.twig'); $response->statusCode = $code; $response->send(); return; } catch (\Exception $innerEx) { return $this->_handleNested($exception, $innerEx); } } parent::handle($exception); } }
function send() { $this->app->hook('response.before_send', $this); // Render before sending headers, as they may be changed in sub-actions. $this->render(false); // Send headers. if ($this->headers) { $this->_sendHeaders($this->headers); } // Streaming support. if ($this->content instanceof \Closure) { $this->app->hook('response.stream', $this); } if ($this->content instanceof \Closure) { $this->app->hook('response.send', $this); $callback = $this->content; $callback($this); } else { $this->app->hook('response.send', $this, $this->content); } return $this; }
protected static function loadHooks() { // hook $hook = App::$config->get('application.hooks', ''); App::import(APP_PATH . DS . $hook['file']); App::$hook = new $hook['class'](); $hook = ['preSystem', 'preRoute', 'preController', 'preResponse', 'endSystem']; foreach ($hook as $method) { if (!method_exists(App::$hook, $method)) { exit("钩子程序需要有这几个方法" . print_r($hook, true) . ".但是系统检查到你的钩子类中缺少方法" . $method); } } }
/** * @covers \Phix\App::trigger */ public function testTrigger() { $called1 = false; $called2 = false; $app = new App(); $app->hook('init', function () use(&$called1) { $called1 = true; return false; }); $app->hook('setup', function () use(&$called2) { $called2 = true; return true; }); $ret = $app->trigger('init'); $this->assertTrue($called1); $this->assertFalse($called2); $this->assertFalse($ret); $ret = $app->trigger('setup'); $this->assertTrue($called2); $this->assertTrue($ret); }