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 mixed __construct ( \Yiisoft\Db\Connection\ConnectionInterface $db, \Yiisoft\Injector\Injector $injector, Yiisoft\Db\Migration\Migrator $migrator )
$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 {@see $newMigrationPath}, {@see $sourcePaths}, {@see $newMigrationNamespace}, {@see $sourceNamespaces}.

public integer before ( string $commandName )
$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 void databaseConnection ( )

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

            
filterMigrations() public method

Filters migrations by namespaces and paths.

public string[] filterMigrations ( string[] $classes, string[] $namespaces = [], string[] $paths = [] )
$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 string findMigrationPath ( )
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 string generateClassName ( string $name )
$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 string getNewMigrationNamespace ( )

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

            
getNewMigrations() public method

Returns the migrations that are not applied.

public string[] getNewMigrations ( )
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 Yiisoft\Db\Migration\MigrationInterface makeMigration ( string $class )
$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 Yiisoft\Db\Migration\MigrationInterface[] makeMigrations ( string[] $classes )
$classes string[]

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

            
makeRevertibleMigration() public method

public Yiisoft\Db\Migration\RevertibleMigrationInterface makeRevertibleMigration ( string $class )
$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 Yiisoft\Db\Migration\RevertibleMigrationInterface[] makeRevertibleMigrations ( string[] $classes )
$classes string[]

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

            
setIo() public method

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

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

            
setNewMigrationNamespace() public method

public void setNewMigrationNamespace ( string $value )
$value string

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

            
setNewMigrationPath() public method

public void setNewMigrationPath ( string $value )
$value string

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

            
setSourceNamespaces() public method

List of namespaces containing the migration update classes.

public void setSourceNamespaces ( array $value )
$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 {@see $newMigrationNamespace} property in case you are using namespaced migrations.

If you have set up {@see $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, {@see $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.

{@see $newMigrationNamespace}

public void setSourcePaths ( array $value )
$value array

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

            
version() public method

public string version ( )

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