Completed
Push — master ( a72986...b23bf5 )
by Mike
03:31
created

Configuration::getAvailableVersions()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 14
ccs 9
cts 9
cp 1
rs 9.4285
cc 3
eloc 7
nc 4
nop 0
crap 3
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the LGPL. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\DBAL\Migrations\Configuration;
21
22
use Doctrine\DBAL\Connection;
23
use Doctrine\DBAL\Migrations\Finder\MigrationDeepFinderInterface;
24
use Doctrine\DBAL\Migrations\MigrationException;
25
use Doctrine\DBAL\Migrations\OutputWriter;
26
use Doctrine\DBAL\Migrations\Version;
27
use Doctrine\DBAL\Migrations\Finder\MigrationFinderInterface;
28
use Doctrine\DBAL\Migrations\Finder\RecursiveRegexFinder;
29
use Doctrine\DBAL\Schema\Column;
30
use Doctrine\DBAL\Schema\Table;
31
use Doctrine\DBAL\Types\Type;
32
33
/**
34
 * Default Migration Configuration object used for configuring an instance of
35
 * the Migration class. Set the connection, version table name, register migration
36
 * classes/versions, etc.
37
 *
38
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
39
 * @link        www.doctrine-project.org
40
 * @since       2.0
41
 * @author      Jonathan H. Wage <[email protected]>
42
 */
