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