Completed
Push — master ( 2958af...77ccc9 )
by JHONATAN
02:21
created

PropertyMetadata   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 103
Duplicated Lines 0 %

Test Coverage

Coverage 93.75%

Importance

Changes 0
Metric Value
wmc 15
dl 0
loc 103
ccs 45
cts 48
cp 0.9375
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A setValue() 0 7 2
A __construct() 0 5 1
A getValue() 0 7 2
B parseType() 0 26 5
A unserialize() 0 6 1
A serialize() 0 6 1
A getClassUses() 0 23 3
1
<?php
2
3
namespace Vox\Metadata;
4
5
use Metadata\PropertyMetadata as BaseMetadata;
6
use ProxyManager\Proxy\AccessInterceptorValueHolderInterface;
7
use ReflectionClass;
8
9
class PropertyMetadata extends BaseMetadata
10
{
11
    use AnnotationsTrait;
12
    
13
    public $type;
14
    
15
    /**
16
     * @param ReflectionClass $class
17
     * @param string $name
18
     */
19 25
    public function __construct($class, $name)
20
    {
21 25
        parent::__construct($class, $name);
22
        
23 25
        $this->type = $this->parseType();
24 25
    }
25
    
26 12
    public function getValue($obj)
27
    {
28 12
        if ($obj instanceof AccessInterceptorValueHolderInterface) {
29 5
            $obj = $obj->getWrappedValueHolderValue();
30
        }
31
        
32 12
        return parent::getValue($obj);
33
    }
34
    
35 15
    public function setValue($obj, $value)
36
    {
37 15
        if ($obj instanceof AccessInterceptorValueHolderInterface) {
38
            $obj = $obj->getWrappedValueHolderValue();
39
        }
40
        
41 15
        parent::setValue($obj, $value);
42 15
    }
43
    
44 25
    private function parseType()
45
    {
46 25
        $docComment = $this->reflection->getDocComment();
47
        
48 25
        preg_match('/@var\s+(([^\[\]\s]+)(\[\])?)/', $docComment, $matches);
49
        
50 25
        $fullType = $matches[1] ?? null;
51 25
        $type     = $matches[2] ?? null;
52
        
53 25
        if (null === $type) {
54 19
            return;
55
        }
56
        
57 13
        $uses = $this->getClassUses();
58
        
59 13
        foreach ($uses as $use) {
60 13
            if (preg_match("/{$type}$/", $use)) {
61
                return $use . ($matches[3] ?? null);
62
            }
63
            
64 13
            if (class_exists("$use\\$type")) {
65 13
                return "$use\\$type" . ($matches[3] ?? null);
66
            }
67
        }
68
        
69 11
        return $fullType;
70
    }
71
    
72 13
    private function getClassUses(): array
73
    {
74 13
        $filename = $this->reflection->getDeclaringClass()->getFileName();
75
        
76 13
        if (is_file($filename)) {
77 13
            $contents = file_get_contents($filename);
78
            
79 13
            preg_match_all('/use\s+(.*);/', $contents, $matches);
80
            
81 13
            $uses = $matches[1] ?? [];
82
            
83 13
            $matches = [];
84
            
85 13
            preg_match('/namespace\s+(.*);/', $contents, $matches);
0 ignored issues
show
Bug introduced by
It seems like $contents can also be of type false; however, parameter $subject of preg_match() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

85
            preg_match('/namespace\s+(.*);/', /** @scrutinizer ignore-type */ $contents, $matches);
Loading history...
86
            
87 13
            if (!empty($matches[1])) {
88 13
                array_push($uses, $matches[1]);
89
            }
90
            
91 13
            return $uses;
92
        }
93
        
94
        return [];
95
    }
96
    
97 5
    public function serialize()
98
    {
99 5
        return serialize(array(
100 5
            $this->class,
101 5
            $this->name,
102 5
            $this->annotations,
103
        ));
104
    }
105
106 4
    public function unserialize($str)
107
    {
108 4
        list($this->class, $this->name, $this->annotations) = unserialize($str);
109
110 4
        $this->reflection = new \ReflectionProperty($this->class, $this->name);
111 4
        $this->reflection->setAccessible(true);
112 4
    }
113
}
114