/** * @param string $name * @param string|\MVCFundamental\Interfaces\ControllerInterface $controller * @return mixed */ public function locateControllerAction($name, $controller) { $controller = $this->locateController($controller); if (!is_null($controller)) { if (method_exists($controller, $name)) { return $name; } $mask = FrontController::getInstance()->getOption('action_name_finder'); $full_name = sprintf($mask, Helper::getPropertyName($name, '_', false)); if (method_exists($controller, $full_name)) { return $full_name; } } return null; }
/** * Build the global layout with all children contents * * @param array $params An array of the parameters passed for the view parsing * @return string Returns the view file content rendering */ public function renderLayout(array $params = array()) { $params = array_merge($this->getParams(), $params); $children = array(); foreach ($this->_children as $name => $item) { if (Helper::classImplements($item, AppKernel::getApi('template'))) { $children[$name] = $item->render(); } else { $children[$name] = $item; } } $params = array_merge($params, $children); $params['children'] = $children; return $this->render($this->getView(), $params); }
/** * @param \MVCFundamental\Interfaces\FrontControllerInterface $app * @return void * @throws \MVCFundamental\Exception\ErrorException */ public static function boot(FrontControllerInterface $app) { // stores the FrontController self::setFrontController($app); // define internal handlers set_exception_handler(array(__CLASS__, 'handleException')); register_shutdown_function(array(__CLASS__, 'handleShutdown')); if (self::getFrontController()->getOption('convert_error_to_exception') == true) { set_error_handler(array(__CLASS__, 'handleError')); } // the required temporary directory $tmp_dir = self::getFrontController()->getOption('temp_dir'); if (empty($tmp_dir) || !file_exists($tmp_dir) && !@DirectoryHelper::create($tmp_dir) || !is_dir($tmp_dir) || !is_writable($tmp_dir)) { $tmp_dir = DirectoryHelper::slashDirname(sys_get_temp_dir()) . 'mvc-fundamental'; if (!@DirectoryHelper::ensureExists($tmp_dir)) { throw new ErrorException(sprintf('The "%s" temporary directory can not be created or is not writable (and a default one could not be taken)!', $tmp_dir)); } self::getFrontController()->setOption('temp_dir', $tmp_dir); } // the application logger if (self::getFrontController()->getOption('minimum_log_level') == null) { self::getFrontController()->setOption('log_level', self::getFrontController()->isMode('production') ? Logger::WARNING : Logger::DEBUG); } $logger_options = array('duplicate_errors' => false, 'directory' => self::getFrontController()->getOption('temp_dir'), 'minimum_log_level' => self::getFrontController()->getOption('log_level')); $logger_class = self::getFrontController()->getOption('app_logger'); if (!class_exists($logger_class) || !Helper::classImplements($logger_class, self::getApi('logger'))) { throw new ErrorException(sprintf('A logger must exist and implement the "%s" interface (for class "%s")!', self::getApi('logger'), $logger_class)); } self::set('logger', new $logger_class($logger_options)); // load services foreach (self::getFrontController()->getOptions() as $var => $val) { if (array_key_exists($var, self::$_api)) { self::set($var, self::apiFactory($var, $val)); } if (array_key_exists($var, self::$_constructors)) { $cls_index = self::$_constructors[$var]; self::getInstance()->setProvider($var, function ($app, $name, array $arguments = array()) use($val, $cls_index) { return $app::apiFactory($cls_index, $val, $arguments); }); } } self::get('event_manager')->setEventClass(self::getFrontController()->getOption('event_item')); }
/** * @param null|string $controller * @param null|string $action * @param array $arguments * @return string * @throws \MVCFundamental\Exception\InternalServerErrorException */ public function callControllerAction($controller = null, $action = null, array $arguments = array()) { $this->boot(); $controller_name = $controller; if (empty($controller)) { $controller = $this->getOption('default_controller_name'); } if (empty($action)) { $action = $this->getOption('default_action_name'); } if (!empty($controller)) { if (!is_object($controller)) { $ctrl = $this->get('locator')->locateController($controller); if (!empty($ctrl)) { $controller = new $ctrl(); } else { throw new InternalServerErrorException(sprintf('Unknown controller "%s"!', $controller_name)); } } $arguments = array_merge(Helper::getDefaultEnvParameters(), $arguments); $action = $this->get('locator')->locateControllerAction($action, $controller); if (!method_exists($controller, $action) || !is_callable(array($controller, $action))) { throw new InternalServerErrorException(sprintf('Action "%s" in controller "%s" is not known or not callable!', $action, $controller_name)); } $result = Helper::fetchArguments($action, $arguments, $controller); // result as a raw content: a string if (is_string($result)) { return $result; // result as an array like ( view_file , params ) } elseif (is_array($result)) { $view_file = $this->get('template_engine')->getTemplate($result[0]); if (!empty($view_file)) { return $this->render($view_file, isset($result[1]) && is_array($result[1]) ? array_merge($arguments, $result[1]) : $arguments); } // a reponse object } elseif (is_object($result) && ($ri = AppKernel::getApi('response')) && $result instanceof $ri) { $this->set('response', $result); } } return ''; }
})->addRoute('/hello/{name}', function ($name) use($fctrl) { return 'Hello ' . $name; })->addRoute('/hello/{name}/controller', 'Demo\\DefaultController')->addRoute('/hello/{name}/method', 'mytest')->addRoute('/hello/{name}/view', 'src/templates/test.php')->addRoute('/hello/{name}/myview', 'myview')->addRoute('/hello/{name}/id/{id:\\d+}', 'args')->addRoute('/hello/{name}/id/{id:\\d+}/alt', 'altargs')->addRoute('/hello/{name}/test', array('\\Demo\\TestController', 'test'))->addRoute('/form', 'form')->addRoute('/saveform', 'saveForm', 'post')->addRoute('/error', function () use($fctrl) { trigger_error('a user test error ...', E_USER_ERROR); })->addRoute('/exception', function () use($fctrl) { throw new \Exception('a user test exception ...'); })->addRoute('/notfoundexception', function () use($fctrl) { throw new \MVCFundamental\Exception\NotFoundException('a user test exception ...'); })->addRoute('/accessforbiddenexception', function () use($fctrl) { throw new \MVCFundamental\Exception\AccessForbiddenException('a user test exception ...'); })->addRoute('/servererror', function () use($fctrl) { throw new \MVCFundamental\Exception\InternalServerErrorException('a user test exception ...'); })->addRoute('/twoexceptions', function () use($fctrl) { throw new \MVCFundamental\Exception\InternalServerErrorException('a user test exception ...', 1, new \MVCFundamental\Exception\Exception('a secondary (previous) exception ...')); })->addRoute('/debug', function () use($fctrl) { \MVCFundamental\Commons\Helper::debug(\MVCFundamental\AppKernel::getInstance()); })->addRoute('/logs', function () use($fctrl) { $log_dir = $fctrl->getOption('temp_dir'); $dh = opendir($log_dir); $logs = array(); $logs[] = 'LOGS DIR : ' . $log_dir; while (false !== ($filename = readdir($dh))) { if (substr($filename, -4) == '.log') { $logs[] = '##### ' . $filename; $logs[] = file_get_contents($log_dir . '/' . $filename); } } call_user_func_array(array('MVCFundamental\\Commons\\Helper', 'debug'), $logs); })->on('event.1', array('Demo\\DefaultController', 'eventHandler'))->addRoute('/test/event2', function () use($fctrl) { $fctrl->trigger('event.2'); return 'Event 2 was triggered';
/** * @param array $arguments * @return mixed */ public function getDefaultLayout(array $arguments = array()) { $view = FrontController::getInstance()->getOption('default_layout'); $class = FrontController::getInstance()->getOption('default_layout_class'); if (class_exists($class) && Helper::classImplements($class, AppKernel::getApi('layout'))) { $layout = new $class($arguments); $layout->setLayout($view); return $layout; } return null; }