Passed
Pull Request — master (#141)
by Aleksei
04:34 queued 02:09
created

OrmFactory::__invoke()   B

Complexity

Conditions 9
Paths 38

Size

Total Lines 46
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 90

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 9
eloc 26
c 3
b 0
f 0
nc 38
nop 3
dl 0
loc 46
ccs 0
cts 26
cp 0
crap 90
rs 8.0555
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Cycle\Factory;
6
7
use Cycle\Database\DatabaseManager;
8
use Cycle\ORM\Collection\CollectionFactoryInterface;
9
use Cycle\ORM\FactoryInterface;
10
use Spiral\Core\FactoryInterface as SpiralFactoryInterface;
11
use Yiisoft\Injector\Injector;
12
use Yiisoft\Yii\Cycle\Exception\BadDeclarationException;
13
use Yiisoft\Yii\Cycle\Exception\ConfigException;
14
15
final class OrmFactory
16
{
17
    private array $config;
18
19
    public function __construct(array $config)
20
    {
21
        $this->config = $config;
22
    }
23
24
    /**
25
     * @throws ConfigException
26
     */
27
    public function __invoke(
28
        DatabaseManager $dbal,
29
        SpiralFactoryInterface $factory,
30
        Injector $injector,
31
    ): FactoryInterface {
32
        // Manage collection factory list
33
        $cfgPath = ['yiisoft/yii-cycle', 'collections'];
34
35
        try {
36
            // Resolve collection factories
37
            $factories = [];
38
            foreach ($this->config['factories'] ?? [] as $alias => $definition) {
39
                $factories[$alias] = $injector->make($definition);
40
                if (!$factories[$alias] instanceof CollectionFactoryInterface) {
41
                    $cfgPath[] = 'factories';
42
                    throw new BadDeclarationException(
43
                        "Collection factory `$alias`",
44
                        CollectionFactoryInterface::class,
45
                        $factories[$alias]
46
                    );
47
                }
48
            }
49
50
            // Resolve default collection factory
51
            $default = $this->config['default'] ?? null;
52
            if ($default !== null) {
53
                if (!\array_key_exists($default, $factories)) {
54
                    if (!\is_a($default, CollectionFactoryInterface::class, true)) {
55
                        $cfgPath[] = 'default';
56
                        throw new \RuntimeException(\sprintf('Default collection factory `%s` not found.', $default));
57
                    }
58
                    $default = \is_string($default) ? $injector->make($default) : $default;
59
                } else {
60
                    $default = $factories[$default];
61
                }
62
            }
63
        } catch (\Throwable $e) {
64
            throw new ConfigException($cfgPath, $e->getMessage(), 0, $e);
65
        }
66
67
        $result = new \Cycle\ORM\Factory($dbal, null, $factory, $default);
68
        // attach collection factories
69
        foreach ($factories as $alias => $collectionFactory) {
70
            $result = $result->withCollectionFactory($alias, $collectionFactory);
71
        }
72
        return $result;
73
    }
74
}
75