Passed
Push — alt-path-loader ( fc3d47...ae5005 )
by Guido
24:40 queued 09:43
created

FluentDriver   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 151
ccs 39
cts 39
cp 1
rs 10
c 0
b 0
f 0
wmc 15
lcom 1
cbo 4

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getAllClassNames() 0 4 1
A isTransient() 0 6 2
A getFluent() 0 4 1
A __construct() 0 9 1
A loadMetadataForClass() 0 6 1
A addMappings() 0 6 2
A addMapping() 0 6 2
A getMappers() 0 4 1
A setFluentFactory() 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 5
        $this->fluentFactory = function (ClassMetadata $metadata) {
33 5
            return new Builder(new ClassMetadataBuilder($metadata));
34
        };
35
36 93
        $this->mappers = new MapperSet();
37 93
        $this->addMappings($mappings);
38 93
    }
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 7
    public function loadMetadataForClass($className, ClassMetadata $metadata)
47
    {
48 7
        $this->mappers->getMapperFor($className)->map(
49 6
            $this->getFluent($metadata)
50 6
        );
51 6
    }
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 13
    public function getAllClassNames()
61
    {
62 13
        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 4
    public function isTransient($className)
74
    {
75
        return
76 4
            !$this->mappers->hasMapperFor($className) ||
77 4
            $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
     *
85
     * @throws MappingException
86
     * @throws InvalidArgumentException
87
     */
88 93
    public function addMappings(array $mappings = [])
89
    {
90 93
        foreach ($mappings as $mapping) {
91 83
            $this->addMapping($mapping);
92 93
        }
93 93
    }
94
95
    /**
96
     * @param string|Mapping $mapping
97
     *
98
     * @throws MappingException
99
     * @throws InvalidArgumentException
100
     *
101
     * @return void
102
     */
103 90
    public function addMapping($mapping)
104
    {
105 90
        $this->mappers->add($mapping instanceof Mapping ?
106 90
            $mapping : $this->createMapping($mapping)
107 88
        );
108 88
    }
109
110
    /**
111
     * @return MapperSet
112
     */
113 6
    public function getMappers()
114
    {
115 6
        return $this->mappers;
116
    }
117
118
    /**
119
     * Override the default Fluent factory method with a custom one.
120
     * Use this to implement your own Fluent builder.
121
     * The method will receive a ClassMetadata object as its only argument.
122
     *
123
     * @param callable $factory
124
     */
125 1
    public function setFluentFactory(callable $factory)
126
    {
127 1
        $this->fluentFactory = $factory;
128 1
    }
129
130
    /**
131
     * @param ClassMetadata $metadata
132
     *
133
     * @return Fluent
134
     */
135 6
    protected function getFluent(ClassMetadata $metadata)
136
    {
137 6
        return call_user_func($this->fluentFactory, $metadata);
138
    }
139
140
    /**
141
     * Create a mapping object from a mapping class, assuming an empty constructor.
142
     *
143
     * @param string $class
144
     *
145
     * @throws InvalidArgumentException
146
     *
147
     * @return Mapping
148
     */
149 83
    protected function createMapping($class)
150
    {
151 83
        if (!class_exists($class)) {
152 1
            throw new InvalidArgumentException("Mapping class [{$class}] does not exist");
153
        }
154
155 82
        $mapping = new $class();
156
157 82
        if (!$mapping instanceof Mapping) {
158 1
            throw new InvalidArgumentException("Mapping class [{$class}] should implement ".Mapping::class);
159
        }
160
161 81
        return $mapping;
162
    }
163
}
164