ObjectParser::getName()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the rafrsr/lib-array2object package.
5
 *
6
 * (c) Rafael SR <https://github.com/rafrsr>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
namespace Rafrsr\LibArray2Object\Parser;
12
13
use Rafrsr\LibArray2Object\AbstractContext;
14
use Rafrsr\LibArray2Object\Array2Object;
15
use Rafrsr\LibArray2Object\Array2ObjectContext;
16
use Rafrsr\LibArray2Object\Object2Array;
17
use Rafrsr\LibArray2Object\Object2ArrayContext;
18
19
class ObjectParser implements ValueParserInterface
20
{
21
    const NAME = 'object';
22
23
    /** @var Array2Object */
24
    protected $array2Object;
25
    /** @var Object2Array */
26
    protected $object2Array;
27
28
    /**
29
     * ObjectParser constructor.
30
     *
31
     * @param AbstractContext $context
32
     */
33
    public function __construct(AbstractContext $context)
34
    {
35
        if ($context instanceof Array2ObjectContext) {
36
            $this->array2Object = new Array2Object($context);
37
        } elseif ($context instanceof Object2ArrayContext) {
38
            $this->object2Array = new Object2Array($context);
39
        }
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function getName()
46
    {
47
        return self::NAME;
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53
    public function toObjectValue($value, $type, \ReflectionProperty $property, $object)
54
    {
55
        $className = null;
56
        $context = new \ReflectionClass($property->class);
57
58
        //try to get the class from use statements in the class file
59
        if ($className === null) {
60
            $classContent = file_get_contents($context->getFileName());
61
62
            $regExps = [
63
                "/use\s+([\w\\\]+$type);/", //use NameSpace\ClassName;
64
                "/use\s+([\w\\\]+)\s+as\s+$type/", //use NameSpace\ClassName as ClassAlias;
65
            ];
66
            foreach ($regExps as $regExp) {
67
                if ($matchClass = $this->extractClass($regExp, $classContent)) {
68
                    $className = $matchClass;
69
                    break;
70
                }
71
            }
72
        }
73
74
        //use the same namespace as class container
75
        if ($className === null && class_exists($context->getNamespaceName().'\\'.$type)) {
76
            $className = $context->getNamespaceName().'\\'.$type;
77
        }
78
79
        //use the type as class
80
        if (class_exists($type)) {
81
            $className = $type;
82
        }
83
84
        if (is_array($value) && $className !== null && class_exists($className) && $this->array2Object) {
85
            $property->setAccessible(true);
86
            $currentValue = $property->getValue($object);
87
            if (is_object($currentValue)) {
88
                $this->array2Object->populate($currentValue, $value);
89
90
                return $currentValue;
91
            } else {
92
                return $this->array2Object->createObject($className, $value);
93
            }
94
        }
95
96
        return $value;
97
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102
    public function toArrayValue($value, $type, \ReflectionProperty $property, $object)
103
    {
104
        if (is_object($value)) {
105
            return $this->object2Array->createArray($value);
106
        }
107
108
        return $value;
109
    }
110
111
    /**
112
     * Extract class usage from origin class content using regular expresion.
113
     *
114
     * @param $regEx
115
     * @param $classContent
116
     */
117
    private function extractClass($regEx, $classContent)
118
    {
119
        preg_match($regEx, $classContent, $matches);
120
        if (isset($matches[1]) && class_exists($matches[1])) {
121
            return $matches[1];
122
        }
123
124
        return;
125
    }
126
}
127