43
class Configuration
44
{
45
    /**
46
     * Configure versions to be organized by year.
47
     */
48
    const VERSIONS_ORGANIZATION_BY_YEAR = 'year';
49
50
    /**
51
     * Configure versions to be organized by year and month.
52
     *
53
     * @var string
54
     */
55
    const VERSIONS_ORGANIZATION_BY_YEAR_AND_MONTH = 'year_and_month';
56
57
    /**
58
     * Name of this set of migrations
59
     *
60
     * @var string
61
     */
62
    private $name;
63
64
    /**
65
     * Flag for whether or not the migration table has been created
66
     *
67
     * @var boolean
68
     */
69
    private $migrationTableCreated = false;
70
71
    /**
72
     * Connection instance to use for migrations
73
     *
74
     * @var Connection
75
     */
76
    private $connection;
77
78
    /**
79
     * OutputWriter instance for writing output during migrations
80
     *
81
     * @var OutputWriter
82
     */
83
    private $outputWriter;
84
85
    /**
86
     * The migration finder implementation -- used to load migrations from a
87
     * directory.
88
     *
89
     * @var MigrationFinderInterface
90
     */
91
    private $migrationFinder;
92
93
    /**
94
     * The migration table name to track versions in
95
     *
96
     * @var string
97
     */
98
    private $migrationsTableName = 'doctrine_migration_versions';
99
100
    /**
101
     * The migration column name to track versions in
102
     *
103
     * @var string
104
     */
105
    private $migrationsColumnName = 'version';
106
107
    /**
108
     * The path to a directory where new migration classes will be written
109
     *
110
     * @var string
111
     */
112
    private $migrationsDirectory;
113
114
    /**
115
     * Namespace the migration classes live in
116
     *
117
     * @var string
118
     */
119
    private $migrationsNamespace;
120
121
    /**
122
     * Array of the registered migrations
123
     *
124
     * @var Version[]
125
     */
126
    private $migrations = [];
127
128
    /**
129
     * Versions are organized by year.
130
     *
131
     * @var boolean
132
     */
133
    private $migrationsAreOrganizedByYear = false;
134
135
    /**
136
     * Versions are organized by year and month.
137
     *
138
     * @var boolean
139
     */
140
    private $migrationsAreOrganizedByYearAndMonth = false;
141
142
    /**
143
     * Construct a migration configuration object.
144
     *
145
     * @param Connection               $connection   A Connection instance
146
     * @param OutputWriter             $outputWriter A OutputWriter instance
147
     * @param MigrationFinderInterface $finder       Migration files finder
148
     */
149 232
    public function __construct(Connection $connection, OutputWriter $outputWriter = null, MigrationFinderInterface $finder = null)
150
    {
151 232
        $this->connection = $connection;
152 232
        if ($outputWriter === null) {
153 200
            $outputWriter = new OutputWriter();
154 200
        }
155 232
        $this->outputWriter = $outputWriter;
156 232
        if ($finder === null) {
157 228
            $finder = new RecursiveRegexFinder();
158 228
        }
159 232
        $this->migrationFinder = $finder;
160 232
    }
161
162
    /**
163
     * @return bool
164
     */
165 21
    public function areMigrationsOrganizedByYear()
166
    {
167 21
        return $this->migrationsAreOrganizedByYear;
168
    }
169
170
    /**
171
     * @return bool
172
     */
173 21
    public function areMigrationsOrganizedByYearAndMonth()
174 6
    {
175 21
        return $this->migrationsAreOrganizedByYearAndMonth;
176
    }
177
178
    /**
179
     * Validation that this instance has all the required properties configured
180
     *
181
     * @throws MigrationException
182
     */
183 116
    public function validate()
184
    {
185 116
        if (!$this->migrationsNamespace) {
186 10
            throw MigrationException::migrationsNamespaceRequired();
187
        }
188 106
        if (!$this->migrationsDirectory) {
189 10
            throw MigrationException::migrationsDirectoryRequired();
190
        }
191 96
    }
192
193
    /**
194
     * Set the name of this set of migrations
195
     *
196
     * @param string $name The name of this set of migrations
197
     */
198 49
    public function setName($name)
199
    {
200 49
        $this->name = $name;
201 49
    }
202
203
    /**
204
     * Returns the name of this set of migrations
205
     *
206
     * @return string $name The name of this set of migrations
207
     */
208 14
    public function getName()
209
    {
210 14
        return $this->name;
211
    }
212
213
    /**
214
     * Sets the output writer.
215
     *
216
     * @param OutputWriter $outputWriter
217
     */
218 1
    public function setOutputWriter(OutputWriter $outputWriter)
219
    {
220 1
        $this->outputWriter = $outputWriter;
221 1
    }
222
223
    /**
224
     * Returns the OutputWriter instance
225
     *
226
     * @return OutputWriter $outputWriter  The OutputWriter instance
227
     */
228 96
    public function getOutputWriter()
229
    {
230 96
        return $this->outputWriter;
231
    }
232
233
    /**
234
     * Returns a timestamp version as a formatted date
235
     *
236
     * @param string $version
237
     *
238
     * @return string The formatted version
239
     * @deprecated
240
     */
241
    public function formatVersion($version)
242
    {
243
        return $this->getDateTime($version);
244
    }
245
246
    /**
247
     * Returns the datetime of a migration
248
     *
249
     * @param $version
250
     * @return string
251
     */
252 20
    public function getDateTime($version)
253
    {
254 20
        $datetime = str_replace('Version', '', $version);
255 20
        $datetime = \DateTime::createFromFormat('YmdHis', $datetime);
256
257 20
        if ($datetime === false) {
258 7
            return '';
259
        }
260
261 13
        return $datetime->format('Y-m-d H:i:s');
262
    }
263
264
    /**
265
     * Returns the Connection instance
266
     *
267
     * @return Connection $connection  The Connection instance
268
     */
269 96
    public function getConnection()
270
    {
271 96
        return $this->connection;
272
    }
273
274
    /**
275
     * Set the migration table name
276
     *
277
     * @param string $tableName The migration table name
278
     */
279 68
    public function setMigrationsTableName($tableName)
280
    {
281 68
        $this->migrationsTableName = $tableName;
282 68
    }
283
284
    /**
285
     * Returns the migration table name
286
     *
287
     * @return string $migrationsTableName The migration table name
288
     */
289 64
    public function getMigrationsTableName()
290
    {
291 64
        return $this->migrationsTableName;
292
    }
293
294
    /**
295
     * Set the migration column name
296
     *
297
     * @param string $columnName The migration column name
298
     */
299 21
    public function setMigrationsColumnName($columnName)
300
    {
301 21
        $this->migrationsColumnName = $columnName;
302 21
    }
303
304
    /**
305
     * Returns the migration column name
306
     *
307
     * @return string $migrationsColumnName The migration column name
308
     */
309 55
    public function getMigrationsColumnName()
310
    {
311 55
        return $this->migrationsColumnName;
312
    }
313
314
    /**
315
     * Set the new migrations directory where new migration classes are generated
316
     *
317
     * @param string $migrationsDirectory The new migrations directory
318
     */
319 151
    public function setMigrationsDirectory($migrationsDirectory)
320
    {
321 151
        $this->migrationsDirectory = $migrationsDirectory;
322 151
    }
323
324
    /**
325
     * Returns the new migrations directory where new migration classes are generated
326
     *
327
     * @return string $migrationsDirectory The new migrations directory
328
     */
329 56
    public function getMigrationsDirectory()
330
    {
331 56
        return $this->migrationsDirectory;
332
    }
333
334
    /**
335
     * Set the migrations namespace
336
     *
337
     * @param string $migrationsNamespace The migrations namespace
338
     */
339 163
    public function setMigrationsNamespace($migrationsNamespace)
340
    {
341 163
        $this->migrationsNamespace = $migrationsNamespace;
342 163
    }
343
344
    /**
345
     * Returns the migrations namespace
346
     *
347
     * @return string $migrationsNamespace The migrations namespace
348
     */
349 70
    public function getMigrationsNamespace()
350
    {
351 70
        return $this->migrationsNamespace;
352
    }
353
354
    /**
355
     * Set the implementation of the migration finder.
356
     *
357
     * @param MigrationFinderInterface $finder The new migration finder
358
     * @throws MigrationException
359
     */
360 8
    public function setMigrationsFinder(MigrationFinderInterface $finder)
361
    {
362 8
        if (($this->migrationsAreOrganizedByYear || $this->migrationsAreOrganizedByYearAndMonth) &&
363 8
            !($finder instanceof MigrationDeepFinderInterface)) {
364
365 4
            throw MigrationException::configurationIncompatibleWithFinder(
366 4
                'organize-migrations',
367
                $finder
368 4
            );
369
        }
370
371 4
        $this->migrationFinder = $finder;
372 4
    }
373
374
    /**
375
     * Register migrations from a given directory. Recursively finds all files
376
     * with the pattern VersionYYYYMMDDHHMMSS.php as the filename and registers
377
     * them as migrations.
378
     *
379
     * @param string $path The root directory to where some migration classes live.
380
     *
381
     * @return Version[] The array of migrations registered.
382
     */
383 82
    public function registerMigrationsFromDirectory($path)
384
    {
385 82
        $this->validate();
386
387 66
        return $this->registerMigrations($this->findMigrations($path));
388
    }
389
390
    /**
391
     * Register a single migration version to be executed by a AbstractMigration
392
     * class.
393
     *
394
     * @param string $version The version of the migration in the format YYYYMMDDHHMMSS.
395
     * @param string $class   The migration class to execute for the version.
396
     *
397
     * @return Version
398
     *
399
     * @throws MigrationException
400
     */
401 54
    public function registerMigration($version, $class)
402
    {
403 54
        $this->ensureMigrationClassExists($class);
404
405 53
        $version = (string) $version;
406 53
        $class = (string) $class;
407 53
        if (isset($this->migrations[$version])) {
408 1
            throw MigrationException::duplicateMigrationVersion($version, get_class($this->migrations[$version]));
409
        }
410 53
        $version = new Version($this, $version, $class);
411 53
        $this->migrations[$version->getVersion()] = $version;
412 53
        ksort($this->migrations);
413
414 53
        return $version;
415
    }
416
417
    /**
418
     * Register an array of migrations. Each key of the array is the version and
419
     * the value is the migration class name.
420
     *
421
     *
422
     * @param array $migrations
423
     *
424
     * @return Version[]
425
     */
426 68
    public function registerMigrations(array $migrations)
427
    {
428 68
        $versions = [];
429 68
        foreach ($migrations as $version => $class) {
430 26
            $versions[] = $this->registerMigration($version, $class);
431 67
        }
432
433 67
        return $versions;
434
    }
435
436
    /**
437
     * Get the array of registered migration versions.
438
     *
439
     * @return Version[] $migrations
440
     */
441 28
    public function getMigrations()
442
    {
443 28
        return $this->migrations;
444
    }
445
446
    /**
447
     * Returns the Version instance for a given version in the format YYYYMMDDHHMMSS.
448
     *
449
     * @param string $version The version string in the format YYYYMMDDHHMMSS.
450
     *
451
     * @return Version
452
     *
453
     * @throws MigrationException Throws exception if migration version does not exist.
454
     */
455 12
    public function getVersion($version)
456
    {
457 12
        if (!isset($this->migrations[$version])) {
458 1
            throw MigrationException::unknownMigrationVersion($version);
459
        }
460
461 11
        return $this->migrations[$version];
462
    }
463
464
    /**
465
     * Check if a version exists.
466
     *
467
     * @param string $version
468
     *
469
     * @return boolean
470
     */
471 20
    public function hasVersion($version)
472
    {
473 20
        if (empty($this->migrations)) {
474 4
            $this->registerMigrationsFromDirectory($this->getMigrationsDirectory());
475 2
        }
476
477 18
        return isset($this->migrations[$version]);
478
    }
479
480
    /**
481
     * Check if a version has been migrated or not yet
482
     *
483
     * @param Version $version
484
     *
485
     * @return boolean
486
     */
487 21
    public function hasVersionMigrated(Version $version)
488
    {
489 21
        $this->createMigrationTable();
490
491 21
        $version = $this->connection->fetchColumn(
492 21
            "SELECT " . $this->migrationsColumnName . " FROM " . $this->migrationsTableName . " WHERE " . $this->migrationsColumnName . " = ?",
493 21
            [$version->getVersion()]
494 21
        );
495
496 21
        return $version !== false;
497
    }
498
499
    /**
500
     * Returns all migrated versions from the versions table, in an array.
501
     *
502
     * @return Version[]
503
     */
504 32
    public function getMigratedVersions()
505
    {
506 32
        $this->createMigrationTable();
507
508 32
        $ret = $this->connection->fetchAll("SELECT " . $this->migrationsColumnName . " FROM " . $this->migrationsTableName);
509 32
        $versions = [];
510 32
        foreach ($ret as $version) {
511 13
            $versions[] = current($version);
512 32
        }
513
514 32
        return $versions;
515
    }
516
517
    /**
518
     * Returns an array of available migration version numbers.
519
     *
520
     * @return array
521
     */
522 14
    public function getAvailableVersions()
523
    {
524 14
        $availableVersions = [];
525
526 14
        if (empty($this->migrations)) {
527 3
            $this->registerMigrationsFromDirectory($this->getMigrationsDirectory());
528 1
        }
529
530 12
        foreach ($this->migrations as $migration) {
531 12
            $availableVersions[] = $migration->getVersion();
532 12
        }
533
534 12
        return $availableVersions;
535
    }
536
537
    /**
538
     * Returns the current migrated version from the versions table.
539
     *
540
     * @return string
541
     */
542 34
    public function getCurrentVersion()
543
    {
544 34
        $this->createMigrationTable();
545
546 32
        if (empty($this->migrations)) {
547 15
            $this->registerMigrationsFromDirectory($this->getMigrationsDirectory());
548 15
        }
549
550 32
        $where = null;
551 32
        if (!empty($this->migrations)) {
552 28
            $migratedVersions = [];
553 28
            foreach ($this->migrations as $migration) {
554 28
                $migratedVersions[] = sprintf("'%s'", $migration->getVersion());
555 28
            }
556 28
            $where = " WHERE " . $this->migrationsColumnName . " IN (" . implode(', ', $migratedVersions) . ")";
557 28
        }
558
559 32
        $sql = sprintf("SELECT %s FROM %s%s ORDER BY %s DESC",
560 32
            $this->migrationsColumnName, $this->migrationsTableName, $where, $this->migrationsColumnName
561 32
        );
562
563 32
        $sql = $this->connection->getDatabasePlatform()->modifyLimitQuery($sql, 1);
564 32
        $result = $this->connection->fetchColumn($sql);
565
566 32
        return $result !== false ? (string) $result : '0';
567
    }
568
569
    /**
570
     * Returns the version prior to the current version.
571
     *
572
     * @return string|null A version string, or null if the current version is
573
     *                     the first.
574
     */
575 8
    public function getPrevVersion()
576
    {
577 8
        return $this->getRelativeVersion($this->getCurrentVersion(), -1);
578
    }
579
580
    /**
581
     * Returns the version following the current version.
582
     *
583
     * @return string|null A version string, or null if the current version is
584
     *                     the latest.
585
     */
586 8
    public function getNextVersion()
587
    {
588 8
        return $this->getRelativeVersion($this->getCurrentVersion(), 1);
589
    }
590
591
    /**
592
     * Returns the version with the specified offset to the specified version.
593
     *
594
     * @return string|null A version string, or null if the specified version
595
     *                     is unknown or the specified delta is not within the
596
     *                     list of available versions.
597
     */
598 12
    public function getRelativeVersion($version, $delta)
599
    {
600 12
        if (empty($this->migrations)) {
601 5
            $this->registerMigrationsFromDirectory($this->getMigrationsDirectory());
602 3
        }
603
604 10
        $versions = array_keys($this->migrations);
605 10
        array_unshift($versions, 0);
606 10
        $offset = array_search($version, $versions);
607 10
        if ($offset === false || !isset($versions[$offset + $delta])) {
608
            // Unknown version or delta out of bounds.
609 8
            return null;
610
        }
611
612 8
        return (string) $versions[$offset + $delta];
613
    }
614
615
    /**
616
     * Returns the version number from an alias.
617
     *
618
     * Supported aliases are:
619
     * - first: The very first version before any migrations have been run.
620
     * - current: The current version.
621
     * - prev: The version prior to the current version.
622
     * - next: The version following the current version.
623
     * - latest: The latest available version.
624
     *
625
     * If an existing version number is specified, it is returned verbatimly.
626
     *
627
     * @return string|null A version number, or null if the specified alias
628
     *                     does not map to an existing version, e.g. if "next"
629
     *                     is passed but the current version is already the
630
     *                     latest.
631
     */
632 7
    public function resolveVersionAlias($alias)
633
    {
634 7
        if ($this->hasVersion($alias)) {
635 1
            return $alias;
636
        }
637
        switch ($alias) {
638 7
            case 'first':
639 1
                return '0';
640 7
            case 'current':
641 7
                return $this->getCurrentVersion();
642 7
            case 'prev':
643 7
                return $this->getPrevVersion();
644 7
            case 'next':
645 7
                return $this->getNextVersion();
646 7
            case 'latest':
647 7
                return $this->getLatestVersion();
648 1
            default:
649 1
                return null;
650 1
        }
651
    }
652
653
    /**
654
     * Returns the total number of executed migration versions
655
     *
656
     * @return integer
657
     */
658 1
    public function getNumberOfExecutedMigrations()
659
    {
660 1
        $this->createMigrationTable();
661
662 1
        $result = $this->connection->fetchColumn("SELECT COUNT(" . $this->migrationsColumnName . ") FROM " . $this->migrationsTableName);
663
664 1
        return $result !== false ? $result : 0;
665
    }
666
667
    /**
668
     * Returns the total number of available migration versions
669
     *
670
     * @return integer
671
     */
672 5
    public function getNumberOfAvailableMigrations()
673
    {
674 5
        if (empty($this->migrations)) {
675 4
            $this->registerMigrationsFromDirectory($this->getMigrationsDirectory());
676 2
        }
677
678 3
        return count($this->migrations);
679
    }
680
681
    /**
682
     * Returns the latest available migration version.
683
     *
684
     * @return string The version string in the format YYYYMMDDHHMMSS.
685
     */
686 20
    public function getLatestVersion()
687
    {
688 20
        if (empty($this->migrations)) {
689 7
            $this->registerMigrationsFromDirectory($this->getMigrationsDirectory());
690 5
        }
691
692 18
        $versions = array_keys($this->migrations);
693 18
        $latest = end($versions);
694
695 18
        return $latest !== false ? (string) $latest : '0';
696
    }
697
698
    /**
699
     * Create the migration table to track migrations with.
700
     *
701
     * @return boolean Whether or not the table was created.
702
     */
703 54
    public function createMigrationTable()
704
    {
705 54
        $this->validate();
706
707 52
        if ($this->migrationTableCreated) {
708 42
            return false;
709
        }
710
711 52
        if (!$this->connection->getSchemaManager()->tablesExist([$this->migrationsTableName])) {
712
            $columns = [
713 52
                $this->migrationsColumnName => new Column($this->migrationsColumnName, Type::getType('string'), ['length' => 255]),
714 52
            ];
715 52
            $table = new Table($this->migrationsTableName, $columns);
716 52
            $table->setPrimaryKey([$this->migrationsColumnName]);
717 52
            $this->connection->getSchemaManager()->createTable($table);
718
719 52
            $this->migrationTableCreated = true;
720
721 52
            return true;
722
        }
723
724 3
        $this->migrationTableCreated = true;
725
726 3
        return false;
727
    }
728
729
    /**
730
     * Returns the array of migrations to executed based on the given direction
731
     * and target version number.
732
     *
733
     * @param string $direction The direction we are migrating.
734
     * @param string $to        The version to migrate to.
735
     *
736
     * @return Version[] $migrations   The array of migrations we can execute.
737
     */
738 33
    public function getMigrationsToExecute($direction, $to)
739
    {
740 33
        if (empty($this->migrations)) {
741 11
            $this->registerMigrationsFromDirectory($this->getMigrationsDirectory());
742 5
        }
743
744 27
        if ($direction === Version::DIRECTION_DOWN) {
745 7
            if (count($this->migrations)) {
746 7
                $allVersions = array_reverse(array_keys($this->migrations));
747 7
                $classes = array_reverse(array_values($this->migrations));
748 7
                $allVersions = array_combine($allVersions, $classes);
749 7
            } else {
750
                $allVersions = [];
751
            }
752 7
        } else {
753 25
            $allVersions = $this->migrations;
754
        }
755 27
        $versions = [];
756 27
        $migrated = $this->getMigratedVersions();
757 27
        foreach ($allVersions as $version) {
758 25
            if ($this->shouldExecuteMigration($direction, $version, $to, $migrated)) {
759 23
                $versions[$version->getVersion()] = $version;
760 23
            }
761 27
        }
762
763 27
        return $versions;
764
    }
765
766
    /**
767
     * Find all the migrations in a given directory.
768
     *
769
     * @param   string $path the directory to search.
770
     * @return  array
771
     */
772 66
    protected function findMigrations($path)
773
    {
774 66
        return $this->migrationFinder->findMigrations($path, $this->getMigrationsNamespace());
775
    }
776
777
    /**
778
     * @param bool $migrationsAreOrganizedByYear
779
     * @throws MigrationException
780
     */
781 9
    public function setMigrationsAreOrganizedByYear($migrationsAreOrganizedByYear = true)
782
    {
783 9
        $this->ensureOrganizeMigrationsIsCompatibleWithFinder();
784
785 5
        $this->migrationsAreOrganizedByYear = $migrationsAreOrganizedByYear;
786 5
    }
787
788
    /**
789
     * @param bool $migrationsAreOrganizedByYearAndMonth
790
     * @throws MigrationException
791
     */
792 10
    public function setMigrationsAreOrganizedByYearAndMonth($migrationsAreOrganizedByYearAndMonth = true)
793
    {
794 10
        $this->ensureOrganizeMigrationsIsCompatibleWithFinder();
795
796 10
        $this->migrationsAreOrganizedByYear = $migrationsAreOrganizedByYearAndMonth;
797 10
        $this->migrationsAreOrganizedByYearAndMonth = $migrationsAreOrganizedByYearAndMonth;
798 10
    }
799
800
    /**
801
     * @throws MigrationException
802
     */
803 19
    private function ensureOrganizeMigrationsIsCompatibleWithFinder()
804
    {
805 19
        if (!($this->migrationFinder instanceof MigrationDeepFinderInterface)) {
806 4
            throw MigrationException::configurationIncompatibleWithFinder(
807 4
                'organize-migrations',
808 4
                $this->migrationFinder
809 4
            );
810
        }
811 15
    }
812
813
    /**
814
     * Check if we should execute a migration for a given direction and target
815
     * migration version.
816
     *
817
     * @param string  $direction The direction we are migrating.
818
     * @param Version $version   The Version instance to check.
819
     * @param string  $to        The version we are migrating to.
820
     * @param array   $migrated  Migrated versions array.
821
     *
822
     * @return boolean
823
     */
824 25
    private function shouldExecuteMigration($direction, Version $version, $to, $migrated)
825
    {
826 25 View Code Duplication
        if ($direction === Version::DIRECTION_DOWN) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
827 7
            if (!in_array($version->getVersion(), $migrated)) {
828 4
                return false;
829
            }
830
831 5
            return $version->getVersion() > $to;
832
        }
833
834 23 View Code Duplication
        if ($direction === Version::DIRECTION_UP) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
835 23
            if (in_array($version->getVersion(), $migrated)) {
836 7
                return false;
837
            }
838
839 23
            return $version->getVersion() <= $to;
840
        }
841
    }
842
843
    /**
844
     * @param string $class
845
     */
846 54
    private function ensureMigrationClassExists($class)
847
    {
848 54
        if ( ! class_exists($class)) {
849 1
            throw MigrationException::migrationClassNotFound($class, $this->getMigrationsNamespace());
850
        }
851 53
    }
852
}
853