1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Er1z\FakeMock\Generator\RecursiveGenerator; |
4
|
|
|
|
5
|
|
|
use Er1z\FakeMock\Accessor; |
6
|
|
|
use Er1z\FakeMock\Metadata\FieldMetadata; |
7
|
|
|
use phpDocumentor\Reflection\Types\Object_; |
8
|
|
|
|
9
|
|
|
class ClassMapper implements ClassMapperInterface |
10
|
|
|
{ |
11
|
|
|
protected $classMapping = []; |
12
|
|
|
|
13
|
40 |
|
protected function getMapping(string $class, FieldMetadata $field) |
14
|
|
|
{ |
15
|
40 |
|
if ($field->configuration->mapToClass) { |
16
|
4 |
|
return $this->getObject($class, $field->configuration->mapToClass); |
17
|
|
|
} |
18
|
|
|
|
19
|
36 |
|
if ($field->objectConfiguration->classMappings && isset($field->objectConfiguration->classMappings[$class])) { |
|
|
|
|
20
|
4 |
|
return $this->getObject($class, $field->objectConfiguration->classMappings[$class]); |
21
|
|
|
} |
22
|
|
|
|
23
|
32 |
|
if (isset($this->classMapping[$class])) { |
24
|
12 |
|
return $this->getObject($class, $this->classMapping[$class]); |
25
|
|
|
} |
26
|
20 |
|
} |
27
|
|
|
|
28
|
44 |
|
protected function getClassFromFqsen(?string $type = null): ?\ReflectionClass |
29
|
|
|
{ |
30
|
|
|
try { |
31
|
44 |
|
$class = new \ReflectionClass($type); |
32
|
4 |
|
} catch (\ReflectionException $ex) { |
33
|
4 |
|
throw new \InvalidArgumentException(sprintf('Class %s does not exist', $type)); |
34
|
|
|
} |
35
|
|
|
|
36
|
40 |
|
return $class; |
37
|
|
|
} |
38
|
|
|
|
39
|
20 |
|
protected function getObject(string $subject, string $mapping) |
40
|
|
|
{ |
41
|
20 |
|
if (!class_exists($mapping)) { |
42
|
4 |
|
throw new \InvalidArgumentException(sprintf('Class %s mapped to %s does not exist', $subject, $mapping)); |
43
|
|
|
} |
44
|
|
|
|
45
|
16 |
|
$object = new $mapping(); |
46
|
|
|
|
47
|
16 |
|
if ($mapping != $subject && !($object instanceof $subject)) { |
48
|
4 |
|
throw new \InvalidArgumentException(sprintf('Class %s does not implement/extend %s', $mapping, $subject)); |
49
|
|
|
} |
50
|
|
|
|
51
|
12 |
|
return $object; |
52
|
|
|
} |
53
|
|
|
|
54
|
83 |
|
public function getObjectForField(FieldMetadata $field) |
55
|
|
|
{ |
56
|
83 |
|
$value = Accessor::getPropertyValue($field->object, $field->property->getName()); |
57
|
|
|
|
58
|
83 |
|
if (is_object($value)) { |
59
|
4 |
|
return $value; |
60
|
|
|
} |
61
|
|
|
|
62
|
79 |
|
if (!($field->type instanceof Object_)) { |
63
|
39 |
|
return null; |
64
|
|
|
} |
65
|
|
|
|
66
|
48 |
|
$fqsen = (string) $field->type->getFqsen(); |
67
|
|
|
|
68
|
48 |
|
if (empty($fqsen)) { |
69
|
4 |
|
return null; |
70
|
|
|
} |
71
|
|
|
|
72
|
44 |
|
$class = $this->getClassFromFqsen($fqsen); |
73
|
|
|
|
74
|
40 |
|
if ($mapping = $this->getMapping($class->getName(), $field)) { |
75
|
12 |
|
return $mapping; |
76
|
|
|
} |
77
|
|
|
|
78
|
20 |
|
if ($class->isInstantiable()) { |
79
|
12 |
|
return new $fqsen(); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
// non-mapped abstract/interface |
83
|
8 |
|
return null; |
84
|
|
|
} |
85
|
|
|
|
86
|
16 |
|
public function addClassMapping(string $abstractOrInterface, string $class) |
87
|
|
|
{ |
88
|
16 |
|
$this->classMapping[$abstractOrInterface] = $class; |
89
|
16 |
|
} |
90
|
|
|
} |
91
|
|
|
|
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.