Update RootController and test so that a Request is passed to UrlMap::Evaluate()
[hoplite.git] / http / root_controller.php
1 <?php
2 // Hoplite
3 // Copyright (c) 2011 Blue Static
4 //
5 // This program is free software: you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License as published by the Free
7 // Software Foundation, either version 3 of the License, or any later version.
8 //
9 // This program is distributed in the hope that it will be useful, but WITHOUT
10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 // more details.
13 //
14 // You should have received a copy of the GNU General Public License along with
15 // this program. If not, see <http://www.gnu.org/licenses/>.
16
17 namespace hoplite\http;
18
19 require_once HOPLITE_ROOT . '/http/request.php';
20 require_once HOPLITE_ROOT . '/http/response.php';
21 require_once HOPLITE_ROOT . '/http/response_code.php';
22
23 /*!
24 The RootController is meant to be invoked from the index.php of the
25 application.
26 */
27 class RootController
28 {
29 /*! @var Request */
30 private $request = NULL;
31
32 /*! @var Response */
33 private $response = NULL;
34
35 /*! @var UrlMap */
36 private $url_map = NULL;
37
38 /*! @var OutputFilter */
39 private $output_filter = NULL;
40
41 /*!
42 Creates the controller with the request context information, typicallhy
43 from the global scope ($GLOBALS), but can be injected for testing.
44 @param UrlMap The routing map
45 @param OutputFilter The object responsible for decorating output.
46 @param array& PHP globals array
47 */
48 public function __construct(array $globals)
49 {
50 $this->response = new Response();
51 $this->request = new Request();
52 $this->request->data = array(
53 '_GET' => &$globals['_GET'],
54 '_POST' => &$globals['_POST'],
55 '_COOKIE' => &$globals['_COOKIE'],
56 '_SERVER' => &$globals['_SERVER']
57 );
58 }
59
60 /*! Accessors */
61 public function request() { return $this->request; }
62 public function response() { return $this->response; }
63
64 /*! Sets the UrlMap. */
65 public function set_urL_map(UrlMap $url_map) { $this->url_map = $url_map; }
66
67 /*! Sest the Output Filter. */
68 public function set_output_filter(OutputFilter $output_filter)
69 {
70 $this->output_filter = $output_filter;
71 }
72
73 /*!
74 Createst the Request and Response that are used throughout the duration of
75 the execution.
76 */
77 public function Run()
78 {
79 // The query rewriter module of the webserver rewrites a request from:
80 // http://example.com/webapp/user/view/42
81 // to:
82 // http://example.com/webapp/index.php/user/view/42
83 // ... which then becomes accessible from PATH_INFO.
84 $url = $this->request->data['_SERVER']['PATH_INFO'];
85 if ($url[0] == '/')
86 $url = substr($url, 1);
87
88 // Set the final pieces of the request.
89 $this->request->url = $url;
90 $this->request->http_method = $this->request->data['_SERVER']['REQUEST_METHOD'];
91
92 // Dispatch the request to an Action.
93 $this->RouteRequest($this->request);
94
95 // When control returns here, all actions have been invoked and it's time
96 // to start the output filter and exit.
97 $this->Stop();
98 }
99
100 /*!
101 Prevents any other Actions from executing. This starts the OutputFilter and
102 then exits.
103 */
104 public function Stop()
105 {
106 $this->output_filter->FilterOutput($this->request, $this->response);
107 $this->_Exit();
108 }
109
110 /*!
111 Wrapper around PHP exit().
112 */
113 protected function _Exit()
114 {
115 exit;
116 }
117
118 /*!
119 Invoked by Run() and can be invoked by others to evaluate and perform the
120 lookup in the UrlMap. This then calls InvokeAction().
121 @param Request The Request whose URL will be routed
122 */
123 public function RouteRequest(Request $request)
124 {
125 $url_map_value = $this->url_map->Evaluate($request);
126
127 $action = NULL;
128 if ($url_map_value)
129 $action = $this->url_map->LookupAction($url_map_value);
130
131 if (!$action) {
132 $this->response->response_code = ResponseCode::NOT_FOUND;
133 $this->Stop();
134 return;
135 }
136
137 $this->InvokeAction($action);
138 }
139
140 /*!
141 Used to run an Action and drive it through its states.
142 @param Action
143 */
144 public function InvokeAction(Action $action)
145 {
146 $action->FilterRequest($this->request, $this->response);
147 $action->Invoke($this->request, $this->response);
148 $action->FilterResponse($this->request, $this->response);
149 }
150
151 /*!
152 Performs a reverse-lookup in the UrlMap for the pattern/fragment for the
153 name of a given Action class.
154 @param string Class name.
155 */
156 public function LookupAction($class)
157 {}
158 }