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  * Construct a controller.
46  * @param string $name Controller name.
47  * @param string $class_name Class name for the controller (derived from $name when empty).
48  * @return \\Rsi\\Fred\\Controller
49  */
50  public function controllerFactory($name,$class_name = null){
51  if(!$class_name) $class_name = $this->controllerClassName($name);
52  return new $class_name($this->_fred,array_replace_recursive(
53  $this->_fred->config('controller',[]),
54  $this->_fred->config(array_merge(['controllers'],array_map('lcfirst',explode('/',$name))),[])
55  ));
56  }
57  /**
58  * Check if user is authorized for a controller.
59  * @param string $name Controller name.
60  * @return bool True if the user is authorized for the controller.
61  */
62  public function controllerAuthorized($name){
63  $user = $this->component('user');
64  $controller = $this->controllerFactory($name);
65  return $user->authenticated($controller->authSets) && $user->authorized($controller->actionRight());
66  }
67  /**
68  * Get controller by name.
69  * @param string $name Controller name.
70  * @param bool $redir Redirect to the denied or login controller if the user is not authorized to execute the requested
71  * controller action. Otherwise return false.
72  * @return \\Rsi\\Fred\\Controller|bool
73  */
74  public function controller($name,$redir = true){
75  extract($this->components('log','user'));
76  $log->debug(__CLASS__ . "::controller('$name')",__FILE__,__LINE__);
77  if($this->validControllerName && !preg_match($this->validControllerName,$name)) $name = $this->unknownControllerName;
78  if(
79  (!$name || !($class_name = $this->controllerClassName($name))) &&
80  !($class_name = $this->controllerClassName($name = $name ? $this->unknownControllerName : $this->defaultControllerName))
81  ) throw new \DomainException("Controller for '$name' does not exists");
82  $controller = $this->controllerFactory($name,$class_name);
83  if(!$user->authenticated($controller->authSets) || !$user->authorized($controller->right))
84  $controller = $redir ? $this->controller($user->authenticationControllerName ?: $this->deniedControllerName) : false;
85  return $controller;
86  }
87  /**
88  * Execute the request and render the view.
89  * An optionally provided action will be executed, which will also complement the request component. Afterwards the view is
90  * rendered.
91  */
92  public function execute(){
93  extract($this->components('alive','event','log','message','request','router'));
94  $timer = $log->start(Log::DEBUG,__CLASS__ . '::execute: router',__FILE__,__LINE__);
95  $controller = $this->controller($router->controllerName);
96  $request->viewControllerName = $name = $controller->name;
97  $log->stop($timer,null,null,__FILE__,__LINE__);
98  $alive->journal($name . '::' . $controller->action);
99  $timer = $log->start(Log::DEBUG,__CLASS__ . '::execute: $controller->execute()',__FILE__,__LINE__, ['controller' => $name]);
100  $controller->execute();
101  $log->stop($timer,null,null,__FILE__,__LINE__);
102  if($request->viewControllerName != $name) $controller = $this->controller($name = $request->viewControllerName);
103  else $controller->reset();
104  foreach($request->errors as $id => $error) $message->error($error,false);
105  $timer = $log->start(Log::DEBUG,__CLASS__ . '::execute: $controller->view->render()',__FILE__,__LINE__, ['controller' => $name]);
106  $event->trigger(self::EVENT_RENDER,$this,$controller);
107  $controller->view->render();
108  $log->stop($timer,null,null,__FILE__,__LINE__);
109  }
110 
111 }
Rsi
Rsi\Fred\Front\execute
execute()
Execute the request and render the view.
Definition: Front.php:92
Rsi\Fred\Front\$defaultControllerName
$defaultControllerName
Definition: Front.php:16
Rsi\Fred\Component\components
components(... $names)
Get multiple components in an array.
Definition: Component.php:90
Rsi\Fred\Front
Front controller component.
Definition: Front.php:8
Rsi\Fred\Component
Basic component class.
Definition: Component.php:8
Rsi\Fred\Front\$unknownControllerName
$unknownControllerName
Definition: Front.php:17
Rsi\Fred\Component\component
component($name)
Get a component (local or default).
Definition: Component.php:81
Rsi\Fred\Front\controllerClassName
controllerClassName($name)
Class name for a controller.
Definition: Front.php:36
Rsi\Fred\Front\controllerAuthorized
controllerAuthorized($name)
Check if user is authorized for a controller.
Definition: Front.php:62
Rsi\Fred\Front\EVENT_RENDER
const EVENT_RENDER
Definition: Front.php:10
Rsi\Fred\Front\controllerFactory
controllerFactory($name, $class_name=null)
Construct a controller.
Definition: Front.php:50
Rsi\Fred\Front\$defaultType
$defaultType
Definition: Front.php:12
Rsi\Fred\Front\$controllerNamespaces
$controllerNamespaces
Namespace prefix (key) per controller name prefix (value).
Definition: Front.php:13
Rsi\Fred\Front\controller
controller($name, $redir=true)
Get controller by name.
Definition: Front.php:74
Rsi\Fred\Front\$deniedControllerName
$deniedControllerName
Definition: Front.php:18
Rsi\Fred\Front\$validControllerName
$validControllerName
Regex for valid controller names (empty = do not check).
Definition: Front.php:14
Rsi\Fred\Log\DEBUG
const DEBUG
Debug-level message.
Definition: Log.php:15
Rsi\Fred\Front\controllerName
controllerName($class_name)
Name for a controller by class name.
Definition: Front.php:25
Rsi\Fred
Definition: Alive.php:3