Completed
Branch master (c78441)
by Antarès
07:43 queued 02:23
created

AutomatedBehaviorTrait::__call()   C

Complexity

Conditions 16
Paths 42

Size

Total Lines 78
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 45
CRAP Score 17.5382

Importance

Changes 4
Bugs 2 Features 0
Metric Value
c 4
b 2
f 0
dl 0
loc 78
ccs 45
cts 55
cp 0.8182
rs 5.142
cc 16
eloc 52
nc 42
nop 2
crap 17.5382

2 Methods

Rating   Name   Duplication   Size   Complexity  
C AutomatedBehaviorTrait::updatePropertyAssociation() 0 42 15
A AutomatedBehaviorTrait::getPropertiesInfo() 0 11 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Accessible;
4
5
use \Accessible\MethodManager\CollectionManager;
6
use \Accessible\Reader\AccessReader;
7
use \Accessible\Reader\AssociationReader;
8
use \Accessible\Reader\ConstraintsReader;
9
use \Accessible\Reader\CollectionsReader;
10
11
trait AutomatedBehaviorTrait
12
{
13
    use AutoConstructTrait, AutoMethodsTrait;
14
15
    /**
16
     * The list of access rights on each property of the object.
17
     *
18
     * @var array
19
     */
20
    private $_accessProperties;
21
22
    /**
23
     * The list of collection properties and their item names.
24
     * Ex: [
25
     *   "byItemName" => "user" => ["property" => "users", "behavior" => "list", "methods" => ["add", "remove"]],
26
     *   "byProperty" => "users" => ["itemName" => "user", "behavior" => "list", "methods" => ["add", "remove"]]
27
     * ]
28
     *
29
     * @var array
30
     */
31
    private $_collectionsItemNames;
32
33
    /**
34
     * The list of associations for each property
35
     * Ex: ["products" => ["property" => "cart", "association" => "inverted"]]
36
     *
37
     * @var array
38
     */
39
    private $_associationsList;
40
41
    /**
42
     * Indicates wether the constraints validation should be enabled or not.
43
     *
44
     * @var boolean
45
     */
46
    private $_constraintsValidationEnabled;
47
48
    /**
49
     * Indicates wether getPropertiesInfo() has been called or not.
50
     *
51
     * @var boolean
52
     */
53
    private $_automatedBehaviorInitialized = false;
54
55
    /**
56
     * Indicates if the properties constraints validation is enabled.
57
     *
58
     * @return boolean
59
     */
60
    public function isPropertiesConstraintsValidationEnabled()
61
    {
62
        return $this->_constraintsValidationEnabled;
63
    }
64
65
    /**
66
     * Enable (or disable) the properties constraints validation.
67
     *
68
     * @param boolean $enabled
69
     */
70 1
    public function setPropertiesConstraintsValidationEnabled($enabled = true)
71
    {
72 1
        $this->_constraintsValidationEnabled = $enabled;
73 1
    }
74
75
    /**
76
     * Disable (or enable) the properties constraints validation.
77
     *
78
     * @param boolean $disabled
79
     */
80 1
    public function setPropertiesConstraintsValidationDisabled($disabled = true)
81
    {
82 1
        $this->_constraintsValidationEnabled = !$disabled;
83 1
    }
84
85
    /**
86
     * Validates the given value compared to given property constraints.
87
     * If the value is not valid, an InvalidArgumentException will be thrown.
88
     *
89
     * @param  string $property The name of the reference property.
90
     * @param  mixed  $value    The value to check.
91
     *
92
     * @throws \InvalidArgumentException If the value is not valid.
93
     */
94 29
    protected function assertPropertyValue($property, $value)
95
    {
96 29
        $this->getPropertiesInfo();
97
98 29
        if ($this->_constraintsValidationEnabled) {
99 28
            $constraintsViolations = ConstraintsReader::validatePropertyValue($this, $property, $value);
100 28
            if ($constraintsViolations->count()) {
101 5
                $errorMessage = "Argument given is invalid; its constraints validation failed for property $property with the following messages: \"";
102 5
                $errorMessageList = array();
103 5
                foreach ($constraintsViolations as $violation) {
104 5
                    $errorMessageList[] = $violation->getMessage();
105 5
                }
106 5
                $errorMessage .= implode("\", \n\"", $errorMessageList) . "\".";
107
108 5
                throw new \InvalidArgumentException($errorMessage);
109
            }
110 27
        }
111 29
    }
112
113
    /**
114
     * Update the property associated to the given property.
115
     * You can pass the old or the new value given to the property.
116
     *
117
     * @param  string $property The property of the current class to update
118
     * @param  object $values   An array of old a new value under the following form:
119
     *                          ['oldValue' => $oldvalue, 'newValue' => $newValue]
120
     *                          If one of theses values is not given, it will simply not be updated.
121
     */
122 29
    protected function updatePropertyAssociation($property, array $values)
123
    {
124 29
        $this->getPropertiesInfo();
125
126 29
        if ($this->_associationsList === null) {
127
            $this->_associationsList = AssociationReader::getAssociations($this);
128
        }
129
130 29
        $oldValue = empty($values['oldValue']) ? null : $values['oldValue'];
131 29
        $newValue = empty($values['newValue']) ? null : $values['newValue'];
132
133 29
        $association = $this->_associationsList[$property];
134 29
        if (!empty($association)) {
135 7
            $associatedProperty = $association['property'];
136 7
            switch ($association['association']) {
137 7
                case 'inverted':
138 5
                    $invertedGetMethod = 'get' . strtoupper(substr($associatedProperty, 0, 1)) . substr($associatedProperty, 1);
139 5
                    $invertedSetMethod = 'set' . strtoupper(substr($associatedProperty, 0, 1)) . substr($associatedProperty, 1);
140 5
                    if ($oldValue !== null && $oldValue->$invertedGetMethod() === $this) {
141 4
                        $oldValue->$invertedSetMethod(null);
142 4
                    }
143 5
                    if ($newValue !== null && $newValue->$invertedGetMethod() !== $this) {
144 5
                        $newValue->$invertedSetMethod($this);
145 5
                    }
146 5
                    break;
147
148 3
                case 'mapped':
149 3
                    $itemName = $association['itemName'];
150 3
                    $mappedGetMethod = 'get' . strtoupper(substr($associatedProperty, 0, 1)) . substr($associatedProperty, 1);
151 3
                    $mappedAddMethod = 'add' . strtoupper(substr($itemName, 0, 1)) . substr($itemName, 1);
152 3
                    $mappedRemoveMethod = 'remove' . strtoupper(substr($itemName, 0, 1)) . substr($itemName, 1);
153
154 3
                    if ($oldValue !== null && CollectionManager::collectionContains($this, $oldValue->$mappedGetMethod())) {
155 3
                        $oldValue->$mappedRemoveMethod($this);
156 3
                    }
157 3
                    if ($newValue !== null && !CollectionManager::collectionContains($this, $newValue->$mappedGetMethod())) {
158 3
                        $newValue->$mappedAddMethod($this);
159 3
                    }
160 3
                    break;
161 7
            }
162 7
        }
163 29
    }
164
165
    /**
166
     * Get every information needed from this class.
167
     */
168 29
    private function getPropertiesInfo()
169
    {
170 29
        if (!$this->_automatedBehaviorInitialized) {
171 29
            $this->_accessProperties = AccessReader::getAccessProperties($this);
172 29
            $this->_collectionsItemNames = CollectionsReader::getCollectionsItemNames($this);
173 29
            $this->_associationsList = AssociationReader::getAssociations($this);
174 29
            $this->_constraintsValidationEnabled = ConstraintsReader::isConstraintsValidationEnabled($this);
175
176 29
            $this->_automatedBehaviorInitialized = true;
177 29
        }
178 29
    }
179
}
180