Skip to content

Commit 0bc1dea

Browse files
committed
chore(seeder): add seeders
The data fixtures can be loaded into the database using the `application:fixtures:load` command. All existing records are `TRUNCATE`d from the database to ensure a clean start.
1 parent e31363b commit 0bc1dea

File tree

9 files changed

+477
-2
lines changed

9 files changed

+477
-2
lines changed

module/Application/config/module.config.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Application;
66

7+
use Application\Command\LoadFixtures;
78
use Application\Controller\Factory\IndexControllerFactory;
89
use Application\Controller\IndexController;
910
use Application\View\Helper\BootstrapElementError;
@@ -148,6 +149,11 @@
148149
'message_separator_string' => '</li><li>',
149150
],
150151
],
152+
'laminas-cli' => [
153+
'commands' => [
154+
'application:fixtures:load' => LoadFixtures::class,
155+
],
156+
],
151157
'doctrine' => [
152158
'driver' => [
153159
__NAMESPACE__ . '_driver' => [
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Application\Command\Factory;
6+
7+
use Application\Command\LoadFixtures;
8+
use Doctrine\ORM\EntityManager;
9+
use Laminas\ServiceManager\Factory\FactoryInterface;
10+
use Psr\Container\ContainerInterface;
11+
12+
class LoadFixturesFactory implements FactoryInterface
13+
{
14+
public function __invoke(
15+
ContainerInterface $container,
16+
string $requestedName,
17+
?array $options = null,
18+
): LoadFixtures {
19+
/** @var EntityManager $entityManager */
20+
$entityManager = $container->get('doctrine.entitymanager.orm_default');
21+
22+
return new LoadFixtures($entityManager);
23+
}
24+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Application\Command;
6+
7+
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
8+
use Doctrine\Common\DataFixtures\Loader;
9+
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
10+
use Doctrine\ORM\EntityManager;
11+
use Symfony\Component\Console\Attribute\AsCommand;
12+
use Symfony\Component\Console\Command\Command;
13+
use Symfony\Component\Console\Input\InputInterface;
14+
use Symfony\Component\Console\Output\OutputInterface;
15+
use Throwable;
16+
17+
#[AsCommand(
18+
name: 'application:fixtures:load',
19+
description: 'Seed the database with data fixtures.',
20+
)]
21+
class LoadFixtures extends Command
22+
{
23+
private const array FIXTURES = [
24+
// './module/Activity/test/Seeder',
25+
// './module/Company/test/Seeder',
26+
'./module/Decision/test/Seeder',
27+
// './module/Education/test/Seeder',
28+
// './module/Frontpage/test/Seeder',
29+
// './module/Photo/test/Seeder',
30+
'./module/User/test/Seeder',
31+
];
32+
33+
public function __construct(private readonly EntityManager $entityManager)
34+
{
35+
parent::__construct();
36+
}
37+
38+
protected function execute(
39+
InputInterface $input,
40+
OutputInterface $output,
41+
): int {
42+
$loader = new Loader();
43+
$purger = new ORMPurger();
44+
$purger->setPurgeMode(ORMPurger::PURGE_MODE_TRUNCATE);
45+
$executor = new ORMExecutor($this->entityManager, $purger);
46+
47+
foreach ($this::FIXTURES as $fixture) {
48+
$loader->loadFromDirectory($fixture);
49+
}
50+
51+
$output->writeln('<info>Loading fixtures into the database...</info>');
52+
53+
$connection = $this->entityManager->getConnection();
54+
try {
55+
// Temporarily disable FK constraint checks. This is necessary because large parts of our database do not have
56+
// explicit CASCADEs set to prevent data loss when syncing with ReportDB (GEWISDB).
57+
// The try-catch is necessary to hide some error messages (because the executeStatement).
58+
$connection->executeStatement('SET FOREIGN_KEY_CHECKS = 0');
59+
$executor->execute($loader->getFixtures());
60+
$connection->executeStatement('SET FOREIGN_KEY_CHECKS = 1');
61+
} catch (Throwable) {
62+
}
63+
64+
$output->writeln('<info>Loaded fixtures!</info>');
65+
66+
return Command::SUCCESS;
67+
}
68+
}

module/Application/src/Module.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace Application;
66

7+
use Application\Command\Factory\LoadFixturesFactory as LoadFixturesCommandFactory;
8+
use Application\Command\LoadFixtures as LoadFixturesCommand;
79
use Application\Extensions\CommonMark\CompanyImage\CompanyImageExtension;
810
use Application\Extensions\CommonMark\NoImage\NoImageExtension;
911
use Application\Extensions\CommonMark\VideoIframe\VideoIframeExtension;
@@ -266,6 +268,7 @@ public function generateSignature(
266268

267269
return new UrlBuilder($config['glide']['base_url'], $signature);
268270
},
271+
LoadFixturesCommand::class => LoadFixturesCommandFactory::class,
269272
],
270273
];
271274
}

module/Decision/src/Model/AssociationYear.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ class AssociationYear
1515
/**
1616
* A GEWIS association year starts 01-07.
1717
*/
18-
public const ASSOCIATION_YEAR_START_MONTH = 7;
19-
public const ASSOCIATION_YEAR_START_DAY = 1;
18+
public const int ASSOCIATION_YEAR_START_MONTH = 7;
19+
public const int ASSOCIATION_YEAR_START_DAY = 1;
2020

2121
/** @var int the first calendar year of the association year */
2222
protected int $firstYear;

0 commit comments

Comments
 (0)