FRED™  3.0
FRED™: Framework for Rapid and Easy Development
Front.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Rsi\Fred;
4 
5 /**
6  * Front controller component.
7  */
8 class Front extends Component{
9 
10  const EVENT_RENDER = 'front:render';
11 
12  public $defaultType = 'html';
13  public $controllerNamespaces = []; //!< Namespace prefix (key) per controller name prefix (value).
14  public $validControllerName = null; //!< Regex for valid controller names (empty = do not check).
15 
16  public $defaultControllerName = 'Home';
17  public $unknownControllerName = 'Unknown';
18  public $deniedControllerName = 'Denied';
19 
20  /**
21  * Name for a controller by class name.
22  * @param string $class_name Class name for the controller.
23  * @return string Controller name.
24  */
25  public function controllerName($class_name){
26  foreach($this->controllerNamespaces as $namespace => $prefix)
27  if(($class_name == $namespace) || \Rsi\Str::startsWith($class_name,$namespace))
28  return $prefix . str_replace('\\','/',substr($class_name,strlen($namespace)));
29  return null;
30  }
31  /**
32  * Class name for a controller.
33  * @param string $name Controller name.
34  * @return string Class name for the controller.
35  */
36  public function controllerClassName($name){
37  foreach($this->controllerNamespaces as $namespace => $prefix) if(
38  (!$prefix || ($name == $prefix) || \Rsi\Str::startsWith($name,$prefix . '/')) &&
39  class_exists($class_name = $namespace . str_replace('/','\\',$prefix ? substr($name,strlen($prefix)) : '\\' . $name)) &&
40  is_subclass_of($class_name,__NAMESPACE__ . '\\Controller')
41  ) return $class_name;
42  return null;
43  }
44  /**
45  * Get controller by name.
46  * @param string $name Controller name.
47  * @param bool $redir Redirect to the denied or login controller if the user is not authorized to execute the requested
48  * controller action. Otherwise return false.
49  * @return \\Rsi\\Fred\\Controller|bool
50  */
51  public function controller($name,$redir = true){
52  $this->component('log')->debug(__CLASS__ . "::controller('$name')",__FILE__,__LINE__);
53  if($this->validControllerName && !preg_match($this->validControllerName,$name)) $name = $this->unknownControllerName;
54  if(
55  (!$name || !($class_name = $this->controllerClassName($name))) &&
56  !($class_name = $this->controllerClassName($name = $name ? $this->unknownControllerName : $this->defaultControllerName))
57  ) throw new \DomainException("Controller for '$name' does not exists");
58  $controller = new $class_name($this->_fred,array_replace_recursive(
59  $this->_fred->config('controller',[]),
60  $this->_fred->config(array_merge(['controllers'],array_map('lcfirst',explode('/',$name))),[])
61  ));
62  $user = $this->component('user');
63  if(!$user->authenticated($controller->authSets) || !$user->authorized($controller->right))
64  $controller = $redir ? $this->controller($user->authenticationControllerName ?: $this->deniedControllerName) : false;
65  return $controller;
66  }
67  /**
68  * Execute the request and render the view.
69  * An optionally provided action will be executed, which will also complement the request component. Afterwards the view is
70  * rendered.
71  */
72  public function execute(){
73  extract($this->components('log','request'));
74  $timer = $log->start(Log::DEBUG,__CLASS__ . '::execute: router',__FILE__,__LINE__);
75  $controller = $this->controller($this->component('router')->controllerName);
76  $request->viewControllerName = $name = $controller->name;
77  $log->stop($timer,null,null,__FILE__,__LINE__);
78  $this->component('alive')->journal($name . '::' . $controller->action);
79  $timer = $log->start(Log::DEBUG,__CLASS__ . '::execute: $controller->execute()',__FILE__,__LINE__);
80  $controller->execute();
81  $log->stop($timer,null,null,__FILE__,__LINE__);
82  if($request->viewControllerName != $name) $controller = $this->controller($request->viewControllerName);
83  else $controller->reset();
84  foreach($request->errors as $id => $error) $this->component('message')->error($error,false);
85  $timer = $log->start(Log::DEBUG,__CLASS__ . '::execute: $controller->view->render()',__FILE__,__LINE__);
86  $this->component('event')->trigger(self::EVENT_RENDER,$this,$controller);
87  $controller->view->render();
88  $log->stop($timer,null,null,__FILE__,__LINE__);
89  }
90 
91 }
controllerClassName($name)
Class name for a controller.
Definition: Front.php:36
$deniedControllerName
Definition: Front.php:18
execute()
Execute the request and render the view.
Definition: Front.php:72
$controllerNamespaces
Namespace prefix (key) per controller name prefix (value).
Definition: Front.php:13
const DEBUG
Debug-level message.
Definition: Log.php:15
controller($name, $redir=true)
Get controller by name.
Definition: Front.php:51
$defaultControllerName
Definition: Front.php:16
Front controller component.
Definition: Front.php:8
Basic component class.
Definition: Component.php:8
$unknownControllerName
Definition: Front.php:17
controllerName($class_name)
Name for a controller by class name.
Definition: Front.php:25
components(... $names)
Get multiple components in an array.
Definition: Component.php:89
const EVENT_RENDER
Definition: Front.php:10
component($name)
Get a component (local or default).
Definition: Component.php:80
$validControllerName
Regex for valid controller names (empty = do not check).
Definition: Front.php:14