-
Notifications
You must be signed in to change notification settings - Fork 0
/
MF-debug.php
315 lines (294 loc) · 10.6 KB
/
MF-debug.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
<?php
/**
* @package MariaFramework
* @author Jiju Thomas Mathew <[email protected]>
*/
/**
* class MF
* @description The main class which provides the framework
*/
class MF
{
/** this is just the version number **/
const Version = 0.27;
/** @var $store array **/
public static $store = array('addons' => 'addons/', 'plugins' => 'plugins/', 'views' => 'views/');
/** @var $events array **/
public static $events = array();
/** @var $fired array **/
public static $fired = array();
/**
* Set value of $var as $val into static pool
* @ void set ( String $var, Mixed $val )
* @param String $var Name of variable being set in the MF scope
* @param any $val Value corresponding to the name being set in the MF scope
*/
public static function set($var, $val)
{
if (in_array($var, array('addons', 'plugins', 'views'))) {
(!is_dir($val)) && $val = self::get($var);
$val .= (substr($val, -1) !== '/') ? '/' : '';
}
self::$store[$var] = $val;
}
/**
* Get value of $var if stored in MF or empty string
* @ Mixed get ( String $var )
* @param String $var Name of the variable that is to be fetched from MF scope
* @return any Value stored in the MF scope with key $var
*/
public static function get($var)
{
return (isset(self::$store[$var])) ? self::$store[$var] : "";
}
/**
* Addons are singlular files containing just functions, and the function
* names should be the base name of the value in addon, the ‘.php’ will
* be assumed and attached when including the file.
* @ mixed addon ( String $addon )
* @param String $addon
* @return Mixed boolean false if addon does not exist
*/
public static function addon($addon)
{
try {
$funcname = basename($addon);
$params = func_get_args();
if (function_exists($funcname) === false) {
$path = ($addon{
0} == '.' or $addon{
0} == '/') ? '' : self::get('addons');
require($path . $addon . '.php');
}
return call_user_func_array($funcname, array_slice($params, 1));
} catch (Exception $e) {
}
return false;
}
/**
* Keeps, checks and makes sure that any object instance is created just
* once. It may be called as an object singleton store. Object instances
* are stored in the static var $bag
* @ Mixed object ( String $item [, Boolean $newIfNotExist = true ] )
* @staticvar array $bag
* @param string $item
* @param bool $newIfNotExist
* @return instanceof class in $item
*/
public static function object($item, $newIfNotExist = true)
{
static $bag = array();
$class = basename($item);
if (isset($bag[$class]) || array_key_exists($class, $bag) === true) {
return $bag[$class];
} elseif ($newIfNotExist === true) {
if (class_exists($class, false) === false) {
$path = ($item{
0} == '.' or $item{
0} == '/') ? '' : self::get('plugins');
require($path . $item . '.php');
}
$bag[$class] = new $class();
return $bag[$class];
}
return false;
}
/**
* The routing handler, such that you could specify the
* valid <method> <resource path> to send the system through the routes.
* The path value set in ‘extend’ is prefixed to the $class, it is
* instantiated through the singleton registry and the $handler method
* of the instance is invoked. The <resource path> is applied to the
* $_SERVER['REQUEST_URI'] assuming that the <resource path> is regular
* expression, means you can use regular expressions, and the resulting
* match array is passed as a parameter for the $class->handler method.
* @ void MFR ( String $route , String $class , String $handler [, int $cacheable ] )
* @param String $route Request Method and url patten together form the route
* @param String $class The handler class for matching route request
* @param String $handler The handler method that is a public method of the handler class
* @param int $cacheable Though default is false, the value taken is unsigned integer
* as minutes for caching
* @uses MF::fireevent to fire before-handler event
* @uses MF::fireevent to fire after-handler event
*/
public static function MFR($route, $class, $handler, $cacheable = false)
{
(empty($route) === true) && $route = 'GET /';
$requestType = substr($route, 0, strpos($route, ' '));
$route = substr($route, strpos($route, ' ') + 1);
if (strcasecmp($requestType, $_SERVER['REQUEST_METHOD']) === 0) {
$matches = array();
$mask = self::get('urimask');
$checkUri = ($route == '/') ? $_SERVER['REQUEST_URI'] : rtrim($_SERVER['REQUEST_URI'], '/');
$tt = parse_url($checkUri);
$checkUri = $tt['path'];
if (!empty($tt['query']))
parse_str($tt['query'], $_GET);
if (preg_match('@^' . $mask . $route . '$@i', $checkUri, $matches) > 0) {
if (self::object($class) !== false) {
(!$cacheable) ?
header("Cache-Control: no-cache, must-revalidate") :
header("Expires: " . gmdate("D, d M Y G:i:s T", time() + $cacheable));
self::fireevent('before-handler', $class, $handler, $cacheable);
self::object($class)->$handler($matches);
self::fireevent('after-handler', $class, $handler, $cacheable);
exit();
}
}
}
}
/**
* Populates any assoicative arrays as name value variables and includes the
* '.php' template file. Means the templates are rendered using raw php.
* @param String $view Name of the template file, '.php' is attached
* @return Boolean
* @uses MF::fireevent to fire before-display event
* @uses MF::fireevent to fire after-display event
*/
public static function display($view)
{
self::fireevent('theme-detect', $view);
$path = self::get('views');
if (is_file($path . $view . '.php') === true) {
for ($i = 1; $i < func_num_args(); $i++) {
$argument = func_get_arg($i);
if (is_array($argument) === true) {
extract($argument);
}
}
/** @var array $global */
$global = self::get('global');
(!empty($global)) && extract($global);
self::fireevent('before-display', $view);
require($path . $view . '.php');
self::fireevent('after-display', $view);
return true;
}
return false;
}
/**
* Since by application server configuration, all not found resources are
* rewritten to our handler, and we dont want genuine not found to return
* HTTP 200 and then an empty page. So the handling of a 404 header, with
* an optional neatly formatted page would be the best.
* @ void run ( [ $page = '' ] )
* @param String $page Optional formatted 404 page, else no content will be sent
*/
public static function run($page = '', $code = 404)
{
// stupid.. normally run would have completed earlier..
if (headers_sent() === false) {
header("HTTP/1.0 " . $code, true, $code);
}
if (!empty($page)) {
self::display($page);
}
exit();
}
/**
* Intenal or external redirects will be required in a portal for
* maintaining old structure or page ranks and for many other purpose too
* @ void redirect ( String $url [, bool $permanent = false ] )
* @param String $url Will redirect to this url
* @param Bool $permanent if true, http 301 else 302 is the status code.
* @uses MF::fireevent to fire before-redirect event
*/
public static function redirect($url, $permanent = false)
{
if (headers_sent() === false) {
self::fireevent('before-redirect', $url, $permanent);
header('Location: ' . $url, true, ($permanent === true) ? 301 : 302);
}
exit();
}
/**
* Idea got from wordpress, but a bit different. Any way this is for plugins to exist and
* attach their methods to events which are fired using MF::fireevent
* @ void addaction ( String $name, array $handler [ int $priority = 10] )
* @param String $name Name of the action, this should be fired with MF::fireevent where the event happens
* @param array $handler Handler is array ( class, method )
* @param int $priority int range 1 - 999
*/
public static function addaction($name, $handler, $priority = 10)
{
if (!isset(self::$fired[$name])) {
$key = is_array($handler) ? join('::', $handler) : $handler;
if (isset(self::$events[$name][$key])) {
self::$events[$name][$key]['priority'] = $priority;
} else {
self::$events[$name][$key] = array('method' => $handler, 'priority' => $priority);
}
}
}
/**
* The real event handler, enables plugins to generate their own events
* and to fire built in events. Themes can also have events to be fired
* such that plugins can hook actions to those events.
* @param String $name the name of the event.
* @uses MF::object to instantiate the handler
* @uses MF::prioritize to sort actions in each event to the priority added
*/
public static function fireevent($name)
{
if (!isset(self::$fired[$name])) {
if (!empty(self::$events[$name])) {
uasort(self::$events[$name], 'MF::prioritize');
$args = func_get_args();
foreach (self::$events[$name] as $method) {
if(is_array($method['method'])){
$h = $method['method'][0];
$c = $method['method'][1];
self::object($h)->$c($args);
}else{
$fn = $method['method'];
$fn($args);
}
}
}
self::$fired[$name] = time();
}
}
/**
* Sorting function for actions in an event chain
* @param mixed $a
* @param mixed $b
* @return int (-1, 0, 1)
*/
public static function prioritize($a, $b)
{
return ($a['priority'] == $b['priority']) ? 0 : (($a['priority'] < $b['priority']) ? -1 : 1);
}
/**
* A debugging function which helped a lot while stuck.
* @return boolean true
*/
public static function debug()
{
$params = func_get_args();
$to = self::get('logfile');
$to = (!empty($to)) ? $to : false;
if (!$to) {
return true;
}
if ($to !== false && is_writable(dirname($to))) {
ob_start();
echo '#---------[' . date('c') . ']------' . "\n";
} else {
echo '<pre style="text-align: left;">' . "\n";
}
foreach ($params as $param) {
if (is_array($param) === true)
print_r($param);
else
var_dump($param);
}
if ($to !== false && is_writable(dirname($to))) {
echo '#------------------------------' . "\n";
$log = ob_get_clean();
file_put_contents($to, $log, FILE_APPEND);
} else {
echo '</pre>' . "\n";
}
return true;
}
}