Completed
Push — master ( e9ba41...791922 )
by Alex
14s queued 12s
created

CascadeSaveService::saveAssociations()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 72
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 43
c 1
b 0
f 0
dl 0
loc 72
rs 8.6097
cc 6
nc 4
nop 5

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arp\DoctrineEntityRepository\Persistence;
6
7
use Arp\DoctrineEntityRepository\Exception\EntityRepositoryException;
8
use Arp\DoctrineEntityRepository\Persistence\Exception\PersistenceException;
9
use Arp\Entity\EntityInterface;
10
use Doctrine\ORM\EntityManagerInterface;
11
12
/**
13
 * @author  Alex Patterson <[email protected]>
14
 * @package Arp\DoctrineEntityRepository\Persistence
15
 */
16
class CascadeSaveService extends AbstractCascadeService
17
{
18
    /**
19
     * @param EntityManagerInterface $entityManager
20
     * @param string                 $entityName
21
     * @param EntityInterface        $entity
22
     * @param array                  $saveOptions
23
     * @param array                  $saveCollectionOptions
24
     *
25
     * @throws PersistenceException
26
     * @throws EntityRepositoryException
27
     */
28
    public function saveAssociations(
29
        EntityManagerInterface $entityManager,
30
        string $entityName,
31
        EntityInterface $entity,
32
        array $saveOptions = [],
33
        array $saveCollectionOptions = []
34
    ): void {
35
        $saveOptions = array_replace_recursive($this->options, $saveOptions);
36
        $saveCollectionOptions = array_replace_recursive($this->collectionOptions, $saveCollectionOptions);
37
38
        $classMetadata = $this->getClassMetadata($entityManager, $entityName);
39
        $mappings = $classMetadata->getAssociationMappings();
40
41
        $this->logger->info(
42
            sprintf('Processing cascade save operations for for entity class \'%s\'', $entityName)
43
        );
44
45
        foreach ($mappings as $mapping) {
46
            if (
47
                !isset(
48
                    $mapping['targetEntity'],
49
                    $mapping['fieldName'],
50
                    $mapping['type'],
51
                    $mapping['isCascadePersist']
52
                )
53
                || true !== $mapping['isCascadePersist']
54
            ) {
55
                // We only want to save associations that are configured to cascade persist
56
                continue;
57
            }
58
59
            $this->logger->info(
60
                sprintf(
61
                    'The entity field \'%s::%s\' is configured for cascade operations for target entity \'%s\'',
62
                    $entityName,
63
                    $mapping['fieldName'],
64
                    $mapping['targetEntity']
65
                )
66
            );
67
68
            $targetEntityOrCollection = $this->resolveTargetEntityOrCollection(
69
                $entity,
70
                $mapping['fieldName'],
71
                $classMetadata,
72
                $this->getClassMetadata($entityManager, $mapping['targetEntity'])
73
            );
74
75
            if (!$this->isValidAssociation($targetEntityOrCollection, $mapping)) {
76
                $errorMessage = sprintf(
77
                    'The entity field \'%s::%s\' value could not be resolved',
78
                    $entityName,
79
                    $mappings['fieldName']
80
                );
81
82
                $this->logger->error($errorMessage);
83
84
                throw new PersistenceException($errorMessage);
85
            }
86
87
            $this->logger->info(
88
                sprintf(
89
                    'Performing cascading save operations for field \'%s::%s\'',
90
                    $entityName,
91
                    $mapping['fieldName']
92
                )
93
            );
94
95
            $this->saveAssociation(
96
                $entityManager,
97
                $mapping['targetEntity'],
98
                $targetEntityOrCollection,
99
                (is_iterable($targetEntityOrCollection) ? $saveCollectionOptions : $saveOptions)
100
            );
101
        }
102
    }
103
104
    /**
105
     * @param EntityManagerInterface                     $entityManager
106
     * @param string                                     $entityName
107
     * @param EntityInterface|EntityInterface[]|iterable $entityOrCollection
108
     * @param array                                      $options
109
     *
110
     * @throws PersistenceException
111
     * @throws EntityRepositoryException
112
     */
113
    public function saveAssociation(
114
        EntityManagerInterface $entityManager,
115
        string $entityName,
116
        $entityOrCollection,
117
        array $options = []
118
    ): void {
119
        if (is_iterable($entityOrCollection)) {
120
            $this->getTargetRepository($entityManager, $entityName)->saveCollection($entityOrCollection, $options);
0 ignored issues
show
Bug introduced by
It seems like $entityOrCollection can also be of type Arp\Entity\EntityInterface; however, parameter $collection of Arp\DoctrineEntityReposi...rface::saveCollection() does only seem to accept iterable, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

120
            $this->getTargetRepository($entityManager, $entityName)->saveCollection(/** @scrutinizer ignore-type */ $entityOrCollection, $options);
Loading history...
121
        } elseif ($entityOrCollection instanceof EntityInterface) {
122
            $this->getTargetRepository($entityManager, $entityName)->save($entityOrCollection, $options);
123
        } else {
124
            $errorMessage = sprintf(
125
                'Unable to cascade save target entity \'%s\': The entity or collection is of an invalid type \'%s\'',
126
                $entityName,
127
                (is_object($entityOrCollection) ? get_class($entityOrCollection) : gettype($entityOrCollection))
128
            );
129
130
            $this->logger->error($errorMessage);
131
132
            throw new PersistenceException($errorMessage);
133
        }
134
    }
135
}
136