0 follower

Final Class Yiisoft\Db\Migration\Service\MigrationService

InheritanceYiisoft\Db\Migration\Service\MigrationService

Public Methods

Hide inherited methods

Method Description Defined By
__construct() Yiisoft\Db\Migration\Service\MigrationService
before() This method is invoked right before an action is to be executed (after all possible filters.) Yiisoft\Db\Migration\Service\MigrationService
databaseConnection() Yiisoft\Db\Migration\Service\MigrationService
filterMigrations() Filters migrations by namespaces and paths. Yiisoft\Db\Migration\Service\MigrationService
findMigrationPath() Finds the file path for migration namespace or path. Yiisoft\Db\Migration\Service\MigrationService
generateClassName() Generates class base name from migration name from user input. Yiisoft\Db\Migration\Service\MigrationService
getNewMigrationNamespace() Returns namespace to create migration Yiisoft\Db\Migration\Service\MigrationService
getNewMigrations() Returns the migrations that are not applied. Yiisoft\Db\Migration\Service\MigrationService
makeMigration() Yiisoft\Db\Migration\Service\MigrationService
makeMigrations() Yiisoft\Db\Migration\Service\MigrationService
makeRevertibleMigration() Yiisoft\Db\Migration\Service\MigrationService
makeRevertibleMigrations() Yiisoft\Db\Migration\Service\MigrationService
setIo() Yiisoft\Db\Migration\Service\MigrationService
setNewMigrationNamespace() Yiisoft\Db\Migration\Service\MigrationService
setNewMigrationPath() Yiisoft\Db\Migration\Service\MigrationService
setSourceNamespaces() List of namespaces containing the migration update classes. Yiisoft\Db\Migration\Service\MigrationService
setSourcePaths() The directory containing the migration update classes. Yiisoft\Db\Migration\Service\MigrationService
version() Yiisoft\Db\Migration\Service\MigrationService

Method Details

Hide inherited methods

__construct() public method

public __construct( \Yiisoft\Db\Connection\ConnectionInterface $db, \Yiisoft\Injector\Injector $injector, Yiisoft\Db\Migration\Migrator $migrator ): mixed
$db \Yiisoft\Db\Connection\ConnectionInterface
$injector \Yiisoft\Injector\Injector
$migrator Yiisoft\Db\Migration\Migrator

                public function __construct(
    private readonly ConnectionInterface $db,
    private readonly Injector $injector,
    private readonly Migrator $migrator,
) {}

            
before() public method

This method is invoked right before an action is to be executed (after all possible filters.)

It checks the existence of the $newMigrationPath, $sourcePaths, $newMigrationNamespace, $sourceNamespaces.

public before( string $commandName ): integer
$commandName string
return integer

Whether the action should continue to be executed.

                public function before(string $commandName): int
{
    switch ($commandName) {
        case 'migrate:create':
            if (empty($this->newMigrationNamespace) && empty($this->newMigrationPath)) {
                $this->io?->error(
                    'One of `newMigrationNamespace` or `newMigrationPath` should be specified.',
                );
                return Command::INVALID;
            }
            if (!empty($this->newMigrationNamespace) && !empty($this->newMigrationPath)) {
                $this->io?->error(
                    'Only one of `newMigrationNamespace` or `newMigrationPath` should be specified.',
                );
                return Command::INVALID;
            }
            break;
        case 'migrate:up':
            if (empty($this->sourceNamespaces) && empty($this->sourcePaths)) {
                $this->io?->error(
                    'At least one of `sourceNamespaces` or `sourcePaths` should be specified.',
                );
                return Command::INVALID;
            }
            break;
    }
    return Command::SUCCESS;
}

            
databaseConnection() public method

public databaseConnection( ): void

                public function databaseConnection(): void
{
    $this->io?->writeln(
        "<fg=cyan>Database connection: {$this->db->getDriverName()}.</>",
    );
}

            
filterMigrations() public method

Filters migrations by namespaces and paths.

public filterMigrations( string[] $classes, string[] $namespaces = [], string[] $paths = [] ): string[]
$classes string[]

Migration classes to be filtered.

$namespaces string[]

Namespaces to filter by.

$paths string[]

Paths to filter by.

return string[]

Filtered migration classes.

                public function filterMigrations(array $classes, array $namespaces = [], array $paths = []): array
{
    $result = [];
    $pathNamespaces = [];
    foreach ($paths as $path) {
        $pathNamespaceList = $this->getNamespacesFromPath($path);
        if (!empty($pathNamespaceList)) {
            $pathNamespaces[$path] = $pathNamespaceList;
        }
    }
    $namespaces = array_map(static fn($namespace) => trim($namespace, '\\'), $namespaces);
    $namespaces = array_unique($namespaces);
    foreach ($classes as $class) {
        $classNamespace = substr($class, 0, strrpos($class, '\\') ?: 0);
        if ($classNamespace === '') {
            continue;
        }
        if (in_array($classNamespace, $namespaces, true)) {
            $result[] = $class;
            continue;
        }
        foreach ($pathNamespaces as $path => $pathNamespaceList) {
            /** @psalm-suppress RedundantCondition */
            if (!in_array($classNamespace, $pathNamespaceList, true)) {
                continue;
            }
            /** @var string $className */
            $className = strrchr($class, '\\');
            $className = substr($className, 1);
            $file = $path . DIRECTORY_SEPARATOR . $className . '.php';
            if (is_file($file)) {
                $result[] = $class;
                break;
            }
        }
    }
    return $result;
}

            
findMigrationPath() public method

