Completed
Pull Request — master (#88)
by Deven
65:50
created

CaseExpression::build()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 32
Code Lines 21

Duplication

Lines 16
Ratio 50 %

Importance

Changes 0
Metric Value
cc 7
eloc 21
nc 8
nop 2
dl 16
loc 32
rs 6.7272
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Parses a reference to a CASE expression
5
 *
6
 * @package    SqlParser
7
 * @subpackage Components
8
 */
9
namespace SqlParser\Components;
10
11
use SqlParser\Context;
12
use SqlParser\Component;
13
use SqlParser\Parser;
14
use SqlParser\Token;
15
use SqlParser\TokensList;
16
17
18
/**
19
 * Parses a reference to a CASE expression
20
 *
21
 * @category   Components
22
 * @package    SqlParser
23
 * @subpackage Components
24
 * @author     Deven Bansod <[email protected]>
25
 * @license    http://opensource.org/licenses/GPL-2.0 GNU Public License
26
 */
27
class CaseExpression extends Component
28
{
29
30
    /**
31
     * The value to be compared
32
     *
33
     * @var Expression
34
     */
35
    public $value;
36
37
    /**
38
     * The conditions in WHEN clauses
39
     *
40
     * @var array
41
     */
42
    public $conditions;
43
44
    /**
45
     * The results matching with the WHEN clauses
46
     *
47
     * @var array
48
     */
49
    public $results;
50
51
    /**
52
     * The values to be compared against
53
     *
54
     * @var array
55
     */
56
    public $compare_values;
57
58
    /**
59
     * The result in ELSE section of expr
60
     *
61
     * @var array
62
     */
63
    public $else_result;
64
65
    /**
66
     * Constructor.
67
     *
68
     */
69
    public function __construct()
70
    {
71
    }
72
73
    /**
74
     *
75
     * @param Parser     $parser  The parser that serves as context.
76
     * @param TokensList $list    The list of tokens that are being parsed.
77
     *
78
     * @return Expression
0 ignored issues
show
Documentation introduced by
Should the return type not be CaseExpression?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
79
     */
80
    public static function parse(Parser $parser, TokensList $list)
81
    {
82
        $ret = new CaseExpression();
83
84
        /**
85
         * State of parser
86
         *
87
         * @var int $parser
88
         */
89
        $state = 0;
90
91
        /**
92
         * Syntax type (type 0 or type 1)
93
         *
94
         * @var int $type
95
         */
96
        $type = 0;
97
98
        ++$list->idx; // Skip 'CASE'
99
100
        for (; $list->idx < $list->count; ++$list->idx) {
101
102
            /**
103
             * Token parsed at this moment.
104
             *
105
             * @var Token $token
106
             */
107
            $token = $list->tokens[$list->idx];
108
109
            // End of statement.
110
            if ($token->type === Token::TYPE_DELIMITER) {
111
                break;
112
            }
113
114
            // Skipping whitespaces and comments.
115
            if (($token->type === Token::TYPE_WHITESPACE)
116
                || ($token->type === Token::TYPE_COMMENT)
117
            ) {
118
                continue;
119
            }
120
121
            if ($state === 0) {
122
                if ($token->type === Token::TYPE_KEYWORD
123
                    && $token->value === 'WHEN'
124
                ) {
125
                    ++$list->idx; // Skip 'WHEN'
126
                    $new_condition = Condition::parse($parser, $list);
0 ignored issues
show
Documentation introduced by
$parser is of type integer, but the function expects a object<SqlParser\Parser>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
127
                    $type = 1;
128
                    $state = 1;
129
                    $ret->conditions[] = $new_condition;
130
                } elseif ($token->type === Token::TYPE_KEYWORD
131
                    && $token->value === 'ELSE'
132
                ) {
133
                    ++$list->idx; // Skip 'ELSE'
134
                    $ret->else_result = Expression::parse($parser, $list);
0 ignored issues
show
Documentation Bug introduced by
It seems like \SqlParser\Components\Ex...::parse($parser, $list) of type object<SqlParser\Components\Expression> or null is incompatible with the declared type array of property $else_result.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
Documentation introduced by
$parser is of type integer, but the function expects a object<SqlParser\Parser>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
135
                    $state = 0; // last clause of CASE expression
136
                } elseif ($token->type === Token::TYPE_KEYWORD
137
                    && ($token->value === 'END'
138
                    || $token->value === 'end')
139
                ) {
140
                    $state = 3; // end of CASE expression
141
                    ++$list->idx;
142
                    break;
143
                } elseif ($token->type === Token::TYPE_KEYWORD) {
144
                    $parser->error(__('Unexpected keyword.'), $token);
0 ignored issues
show
Bug introduced by
The method error cannot be called on $parser (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
145
                    break;
146
                } else {
147
                    $ret->value = Expression::parse($parser, $list);
0 ignored issues
show
Documentation introduced by
$parser is of type integer, but the function expects a object<SqlParser\Parser>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
148
                    $type = 0;
149
                    $state = 1;
150
                }
151
            } elseif ($state === 1) {
152
                if ($type === 0) {
153
                    if ($token->type === Token::TYPE_KEYWORD
154
                        && $token->value === 'WHEN'
155
                    ) {
156
                        ++$list->idx; // Skip 'WHEN'
157
                        $new_value = Expression::parse($parser, $list);
0 ignored issues
show
Documentation introduced by
$parser is of type integer, but the function expects a object<SqlParser\Parser>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
158
                        $state = 2;
159
                        $ret->compare_values[] = $new_value;
160
                    } elseif ($token->type === Token::TYPE_KEYWORD
161
                        && $token->value === 'ELSE'
162
                    ) {
163
                        ++$list->idx; // Skip 'ELSE'
164
                        $ret->else_result = Expression::parse($parser, $list);
0 ignored issues
show
Documentation introduced by
$parser is of type integer, but the function expects a object<SqlParser\Parser>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
165
                        $state = 0; // last clause of CASE expression
166
                    } elseif ($token->type === Token::TYPE_KEYWORD
167
                        && ($token->value === 'END'
168
                        || $token->value === 'end')
169
                    ) {
170
                        $state = 3; // end of CASE expression
171
                        ++$list->idx;
172
                        break;
173
                    } elseif ($token->type === Token::TYPE_KEYWORD) {
174
                        $parser->error(__('Unexpected keyword.'), $token);
0 ignored issues
show
Bug introduced by
The method error cannot be called on $parser (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
175
                        break;
176
                    } else {
177
                        $parser->error(__('Unexpected token.'), $token);
0 ignored issues
show
Bug introduced by
The method error cannot be called on $parser (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
178
                        break;
179
                    }
180 View Code Duplication
                } else {
181
                    if ($token->type === Token::TYPE_KEYWORD
182
                        && $token->value === 'THEN'
183
                    ) {
184
                        ++$list->idx; // Skip 'THEN'
185
                        $new_result = Expression::parse($parser, $list);
0 ignored issues
show
Documentation introduced by
$parser is of type integer, but the function expects a object<SqlParser\Parser>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
186
                        $state = 0;
187
                        $ret->results[] = $new_result;
188
                    } elseif ($token->type === Token::TYPE_KEYWORD) {
189
                        $parser->error(__('Unexpected keyword.'), $token);
0 ignored issues
show
Bug introduced by
The method error cannot be called on $parser (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
190
                        break;
191
                    } else {
192
                        $parser->error(__('Unexpected token.'), $token);
0 ignored issues
show
Bug introduced by
The method error cannot be called on $parser (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
193
                        break;
194
                    }
195
                }
196
            } elseif ($state === 2) {
197 View Code Duplication
                if ($type === 0) {
198
                    if ($token->type === Token::TYPE_KEYWORD
199
                        && $token->value === 'THEN'
200
                    ) {
201
                        ++$list->idx; // Skip 'THEN'
202
                        $new_result = Expression::parse($parser, $list);
0 ignored issues
show
Documentation introduced by
$parser is of type integer, but the function expects a object<SqlParser\Parser>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
203
                        $ret->results[] = $new_result;
204
                        $state = 1;
205
                    } elseif ($token->type === Token::TYPE_KEYWORD) {
206
                        $parser->error(__('Unexpected keyword.'), $token);
0 ignored issues
show
Bug introduced by
The method error cannot be called on $parser (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
207
                        break;
208
                    } else {
209
                        $parser->error(__('Unexpected token.'), $token);
0 ignored issues
show
Bug introduced by
The method error cannot be called on $parser (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
210
                        break;
211
                    }
212
                }
213
            }
214
        }
215
216
        if ($state !== 3) {
217
            $parser->error(
0 ignored issues
show
Bug introduced by
The method error cannot be called on $parser (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
218
                __('Unexpected end of CASE expression'),
219
                $list->tokens[$list->idx - 1]
220
            );
221
        }
222
223
        --$list->idx;
224
        return $ret;
225
    }
226
227
    /**
228
     * @param Expression $component The component to be built.
229
     * @param array      $options   Parameters for building.
230
     *
231
     * @return string
232
     */
233
    public static function build($component, array $options = array())
234
    {
235
        $ret = 'CASE ';
236
        if (isset($component->value)) {
237
            // Syntax type 0
238
            $ret .= $component->value . ' ';
0 ignored issues
show
Bug introduced by
The property value does not seem to exist in SqlParser\Components\Expression.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
239 View Code Duplication
            for (
240
                $i = 0;
241
                $i < count($component->compare_values) && $i < count($component->results);
0 ignored issues
show
Bug introduced by
The property compare_values does not seem to exist in SqlParser\Components\Expression.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
Bug introduced by
The property results does not seem to exist in SqlParser\Components\Expression.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
242
                $i++
243
            ) {
244
                $ret .= 'WHEN ' . $component->compare_values[$i] . ' ';
245
                $ret .= 'THEN ' . $component->results[$i] . ' ';
246
            }
247
        } else {
248
            // Syntax type 1
249 View Code Duplication
            for (
250
                $i = 0;
251
                $i < count($component->conditions) && $i < count($component->results);
0 ignored issues
show
Bug introduced by
The property conditions does not seem to exist in SqlParser\Components\Expression.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
252
                $i++
253
            ) {
254
                $ret .= 'WHEN ' . Condition::build($component->conditions[$i]) . ' ';
255
                $ret .= 'THEN ' . $component->results[$i] . ' ';
256
            }
257
        }
258
        if (isset($component->else_result)) {
259
            $ret .= 'ELSE ' . $component->else_result . ' ';
0 ignored issues
show
Bug introduced by
The property else_result does not seem to exist in SqlParser\Components\Expression.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
260
        }
261
        $ret .= 'END';
262
263
        return $ret;
264
    }
265
}
266