GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#225)
by joseph
18:50
created

AbstractEntityFixtureLoader::loadBulk()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3.512

Importance

Changes 3
Bugs 0 Features 1
Metric Value
cc 3
eloc 8
c 3
b 0
f 1
nc 3
nop 0
dl 0
loc 14
ccs 8
cts 13
cp 0.6153
crap 3.512
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures;
6
7
use Doctrine\Common\DataFixtures\AbstractFixture;
8
use Doctrine\Common\DataFixtures\ReferenceRepository;
9
use Doctrine\Common\Persistence\ObjectManager;
10
use Doctrine\ORM\EntityManagerInterface;
11
use Doctrine\ORM\Mapping\MappingException;
12
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\NamespaceHelper;
13
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\EntityInterface;
14
use EdmondsCommerce\DoctrineStaticMeta\Entity\Savers\EntitySaverFactory;
15
use EdmondsCommerce\DoctrineStaticMeta\Entity\Savers\EntitySaverInterface;
16
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityGenerator\TestEntityGenerator;
17
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityGenerator\TestEntityGeneratorFactory;
18
use EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException;
19
use ErrorException;
20
use LogicException;
21
use Psr\Container\ContainerInterface;
22
use ReflectionException;
23
use RuntimeException;
24
25
use function get_class;
26
27
/**
28
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
29
 */
