Completed
Push — master ( 6751ec...bd2805 )
by JHONATAN
03:37
created

PropertyMetadata   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Test Coverage

Coverage 98.11%

Importance

Changes 0
Metric Value
wmc 17
dl 0
loc 111
ccs 52
cts 53
cp 0.9811
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A setValue() 0 7 2
A __construct() 0 5 1
A getValue() 0 7 2
A getClassUses() 0 23 3
A unserialize() 0 6 1
A getParsedType() 0 4 2
A serialize() 0 7 1
B parseType() 0 26 5
1
<?php
2
3
namespace Vox\Metadata;
4
5
use Metadata\PropertyMetadata as BaseMetadata;
6
use ProxyManager\Proxy\AccessInterceptorValueHolderInterface;
7
use ReflectionClass;
8
9
/**
10
 * Holds all metadata for a single property
11
 * 
12
 * @author Jhonatan Teixeira <[email protected]>
13
 */
14
class PropertyMetadata extends BaseMetadata
15
{
16
    use AnnotationsTrait;
17
    
18
    public $type;
19
    
20
    /**
21
     * @param ReflectionClass $class
22
     * @param string $name
23
     */
24 46
    public function __construct($class, $name)
25
    {
26 46
        parent::__construct($class, $name);
27
        
28 46
        $this->type = $this->parseType();
29 46
    }
30
    
31 27
    public function getValue($obj)
32
    {
33 27
        if ($obj instanceof AccessInterceptorValueHolderInterface) {
34 10
            $obj = $obj->getWrappedValueHolderValue();
35
        }
36
        
37 27
        return parent::getValue($obj);
38
    }
39
    
40 29
    public function setValue($obj, $value)
41
    {
42 29
        if ($obj instanceof AccessInterceptorValueHolderInterface) {
43 3
            $obj = $obj->getWrappedValueHolderValue();
44
        }
45
        
46 29
        parent::setValue($obj, $value);
47 29
    }
48
    
49 46
    private function parseType()
50
    {
51 46
        $docComment = $this->reflection->getDocComment();
52
        
53 46
        preg_match('/@var\s+(([^\[\]\s]+)(\[\])?)/', $docComment, $matches);
54
        
55 46
        $fullType = $matches[1] ?? null;
56 46
        $type     = $matches[2] ?? null;
57
        
58 46
        if (null === $type) {
59 24
            return;
60
        }
61
        
62 34
        $uses = $this->getClassUses();
63
        
64 34
        foreach ($uses as $use) {
65 34
            if (preg_match("/{$type}$/", $use)) {
66 1
                return $use . ($matches[3] ?? null);
67
            }
68
            
69 34
            if (class_exists("$use\\$type")) {
70 34
                return "$use\\$type" . ($matches[3] ?? null);
71
            }
72
        }
73
        
74 32
        return $fullType;
75
    }
76
    
77 34
    private function getClassUses(): array
78
    {
79 34
        $filename = $this->reflection->getDeclaringClass()->getFileName();
80
        
81 34
        if (is_file($filename)) {
82 34
            $contents = file_get_contents($filename);
83
            
84 34
            preg_match_all('/use\s+(.*);/', $contents, $matches);
85
            
86 34
            $uses = $matches[1] ?? [];
87
            
88 34
            $matches = [];
89
            
90 34
            preg_match('/namespace\s+(.*);/', $contents, $matches);
91
            
92 34
            if (!empty($matches[1])) {
93 34
                array_push($uses, $matches[1]);
94
            }
95
            
96 34
            return $uses;
97
        }
98
        
99
        return [];
100
    }
101
    
102 9
    public function getParsedType()
103
    {
104 9
        if (isset($this->type)) {
105 9
            return preg_replace('/(\[\]$)|(\<\>$)/', '', $this->type);
106
        }
107 2
    }
108
    
109 6
    public function serialize()
110
    {
111 6
        return serialize(array(
112 6
            $this->class,
113 6
            $this->name,
114 6
            $this->annotations,
115 6
            $this->type,
116
        ));
117
    }
118
119 4
    public function unserialize($str)
120
    {
121 4
        list($this->class, $this->name, $this->annotations, $this->type) = unserialize($str);
122
123 4
        $this->reflection = new \ReflectionProperty($this->class, $this->name);
124 4
        $this->reflection->setAccessible(true);
125 4
    }
126
}
127