Passed
Push — 2.3 ( 688483...e51024 )
by Kévin
03:09
created

ItemNormalizer::__construct()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 2
nc 1
nop 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <[email protected]>
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\Core\Serializer;
15
16
use ApiPlatform\Core\Api\IriConverterInterface;
17
use ApiPlatform\Core\Api\ResourceClassResolverInterface;
18
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
19
use ApiPlatform\Core\Exception\InvalidArgumentException;
20
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
21
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
22
use Psr\Log\LoggerInterface;
23
use Psr\Log\NullLogger;
24
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
25
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
26
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
27
28
/**
29
 * Generic item normalizer.
30
 *
31
 * @final
32
 *
33
 * @author Kévin Dunglas <[email protected]>
34
 */
35
class ItemNormalizer extends AbstractItemNormalizer
36
{
37
    private $logger;
38
39
    public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, IriConverterInterface $iriConverter, ResourceClassResolverInterface $resourceClassResolver, PropertyAccessorInterface $propertyAccessor = null, NameConverterInterface $nameConverter = null, ClassMetadataFactoryInterface $classMetadataFactory = null, ItemDataProviderInterface $itemDataProvider = null, bool $allowPlainIdentifiers = false, LoggerInterface $logger = null)
40
    {
41
        parent::__construct($propertyNameCollectionFactory, $propertyMetadataFactory, $iriConverter, $resourceClassResolver, $propertyAccessor, $nameConverter, $classMetadataFactory, $itemDataProvider, $allowPlainIdentifiers);
42
43
        $this->logger = $logger ?: new NullLogger();
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     *
49
     * @throws InvalidArgumentException
50
     */
51
    public function denormalize($data, $class, $format = null, array $context = [])
52
    {
53
        // Avoid issues with proxies if we populated the object
54
        if (isset($data['id']) && !isset($context[self::OBJECT_TO_POPULATE])) {
55
            if (isset($context['api_allow_update']) && true !== $context['api_allow_update']) {
56
                throw new InvalidArgumentException('Update is not allowed for this operation.');
57
            }
58
59
            if (isset($context['resource_class'])) {
60
                $this->updateObjectToPopulate($data, $context);
61
            } else {
62
                // See https://github.com/api-platform/core/pull/2326 to understand this message.
63
                $this->logger->warning('The "resource_class" key is missing from the context.', [
64
                    'context' => $context,
65
                ]);
66
            }
67
        }
68
69
        return parent::denormalize($data, $class, $format, $context);
70
    }
71
72
    private function updateObjectToPopulate(array $data, array &$context)
73
    {
74
        try {
75
            $context[self::OBJECT_TO_POPULATE] = $this->iriConverter->getItemFromIri((string) $data['id'], $context + ['fetch_data' => true]);
76
        } catch (InvalidArgumentException $e) {
77
            $identifier = null;
78
            foreach ($this->propertyNameCollectionFactory->create($context['resource_class'], $context) as $propertyName) {
79
                if (true === $this->propertyMetadataFactory->create($context['resource_class'], $propertyName)->isIdentifier()) {
80
                    $identifier = $propertyName;
81
                    break;
82
                }
83
            }
84
85
            if (null === $identifier) {
0 ignored issues
show
introduced by
The condition null === $identifier is always true.
Loading history...
86
                throw $e;
87
            }
88
89
            $context[self::OBJECT_TO_POPULATE] = $this->iriConverter->getItemFromIri(sprintf('%s/%s', $this->iriConverter->getIriFromResourceClass($context['resource_class']), $data[$identifier]), $context + ['fetch_data' => true]);
90
        }
91
    }
92
}
93