/** * Handle REST request. * * @return Mage_Webapi_Controller_Dispatcher_Rest */ public function dispatch() { try { $this->_authentication->authenticate(); $route = $this->_router->match($this->_request); $operation = $this->_request->getOperationName(); $resourceVersion = $this->_request->getResourceVersion(); $this->_apiConfig->validateVersionNumber($resourceVersion, $this->_request->getResourceName()); $method = $this->_apiConfig->getMethodNameByOperation($operation, $resourceVersion); $controllerClassName = $this->_apiConfig->getControllerClassByOperationName($operation); $controllerInstance = $this->_controllerFactory->createActionController($controllerClassName, $this->_request); $versionAfterFallback = $this->_apiConfig->identifyVersionSuffix($operation, $resourceVersion, $controllerInstance); /** * Route check has two stages: * The first is performed against full list of routes that is merged from all resources. * The second stage of route check can be performed only when actual version to be executed is known. */ $this->_router->checkRoute($this->_request, $method, $versionAfterFallback); $this->_apiConfig->checkDeprecationPolicy($route->getResourceName(), $method, $versionAfterFallback); $action = $method . $versionAfterFallback; $this->_authorization->checkResourceAcl($route->getResourceName(), $method); $inputData = $this->_restPresentation->fetchRequestData($controllerInstance, $action); $outputData = call_user_func_array(array($controllerInstance, $action), $inputData); $this->_restPresentation->prepareResponse($method, $outputData); } catch (Exception $e) { $this->_response->setException($e); } $this->_response->sendResponse(); return $this; }
/** * Get renderer for Mime-Type specified in Accept header of request. * * @return Mage_Webapi_Controller_Response_Rest_RendererInterface * @throws Mage_Webapi_Exception * @throws LogicException */ public function get() { $acceptTypes = $this->_request->getAcceptTypes(); $availableRenderers = (array) $this->_applicationConfig->getNode(self::XML_PATH_WEBAPI_RESPONSE_RENDERS); if (!is_array($acceptTypes)) { $acceptTypes = array($acceptTypes); } foreach ($acceptTypes as $acceptType) { foreach ($availableRenderers as $rendererConfig) { $rendererType = (string) $rendererConfig->type; if ($acceptType == $rendererType || $acceptType == current(explode('/', $rendererType)) . '/*' || $acceptType == '*/*') { $rendererClass = (string) $rendererConfig->model; break 2; } } } if (!isset($rendererClass)) { /** If server does not have renderer for any of the accepted types it SHOULD send 406 (not acceptable). */ throw new Mage_Webapi_Exception($this->_helper->__('Server cannot understand Accept HTTP header media type.'), Mage_Webapi_Exception::HTTP_NOT_ACCEPTABLE); } $renderer = $this->_objectManager->get($rendererClass); if (!$renderer instanceof Mage_Webapi_Controller_Response_Rest_RendererInterface) { throw new LogicException('The renderer must implement "Mage_Webapi_Controller_Response_Rest_RendererInterface".'); } return $renderer; }
/** * Check whether current request matches any route of specified method or not. Method version is taken into account. * * @param Mage_Webapi_Controller_Request_Rest $request * @param string $methodName * @param string $version * @throws Mage_Webapi_Exception In case when request does not match any route of specified method. */ public function checkRoute(Mage_Webapi_Controller_Request_Rest $request, $methodName, $version) { $resourceName = $request->getResourceName(); $routes = $this->_apiConfig->getMethodRestRoutes($resourceName, $methodName, $version); foreach ($routes as $route) { if ($route->match($request)) { return; } } throw new Mage_Webapi_Exception($this->_helper->__('Request does not match any route.'), Mage_Webapi_Exception::HTTP_NOT_FOUND); }
/** * Generate a list of routes available fo the specified method. * * @param ReflectionMethod $methodReflection * @return array */ public function generateRestRoutes(ReflectionMethod $methodReflection) { $routes = array(); $routePath = "/:" . Mage_Webapi_Controller_Router_Route_Rest::PARAM_VERSION; $routeParts = $this->_helper->getResourceNameParts($methodReflection->getDeclaringClass()->getName()); $partsCount = count($routeParts); for ($i = 0; $i < $partsCount; $i++) { if ($this->_isParentResourceIdExpected($methodReflection) && $i == $partsCount - 1) { $routePath .= "/:" . Mage_Webapi_Controller_Router_Route_Rest::PARAM_PARENT_ID; } $routePath .= "/" . lcfirst($this->_helper->convertSingularToPlural($routeParts[$i])); } if ($this->_isResourceIdExpected($methodReflection)) { $routePath .= "/:" . Mage_Webapi_Controller_Router_Route_Rest::PARAM_ID; } foreach ($this->_getAdditionalRequiredParamNames($methodReflection) as $additionalRequired) { $routePath .= "/{$additionalRequired}/:{$additionalRequired}"; } $actionType = Mage_Webapi_Controller_Request_Rest::getActionTypeByOperation($this->_helper->getMethodNameWithoutVersionSuffix($methodReflection)); $resourceName = $this->_helper->translateResourceName($methodReflection->getDeclaringClass()->getName()); $optionalParams = $this->_getOptionalParamNames($methodReflection); foreach ($this->_getPathCombinations($optionalParams, $routePath) as $finalRoutePath) { $routes[$finalRoutePath] = array('actionType' => $actionType, 'resourceName' => $resourceName); } $this->_routes = array_merge($this->_routes, $routes); return $routes; }
/** * Retrieve a list of all route objects associated with specified method. * * @param string $resourceName * @param string $methodName * @param string $version * @return Mage_Webapi_Controller_Router_Route_Rest[] * @throws InvalidArgumentException */ public function getMethodRestRoutes($resourceName, $methodName, $version) { $resourceData = $this->_getResourceData($resourceName, $version); if (!isset($resourceData['methods'][$methodName]['rest_routes'])) { throw new InvalidArgumentException(sprintf('The "%s" resource does not have any REST routes for "%s" method.', $resourceName, $methodName)); } $routes = array(); foreach ($resourceData['methods'][$methodName]['rest_routes'] as $routePath) { $routes[] = $this->_createRoute($routePath, $resourceName, Mage_Webapi_Controller_Request_Rest::getActionTypeByOperation($methodName)); } return $routes; }
/** * Test get method with wrong Renderer class. */ public function testGetWithWrongRendererClass() { $acceptTypes = array('application/json'); $availableRenders = $this->_createConfigElementForRenders(); /** Mock application config getNode method to return the list of renders. */ $this->_applicationMock->expects($this->once())->method('getNode')->will($this->returnValue($availableRenders)); /** Mock request getAcceptTypes method to return specified value. */ $this->_requestMock->expects($this->once())->method('getAcceptTypes')->will($this->returnValue($acceptTypes)); /** Mock object to return Varien_Object */ $this->_objectManagerMock->expects($this->once())->method('get')->with('Mage_Webapi_Controller_Response_Rest_Renderer_Json')->will($this->returnValue(new Varien_Object())); $this->setExpectedException('LogicException', 'The renderer must implement "Mage_Webapi_Controller_Response_Rest_RendererInterface".'); $this->_factory->get(); }
/** * Retrieve request data. Ensure that data is not empty. * * @param string $method * @return array */ protected function _getRequestBody($method) { $processedInputData = null; switch ($method) { case Mage_Webapi_Controller_ActionAbstract::METHOD_CREATE: $processedInputData = $this->_request->getBodyParams(); // TODO: Implement data filtration of item break; case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_CREATE: $processedInputData = $this->_request->getBodyParams(); break; case Mage_Webapi_Controller_ActionAbstract::METHOD_UPDATE: $processedInputData = $this->_request->getBodyParams(); // TODO: Implement data filtration break; case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_UPDATE: $processedInputData = $this->_request->getBodyParams(); // TODO: Implement fields filtration break; case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_DELETE: // break is intentionally omitted // break is intentionally omitted // break is intentionally omitted // break is intentionally omitted case Mage_Webapi_Controller_ActionAbstract::METHOD_GET: // break is intentionally omitted // break is intentionally omitted // break is intentionally omitted // break is intentionally omitted case Mage_Webapi_Controller_ActionAbstract::METHOD_DELETE: // break is intentionally omitted // break is intentionally omitted // break is intentionally omitted // break is intentionally omitted case Mage_Webapi_Controller_ActionAbstract::METHOD_LIST: break; } return $processedInputData; }
public function testGetActionTypeException() { $methodName = 'invalidMethodV1'; $this->setExpectedException('InvalidArgumentException', sprintf('The "%s" method is not a valid resource method.', $methodName)); Mage_Webapi_Controller_Request_Rest::getActionTypeByOperation($methodName); }