mirror of
https://github.com/bdnugget/magento2.git
synced 2026-11-07 09:17:35 +00:00
203 lines
6.2 KiB
PHP
203 lines
6.2 KiB
PHP
<?php
|
|
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Magento\Webapi\Controller\Rest;
|
|
|
|
use Magento\Framework\Api\SimpleDataObjectConverter;
|
|
use Magento\Framework\App\ObjectManager;
|
|
use Magento\Framework\Exception\AuthorizationException;
|
|
use Magento\Framework\Exception\InputException;
|
|
use Magento\Framework\Exception\LocalizedException;
|
|
use Magento\Framework\Reflection\MethodsMap;
|
|
use Magento\Framework\Webapi\Exception;
|
|
use Magento\Framework\Webapi\ServiceInputProcessor;
|
|
use Magento\Framework\Webapi\Rest\Request as RestRequest;
|
|
use Magento\Framework\Webapi\Validator\EntityArrayValidator\InputArraySizeLimitValue;
|
|
use Magento\Webapi\Controller\Rest\Router\Route;
|
|
|
|
/**
|
|
* This class is responsible for retrieving resolved input data
|
|
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
|
*/
|
|
class InputParamsResolver
|
|
{
|
|
/**
|
|
* @var RestRequest
|
|
*/
|
|
private $request;
|
|
|
|
/**
|
|
* @var ParamsOverrider
|
|
*/
|
|
private $paramsOverrider;
|
|
|
|
/**
|
|
* @var ServiceInputProcessor
|
|
*/
|
|
private $serviceInputProcessor;
|
|
|
|
/**
|
|
* @var Router
|
|
*/
|
|
private $router;
|
|
|
|
/**
|
|
* @var Route
|
|
*/
|
|
private $route;
|
|
|
|
/**
|
|
* @var RequestValidator
|
|
*/
|
|
private $requestValidator;
|
|
|
|
/**
|
|
* @var MethodsMap
|
|
*/
|
|
private $methodsMap;
|
|
|
|
/**
|
|
* @var InputArraySizeLimitValue
|
|
*/
|
|
private $inputArraySizeLimitValue;
|
|
|
|
/**
|
|
* Initialize dependencies
|
|
*
|
|
* @param RestRequest $request
|
|
* @param ParamsOverrider $paramsOverrider
|
|
* @param ServiceInputProcessor $serviceInputProcessor
|
|
* @param Router $router
|
|
* @param RequestValidator $requestValidator
|
|
* @param MethodsMap|null $methodsMap
|
|
* @param InputArraySizeLimitValue|null $inputArraySizeLimitValue
|
|
*/
|
|
public function __construct(
|
|
RestRequest $request,
|
|
ParamsOverrider $paramsOverrider,
|
|
ServiceInputProcessor $serviceInputProcessor,
|
|
Router $router,
|
|
RequestValidator $requestValidator,
|
|
MethodsMap $methodsMap = null,
|
|
?InputArraySizeLimitValue $inputArraySizeLimitValue = null
|
|
) {
|
|
$this->request = $request;
|
|
$this->paramsOverrider = $paramsOverrider;
|
|
$this->serviceInputProcessor = $serviceInputProcessor;
|
|
$this->router = $router;
|
|
$this->requestValidator = $requestValidator;
|
|
$this->methodsMap = $methodsMap ?: ObjectManager::getInstance()
|
|
->get(MethodsMap::class);
|
|
$this->inputArraySizeLimitValue = $inputArraySizeLimitValue ?? ObjectManager::getInstance()
|
|
->get(InputArraySizeLimitValue::class);
|
|
}
|
|
|
|
/**
|
|
* Process and resolve input parameters
|
|
*
|
|
* @return array
|
|
* @throws Exception|AuthorizationException|LocalizedException
|
|
*/
|
|
public function resolve()
|
|
{
|
|
$this->requestValidator->validate();
|
|
$route = $this->getRoute();
|
|
$this->inputArraySizeLimitValue->set($route->getInputArraySizeLimit());
|
|
|
|
return $this->serviceInputProcessor->process(
|
|
$route->getServiceClass(),
|
|
$route->getServiceMethod(),
|
|
$this->getInputData(),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get API input data
|
|
*
|
|
* @return array
|
|
* @throws InputException|Exception
|
|
*/
|
|
public function getInputData()
|
|
{
|
|
$route = $this->getRoute();
|
|
$serviceMethodName = $route->getServiceMethod();
|
|
$serviceClassName = $route->getServiceClass();
|
|
/*
|
|
* Valid only for updates using PUT when passing id value both in URL and body
|
|
*/
|
|
if ($this->request->getHttpMethod() == RestRequest::HTTP_METHOD_PUT) {
|
|
$inputData = $this->paramsOverrider->overrideRequestBodyIdWithPathParam(
|
|
$this->request->getParams(),
|
|
$this->request->getBodyParams(),
|
|
$serviceClassName,
|
|
$serviceMethodName
|
|
);
|
|
$inputData = array_merge($inputData, $this->request->getParams());
|
|
} else {
|
|
$inputData = $this->request->getRequestData();
|
|
}
|
|
$this->validateParameters($serviceClassName, $serviceMethodName, array_keys($route->getParameters()));
|
|
|
|
return $this->paramsOverrider->override($inputData, $route->getParameters());
|
|
}
|
|
|
|
/**
|
|
* Retrieve current route.
|
|
*
|
|
* @return Route
|
|
* @throws Exception
|
|
*/
|
|
public function getRoute()
|
|
{
|
|
if (!$this->route) {
|
|
$this->route = $this->router->match($this->request);
|
|
}
|
|
|
|
return $this->route;
|
|
}
|
|
|
|
/**
|
|
* Validate that parameters are really used in the current request.
|
|
*
|
|
* @param string $serviceClassName
|
|
* @param string $serviceMethodName
|
|
* @param array $paramOverriders
|
|
*/
|
|
private function validateParameters(
|
|
string $serviceClassName,
|
|
string $serviceMethodName,
|
|
array $paramOverriders
|
|
): void {
|
|
$methodParams = $this->methodsMap->getMethodParams($serviceClassName, $serviceMethodName);
|
|
foreach ($paramOverriders as $key => $param) {
|
|
$arrayKeys = explode('.', $param ?? '');
|
|
$value = array_shift($arrayKeys);
|
|
|
|
foreach ($methodParams as $serviceMethodParam) {
|
|
$serviceMethodParamName = $serviceMethodParam[MethodsMap::METHOD_META_NAME];
|
|
$serviceMethodType = $serviceMethodParam[MethodsMap::METHOD_META_TYPE];
|
|
|
|
$camelCaseValue = SimpleDataObjectConverter::snakeCaseToCamelCase($value);
|
|
if ($serviceMethodParamName === $value || $serviceMethodParamName === $camelCaseValue) {
|
|
if (count($arrayKeys) > 0) {
|
|
$camelCaseKey = SimpleDataObjectConverter::snakeCaseToCamelCase('set_' . $arrayKeys[0]);
|
|
$this->validateParameters($serviceMethodType, $camelCaseKey, [implode('.', $arrayKeys)]);
|
|
}
|
|
unset($paramOverriders[$key]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!empty($paramOverriders)) {
|
|
$message = 'The current request does not expect the next parameters: '
|
|
. implode(', ', $paramOverriders);
|
|
throw new \UnexpectedValueException(__($message)->__toString());
|
|
}
|
|
}
|
|
}
|