Elevator   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 93
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 9
c 1
b 0
f 0
lcom 1
cbo 2
dl 0
loc 93
ccs 30
cts 30
cp 1
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 21 3
A mergeMap() 0 17 4
A elevate() 0 16 2
1
<?php
2
3
/**
4
 * elevator
5
 *
6
 * @category Jkphl
7
 * @package Jkphl\Rdfalite
8
 * @subpackage Jkphl\Elevator\Domain
9
 * @author Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright Copyright © 2017 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license http://opensource.org/licenses/MIT The MIT License (MIT)
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2017 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Jkphl\Elevator\Domain;
38
39
/**
40
 * Elevator
41
 *
42
 * @package Jkphl\Elevator
43
 * @subpackage Jkphl\Elevator\Domain
44
 */
45
class Elevator
46
{
47
    /**
48
     * Source object
49
     *
50
     * @var object
51
     */
52
    protected $object;
53
    /**
54
     * Source object class reflection
55
     *
56
     * @var \ReflectionClass
57
     */
58
    protected $class;
59
60
    /**
61
     * Constructor
62
     *
63
     * @param object $object Source object
64
     * @throws UnexpectedValueException If the argument is not an object
65
     */
66 7
    public function __construct($object)
67
    {
68
        // If the argument is not an object
69 7
        if (!is_object($object)) {
70 1
            throw new UnexpectedValueException(
71 1
                UnexpectedValueException::OBJECT_REQUIRED_STR,
72 1
                UnexpectedValueException::OBJECT_REQUIRED
73
            );
74
        }
75
76 6
        $this->object = $object;
77 6
        $this->class = new \ReflectionClass($this->object);
78
79
        // If the object is of an internal class
80 6
        if ($this->class->isInternal()) {
81 1
            throw new UnexpectedValueException(
82 1
                sprintf(UnexpectedValueException::NON_INTERNAL_REQUIRED_STR, $this->class->name),
83 1
                UnexpectedValueException::NON_INTERNAL_REQUIRED
84
            );
85
        }
86 5
    }
87
88
    /**
89
     * Elevate the current object to a particular class
90
     *
91
     * @param \ReflectionClass $class Target class
92
     * @param ElevationMap $map
93
     * @return object Elevated target object
94
     */
95 5
    public function elevate(\ReflectionClass $class, ElevationMap $map)
96
    {
97
        // If the target class doesn't extend the source object class
98 5
        if (!$class->isSubclassOf($this->class->name)) {
99 1
            throw new UnexpectedValueException(
100
                sprintf(
101 1
                    UnexpectedValueException::INVALID_TARGET_CLASS_STR,
102 1
                    $class->name,
103 1
                    $this->class->name
104
                ),
105 1
                UnexpectedValueException::INVALID_TARGET_CLASS
106
            );
107
        }
108
109 4
        return $this->mergeMap($class->newInstanceWithoutConstructor(), $class, $map);
110
    }
111
112
    /**
113
     * Recursively merge an elevation map into an elevated target object
114
     *
115
     * @param object $object Target object
116
     * @param \ReflectionClass $class Current class
117
     * @param ElevationMap $map Elevation map
118
     * @return object Target object
119
     */
120 4
    protected function mergeMap($object, \ReflectionClass $class, ElevationMap $map)
121
    {
122
        // Run through all property values declared by this class
123 4
        foreach ($map->getPropertyValues($class) as $propertyName => $propertyValue) {
124 4
            $property = $class->getProperty($propertyName);
125 4
            $property->setAccessible(true);
126 4
            $property->setValue($object, $propertyValue);
127 4
            $property->setAccessible(false);
128
        }
129
130 4
        $parentClass = $class->getParentClass();
131 4
        if (($parentClass instanceof \ReflectionClass) && !$parentClass->isInternal()) {
132 4
            $this->mergeMap($object, $parentClass, $map);
133
        }
134
135 4
        return $object;
136
    }
137
}
138