Completed
Push — master ( 674961...f4f264 )
by Antarès
03:25
created

AutomatedBehaviorTrait   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 187
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 94.29%

Importance

Changes 9
Bugs 2 Features 0
Metric Value
wmc 24
c 9
b 2
f 0
lcom 1
cbo 6
dl 0
loc 187
ccs 66
cts 70
cp 0.9429
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A isPropertiesConstraintsValidationEnabled() 0 4 1
A setPropertiesConstraintsValidationEnabled() 0 4 1
A setPropertiesConstraintsValidationDisabled() 0 4 1
A assertPropertyValue() 0 18 4
C updatePropertyAssociation() 0 42 15
A getPropertiesInfo() 0 15 2
1
<?php
2
3
namespace Accessible;
4
5
use \Accessible\MethodManager\CollectionManager;
6
use \Accessible\Reader\Reader;
7
use \Accessible\Reader\AssociationReader;
8
use \Accessible\Reader\ConstraintsReader;
9
10
trait AutomatedBehaviorTrait
11
{
12
    use AutoConstructTrait, AutoMethodsTrait;
13
14
    /**
15
     * The list of access rights on each property of the object.
16
     *
17
     * @var array
18
     */
19
    private $_accessProperties;
20
21
    /**
22
     * The list of collection properties and their item names.
23
     * Ex: [
24
     *   "byItemName" => "user" => ["property" => "users", "behavior" => "list", "methods" => ["add", "remove"]],
25
     *   "byProperty" => "users" => ["itemName" => "user", "behavior" => "list", "methods" => ["add", "remove"]]
26
     * ]
27
     *
28
     * @var array
29
     */
30
    private $_collectionsItemNames;
31
32
    /**
33
     * The list of associations for each property
34
     * Ex: ["products" => ["property" => "cart", "association" => "inverted"]]
35
     *
36
     * @var array
37
     */
38
    private $_associationsList;
39
40
    /**
41
     * Indicates wether the constraints validation should be enabled or not.
42
     *
43
     * @var boolean
44
     */
45
    private $_constraintsValidationEnabled;
46
47
    /**
48
     * The initial values of the properties that use Initialize and InitializeObject annotations.
49
     *
50
     * @var array
51
     */
52
    private $_initialPropertiesValues;
53
54
    /**
55
     * The arguments needed for the constructor.
56
     *
57
     * @var array
58
     */
59
    private $_initializationNeededArguments;
60
61
    /**
62
     * Indicates wether getPropertiesInfo() has been called or not.
63
     *
64
     * @var boolean
65
     */
66
    private $_automatedBehaviorInitialized = false;
67
68
    /**
69
     * Indicates if the properties constraints validation is enabled.
70
     *
71
     * @return boolean
72
     */
73
    public function isPropertiesConstraintsValidationEnabled()
74
    {
75
        return $this->_constraintsValidationEnabled;
76
    }
77
78
    /**
79
     * Enable (or disable) the properties constraints validation.
80
     *
81
     * @param boolean $enabled
82
     */
83 1
    public function setPropertiesConstraintsValidationEnabled($enabled = true)
84
    {
85 1
        $this->_constraintsValidationEnabled = $enabled;
86 1
    }
87
88
    /**
89
     * Disable (or enable) the properties constraints validation.
90
     *
91
     * @param boolean $disabled
92
     */
93 1
    public function setPropertiesConstraintsValidationDisabled($disabled = true)
94
    {
95 1
        $this->_constraintsValidationEnabled = !$disabled;
96 1
    }
97
98
    /**
99
     * Validates the given value compared to given property constraints.
100
     * If the value is not valid, an InvalidArgumentException will be thrown.
101
     *
102
     * @param  string $property The name of the reference property.
103
     * @param  mixed  $value    The value to check.
104
     *
105
     * @throws \InvalidArgumentException If the value is not valid.
106
     */
107 29
    protected function assertPropertyValue($property, $value)
108
    {
109 29
        $this->getPropertiesInfo();
110
111 29
        if ($this->_constraintsValidationEnabled) {
112 28
            $constraintsViolations = ConstraintsReader::validatePropertyValue($this, $property, $value);
113 28
            if ($constraintsViolations->count()) {
114 5
                $errorMessage = "Argument given is invalid; its constraints validation failed for property $property with the following messages: \"";
115 5
                $errorMessageList = array();
116 5
                foreach ($constraintsViolations as $violation) {
117 5
                    $errorMessageList[] = $violation->getMessage();
118 5
                }
119 5
                $errorMessage .= implode("\", \n\"", $errorMessageList) . "\".";
120
121 5
                throw new \InvalidArgumentException($errorMessage);
122
            }
123 27
        }
124 29
    }
125
126
    /**
127
     * Update the property associated to the given property.
128
     * You can pass the old or the new value given to the property.
129
     *
130
     * @param  string $property The property of the current class to update
131
     * @param  object $values   An array of old a new value under the following form:
132
     *                          ['oldValue' => $oldvalue, 'newValue' => $newValue]
133
     *                          If one of theses values is not given, it will simply not be updated.
134
     */
135 29
    protected function updatePropertyAssociation($property, array $values)
136
    {
137 29
        $this->getPropertiesInfo();
138
139 29
        if ($this->_associationsList === null) {
140
            $this->_associationsList = AssociationReader::getAssociations($this);
0 ignored issues
show
Bug introduced by
The call to getAssociations() misses a required argument $annotationReader.

This check looks for function calls that miss required arguments.

Loading history...
141
        }
142
143 29
        $oldValue = empty($values['oldValue']) ? null : $values['oldValue'];
144 29
        $newValue = empty($values['newValue']) ? null : $values['newValue'];
145
146 29
        $association = $this->_associationsList[$property];
147 29
        if (!empty($association)) {
148 7
            $associatedProperty = $association['property'];
149 7
            switch ($association['association']) {
150 7
                case 'inverted':
151 5
                    $invertedGetMethod = 'get' . strtoupper(substr($associatedProperty, 0, 1)) . substr($associatedProperty, 1);
152 5
                    $invertedSetMethod = 'set' . strtoupper(substr($associatedProperty, 0, 1)) . substr($associatedProperty, 1);
153 5
                    if ($oldValue !== null && $oldValue->$invertedGetMethod() === $this) {
154 4
                        $oldValue->$invertedSetMethod(null);
155 4
                    }
156 5
                    if ($newValue !== null && $newValue->$invertedGetMethod() !== $this) {
157 5
                        $newValue->$invertedSetMethod($this);
158 5
                    }
159 5
                    break;
160
161 3
                case 'mapped':
162 3
                    $itemName = $association['itemName'];
163 3
                    $mappedGetMethod = 'get' . strtoupper(substr($associatedProperty, 0, 1)) . substr($associatedProperty, 1);
164 3
                    $mappedAddMethod = 'add' . strtoupper(substr($itemName, 0, 1)) . substr($itemName, 1);
165 3
                    $mappedRemoveMethod = 'remove' . strtoupper(substr($itemName, 0, 1)) . substr($itemName, 1);
166
167 3
                    if ($oldValue !== null && CollectionManager::collectionContains($this, $oldValue->$mappedGetMethod())) {
168 3
                        $oldValue->$mappedRemoveMethod($this);
169 3
                    }
170 3
                    if ($newValue !== null && !CollectionManager::collectionContains($this, $newValue->$mappedGetMethod())) {
171 3
                        $newValue->$mappedAddMethod($this);
172 3
                    }
173 3
                    break;
174 7
            }
175 7
        }
176 29
    }
177
178
    /**
179
     * Get every information needed from this class.
180
     */
181 29
    private function getPropertiesInfo()
182
    {
183 29
        if (!$this->_automatedBehaviorInitialized) {
184 29
            $classInfo = Reader::getClassInformation($this);
185
186 29
            $this->_accessProperties = $classInfo['accessProperties'];
187 29
            $this->_collectionsItemNames = $classInfo['collectionsItemNames'];
188 29
            $this->_associationsList = $classInfo['associationsList'];
189 29
            $this->_constraintsValidationEnabled = $classInfo['constraintsValidationEnabled'];
190 29
            $this->_initialPropertiesValues = $classInfo['initialPropertiesValues'];
191 29
            $this->_initializationNeededArguments = $classInfo['initializationNeededArguments'];
192
193 29
            $this->_automatedBehaviorInitialized = true;
194 29
        }
195 29
    }
196
}
197