Completed
Push — php7.2-travis ( f6798b...7aec14 )
by
unknown
430:08 queued 423:26
created

sql_compiler::parse_ident()   F

Complexity

Conditions 22
Paths 722

Size

Total Lines 109
Code Lines 78

Duplication

Lines 24
Ratio 22.02 %

Code Coverage

Tests 57
CRAP Score 54.4388

Importance

Changes 0
Metric Value
cc 22
eloc 78
nc 722
nop 1
dl 24
loc 109
ccs 57
cts 96
cp 0.5938
crap 54.4388
rs 2.2834
c 0
b 0
f 0

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
abstract class sql_compiler {
4
	protected $skipDefaultOrderBy;
5
	protected $store;
6
	public  $error;
7
	protected $join_target_properties;
8
	protected $offset;
9
	protected $limit;
10
	protected $cache;
11
	protected $path;
12
	protected $_SCAN_WS        = array(" " => true, "\t" => true, "\n" => true ,"\r" => true);
13
	protected $_SCAN_AZ        = array("a" => true, "A" => true, "b" => true, "B" => true, "c" => true, "C" => true, "d" => true, "D" => true, "e" => true, "E" => true, "f" => true, "F" => true, "g" => true, "G" => true, "h" => true, "H" => true, "i" => true, "I" => true, "j" => true, "J" => true, "k" => true, "K" => true, "l" => true, "L" => true, "m" => true, "M" => true, "n" => true, "N" => true, "o" => true, "O" => true, "p" => true, "P" => true, "q" => true, "Q" => true, "r" => true, "R" => true, "s" => true, "S" => true, "t" => true, "T" => true, "u" => true, "U" => true, "v" => true, "V" => true, "w" => true, "W" => true, "x" => true, "X" => true, "y" => true, "Y" => true, "z" => true, "Z" => true);
14
	protected $_SCAN_AZ_09     = array("a" => true, "A" => true, "b" => true, "B" => true, "c" => true, "C" => true, "d" => true, "D" => true, "e" => true, "E" => true, "f" => true, "F" => true, "g" => true, "G" => true, "h" => true, "H" => true, "i" => true, "I" => true, "j" => true, "J" => true, "k" => true, "K" => true, "l" => true, "L" => true, "m" => true, "M" => true, "n" => true, "N" => true, "o" => true, "O" => true, "p" => true, "P" => true, "q" => true, "Q" => true, "r" => true, "R" => true, "s" => true, "S" => true, "t" => true, "T" => true, "u" => true, "U" => true, "v" => true, "V" => true, "w" => true, "W" => true, "x" => true, "X" => true, "y" => true, "Y" => true, "z" => true, "Z" => true, "_" => true, "0" => true, "1" => true, "2" => true, "3" => true, "4" => true, "5" => true, "6" => true, "7" => true, "8" => true, "9" => true);
15
	protected $_SCAN_NUM       = array("0" => true, "1" => true, "2" => true, "3" => true, "4" => true, "5" => true, "6" => true, "7" => true, "8" => true, "9" => true);
16
	protected $_SCAN_NUM_START = array("0" => true, "1" => true, "2" => true, "3" => true, "4" => true, "5" => true, "6" => true, "7" => true, "8" => true, "9" => true, "-" => true);
17
	protected $_SCAN_CMP       = array("~" => array("=" => array("FIN" => true)), "=" => array("=" => array("FIN" => true), "FIN" => true, "~" => array("FIN" => true, "~" => array("FIN" => true)), "*" => array("FIN" => true, "*" => array("FIN" => true)), "/" => array("FIN" => true)), "!" => array("=" => array("FIN" => true), "~" => array("FIN" => true, "~" => array("FIN" => true)), "*" => array("FIN" => true, "*" => array("FIN" => true)), "/" => array("FIN" => true, "/" => array("FIN" => true))), "<" => array("=" => array("FIN" => true), "FIN" => true), ">" => array("=" => array("FIN" => true), "FIN" => true), "/" => array("=" => array("=" => array("FIN" => true))));
18
19
20 14
	protected function parse_const(&$YYBUFFER) {
21 14
		$YYCURSOR = 0;
22 14
		while (isset($this->_SCAN_WS[$YYBUFFER[$YYCURSOR]])) {
23 2
			$YYCURSOR++;
24 2
		}
25 14
		$value = '';
26 14
		$yych = $YYBUFFER[$YYCURSOR];
27
		switch (true) {
28 14
			case '"' === $yych:
29 14
			case "'" === $yych:
30 14
				$quote = $yych;
31 14
				$yych = $YYBUFFER[++$YYCURSOR];
32 14
				while ($yych !== "\0" && $yych !== $quote) {
33 14
					if ($yych === "\\") {
34 1
						$yych = $YYBUFFER[++$YYCURSOR];
35 1
						if ($yych !== $quote && $yych != "\\") {
36
							$value .= "\\";
37
						}
38 1
					}
39 14
					$value .= $yych;
40 14
					$yych = $YYBUFFER[++$YYCURSOR];
41 14
				}
42 14
				$YYBUFFER = substr($YYBUFFER, $YYCURSOR + 1);
43 14
				$node["id"] = "string";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$node was never initialized. Although not strictly required by PHP, it is generally a good practice to add $node = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
44 14
				$node["type"] = ($quote === '"') ? "double" : "single";
45 14
				$node["value"] = stripslashes($value);
46 14
				return $node;
47
			break;
48
			case $this->_SCAN_NUM_START[$yych]:
49
				$value = $yych;
50
				$yych = $YYBUFFER[++$YYCURSOR];
51
				while (isset($this->_SCAN_NUM[$yych])) {
52
					$value .= $yych;
53
					$yych = $YYBUFFER[++$YYCURSOR];
54
				}
55
				if ($yych === '.') {
56
					$value .= $yych;
57
					$yych = $YYBUFFER[++$YYCURSOR];
58
					while (isset($this->_SCAN_NUM[$yych])) {
59
						$value .= $yych;
60
						$yych = $YYBUFFER[++$YYCURSOR];
61
					}
62
					$node["id"]="float";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$node was never initialized. Although not strictly required by PHP, it is generally a good practice to add $node = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
63
					$node["value"]=(float)$value;
64
				} else {
65
					$node["id"]="int";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$node was never initialized. Although not strictly required by PHP, it is generally a good practice to add $node = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
66
					$node["value"]=(int)$value;;
67
				}
68
				$YYBUFFER = substr($YYBUFFER, $YYCURSOR);
69
				return $node;
70
			break;
71
		}
72
	}
73
74 14
	protected function parse_ident(&$YYBUFFER) {
75
		/* parse identifier regs 1,2 and 3
76
77
			reg[1]: tablename
78
			reg[2]: property name
79
			reg[3]: only used with 'my' properties
80
		*/
81 14
		$reg_id='^[[:space:]]*(([a-z_][a-z0-9_]*)(:[a-z]+)?([.][a-z_][a-z0-9_]*)?([.][a-z_][a-z0-9_]*)?)';
82 14
		$reg_id.='[[:space:]]*';
83
84 14
		$YYCURSOR = 0;
85 14
		while (isset($this->_SCAN_WS[$YYBUFFER[$YYCURSOR]])) {
86
			$YYCURSOR++;
87
		}
88 14
		$value = '';
89 14
		$yych = $YYBUFFER[$YYCURSOR];
90
91 14
		if ($this->_SCAN_AZ[$yych]) {
92 14
			$value .= $yych;
93 14
			$yych = $YYBUFFER[++$YYCURSOR];
94 14
			while (isset($this->_SCAN_AZ_09[$yych])) {
95 14
				$value .= $yych;
96 14
				$yych = $YYBUFFER[++$YYCURSOR];
97 14
			}
98 14
			$match_1 = $value; $value = '';
99 14
			if ($yych === ':') {
100
				$yych = $YYBUFFER[++$YYCURSOR];
101
				while (isset($this->_SCAN_AZ[$yych])) {
102
					$value .= $yych;
103
					$yych = $YYBUFFER[++$YYCURSOR];
104
				}
105
				$record_id = $value; $value = '';
106
			}
107 14 View Code Duplication
			if ($yych === '.') {
108 14
				$yych = $YYBUFFER[++$YYCURSOR];
109 14
				if ($this->_SCAN_AZ[$yych]) {
110 14
					$value .= $yych;
111 14
					$yych = $YYBUFFER[++$YYCURSOR];
112 14
					while (isset($this->_SCAN_AZ_09[$yych])) {
113 14
						$value .= $yych;
114 14
						$yych = $YYBUFFER[++$YYCURSOR];
115 14
					}
116 14
				}
117 14
				$match_2 = $value; $value = '';
118 14
			}
119 14 View Code Duplication
			if ($yych === '.') {
120
				$yych = $YYBUFFER[++$YYCURSOR];
121
				if ($this->_SCAN_AZ[$yych]) {
122
					$value .= $yych;
123
					$yych = $YYBUFFER[++$YYCURSOR];
124
					while (isset($this->_SCAN_AZ_09[$yych])) {
125
						$value .= $yych;
126
						$yych = $YYBUFFER[++$YYCURSOR];
127
					}
128
				}
129
				$match_3 = $value; $value = '';
0 ignored issues
show
Unused Code introduced by
$value is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
130
			}
131
132 14
		}
133
134
135 14
		if($match_1) {
136 14
			if (!$match_2) {
0 ignored issues
show
Bug introduced by
The variable $match_2 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
137
				/* default table is 'object' */
138 12
				$match_2 = $match_1;
0 ignored issues
show
Bug introduced by
The variable $match_1 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
139 12
				$match_1 = "object";
140 12
			}
141 14
			$node["id"]="ident";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$node was never initialized. Although not strictly required by PHP, it is generally a good practice to add $node = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
142
143 14
			$table=$match_1;
144 14
			$field=$match_2;
145 14
			if ($table=="object") {
146
				switch ($field) {
147 12
					case "implements":
148
						$node["id"]="implements";
149
					break;
150 12
					case "path":
151 12
					case "parent":
152 12
					case "priority":
153
						$node["table"]="nodes";
154
						$node["field"]=$field;
155
					break;
156 12
					default:
157 12
						$node["table"]="objects";
158 12
						$node["field"]=$field;
159 12
				}
160 12
			} else
161 14
			if ($table === "my") {
162
				$node["id"] = "custom";
163
				if ($match_3) {
164
					$node["nls"] = $field;
165
					$field = $match_3;
0 ignored issues
show
Bug introduced by
The variable $match_3 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
166
				}
167
				$node["field"] = $field;
168
				$node["record_id"] = $record_id;
0 ignored issues
show
Bug introduced by
The variable $record_id does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
169
			} else {
170 14
				$node["id"]="property";
171 14
				if ($match_3) {
172
					$node["nls"] = $field;
173
					$field = $match_3;
174
				}
175 14
				$node["table"]="prop_".$table;
176 14
				$node["field"]="AR_".$field;
177 14
				$node["record_id"] = $record_id;
178
			}
179 14
		}
180 14
		$YYBUFFER = substr($YYBUFFER, $YYCURSOR);
181 14
		return $node;
0 ignored issues
show
Bug introduced by
The variable $node does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
182
	}
183
184 14
	protected function parse_cmp_expr(&$YYBUFFER) {
185 14
		$result=$this->parse_ident($YYBUFFER);
186 14
		if ($result) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type array<string,string> 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...
187 14
			$YYCURSOR = 0;
188 14
			while (isset($this->_SCAN_WS[$YYBUFFER[$YYCURSOR]])) {
189 2
				$YYCURSOR++;
190 2
			}
191 14
			$yych = $YYBUFFER[$YYCURSOR];
192 14
			$YYCURSOR_START = $YYCURSOR;
193 14
			$RULES = &$this->_SCAN_CMP;
194 14
			while (isset($RULES[$yych])) {
195 14
				$RULES = &$RULES[$yych];
196 14
				if (isset($RULES['FIN'])) {
197 14
					$YYMATCH = $YYCURSOR;
198 14
				}
199 14
				$yych = $YYBUFFER[++$YYCURSOR];
200 14
			}
201 14
			if (isset($YYMATCH)) {
202 14
					$node["id"]="cmp";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$node was never initialized. Although not strictly required by PHP, it is generally a good practice to add $node = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
203 14
					$node["operator"]=substr($YYBUFFER, $YYCURSOR_START, ($YYMATCH + 1) - $YYCURSOR_START);
204 14
					$node["left"]=$result;
205 14
					$YYBUFFER = substr($YYBUFFER, $YYCURSOR);
206 14
					$result=$this->parse_const($YYBUFFER);
207 14
					if ($result) {
208 14
						$node["right"]=$result;
209 14
					}
210 14
					$result=$node;
211 14
			} else {
212
				$this->error="unknow compare-operator near '$YYBUFFER'";
213
			}
214 14
		}
215 14
		return $result;
216
	}
