Completed
Push — dev ( 240328...12a618 )
by
unknown
20:20
created

Cloner   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 16
c 1
b 0
f 0
lcom 1
cbo 6
dl 0
loc 129
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B cloneObject() 0 23 4
C handleRelation() 0 28 7
A getRelationClonerResult() 0 5 1
A afterClone() 0 3 1
A getClonerManager() 0 4 1
A getOptions() 0 4 1
1
<?php
2
/**
3
 * @year    2016
4
 * @link    https://github.com/nnx-framework/cloner
5
 * @author  Lobanov Aleksandr <[email protected]>
6
 */
7
8
namespace Nnx\Cloner;
9
10
/**
11
 * Class Cloner
12
 *
13
 * @package Nnx\Cloner
14
 */
15
class Cloner implements ClonerInterface
16
{
17
18
    /**
19
     * @var ClonerManagerInterface
20
     */
21
    private $clonerManager;
22
23
    /**
24
     * @var Options\ClonerOptions
25
     */
26
    private $options;
27
28
    /**
29
     * Cloner constructor.
30
     *
31
     * @param ClonerInterface       $clonerManager
32
     * @param Options\ClonerOptions $options
33
     */
34
    public function __construct(ClonerInterface $clonerManager, Options\ClonerOptions $options)
35
    {
36
        $this->clonerManager = $clonerManager;
0 ignored issues
show
Documentation Bug introduced by
It seems like $clonerManager of type object<Nnx\Cloner\ClonerInterface> is incompatible with the declared type object<Nnx\Cloner\ClonerManagerInterface> of property $clonerManager.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
37
        $this->options = $options;
38
    }
39
40
    /**
41
     * @param mixed
42
     *
43
     * @return mixed
44
     * @throws \Nnx\Cloner\Exception\InvalidArgumentException
45
     * @throws \Nnx\Cloner\Exception\SetterNotFoundException
46
     */
47
    public function cloneObject($object)
48
    {
49
        if (!is_object($object)) {
50
            throw new Exception\InvalidArgumentException('Excepted object');
51
        }
52
53
        $cloneObject = clone $object;
54
        $this->afterClone($object, $cloneObject);
55
56
        foreach ($this->options->getRelations() as $relationName => $relation) {
57
            $cloneRelation = $this->handleRelation($object, $relationName, $relation);
58
59
            $relationSetter = 'set' . ucfirst($relationName);
60
            if (!method_exists($cloneObject, $relationSetter)) {
61
                throw new Exception\SetterNotFoundException(
62
                    sprintf('Not found setter %s in %s', $relationSetter, get_class($cloneObject))
63
                );
64
            }
65
            $cloneObject->$relationSetter($cloneRelation);
66
        }
67
68
        return $cloneObject;
69
    }
70
71
    /**
72
     * @param mixed                          $object
73
     * @param string                         $relationName
74
     * @param Options\Cloner\RelationOptions $options
75
     *
76
     * @return mixed
77
     * @throws \Nnx\Cloner\Exception\GetterNotFoundException
78
     */
79
    protected function handleRelation($object, $relationName, Options\Cloner\RelationOptions $options)
80
    {
81
        $relationName = 'get' . ucfirst($relationName);
82
        if (!method_exists($object, $relationName)) {
83
            throw new Exception\GetterNotFoundException(
84
                sprintf('Not found getter %s in %s', $relationName, get_class($object))
85
            );
86
        }
87
88
        $relationData = $object->$relationName();
89
        if ($relationData === null) {
90
            return null;
91
        }
92
        $cloneData = null;
0 ignored issues
show
Unused Code introduced by
$cloneData is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
93
        if (is_array($relationData)
94
            || $relationData instanceof \Traversable
95
        ) {
96
            $cloneData = [];
97
            foreach ($relationData as $data) {
98
                if ($relationArchiverResult = $this->getRelationClonerResult($options->getClonerName(), $data)) {
99
                    $cloneData[] = $relationArchiverResult;
100
                }
101
            }
102
        } else {
103
            $cloneData = $this->getRelationClonerResult($options->getClonerName(), $relationData);
104
        }
105
        return $cloneData;
106
    }
107
108
    /**
109
     * @param string $clonerName
110
     * @param mixed  $relationData
111
     *
112
     * @return mixed
113
     */
114
    protected function getRelationClonerResult($clonerName, $relationData)
115
    {
116
        $cloner = $this->getClonerManager()->get($clonerName);
117
        return $cloner->cloneObject($relationData);
118
    }
119
120
    /**
121
     * @param mixed $object      Исходный объект
122
     * @param mixed $cloneObject Склонированный объект
123
     */
124
    protected function afterClone($object, $cloneObject)
125
    {
126
    }
127
128
    /**
129
     * @return ClonerManagerInterface
130
     */
131
    protected function getClonerManager()
132
    {
133
        return $this->clonerManager;
134
    }
135
136
    /**
137
     * @return Options\ClonerOptions
138
     */
139
    protected function getOptions()
140
    {
141
        return $this->options;
142
    }
143
}
144