FunctionCallsCollector::collect()   D
last analyzed

Complexity

Conditions 20
Paths 32

Size

Total Lines 118
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 20
eloc 51
c 1
b 0
f 0
nc 32
nop 1
dl 0
loc 118
rs 4.1666

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
 * Created by PhpStorm.
4
 * User: peter
5
 * Date: 20.07.18
6
 * Time: 14:16
7
 */
8
9
namespace Maslosoft\Whitelist\Tokenizer\Collectors;
10
11
12
use Maslosoft\Whitelist\Interfaces\TokenCollectorInterface;
13
use Maslosoft\Whitelist\Interfaces\TokenInterface;
14
use Maslosoft\Whitelist\Tokenizer\Composite\FunctionCall;
15
use const T_DO;
16
use const T_DOUBLE_COLON;
17
use const T_ECHO;
18
use const T_EVAL;
19
use const T_EXIT;
20
use const T_FOR;
21
use const T_FOREACH;
22
use const T_HALT_COMPILER;
23
use const T_OBJECT_OPERATOR;
24
use const T_PRINT;
25
use const T_RETURN;
26
use const T_WHILE;
27
28
class FunctionCallsCollector implements TokenCollectorInterface
29
{
30
	public function collect($tokens)
31
	{
32
		$result = [];
33
		foreach ($tokens as $index => $token)
34
		{
35
			// Check for exists/returns, eval's, echo and other constructs
36
			$toCheck = [
37
				// Eval
38
				T_EVAL,
39
40
				// Echo constructs
41
				T_ECHO,
42
				T_PRINT,
43
44
				// Finishing instructions
45
				T_RETURN,
46
				T_EXIT,
47
				T_HALT_COMPILER,
48
49
				// Loops
50
				T_FOR,
51
				T_FOREACH,
52
				T_WHILE,
53
				T_DO
54
			];
55
56
			foreach($toCheck as $type)
57
			{
58
				if($token->is($type))
59
				{
60
					$result[] = $token;
61
					continue 2;
62
				}
63
			}
64
65
			// Looks not looks like a function then skip
66
			if (!$token->valIs('('))
67
			{
68
				continue;
69
			}
70
71
			// Get actual token rather than `(`
72
			$token = $token->prev();
73
74
			// If not string or variable, might be control operator, skip
75
			// Variable might be used as variable function name, ie $name()
76
			// This could be also `]` when it's array member
77
			if ($token->not(T_STRING) && $token->not(T_VARIABLE) && !$token->valIs(']'))
78
			{
79
				continue;
80
			}
81
82
			// Get token before function name
83
			$prev = $token->prev();
84
85
			// Method call
86
			if($prev->is(T_OBJECT_OPERATOR))
87
			{
88
				continue;
89
			}
90
91
			// Static method call
92
			if($prev->is(T_DOUBLE_COLON))
93
			{
94
				continue;
95
			}
96
97
			// Check if is simple function
98
			// By checking what's before name
99
			// Exclude array members calls here, as it is special case
100
			if (
101
				$prev->not(T_DOUBLE_COLON) &&
102
				$prev->not(T_NEW) &&
103
				$prev->not(T_OBJECT_OPERATOR) &&
104
				!$token->valIs(']')
105
			)
106
			{
107
				$result[] = $token;
108
				continue;
109
			}
110
111
			// Check for array member call
112
			if ($token->valIs(']'))
113
			{
114
				$arr = $token;
115
116
				$isClosed = false;
117
118
				$name = [];
119
				// Search back to find variable name of this array
120
				// And whole expression value
121
				// Need to check for `[$variable]` too
122
				//
123
				// If could not find variable, bogus code? Break loop.
124
				// This would be code like only `]()`
125
				while ($arr->not(TokenInterface::TypeEmpty))
126
				{
127
					$name[] = $arr->value;
128
					if ($arr->valIs(']'))
129
					{
130
						$isClosed = false;
131
					}
132
					if ($arr->valIs('['))
133
					{
134
						$isClosed = true;
135
					}
136
					$arr = $arr->prev();
137
					if ($arr->is(T_VARIABLE) && $isClosed)
138
					{
139
						$name[] = $arr->value;
140
						break;
141
					}
142
				}
143
				$tmp = implode('', array_reverse($name));
144
				$result[] = new FunctionCall($tmp, $tokens, $index);
145
			}
146
		}
147
		return $result;
148
	}
149
150
}