• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

api-platform / core / 13925245599

18 Mar 2025 02:06PM UTC coverage: 61.074% (-0.9%) from 61.973%
13925245599

Pull #7031

github

web-flow
Merge 8990d8b26 into 7cb5a6db8
Pull Request #7031: fix: header parameter should be case insensitive

3 of 4 new or added lines in 1 file covered. (75.0%)

167 existing lines in 27 files now uncovered.

11314 of 18525 relevant lines covered (61.07%)

51.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/GraphQl/Resolver/Factory/ItemMutationResolverFactory.php
1
<?php
2

3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <dunglas@gmail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types=1);
13

14
namespace ApiPlatform\GraphQl\Resolver\Factory;
15

16
use ApiPlatform\GraphQl\Resolver\MutationResolverInterface;
17
use ApiPlatform\GraphQl\Resolver\Stage\DeserializeStageInterface;
18
use ApiPlatform\GraphQl\Resolver\Stage\ReadStageInterface;
19
use ApiPlatform\GraphQl\Resolver\Stage\SecurityPostDenormalizeStageInterface;
20
use ApiPlatform\GraphQl\Resolver\Stage\SecurityPostValidationStageInterface;
21
use ApiPlatform\GraphQl\Resolver\Stage\SecurityStageInterface;
22
use ApiPlatform\GraphQl\Resolver\Stage\SerializeStageInterface;
23
use ApiPlatform\GraphQl\Resolver\Stage\ValidateStageInterface;
24
use ApiPlatform\GraphQl\Resolver\Stage\WriteStageInterface;
25
use ApiPlatform\Metadata\DeleteOperationInterface;
26
use ApiPlatform\Metadata\GraphQl\Operation;
27
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
28
use ApiPlatform\Metadata\Util\ClassInfoTrait;
29
use ApiPlatform\Metadata\Util\CloneTrait;
30
use GraphQL\Type\Definition\ResolveInfo;
31
use Psr\Container\ContainerInterface;
32

33
/**
34
 * Creates a function resolving a GraphQL mutation of an item.
35
 *
36
 * @author Alan Poulain <contact@alanpoulain.eu>
37
 * @author Vincent Chalamon <vincentchalamon@gmail.com>
38
 *
39
 * @deprecated
40
 */
41
final class ItemMutationResolverFactory implements ResolverFactoryInterface
42
{
43
    use ClassInfoTrait;
44
    use CloneTrait;
45

46
    public function __construct(private readonly ReadStageInterface $readStage, private readonly SecurityStageInterface $securityStage, private readonly SecurityPostDenormalizeStageInterface $securityPostDenormalizeStage, private readonly SerializeStageInterface $serializeStage, private readonly DeserializeStageInterface $deserializeStage, private readonly WriteStageInterface $writeStage, private readonly ValidateStageInterface $validateStage, private readonly ContainerInterface $mutationResolverLocator, private readonly SecurityPostValidationStageInterface $securityPostValidationStage)
47
    {
UNCOV
48
    }
×
49

50
    public function __invoke(?string $resourceClass = null, ?string $rootClass = null, ?Operation $operation = null, ?PropertyMetadataFactoryInterface $propertyMetadataFactory = null): callable
51
    {
52
        return function (?array $source, array $args, $context, ResolveInfo $info) use ($resourceClass, $rootClass, $operation): ?array {
×
53
            if (null === $resourceClass || null === $operation) {
×
54
                return null;
×
55
            }
56

57
            $resolverContext = ['source' => $source, 'args' => $args, 'info' => $info, 'is_collection' => false, 'is_mutation' => true, 'is_subscription' => false];
×
58

59
            $item = ($this->readStage)($resourceClass, $rootClass, $operation, $resolverContext);
×
60
            if (null !== $item && !\is_object($item)) {
×
61
                throw new \LogicException('Item from read stage should be a nullable object.');
×
62
            }
63
            ($this->securityStage)($resourceClass, $operation, $resolverContext + [
×
64
                'extra_variables' => [
×
65
                    'object' => $item,
×
66
                ],
×
67
            ]);
×
68
            $previousItem = $this->clone($item);
×
69

70
            if ('delete' === $operation->getName() || $operation instanceof DeleteOperationInterface) {
×
71
                ($this->securityPostDenormalizeStage)($resourceClass, $operation, $resolverContext + [
×
72
                    'extra_variables' => [
×
73
                        'object' => $item,
×
74
                        'previous_object' => $previousItem,
×
75
                    ],
×
76
                ]);
×
77
                $item = ($this->writeStage)($item, $resourceClass, $operation, $resolverContext);
×
78

79
                return ($this->serializeStage)($item, $resourceClass, $operation, $resolverContext);
×
80
            }
81

82
            $item = ($this->deserializeStage)($item, $resourceClass, $operation, $resolverContext);
×
83

84
            $mutationResolverId = $operation->getResolver();
×
85
            if (null !== $mutationResolverId) {
×
86
                /** @var MutationResolverInterface $mutationResolver */
87
                $mutationResolver = $this->mutationResolverLocator->get($mutationResolverId);
×
88
                $item = $mutationResolver($item, $resolverContext);
×
89
                if (null !== $item && $resourceClass !== $itemClass = $this->getObjectClass($item)) {
×
90
                    throw new \LogicException(\sprintf('Custom mutation resolver "%s" has to return an item of class %s but returned an item of class %s.', $mutationResolverId, $operation->getShortName(), (new \ReflectionClass($itemClass))->getShortName()));
×
91
                }
92
            }
93

94
            ($this->securityPostDenormalizeStage)($resourceClass, $operation, $resolverContext + [
×
95
                'extra_variables' => [
×
96
                    'object' => $item,
×
97
                    'previous_object' => $previousItem,
×
98
                ],
×
99
            ]);
×
100

101
            if (null !== $item) {
×
102
                ($this->validateStage)($item, $resourceClass, $operation, $resolverContext);
×
103

104
                ($this->securityPostValidationStage)($resourceClass, $operation, $resolverContext + [
×
105
                    'extra_variables' => [
×
106
                        'object' => $item,
×
107
                        'previous_object' => $previousItem,
×
108
                    ],
×
109
                ]);
×
110

111
                $persistResult = ($this->writeStage)($item, $resourceClass, $operation, $resolverContext);
×
112
            }
113

114
            return ($this->serializeStage)($persistResult ?? $item, $resourceClass, $operation, $resolverContext);
×
115
        };
×
116
    }
117
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc