Final Class Yiisoft\Db\Migration\Service\MigrationService
| Inheritance | Yiisoft\Db\Migration\Service\MigrationService |
|---|
Public Methods
Method Details
| 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,
) {}
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;
}
| public void databaseConnection ( ) |
public function databaseConnection(): void
{
$this->io?->writeln(
"<fg=cyan>\nDatabase connection: {$this->db->getDriverName()}.</>",
);
}
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;
}
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);
}
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));
}
Returns namespace to create migration
| public string getNewMigrationNamespace ( ) |
public function getNewMigrationNamespace(): string
{
return $this->newMigrationNamespace;
}
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);
}
| 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;
}
| public Yiisoft\Db\Migration\MigrationInterface[] makeMigrations ( string[] $classes ) | ||
| $classes | string[] | |
public function makeMigrations(array $classes): array
{
return array_map(
$this->makeMigration(...),
$classes,
);
}
| 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;
}
| public Yiisoft\Db\Migration\RevertibleMigrationInterface[] makeRevertibleMigrations ( string[] $classes ) | ||
| $classes | string[] | |
public function makeRevertibleMigrations(array $classes): array
{
return array_map(
$this->makeRevertibleMigration(...),
$classes,
);
}
| 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;
}
| public void setNewMigrationNamespace ( string $value ) | ||
| $value | string | |
public function setNewMigrationNamespace(string $value): void
{
$this->newMigrationNamespace = $value;
}
| public void setNewMigrationPath ( string $value ) | ||
| $value | string | |
public function setNewMigrationPath(string $value): void
{
$this->newMigrationPath = $value;
}
List of namespaces containing the migration update classes.
| public void setSourceNamespaces ( array $value ) | ||
| $value | array | |
public function setSourceNamespaces(array $value): void
{
$this->sourceNamespaces = $value;
}
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;
}
Signup or Login in order to comment.