/** * Check if specified version of resource exists. If not - exception is thrown. * * @param string $resourceName * @param string $resourceVersion * @throws RuntimeException When resource does not exist. */ protected function _checkIfResourceVersionExists($resourceName, $resourceVersion) { if (!isset($this->_data['resources'][$resourceName])) { throw new RuntimeException($this->_helper->__('Unknown resource "%s".', $resourceName)); } if (!isset($this->_data['resources'][$resourceName]['versions'][$resourceVersion])) { throw new RuntimeException($this->_helper->__('Unknown version "%s" for resource "%s".', $resourceVersion, $resourceName)); } }
/** * Fetch data from request and prepare it for passing to specified action. * * @param object $controllerInstance * @param string $action * @return array */ public function fetchRequestData($controllerInstance, $action) { $methodReflection = Mage_Webapi_Helper_Data::createMethodReflection($controllerInstance, $action); $methodName = $this->_configHelper->getMethodNameWithoutVersionSuffix($methodReflection); $bodyParamName = $this->_configHelper->getOperationBodyParamName($methodReflection); $requestParams = array_merge($this->_request->getParams(), array($bodyParamName => $this->_getRequestBody($methodName))); /** Convert names of ID and Parent ID params in request to those which are used in method interface. */ $idArgumentName = $this->_configHelper->getOperationIdParamName($methodReflection); $parentIdParamName = Mage_Webapi_Controller_Router_Route_Rest::PARAM_PARENT_ID; $idParamName = Mage_Webapi_Controller_Router_Route_Rest::PARAM_ID; if (isset($requestParams[$parentIdParamName]) && $idArgumentName != $parentIdParamName) { $requestParams[$idArgumentName] = $requestParams[$parentIdParamName]; unset($requestParams[$parentIdParamName]); } elseif (isset($requestParams[$idParamName]) && $idArgumentName != $idParamName) { $requestParams[$idArgumentName] = $requestParams[$idParamName]; unset($requestParams[$idParamName]); } return $this->_apiHelper->prepareMethodParams($controllerInstance, $action, $requestParams, $this->_apiConfig); }
/** * Format data of array type. * * @param array $data * @param string $dataType * @param Mage_Webapi_Model_ConfigAbstract $apiConfig * @return array * @throws Mage_Webapi_Exception If passed data is not an array */ protected function _formatArrayData($data, $dataType, $apiConfig) { $itemDataType = $this->_configHelper->getArrayItemType($dataType); $formattedData = array(); if (!is_array($data)) { throw new Mage_Webapi_Exception($this->__('Data corresponding to "%s" type is expected to be an array.', $dataType), Mage_Webapi_Exception::HTTP_BAD_REQUEST); } foreach ($data as $itemData) { $formattedData[] = $this->_formatParamData($itemData, $itemDataType, $apiConfig); } return $formattedData; }
/** * Process different element types. * * @param string $elementType * @param string $documentation * @param DOMElement $appInfoNode */ protected function _processElementType($elementType, $documentation, DOMElement $appInfoNode) { if ($elementType == 'int') { $this->_processRequiredAnnotation('min', $documentation, $appInfoNode); $this->_processRequiredAnnotation('max', $documentation, $appInfoNode); } if ($elementType == 'string') { $this->_processRequiredAnnotation('maxLength', $documentation, $appInfoNode); } if ($this->_helper->isArrayType($elementType)) { $natureOfTypeNode = $this->_dom->createElement(self::APP_INF_NS . ':natureOfType'); $natureOfTypeNode->appendChild($this->_dom->createTextNode('array')); $appInfoNode->appendChild($natureOfTypeNode); } }
/** * Retrieve the list of names of required params except ID and Request body. * * @param ReflectionMethod $methodReflection * @return array */ protected function _getAdditionalRequiredParamNames(ReflectionMethod $methodReflection) { $paramNames = array(); $methodInterfaces = $methodReflection->getPrototypes(); /** Take the fullest interface that includes optional parameters also. */ /** @var \Zend\Server\Reflection\Prototype $methodInterface */ $methodInterface = end($methodInterfaces); $methodParams = $methodInterface->getParameters(); $idParamName = $this->_helper->getOperationIdParamName($methodReflection); $bodyParamName = $this->_helper->getOperationBodyParamName($methodReflection); /** @var ReflectionParameter $paramReflection */ foreach ($methodParams as $paramReflection) { if (!$paramReflection->isOptional() && $paramReflection->getName() != $bodyParamName && $paramReflection->getName() != $idParamName) { $paramNames[] = $paramReflection->getName(); } } return $paramNames; }
/** * Assert parameter data. * * @param string $expectedName * @param string $expectedType * @param string $expectedIsRequired * @param string $expectedDoc * @param array $expectedAppinfo * @param DOMElement $complexType with actual parameter element. */ protected function _assertParameter($expectedName, $expectedType, $expectedIsRequired, $expectedDoc, $expectedAppinfo, DOMElement $complexType) { $xsdNs = Wsdl::XSD_NS; $tns = Wsdl::TYPES_NS; /** @var DOMElement $parameterElement */ $parameterElement = $this->_xpath->query("{$xsdNs}:sequence/{$xsdNs}:element[@name='{$expectedName}']", $complexType)->item(0); $this->assertNotNull($parameterElement, sprintf('"%s" element was not found in complex type "%s".', $expectedName, $complexType->getAttribute('name'))); $isArray = $this->_helper->isArrayType($expectedType); if ($isArray) { $expectedType = $this->_helper->translateArrayTypeName($expectedType); } else { $this->assertEquals($expectedIsRequired ? 1 : 0, $parameterElement->getAttribute('minOccurs')); $this->assertEquals(1, $parameterElement->getAttribute('maxOccurs')); } $expectedNs = $this->_helper->isTypeSimple($expectedType) ? $xsdNs : $tns; $this->assertEquals("{$expectedNs}:{$expectedType}", $parameterElement->getAttribute('type')); $this->_assertDocumentation($expectedDoc, $parameterElement); $this->_assertAppinfo($expectedAppinfo, $parameterElement); }
/** * Process call info data from interface. * * @param array $interface * @param string $resourceName * @param string $methodName */ protected function _processInterfaceCallInfo($interface, $resourceName, $methodName) { foreach ($interface as $direction => $interfaceData) { $direction = $direction == 'in' ? 'requiredInput' : 'returned'; foreach ($interfaceData['parameters'] as $parameterData) { $parameterType = $parameterData['type']; if (!$this->_helper->isTypeSimple($parameterType)) { $operation = $this->getOperationName($resourceName, $methodName); if ($parameterData['required']) { $condition = $direction == 'requiredInput' ? 'yes' : 'always'; } else { $condition = $direction == 'requiredInput' ? 'no' : 'conditionally'; } $callInfo = array(); $callInfo[$direction][$condition]['calls'][] = $operation; $this->_apiConfig->setTypeData($parameterType, array('callInfo' => $callInfo)); } } } }
/** * Extract method deprecation policy "use method" data. * * @param ReflectionMethod $methodReflection * @param string $useMethod * @param array $deprecationPolicy * @throws LogicException */ protected function _extractDeprecationPolicyUseMethod(ReflectionMethod $methodReflection, $useMethod, &$deprecationPolicy) { $invalidFormatMessage = sprintf('The "%s" method has invalid format of Deprecation policy. ' . 'Accepted formats are createV1, catalogProduct::createV1 ' . 'and Mage_Catalog_Webapi_ProductController::createV1.', $methodReflection->getDeclaringClass()->getName() . '::' . $methodReflection->getName()); /** Add information about what method should be used instead of deprecated/removed one. */ /** * Description is expected in one of the following formats: * - Mage_Catalog_Webapi_ProductController::createV1 * - catalogProduct::createV1 * - createV1 */ $useMethodParts = explode('::', $useMethod); switch (count($useMethodParts)) { case 2: try { /** Support of: Mage_Catalog_Webapi_ProductController::createV1 */ $resourceName = $this->_helper->translateResourceName($useMethodParts[0]); } catch (InvalidArgumentException $e) { /** Support of: catalogProduct::createV1 */ $resourceName = $useMethodParts[0]; } $deprecationPolicy['use_resource'] = $resourceName; $methodName = $useMethodParts[1]; break; case 1: $methodName = $useMethodParts[0]; /** If resource was not specified, current one should be used. */ $deprecationPolicy['use_resource'] = $this->_helper->translateResourceName($methodReflection->getDeclaringClass()->getName()); break; default: throw new LogicException($invalidFormatMessage); break; } try { $methodWithoutVersion = $this->getMethodNameWithoutVersionSuffix($methodName); } catch (Exception $e) { throw new LogicException($invalidFormatMessage); } $deprecationPolicy['use_method'] = $methodWithoutVersion; $methodVersion = str_replace($methodWithoutVersion, '', $methodName); $deprecationPolicy['use_version'] = ucfirst($methodVersion); }
/** * Retrieve complex type information from class public properties. * * @param string $class * @return array * @throws InvalidArgumentException */ protected function _processComplexType($class) { $typeName = $this->_helper->translateTypeName($class); $this->_types[$typeName] = array(); if ($this->_helper->isArrayType($class)) { $this->process($this->_helper->getArrayItemType($class)); } else { if (!class_exists($class)) { throw new InvalidArgumentException(sprintf('Could not load the "%s" class as parameter type.', $class)); } $reflection = new ClassReflection($class); $docBlock = $reflection->getDocBlock(); $this->_types[$typeName]['documentation'] = $docBlock ? $this->_getDescription($docBlock) : ''; $defaultProperties = $reflection->getDefaultProperties(); /** @var \Zend\Code\Reflection\PropertyReflection $property */ foreach ($reflection->getProperties(ReflectionProperty::IS_PUBLIC) as $property) { $this->_processProperty($property, $defaultProperties, $typeName); } } return $this->_types[$typeName]; }
public function testGetIdParamException() { $className = 'Vendor_Module_Webapi_Resource_Invalid'; $this->setExpectedException('LogicException', sprintf('"%s" is not a valid resource class.', $className)); $this->_helper->getOperationIdParamName(Mage_Webapi_Helper_Data::createMethodReflection($className, 'updateV1')); }