30
abstract class AbstractEntityFixtureLoader extends AbstractFixture
31
{
32
    /**
33
     * If you override the loadBulk method, please ensure you update this number to reflect the number of Entities you
34
     * are actually generating
35
     */
36
    public const BULK_AMOUNT_TO_GENERATE = 100;
37
38
    public const REFERENCE_PREFIX = 'OVERRIDE ME';
39
40
    /**
41
     * @var TestEntityGenerator
42
     */
43
    protected $testEntityGenerator;
44
    /**
45
     * @var EntitySaverInterface
46
     */
47
    protected $saver;
48
49
    /**
50
     * @var null|FixtureEntitiesModifierInterface
51
     */
52
    protected $modifier;
53
54
    /**
55
     * @var string
56
     */
57
    protected $entityFqn;
58
    /**
59
     * @var NamespaceHelper
60
     */
61
    protected $namespaceHelper;
62
63
    /**
64
     * @var TestEntityGeneratorFactory
65
     */
66
    private $testEntityGeneratorFactory;
67
    /**
68
     * @var ContainerInterface
69
     */
70
    private $container;
71
72
    private $usingReferences = false;
73
    /**
74
     * @var EntityManagerInterface
75
     */
76
    private $entityManager;
77
    /**
78
     * @var bool
79
     */
80
    protected $generateCustomFixtures = false;
81
    /**
82
     * @var int
83
     */
84
    protected $numberToGenerate;
85
    /**
86
     * @var array
87
     */
88
    protected $customData;
89
90 4
    public function __construct(
91
        TestEntityGeneratorFactory $testEntityGeneratorFactory,
92
        EntitySaverFactory $saverFactory,
93
        NamespaceHelper $namespaceHelper,
94
        EntityManagerInterface $entityManager,
95
        ContainerInterface $container,
96
        ?FixtureEntitiesModifierInterface $modifier = null
97
    ) {
98 4
        $this->namespaceHelper = $namespaceHelper;
99 4
        $this->entityFqn       = $this->getEntityFqn();
100 4
        $this->saver           = $saverFactory->getSaverForEntityFqn($this->entityFqn);
101 4
        if (null !== $modifier) {
102 1
            $this->setModifier($modifier);
103
        }
104 4
        $this->testEntityGeneratorFactory = $testEntityGeneratorFactory;
105 4
        $this->container                  = $container;
106 4
        $this->assertReferencePrefixOverridden();
107 4
        $this->entityManager = $entityManager;
108 4
    }
109
110
    /**
111
     * Get the fully qualified name of the Entity we are testing,
112
     * assumes EntityNameTest as the entity class short name
113
     *
114
     * @return string
115
     */
116 4
    protected function getEntityFqn(): string
117
    {
118 4
        if (null === $this->entityFqn) {
119 4
            $this->entityFqn = $this->namespaceHelper->getEntityFqnFromFixtureFqn(static::class);
120
        }
121
122 4
        return $this->entityFqn;
123
    }
124
125
    /**
126
     * Use this method to inject your own modifier that will receive the array of generated entities and can then
127
     * update them as you see fit
128
     *
129
     * @param FixtureEntitiesModifierInterface $modifier
130
     */
131 1
    public function setModifier(FixtureEntitiesModifierInterface $modifier): void
132
    {
133 1
        $this->modifier = $modifier;
134 1
    }
135
136 4
    private function assertReferencePrefixOverridden(): void
137
    {
138 4
        if (static::REFERENCE_PREFIX === self::REFERENCE_PREFIX) {
0 ignored issues
show
introduced by
The condition static::REFERENCE_PREFIX... self::REFERENCE_PREFIX is always true.
Loading history...
139
            throw new LogicException('You must override the REFERENCE_PREFIX constant in your Fixture');
140
        }
141 4
    }
142
143
    /**
144
     * Load data fixtures with the passed EntityManager
145
     *
146
     * @param ObjectManager $manager
147
     *
148
     * @throws ReflectionException
149
     */
150 3
    public function load(ObjectManager $manager)
151
    {
152 3
        if (!$manager instanceof EntityManagerInterface) {
153
            throw new RuntimeException(
154
                'Expecting $manager to be EntityManagerInterface but got ' . get_class($manager)
155
            );
156
        }
157 3
        $this->testEntityGenerator = $this->testEntityGeneratorFactory->createForEntityFqn($this->entityFqn, $manager);
158 3
        $this->testEntityGenerator->assertSameEntityManagerInstance($manager);
159 3
        $entities = $this->loadBulk();
160 3
        $this->validateNumberGenerated($entities);
161 3
        $this->updateGenerated($entities);
162 3
        $this->saver->saveAll($entities);
163 3
    }
164
165
    /**
166
     * This method can be used to generate ad hoc fixture with specified data. To use it pass in an array of arrays,
167
     * with each child array keyed with the properties that you want to set, e.g.
168
     * [
169
     *      [
170
     *          'propertyOne' => true,
171
     *          'propertyTwo' => DifferentEntity,
172
     *          ...
173
     *      ],
174
     *      ...
175
     * ]
176
     *
177
     * The entity will be created as normal, with Faker data used to populate each field and then the data in the array
178
     * will be used to override the properties
179
     *
180
     * @param array $customData
181
     */
182
    public function setCustomData(array $customData): void
183
    {
184
        $this->numberToGenerate       = count($customData);
185
        $this->customData             = $customData;
186
        $this->generateCustomFixtures = true;
187
    }
188
189
    /**
190
     * This method will be used to check that the number of entities generated matches the number expected. If you are
191
     * generating custom fixtures then this will check the number generated matches the number of custom array items
192
     * passed in, otherwise it will check the constant defined in the class
193
     *
194
     * @param array $entities
195
     */
196 3
    protected function validateNumberGenerated(array $entities): void
197
    {
198 3
        $expected = $this->generateCustomFixtures === true ? $this->numberToGenerate : static::BULK_AMOUNT_TO_GENERATE;
199 3
        if (count($entities) !== $expected) {
200
            throw new RuntimeException(
201
                'generated ' . count($entities) .
202
                ' but the constant ' . get_class($this) . '::BULK_AMOUNT_TO_GENERATE is ' . $expected
203
            );
204
        }
205 3
    }
206
207
    /**
208
     * @return array|EntityInterface[]
209
     */
210 3
    protected function loadBulk(): array
211
    {
212 3
        if ($this->generateCustomFixtures === true) {
213
            return $this->generateCustomFixtures();
214
        }
215 3
        $entities = $this->testEntityGenerator->generateEntities(
216 3
            static::BULK_AMOUNT_TO_GENERATE
217
        );
218 3
        $num      = 0;
219 3
        foreach ($entities as $generated) {
220 3
            $this->addReference(static::REFERENCE_PREFIX . $num++, $generated);
221
        }
222
223 3
        return $entities;
224
    }
225
226
    /**
227
     * This loops over the custom array and passes the data to to a function used to create and update the entity
228
     *
229
     * @return array
230
     */
231
    protected function generateCustomFixtures(): array
232
    {
233
        $customFixtures = [];
234
        for ($numberToGenerate = 0; $numberToGenerate < $this->numberToGenerate; $numberToGenerate++) {
235
            $customFixtures[] = $this->generateCustomFixture($this->customData[$numberToGenerate], $numberToGenerate);
236
        }
237
238
        return $customFixtures;
239
    }
240
241
    /**
242
     * This is used to create the custom entity. It can be overwritten if you want to use customise it further, e.g.
243
     * using the same vaule for each entity. The method is passed the array of custom data and the number, zero indexed,
244
     * of the entity being generated
245
     *
246
     * @param array $customData
247
     * @param int   $fixtureNumber
248
     * @SuppressWarnings(PHPMD.UnusedFormalParameter) - We don't need the fixture number in this method, but it may be
249
     *                                                useful if the method is overwritten
250
     *
251
     * @return EntityInterface
252
     */
253
    protected function generateCustomFixture(array $customData, int $fixtureNumber): EntityInterface
0 ignored issues
show
Unused Code introduced by
The parameter $fixtureNumber is not used and could be removed. ( Ignorable by Annotation )

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

253
    protected function generateCustomFixture(array $customData, /** @scrutinizer ignore-unused */ int $fixtureNumber): EntityInterface

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
254
    {
255
        return $this->testEntityGenerator->create($customData);
256
    }
257
258 3
    public function addReference($name, $object)
259
    {
260 3
        if (false === $this->usingReferences) {
261
            return;
262
        }
263 3
        parent::addReference($name, $object);
264 3
    }
265
266 3
    protected function updateGenerated(array &$entities): void
267
    {
268 3
        if (null === $this->modifier) {
269 2
            return;
270
        }
271 1
        $this->modifier->modifyEntities($entities);
272 1
    }
273
274 3
    public function setReferenceRepository(ReferenceRepository $referenceRepository)
275
    {
276 3
        $this->setUsingReferences(true);
277 3
        parent::setReferenceRepository($referenceRepository); // TODO: Change the autogenerated stub
278 3
    }
279
280
    /**
281
     * @param bool $usingReferences
282
     *
283
     * @return AbstractEntityFixtureLoader
284
     */
285 3
    public function setUsingReferences(bool $usingReferences): AbstractEntityFixtureLoader
286
    {
287 3
        $this->usingReferences = $usingReferences;
288
289 3
        return $this;
290
    }
291
292
    public function getReference($name): EntityInterface
293
    {
294
        $reference = parent::getReference($name);
295
        $this->entityManager->initializeObject($reference);
296
        if ($reference instanceof EntityInterface) {
297
            return $reference;
298
        }
299
        throw new RuntimeException('Failed initialising refernce into Entity');
300
    }
301
302
    /**
303
     * Generally we should avoid using the container as a service locator, however for test assets it is acceptable if
304
     * really necessary
305
     *
306
     * @return ContainerInterface
307
     */
308
    protected function getContainer(): ContainerInterface
309
    {
310
        return $this->container;
311
    }
312
}
313