Skip to content
This repository was archived by the owner on Sep 10, 2021. It is now read-only.

Commit 8cbd95e

Browse files
author
Jamie Snape
committed
Update Zend RESTful Framework to 7ae983a5ca
1 parent ba81d0b commit 8cbd95e

File tree

6 files changed

+338
-132
lines changed

6 files changed

+338
-132
lines changed

library/REST/Controller.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* REST Controller default actions
44
*
55
*/
6-
require_once BASE_PATH.'/core/AppController.php';
6+
require_once BASE_PATH . '/core/AppController.php';
77

88
abstract class REST_Controller extends AppController
99
{

library/REST/Controller/Action/Helper/ContextSwitch.php

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class REST_Controller_Action_Helper_ContextSwitch extends Zend_Controller_Action
1313
'json' => 'Zend_Serializer_Adapter_Json',
1414
'xml' => 'REST_Serializer_Adapter_Xml',
1515
'php' => 'Zend_Serializer_Adapter_PhpSerialize',
16-
'html' => 'Zend_Serializer_Adapter_Json',
16+
'html' => 'Zend_Serializer_Adapter_Json'
1717
);
1818

1919
protected $_rest_contexts = array(
@@ -74,7 +74,7 @@ class REST_Controller_Action_Helper_ContextSwitch extends Zend_Controller_Action
7474
'options' => array(
7575
'autoDisableLayout' => false,
7676
),
77-
77+
7878
'callbacks' => array(
7979
'init' => 'initAbstractContext',
8080
'post' => 'restContext'
@@ -128,6 +128,7 @@ public function restContext()
128128
if ($view instanceof Zend_View_Interface) {
129129
if (method_exists($view, 'getVars')) {
130130
$vars = $view->getVars();
131+
131132
if (isset($vars['apiresults'])) {
132133
$data = $vars['apiresults'];
133134

@@ -142,17 +143,17 @@ public function restContext()
142143
$body = str_replace('<?xml version="1.0"?>', sprintf('<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="%s"?>', $stylesheet), $body);
143144
}
144145
}
145-
146+
146147
if ($this->_currentContext == 'json') {
147148
$callback = $this->getRequest()->getParam('jsonp-callback', false);
148149

149150
if ($callback !== false and !empty($callback)) {
150151
$body = sprintf('%s(%s)', $callback, $body);
151152
}
152153
}
153-
154+
154155
if ($this->_currentContext == 'html') {
155-
$body = $this->prettyPrint($body, array("format" => "html"));
156+
$body = self::prettyPrint($body, array('format' => 'html'));
156157
}
157158

158159
$this->getResponse()->setBody($body);
@@ -172,14 +173,8 @@ public function getAutoSerialization()
172173
{
173174
return $this->_autoSerialization;
174175
}
175-
176-
176+
177177
/**
178-
* This function is based on the below Zend patches with minor customized changes
179-
* Refs:
180-
* http://framework.zend.com/issues/browse/ZF-9577
181-
* http://framework.zend.com/issues/browse/ZF-10185
182-
*
183178
* Pretty-print JSON string
184179
*
185180
* Use 'format' option to select output format - currently html and txt supported, txt is default
@@ -189,58 +184,59 @@ public function getAutoSerialization()
189184
* @param array $options Encoding options
190185
* @return string
191186
*/
192-
public function prettyPrint($json, $options = array())
187+
private static function prettyPrint($json, $options = array())
193188
{
194189
$tokens = preg_split('|([\{\}\]\[,])|', $json, -1, PREG_SPLIT_DELIM_CAPTURE);
195-
$result = "";
190+
$result = '';
196191
$indent = 0;
197192

198-
$format= "txt";
193+
$format= 'txt';
199194

200195
$ind = "\t";
201196

202-
if(isset($options['format'])) {
197+
if (isset($options['format'])) {
203198
$format = $options['format'];
204199
}
205200

206-
switch ($format):
201+
switch ($format) {
207202
case 'html':
208-
$line_break = "<br />";
209-
$line_break_length = 6;
210-
$ind = "&nbsp;&nbsp;&nbsp;&nbsp;";
203+
$lineBreak = '<br />';
204+
$ind = '&nbsp;&nbsp;&nbsp;&nbsp;';
211205
break;
212206
default:
213207
case 'txt':
214-
$line_break = "\n";
215-
$line_break_length = 2;
208+
$lineBreak = "\n";
216209
$ind = "\t";
217210
break;
218-
endswitch;
211+
}
219212

220-
//override the defined indent setting with the supplied option
221-
if(isset($options['indent'])) {
213+
// override the defined indent setting with the supplied option
214+
if (isset($options['indent'])) {
222215
$ind = $options['indent'];
223216
}
224-
225-
$inLiteral = false;
217+
218+
$inLiteral = false;
226219
foreach($tokens as $token) {
227-
if($token == "") continue;
220+
if($token == '') {
221+
continue;
222+
}
228223

229224
$prefix = str_repeat($ind, $indent);
230225
if (!$inLiteral && ($token == '{' || $token == '[')) {
231226
$indent++;
232-
if($result != "" && substr($result, strlen($result)-$line_break_length) == $line_break) {
227+
if (($result != '') && ($result[(strlen($result)-1)] == $lineBreak)) {
233228
$result .= $prefix;
234229
}
235-
$result .= "$token$line_break";
230+
$result .= $token . $lineBreak;
236231
} elseif (!$inLiteral && ($token == '}' || $token == ']')) {
237232
$indent--;
238233
$prefix = str_repeat($ind, $indent);
239-
$result .= "$line_break$prefix$token";
234+
$result .= $lineBreak . $prefix . $token;
240235
} elseif (!$inLiteral && $token == ',') {
241-
$result .= "$token$line_break" ;
236+
$result .= $token . $lineBreak;
242237
} else {
243238
$result .= ( $inLiteral ? '' : $prefix ) . $token;
239+
244240
// Count # of unescaped double-quotes in token, subtract # of
245241
// escaped double-quotes and if the result is odd then we are
246242
// inside a string literal

library/REST/Controller/Plugin/RestHandler.php

Lines changed: 71 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -50,104 +50,90 @@ class REST_Controller_Plugin_RestHandler extends Zend_Controller_Plugin_Abstract
5050
);
5151

5252
public function __construct(Zend_Controller_Front $frontController)
53-
{
54-
$this->dispatcher = $frontController->getDispatcher();
55-
}
53+
{
54+
$this->dispatcher = $frontController->getDispatcher();
55+
}
5656

5757
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
58-
{
59-
// only handle Restful WebApi URI
60-
if(strpos($request->getPathInfo(), '/rest/') !== FALSE)
61-
{
62-
// send the HTTP Vary header
63-
$this->_response->setHeader('Vary', 'Accept');
58+
{
59+
// only handle RESTful API URI
60+
if (strpos($request->getPathInfo(), '/rest/') !== false) {
61+
// send the HTTP Vary header
62+
$this->_response->setHeader('Vary', 'Accept');
6463

65-
// Cross-Origin Resource Sharing (CORS)
66-
// TODO: probably should be an environment setting?
67-
$this->_response->setHeader('Access-Control-Max-Age', '86400');
68-
$this->_response->setHeader('Access-Control-Allow-Origin', '*');
69-
$this->_response->setHeader('Access-Control-Allow-Credentials', 'true');
70-
$this->_response->setHeader('Access-Control-Allow-Headers', 'Authorization, X-Authorization, Origin, Accept, Content-Type, X-Requested-With, X-HTTP-Method-Override');
64+
// Cross-Origin Resource Sharing (CORS)
65+
// TODO: probably should be an environment setting?
66+
$this->_response->setHeader('Access-Control-Max-Age', '86400');
67+
$this->_response->setHeader('Access-Control-Allow-Origin', '*');
68+
$this->_response->setHeader('Access-Control-Allow-Credentials', 'true');
69+
$this->_response->setHeader('Access-Control-Allow-Headers', 'Authorization, X-Authorization, Origin, Accept, Content-Type, X-Requested-With, X-HTTP-Method-Override');
7170

72-
// process module apis
73-
$this->handlePathInfo($request);
71+
// process module APIs
72+
$this->handlePathInfo($request);
7473

75-
$class = $this->getReflectionClass($request);
74+
$class = $this->getReflectionClass($request);
7675

77-
if ($this->isRestClass($class))
78-
{
79-
// set config settings from application.ini
80-
$this->setConfig();
76+
if ($this->isRestClass($class)) {
77+
// set config settings from application.ini
78+
$this->setConfig();
8179

82-
// set response format
83-
$this->setResponseFormat($request);
80+
// set response format
81+
$this->setResponseFormat($request);
8482

85-
// process requested action
86-
$this->handleActions($request);
83+
// process requested action
84+
$this->handleActions($request);
8785

88-
// process request body
89-
$this->handleRequestBody($request);
90-
}
86+
// process request body
87+
$this->handleRequestBody($request);
88+
}
9189
}
92-
}
90+
}
9391

9492
/**
9593
* Parse PathInfo in the orginal request and then alter the original request
96-
* based on the valid Midas Restful URI format:
94+
* based on the valid RESTful API URI format:
9795
* /rest[/{moduleName}]/{controllerName}[/{methodName}][/{Id}]
9896
* note: [] means optinal parts.
9997
*/
10098
private function handlePathInfo(Zend_Controller_Request_Abstract $request)
101-
{
102-
$tokens = preg_split('@/@', $request->getPathInfo(), NULL, PREG_SPLIT_NO_EMPTY);
103-
array_shift($tokens); // remove 'rest' prefix
104-
if(!empty($tokens))
105-
{
106-
if(in_array($tokens[0], Zend_Registry::get('modulesHaveApi')))
107-
{
108-
$apiModuleName = 'api' . array_shift($tokens);
109-
$controllerName = array_shift($tokens);
110-
$request->setParam('module', $apiModuleName);
111-
$request->setParam('controller', $controllerName);
112-
$request->setModuleName($apiModuleName);
113-
$request->setControllerName($controllerName);
114-
// remove redundant parameter generated by Zend routing
115-
$request->setParam($controllerName, NULL);
116-
}
117-
else
118-
{
119-
array_shift($tokens); // remove controllerName
120-
}
121-
// handle method
122-
if(!empty($tokens) && !is_numeric($tokens[0]))
123-
{
124-
$methodName = array_shift($tokens);
125-
$request->setParam('method', $methodName);
126-
// remove redundant parameter generated by Zend routing
127-
$request->setParam($methodName, NULL);
128-
$request->setParam('id', NULL);
129-
}
130-
// forward to index action if id is not provided
131-
$action = $request->getActionName();
132-
if(empty($tokens) && ($action == "get" || $action == "index"))
133-
{
134-
$request->setActionName("index");
135-
}
136-
else if(empty($tokens) && ($action == "post" || $action == "put"))
137-
{
138-
$request->setActionName("post");
139-
}
140-
else if(!empty($tokens) && is_numeric($tokens[0]))
141-
{
142-
$request->setParam('id', array_shift($tokens));
143-
}
144-
else
145-
{
146-
$this->_response->setHttpResponseCode(400); //400 Bad Request
147-
throw new Exception('The Webapi ' . $request->getPathInfo() . ' is not supported.', 400);
148-
}
99+
{
100+
$tokens = preg_split('@/@', $request->getPathInfo(), null, PREG_SPLIT_NO_EMPTY);
101+
array_shift($tokens); // remove 'rest' prefix
102+
if (!empty($tokens)) {
103+
if (in_array($tokens[0], Zend_Registry::get('modulesHaveApi'))) {
104+
$apiModuleName = 'api' . array_shift($tokens);
105+
$controllerName = array_shift($tokens);
106+
$request->setParam('module', $apiModuleName);
107+
$request->setParam('controller', $controllerName);
108+
$request->setModuleName($apiModuleName);
109+
$request->setControllerName($controllerName);
110+
// remove redundant parameter generated by Zend routing
111+
$request->setParam($controllerName, null);
112+
} else {
113+
array_shift($tokens); // remove controllerName
114+
}
115+
// handle method
116+
if (!empty($tokens) && !is_numeric($tokens[0])) {
117+
$methodName = array_shift($tokens);
118+
$request->setParam('method', $methodName);
119+
// remove redundant parameter generated by Zend routing
120+
$request->setParam($methodName, null);
121+
$request->setParam('id', null);
122+
}
123+
// forward to index action if id is not provided
124+
$action = $request->getActionName();
125+
if (empty($tokens) && ($action == 'get' || $action == 'index')) {
126+
$request->setActionName('index');
127+
} else if (empty($tokens) && ($action == 'post' || $action == 'put')) {
128+
$request->setActionName('post');
129+
} else if (!empty($tokens) && is_numeric($tokens[0])) {
130+
$request->setParam('id', array_shift($tokens));
131+
} else {
132+
$this->_response->setHttpResponseCode(400); // 400 Bad Request
133+
throw new Exception('The web API ' . $request->getPathInfo() . ' is not supported.', 400);
134+
}
149135
}
150-
}
136+
}
151137

152138
private function setConfig()
153139
{
@@ -176,7 +162,7 @@ private function setResponseFormat(Zend_Controller_Request_Abstract $request)
176162
} else {
177163
$bestMimeType = $this->negotiateContentType($request);
178164

179-
// if there's no matching MimeType, assign default json
165+
// if there's no matching MimeType, assign default JSON
180166
if (!$bestMimeType || $bestMimeType == '*/*') {
181167
$bestMimeType = 'application/json';
182168
}
@@ -211,7 +197,7 @@ private function handleActions(Zend_Controller_Request_Abstract $request)
211197

212198
if ($name == '__CALL' and $method->class != 'Zend_Controller_Action') {
213199
$actions[] = $request->getMethod();
214-
} elseif (substr($name, -6) == 'ACTION' and $name != 'INDEXACTION' and $name != 'CALLCOREACTION') {
200+
} elseif (substr($name, -6) == 'ACTION' and $name != 'INDEXACTION') {
215201
$actions[] = str_replace('ACTION', null, $name);
216202
}
217203
}
@@ -361,6 +347,9 @@ private function getReflectionClass(Zend_Controller_Request_Abstract $request)
361347
if ($this->reflectionClass === null) {
362348
// get the dispatcher to load the controller class
363349
$controller = $this->dispatcher->getControllerClass($request);
350+
// if no controller present escape silently...
351+
if ($controller === false) return false;
352+
// ... load controller class
364353
$className = $this->dispatcher->loadClass($controller);
365354

366355
// extract the actions through reflection

library/REST/LICENSE

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
Copyright (c) 2011 Code in Chaos Inc. http://www.codeinchaos.com
1+
The MIT License (MIT)
22

3-
Permission is hereby granted, free of charge, to any person obtaining
4-
a copy of this software and associated documentation files (the
5-
"Software"), to deal in the Software without restriction, including
6-
without limitation the rights to use, copy, modify, merge, publish,
7-
distribute, sublicense, and/or sell copies of the Software, and to
8-
permit persons to whom the Software is furnished to do so, subject to
9-
the following conditions:
3+
Copyright (c) 2014 Ahmad Nassri. http://ahmadnassri.com
104

11-
The above copyright notice and this permission notice shall be
12-
included in all copies or substantial portions of the Software.
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
1311

14-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)