1 | <?php |
||
16 | class FunctionDataCollector extends AbstractDataCollector |
||
17 | { |
||
18 | |||
19 | /** |
||
20 | * Collect data from a namespace. |
||
21 | * |
||
22 | * @param integer $file_id File id. |
||
23 | * @param ReflectionFileNamespace $namespace Namespace. |
||
24 | * |
||
25 | * @return void |
||
26 | */ |
||
27 | 4 | public function collectData($file_id, ReflectionFileNamespace $namespace) |
|
80 | |||
81 | /** |
||
82 | * Deletes functions. |
||
83 | * |
||
84 | * @param integer $file_id File ID. |
||
85 | * @param array $functions Methods. |
||
86 | * |
||
87 | * @return void |
||
88 | */ |
||
89 | 1 | protected function deleteFunctions($file_id, array $functions) |
|
123 | |||
124 | /** |
||
125 | * Processes function parameters. |
||
126 | * |
||
127 | * @param integer $function_id Function ID. |
||
128 | * @param \ReflectionFunction $function Function. |
||
129 | * |
||
130 | * @return void |
||
131 | */ |
||
132 | 4 | protected function processFunctionParameters($function_id, \ReflectionFunction $function) |
|
133 | { |
||
134 | $sql = 'SELECT Name |
||
135 | FROM FunctionParameters |
||
136 | 4 | WHERE FunctionId = :function_id'; |
|
137 | 4 | $old_parameters = $this->db->fetchCol($sql, array( |
|
138 | 4 | 'function_id' => $function_id, |
|
139 | 4 | )); |
|
140 | |||
141 | $insert_sql = ' INSERT INTO FunctionParameters (FunctionId, Name, Position, TypeClass, HasType, TypeName, AllowsNull, IsArray, IsCallable, IsOptional, IsVariadic, CanBePassedByValue, IsPassedByReference, HasDefaultValue, DefaultValue, DefaultConstant) |
||
142 | 4 | VALUES (:function_id, :name, :position, :type_class, :has_type, :type_name, :allows_null, :is_array, :is_callable, :is_optional, :is_variadic, :can_be_passed_by_value, :is_passed_by_reference, :has_default_value, :default_value, :default_constant)'; |
|
143 | $update_sql = ' UPDATE FunctionParameters |
||
144 | SET Position = :position, |
||
145 | TypeClass = :type_class, |
||
146 | HasType = :has_type, |
||
147 | TypeName = :type_name, |
||
148 | AllowsNull = :allows_null, |
||
149 | IsArray = :is_array, |
||
150 | IsCallable = :is_callable, |
||
151 | IsOptional = :is_optional, |
||
152 | IsVariadic = :is_variadic, |
||
153 | CanBePassedByValue = :can_be_passed_by_value, |
||
154 | IsPassedByReference = :is_passed_by_reference, |
||
155 | HasDefaultValue = :has_default_value, |
||
156 | DefaultValue = :default_value, |
||
157 | DefaultConstant = :default_constant |
||
158 | 4 | WHERE FunctionId = :function_id AND Name = :name'; |
|
159 | |||
160 | 4 | $new_parameters = array(); |
|
161 | |||
162 | 4 | foreach ( $function->getParameters() as $position => $parameter ) { |
|
163 | 4 | $parameter_name = $parameter->getName(); |
|
164 | 4 | $new_parameters[] = $parameter_name; |
|
165 | |||
166 | 4 | $type_class = $parameter->getClass(); |
|
167 | 4 | $type_class = $type_class ? $type_class->getName() : null; |
|
168 | |||
169 | 4 | $has_type = $parameter->hasType(); |
|
|
|||
170 | 4 | $type_name = $has_type ? (string)$parameter->getType() : null; |
|
171 | |||
172 | 4 | $has_default_value = $parameter->isDefaultValueAvailable(); |
|
173 | 4 | $default_value_is_constant = $has_default_value ? $parameter->isDefaultValueConstant() : false; |
|
174 | |||
175 | 4 | $this->db->perform( |
|
176 | 4 | in_array($parameter_name, $old_parameters) ? $update_sql : $insert_sql, |
|
177 | array( |
||
178 | 4 | 'function_id' => $function_id, |
|
179 | 4 | 'name' => $parameter_name, |
|
180 | 4 | 'position' => $position, |
|
181 | 4 | 'type_class' => $type_class, |
|
182 | 4 | 'has_type' => (int)$has_type, |
|
183 | 4 | 'type_name' => $type_name, |
|
184 | 4 | 'allows_null' => (int)$parameter->allowsNull(), |
|
185 | 4 | 'is_array' => (int)$parameter->isArray(), |
|
186 | 4 | 'is_callable' => (int)$parameter->isCallable(), |
|
187 | 4 | 'is_optional' => (int)$parameter->isOptional(), |
|
188 | 4 | 'is_variadic' => (int)$parameter->isVariadic(), |
|
189 | 4 | 'can_be_passed_by_value' => (int)$parameter->canBePassedByValue(), |
|
190 | 4 | 'is_passed_by_reference' => (int)$parameter->isPassedByReference(), |
|
191 | 4 | 'has_default_value' => (int)$has_default_value, |
|
192 | 4 | 'default_value' => $has_default_value ? json_encode($parameter->getDefaultValue()) : null, |
|
193 | 4 | 'default_constant' => $default_value_is_constant ? $parameter->getDefaultValueConstantName() : null, |
|
194 | ) |
||
195 | 4 | ); |
|
196 | 4 | } |
|
197 | |||
198 | 4 | $delete_parameters = array_diff($old_parameters, $new_parameters); |
|
199 | |||
200 | 4 | if ( $delete_parameters ) { |
|
201 | $sql = 'DELETE FROM FunctionParameters |
||
202 | WHERE FunctionId = :function_id AND Name IN (:names)'; |
||
203 | $this->db->perform($sql, array( |
||
204 | 'function_id' => $function_id, |
||
205 | 'names' => $delete_parameters, |
||
206 | )); |
||
207 | } |
||
208 | 4 | } |
|
209 | |||
210 | /** |
||
211 | * Delete previously collected data for a files. |
||
212 | * |
||
213 | * @param array $file_ids File IDs. |
||
214 | * |
||
215 | * @return void |
||
216 | */ |
||
217 | 1 | public function deleteData(array $file_ids) |
|
223 | |||
224 | /** |
||
225 | * Returns statistics about the code. |
||
226 | * |
||
227 | * @return array |
||
228 | */ |
||
229 | 1 | public function getStatistics() |
|
239 | |||
240 | } |
||
241 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the parent class: