如何在cakephp 3中运行所有插件的所有迁移?

时间:2017-02-05 11:33:35

标签: cakephp cakephp-3.0

我知道我可以运行bin / cake迁移迁移--plugin MyPlugin

但是我在我的项目中使用了50多个插件,并且喜欢使用一个命令在所有插件中运行所有迁移?这可能吗?

4 个答案:

答案 0 :(得分:2)

据我所知,没有直接的命令来运行所有插件的迁移。但是,您可以组合一个简单的Shell脚本来执行此操作。

您可以使用以下方法检索应用的所有已加载插件的列表: -

$plugins = Plugin::loaded();

然后,您可以使用dispatchShell为每个插件运行迁移,这允许您从另一个Shell运行命令: -

$this->dispatchShell(
    'migrations',
    'migrate',
    '-p',
    $plugin
);

迁移的每个参数都作为参数传递给dispatchShell

所以,将所有这些放在一个Shell脚本中: -

<?php
// src/Shell/InstallShell.php
namespace App\Shell;

use Cake\Console\Shell;
use Cake\Core\Plugin;

class InstallShell extends Shell
{
    public function plugins()
    {
        $plugins = Plugin::loaded();
        foreach ($plugins as $plugin) {
            $this->dispatchShell(
                'migrations',
                'migrate',
                '-p',
                $plugin
            );
        }
    }
}

此脚本将被称为$ bin/cake install plugins

答案 1 :(得分:0)

是的,有可能通过多种方法实现这一目标 编写shell脚本并使用所有50个插件迁移保存在bin目录中 或者你也可以使用cakephp shell Api read here

答案 2 :(得分:0)

我已经改进了#dr; drmonkeyninja&#34;回答以下代码。这样,迁移仅在以前未迁移时运行,并且按文件名中给出的时间戳顺序迁移。

<?php
// src/Shell/InstallShell.php
namespace App\Shell;

use Cake\Console\Shell;
use Cake\Core\Plugin;
use Migrations\Migrations;

class InstallShell extends Shell
{
    public function plugins()
    {
        $migrationsClass = new Migrations();
        $migrations = [];
        $pluginMigrations = [];
        $plugins = Plugin::loaded();
        foreach ($plugins as $plugin) {
            $statuses = $migrationsClass->status(['plugin' => $plugin]);
            $path = Plugin::path($plugin) . 'config' . DS . 'Migrations' . DS;
            if (@$handle = opendir($path)) {
                while (false !== ($entry = readdir($handle))) {
                    if ($entry != "." && $entry != "..") {
                        $timestamp = substr($entry, 0, 14);
                        if(!is_numeric($timestamp)) {
                            continue;
                        }

                        foreach($statuses as $status){
                            if ($status['status'] == 'up' && $status['id'] === $timestamp) {
                                continue(2);
                            }
                        }

                        $migrations[] = $timestamp;
                        $pluginMigrations[$timestamp] = $plugin;
                    }
                }
                closedir($handle);
            }
        }

        sort($migrations);

        foreach ($migrations as $timestamp) {
            $this->dispatchShell(
                'migrations',
                'migrate',
                '-p',
                $pluginMigrations[$timestamp],
                '-t',
                $timestamp
            ); 
        }
    }
}

答案 3 :(得分:0)

之前的答案对我的 Cake ~4.1.0 应用程序不太适用,因为此后发生了各种弃用,所以我做了一些调整。也许对其他人有用。这是在scr/Command/MigrationsCommand.php

declare(strict_types=1);

namespace App\Command;

use Cake\Command\Command;
use Cake\Console\Arguments;
use Cake\Console\ConsoleIo;
use Cake\Console\ConsoleOptionParser;
use Cake\Core\Plugin;
use Migrations\Command\MigrationsMigrateCommand;

class MigrationsCommand extends Command
{
    protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
    {
        $parser->addArgument('plugins', ['help' => 'Run all plugin migrations']);

        return $parser;
    }

    public function execute(Arguments $args, ConsoleIo $io): ?int
    {
        if($args->getArgument('plugins'))
        {
            $plugins = Plugin::loaded();
            $migrations = new MigrationsMigrateCommand();

            foreach ($plugins as $plugin) {
                $io->out('Run migrations for ' . $plugin . ':');

                $this->executeCommand(
                    $migrations,
                    [
                        '-p',
                        $plugin
                    ]
                );
            }
        }

        return null;
    }
}

我使用:

cake migrations plugins

请注意,它会尝试所有您的插件。这会导致它为没有定义迁移的插件抛出错误。你可以解决这个问题,但我对这种行为没有意见。