Skip to content

Commit

Permalink
chore(seeder): add seeders
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tomudding committed Oct 23, 2024
1 parent e31363b commit 0bc1dea
Show file tree
Hide file tree
Showing 9 changed files with 477 additions and 2 deletions.
6 changes: 6 additions & 0 deletions module/Application/config/module.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Application;

use Application\Command\LoadFixtures;
use Application\Controller\Factory\IndexControllerFactory;
use Application\Controller\IndexController;
use Application\View\Helper\BootstrapElementError;
Expand Down Expand Up @@ -148,6 +149,11 @@
'message_separator_string' => '</li><li>',
],
],
'laminas-cli' => [
'commands' => [
'application:fixtures:load' => LoadFixtures::class,
],
],
'doctrine' => [
'driver' => [
__NAMESPACE__ . '_driver' => [
Expand Down
24 changes: 24 additions & 0 deletions module/Application/src/Command/Factory/LoadFixturesFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Application\Command\Factory;

use Application\Command\LoadFixtures;
use Doctrine\ORM\EntityManager;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Psr\Container\ContainerInterface;

class LoadFixturesFactory implements FactoryInterface
{
public function __invoke(

Check failure on line 14 in module/Application/src/Command/Factory/LoadFixturesFactory.php

View workflow job for this annotation

GitHub Actions / PHPStan

Parameter #2 $requestedName (string) of method Application\Command\Factory\LoadFixturesFactory::__invoke() is not contravariant with parameter #2 $requestedName (mixed) of method Laminas\ServiceManager\Factory\FactoryInterface::__invoke().
ContainerInterface $container,
string $requestedName,

Check failure on line 16 in module/Application/src/Command/Factory/LoadFixturesFactory.php

View workflow job for this annotation

GitHub Actions / Psalm

MethodSignatureMismatch

module/Application/src/Command/Factory/LoadFixturesFactory.php:16:16: MethodSignatureMismatch: Argument 2 of Application\Command\Factory\LoadFixturesFactory::__invoke has wrong type 'string', expecting '' as defined by Laminas\ServiceManager\Factory\FactoryInterface::__invoke (see https://psalm.dev/042)
?array $options = null,
): LoadFixtures {
/** @var EntityManager $entityManager */
$entityManager = $container->get('doctrine.entitymanager.orm_default');

return new LoadFixtures($entityManager);
}
}
68 changes: 68 additions & 0 deletions module/Application/src/Command/LoadFixtures.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

declare(strict_types=1);

namespace Application\Command;

use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\Loader;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Throwable;

#[AsCommand(
name: 'application:fixtures:load',
description: 'Seed the database with data fixtures.',
)]
class LoadFixtures extends Command
{
private const array FIXTURES = [
// './module/Activity/test/Seeder',
// './module/Company/test/Seeder',
'./module/Decision/test/Seeder',
// './module/Education/test/Seeder',
// './module/Frontpage/test/Seeder',
// './module/Photo/test/Seeder',
'./module/User/test/Seeder',
];

public function __construct(private readonly EntityManager $entityManager)
{
parent::__construct();
}

protected function execute(
InputInterface $input,
OutputInterface $output,
): int {
$loader = new Loader();
$purger = new ORMPurger();
$purger->setPurgeMode(ORMPurger::PURGE_MODE_TRUNCATE);
$executor = new ORMExecutor($this->entityManager, $purger);

foreach ($this::FIXTURES as $fixture) {
$loader->loadFromDirectory($fixture);
}

$output->writeln('<info>Loading fixtures into the database...</info>');

$connection = $this->entityManager->getConnection();
try {
// Temporarily disable FK constraint checks. This is necessary because large parts of our database do not have

Check warning on line 55 in module/Application/src/Command/LoadFixtures.php

View workflow job for this annotation

GitHub Actions / php-codesniffer / PHP_CodeSniffer (8.3)

Line exceeds 120 characters; contains 122 characters
// explicit CASCADEs set to prevent data loss when syncing with ReportDB (GEWISDB).
// The try-catch is necessary to hide some error messages (because the executeStatement).
$connection->executeStatement('SET FOREIGN_KEY_CHECKS = 0');
$executor->execute($loader->getFixtures());
$connection->executeStatement('SET FOREIGN_KEY_CHECKS = 1');
} catch (Throwable) {
}

$output->writeln('<info>Loaded fixtures!</info>');

return Command::SUCCESS;
}
}
3 changes: 3 additions & 0 deletions module/Application/src/Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Application;

use Application\Command\Factory\LoadFixturesFactory as LoadFixturesCommandFactory;
use Application\Command\LoadFixtures as LoadFixturesCommand;
use Application\Extensions\CommonMark\CompanyImage\CompanyImageExtension;
use Application\Extensions\CommonMark\NoImage\NoImageExtension;
use Application\Extensions\CommonMark\VideoIframe\VideoIframeExtension;
Expand Down Expand Up @@ -266,6 +268,7 @@ public function generateSignature(

return new UrlBuilder($config['glide']['base_url'], $signature);
},
LoadFixturesCommand::class => LoadFixturesCommandFactory::class,
],
];
}
Expand Down
4 changes: 2 additions & 2 deletions module/Decision/src/Model/AssociationYear.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class AssociationYear
/**
* A GEWIS association year starts 01-07.
*/
public const ASSOCIATION_YEAR_START_MONTH = 7;
public const ASSOCIATION_YEAR_START_DAY = 1;
public const int ASSOCIATION_YEAR_START_MONTH = 7;
public const int ASSOCIATION_YEAR_START_DAY = 1;

/** @var int the first calendar year of the association year */
protected int $firstYear;
Expand Down
Loading

0 comments on commit 0bc1dea

Please sign in to comment.