Source of file Controller.php
Size: 9,640 Bytes - Last Modified: 2017-11-08T13:54:24+00:00
/home/travis/build/bluzphp/framework/src/Controller/Controller.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 | <?php /** * Bluz Framework Component * * @copyright Bluz PHP Team * @link https://github.com/bluzphp/framework */ declare(strict_types=1); namespace Bluz\Controller; use Bluz\Application\Application; use Bluz\Auth\EntityInterface; use Bluz\Common\Exception\CommonException; use Bluz\Common\Exception\ComponentException; use Bluz\Common\Helper; use Bluz\Proxy\Cache; use Bluz\Proxy\Logger; use Bluz\Response\ResponseTrait; use Bluz\View\View; /** * Statement * * @package Bluz\Controller * @author Anton Shevchuk * * @method void attachment(string $file) * @method void checkHttpAccept() * @method void checkHttpMethod() * @method void checkPrivilege() * @method void denied() * @method void disableLayout() * @method void disableView() * @method Controller dispatch(string $module, string $controller, array $params = []) * @method void redirect(string $url) * @method void redirectTo(string $module, string $controller, array $params = []) * @method void reload() * @method bool isAllowed($privilege) * @method void useJson() * @method void useLayout($layout) * @method EntityInterface user() */ class Controller implements \JsonSerializable { use Helper; use ResponseTrait; /** * @var string */ protected $module; /** * @var string */ protected $controller; /** * @var array */ protected $params; /** * @var string Cache key */ protected $key; /** * @var string Template name, by default is equal to controller name */ protected $template; /** * @var string */ protected $file; /** * @var Meta */ protected $meta; /** * @var Data */ protected $data; /** * Constructor of Statement * * @param string $module * @param string $controller * @param array $params * * @throws CommonException */ public function __construct($module, $controller, array $params = []) { // initial default helper path $this->addHelperPath(__DIR__ . '/Helper/'); $this->setModule($module); $this->setController($controller); $this->setParams($params); $this->setTemplate($controller . '.phtml'); $this->key = "data.$module.$controller." . md5(http_build_query($params)); } /** * @return string */ public function getModule(): string { return $this->module; } /** * @param string $module */ protected function setModule(string $module) { $this->module = $module; } /** * @return string */ public function getController(): string { return $this->controller; } /** * @param string $controller */ protected function setController(string $controller) { $this->controller = $controller; } /** * @return array */ public function getParams(): array { return $this->params; } /** * @param array $params */ protected function setParams(array $params) { $this->params = $params; } /** * @return string */ public function getTemplate() { return $this->template; } /** * @param string $template */ protected function setTemplate(string $template) { $this->template = $template; } /** * Run controller logic * * @return Data * @throws ComponentException * @throws ControllerException */ public function run(): Data { if (!$this->loadData()) { $this->process(); $this->saveData(); } return $this->data; } /** * Controller run * * @return Data * @throws ComponentException * @throws ControllerException */ protected function process(): Data { // initial variables for use inside controller $module = $this->module; $controller = $this->controller; $params = $this->params; /** * @var \closure $controllerClosure */ $controllerClosure = include $this->getFile(); if (!is_callable($controllerClosure)) { throw new ControllerException("Controller is not callable '{$module}/{$controller}'"); } // process params $params = $this->getMeta()->params($params); // call Closure or Controller $result = $controllerClosure(...$params); // switch statement for result of Closure run switch (true) { case ($result === false): // return "false" is equal to disable view and layout $this->disableLayout(); $this->disableView(); break; case is_string($result): // return string variable is equal to change view template $this->setTemplate($result); break; case is_array($result): // return associative array is equal to setup view data $this->getData()->setFromArray($result); break; case ($result instanceof Controller): // return Controller - just extract data from it $this->getData()->setFromArray($result->getData()->toArray()); break; } return $this->getData(); } /** * Setup controller file * * @return void * @throws ControllerException */ protected function findFile() { $path = Application::getInstance()->getPath(); $file = "$path/modules/{$this->module}/controllers/{$this->controller}.php"; if (!file_exists($file)) { throw new ControllerException("Controller file not found '{$this->module}/{$this->controller}'", 404); } $this->file = $file; } /** * Get controller file path * * @return string * @throws ControllerException */ protected function getFile(): string { if (!$this->file) { $this->findFile(); } return $this->file; } /** * Retrieve reflection for anonymous function * * @return void * @throws ComponentException * @throws ControllerException */ protected function initMeta() { // cache for reflection data $cacheKey = "meta.{$this->module}.{$this->controller}"; if (!$meta = Cache::get($cacheKey)) { $meta = new Meta($this->getFile()); $meta->process(); Cache::set( $cacheKey, $meta, Cache::TTL_NO_EXPIRY, ['system', 'meta'] ); } $this->meta = $meta; } /** * Get meta information * * @return Meta * @throws ControllerException * @throws ComponentException */ public function getMeta(): Meta { if (!$this->meta) { $this->initMeta(); } return $this->meta; } /** * Assign key/value pair to Data object * * @param string $key * @param mixed $value * * @return void */ public function assign($key, $value) { $this->getData()->set($key, $value); } /** * Get controller Data container * * @return Data */ public function getData(): Data { if (!$this->data) { $this->data = new Data(); } return $this->data; } /** * Load Data from cache * * @return bool * @throws ComponentException * @throws ControllerException */ private function loadData(): bool { $cacheTime = $this->getMeta()->getCache(); if ($cacheTime && $cached = Cache::get($this->key)) { $this->data = $cached; return true; } return false; } /** * Save Data to cache * * @return bool * @throws ComponentException * @throws ControllerException */ private function saveData(): bool { if ($cacheTime = $this->getMeta()->getCache()) { return Cache::set( $this->key, $this->getData(), $cacheTime, ['system', 'data'] ); } return false; } /** * Specify data which should be serialized to JSON * * @return Data */ public function jsonSerialize() { return $this->getData(); } /** * Magic cast to string * * @return string */ public function __toString() { if (!$this->template) { return ''; } try { // $view for use in closure $view = new View(); $path = Application::getInstance()->getPath(); // setup additional helper path $view->addHelperPath($path . '/layouts/helpers'); // setup additional partial path $view->addPartialPath($path . '/layouts/partial'); // setup default path $view->setPath($path . '/modules/' . $this->module . '/views'); // setup template $view->setTemplate($this->template); // setup data $view->setFromArray($this->getData()->toArray()); return $view->render(); } catch (\Exception $e) { // save log Logger::exception($e); return ''; } } } |