217
218 14
	protected function parse_group_expr(&$YYBUFFER) {
219 14
		$YYCURSOR = 0;
220 14
		while (isset($this->_SCAN_WS[$YYBUFFER[$YYCURSOR]])) {
221
			$YYCURSOR++;
222
		}
223 14
		$yych = $YYBUFFER[$YYCURSOR++];
224 14
		if ($yych === '(') {
225
			$YYBUFFER = substr($YYBUFFER, $YYCURSOR);
226
			$result = $this->parse_or_expr($YYBUFFER);
227
			$YYCURSOR = 0;
228
			while (isset($this->_SCAN_WS[$YYBUFFER[$YYCURSOR]])) {
229
				$YYCURSOR++;
230
			}
231
			$yych = $YYBUFFER[$YYCURSOR++];
232
			if ($yych === ')') {
233
				$YYBUFFER = substr($YYBUFFER, $YYCURSOR);
234
				$node["id"]="group";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$node was never initialized. Although not strictly required by PHP, it is generally a good practice to add $node = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
235
				$node["left"]=$result;
236
				$result=$node;
237
			} else {
238
				unset($result);
239
				$this->error = "missing closing group sign near '$YYBUFFER'";
240
			}
241
		} else {
242 14
			$result = $this->parse_cmp_expr($YYBUFFER);
243
		}
244 14
		return $result;
245
	}
