AutomatedBehaviorTrait   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 190
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 97.1%

Importance

Changes 13
Bugs 3 Features 1
Metric Value
wmc 24
c 13
b 3
f 1
lcom 1
cbo 5
dl 0
loc 190
ccs 67
cts 69
cp 0.971
rs 10

6 Methods

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