Passed
Push — master ( 85fd9a...e9971f )
by Alexander
02:00
created

FunctionDataCollector::collectData()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 51
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 6.0018

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 27
c 1
b 0
f 0
nc 10
nop 2
dl 0
loc 51
ccs 26
cts 27
cp 0.963
crap 6.0018
rs 8.8657

How to fix   Long Method   

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
 * This file is part of the Code-Insight library.
4
 * For the full copyright and license information, please view
5
 * the LICENSE file that was distributed with this source code.
6
 *
7
 * @copyright Alexander Obuhovich <[email protected]>
8
 * @link      https://github.com/console-helpers/code-insight
9
 */
10
11
namespace ConsoleHelpers\CodeInsight\KnowledgeBase\DataCollector;
12
13
14
use Go\ParserReflection\ReflectionFileNamespace;
15
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)
28
	{
29 4
		$sql = 'SELECT Name, Id
30
				FROM Functions
31
				WHERE FileId = :file_id';
32 4
		$old_functions = $this->db->fetchPairs($sql, array(
33 4
			'file_id' => $file_id,
34
		));
35
36 4
		$insert_sql = '	INSERT INTO Functions (FileId, Name, ParameterCount, RequiredParameterCount, IsVariadic, ReturnsReference, HasReturnType, ReturnType)
37
						VALUES (:file_id, :name, :parameter_count, :required_parameter_count, :is_variadic, :returns_reference, :has_return_type, :return_type)';
38 4
		$update_sql = '	UPDATE Functions
39
						SET	ParameterCount = :parameter_count,
40
							RequiredParameterCount = :required_parameter_count,
41
							IsVariadic = :is_variadic,
42
							ReturnsReference = :returns_reference,
43
							ReturnType = :return_type,
44
							HasReturnType = :has_return_type
45
						WHERE FileId = :file_id AND Name = :name';
46
47 4
		$new_functions = array();
48
49 4
		foreach ( $namespace->getFunctions() as $function ) {
50 4
			$function_name = $function->getName();
51 4
			$new_functions[] = $function_name;
52
53 4
			$has_return_type = $function->hasReturnType();
54 4
			$return_type = $has_return_type ? (string)$function->getReturnType() : null;
55
56 4
			$this->db->perform(
57 4
				isset($old_functions[$function_name]) ? $update_sql : $insert_sql,
58
				array(
59 4
					'file_id' => $file_id,
60 4
					'name' => $function_name,
61 4
					'parameter_count' => $function->getNumberOfParameters(),
62 4
					'required_parameter_count' => $function->getNumberOfRequiredParameters(),
63 4
					'is_variadic' => (int)$function->isVariadic(),
64 4
					'returns_reference' => (int)$function->returnsReference(),
65 4
					'has_return_type' => (int)$has_return_type,
66 4
					'return_type' => $return_type,
67
				)
68
			);
69
70 4
			$function_id = isset($old_functions[$function_name]) ? $old_functions[$function_name] : $this->db->lastInsertId();
71 4
			$this->processFunctionParameters($function_id, $function);
72
		}
73
74 4
		$delete_functions = array_diff(array_keys($old_functions), $new_functions);
75
76 4
		if ( $delete_functions ) {
77
			$this->deleteFunctions($file_id, $delete_functions);
78
		}
79 4
	}
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)
90
	{
91 1
		if ( $functions ) {
92
			// Delete only given functions.
93
			$sql = 'SELECT Id
94
					FROM Functions
95
					WHERE FileId = :file_id AND Name IN (:names)';
96
			$function_ids = $this->db->fetchCol($sql, array(
97
				'file_id' => $file_id,
98
				'names' => $functions,
99
			));
100
		}
101
		else {
102
			// Delete all functions in a file.
103 1
			$sql = 'SELECT Id
104
					FROM Functions
105
					WHERE FileId = :file_id';
106 1
			$function_ids = $this->db->fetchCol($sql, array(
107 1
				'file_id' => $file_id,
108
			));
109
		}
110
111
		// @codeCoverageIgnoreStart
112
		if ( !$function_ids ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $function_ids of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
113
			return;
114
		}
115
		// @codeCoverageIgnoreEnd
116
117 1
		$sql = 'DELETE FROM Functions WHERE Id IN (:function_ids)';
118 1
		$this->db->perform($sql, array('function_ids' => $function_ids));
119
120 1
		$sql = 'DELETE FROM FunctionParameters WHERE FunctionId IN (:function_ids)';
121 1
		$this->db->perform($sql, array('function_ids' => $function_ids));
122 1
	}
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 4
		$sql = 'SELECT Name
135
				FROM FunctionParameters
136
				WHERE FunctionId = :function_id';
137 4
		$old_parameters = $this->db->fetchCol($sql, array(
138 4
			'function_id' => $function_id,
139
		));
140
141 4
		$insert_sql = '	INSERT INTO FunctionParameters (FunctionId, Name, Position, TypeClass, HasType, TypeName, AllowsNull, IsArray, IsCallable, IsOptional, IsVariadic, CanBePassedByValue, IsPassedByReference, HasDefaultValue, DefaultValue, DefaultConstant)
142
						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 4
		$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
						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
			);
196
		}
197
198 4
		$delete_parameters = array_diff($old_parameters, $new_parameters);
199
200 4
		if ( $delete_parameters ) {
201 1
			$sql = 'DELETE FROM FunctionParameters
202
					WHERE FunctionId = :function_id AND Name IN (:names)';
203 1
			$this->db->perform($sql, array(
204 1
				'function_id' => $function_id,
205 1
				'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)
218
	{
219 1
		foreach ( $file_ids as $file_id ) {
220 1
			$this->deleteFunctions($file_id, array());
221
		}
222 1
	}
223
224
	/**
225
	 * Returns statistics about the code.
226
	 *
227
	 * @return array
228
	 */
229 1
	public function getStatistics()
230
	{
231 1
		$sql = 'SELECT COUNT(*)
232
				FROM Functions';
233 1
		$function_count = $this->db->fetchValue($sql);
234
235
		return array(
236 1
			'Functions' => $function_count,
237
		);
238
	}
239
240
}
241