Completed
Pull Request — master (#88)
by Deven
184:10 queued 119:09
created

CaseExpression::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
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
 * @license    http://opensource.org/licenses/GPL-2.0 GNU Public License
25
 */
26
class CaseExpression extends Component
27
{
28
29
    /**
30
     * The value to be compared
31
     *
32
     * @var Expression
33
     */
34
    public $value;
35
36
    /**
37
     * The conditions in WHEN clauses
38
     *
39
     * @var array
40
     */
41
    public $conditions;
42
43
    /**
44
     * The results matching with the WHEN clauses
45
     *
46
     * @var array
47
     */
48
    public $results;
49
50
    /**
51
     * The values to be compared against
52
     *
53
     * @var array
54
     */
55
    public $compare_values;
56
57
    /**
58
     * The result in ELSE section of expr
59
     *
60
     * @var array
61
     */
62
    public $else_result;
63
64
    /**
65
     * Constructor.
66
     *
67
     */
68
    public function __construct()
69
    {
70
    }
71
72
    /**
73
     *
74
     * @param Parser     $parser  The parser that serves as context.
75
     * @param TokensList $list    The list of tokens that are being parsed.
76
     *
77
     * @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...
78
     */
79
    public static function parse(Parser $parser, TokensList $list, array $options = array())
80
    {
81
        $ret = new CaseExpression();
82
83
        /**
84
         * State of parser
85
         *
86
         * @var int $parser
87
         */
88
        $state = 0;
89
90
        /**
91
         * Syntax type (type 0 or type 1)
92
         *
93
         * @var int $type
94
         */
95
        $type = 0;
96
97
        ++$list->idx; // Skip 'CASE'
98
99
        for (; $list->idx < $list->count; ++$list->idx) {
100
101
            /**
102
             * Token parsed at this moment.
103
             *
104
             * @var Token $token
105
             */
106
            $token = $list->tokens[$list->idx];
107
108
            // End of statement.
109
            if ($token->type === Token::TYPE_DELIMITER) {
110
                break;
111
            }
112
113
            // Skipping whitespaces and comments.
114
            if (($token->type === Token::TYPE_WHITESPACE)
115
                || ($token->type === Token::TYPE_COMMENT)
116
            ) {
117
                continue;
118
            }
119
120
            if ($state === 0) {
121
                if ($token->type === Token::TYPE_KEYWORD
122
                    && $token->value === 'WHEN'
123
                ) {
124
                    ++$list->idx; // Skip 'WHEN'
125
                    $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...
126
                    $type = 1;
127
                    $state = 1;
128
                    $ret->conditions[] = $new_condition;
129
                } elseif ($token->type === Token::TYPE_KEYWORD
130
                    && $token->value === 'ELSE'
131
                ) {
132
                    ++$list->idx; // Skip 'ELSE'
133
                    $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...
134
                    $state = 0; // last clause of CASE expression
135
                } elseif ($token->type === Token::TYPE_KEYWORD
136
                    && ($token->value === 'END'
137
                    || $token->value === 'end')
138
                ) {
139
                    $state = 3; // end of CASE expression
140
                    ++$list->idx;
141
                    break;
142
                } elseif ($token->type === Token::TYPE_KEYWORD) {
143
                    $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...
144
                    break;
145
                } else {
146
                    $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...
147
                    $type = 0;
148
                    $state = 1;
149
                }
150
            } elseif ($state === 1) {
151
                if ($type === 0) {
152
                    if ($token->type === Token::TYPE_KEYWORD
153
                        && $token->value === 'WHEN'
154
                    ) {
155
                        ++$list->idx; // Skip 'WHEN'
156
                        $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...
157
                        $state = 2;
158
                        $ret->compare_values[] = $new_value;
159
                    } elseif ($token->type === Token::TYPE_KEYWORD
160
                        && $token->value === 'ELSE'
161
                    ) {
162
                        ++$list->idx; // Skip 'ELSE'
163
                        $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...
164
                        $state = 0; // last clause of CASE expression
165
                    } elseif ($token->type === Token::TYPE_KEYWORD
166
                        && ($token->value === 'END'
167
                        || $token->value === 'end')
168
                    ) {
169
                        $state = 3; // end of CASE expression
170
                        ++$list->idx;
171
                        break;
172
                    } elseif ($token->type === Token::TYPE_KEYWORD) {
173
                        $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...
174
                        break;
175
                    } else {
176
                        $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...
177
                        break;
178
                    }
179 View Code Duplication
                } else {
180
                    if ($token->type === Token::TYPE_KEYWORD
181
                        && $token->value === 'THEN'
182
                    ) {
183
                        ++$list->idx; // Skip 'THEN'
184
                        $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...
185
                        $state = 0;
186
                        $ret->results[] = $new_result;
187
                    } elseif ($token->type === Token::TYPE_KEYWORD) {
188
                        $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...
189
                        break;
190
                    } else {
191
                        $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...
192
                        break;
193
                    }
194
                }
195
            } elseif ($state === 2) {
196 View Code Duplication
                if ($type === 0) {
197
                    if ($token->type === Token::TYPE_KEYWORD
198
                        && $token->value === 'THEN'
199
                    ) {
200
                        ++$list->idx; // Skip 'THEN'
201
                        $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...
202
                        $ret->results[] = $new_result;
203
                        $state = 1;
204
                    } elseif ($token->type === Token::TYPE_KEYWORD) {
205
                        $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...
206
                        break;
207
                    } else {
208
                        $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...
209
                        break;
210
                    }
211
                }
212
            }
213
        }
214
215
        if ($state !== 3) {
216
            $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...
217
                __('Unexpected end of CASE expression'),
218
                $list->tokens[$list->idx - 1]
219
            );
220
        }
221
222
        --$list->idx;
223
        return $ret;
224
    }
225
226
    /**
227
     * @param Expression $component The component to be built.
228
     * @param array      $options   Parameters for building.
229
     *
230
     * @return string
231
     */
232
    public static function build($component, array $options = array())
233
    {
234
        $ret = 'CASE ';
235
        if (isset($component->value)) {
236
            // Syntax type 0
237
            $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...
238 View Code Duplication
            for (
239
                $i = 0;
240
                $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...
241
                $i++
242
            ) {
243
                $ret .= 'WHEN ' . $component->compare_values[$i] . ' ';
244
                $ret .= 'THEN ' . $component->results[$i] . ' ';
245
            }
246
        } else {
247
            // Syntax type 1
248 View Code Duplication
            for (
249
                $i = 0;
250
                $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...
251
                $i++
252
            ) {
253
                $ret .= 'WHEN ' . Condition::build($component->conditions[$i]) . ' ';
254
                $ret .= 'THEN ' . $component->results[$i] . ' ';
255
            }
256
        }
257
        if (isset($component->else_result)) {
258
            $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...
259
        }
260
        $ret .= 'END';
261
262
        return $ret;
263
    }
264
}
265