/** * @param MethodCollection $methodCollection * * @return array */ public function extract(MethodCollection $methodCollection) { $metadata = []; /** @var callable $callable */ foreach ($methodCollection as $methodName => $callable) { $reflectionFunction = ReflectionFunctionFactory::createFromCallable($callable); $requestObjectClass = $this->determineRequestObjectClass($reflectionFunction); $responseObjectClass = $this->determineResponseObjectClass($reflectionFunction); $docBlock = new DocBlock($reflectionFunction); $metadata[] = ['method' => $methodName, 'description' => $docBlock->getShortDescription(), 'parameters' => $this->extractParameters($requestObjectClass), 'returns' => $this->extractParameters($responseObjectClass)]; } return $metadata; }
/** * {@inheritdoc} */ public function invoke(callable $callable, $requestObject) { /** @var Attribute $attributeAnnotation */ $attributeAnnotation = $this->annotationReader->getMethodAnnotation(ReflectionFunctionFactory::createReflectionMethodFromCallable($callable), Attribute::class); $attributeName = $attributeAnnotation->name; $attributeValue = $this->propertyAccessor->getValue($requestObject, $attributeAnnotation->valueAt); $userId = $this->userProvider->getUserId(); if (!is_array($attributeValue) && !$this->guard->isGranted($userId, $attributeName, $attributeValue)) { throw new AccessDeniedException(); } if (is_array($attributeValue)) { $attributeValue = $this->guard->filterGranted($userId, $attributeName, $attributeValue); $this->propertyAccessor->setValue($requestObject, $attributeAnnotation->valueAt, $attributeValue); } return $this->methodInvoker->invoke($callable, $requestObject); }
/** * {@inheritdoc} */ public function mapToObject(callable $callable, array $arguments) { if (count($arguments) > 0 && $this->isIndexedArray($arguments)) { throw new InvalidCallableArgumentsException('Can not map indexed arrays'); } $reflectionFunction = ReflectionFunctionFactory::createFromCallable($callable); if ($reflectionFunction->getNumberOfRequiredParameters() > 1) { throw new InvalidMethodParametersException('Could not map to more than one parameter'); } $reflectionParameters = $reflectionFunction->getParameters(); /** @var \ReflectionParameter $targetReflectionParameter */ $targetReflectionParameter = reset($reflectionParameters); if (null === $targetReflectionParameter->getClass()) { throw new InvalidMethodParametersException('Method parameter should have type definition'); } $mapped = $this->normalizer->denormalize($targetReflectionParameter->getClass()->name, $arguments); return $mapped; }