Completed
Pull Request — master (#125)
by Robbert
61:23 queued 48:44
created

postgresql_compiler::compile_tree()   D

Complexity

Conditions 63
Paths 177

Size

Total Lines 248
Code Lines 192

Duplication

Lines 148
Ratio 59.68 %

Code Coverage

Tests 62
CRAP Score 1556.8008

Importance

Changes 0
Metric Value
cc 63
eloc 192
nc 177
nop 1
dl 148
loc 248
ccs 62
cts 223
cp 0.278
crap 1556.8008
rs 4
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
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 4 and the first side effect is on line 2.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
include($this->code."stores/modules/sql_compiler.php");
3
4
class postgresql_compiler extends sql_compiler {
5
	protected $tbl_prefix;
6
	protected $in_orderby;
7
	protected $nls_join;
8
	protected $select_tables;
9
	protected $used_tables;
10
	protected $custom_id;
11
	protected $custom_ref;
12
	protected $used_custom_fields;
13
	protected $where_s_ext;
14
	protected $where_s;
15
	protected $limit_s;
16
	protected $orderby_s;
17
	protected $select_list;
18
19 28
	function __construct(&$store, $tbl_prefix="") {
20 28
		debug("postgresql_compiler($tbl_prefix)", "store");
21 28
		$this->tbl_prefix=$tbl_prefix;
22 28
		$this->store=$store;
23 28
	}
24
25 28
	function test_for_lowercase(&$node){
26 28
		$ret = false;
27 28
		switch ((string)$node["id"]) {
28 28
			case 'ident':
29
				if ( $node["table"] == "nodes" ) {
30
					if ( $node["field"] == "path" or $node["field"] == "parent" ) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
31
						$ret = true;
32
					}
33
				}
34
				break;
35
		}
36 28
		return $ret;
37
	}
38
39 28
	function compile_tree(&$node) {
40 28
		switch ((string)$node["id"]) {
41 28
			case 'property':
42 28
				$table=$this->tbl_prefix.$node["table"];
43 28
				$field=$node["field"];
44 28
				$record_id=$node["record_id"];
45 28
				if (!$record_id) {
46 28
					if (!$this->in_orderby) {
47 28
						$result=" $table.object = ".$this->tbl_prefix."objects.id and $table.$field ";
48 28
						$this->used_tables[$table]=$table;
49 14 View Code Duplication
					} else {
50
						if ($this->in_orderby && $node["nls"]) {
51
							/*
52
								we do a left join so that we will also find non
53
								matching objects
54
							*/
55
							$objects_table = $this->tbl_prefix."objects";
56
							$this->nls_join[$table] = "left join $table as order_$table on $objects_table.id=order_$table.object and order_$table.AR_nls='".$node["nls"]."' ";
57
58
							$result = " order_$table.$field ";
59
							$this->select_list["order_".$table.".".$field] = "order_$table.$field";
60
61
						} else {
62
							/*
63
								if we are parsing 'orderby' properties we have
64
								to join our tables for the whole query
65
							*/
66
							$this->select_tables[$table]=$table;
67
							$this->used_tables[$table]=$table;
68 14
							$result=" $table.$field ";
69
						}
70
					}
71 14
				} else {
72
					$this->used_tables["$table as $table$record_id"] = $table.$record_id;
73
					if (!$this->in_orderby) {
74
						$result=" $table$record_id.object = ".$this->tbl_prefix."objects.id and $table$record_id.$field ";
75
					} else {
76
						$this->select_tables["$table as $table$record_id"] = $table.$record_id;
77
						$result=" $table$record_id.$field ";
78
					}
79
				}
80 28
			break;
81 28 View Code Duplication
			case 'ident':
82
				$table=$this->tbl_prefix.$node["table"];
83
				$field=$node["field"];
84
				$this->used_tables[$table]=$table;
85
				$result=" $table.$field ";
86
			break;
87 28 View Code Duplication
			case 'custom':
88
				$table = $this->tbl_prefix."prop_custom";
89
				$field = $node["field"];
90
				$nls = $node["nls"];
91
				$record_id = $node["record_id"];
92
				/*
93
					when we are compiling orderby properties we always want
94
					to assign it to a new table alias
95
				*/
96
				if ($this->in_orderby) {
97
					$this->custom_id++;
98
				}
99
				$this->custom_ref++;
100
				if (!$record_id) {
101
					$this->used_tables[$table." as $table".$this->custom_id] = $table.$this->custom_id;
102
					$this->select_tables[$table." as $table".$this->custom_id] = 1;
103
104
					$this->used_custom_fields[$field] = true;
105
					$result = " $table".$this->custom_id.".AR_name = '$field' ";
106
					if ($nls) {
107
						$result = " $result and $table".$this->custom_id.".AR_nls = '$nls' ";
108
					}
109
110
					if (!$this->in_orderby) {
111
						$result = " $result and $table".$this->custom_id.".AR_value ";
112
					} else {
113
						$this->where_s_ext = $result;
114
						$result = " $table".$this->custom_id.".AR_value ";
115
					}
116
				} else {
117
					$this->used_tables["$table as $table$record_id"] = $table.$record_id;
118
			//		$this->select_tables[$table." as $table$record_id"] = 1;
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
119
120
					$result = " $table$record_id.AR_name = '$field' ";
121
					if (!$this->in_orderby ) {
122
						if ($this->join_target_properties["prop_my"][":$record_id"]) {
123
							$result=" $result and $table$record_id.object = target.object and $table$record_id.AR_value ";
124
						} else {
125
							$result=" $table$record_id.object = ".$this->tbl_prefix."objects.id and $table$record_id.AR_value ";
126
						}
127
					} else {
128
						if ($this->join_target_properties[$node["table"]]) {
129
							$this->join_target_properties["$table as $table$record_id"] = $table.$record_id;
130
						}
131
						$this->select_tables["$table as $table$record_id"] = $table.$record_id;
132
						$result=" $table$record_id.AR_value ";
133
					}
134
				}
135
			break;
136 28
			case 'string':
137 28
				$result=" '".pg_escape_string($node["value"])."' ";
138 28
			break;
139 28
			case 'float':
140 28
			case 'int':
141
				$result=" ".$node["value"]." ";
142
			break;
143 28 View Code Duplication
			case 'and':
144
				$cr = $this->custom_ref;
145
				$left=$this->compile_tree($node["left"]);
146
				if ($this->custom_ref > $cr) {
147
					$this->custom_id++;
148
				}
149
150
				$right=$this->compile_tree($node["right"]);
151
				$cr = $this->custom_ref;
152
				if ($this->custom_ref > $cr) {
153
					$this->custom_id++;
154
				}
155
				$result=" $left and $right ";
156
			break;
157 28 View Code Duplication
			case 'or':
158
				$left=$this->compile_tree($node["left"]);
159
				$right=$this->compile_tree($node["right"]);
160
				$result=" $left or $right ";
161
			break;
162 28
			case 'cmp':
163 28
				$not = '';
164 28
				switch ($node["operator"]) {
165 28
					case '=':
166 14
					case '==':
167 28
						$operator="=";
168 28
					break;
169
					case '!=':
170
					case '<=':
171
					case '>=':
172
					case '<':
173
					case '>':
174
						$operator=$node["operator"];
175
					break;
176
					case '!~':
177
					case '!~~':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
178
						$not="NOT ";
179
 					case '~=':
180
					case '=~':
181 View Code Duplication
					case '=~~':
182
						if (!strlen($node["operator"])==3) {
183
							$not.="I";
184
						}
185
						$operator=$not."LIKE";
186
					break;
187
					case '!/':
188
					case '!//':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
189
						$not="!";
190
					case '=/':
191 View Code Duplication
					case '=//':
192
						$operator=$not."~";
193
						if (strlen($node["operator"])==3) {
194
							$operator.="*";
195
						}
196
						break;
197 14
				}
198 28
				if ($node["left"]["id"]!=="implements") {
199 28
					$left=$this->compile_tree($node["left"]);
200 28
					$right=$this->compile_tree($node["right"]);
201 28
					if($this->test_for_lowercase($node["left"])){
202
						// lowercase compile
203
						$result=" lower($left) $operator lower($right) ";
0 ignored issues
show
Bug introduced by
The variable $operator 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...
204
					} else {
205
						// normal compile
206
						/* lastchanged == unixtimestamp -> lastchanged == 200201.. */
207 28
						if ($node["left"]["field"]=="lastchanged") {
208
							$right = "to_timestamp($right)";
209
						}
210 28
						$result=" $left $operator $right ";
211
					}
212 14
				} else {
213
					$table=$this->tbl_prefix."types";
214
					$type=$this->compile_tree($node["right"]);
215
					switch ($operator) {
216 View Code Duplication
						case '!=':
217
							$result=" (".$this->tbl_prefix."objects.type not in (select type from ".$this->tbl_prefix."types where implements = $type )) ";
218
						break;
219
						default:
220
							$this->used_tables[$table]=$table;
221
							$result=" (".$this->tbl_prefix."types.implements $operator $type and ".$this->tbl_prefix."objects.vtype = ".$this->tbl_prefix."types.type ) ";
222
						break;
223
					}
224
				}
225 28
			break;
226 28 View Code Duplication
			case 'group':
227
				$left=$this->compile_tree($node["left"]);
228
				if ($left) {
229
					$result=" ( $left ) ";
230
				}
231
			break;
232
233 28 View Code Duplication
			case 'orderby':
234 24
				$result=$this->compile_tree($node["left"]);
235 24
				$this->orderby_s=$this->compile_tree($node["right"]);
236 24
			break;
237
238 28
			case 'orderbyfield':
239 24
				$this->in_orderby = true;
240 24
				$left=$this->compile_tree($node["left"]);
241 24
				if ( $node["right"]["field"] != "none" ) {
242
					$right=$this->compile_tree($node["right"]);
243
					if ($left) {
244
						$result=" $left ,  $right ".$node["type"]." ";
245 View Code Duplication
						if($node["left"]['id'] == 'property' && !$node["right"]['nls']){
246
							$lefttablefield = $this->tbl_prefix.$node["left"]['table'].".".$node["left"]['field'];
247
							$this->select_list[$lefttablefield] = $lefttablefield;
248
						}
249
					} else {
250
						$result=" $right ".$node["type"]." ";
251
					}
252 View Code Duplication
					if($node["right"]['id'] == 'property' && !$node["right"]['nls']){
253
						$righttablefield = $this->tbl_prefix.$node["right"]['table'].".".$node["right"]['field'];
254
						$this->select_list[$righttablefield] = $righttablefield;
255
					}
256
				} else {
257 24
					$result = "";
258 24
					if ($left) {
259
						$result = " $left ";
260 View Code Duplication
						if($node["left"]['id'] == 'property' && !$node["right"]['nls']){
261
							$lefttablefield = $this->tbl_prefix.$node["left"]['table'].".".$node["left"]['field'];
262
							$this->select_list[$lefttablefield] = $lefttablefield;
263
						}
264
					}
265 24
					$this->skipDefaultOrderBy = true;
266
				}
267 24
			break;
268
269 28 View Code Duplication
			case 'limit':
270 28
				$this->where_s=$this->compile_tree($node["left"]);
271 28
				$this->limit_s="";
272 28
				if ($node["limit"]) {
273 4
					$this->limit_s=" offset ".(int)$node["offset"]." limit ".$node["limit"]." ";
274 2
				} else
275 24
				if ($node["offset"]) {
276
					$this->limit_s=" limit ".(int)$node["offset"]." ";
277
				} else {
278 24
					if ($this->limit) {
279
						$offset = (int)$this->offset;
280
						$this->limit_s=" offset $offset limit ".(int)$this->limit." ";
281
					}
282
				}
283 28
			break;
284
		}
285 28
		return $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...
286
	}
287
288
	// postgresql specific compiler function
289 28
	function priv_sql_compile($tree) {
290 28
		$this->custom_ref = 0;
291 28
		$this->custom_id = 0;
292 28
		$this->used_tables="";
293 28
		$this->compile_tree($tree);
294
295 28
		if ( $this->error ) {
296
			return null;
297
		}
298
299 28
		$nodes=$this->tbl_prefix."nodes";
300 28
		$objects=$this->tbl_prefix."objects";
301 28
		$this->used_tables[$nodes]=$nodes;
302 28
		$this->used_tables[$objects]=$objects;
303 28
		@reset($this->used_tables);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
304 28
		while (list($key, $val)=each($this->used_tables)) {
305 28
			if ($tables) {
306 28
				$tables.=", $key";
0 ignored issues
show
Bug introduced by
The variable $tables 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...
307 14
			} else {
308 28
				$tables="$key";
309
			}
310 28
			if ($this->select_tables[$key]) {
311
				$prop_dep.=" and $val.object=$objects.id ";
0 ignored issues
show
Bug introduced by
The variable $prop_dep 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...
312
			}
313 14
		}
314 28
		if (is_array($this->nls_join)) {
315
			$join = join($this->nls_join);
316
		}
317 28
		if(is_array($this->select_list)){
318
			$select = join(", ", $this->select_list);
319
		}
320
321 28
		$query ="where $nodes.object=$objects.id $prop_dep";
322 28
		$query.=" and $nodes.path like '".str_replace('_','\\_',pg_escape_string($this->path))."%' ";
323 28
		if ($this->where_s) {
324 28
			$query.=" and ( $this->where_s ) ";
325 14
		}
326 28
		if ($this->where_s_ext) {
327
			$query .= " and ($this->where_s_ext) ";
328
		}
329 28
		$order = '';
330 28
		if ($this->orderby_s) {
331 View Code Duplication
			if ($this->skipDefaultOrderBy) {
332
				$order .= "order by $this->orderby_s";
333
			} else {
334
				$order .= "order by $this->orderby_s, $nodes.parent ASC, $nodes.priority DESC, $nodes.path ASC ";
335
			}
336 28
		} else if (!$this->skipDefaultOrderBy) {
337 4
			$order .= "order by $nodes.parent ASC, $nodes.priority DESC, $nodes.path ASC ";
338 2
		}
339
340 28
		$order .= " $this->limit_s ";
341
342 28
		$select_query  = "select distinct($nodes.path), $nodes.parent, $nodes.priority, ";
343 28
		$select_query .= " $objects.id, $objects.type, $objects.object, date_part('epoch', $objects.lastchanged) as lastchanged, $objects.vtype ";
344
345 28
		if($select){
346
			$select_query .= ", " . $select;
0 ignored issues
show
Bug introduced by
The variable $select 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...
347
		}
348
349 28
		$select_query .= " from $tables $join $query $order";
0 ignored issues
show
Bug introduced by
The variable $join 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...
350 28
		$count_query = "select count(distinct($nodes.path)) as count from $tables ".$query;
351
352 28
		return Array("select_query" => $select_query, "count_query" => $count_query);
353
	}
354
355
  }
356