246
247 14 View Code Duplication
	protected function parse_and_expr(&$YYBUFFER) {
248 14
		$result=$this->parse_group_expr($YYBUFFER);
249 14
		while (is_array($result)) {
250 14
			$YYCURSOR = 0;
251 14
			while (isset($this->_SCAN_WS[$YYBUFFER[$YYCURSOR]])) {
252 12
				$YYCURSOR++;
253 12
			}
254 14
			$ident = strtolower(substr($YYBUFFER, $YYCURSOR, 3));
255 14
			if ($ident === 'and' && !isset($this->_SCAN_AZ_09[$YYBUFFER[$YYCURSOR + 3]]) ) {
256
				$YYBUFFER = substr($YYBUFFER, $YYCURSOR + 3);
257
				$right = $this->parse_group_expr($YYBUFFER);
258
				if (is_array($right)) {
259
					$result = array(
260
						'id' => $ident,
261
						'left' => $result,
262
						'right' => $right
263
					);
264
				} else {
265
					unset($result);
266
				}
267
			} else {
268 14
				break;
269
			}
270
		}
271 14
		return $result;
272
	}
273
274 14 View Code Duplication
	protected function parse_or_expr(&$YYBUFFER) {
275 14
		$result=$this->parse_and_expr($YYBUFFER);
276 14
		while (is_array($result)) {
277 14
			$YYCURSOR = 0;
278 14
			while (isset($this->_SCAN_WS[$YYBUFFER[$YYCURSOR]])) {
279 12
				$YYCURSOR++;
280 12
			}
281 14
			$ident = strtolower(substr($YYBUFFER, $YYCURSOR, 2));
282 14
			if ($ident === 'or' && !isset($this->_SCAN_AZ_09[$YYBUFFER[$YYCURSOR + 2]]) ) {
283
				$YYBUFFER = substr($YYBUFFER, $YYCURSOR + 2);
284
				$right = $this->parse_and_expr($YYBUFFER);
285
				if (is_array($right)) {
286
					$result = array(
287
						'id' => $ident,
288
						'left' => $result,
289
						'right' => $right
290
					);
291
				} else {
292
					unset($result);
293
				}
294
			} else {
295 14
				break;
296
			}
297
		}
298 14
		return $result;
299
	}
