ateCommand.php$0   A
last analyzed

Complexity

Total Complexity 2

Size/Duplication

Total Lines 8
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 10
wmc 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * Copyright (C) 2020-2025 Iain Cambridge
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as published by
10
 * the Free Software Foundation, either version 2.1 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
namespace Parthenon\MultiTenancy\Command;
23
24
use Doctrine\Migrations\Configuration\Configuration;
0 ignored issues
show
Bug introduced by
The type Doctrine\Migrations\Configuration\Configuration was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
use Doctrine\Migrations\Configuration\EntityManager\EntityManagerLoader;
0 ignored issues
show
Bug introduced by
The type Doctrine\Migrations\Conf...ger\EntityManagerLoader was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
26
use Doctrine\Migrations\Configuration\Migration\ConfigurationLoader;
0 ignored issues
show
Bug introduced by
The type Doctrine\Migrations\Conf...ion\ConfigurationLoader was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
27
use Doctrine\Migrations\DependencyFactory;
0 ignored issues
show
Bug introduced by
The type Doctrine\Migrations\DependencyFactory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
use Doctrine\ORM\EntityManagerInterface;
29
use Doctrine\Persistence\ManagerRegistry;
30
use Parthenon\Common\LoggerAwareTrait;
31
use Parthenon\MultiTenancy\Dbal\TenantConnection;
32
use Parthenon\MultiTenancy\Entity\Tenant;
33
use Parthenon\MultiTenancy\Repository\TenantRepositoryInterface;
34
use Parthenon\MultiTenancy\TenantProvider\TenantProviderInterface;
35
use Parthenon\MultiTenancy\TenantProvider\TestCurrentTenantProvider;
36
use Symfony\Component\Console\Attribute\AsCommand;
37
use Symfony\Component\Console\Command\Command;
38
use Symfony\Component\Console\Input\ArrayInput;
39
use Symfony\Component\Console\Input\InputArgument;
40
use Symfony\Component\Console\Input\InputInterface;
41
use Symfony\Component\Console\Input\InputOption;
42
use Symfony\Component\Console\Output\OutputInterface;
43
44
#[AsCommand(name: 'parthenon:multi-tenancy:migrate', aliases: ['p:m:m'])]
45
class MigrateCommand extends Command
46
{
47
    use LoggerAwareTrait;
48
49
    public function __construct(
50
        private TenantRepositoryInterface $tenantRepository,
51
        private TenantProviderInterface $tenantProvider,
52
        private TenantConnection $tenantConnection,
53
        private ManagerRegistry $managerRegistry,
54
        private string $migrationsDirectory,
55
        private string $entityManagerName,
56
        private bool $enabled,
57
    ) {
58
        parent::__construct(null);
59
    }
60
61
    protected function configure()
62
    {
63
        $this
64
            ->addArgument('version', InputArgument::OPTIONAL, 'The version number (YYYYMMDDHHMMSS) or alias (first, prev, next, latest) to migrate to.', 'latest')
65
            ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Execute the migration as a dry run.');
66
    }
67
68
    protected function execute(InputInterface $input, OutputInterface $output): int
69
    {
70
        $output->writeln('Starting Parthenon Multi-Tenancy Migrations');
71
        $this->getLogger()->info('Starting Parthenon Multi-Tenancy Migrations');
72
73
        if (!$this->enabled) {
74
            $output->writeln('Multi-Tenancy is not enabled');
75
            $this->getLogger()->warning('Multi-Tenancy is not enabled');
76
77
            return 1;
78
        }
79
80
        $this->tenantConnection->setCurrentTenantProvider($this->tenantProvider);
81
82
        $lastId = null;
83
        do {
84
            $results = $this->tenantRepository->getList(lastId: $lastId);
85
            /** @var Tenant $result */
86
            foreach ($results->getResults() as $result) {
87
                $this->getLogger()->info('Handling migrations for tenant.', ['tenant_subdomain' => $result->getSubdomain()]);
88
                $output->writeln('Handling migrations for '.$result->getSubdomain());
89
90
                TestCurrentTenantProvider::setTenantInfo($result->getDatabase(), $result->getSubdomain());
91
                $this->tenantConnection->connect(true);
92
93
                $this->executeMigrations($input, $output);
94
                $lastId = $result->getId();
95
            }
96
        } while ($results->hasMore());
97
98
        return 0;
99
    }
100
101
    protected function getDependencyFactory(): DependencyFactory
102
    {
103
        $em = $this->managerRegistry->getManager($this->entityManagerName);
104
        $a = new Configuration();
105
        $a->addMigrationsDirectory('DoctrineMigrations', $this->migrationsDirectory);
106
        $a->setAllOrNothing(false);
107
        $a->setCheckDatabasePlatform(true);
108
        $a->setTransactional(true);
109
        $a->setMetadataStorageConfiguration(new \Doctrine\Migrations\Metadata\Storage\TableMetadataStorageConfiguration());
0 ignored issues
show
Bug introduced by
The type Doctrine\Migrations\Meta...ataStorageConfiguration was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
110
111
        $configLoader = $this->getConfigLoader($a);
112
        $emLoader = $this->getEmLoader($em);
113
114
        return DependencyFactory::fromEntityManager($configLoader, $emLoader);
115
    }
116
117
    protected function executeMigrations(InputInterface $input, OutputInterface $output)
118
    {
119
        $newInput = new ArrayInput([
120
            'version' => $input->getArgument('version'),
121
            '--dry-run' => $input->getOption('dry-run'),
122
        ]);
123
        $newInput->setInteractive(false);
124
        $otherCommand = new \Doctrine\Migrations\Tools\Console\Command\MigrateCommand($this->getDependencyFactory());
0 ignored issues
show
Bug introduced by
The type Doctrine\Migrations\Tool...\Command\MigrateCommand was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
125
        $otherCommand->run($newInput, $output);
126
    }
127
128
    protected function getConfigLoader(Configuration $a)
129
    {
130
        $configLoader = new class($a) implements ConfigurationLoader {
131
            public function __construct(private $a)
132
            {
133
            }
134
135
            public function getConfiguration(): Configuration
136
            {
137
                return $this->a;
138
            }
139
        };
140
141
        return $configLoader;
142
    }
143
144
    protected function getEmLoader(\Doctrine\Persistence\ObjectManager $em)
145
    {
146
        $emLoader = new class($em) implements EntityManagerLoader {
147
            public function __construct(private $em)
148
            {
149
            }
150
151
            public function getEntityManager(?string $name = null): EntityManagerInterface
152
            {
153
                return $this->em;
154
            }
155
        };
156
157
        return $emLoader;
158
    }
159
}
160