|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00025 require_once 'Zend/Controller/Router/Route/Interface.php'; 00026 00030 require_once 'Zend/Controller/Router/Route/Module.php'; 00031 00035 require_once 'Zend/Controller/Dispatcher/Interface.php'; 00036 00040 require_once 'Zend/Controller/Request/Abstract.php'; 00041 00052 class Zend_Rest_Route extends Zend_Controller_Router_Route_Module 00053 { 00058 protected $_restfulModules = null; 00059 00064 protected $_restfulControllers = null; 00065 00069 protected $_front; 00070 00078 public function __construct(Zend_Controller_Front $front, 00079 array $defaults = array(), 00080 array $responders = array() 00081 ) { 00082 $this->_defaults = $defaults; 00083 00084 if ($responders) { 00085 $this->_parseResponders($responders); 00086 } 00087 00088 $this->_front = $front; 00089 $this->_dispatcher = $front->getDispatcher(); 00090 } 00091 00095 public static function getInstance(Zend_Config $config) 00096 { 00097 $frontController = Zend_Controller_Front::getInstance(); 00098 $defaultsArray = array(); 00099 $restfulConfigArray = array(); 00100 foreach ($config as $key => $values) { 00101 if ($key == 'type') { 00102 // do nothing 00103 } elseif ($key == 'defaults') { 00104 $defaultsArray = $values->toArray(); 00105 } else { 00106 $restfulConfigArray[$key] = explode(',', $values); 00107 } 00108 } 00109 $instance = new self($frontController, $defaultsArray, $restfulConfigArray); 00110 return $instance; 00111 } 00112 00124 public function match($request, $partial = false) 00125 { 00126 if (!$request instanceof Zend_Controller_Request_Http) { 00127 $request = $this->_front->getRequest(); 00128 } 00129 $this->_request = $request; 00130 $this->_setRequestKeys(); 00131 00132 $path = $request->getPathInfo(); 00133 $params = $request->getParams(); 00134 $values = array(); 00135 $path = trim($path, self::URI_DELIMITER); 00136 00137 if ($path != '') { 00138 00139 $path = explode(self::URI_DELIMITER, $path); 00140 // Determine Module 00141 $moduleName = $this->_defaults[$this->_moduleKey]; 00142 $dispatcher = $this->_front->getDispatcher(); 00143 if ($dispatcher && $dispatcher->isValidModule($path[0])) { 00144 $moduleName = $path[0]; 00145 if ($this->_checkRestfulModule($moduleName)) { 00146 $values[$this->_moduleKey] = array_shift($path); 00147 $this->_moduleValid = true; 00148 } 00149 } 00150 00151 // Determine Controller 00152 $controllerName = $this->_defaults[$this->_controllerKey]; 00153 if (count($path) && !empty($path[0])) { 00154 if ($this->_checkRestfulController($moduleName, $path[0])) { 00155 $controllerName = $path[0]; 00156 $values[$this->_controllerKey] = array_shift($path); 00157 $values[$this->_actionKey] = 'get'; 00158 } else { 00159 // If Controller in URI is not found to be a RESTful 00160 // Controller, return false to fall back to other routes 00161 return false; 00162 } 00163 } elseif ($this->_checkRestfulController($moduleName, $controllerName)) { 00164 $values[$this->_controllerKey] = $controllerName; 00165 $values[$this->_actionKey] = 'get'; 00166 } else { 00167 return false; 00168 } 00169 00170 //Store path count for method mapping 00171 $pathElementCount = count($path); 00172 00173 // Check for "special get" URI's 00174 $specialGetTarget = false; 00175 if ($pathElementCount && array_search($path[0], array('index', 'new')) > -1) { 00176 $specialGetTarget = array_shift($path); 00177 } elseif ($pathElementCount && $path[$pathElementCount-1] == 'edit') { 00178 $specialGetTarget = 'edit'; 00179 $params['id'] = $path[$pathElementCount-2]; 00180 } elseif ($pathElementCount == 1) { 00181 $params['id'] = urldecode(array_shift($path)); 00182 } elseif ($pathElementCount == 0 && !isset($params['id'])) { 00183 $specialGetTarget = 'index'; 00184 } 00185 00186 // Digest URI params 00187 if ($numSegs = count($path)) { 00188 for ($i = 0; $i < $numSegs; $i = $i + 2) { 00189 $key = urldecode($path[$i]); 00190 $val = isset($path[$i + 1]) ? urldecode($path[$i + 1]) : null; 00191 $params[$key] = $val; 00192 } 00193 } 00194 00195 // Determine Action 00196 $requestMethod = strtolower($request->getMethod()); 00197 if ($requestMethod != 'get') { 00198 if ($request->getParam('_method')) { 00199 $values[$this->_actionKey] = strtolower($request->getParam('_method')); 00200 } elseif ( $request->getHeader('X-HTTP-Method-Override') ) { 00201 $values[$this->_actionKey] = strtolower($request->getHeader('X-HTTP-Method-Override')); 00202 } else { 00203 $values[$this->_actionKey] = $requestMethod; 00204 } 00205 00206 // Map PUT and POST to actual create/update actions 00207 // based on parameter count (posting to resource or collection) 00208 switch( $values[$this->_actionKey] ){ 00209 case 'post': 00210 if ($pathElementCount > 0) { 00211 $values[$this->_actionKey] = 'put'; 00212 } else { 00213 $values[$this->_actionKey] = 'post'; 00214 } 00215 break; 00216 case 'put': 00217 $values[$this->_actionKey] = 'put'; 00218 break; 00219 } 00220 00221 } elseif ($specialGetTarget) { 00222 $values[$this->_actionKey] = $specialGetTarget; 00223 } 00224 00225 } 00226 $this->_values = $values + $params; 00227 00228 $result = $this->_values + $this->_defaults; 00229 00230 if ($partial && $result) 00231 $this->setMatchedPath($request->getPathInfo()); 00232 00233 return $result; 00234 } 00235 00244 public function assemble($data = array(), $reset = false, $encode = true) 00245 { 00246 if (!$this->_keysSet) { 00247 if (null === $this->_request) { 00248 $this->_request = $this->_front->getRequest(); 00249 } 00250 $this->_setRequestKeys(); 00251 } 00252 00253 $params = (!$reset) ? $this->_values : array(); 00254 00255 foreach ($data as $key => $value) { 00256 if ($value !== null) { 00257 $params[$key] = $value; 00258 } elseif (isset($params[$key])) { 00259 unset($params[$key]); 00260 } 00261 } 00262 00263 $params += $this->_defaults; 00264 00265 $url = ''; 00266 00267 if ($this->_moduleValid || array_key_exists($this->_moduleKey, $data)) { 00268 if ($params[$this->_moduleKey] != $this->_defaults[$this->_moduleKey]) { 00269 $module = $params[$this->_moduleKey]; 00270 } 00271 } 00272 unset($params[$this->_moduleKey]); 00273 00274 $controller = $params[$this->_controllerKey]; 00275 unset($params[$this->_controllerKey]); 00276 00277 unset($params[$this->_actionKey]); 00278 00279 if (isset($params['index']) && $params['index']) { 00280 unset($params['index']); 00281 $url .= '/index'; 00282 foreach ($params as $key => $value) { 00283 if ($encode) $value = urlencode($value); 00284 $url .= '/' . $key . '/' . $value; 00285 } 00286 } elseif (isset($params['id'])) { 00287 $url .= '/' . $params['id']; 00288 } 00289 00290 if (!empty($url) || $controller !== $this->_defaults[$this->_controllerKey]) { 00291 $url = '/' . $controller . $url; 00292 } 00293 00294 if (isset($module)) { 00295 $url = '/' . $module . $url; 00296 } 00297 00298 return ltrim($url, self::URI_DELIMITER); 00299 } 00300 00306 public function getVersion() 00307 { 00308 return 2; 00309 } 00310 00317 protected function _parseResponders($responders) 00318 { 00319 $modulesOnly = true; 00320 foreach ($responders as $responder) { 00321 if(is_array($responder)) { 00322 $modulesOnly = false; 00323 break; 00324 } 00325 } 00326 if ($modulesOnly) { 00327 $this->_restfulModules = $responders; 00328 } else { 00329 $this->_restfulControllers = $responders; 00330 } 00331 } 00332 00339 protected function _checkRestfulModule($moduleName) 00340 { 00341 if ($this->_allRestful()) { 00342 return true; 00343 } 00344 if ($this->_fullRestfulModule($moduleName)) { 00345 return true; 00346 } 00347 if ($this->_restfulControllers && array_key_exists($moduleName, $this->_restfulControllers)) { 00348 return true; 00349 } 00350 return false; 00351 } 00352 00361 protected function _checkRestfulController($moduleName, $controllerName) 00362 { 00363 if ($this->_allRestful()) { 00364 return true; 00365 } 00366 if ($this->_fullRestfulModule($moduleName)) { 00367 return true; 00368 } 00369 if ($this->_checkRestfulModule($moduleName) 00370 && $this->_restfulControllers 00371 && (false !== array_search($controllerName, $this->_restfulControllers[$moduleName])) 00372 ) { 00373 return true; 00374 } 00375 return false; 00376 } 00377 00383 protected function _allRestful() 00384 { 00385 return (!$this->_restfulModules && !$this->_restfulControllers); 00386 } 00387 00394 protected function _fullRestfulModule($moduleName) 00395 { 00396 return ( 00397 $this->_restfulModules 00398 && (false !==array_search($moduleName, $this->_restfulModules)) 00399 ); 00400 } 00401 }