300
301 14
	protected function parse_orderby(&$YYBUFFER) {
302 12
		$field = $this->parse_ident($YYBUFFER);
303
304 12
		$YYCURSOR = 0;
305 14
		while (isset($this->_SCAN_WS[$YYBUFFER[$YYCURSOR]])) {
306
			$YYCURSOR++;
307
		}
308 12
		$value = '';
309 12
		$yych  = $YYBUFFER[$YYCURSOR];
310 12 View Code Duplication
		if ($this->_SCAN_AZ[$yych]) {
311
			$value .= $yych;
312
			$yych = $YYBUFFER[++$YYCURSOR];
313
			while (isset($this->_SCAN_AZ[$yych])) {
314
				$value .= $yych;
315
				$yych = $YYBUFFER[++$YYCURSOR];
316
			}
317
			$sort_type = strtoupper($value);
318
			if (!($sort_type == 'ASC' || $sort_type == 'DESC')) { // If sort type is anything else than ASC or DESC, it is not part of the order by.
319
				$sort_type = 'ASC';
320
				$YYCURSOR = $YYCURSOR - strlen($value);
321 14
				$value = '';
0 ignored issues
show
Unused Code introduced by
$value is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
322
			}
323
		} else {
324 12
			$sort_type = 'ASC';
325
		}
326 12
		while (is_array($field)) {
327
			$result = array(
328 12
				'id' => 'orderbyfield',
329 12
				'type' => $sort_type,
330 12
				'right' => $field,
331
				'left' => $result
0 ignored issues
show
Bug introduced by
The variable $result does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
332 12
			);
333 12
			while (isset($this->_SCAN_WS[$YYBUFFER[$YYCURSOR]])) {
334
				$YYCURSOR++;
335
			}
336 12
			$yych  = $YYBUFFER[$YYCURSOR];
337 12
			if ($yych !== ',') {
338 12
				$YYBUFFER = substr($YYBUFFER, $YYCURSOR);
339 12
				unset($field);
340 12
			} else {
341
				$YYBUFFER = substr($YYBUFFER, $YYCURSOR + 1);
342
				$field = $this->parse_ident($YYBUFFER);
343
				$YYCURSOR = 0;
344
				while (isset($this->_SCAN_WS[$YYBUFFER[$YYCURSOR]])) {
345 14
					$YYCURSOR++;
346
				}
347
				$value = '';
348
				$yych  = $YYBUFFER[$YYCURSOR];
349 14 View Code Duplication
				if ($this->_SCAN_AZ[$yych]) {
350
					$value .= $yych;
351
					$yych = $YYBUFFER[++$YYCURSOR];
352
					while (isset($this->_SCAN_AZ[$yych])) {
353
						$value .= $yych;
354
						$yych = $YYBUFFER[++$YYCURSOR];
355
					}
356
					$sort_type = strtoupper($value);
357
					if (!($sort_type == 'ASC' || $sort_type == 'DESC')) { // If sort type is anything else than ASC or DESC, it is not part of the order by.
358
						$sort_type = 'ASC';
359
						$YYCURSOR = $YYCURSOR - strlen($value);
360
						$value = '';
0 ignored issues
show
Unused Code introduced by
$value is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
361
					}
362
				} else {
363
					$sort_type = 'ASC';
364
				}
365
			}
366 12
		}
367 12
		return $result;
368
	}
