1 <?php
2
3 namespace Alo\Controller;
4
5 use Alo;
6 use Alo\Security;
7
8 if (!defined('GEN_START')) {
9 http_response_code(404);
10 } else {
11
12 /**
13 * The controller superclass
14 *
15 * @author Art <a.molcanovas@gmail.com>
16 */
17 abstract class AbstractController {
18
19 /**
20 * Static reference to the last instance of the class
21 *
22 * @var AbstractController
23 */
24 static $this;
25 /**
26 * Whether to echo contents on object destruct
27 *
28 * @var boolean
29 */
30 private $echoOnDestruct;
31
32 /**
33 * Instantiates the class
34 *
35 * @param boolean $echoOnDestruct Whether to echo contents on object destruct
36 *
37 * @author Art <a.molcanovas@gmail.com>
38 */
39 function __construct($echoOnDestruct = true) {
40 ob_start();
41 $this->echoOnDestruct = (bool)$echoOnDestruct;
42
43 self::$this = &$this;
44 }
45
46 /**
47 * Method to avoid errors. Should always be overridden.
48 *
49 * @author Art <a.molcanovas@gmail.com>
50 */
51 function index() {
52 $this->httpError(404);
53 }
54
55 /**
56 * Forces a HTTP error page to be displayed. This does not stop script execution, but prevents further output.
57 *
58 * @author Art <a.molcanovas@gmail.com>
59 *
60 * @param int $code The HTTP response code
61 */
62 protected function httpError($code = 404) {
63 $this->echoOnDestruct = true;
64 ob_clean();
65
66 $controller = Alo::$router->getErrController();
67 $controllerNamespaced = '\Controller\\' . $controller;
68
69 Alo::includeonceifexists(DIR_APP . 'controllers' . DIRECTORY_SEPARATOR . strtolower($controller) .
70 '.php');
71
72 if (!class_exists($controllerNamespaced, true)) {
73 http_response_code((int)$code);
74 echo 'HTTP ' . Security::unXss($code) . '.';
75 } else {
76 Alo::$controller = new $controllerNamespaced;
77 /** @noinspection PhpUndefinedMethodInspection */
78 Alo::$controller->error($code);
79 ob_flush();
80 $this->echoOnDestruct = false;
81 }
82 }
83
84 /**
85 * Closure operations
86 *
87 * @author Art <a.molcanovas@gmail.com>
88 */
89 function __destruct() {
90 if ($this->echoOnDestruct) {
91 $ob = ob_get_clean();
92
93 if (Alo::$router->isCliRequest()) {
94 $ob = strip_tags($ob);
95 }
96
97 echo $ob;
98 } else {
99 ob_end_clean();
100 }
101 }
102
103 /**
104 * Returns if echoOnDestruct is true or false if called without a parameter
105 * or sets it to true/false if the parameter is set
106 *
107 * @param boolean|null $switch The parameter
108 *
109 * @return boolean|AbstractController
110 */
111 protected function echoOnDestruct($switch = null) {
112 if ($switch === null) {
113 return $this->echoOnDestruct;
114 } else {
115 $this->echoOnDestruct = (bool)$switch;
116
117 return $this;
118 }
119 }
120
121 /**
122 * Loads a view
123 *
124 * @author Art <a.molcanovas@gmail.com>
125 *
126 * @param string $name The name of the view without ".php".
127 * @param array $params Associative array of parameters to pass on to the view
128 * @param boolean $return If set to TRUE, will return the view, if FALSE,
129 * will echo it
130 *
131 * @return null|string
132 */
133 protected function loadView($name, $params = null, $return = false) {
134 $name = strtolower($name);
135
136 if (substr($name, -4) == '.php') {
137 $name = substr($name, 0, -4);
138 }
139
140 $path = DIR_APP . 'view' . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $name) . '.php';
141
142 if (!file_exists($path)) {
143 phpError('View file for ' . $name . ' could not be found');
144 } else {
145 if (is_array($params) && !empty($params)) {
146 extract($params);
147 }
148
149 if ($return) {
150 ob_start();
151 }
152
153 //not include_once so the view can be reused
154 include $path;
155
156 if ($return) {
157 return ob_get_clean();
158 }
159 }
160
161 return null;
162 }
163
164 }
165 }
166