Completed
Push — master ( 969ba5...87cf68 )
by Przemysław eRIZ
02:24
created

ClassMapper::getMapping()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 12
rs 9.6111
c 0
b 0
f 0
cc 5
nc 4
nop 2
1
<?php
2
3
namespace Er1z\FakeMock\Generator\RecursiveGenerator;
4
5
use Er1z\FakeMock\Metadata\FieldMetadata;
6
use phpDocumentor\Reflection\Types\Object_;
7
8
class ClassMapper implements ClassMapperInterface
9
{
10
    protected $classMapping = [];
11
12
    protected function getMapping(string $class, FieldMetadata $field)
13
    {
14
        if ($field->configuration->mapToClass) {
15
            return $this->getObject($class, $field->configuration->mapToClass);
16
        }
17
18
        if ($field->objectConfiguration->classMappings && isset($field->objectConfiguration->classMappings[$class])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $field->objectConfiguration->classMappings of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
19
            return $this->getObject($class, $field->objectConfiguration->classMappings[$class]);
20
        }
21
22
        if (isset($this->classMapping[$class])) {
23
            return $this->getObject($class, $this->classMapping[$class]);
24
        }
25
    }
26
27
    protected function getClassFromFqsen(?string $type = null): ?\ReflectionClass
28
    {
29
        try {
30
            $class = new \ReflectionClass($type);
31
        } catch (\ReflectionException $ex) {
32
            throw new \InvalidArgumentException(sprintf('Class %s does not exist', $type));
33
        }
34
35
        return $class;
36
    }
37
38
    protected function getObject(string $subject, string $mapping)
39
    {
40
        if (!class_exists($mapping)) {
41
            throw new \InvalidArgumentException(sprintf('Class %s mapped to %s does not exist', $subject, $mapping));
42
        }
43
44
        $object = new $mapping();
45
46
        if ($mapping != $subject && !($object instanceof $subject)) {
47
            throw new \InvalidArgumentException(sprintf('Class %s does not implement/extend %s', $mapping, $subject));
48
        }
49
50
        return $object;
51
    }
52
53
    public function getObjectForField(FieldMetadata $field)
54
    {
55
        $value = $field->property->getValue($field->object);
56
57
        if (is_object($value)) {
58
            return $value;
59
        }
60
61
        if (!($field->type instanceof Object_)) {
62
            return null;
63
        }
64
65
        $fqsen = (string) $field->type->getFqsen();
66
67
        if (empty($fqsen)) {
68
            return null;
69
        }
70
71
        $class = $this->getClassFromFqsen($fqsen);
72
73
        if ($mapping = $this->getMapping($class->getName(), $field)) {
74
            return $mapping;
75
        }
76
77
        if ($class->isInstantiable()) {
78
            return new $fqsen();
79
        }
80
81
        // non-mapped abstract/interface
82
        return null;
83
    }
84
85
    public function addClassMapping(string $abstractOrInterface, string $class)
86
    {
87
        $this->classMapping[$abstractOrInterface] = $class;
88
    }
89
}
90