369
370
371
	protected function parse_join_target_properties(&$query) {
372
		do {
373
			if (!preg_match('/^([a-z_][a-z0-9_]*)(:[a-z]+)?/i', $query, $regs)) {
374
				$this->error = "expected property name at '$query'";
375
				return false;
376
			}
377
			$this->join_target_properties["prop_".$regs[1]][$regs[2]] = true;
378
			$query = substr($query, strlen($regs[0]));
379
380
			if (!preg_match('/^[[:space:]]*,[[:space:]]*/', $query, $regs)) {
381
				return true;
382
			}
383
			$query = substr($query, strlen($regs[0]));
384
		} while(1);
385
	}
386
387 14
	protected function parse_query(&$query) {
388
389 14
		if (!preg_match('|^[[:space:]]*order[[:space:]]*by[[:space:]]+|i', $query, $regs)) {
390 14
			$result=$this->parse_or_expr($query);
391 14
		} else {
392
			$no_selection = true;
393
		}
394
395
/*
396
		$YYCURSOR = 0;
397
		while ($this->_SCAN_WS[$YYBUFFER[$YYCURSOR]]) {
398
			$YYCURSOR++;
399
		}
400
401
		$yych  = $YYBUFFER[$YYCURSOR];
402
		if ($this->_SCAN_AZ[$yych]) {
403
			$value = $yych;
404
			$yych  = $YYBUFFER[++$YYCURSOR];
405
			while ($this->_SCAN_AZ[$yych]) {
406
				$value .= $yych;
407
				$yych = $YYBUFFER[++$YYCURSOR];
408
			}
409
			$value = strtolower($value);
410
			if ($value === 'order') {
411
				while ($this->_SCAN_WS[$YYBUFFER[$YYCURSOR]]) {
412
					$YYCURSOR++;
413
				}
414
				$yych  = $YYBUFFER[$YYCURSOR];
415
				if ($this->_SCAN_AZ[$yych]) {
416
					$value = $yych;
417
					$yych  = $YYBUFFER[++$YYCURSOR];
418
					while ($this->_SCAN_AZ[$yych]) {
419
						$value .= $yych;
420
						$yych = $YYBUFFER[++$YYCURSOR];
421
					}
422
					$value = strtolower($value);
423
					if ($value === 'by') {
424
						$YYBUFFER = substr($YYBUFFER, $YYCURSOR;
425
						$result = $this->parse_or_expr($YYBUFFER);
426
						$YYCURSOR = 0;
427
						$value = '';
428
					} else {
429
						$this->error = "syntax error near: $YYBUFFER";
430
						return false;
431
					}
432
				}
433
			}
434
		}
435
436
*/
437
438 14
		if (preg_match('|^[[:space:]]*join[[:space:]]*target[[:space:]]*on[[:space:]]*|i', $query, $regs)) {
439
			$this->join_target_properties = array();
440
			$query = substr($query, strlen($regs[0]));
441
			$this->parse_join_target_properties($query);
442
		}
443
444 14
		$matching = preg_match('|^[[:space:]]*order[[:space:]]*by[[:space:]]+|i', $query, $regs);
445 14
		if ( $matching || $no_selection ) {
0 ignored issues
show
Bug introduced by
The variable $no_selection does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
446 12
			$query=substr($query, strlen($regs[0]));
447 12
			$node["id"]="orderby";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$node was never initialized. Although not strictly required by PHP, it is generally a good practice to add $node = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
448 12
			$node["right"]=$this->parse_orderby($query);
449 12
			$node["left"]=$result;
0 ignored issues
show
Bug introduced by
The variable $result does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
450 12
			$result=$node;
451 12
		}
452 14
		if (preg_match('|^[[:space:]]*limit[[:space:]]+([0-9]+)[[:space:]]*([,][[:space:]]*([0-9]+))?|i', $query, $regs)) {
453
			$query=substr($query, strlen($regs[0]));
454
			$limit_s["id"]="limit";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$limit_s was never initialized. Although not strictly required by PHP, it is generally a good practice to add $limit_s = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
455
			$limit_s["offset"]=$regs[1];
456
			$limit_s["limit"]=$regs[3];
457
		} else {
458 14
			$limit_s["id"]="limit";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$limit_s was never initialized. Although not strictly required by PHP, it is generally a good practice to add $limit_s = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
459 14
			$limit_s["offset"]=($this->offset) ? $this->offset : 0;
460 14
			$limit_s["limit"]=($this->limit) ? $this->limit : 0;
461
		}
462 14
		$limit_s["left"]=$result;
463 14
		$result=$limit_s;
464
465 14
		return $result;
466
	}
467
468
	// virtual (&private) method. To be implemented in the sql specific compiler
469
	protected abstract function priv_sql_compile($node) ;
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
470
471 14
	public function compile($path, $query, $limit=100, $offset=0, $layers = array()) {
472 14
		debug("sql_compiler::compile ($path, $query, $limit, $offset)", "store");
473 14
		$this->error="";
474 14
		$this->path = $path;
475
476 14
		$this->limit=$limit;
477 14
		$this->offset=$offset;
478 14
		$this->layers=$layers;
0 ignored issues
show
Bug introduced by
The property layers does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
479
480 14
		$tree=$this->parse_query($query);
481
482 14
		if ( $this->error ) {
483
			return null;
484 14
		} else if ( trim($query) ) {
485
			// no error detected, but there is still a part of the query left
486
			$this->error="unkown operator near '$query'";
487
			return null;
488 14
		} else if ( $tree ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $tree 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...
489 14
			$compiled_query=$this->priv_sql_compile($tree);
490 14
			return $compiled_query;
491
		} else {
492
			return null;
493
		}
494
495
	}
496
497
498
  }
499