Skip to content

Commit 79f0b99

Browse files
committed
fix: content migrations not marked as executed by default
1 parent b2a6406 commit 79f0b99

2 files changed

Lines changed: 65 additions & 2 deletions

File tree

src/EventListener/ContentListener.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo;
1010
use Psr\Log\LoggerInterface;
1111
use Symfony\Component\DependencyInjection\Attribute\Autowire;
12+
use Symfony\Component\DependencyInjection\ContainerInterface;
1213
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
1314
use vardumper\IbexaAutomaticMigrationsBundle\Helper\Helper;
1415
use vardumper\IbexaAutomaticMigrationsBundle\Process\MigrationRunnerInterface;
@@ -22,14 +23,18 @@ final class ContentListener
2223
private string $destination;
2324
private array $consoleCommand;
2425
private MigrationRunnerInterface $migrationRunner;
26+
private ContainerInterface $container;
2527

2628
public function __construct(
2729
private readonly LoggerInterface $logger,
2830
private readonly \vardumper\IbexaAutomaticMigrationsBundle\Service\SettingsService $settingsService,
2931
#[Autowire('%kernel.project_dir%')]
3032
string $projectDir,
33+
#[Autowire(service: 'service_container')]
34+
ContainerInterface $container,
3135
?MigrationRunnerInterface $migrationRunner = null,
3236
) {
37+
$this->container = $container;
3338
$this->migrationRunner = $migrationRunner ?? new SymfonyProcessRunner();
3439
$this->projectDir = rtrim($projectDir, DIRECTORY_SEPARATOR);
3540
$this->isCli = PHP_SAPI === 'cli' && ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) !== 'testing';
@@ -129,6 +134,59 @@ private function generateMigration(ContentInfo $contentInfo, string $mode): void
129134
$this->migrationRunner->run($cmd, $this->projectDir);
130135
$code = $this->migrationRunner->getExitCode();
131136
$this->logger->info('Content migration generate process finished', ['name' => $name, 'code' => $code, 'output' => $this->migrationRunner->getOutput(), 'error' => $this->migrationRunner->getErrorOutput()]);
137+
138+
if ($code == 0) {
139+
if ($this->mode === 'ibexa') {
140+
$fileName = $inputArray['--file'];
141+
} else {
142+
$files = glob($this->destination . DIRECTORY_SEPARATOR . '*.{yml,yaml}', GLOB_BRACE);
143+
$latestFile = '';
144+
$latestTime = 0;
145+
foreach ($files as $file) {
146+
$mtime = filemtime($file);
147+
if ($mtime > $latestTime) {
148+
$latestTime = $mtime;
149+
$latestFile = $file;
150+
}
151+
}
152+
if ($latestFile) {
153+
$fileName = basename($latestFile);
154+
} else {
155+
$this->logger->warning('No migration files found after generation');
156+
return;
157+
}
158+
}
159+
160+
$fullPath = $this->destination . DIRECTORY_SEPARATOR . $fileName;
161+
162+
try {
163+
$conn = $this->container->get('doctrine.dbal.default_connection');
164+
if ($this->mode === 'ibexa') {
165+
$data = ['executed_at' => new \DateTime(), 'execution_time' => null];
166+
$identifier = ['name' => $fileName];
167+
$affected = $conn->update('ibexa_migrations', $data, $identifier);
168+
if ($affected === 0) {
169+
$conn->insert('ibexa_migrations', array_merge($identifier, $data));
170+
}
171+
} elseif ($this->mode === 'kaliop') {
172+
$data = ['execution_date' => time(), 'status' => 2];
173+
$identifier = ['migration' => $fileName];
174+
$affected = $conn->update('kaliop_migrations', $data, $identifier);
175+
if ($affected === 0) {
176+
$conn->insert('kaliop_migrations', array_merge($identifier, $data, [
177+
'md5' => md5_file($fullPath),
178+
'path' => $fullPath,
179+
'execution_error' => null,
180+
]));
181+
}
182+
}
183+
$this->logger->info('Content migration marked as executed', ['filename' => $fileName, 'mode' => $this->mode]);
184+
} catch (\Throwable $e) {
185+
$this->logger->warning('Failed to mark content migration as executed', ['exception' => $e->getMessage()]);
186+
}
187+
} else {
188+
$this->logger->error('Content migration generation failed', ['code' => $code, 'error' => $this->migrationRunner->getErrorOutput()]);
189+
}
132190
} catch (\Throwable $e) {
133191
$this->logger->error('Failed to generate content migration programmatically', ['exception' => $e->getMessage()]);
134192
}

tests/Unit/EventListener/ContentListenerTest.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
$this->listener = new ContentListener(
1818
new NullLogger(),
1919
makeSettingsService($this->tmpDir, true, ['content' => true]),
20-
$this->tmpDir
20+
$this->tmpDir,
21+
makeContainer()
2122
);
2223

2324
$contentInfo = new ContentInfo(['id' => 1, 'mainLocationId' => 2]);
@@ -73,7 +74,8 @@
7374
$listener = new ContentListener(
7475
new NullLogger(),
7576
makeSettingsService($this->tmpDir, true, ['content' => false]),
76-
$this->tmpDir
77+
$this->tmpDir,
78+
makeContainer()
7779
);
7880
expect(fn () => $listener->onPublished($this->publishCreateEvent))->not->toThrow(\Throwable::class);
7981
} finally {
@@ -134,6 +136,7 @@
134136
new NullLogger(),
135137
makeSettingsService($this->tmpDir, true, ['content' => true]),
136138
$this->tmpDir,
139+
makeContainer(),
137140
makeFakeRunner(0)
138141
));
139142

@@ -145,6 +148,7 @@
145148
new NullLogger(),
146149
makeSettingsService($this->tmpDir, true, ['content' => true]),
147150
$this->tmpDir,
151+
makeContainer(),
148152
makeFakeRunner(1, '', 'boom')
149153
));
150154

@@ -156,6 +160,7 @@
156160
new NullLogger(),
157161
makeSettingsService($this->tmpDir, true, ['content' => true]),
158162
$this->tmpDir,
163+
makeContainer(),
159164
makeFakeRunner(1, '', 'ibexa-fail')
160165
));
161166
setPrivateProperty($listener, 'mode', 'ibexa');

0 commit comments

Comments
 (0)