Test Failed
Push — alt-path-loader ( dd5973 )
by Guido
07:14
created

FluentDriver   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 147
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 0
loc 147
rs 10
c 0
b 0
f 0
wmc 15
lcom 1
cbo 4

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A loadMetadataForClass() 0 6 1
A getAllClassNames() 0 4 1
A isTransient() 0 6 2
A addMappings() 0 6 2
A addMapping() 0 6 2
A getMappers() 0 4 1
A setFluentFactory() 0 4 1
A getFluent() 0 4 1
A createMapping() 0 14 3
1
<?php
2
3
namespace LaravelDoctrine\Fluent;
4
5
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
6
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
7
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
8
use Doctrine\ORM\Mapping\MappingException;
9
use InvalidArgumentException;
10
use LaravelDoctrine\Fluent\Builders\Builder;
11
use LaravelDoctrine\Fluent\Mappers\MapperSet;
12
13
class FluentDriver implements MappingDriver
14
{
15
    /**
16
     * @var MapperSet
17
     */
18
    protected $mappers;
19
20
    /**
21
     * @var callable
22
     */
23
    protected $fluentFactory;
24
25
    /**
26
     * Initializes a new FluentDriver that will load given Mapping classes / objects.
27
     *
28
     * @param string[]|Mapping[] $mappings
29
     */
30
    public function __construct(array $mappings = [])
31
    {
32
        $this->fluentFactory = function (ClassMetadata $metadata) {
33
            return new Builder(new ClassMetadataBuilder($metadata));
34
        };
35
36
        $this->mappers = new MapperSet();
37
        $this->addMappings($mappings);
38
    }
39
40
    /**
41
     * Loads the metadata for the specified class into the provided container.
42
     *
43
     * @param string        $className
44
     * @param ClassMetadata $metadata
45
     */
46
    public function loadMetadataForClass($className, ClassMetadata $metadata)
47
    {
48
        $this->mappers->getMapperFor($className)->map(
49
            $this->getFluent($metadata)
50
        );
51
    }
52
53
    /**
54
     * Gets the names of all mapped classes known to this driver.
55
     *
56
     * @throws MappingException
57
     *
58
     * @return string[] The names of all mapped classes known to this driver.
59
     */
60
    public function getAllClassNames()
61
    {
62
        return $this->mappers->getClassNames();
63
    }
64
65
    /**
66
     * Returns whether the class with the specified name should have its metadata loaded.
67
     * This is only the case if it is either mapped as an Entity or a MappedSuperclass.
68
     *
69
     * @param string $className
70
     *
71
     * @return bool
72
     */
73
    public function isTransient($className)
74
    {
75
        return
76
            !$this->mappers->hasMapperFor($className) ||
77
            $this->mappers->getMapperFor($className)->isTransient();
78
    }
79
80
    /**
81
     * Adds an array of mapping classes / objects to the driver.
82
     *
83
     * @param string[]|Mapping[] $mappings
84
     * @throws MappingException
85
     * @throws InvalidArgumentException
86
     */
87
    public function addMappings(array $mappings = [])
88
    {
89
        foreach ($mappings as $mapping) {
90
            $this->addMapping($mapping);
91
        }
92
    }
93
94
    /**
95
     * @param string|Mapping $mapping
96
     *
97
     * @throws MappingException
98
     * @throws InvalidArgumentException
99
     * @return void
100
     */
101
    public function addMapping($mapping)
102
    {
103
        $this->mappers->add($mapping instanceof Mapping ?
104
            $mapping : $this->createMapping($mapping)
105
        );
106
    }
107
108
    /**
109
     * @return MapperSet
110
     */
111
    public function getMappers()
112
    {
113
        return $this->mappers;
114
    }
115
116
    /**
117
     * Override the default Fluent factory method with a custom one.
118
     * Use this to implement your own Fluent builder.
119
     * The method will receive a ClassMetadata object as its only argument.
120
     *
121
     * @param callable $factory
122
     */
123
    public function setFluentFactory(callable $factory)
124
    {
125
        $this->fluentFactory = $factory;
126
    }
127
128
    /**
129
     * @param ClassMetadata $metadata
130
     *
131
     * @return Fluent
132
     */
133
    protected function getFluent(ClassMetadata $metadata)
134
    {
135
        return call_user_func($this->fluentFactory, $metadata);
136
    }
137
138
    /**
139
     * Create a mapping object from a mapping class, assuming an empty constructor.
140
     *
141
     * @param  string $class
142
     * @return Mapping
143
     * @throws InvalidArgumentException
144
     */
145
    protected function createMapping($class)
146
    {
147
        if (!class_exists($class)) {
148
            throw new InvalidArgumentException("Mapping class [{$class}] does not exist");
149
        }
150
151
        $mapping = new $class();
152
153
        if (!$mapping instanceof Mapping) {
154
            throw new InvalidArgumentException("Mapping class [{$class}] should implement ".Mapping::class);
155
        }
156
157
        return $mapping;
158
    }
159
}
160