Finds the file path for migration namespace or path.

public findMigrationPath( ): string
return string

The migration file path.

                public function findMigrationPath(): string
{
    return empty($this->newMigrationNamespace)
        ? $this->newMigrationPath
        : $this->getNamespacePath($this->newMigrationNamespace);
}

            
generateClassName() public method

Generates class base name from migration name from user input.

public generateClassName( string $name ): string
$name string

Migration name from the user input.

return string

The class base name.

                public function generateClassName(string $name): string
{
    /** @var string $words */
    $words = preg_replace('/[^a-z0-9]+/i', ' ', $name);
    return 'M' . gmdate('ymdHis') . str_replace(' ', '', ucwords($words));
}

            
getNewMigrationNamespace() public method

Returns namespace to create migration

public getNewMigrationNamespace( ): string

                public function getNewMigrationNamespace(): string
{
    return $this->newMigrationNamespace;
}

            
getNewMigrations() public method

Returns the migrations that are not applied.

public getNewMigrations( ): string[]
return string[]

List of new migrations.

                public function getNewMigrations(): array
{
    $applied = [];
    foreach ($this->migrator->getHistory() as $class => $time) {
        $applied[trim($class, '\\')] = true;
    }
    $migrationPaths = [];
    foreach ($this->sourcePaths as $path) {
        $migrationPaths[] = [$path, ''];
    }
    foreach ($this->sourceNamespaces as $namespace) {
        $migrationPaths[] = [$this->getNamespacePath($namespace), $namespace];
    }
    $migrations = [];
    foreach ($migrationPaths as $item) {
        [$sourcePath, $namespace] = $item;
        if (!is_dir($sourcePath)) {
            continue;
        }
        /** @var resource $handle */
        $handle = opendir($sourcePath);
        while (($file = readdir($handle)) !== false) {
            if ($file === '.' || $file === '..') {
                continue;
            }
            $path = $sourcePath . DIRECTORY_SEPARATOR . $file;
            if (is_file($path) && preg_match('/^(M(\d{12}).*)\.php$/s', $file, $matches)) {
                [, $class, $time] = $matches;
                if (!empty($namespace)) {
                    $class = $namespace . '\\' . $class;
                }
                /** @psalm-var class-string $class */
                if (!isset($applied[$class])) {
                    $migrations[$time . '\\' . $class] = $class;
                }
            }
        }
        closedir($handle);
    }
    ksort($migrations);
    return array_values($migrations);
}

            
makeMigration() public method

public makeMigration( string $class ): Yiisoft\Db\Migration\MigrationInterface
$class string

                public function makeMigration(string $class): MigrationInterface
{
    $migration = $this->makeMigrationInstance($class);
    if (!$migration instanceof MigrationInterface) {
        throw new RuntimeException("Migration $class does not implement MigrationInterface.");
    }
    return $migration;
}

            
makeMigrations() public method

public makeMigrations( string[] $classes ): Yiisoft\Db\Migration\MigrationInterface[]
$classes string[]

                public function makeMigrations(array $classes): array
{
    return array_map(
        $this->makeMigration(...),
        $classes,
    );
}

            
makeRevertibleMigration() public method

public makeRevertibleMigration( string $class ): Yiisoft\Db\Migration\RevertibleMigrationInterface
$class string

                public function makeRevertibleMigration(string $class): RevertibleMigrationInterface
{
    $migration = $this->makeMigrationInstance($class);
    if (!$migration instanceof RevertibleMigrationInterface) {
        throw new RuntimeException("Migration $class does not implement RevertibleMigrationInterface.");
    }
    return $migration;
}

            
makeRevertibleMigrations() public method

public makeRevertibleMigrations( string[] $classes ): Yiisoft\Db\Migration\RevertibleMigrationInterface[]
$classes string[]

                public function makeRevertibleMigrations(array $classes): array
{
    return array_map(
        $this->makeRevertibleMigration(...),
        $classes,
    );
}

            
setIo() public method

public setIo( \Symfony\Component\Console\Style\SymfonyStyle|null $io ): void
$io \Symfony\Component\Console\Style\SymfonyStyle|null

                public function setIo(?SymfonyStyle $io): void
{
    $this->io = $io;
}

            
setNewMigrationNamespace() public method

public setNewMigrationNamespace( string $value ): void
$value string

                public function setNewMigrationNamespace(string $value): void
{
    $this->newMigrationNamespace = $value;
}

            
setNewMigrationPath() public method

public setNewMigrationPath( string $value ): void
$value string

                public function setNewMigrationPath(string $value): void
{
    $this->newMigrationPath = $value;
}

            
setSourceNamespaces() public method

List of namespaces containing the migration update classes.

public setSourceNamespaces( array $value ): void
$value array

                public function setSourceNamespaces(array $value): void
{
    $this->sourceNamespaces = $value;
}

            
setSourcePaths() public method

The directory containing the migration update classes.

Migration classes located on this path should be declared without a namespace. Use $newMigrationNamespace property in case you are using namespaced migrations.

If you have set up $newMigrationNamespace, you may set this field to null to disable usage of migrations that are not namespaced.

In general, to load migrations from different locations, $newMigrationNamespace is the preferable solution as the migration name contains the origin of the migration in the history, which is not the case when using multiple migration paths.

$newMigrationNamespace

public setSourcePaths( array $value ): void
$value array

                public function setSourcePaths(array $value): void
{
    $this->sourcePaths = $value;
}

            
version() public method

public version( ): string

                public function version(): string
{
    return $this->version;
}