Add OutputFilter::_EncodeXML and create a test
[hoplite.git] / http / output_filter.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/response_code.php';
20
21 /*!
22 The OutputFilter is executed after all Actions have been processed. The
23 primary function is to generate the actual HTTP response body from the model
24 data contained within the http\Response. Depending on how the Request was
25 sent, this
26 */
27 class OutputFilter
28 {
29 /*! @var RootController */
30 private $controller;
31
32 /*!
33 Constructor that takes a reference to the RootController.
34 */
35 public function __construct(RootController $controller)
36 {
37 $this->controller = $controller;
38 }
39
40 /*! Accessor for the RootController. */
41 public function controller() { return $this->controller; }
42
43 /*! @brief Main entry point for output filtering
44 This is called from the RootController to begin processing the output and
45 generating the response.
46 */
47 public function FilterOutput(Request $request, Response $response)
48 {
49 // If there was an error during the processing of an action, allow hooking
50 // custom logic.
51 if ($response->response_code != ResponseCode::OK)
52 if (!$this->_ContinueHandlingResponseForCode($request, $response))
53 return;
54
55 // If there's already raw data for the body, just output that.
56 if ($response->body)
57 return;
58
59 // Otherwise, construct the body based on how the Request was received and
60 // any other information in the response.
61 $this->_CreateBodyForResponse($request, $response);
62 }
63
64 /*!
65 If the request did not generate an 200 response code, the filter gives the
66 client an opportunity to override the normal output control flow and perform
67 some other task. If you want the control flow to continue executing as
68 normal, return TRUE; otherwise, return FALSE to exit from ::FilterOutput().
69 @return boolean
70 */
71 protected function _ContinueHandlingResponseForCode(Request $request,
72 Response $response)
73 {
74 return TRUE;
75 }
76
77 /*!
78 Fills out the Response#data field. This could be an evaluated HTML template,
79 a JSON payload, XML, or any other type of response for the client.
80 */
81 protected function _CreateBodyForResponse(Request $request,
82 Response $response)
83 {}
84
85 /*!
86 Creates an XML tree from an array. Equivalent to json_encode.
87 */
88 protected function _EncodeXML($data)
89 {
90 $response = new \SimpleXMLElement('<response/>');
91
92 $writer = function($elm, $parent) use (&$writer) {
93 foreach ($elm as $key => $value) {
94 if (is_scalar($value)) {
95 $parent->AddChild($key, $value);
96 } else {
97 $new_parent = $parent->AddChild($key);
98 $writer($value, $new_parent);
99 }
100 }
101 };
102
103 $writer($data, $response);
104 return $response->AsXML();
105 }
106 }