-
Notifications
You must be signed in to change notification settings - Fork 0
/
controller.php
executable file
·143 lines (125 loc) · 4.18 KB
/
controller.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
<?php
namespace jmvc;
/**
* Public controller methods map to URLs: /controller_name[/method_name][/$args[0]/$args[1]...]
* index() is the default method if no method_name is in the URL.
*/
abstract class Controller {
/**
* Constructor
* @param array $args Arbitrary data to be passed to the controller
* @param array $context The site, template, controller, and view requested
* @return \jmvc\Controller
*/
public function __construct($args, $context=array())
{
$this->args = $args;
$this->context = $context;
}
/**
* Object ID based routing. URLs like /controller_name/object_id/method_name/ where object_id is numeric.
* Call from index() like this:
* if ($this->route_object(args...)) {
* return;
* }
* @param string $model Model class to attempt to load
* @param string $default Default method to run if URL is /controller_name/object_id/
* @param \jmvc\Model &$obj Reference return of found object
* @param function $filter_callback Object will be passed to this function; if the function returns false, a 404 will be triggered
* @return bool Whether an object was found or not
*/
public function route_object($model, $default=false, &$obj=null, $filter_callback=null)
{
if (!is_numeric($this->args[0])) {
return false;
}
$method = $this->args[1] ?: $default;
if (!method_exists($this, $method)) {
\jmvc::do404();
}
$obj = $model::factory($this->args[0]);
if (!$obj) {
\jmvc::do404();
}
if ($filter_callback && !$filter_callback($obj)) {
\jmvc::do404();
}
$this->view_override(array('view'=>$method));
$this->$method($obj);
return true;
}
/**
* Load a different view instead of the one matching the current context.
* @param mixed $context If a string, look for a view by that name within current context.
* If an array, array keys match the context values to be changed.
* @return void
*/
public function view_override($context=null)
{
if (is_array($context)) {
$this->context_override = $context;
} else if (is_string($context)) {
$this->context_override = array('view'=>$context);
} else if (isset($this->context_override)) {
return $this->context_override;
}
}
/**
* Redirect the user to a new URL. Terminates execution of current script.
* @param strin $url URL to be loaded. Domain name optional.
* @param bool $permanent Send a 301 Permanent Redirect. If false, send a 303 Temporarily Moved.
* Defaults to false.
* @return void
*/
public static function forward($url, $permanent=false)
{
if ($permanent) {
header('HTTP/1.1 301 Moved Permanently');
} else {
header('HTTP/1.1 303 See Other');
}
if (strpos($url, '://') === false) {
$host = ($_SERVER['HTTPS'] ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'];
} else {
$host = '';
}
// remove tabs and newlines, which break HTTP headers
$url = str_replace(["\n", "\r", "\t"], ' ', html_entity_decode($url));
header('location: '.$url);
exit();
}
/**
* Retreive a controller instance based on context.
* @param array $context Site, template, controller, view being requested
* @param array $args Arbitrary data to be passed to controller instance
* @return \jmvc\Controller
*/
public static function factory($context, $args=array())
{
if (!self::exists($context['site'], $context['controller'])) {
return false;
}
$controller_name = 'controllers\\'.$context['site'].'\\'.$context['controller'];
return new $controller_name($args, $context);
}
/**
* Check if a controller class exists.
* @param string $site
* @param string $controller
* @return bool
*/
public static function exists($site, $controller)
{
return file_exists(APP_DIR.'sites/'.$site.'/'.strtolower($controller).'.php');
}
/**
* Set a data value that can be retrieved in future requests. Useful for setting status messages.
* @param string $msg
* @param string $bucket Optional grouping of flash messages. Used to avoid retrieving all messages at once.
* @return void
*/
public static function flash($msg, $bucket=0)
{
View::flash($msg, $bucket);
}
}