Passed
Push — fix-php-74 ( 9989b6...f6eb65 )
by Alexander
30:32 queued 19s
created

MigrateController   F

Complexity

Total Complexity 66

Size/Duplication

Total Lines 541
Duplicated Lines 0 %

Test Coverage

Coverage 25.75%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 240
dl 0
loc 541
ccs 60
cts 233
cp 0.2575
rs 3.12
c 1
b 0
f 0
wmc 66

17 Methods

Rating   Name   Duplication   Size   Complexity  
A optionAliases() 0 10 1
A beforeAction() 0 8 2
A removeMigrationHistory() 0 6 1
A createMigration() 0 8 1
A createMigrationHistoryTable() 0 13 1
A addMigrationHistory() 0 7 1
A normalizeTableName() 0 11 3
A isViewRelated() 0 14 3
A addDefaultPrimaryKey() 0 8 3
C generateMigrationSourceCode() 0 102 14
A splitFieldIntoChunks() 0 20 5
B parseFields() 0 38 7
A generateTableName() 0 7 2
B truncateDatabase() 0 26 7
A options() 0 8 2
B getMigrationHistory() 0 52 9
A getMigrationNameLimit() 0 11 4

How to fix   Complexity   

Complex Class

Complex classes like MigrateController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use MigrateController, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace yii\console\controllers;
9
10
use Yii;
11
use yii\db\Connection;
12
use yii\db\Query;
13
use yii\di\Instance;
14
use yii\helpers\ArrayHelper;
15
use yii\helpers\Console;
16
use yii\helpers\Inflector;
17
18
/**
19
 * Manages application migrations.
20
 *
21
 * A migration means a set of persistent changes to the application environment
22
 * that is shared among different developers. For example, in an application
23
 * backed by a database, a migration may refer to a set of changes to
24
 * the database, such as creating a new table, adding a new table column.
25
 *
26
 * This command provides support for tracking the migration history, upgrading
27
 * or downloading with migrations, and creating new migration skeletons.
28
 *
29
 * The migration history is stored in a database table named
30
 * as [[migrationTable]]. The table will be automatically created the first time
31
 * this command is executed, if it does not exist. You may also manually
32
 * create it as follows:
33
 *
34
 * ```sql
35
 * CREATE TABLE migration (
36
 *     version varchar(180) PRIMARY KEY,
37
 *     apply_time integer
38
 * )
39
 * ```
40
 *
41
 * Below are some common usages of this command:
42
 *
43
 * ```
44
 * # creates a new migration named 'create_user_table'
45
 * yii migrate/create create_user_table
46
 *
47
 * # applies ALL new migrations
48
 * yii migrate
49
 *
50
 * # reverts the last applied migration
51
 * yii migrate/down
52
 * ```
53
 *
54
 * Since 2.0.10 you can use namespaced migrations. In order to enable this feature you should configure [[migrationNamespaces]]
55
 * property for the controller at application configuration:
56
 *
57
 * ```php
58
 * return [
59
 *     'controllerMap' => [
60
 *         'migrate' => [
61
 *             'class' => 'yii\console\controllers\MigrateController',
62
 *             'migrationNamespaces' => [
63
 *                 'app\migrations',
64
 *                 'some\extension\migrations',
65
 *             ],
66
 *             //'migrationPath' => null, // allows to disable not namespaced migration completely
67
 *         ],
68
 *     ],
69
 * ];
70
 * ```
71
 *
72
 * @author Qiang Xue <[email protected]>
73
 * @since 2.0
74
 */
