From 83da509e57641cf8270033959915123864e70a3a Mon Sep 17 00:00:00 2001 From: meyerbaptiste Date: Mon, 31 Oct 2016 18:23:43 +0100 Subject: [PATCH] Various fixes after a static analysis --- src/Api/ResourceClassResolver.php | 2 +- .../Doctrine/Orm/CollectionDataProvider.php | 2 ++ .../Orm/Extension/EagerLoadingExtension.php | 2 +- .../Orm/Extension/FilterExtension.php | 2 +- .../Doctrine/Orm/Filter/BooleanFilter.php | 8 ----- src/Bridge/Doctrine/Orm/Filter/DateFilter.php | 10 +------ .../Doctrine/Orm/Filter/NumericFilter.php | 8 ----- .../Doctrine/Orm/Filter/RangeFilter.php | 8 ----- .../Doctrine/Orm/Filter/SearchFilter.php | 4 +-- src/Bridge/Doctrine/Orm/ItemDataProvider.php | 7 +++++ src/Bridge/Doctrine/Orm/Paginator.php | 12 ++------ src/Bridge/Doctrine/Orm/Util/QueryChecker.php | 7 ++--- .../NelmioApiDoc/Parser/ApiPlatformParser.php | 15 ++++------ .../ApiPlatformExtension.php | 4 +-- .../Compiler/DataProviderPass.php | 2 +- .../Compiler/DoctrineQueryExtensionPass.php | 2 +- .../Compiler/FilterPass.php | 2 ++ .../Bundle/Resources/config/doctrine_orm.xml | 4 +-- ...pertyInfoPropertyNameCollectionFactory.php | 2 ++ src/Bridge/Symfony/Routing/IriConverter.php | 2 +- .../Routing/RouterOperationPathResolver.php | 2 ++ src/Documentation/Documentation.php | 2 +- src/EventListener/AddFormatListener.php | 5 +++- src/EventListener/ExceptionListener.php | 4 +-- src/EventListener/SerializeListener.php | 4 ++- src/Hal/Serializer/ItemNormalizer.php | 4 ++- src/JsonLd/ContextBuilder.php | 2 +- .../AnnotationPropertyMetadataFactory.php | 2 +- .../Factory/XmlResourceMetadataFactory.php | 2 ++ .../XmlResourceNameCollectionFactory.php | 2 ++ .../Factory/YamlResourceMetadataFactory.php | 1 + .../YamlResourceNameCollectionFactory.php | 1 + src/Serializer/AbstractItemNormalizer.php | 11 ++++--- src/Util/IriHelper.php | 2 ++ .../Doctrine/Orm/ItemDataProviderTest.php | 30 +++++++++++++++++++ tests/Fixtures/app/bootstrap.php | 2 +- tests/Fixtures/app/config/config.yml | 2 +- .../Property/PropertyMetadataTest.php | 20 ++++++------- .../Resource/ResourceMetadataTest.php | 12 ++++---- .../ValidationGroupsResolverInterface.php | 29 ------------------ 40 files changed, 117 insertions(+), 127 deletions(-) delete mode 100644 tests/Mock/ValidationGroupsResolverInterface.php diff --git a/src/Api/ResourceClassResolver.php b/src/Api/ResourceClassResolver.php index 3543f623136..bb1c26967fa 100644 --- a/src/Api/ResourceClassResolver.php +++ b/src/Api/ResourceClassResolver.php @@ -49,7 +49,7 @@ public function getResourceClass($value, string $resourceClass = null, bool $str $typeToFind = $type = $resourceClass; } - if (!$this->isResourceClass($typeToFind) || ($strict && isset($type) && $resourceClass !== $type)) { + if (($strict && isset($type) && $resourceClass !== $type) || !$this->isResourceClass($typeToFind)) { if (is_subclass_of($type, $resourceClass) && $this->isResourceClass($resourceClass)) { return $type; } diff --git a/src/Bridge/Doctrine/Orm/CollectionDataProvider.php b/src/Bridge/Doctrine/Orm/CollectionDataProvider.php index 77a6f4aef44..6fc366f6801 100644 --- a/src/Bridge/Doctrine/Orm/CollectionDataProvider.php +++ b/src/Bridge/Doctrine/Orm/CollectionDataProvider.php @@ -42,6 +42,8 @@ public function __construct(ManagerRegistry $managerRegistry, array $collectionE /** * {@inheritdoc} + * + * @throws RuntimeException */ public function getCollection(string $resourceClass, string $operationName = null) { diff --git a/src/Bridge/Doctrine/Orm/Extension/EagerLoadingExtension.php b/src/Bridge/Doctrine/Orm/Extension/EagerLoadingExtension.php index 5fa67f73d0b..7a7d800258c 100644 --- a/src/Bridge/Doctrine/Orm/Extension/EagerLoadingExtension.php +++ b/src/Bridge/Doctrine/Orm/Extension/EagerLoadingExtension.php @@ -116,7 +116,7 @@ private function joinRelations(QueryBuilder $queryBuilder, string $resourceClass $queryBuilder->addSelect(sprintf('partial %s.{%s}', $associationAlias, implode(',', $select))); - $relationAlias = $relationAlias.++$j; + $relationAlias .= ++$j; $this->joinRelations($queryBuilder, $mapping['targetEntity'], $propertyMetadataOptions, $associationAlias, $relationAlias, $method === 'leftJoin'); } diff --git a/src/Bridge/Doctrine/Orm/Extension/FilterExtension.php b/src/Bridge/Doctrine/Orm/Extension/FilterExtension.php index 2d0e35bacd6..479b3bfff1d 100644 --- a/src/Bridge/Doctrine/Orm/Extension/FilterExtension.php +++ b/src/Bridge/Doctrine/Orm/Extension/FilterExtension.php @@ -47,7 +47,7 @@ public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGenerator } foreach ($this->filters as $filterName => $filter) { - if (in_array($filterName, $resourceFilters) && $filter instanceof FilterInterface) { + if ($filter instanceof FilterInterface && in_array($filterName, $resourceFilters)) { $filter->apply($queryBuilder, $queryNameGenerator, $resourceClass, $operationName); } } diff --git a/src/Bridge/Doctrine/Orm/Filter/BooleanFilter.php b/src/Bridge/Doctrine/Orm/Filter/BooleanFilter.php index 5623a8cba1d..24a855e4cb5 100644 --- a/src/Bridge/Doctrine/Orm/Filter/BooleanFilter.php +++ b/src/Bridge/Doctrine/Orm/Filter/BooleanFilter.php @@ -13,11 +13,8 @@ use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface; use ApiPlatform\Core\Exception\InvalidArgumentException; -use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\DBAL\Types\Type as DBALType; use Doctrine\ORM\QueryBuilder; -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\RequestStack; /** * Filters the collection by boolean values. @@ -33,11 +30,6 @@ */ class BooleanFilter extends AbstractFilter { - public function __construct(ManagerRegistry $managerRegistry, RequestStack $requestStack, LoggerInterface $logger = null, array $properties = null) - { - parent::__construct($managerRegistry, $requestStack, $logger, $properties); - } - /** * {@inheritdoc} */ diff --git a/src/Bridge/Doctrine/Orm/Filter/DateFilter.php b/src/Bridge/Doctrine/Orm/Filter/DateFilter.php index 06bbecc9123..df11a7a9ed4 100644 --- a/src/Bridge/Doctrine/Orm/Filter/DateFilter.php +++ b/src/Bridge/Doctrine/Orm/Filter/DateFilter.php @@ -12,10 +12,7 @@ namespace ApiPlatform\Core\Bridge\Doctrine\Orm\Filter; use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface; -use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\ORM\QueryBuilder; -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\RequestStack; /** * Filters the collection by date intervals. @@ -37,11 +34,6 @@ class DateFilter extends AbstractFilter 'time' => true, ]; - public function __construct(ManagerRegistry $managerRegistry, RequestStack $requestStack, LoggerInterface $logger = null, array $properties = null) - { - parent::__construct($managerRegistry, $requestStack, $logger, $properties); - } - /** * {@inheritdoc} */ @@ -88,7 +80,7 @@ protected function filterProperty(string $property, $values, QueryBuilder $query list($alias, $field) = $this->addJoinsForNestedProperty($property, $alias, $queryBuilder, $queryNameGenerator); } - $nullManagement = isset($this->properties[$property]) ? $this->properties[$property] : null; + $nullManagement = $this->properties[$property] ?? null; if (self::EXCLUDE_NULL === $nullManagement) { $queryBuilder->andWhere($queryBuilder->expr()->isNotNull(sprintf('%s.%s', $alias, $field))); diff --git a/src/Bridge/Doctrine/Orm/Filter/NumericFilter.php b/src/Bridge/Doctrine/Orm/Filter/NumericFilter.php index 67356c4e731..b2caaca1faa 100644 --- a/src/Bridge/Doctrine/Orm/Filter/NumericFilter.php +++ b/src/Bridge/Doctrine/Orm/Filter/NumericFilter.php @@ -13,11 +13,8 @@ use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface; use ApiPlatform\Core\Exception\InvalidArgumentException; -use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\DBAL\Types\Type as DBALType; use Doctrine\ORM\QueryBuilder; -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\RequestStack; /** * Filters the collection by numeric values. @@ -45,11 +42,6 @@ class NumericFilter extends AbstractFilter DBALType::SMALLINT => true, ]; - public function __construct(ManagerRegistry $managerRegistry, RequestStack $requestStack, LoggerInterface $logger = null, array $properties = null) - { - parent::__construct($managerRegistry, $requestStack, $logger, $properties); - } - /** * {@inheritdoc} */ diff --git a/src/Bridge/Doctrine/Orm/Filter/RangeFilter.php b/src/Bridge/Doctrine/Orm/Filter/RangeFilter.php index 3308e8156d4..63989ef908d 100644 --- a/src/Bridge/Doctrine/Orm/Filter/RangeFilter.php +++ b/src/Bridge/Doctrine/Orm/Filter/RangeFilter.php @@ -13,10 +13,7 @@ use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface; use ApiPlatform\Core\Exception\InvalidArgumentException; -use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\ORM\QueryBuilder; -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\RequestStack; /** * Filters the collection by range. @@ -31,11 +28,6 @@ class RangeFilter extends AbstractFilter const PARAMETER_LESS_THAN = 'lt'; const PARAMETER_LESS_THAN_OR_EQUAL = 'lte'; - public function __construct(ManagerRegistry $managerRegistry, RequestStack $requestStack, LoggerInterface $logger = null, array $properties = null) - { - parent::__construct($managerRegistry, $requestStack, $logger, $properties); - } - /** * {@inheritdoc} */ diff --git a/src/Bridge/Doctrine/Orm/Filter/SearchFilter.php b/src/Bridge/Doctrine/Orm/Filter/SearchFilter.php index 8a7f66de050..7e0f18e3e95 100644 --- a/src/Bridge/Doctrine/Orm/Filter/SearchFilter.php +++ b/src/Bridge/Doctrine/Orm/Filter/SearchFilter.php @@ -168,9 +168,9 @@ private function getType(string $doctrineType) : string protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null) { if ( + null === $value || !$this->isPropertyEnabled($property) || - !$this->isPropertyMapped($property, $resourceClass, true) || - null === $value + !$this->isPropertyMapped($property, $resourceClass, true) ) { return; } diff --git a/src/Bridge/Doctrine/Orm/ItemDataProvider.php b/src/Bridge/Doctrine/Orm/ItemDataProvider.php index bab778ee847..141a493860c 100644 --- a/src/Bridge/Doctrine/Orm/ItemDataProvider.php +++ b/src/Bridge/Doctrine/Orm/ItemDataProvider.php @@ -17,6 +17,7 @@ use ApiPlatform\Core\DataProvider\ItemDataProviderInterface; use ApiPlatform\Core\Exception\PropertyNotFoundException; use ApiPlatform\Core\Exception\ResourceClassNotSupportedException; +use ApiPlatform\Core\Exception\RuntimeException; use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface; use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface; use Doctrine\Common\Persistence\ManagerRegistry; @@ -53,6 +54,8 @@ public function __construct(ManagerRegistry $managerRegistry, PropertyNameCollec /** * {@inheritdoc} + * + * @throws RuntimeException */ public function getItem(string $resourceClass, $id, string $operationName = null, bool $fetchData = false) { @@ -68,6 +71,10 @@ public function getItem(string $resourceClass, $id, string $operationName = null } $repository = $manager->getRepository($resourceClass); + if (!method_exists($repository, 'createQueryBuilder')) { + throw new RuntimeException('The repository class must have a "createQueryBuilder" method.'); + } + $queryBuilder = $repository->createQueryBuilder('o'); $queryNameGenerator = new QueryNameGenerator(); diff --git a/src/Bridge/Doctrine/Orm/Paginator.php b/src/Bridge/Doctrine/Orm/Paginator.php index 92d22aff711..dc0d18d2646 100644 --- a/src/Bridge/Doctrine/Orm/Paginator.php +++ b/src/Bridge/Doctrine/Orm/Paginator.php @@ -12,7 +12,6 @@ namespace ApiPlatform\Core\Bridge\Doctrine\Orm; use ApiPlatform\Core\DataProvider\PaginatorInterface; -use Doctrine\ORM\Query; use Doctrine\ORM\Tools\Pagination\Paginator as DoctrineOrmPaginator; /** @@ -24,11 +23,6 @@ final class Paginator implements \IteratorAggregate, PaginatorInterface { private $paginator; - /** - * @var Query - */ - private $query; - /** * @var int */ @@ -52,9 +46,9 @@ final class Paginator implements \IteratorAggregate, PaginatorInterface public function __construct(DoctrineOrmPaginator $paginator) { $this->paginator = $paginator; - $this->query = $paginator->getQuery(); - $this->firstResult = $this->query->getFirstResult(); - $this->maxResults = $this->query->getMaxResults(); + $query = $paginator->getQuery(); + $this->firstResult = $query->getFirstResult(); + $this->maxResults = $query->getMaxResults(); $this->totalItems = count($paginator); } diff --git a/src/Bridge/Doctrine/Orm/Util/QueryChecker.php b/src/Bridge/Doctrine/Orm/Util/QueryChecker.php index 22ccd29732c..17c70504eb6 100644 --- a/src/Bridge/Doctrine/Orm/Util/QueryChecker.php +++ b/src/Bridge/Doctrine/Orm/Util/QueryChecker.php @@ -132,16 +132,13 @@ public static function hasOrderByOnToManyJoin(QueryBuilder $queryBuilder, Manage } if (!empty($orderByAliases)) { - foreach ($joinParts as $rootAlias => $joins) { + foreach ($joinParts as $joins) { foreach ($joins as $join) { $alias = QueryJoinParser::getJoinAlias($join); if (isset($orderByAliases[$alias])) { $relationship = QueryJoinParser::getJoinRelationship($join); - - $relationshipParts = explode('.', $relationship); - $parentAlias = $relationshipParts[0]; - $association = $relationshipParts[1]; + list($parentAlias, $association) = explode('.', $relationship); $parentMetadata = QueryJoinParser::getClassMetadataFromJoinAlias($parentAlias, $queryBuilder, $managerRegistry); diff --git a/src/Bridge/NelmioApiDoc/Parser/ApiPlatformParser.php b/src/Bridge/NelmioApiDoc/Parser/ApiPlatformParser.php index 57d364f5528..5785cbf9257 100644 --- a/src/Bridge/NelmioApiDoc/Parser/ApiPlatformParser.php +++ b/src/Bridge/NelmioApiDoc/Parser/ApiPlatformParser.php @@ -131,7 +131,7 @@ private function getGroupsContext(ResourceMetadata $resourceMetadata, string $op $groupsContext = $isNormalization ? 'normalization_context' : 'denormalization_context'; $itemOperationAttribute = $resourceMetadata->getItemOperationAttribute($operationName, $groupsContext, ['groups' => []], true)['groups']; $collectionOperationAttribute = $resourceMetadata->getCollectionOperationAttribute($operationName, $groupsContext, ['groups' => []], true)['groups']; - $operation[$groupsContext]['groups'] = array_merge(isset($itemOperationAttribute) ? $itemOperationAttribute : [], isset($collectionOperationAttribute) ? $collectionOperationAttribute : []); + $operation[$groupsContext]['groups'] = array_merge($itemOperationAttribute ?? [], $collectionOperationAttribute ?? []); return $operation; } @@ -141,6 +141,7 @@ private function getGroupsContext(ResourceMetadata $resourceMetadata, string $op * * @param ResourceMetadata $resourceMetadata * @param string $operationName + * @param string $io * * @return array */ @@ -213,15 +214,11 @@ private function parseProperty(ResourceMetadata $resourceMetadata, PropertyMetad 'readonly' => !$propertyMetadata->isWritable(), ]; - if (null === $type) { - $type = $propertyMetadata->getType(); - - if (null === $type) { - // Default to string - $data['dataType'] = DataTypes::STRING; + if (null === $type && null === $type = $propertyMetadata->getType()) { + // Default to string + $data['dataType'] = DataTypes::STRING; - return $data; - } + return $data; } if ($type->isCollection()) { diff --git a/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php b/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php index 2a7690797ed..d4779732fc2 100644 --- a/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php +++ b/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php @@ -38,11 +38,11 @@ public function prepend(ContainerBuilder $container) return; } - if (!isset($frameworkConfiguration['serializer']) || !isset($frameworkConfiguration['serializer']['enabled'])) { + if (!isset($frameworkConfiguration['serializer'], $frameworkConfiguration['serializer']['enabled'])) { $container->prependExtensionConfig('framework', ['serializer' => ['enabled' => true]]); } - if (!isset($frameworkConfiguration['property_info']) || !isset($frameworkConfiguration['property_info']['enabled'])) { + if (!isset($frameworkConfiguration['property_info'], $frameworkConfiguration['property_info']['enabled'])) { $container->prependExtensionConfig('framework', ['property_info' => ['enabled' => true]]); } } diff --git a/src/Bridge/Symfony/Bundle/DependencyInjection/Compiler/DataProviderPass.php b/src/Bridge/Symfony/Bundle/DependencyInjection/Compiler/DataProviderPass.php index cddae693190..197dd1af282 100644 --- a/src/Bridge/Symfony/Bundle/DependencyInjection/Compiler/DataProviderPass.php +++ b/src/Bridge/Symfony/Bundle/DependencyInjection/Compiler/DataProviderPass.php @@ -49,7 +49,7 @@ private function registerDataProviders(ContainerBuilder $container, string $type foreach ($services as $serviceId => $tags) { foreach ($tags as $attributes) { - $priority = isset($attributes['priority']) ? $attributes['priority'] : 0; + $priority = $attributes['priority'] ?? 0; $queue->insert(new Reference($serviceId), $priority); } } diff --git a/src/Bridge/Symfony/Bundle/DependencyInjection/Compiler/DoctrineQueryExtensionPass.php b/src/Bridge/Symfony/Bundle/DependencyInjection/Compiler/DoctrineQueryExtensionPass.php index a57708009bc..3add3fa0595 100644 --- a/src/Bridge/Symfony/Bundle/DependencyInjection/Compiler/DoctrineQueryExtensionPass.php +++ b/src/Bridge/Symfony/Bundle/DependencyInjection/Compiler/DoctrineQueryExtensionPass.php @@ -55,7 +55,7 @@ private function findSortedServices(ContainerBuilder $container, $tag) $extensions = []; foreach ($container->findTaggedServiceIds($tag) as $serviceId => $tags) { foreach ($tags as $tag) { - $priority = isset($tag['priority']) ? $tag['priority'] : 0; + $priority = $tag['priority'] ?? 0; $extensions[$priority][] = new Reference($serviceId); } } diff --git a/src/Bridge/Symfony/Bundle/DependencyInjection/Compiler/FilterPass.php b/src/Bridge/Symfony/Bundle/DependencyInjection/Compiler/FilterPass.php index 7476620c61a..ccc22528507 100644 --- a/src/Bridge/Symfony/Bundle/DependencyInjection/Compiler/FilterPass.php +++ b/src/Bridge/Symfony/Bundle/DependencyInjection/Compiler/FilterPass.php @@ -27,6 +27,8 @@ final class FilterPass implements CompilerPassInterface { /** * {@inheritdoc} + * + * @throws RuntimeException */ public function process(ContainerBuilder $container) { diff --git a/src/Bridge/Symfony/Bundle/Resources/config/doctrine_orm.xml b/src/Bridge/Symfony/Bundle/Resources/config/doctrine_orm.xml index 0ff2c4f2b54..756e958949a 100644 --- a/src/Bridge/Symfony/Bundle/Resources/config/doctrine_orm.xml +++ b/src/Bridge/Symfony/Bundle/Resources/config/doctrine_orm.xml @@ -11,14 +11,14 @@ - + - + diff --git a/src/Bridge/Symfony/PropertyInfo/Metadata/Property/PropertyInfoPropertyNameCollectionFactory.php b/src/Bridge/Symfony/PropertyInfo/Metadata/Property/PropertyInfoPropertyNameCollectionFactory.php index b23df2be06b..2b3d5aa7b96 100644 --- a/src/Bridge/Symfony/PropertyInfo/Metadata/Property/PropertyInfoPropertyNameCollectionFactory.php +++ b/src/Bridge/Symfony/PropertyInfo/Metadata/Property/PropertyInfoPropertyNameCollectionFactory.php @@ -34,6 +34,8 @@ public function __construct(PropertyInfoExtractorInterface $propertyInfo) /** * {@inheritdoc} + * + * @throws RuntimeException */ public function create(string $resourceClass, array $options = []) : PropertyNameCollection { diff --git a/src/Bridge/Symfony/Routing/IriConverter.php b/src/Bridge/Symfony/Routing/IriConverter.php index ac8586e4561..55147077a90 100644 --- a/src/Bridge/Symfony/Routing/IriConverter.php +++ b/src/Bridge/Symfony/Routing/IriConverter.php @@ -61,7 +61,7 @@ public function getItemFromIri(string $iri, bool $fetchData = false) throw new InvalidArgumentException(sprintf('No route matches "%s".', $iri), $e->getCode(), $e); } - if (!isset($parameters['_api_resource_class']) || !isset($parameters['id'])) { + if (!isset($parameters['_api_resource_class'], $parameters['id'])) { throw new InvalidArgumentException(sprintf('No resource associated to "%s".', $iri)); } diff --git a/src/Bridge/Symfony/Routing/RouterOperationPathResolver.php b/src/Bridge/Symfony/Routing/RouterOperationPathResolver.php index 8fd6a85a3ac..c1a48b8ebb7 100644 --- a/src/Bridge/Symfony/Routing/RouterOperationPathResolver.php +++ b/src/Bridge/Symfony/Routing/RouterOperationPathResolver.php @@ -33,6 +33,8 @@ public function __construct(RouterInterface $router, OperationPathResolverInterf /** * {@inheritdoc} + * + * @throws InvalidArgumentException */ public function resolveOperationPath(string $resourceShortName, array $operation, bool $collection) : string { diff --git a/src/Documentation/Documentation.php b/src/Documentation/Documentation.php index 110ab8c508d..61ddc7bbb27 100644 --- a/src/Documentation/Documentation.php +++ b/src/Documentation/Documentation.php @@ -32,7 +32,7 @@ public function __construct(ResourceNameCollection $resourceNameCollection, stri $this->title = $title; $this->description = $description; $this->version = $version; - foreach ($formats as $format => $mimeTypes) { + foreach ($formats as $mimeTypes) { foreach ($mimeTypes as $mimeType) { $this->mimeTypes[] = $mimeType; } diff --git a/src/EventListener/AddFormatListener.php b/src/EventListener/AddFormatListener.php index 29a7f3c1eee..d3fe93565f8 100644 --- a/src/EventListener/AddFormatListener.php +++ b/src/EventListener/AddFormatListener.php @@ -38,6 +38,9 @@ public function __construct(Negotiator $negotiator, array $formats) * Sets the applicable format to the HttpFoundation Request. * * @param GetResponseEvent $event + * + * @throws NotFoundHttpException + * @throws NotAcceptableHttpException */ public function onKernelRequest(GetResponseEvent $event) { @@ -55,7 +58,7 @@ public function onKernelRequest(GetResponseEvent $event) } elseif (!isset($this->formats[$routeFormat])) { throw new NotFoundHttpException('Not Found'); } else { - $mimeTypes = $request->getMimeTypes($routeFormat); + $mimeTypes = Request::getMimeTypes($routeFormat); } // First, try to guess the format from the Accept header diff --git a/src/EventListener/ExceptionListener.php b/src/EventListener/ExceptionListener.php index 14db6112047..bd7c8fc5239 100644 --- a/src/EventListener/ExceptionListener.php +++ b/src/EventListener/ExceptionListener.php @@ -27,8 +27,8 @@ public function onKernelException(GetResponseForExceptionEvent $event) $request = $event->getRequest(); // Normalize exceptions only for routes managed by API Platform if ( - (!$request->attributes->has('_api_resource_class') && !$request->attributes->has('_api_respond')) || - 'html' === $request->getRequestFormat(null) + 'html' === $request->getRequestFormat(null) || + (!$request->attributes->has('_api_resource_class') && !$request->attributes->has('_api_respond')) ) { return; } diff --git a/src/EventListener/SerializeListener.php b/src/EventListener/SerializeListener.php index 2f4b35a7590..10110b611b1 100644 --- a/src/EventListener/SerializeListener.php +++ b/src/EventListener/SerializeListener.php @@ -70,6 +70,8 @@ public function onKernelView(GetResponseForControllerResultEvent $event) * @param GetResponseForControllerResultEvent $event * @param Request $request * @param object $controllerResult + * + * @throws RuntimeException */ private function serializeRawData(GetResponseForControllerResultEvent $event, Request $request, $controllerResult) { @@ -84,7 +86,7 @@ private function serializeRawData(GetResponseForControllerResultEvent $event, Re } if (!$this->serializer instanceof EncoderInterface) { - throw new RuntimeException('The serializer instance must implements the "%s" interface.', EncoderInterface::class); + throw new RuntimeException(sprintf('The serializer instance must implements the "%s" interface.', EncoderInterface::class)); } $event->setControllerResult($this->serializer->encode($controllerResult, $request->getRequestFormat())); diff --git a/src/Hal/Serializer/ItemNormalizer.php b/src/Hal/Serializer/ItemNormalizer.php index 79d637cbff3..00780a8f155 100644 --- a/src/Hal/Serializer/ItemNormalizer.php +++ b/src/Hal/Serializer/ItemNormalizer.php @@ -66,6 +66,8 @@ public function supportsDenormalization($data, $type, $format = null) /** * {@inheritdoc} + * + * @throws RuntimeException */ public function denormalize($data, $class, $format = null, array $context = []) { @@ -190,7 +192,7 @@ private function populateRelation(array $data, $object, string $format = null, a */ private function getRelationIri($rel) : string { - return isset($rel['_links']['self']['href']) ? $rel['_links']['self']['href'] : $rel; + return $rel['_links']['self']['href'] ?? $rel; } /** diff --git a/src/JsonLd/ContextBuilder.php b/src/JsonLd/ContextBuilder.php index 52afd73fb6f..5841c117cd3 100644 --- a/src/JsonLd/ContextBuilder.php +++ b/src/JsonLd/ContextBuilder.php @@ -104,7 +104,7 @@ public function getResourceContext(string $resourceClass, int $referenceType = U } if (true !== $propertyMetadata->isReadableLink()) { - $jsonldContext = $jsonldContext + [ + $jsonldContext += [ '@id' => $id, '@type' => '@id', ]; diff --git a/src/Metadata/Property/Factory/AnnotationPropertyMetadataFactory.php b/src/Metadata/Property/Factory/AnnotationPropertyMetadataFactory.php index eb54bd5c436..ea96bce866a 100644 --- a/src/Metadata/Property/Factory/AnnotationPropertyMetadataFactory.php +++ b/src/Metadata/Property/Factory/AnnotationPropertyMetadataFactory.php @@ -39,7 +39,7 @@ public function __construct(Reader $reader, PropertyMetadataFactoryInterface $de public function create(string $resourceClass, string $property, array $options = []) : PropertyMetadata { $parentPropertyMetadata = null; - if (isset($this->decorated)) { + if ($this->decorated) { try { $parentPropertyMetadata = $this->decorated->create($resourceClass, $property, $options); } catch (PropertyNotFoundException $propertyNotFoundException) { diff --git a/src/Metadata/Resource/Factory/XmlResourceMetadataFactory.php b/src/Metadata/Resource/Factory/XmlResourceMetadataFactory.php index f3d7d1157ac..f6e0e44de73 100644 --- a/src/Metadata/Resource/Factory/XmlResourceMetadataFactory.php +++ b/src/Metadata/Resource/Factory/XmlResourceMetadataFactory.php @@ -65,6 +65,8 @@ public function create(string $resourceClass) : ResourceMetadata * * @param string $resourceClass * + * @throws InvalidArgumentException + * * @return array */ private function getMetadata(string $resourceClass) : array diff --git a/src/Metadata/Resource/Factory/XmlResourceNameCollectionFactory.php b/src/Metadata/Resource/Factory/XmlResourceNameCollectionFactory.php index 2193b2ea700..0d4a36807dc 100644 --- a/src/Metadata/Resource/Factory/XmlResourceNameCollectionFactory.php +++ b/src/Metadata/Resource/Factory/XmlResourceNameCollectionFactory.php @@ -40,6 +40,8 @@ public function __construct(array $paths, ResourceNameCollectionFactoryInterface /** * {@inheritdoc} + * + * @throws InvalidArgumentException */ public function create() : ResourceNameCollection { diff --git a/src/Metadata/Resource/Factory/YamlResourceMetadataFactory.php b/src/Metadata/Resource/Factory/YamlResourceMetadataFactory.php index dfcc21979ec..c650a98528b 100644 --- a/src/Metadata/Resource/Factory/YamlResourceMetadataFactory.php +++ b/src/Metadata/Resource/Factory/YamlResourceMetadataFactory.php @@ -41,6 +41,7 @@ public function __construct(array $paths, ResourceMetadataFactoryInterface $deco * {@inheritdoc} * * @throws ParseException + * @throws InvalidArgumentException */ public function create(string $resourceClass) : ResourceMetadata { diff --git a/src/Metadata/Resource/Factory/YamlResourceNameCollectionFactory.php b/src/Metadata/Resource/Factory/YamlResourceNameCollectionFactory.php index 909ce85e3a1..46c6dc74269 100644 --- a/src/Metadata/Resource/Factory/YamlResourceNameCollectionFactory.php +++ b/src/Metadata/Resource/Factory/YamlResourceNameCollectionFactory.php @@ -40,6 +40,7 @@ public function __construct(array $paths, ResourceNameCollectionFactoryInterface * {@inheritdoc} * * @throws ParseException + * @throws InvalidArgumentException */ public function create() : ResourceNameCollection { diff --git a/src/Serializer/AbstractItemNormalizer.php b/src/Serializer/AbstractItemNormalizer.php index 53b9a89f186..5eda2c18f6d 100644 --- a/src/Serializer/AbstractItemNormalizer.php +++ b/src/Serializer/AbstractItemNormalizer.php @@ -153,7 +153,7 @@ protected function setAttributeValue($object, $attribute, $value, $format = null return; } - if ($type->isNullable() && null === $value) { + if (null === $value && $type->isNullable()) { $this->setValue($object, $attribute, $value); return; @@ -200,7 +200,7 @@ protected function setAttributeValue($object, $attribute, $value, $format = null protected function validateType(string $attribute, Type $type, $value, string $format = null) { $builtinType = $type->getBuiltinType(); - if (false !== strpos($format, 'json') && Type::BUILTIN_TYPE_FLOAT === $builtinType) { + if (Type::BUILTIN_TYPE_FLOAT === $builtinType && false !== strpos($format, 'json')) { $isValid = is_float($value) || is_int($value); } else { $isValid = call_user_func('is_'.$builtinType, $value); @@ -224,6 +224,8 @@ protected function validateType(string $attribute, Type $type, $value, string $f * @param string|null $format * @param array $context * + * @throws InvalidArgumentException + * * @return array */ private function denormalizeCollection(string $attribute, PropertyMetadata $propertyMetadata, Type $type, string $className, $value, string $format = null, array $context) : array @@ -344,14 +346,15 @@ protected function getFactoryOptions(array $context) : array protected function createRelationSerializationContext(string $resourceClass, array $context) : array { $context['resource_class'] = $resourceClass; - unset($context['item_operation_name']); - unset($context['collection_operation_name']); + unset($context['item_operation_name'], $context['collection_operation_name']); return $context; } /** * {@inheritdoc} + * + * @throws NoSuchPropertyException */ protected function getAttributeValue($object, $attribute, $format = null, array $context = []) { diff --git a/src/Util/IriHelper.php b/src/Util/IriHelper.php index 83564afcde7..3c263a8119e 100644 --- a/src/Util/IriHelper.php +++ b/src/Util/IriHelper.php @@ -32,6 +32,8 @@ private function __construct() * @param string $iri * @param string $pageParameterName * + * @throws InvalidArgumentException + * * @return array */ public static function parseIri(string $iri, string $pageParameterName) : array diff --git a/tests/Bridge/Doctrine/Orm/ItemDataProviderTest.php b/tests/Bridge/Doctrine/Orm/ItemDataProviderTest.php index f247f84b822..72e7ec6f971 100644 --- a/tests/Bridge/Doctrine/Orm/ItemDataProviderTest.php +++ b/tests/Bridge/Doctrine/Orm/ItemDataProviderTest.php @@ -22,6 +22,7 @@ use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Dummy; use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\Common\Persistence\ObjectManager; +use Doctrine\Common\Persistence\ObjectRepository; use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping\ClassMetadata; @@ -219,4 +220,33 @@ public function testThrowResourceClassNotSupportedException() $dataProvider = new ItemDataProvider($managerRegistryProphecy->reveal(), $propertyNameCollectionFactoryProphecy->reveal(), $propertyMetadataFactoryProphecy->reveal(), [$extensionProphecy->reveal()]); $dataProvider->getItem(Dummy::class, 'foo'); } + + /** + * @expectedException \ApiPlatform\Core\Exception\RuntimeException + * @expectedExceptionMessage The repository class must have a "createQueryBuilder" method. + */ + public function testCannotCreateQueryBuilder() + { + $repositoryProphecy = $this->prophesize(ObjectRepository::class); + + $classMetadataProphecy = $this->prophesize(ClassMetadata::class); + $classMetadataProphecy->getIdentifier()->willReturn(['id'])->shouldBeCalled(); + + $managerProphecy = $this->prophesize(ObjectManager::class); + $managerProphecy->getRepository(Dummy::class)->willReturn($repositoryProphecy->reveal())->shouldBeCalled(); + $managerProphecy->getClassMetadata(Dummy::class)->willReturn($classMetadataProphecy->reveal())->shouldBeCalled(); + + $managerRegistryProphecy = $this->prophesize(ManagerRegistry::class); + $managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($managerProphecy->reveal())->shouldBeCalled(); + + $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class); + $propertyNameCollectionFactoryProphecy->create(Dummy::class)->willReturn(new PropertyNameCollection(['id']))->shouldBeCalled(); + + $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class); + $propertyMetadataFactoryProphecy->create(Dummy::class, 'id')->willReturn((new PropertyMetadata())->withIdentifier(true))->shouldBeCalled(); + + $extensionProphecy = $this->prophesize(QueryItemExtensionInterface::class); + + (new ItemDataProvider($managerRegistryProphecy->reveal(), $propertyNameCollectionFactoryProphecy->reveal(), $propertyMetadataFactoryProphecy->reveal(), [$extensionProphecy->reveal()]))->getItem(Dummy::class, 'foo'); + } } diff --git a/tests/Fixtures/app/bootstrap.php b/tests/Fixtures/app/bootstrap.php index 94afa4d5038..1bc06d59d76 100644 --- a/tests/Fixtures/app/bootstrap.php +++ b/tests/Fixtures/app/bootstrap.php @@ -14,7 +14,7 @@ date_default_timezone_set('UTC'); $loader = require __DIR__.'/../../../vendor/autoload.php'; -require 'AppKernel.php'; +require __DIR__.'/AppKernel.php'; AnnotationRegistry::registerLoader([$loader, 'loadClass']); diff --git a/tests/Fixtures/app/config/config.yml b/tests/Fixtures/app/config/config.yml index e2e3618ddc6..707693d934c 100644 --- a/tests/Fixtures/app/config/config.yml +++ b/tests/Fixtures/app/config/config.yml @@ -78,7 +78,7 @@ services: - '%fos_user.model.user.class%' fos_user.mailer.default: - class: 'ApiPlatform\Core\Bridge\Symfony\Bundle\Tests\Mock\MailerMock' + class: 'ApiPlatform\Core\Tests\Mock\MailerMock' app.name_converter: class: 'ApiPlatform\Core\Tests\Fixtures\TestBundle\Serializer\NameConverter\CustomConverter' diff --git a/tests/Metadata/Property/PropertyMetadataTest.php b/tests/Metadata/Property/PropertyMetadataTest.php index 871e53c6ad2..ba3b3d6005c 100644 --- a/tests/Metadata/Property/PropertyMetadataTest.php +++ b/tests/Metadata/Property/PropertyMetadataTest.php @@ -36,43 +36,43 @@ public function testValueObject() $newType = new Type(Type::BUILTIN_TYPE_BOOL); $newMetadata = $metadata->withType($newType); - $this->assertFalse($newMetadata === $metadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertEquals($newType, $newMetadata->getType()); $newMetadata = $metadata->withDescription('description'); - $this->assertFalse($newMetadata === $metadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertEquals('description', $newMetadata->getDescription()); $newMetadata = $metadata->withReadable(false); - $this->assertFalse($newMetadata === $metadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertFalse($newMetadata->isReadable()); $newMetadata = $metadata->withWritable(false); - $this->assertFalse($newMetadata === $metadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertFalse($newMetadata->isWritable()); $newMetadata = $metadata->withReadableLink(true); - $this->assertFalse($newMetadata === $metadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertTrue($newMetadata->isReadableLink()); $newMetadata = $metadata->withWritableLink(true); - $this->assertFalse($newMetadata === $metadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertTrue($newMetadata->isWritableLink()); $newMetadata = $metadata->withRequired(false); - $this->assertFalse($newMetadata === $metadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertFalse($newMetadata->isRequired()); $newMetadata = $metadata->withIdentifier(true); - $this->assertFalse($newMetadata === $metadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertTrue($newMetadata->isIdentifier()); $newMetadata = $metadata->withIri('foo:bar'); - $this->assertFalse($newMetadata === $metadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertEquals('foo:bar', $newMetadata->getIri()); $newMetadata = $metadata->withAttributes(['a' => 'b']); - $this->assertFalse($newMetadata === $metadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertEquals(['a' => 'b'], $newMetadata->getAttributes()); } diff --git a/tests/Metadata/Resource/ResourceMetadataTest.php b/tests/Metadata/Resource/ResourceMetadataTest.php index 58ab32919b9..73d0bd828cc 100644 --- a/tests/Metadata/Resource/ResourceMetadataTest.php +++ b/tests/Metadata/Resource/ResourceMetadataTest.php @@ -39,27 +39,27 @@ public function testValueObject() $this->assertEquals('z', $metadata->getAttribute('notExist', 'z')); $newMetadata = $metadata->withShortName('name'); - $this->assertFalse($metadata === $newMetadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertEquals('name', $newMetadata->getShortName()); $newMetadata = $metadata->withDescription('description'); - $this->assertFalse($metadata === $newMetadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertEquals('description', $newMetadata->getDescription()); $newMetadata = $metadata->withIri('foo:bar'); - $this->assertFalse($metadata === $newMetadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertEquals('foo:bar', $newMetadata->getIri()); $newMetadata = $metadata->withItemOperations(['a' => ['b' => 'c']]); - $this->assertFalse($metadata === $newMetadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertEquals(['a' => ['b' => 'c']], $newMetadata->getItemOperations()); $newMetadata = $metadata->withCollectionOperations(['a' => ['b' => 'c']]); - $this->assertFalse($metadata === $newMetadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertEquals(['a' => ['b' => 'c']], $newMetadata->getCollectionOperations()); $newMetadata = $metadata->withAttributes(['a' => ['b' => 'c']]); - $this->assertFalse($metadata === $newMetadata); + $this->assertNotSame($metadata, $newMetadata); $this->assertEquals(['a' => ['b' => 'c']], $newMetadata->getAttributes()); } } diff --git a/tests/Mock/ValidationGroupsResolverInterface.php b/tests/Mock/ValidationGroupsResolverInterface.php deleted file mode 100644 index eaed9a2e81d..00000000000 --- a/tests/Mock/ValidationGroupsResolverInterface.php +++ /dev/null @@ -1,29 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace ApiPlatform\Core\Tests\Mock; - -use Symfony\Component\Validator\Constraints\GroupSequence; - -/** - * @author Teoh Han Hui - */ -interface ValidationGroupsResolverInterface -{ - /** - * Gets validation groups for the provided data. - * - * @param mixed $data - * - * @return string[]|GroupSequence - */ - public function getValidationGroups($data); -}