GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Failed Conditions
Push — master ( f2da15...888a68 )
by Charlotte
05:28
created

src/Commands/PromiseCommand.php (5 issues)

1
<?php
2
/**
3
 * Plasma Driver MySQL component
4
 * Copyright 2018 PlasmaPHP, All Rights Reserved
5
 *
6
 * Website: https://github.com/PlasmaPHP
7
 * License: https://github.com/PlasmaPHP/driver-mysql/blob/master/LICENSE
8
*/
9
10
namespace Plasma\Drivers\MySQL\Commands;
11
12
/**
13
 * Abstract command which has a promise.
14
 * @internal
15
 */
16
abstract class PromiseCommand implements CommandInterface {
17
    use \Evenement\EventEmitterTrait;
18
    
19
    /**
20
     * @var \Plasma\DriverInterface
21
     */
22
    protected $driver;
23
    
24
    /**
25
     * @var \React\Promise\Deferred
26
     */
27
    protected $deferred;
28
    
29
    /**
30
     * @var mixed
31
     */
32
    protected $resolveValue;
33
    
34
    /**
35
     * @var bool
36
     */
37
    protected $finished = false;
38
    
39
    /**
40
     * Constructor.
41
     * @param \Plasma\DriverInterface  $driver
42
     */
43
    function __construct(\Plasma\DriverInterface $driver) {
0 ignored issues
show
The parameter $driver is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

43
    function __construct(/** @scrutinizer ignore-unused */ \Plasma\DriverInterface $driver) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
44
        $this->deferred = new \React\Promise\Deferred();
45
        
46
        $this->once('error', function (\Throwable $error) {
47
            $this->deferred->reject($error);
48
        });
49
        
50
        $this->once('end', function () {
51
            $this->deferred->resolve($this->resolveValue);
52
        });
53
    }
54
    
55
    /**
56
     * Get the encoded message for writing to the database connection.
57
     * @return string
58
     */
59
    abstract function getEncodedMessage(): string;
60
    
61
    /**
62
     * Get the promise.
63
     * @var \React\Promise\PromiseInterface
64
     */
65
    function getPromise(): \React\Promise\PromiseInterface {
66
        return $this->deferred->promise();
67
    }
68
    
69
    /**
70
     * Sets the parser state, if necessary. If not, return `-1`.
71
     * @return int
72
     */
73
    function setParserState(): int {
74
        return -1;
75
    }
76
    
77
    /**
78
     * Sets the command as completed. This state gets reported back to the user.
79
     * @return void
80
     */
81
    function onComplete(): void {
82
        $this->finished = true;
83
        $this->emit('end');
84
    }
85
    
86
    /**
87
     * Sets the command as errored. This state gets reported back to the user.
88
     * @param \Throwable  $throwable
89
     * @return void
90
     */
91
    function onError(\Throwable $throwable): void {
92
        $this->finished = true;
93
        
94
        if($this->resolveValue !== null) {
95
            // Workaround for getting the promise resolved AFTER receiving and processing an error packet,
96
            // so we would miss the error packet
97
            $this->driver->getLoop()->futureTick(function () use ($throwable) {
98
                $this->emit('error', array($throwable));
99
            });
100
            
101
            return;
102
        }
103
        
104
        $this->emit('error', array($throwable));
105
    }
106
    
107
    /**
108
     * Sends the next received value into the command.
109
     * @param mixed  $value
110
     * @return void
111
     */
112
    abstract function onNext($value): void;
113
    
114
    /**
115
     * Whether the command has finished.
116
     * @return bool
117
     */
118
    function hasFinished(): bool {
119
        return $this->finished;
120
    }
121
    
122
    /**
123
     * Whether this command sets the connection as busy.
124
     * @return bool
125
     */
126
    function waitForCompletion(): bool {
127
        return true;
128
    }
129
    
130
    /**
131
     * Handles query commands on next caller.
132
     * @param \Plasma\Drivers\MySQL\ProtocolOnNextCaller  $value
133
     * @return void
134
     */
135
    function handleQueryOnNextCaller(\Plasma\Drivers\MySQL\ProtocolOnNextCaller $value): void {
136
        $buffer = $value->getBuffer();
137
        $parser = $value->getParser();
138
        
139
        if($this->resolveValue !== null) {
140
            $row = $this->parseResultsetRow($buffer);
141
            $this->emit('data', array($row));
142
        } else {
143
            $field = $this->handleQueryOnNextCallerColumns($buffer, $parser);
144
            if($field) {
145
                $this->fields[$field->getName()] = $field;
146
            }
147
        }
148
    }
149
    
150
    /**
151
     * Handles the column definitions of query commands on next caller.
152
     * @param \Plasma\BinaryBuffer                  $buffer
153
     * @param \Plasma\Drivers\MySQL\ProtocolParser  $parser
154
     * @return \Plasma\ColumnDefinitionInterface|null
155
     */
156
    function handleQueryOnNextCallerColumns(\Plasma\BinaryBuffer $buffer, \Plasma\Drivers\MySQL\ProtocolParser $parser): ?\Plasma\ColumnDefinitionInterface {
157
        if($this->fieldsCount === null) {
158
            $fieldCount = $buffer->readIntLength();
159
            
160
            if($fieldCount === 0xFB) {
161
                // Handle it on future tick, so we can cleanly finish the buffer of this call
162
                $this->driver->getLoop()->futureTick(function () use (&$buffer, &$parser) {
163
                    $localMsg = new \Plasma\Drivers\MySQL\Messages\LocalInFileRequestMessage($parser);
164
                    $parser->handleMessage($buffer, $localMsg);
165
                });
166
                
167
                return null;
168
            } elseif($fieldCount === 0x00) {
169
                $this->driver->getLoop()->futureTick(function () use (&$buffer, &$parser) {
170
                    $okMsg = new \Plasma\Drivers\MySQL\Messages\OkResponseMessage($parser);
171
                    $parser->handleMessage($buffer, $okMsg);
172
                });
173
                
174
                return null;
175
            }
176
            
177
            $this->fieldsCount = $fieldCount;
178
            return null;
179
        }
180
        
181
        return static::parseColumnDefinition($buffer);
182
    }
183
    
184
    /**
185
     * Parses the column definition.
186
     * @param \Plasma\BinaryBuffer  $buffer
187
     * @return \Plasma\ColumnDefinitionInterface
188
     */
189
    static function parseColumnDefinition(\Plasma\BinaryBuffer $buffer): \Plasma\ColumnDefinitionInterface {
190
        \Plasma\Drivers\MySQL\Messages\MessageUtility::debug('CD 5 bytes: '.implode(', ', unpack('C*', \substr($buffer->getContents(), 0, 5))));
191
        $buffer->readStringLength(); // catalog - always "def"
192
        $database = $buffer->readStringLength();
193
        
194
        $table = $buffer->readStringLength();
195
        $buffer->readStringLength(); // orgTable
196
        
197
        $name = $buffer->readStringLength();
198
        $buffer->readStringLength(); // orgName
199
        
200
        $buffer->read(1); // 0x0C
201
        
202
        $charset = $buffer->readInt2();
203
        $length = $buffer->readInt4();
204
        $type = $buffer->readInt1();
205
        $flags = $buffer->readInt2();
206
        $decimals = $buffer->readInt1();
207
        
208
        $buffer->read(2); // fillers
209
        
210
        /*if($this instanceof COM_FIELD_LIST) {
211
            $buffer->readStringLength();
212
        }*/
213
        
214
        $charset = \Plasma\Drivers\MySQL\CharacterSetFlags::CHARSET_MAP[$charset] ?? 'Unknown charset "'.$charset.'"';
215
        $type = \Plasma\Drivers\MySQL\FieldFlags::TYPE_MAP[$type] ?? 'Unknown type "'.$type.'"';
216
        $nullable = (($flags & \Plasma\Drivers\MySQL\FieldFlags::NOT_NULL_FLAG) === 0);
217
        
218
        return (new \Plasma\ColumnDefinition($database, $table, $name, $type, $charset, $length, $nullable, $flags, $decimals));
3 ignored issues
show
It seems like $name can also be of type null; however, parameter $name of Plasma\ColumnDefinition::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

218
        return (new \Plasma\ColumnDefinition($database, $table, /** @scrutinizer ignore-type */ $name, $type, $charset, $length, $nullable, $flags, $decimals));
Loading history...
It seems like $table can also be of type null; however, parameter $table of Plasma\ColumnDefinition::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

218
        return (new \Plasma\ColumnDefinition($database, /** @scrutinizer ignore-type */ $table, $name, $type, $charset, $length, $nullable, $flags, $decimals));
Loading history...
It seems like $database can also be of type null; however, parameter $database of Plasma\ColumnDefinition::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

218
        return (new \Plasma\ColumnDefinition(/** @scrutinizer ignore-type */ $database, $table, $name, $type, $charset, $length, $nullable, $flags, $decimals));
Loading history...
219
    }
220
    
221
    /**
222
     * Parses the text resultset row and returns the row.
223
     * @param \Plasma\ColumnDefinitionInterface  $column
224
     * @param \Plasma\BinaryBuffer               $buffer
225
     * @return array
226
     */
227
    protected function parseResultsetRow(\Plasma\BinaryBuffer $buffer): array {
228
        $row = array();
229
        
230
        /** @var \Plasma\ColumnDefinitionInterface  $column */
231
        foreach($this->fields as $column) {
232
            $rawValue = $buffer->readStringLength();
233
            
234
            try {
235
                $value = \Plasma\Types\TypeExtensionsManager::getManager('driver-mysql')
236
                    ->decodeType($column->getType(), $rawValue)
237
                    ->getValue();
238
            } catch (\Plasma\Exception $e) {
239
                $value = $this->stdDecodeValue($column, $rawValue);
0 ignored issues
show
It seems like $rawValue can also be of type null; however, parameter $param of Plasma\Drivers\MySQL\Com...mmand::stdDecodeValue() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

239
                $value = $this->stdDecodeValue($column, /** @scrutinizer ignore-type */ $rawValue);
Loading history...
240
            }
241
            
242
            $row[$column->getName()] = $value;
243
        }
244
        
245
        return $row;
246
    }
247
    
248
    /**
249
     * Standard decode value, if type extensions failed.
250
     * @param \Plasma\ColumnDefinitionInterface  $column
251
     * @param string                             $param
252
     * @return mixed
253
     * @throws \Plasma\Exception
254
     */
255
    protected function stdDecodeValue(\Plasma\ColumnDefinitionInterface $column, string $param) {
256
        $flags = $column->getFlags();
257
        
258
        if($param !== null && ($flags & \Plasma\Drivers\MySQL\FieldFlags::ZEROFILL_FLAG) === 0) {
259
            switch($column->getType()) {
260
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_LONG:
261
                    if(($flags & \Plasma\Drivers\MySQL\FieldFlags::UNSIGNED_FLAG) === 0 || \PHP_INT_SIZE > 4) {
262
                        $param = (int) $param;
263
                    }
264
                break;
265
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_LONGLONG:
266
                    if(($flags & \Plasma\Drivers\MySQL\FieldFlags::UNSIGNED_FLAG) === 0 && \PHP_INT_SIZE > 4) {
267
                        $param = (int) $param;
268
                    }
269
                break;
270
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_TINY:
271
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_SHORT:
272
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_INT24:
273
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_TIMESTAMP:
274
                    $param = (int) $param;
275
                break;
276
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_FLOAT:
277
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_DOUBLE:
278
                    $param = (float) $param;
279
                break;
280
                // Other types are taken as string
281
            }
282
        }
283
        
284
        return $param;
285
    }
286
}
287