75
class MigrateController extends BaseMigrateController
76
{
77
    /**
78
     * Maximum length of a migration name.
79
     * @since 2.0.13
80
     */
81
    const MAX_NAME_LENGTH = 180;
82
83
    /**
84
     * @var string the name of the table for keeping applied migration information.
85
     */
86
    public $migrationTable = '{{%migration}}';
87
    /**
88
     * {@inheritdoc}
89
     */
90
    public $templateFile = '@yii/views/migration.php';
91
    /**
92
     * @var array a set of template paths for generating migration code automatically.
93
     *
94
     * The key is the template type, the value is a path or the alias. Supported types are:
95
     * - `create_table`: table creating template
96
     * - `drop_table`: table dropping template
97
     * - `add_column`: adding new column template
98
     * - `drop_column`: dropping column template
99
     * - `create_junction`: create junction template
100
     *
101
     * @since 2.0.7
102
     */
103
    public $generatorTemplateFiles = [
104
        'create_table' => '@yii/views/createTableMigration.php',
105
        'drop_table' => '@yii/views/dropTableMigration.php',
106
        'add_column' => '@yii/views/addColumnMigration.php',
107
        'drop_column' => '@yii/views/dropColumnMigration.php',
108
        'create_junction' => '@yii/views/createTableMigration.php',
109
    ];
110
    /**
111
     * @var bool indicates whether the table names generated should consider
112
     * the `tablePrefix` setting of the DB connection. For example, if the table
113
     * name is `post` the generator wil return `{{%post}}`.
114
     * @since 2.0.8
115
     */
116
    public $useTablePrefix = true;
117
    /**
118
     * @var array column definition strings used for creating migration code.
119
     *
120
     * The format of each definition is `COLUMN_NAME:COLUMN_TYPE:COLUMN_DECORATOR`. Delimiter is `,`.
121
     * For example, `--fields="name:string(12):notNull:unique"`
122
     * produces a string column of size 12 which is not null and unique values.
123
     *
124
     * Note: primary key is added automatically and is named id by default.
125
     * If you want to use another name you may specify it explicitly like
126
     * `--fields="id_key:primaryKey,name:string(12):notNull:unique"`
127
     * @since 2.0.7
128
     */
129
    public $fields = [];
130
    /**
131
     * @var Connection|array|string the DB connection object or the application component ID of the DB connection to use
132
     * when applying migrations. Starting from version 2.0.3, this can also be a configuration array
133
     * for creating the object.
134
     */
135
    public $db = 'db';
136
    /**
137
     * @var string the comment for the table being created.
138
     * @since 2.0.14
139
     */
140
    public $comment = '';
141
142
143
    /**
144
     * {@inheritdoc}
145
     */
146 38
    public function options($actionID)
147
    {
148 38
        return array_merge(
149 38
            parent::options($actionID),
150 38
            ['migrationTable', 'db'], // global for all actions
151 38
            $actionID === 'create'
152
                ? ['templateFile', 'fields', 'useTablePrefix', 'comment']
153 38
                : []
154
        );
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     * @since 2.0.8
160
     */
161
    public function optionAliases()
162
    {
163
        return array_merge(parent::optionAliases(), [
164
            'C' => 'comment',
165
            'f' => 'fields',
166
            'p' => 'migrationPath',
167
            't' => 'migrationTable',
168
            'F' => 'templateFile',
169
            'P' => 'useTablePrefix',
170
            'c' => 'compact',
171
        ]);
172
    }
173
174
    /**
175
     * This method is invoked right before an action is to be executed (after all possible filters.)
176
     * It checks the existence of the [[migrationPath]].
177
     * @param \yii\base\Action $action the action to be executed.
178
     * @return bool whether the action should continue to be executed.
179
     */
180 38
    public function beforeAction($action)
181
    {
182 38
        if (parent::beforeAction($action)) {
183 38
            $this->db = Instance::ensure($this->db, Connection::className());
0 ignored issues
show
Deprecated Code introduced by
The function yii\base\BaseObject::className() has been deprecated: since 2.0.14. On PHP >=5.5, use `::class` instead. ( Ignorable by Annotation )

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

183
            $this->db = Instance::ensure($this->db, /** @scrutinizer ignore-deprecated */ Connection::className());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
184 38
            return true;
185
        }
186
187
        return false;
188
    }
189
190
    /**
191
     * Creates a new migration instance.
192
     * @param string $class the migration class name
193
     * @return \yii\db\Migration the migration instance
194
     */
195 38
    protected function createMigration($class)
196
    {
197 38
        $this->includeMigrationFile($class);
198
199 38
        return Yii::createObject([
200 38
            'class' => $class,
201 38
            'db' => $this->db,
202 38
            'compact' => $this->compact,
203
        ]);
204
    }
205
206
    /**
207
     * {@inheritdoc}
208
     */
209 38
    protected function getMigrationHistory($limit)
210
    {
211 38
        if ($this->db->schema->getTableSchema($this->migrationTable, true) === null) {
212 8
            $this->createMigrationHistoryTable();
213
        }
214 38
        $query = (new Query())
215 38
            ->select(['version', 'apply_time'])
216 38
            ->from($this->migrationTable)
217 38
            ->orderBy(['apply_time' => SORT_DESC, 'version' => SORT_DESC]);
218
219 38
        if (empty($this->migrationNamespaces)) {
220 38
            $query->limit($limit);
221 38
            $rows = $query->all($this->db);
222 38
            $history = ArrayHelper::map($rows, 'version', 'apply_time');
223 38
            unset($history[self::BASE_MIGRATION]);
224 38
            return $history;
225
        }
226
227
        $rows = $query->all($this->db);
228
229
        $history = [];
230
        foreach ($rows as $key => $row) {
231
            if ($row['version'] === self::BASE_MIGRATION) {
232
                continue;
233
            }
234
            if (preg_match('/m?(\d{6}_?\d{6})(\D.*)?$/is', $row['version'], $matches)) {
235
                $time = str_replace('_', '', $matches[1]);
236
                $row['canonicalVersion'] = $time;
237
            } else {
238
                $row['canonicalVersion'] = $row['version'];
239
            }
240
            $row['apply_time'] = (int) $row['apply_time'];
241
            $history[] = $row;
242
        }
243
244
        usort($history, function ($a, $b) {
245
            if ($a['apply_time'] === $b['apply_time']) {
246
                if (($compareResult = strcasecmp($b['canonicalVersion'], $a['canonicalVersion'])) !== 0) {
247
                    return $compareResult;
248
                }
249
250
                return strcasecmp($b['version'], $a['version']);
251
            }
252
253
            return ($a['apply_time'] > $b['apply_time']) ? -1 : +1;
254
        });
255
256
        $history = array_slice($history, 0, $limit);
257
258
        $history = ArrayHelper::map($history, 'version', 'apply_time');
259
260
        return $history;
261
    }
262
263
    /**
264
     * Creates the migration history table.
265
     */
266 8
    protected function createMigrationHistoryTable()
267
    {
268 8
        $tableName = $this->db->schema->getRawTableName($this->migrationTable);
269 8
        $this->stdout("Creating migration history table \"$tableName\"...", Console::FG_YELLOW);
270 8
        $this->db->createCommand()->createTable($this->migrationTable, [
271 8
            'version' => 'varchar(' . static::MAX_NAME_LENGTH . ') NOT NULL PRIMARY KEY',
272 8
            'apply_time' => 'integer',
273 8
        ])->execute();
274 8
        $this->db->createCommand()->insert($this->migrationTable, [
275 8
            'version' => self::BASE_MIGRATION,
276 8
            'apply_time' => time(),
277 8
        ])->execute();
278 8
        $this->stdout("Done.\n", Console::FG_GREEN);
279 8
    }
280
281
    /**
282
     * {@inheritdoc}
283
     */
284 38
    protected function addMigrationHistory($version)
285
    {
286 38
        $command = $this->db->createCommand();
287 38
        $command->insert($this->migrationTable, [
288 38
            'version' => $version,
289 38
            'apply_time' => time(),
290 38
        ])->execute();
291 38
    }
292
293
    /**
294
     * {@inheritdoc}
295
     * @since 2.0.13
296
     */
297
    protected function truncateDatabase()
298
    {
299
        $db = $this->db;
300
        $schemas = $db->schema->getTableSchemas();
301
302
        // First drop all foreign keys,
303
        foreach ($schemas as $schema) {
304
            if ($schema->foreignKeys) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $schema->foreignKeys 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...
305
                foreach ($schema->foreignKeys as $name => $foreignKey) {
306
                    $db->createCommand()->dropForeignKey($name, $schema->name)->execute();
307
                    $this->stdout("Foreign key $name dropped.\n");
308
                }
309
            }
310
        }
311
312
        // Then drop the tables:
313
        foreach ($schemas as $schema) {
314
            try {
315
                $db->createCommand()->dropTable($schema->name)->execute();
316
                $this->stdout("Table {$schema->name} dropped.\n");
317
            } catch (\Exception $e) {
318
                if ($this->isViewRelated($e->getMessage())) {
319
                    $db->createCommand()->dropView($schema->name)->execute();
320
                    $this->stdout("View {$schema->name} dropped.\n");
321
                } else {
322
                    $this->stdout("Cannot drop {$schema->name} Table .\n");
323
                }
324
            }
325
        }
326
    }
327
328
    /**
329
     * Determines whether the error message is related to deleting a view or not
330
     * @param string $errorMessage
331
     * @return bool
332
     */
333
    private function isViewRelated($errorMessage)
334
    {
335
        $dropViewErrors = [
336
            'DROP VIEW to delete view', // SQLite
337
            'SQLSTATE[42S02]', // MySQL
338
        ];
339
340
        foreach ($dropViewErrors as $dropViewError) {
341
            if (strpos($errorMessage, $dropViewError) !== false) {
342
                return true;
343
            }
344
        }
345
346
        return false;
347
    }
348
349
    /**
350
     * {@inheritdoc}
351
     */
352 38
    protected function removeMigrationHistory($version)
353
    {
354 38
        $command = $this->db->createCommand();
355 38
        $command->delete($this->migrationTable, [
356 38
            'version' => $version,
357 38
        ])->execute();
358 38
    }
359
360
    private $_migrationNameLimit;
361
362
    /**
363
     * {@inheritdoc}
364
     * @since 2.0.13
365
     */
366 38
    protected function getMigrationNameLimit()
367
    {
368 38
        if ($this->_migrationNameLimit !== null) {
369
            return $this->_migrationNameLimit;
370
        }
371 38
        $tableSchema = $this->db->schema ? $this->db->schema->getTableSchema($this->migrationTable, true) : null;
372 38
        if ($tableSchema !== null) {
373 38
            return $this->_migrationNameLimit = $tableSchema->columns['version']->size;
374
        }
375
376
        return static::MAX_NAME_LENGTH;
377
    }
378
379
    /**
380
     * Normalizes table name for generator.
381
     * When name is preceded with underscore name case is kept - otherwise it's converted from camelcase to underscored.
382
     * Last underscore is always trimmed so if there should be underscore at the end of name use two of them.
383
     * @param string $name
384
     * @return string
385
     */
386
    private function normalizeTableName($name)
387
    {
388
        if (substr($name, -1) === '_') {
389
            $name = substr($name, 0, -1);
390
        }
391
392
        if (strpos($name, '_') === 0) {
393
            return substr($name, 1);
394
        }
395
396
        return Inflector::underscore($name);
397
    }
398
399
    /**
400
     * {@inheritdoc}
401
     * @since 2.0.8
402
     */
403
    protected function generateMigrationSourceCode($params)
404
    {
405
        $parsedFields = $this->parseFields();
406
        $fields = $parsedFields['fields'];
407
        $foreignKeys = $parsedFields['foreignKeys'];
408
409
        $name = $params['name'];
410
        if ($params['namespace']) {
411
            $name = substr($name, strrpos($name, '\\') + 1);
412
        }
413
414
        $templateFile = $this->templateFile;
415
        $table = null;
416
        if (preg_match(
417
            '/^create_?junction_?(?:table)?_?(?:for)?(.+)_?and(.+)_?tables?$/i',
418
            $name,
419
            $matches
420
        )) {
421
            $templateFile = $this->generatorTemplateFiles['create_junction'];
422
            $firstTable = $this->normalizeTableName($matches[1]);
423
            $secondTable = $this->normalizeTableName($matches[2]);
424
425
            $fields = array_merge(
426
                [
427
                    [
428
                        'property' => $firstTable . '_id',
429
                        'decorators' => 'integer()',
430
                    ],
431
                    [
432
                        'property' => $secondTable . '_id',
433
                        'decorators' => 'integer()',
434
                    ],
435
                ],
436
                $fields,
437
                [
438
                    [
439
                        'property' => 'PRIMARY KEY(' .
440
                            $firstTable . '_id, ' .
441
                            $secondTable . '_id)',
442
                    ],
443
                ]
444
            );
445
446
            $foreignKeys[$firstTable . '_id']['table'] = $firstTable;
447
            $foreignKeys[$secondTable . '_id']['table'] = $secondTable;
448
            $foreignKeys[$firstTable . '_id']['column'] = null;
449
            $foreignKeys[$secondTable . '_id']['column'] = null;
450
            $table = $firstTable . '_' . $secondTable;
451
        } elseif (preg_match('/^add(.+)columns?_?to(.+)table$/i', $name, $matches)) {
452
            $templateFile = $this->generatorTemplateFiles['add_column'];
453
            $table = $this->normalizeTableName($matches[2]);
454
        } elseif (preg_match('/^drop(.+)columns?_?from(.+)table$/i', $name, $matches)) {
455
            $templateFile = $this->generatorTemplateFiles['drop_column'];
456
            $table = $this->normalizeTableName($matches[2]);
457
        } elseif (preg_match('/^create(.+)table$/i', $name, $matches)) {
458
            $this->addDefaultPrimaryKey($fields);
459
            $templateFile = $this->generatorTemplateFiles['create_table'];
460
            $table = $this->normalizeTableName($matches[1]);
461
        } elseif (preg_match('/^drop(.+)table$/i', $name, $matches)) {
462
            $this->addDefaultPrimaryKey($fields);
463
            $templateFile = $this->generatorTemplateFiles['drop_table'];
464
            $table = $this->normalizeTableName($matches[1]);
465
        }
466
467
        foreach ($foreignKeys as $column => $foreignKey) {
468
            $relatedColumn = $foreignKey['column'];
469
            $relatedTable = $foreignKey['table'];
470
            // Since 2.0.11 if related column name is not specified,
471
            // we're trying to get it from table schema
472
            // @see https://github.com/yiisoft/yii2/issues/12748
473
            if ($relatedColumn === null) {
474
                $relatedColumn = 'id';
475
                try {
476
                    $this->db = Instance::ensure($this->db, Connection::className());
0 ignored issues
show
Deprecated Code introduced by
The function yii\base\BaseObject::className() has been deprecated: since 2.0.14. On PHP >=5.5, use `::class` instead. ( Ignorable by Annotation )

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

476
                    $this->db = Instance::ensure($this->db, /** @scrutinizer ignore-deprecated */ Connection::className());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
477
                    $relatedTableSchema = $this->db->getTableSchema($relatedTable);
478
                    if ($relatedTableSchema !== null) {
479
                        $primaryKeyCount = count($relatedTableSchema->primaryKey);
480
                        if ($primaryKeyCount === 1) {
481
                            $relatedColumn = $relatedTableSchema->primaryKey[0];
482
                        } elseif ($primaryKeyCount > 1) {
483
                            $this->stdout("Related table for field \"{$column}\" exists, but primary key is composite. Default name \"id\" will be used for related field\n", Console::FG_YELLOW);
484
                        } elseif ($primaryKeyCount === 0) {
485
                            $this->stdout("Related table for field \"{$column}\" exists, but does not have a primary key. Default name \"id\" will be used for related field.\n", Console::FG_YELLOW);
486
                        }
487
                    }
488
                } catch (\ReflectionException $e) {
489
                    $this->stdout("Cannot initialize database component to try reading referenced table schema for field \"{$column}\". Default name \"id\" will be used for related field.\n", Console::FG_YELLOW);
490
                }
491
            }
492
            $foreignKeys[$column] = [
493
                'idx' => $this->generateTableName("idx-$table-$column"),
494
                'fk' => $this->generateTableName("fk-$table-$column"),
495
                'relatedTable' => $this->generateTableName($relatedTable),
496
                'relatedColumn' => $relatedColumn,
497
            ];
498
        }
499
500
        return $this->renderFile(Yii::getAlias($templateFile), array_merge($params, [
501
            'table' => $this->generateTableName($table),
502
            'fields' => $fields,
503
            'foreignKeys' => $foreignKeys,
504
            'tableComment' => $this->comment,
505
        ]));
506
    }
507
508
    /**
509
     * If `useTablePrefix` equals true, then the table name will contain the
510
     * prefix format.
511
     *
512
     * @param string $tableName the table name to generate.
513
     * @return string
514
     * @since 2.0.8
515
     */
516
    protected function generateTableName($tableName)
517
    {
518
        if (!$this->useTablePrefix) {
519
            return $tableName;
520
        }
521
522
        return '{{%' . $tableName . '}}';
523
    }
524
525
    /**
526
     * Parse the command line migration fields.
527
     * @return array parse result with following fields:
528
     *
529
     * - fields: array, parsed fields
530
     * - foreignKeys: array, detected foreign keys
531
     *
532
     * @since 2.0.7
533
     */
534
    protected function parseFields()
535
    {
536
        $fields = [];
537
        $foreignKeys = [];
538
539
        foreach ($this->fields as $index => $field) {
540
            $chunks = $this->splitFieldIntoChunks($field);
541
            $property = array_shift($chunks);
0 ignored issues
show
Bug introduced by
It seems like $chunks can also be of type false; however, parameter $array of array_shift() does only seem to accept array, 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

541
            $property = array_shift(/** @scrutinizer ignore-type */ $chunks);
Loading history...
542
543
            foreach ($chunks as $i => &$chunk) {
544
                if (strncmp($chunk, 'foreignKey', 10) === 0) {
545
                    preg_match('/foreignKey\((\w*)\s?(\w*)\)/', $chunk, $matches);
546
                    $foreignKeys[$property] = [
547
                        'table' => isset($matches[1])
548
                            ? $matches[1]
549
                            : preg_replace('/_id$/', '', $property),
550
                        'column' => !empty($matches[2])
551
                            ? $matches[2]
552
                            : null,
553
                    ];
554
555
                    unset($chunks[$i]);
556
                    continue;
557
                }
558
559
                if (!preg_match('/^(.+?)\(([^(]+)\)$/', $chunk)) {
560
                    $chunk .= '()';
561
                }
562
            }
563
            $fields[] = [
564
                'property' => $property,
565
                'decorators' => implode('->', $chunks),
566
            ];
567
        }
568
569
        return [
570
            'fields' => $fields,
571
            'foreignKeys' => $foreignKeys,
572
        ];
573
    }
574
575
    /**
576
     * Splits field into chunks
577
     *
578
     * @param string $field
579
     * @return string[]|false
580
     */
581
    protected function splitFieldIntoChunks($field)
582
    {
583
        $hasDoubleQuotes = false;
584
        preg_match_all('/defaultValue\(.*?:.*?\)/', $field, $matches);
585
        if (isset($matches[0][0])) {
586
            $hasDoubleQuotes = true;
587
            $originalDefaultValue = $matches[0][0];
588
            $defaultValue = str_replace(':', '{{colon}}', $originalDefaultValue);
589
            $field = str_replace($originalDefaultValue, $defaultValue, $field);
590
        }
591
592
        $chunks = preg_split('/\s?:\s?/', $field);
593
594
        if (is_array($chunks) && $hasDoubleQuotes) {
595
            foreach ($chunks as $key => $chunk) {
596
                $chunks[$key] = str_replace($defaultValue, $originalDefaultValue, $chunk);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $originalDefaultValue does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $defaultValue does not seem to be defined for all execution paths leading up to this point.
Loading history...
597
            }
598
        }
599
600
        return $chunks;
601
    }
602
603
    /**
604
     * Adds default primary key to fields list if there's no primary key specified.
605
     * @param array $fields parsed fields
606
     * @since 2.0.7
607
     */
608
    protected function addDefaultPrimaryKey(&$fields)
609
    {
610
        foreach ($fields as $field) {
611
            if (false !== strripos($field['decorators'], 'primarykey()')) {
612
                return;
613
            }
614
        }
615
        array_unshift($fields, ['property' => 'id', 'decorators' => 'primaryKey()']);
616
    }
617
}
618