Compare commits

...

2 commits

Author SHA1 Message Date
1963855c64 Add subject, show subjects 2026-06-02 20:01:42 +00:00
6c7abd9725 Rename IndexController to SubjectController 2026-06-02 18:30:18 +00:00
16 changed files with 313 additions and 34 deletions

View file

@ -103,6 +103,7 @@
} }
}, },
"require-dev": { "require-dev": {
"dama/doctrine-test-bundle": "^8.6",
"phpstan/extension-installer": "^1.4", "phpstan/extension-installer": "^1.4",
"phpstan/phpstan": "^2.2", "phpstan/phpstan": "^2.2",
"phpstan/phpstan-doctrine": "^2.0", "phpstan/phpstan-doctrine": "^2.0",

71
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "6aa0596ff046b9df530a9c0757f8d54e", "content-hash": "cd40b73a97f584ed609ab7a2dca91ce9",
"packages": [ "packages": [
{ {
"name": "composer/semver", "name": "composer/semver",
@ -7703,6 +7703,75 @@
} }
], ],
"packages-dev": [ "packages-dev": [
{
"name": "dama/doctrine-test-bundle",
"version": "v8.6.0",
"source": {
"type": "git",
"url": "https://github.com/dmaicher/doctrine-test-bundle.git",
"reference": "f7e3487643e685432f7e27c50cac64e9f8c515a4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dmaicher/doctrine-test-bundle/zipball/f7e3487643e685432f7e27c50cac64e9f8c515a4",
"reference": "f7e3487643e685432f7e27c50cac64e9f8c515a4",
"shasum": ""
},
"require": {
"doctrine/dbal": "^3.3 || ^4.0",
"doctrine/doctrine-bundle": "^2.11.0 || ^3.0",
"php": ">= 8.2",
"psr/cache": "^2.0 || ^3.0",
"symfony/cache": "^6.4 || ^7.3 || ^8.0",
"symfony/framework-bundle": "^6.4 || ^7.3 || ^8.0"
},
"conflict": {
"phpunit/phpunit": "<11.0"
},
"require-dev": {
"behat/behat": "^3.0",
"friendsofphp/php-cs-fixer": "^3.27",
"phpstan/phpstan": "^2.0",
"phpunit/phpunit": "^11.5.41|| ^12.3.14",
"symfony/dotenv": "^6.4 || ^7.3 || ^8.0",
"symfony/process": "^6.4 || ^7.3 || ^8.0"
},
"type": "symfony-bundle",
"extra": {
"branch-alias": {
"dev-master": "8.x-dev"
}
},
"autoload": {
"psr-4": {
"DAMA\\DoctrineTestBundle\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "David Maicher",
"email": "mail@dmaicher.de"
}
],
"description": "Symfony bundle to isolate doctrine database tests and improve test performance",
"keywords": [
"doctrine",
"isolation",
"performance",
"symfony",
"testing",
"tests"
],
"support": {
"issues": "https://github.com/dmaicher/doctrine-test-bundle/issues",
"source": "https://github.com/dmaicher/doctrine-test-bundle/tree/v8.6.0"
},
"time": "2026-01-21T07:39:44+00:00"
},
{ {
"name": "myclabs/deep-copy", "name": "myclabs/deep-copy",
"version": "1.13.4", "version": "1.13.4",

View file

@ -13,4 +13,5 @@ return [
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true],
]; ];

View file

@ -0,0 +1,5 @@
when@test:
dama_doctrine_test:
enable_static_connection: true
enable_static_meta_data_cache: true
enable_static_query_cache: true

View file

@ -1474,6 +1474,12 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* generate_final_classes?: bool|Param, // Default: true * generate_final_classes?: bool|Param, // Default: true
* generate_final_entities?: bool|Param, // Default: false * generate_final_entities?: bool|Param, // Default: false
* } * }
* @psalm-type DamaDoctrineTestConfig = array{
* enable_static_connection?: mixed, // Default: true
* enable_static_meta_data_cache?: bool|Param, // Default: true
* enable_static_query_cache?: bool|Param, // Default: true
* connection_keys?: list<mixed>,
* }
* @psalm-type ConfigType = array{ * @psalm-type ConfigType = array{
* imports?: ImportsConfig, * imports?: ImportsConfig,
* parameters?: ParametersConfig, * parameters?: ParametersConfig,
@ -1532,6 +1538,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* twig_extra?: TwigExtraConfig, * twig_extra?: TwigExtraConfig,
* security?: SecurityConfig, * security?: SecurityConfig,
* monolog?: MonologConfig, * monolog?: MonologConfig,
* dama_doctrine_test?: DamaDoctrineTestConfig,
* }, * },
* ...<string, ExtensionType|array{ // extra keys must follow the when@%env% pattern or match an extension alias * ...<string, ExtensionType|array{ // extra keys must follow the when@%env% pattern or match an extension alias
* imports?: ImportsConfig, * imports?: ImportsConfig,

View file

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20260602195404 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE subject (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, name VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, PRIMARY KEY (id))');
$this->addSql('CREATE TABLE messenger_messages (id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, body TEXT NOT NULL, headers TEXT NOT NULL, queue_name VARCHAR(190) NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, available_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, delivered_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, PRIMARY KEY (id))');
$this->addSql('CREATE INDEX IDX_75EA56E0FB7336F0E3BD61CE16BA31DBBF396750 ON messenger_messages (queue_name, available_at, delivered_at, id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP TABLE subject');
$this->addSql('DROP TABLE messenger_messages');
}
}

View file

@ -40,5 +40,6 @@
</source> </source>
<extensions> <extensions>
<bootstrap class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension" />
</extensions> </extensions>
</phpunit> </phpunit>

View file

@ -1,16 +0,0 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class IndexController extends AbstractController
{
#[Route('/')]
public function index(): Response
{
return $this->render('index/page.html.twig');
}
}

View file

@ -0,0 +1,54 @@
<?php
namespace App\Controller;
use App\Entity\Restaurant;
use App\Repository\SubjectRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class SubjectController extends AbstractController
{
#[Route('/')]
public function index(
Request $request,
EntityManagerInterface $em,
SubjectRepository $repo,
): Response {
$subject = new Restaurant();
$subject->setName("MyRestaurant");
$form = $this->createFormBuilder($subject)
->add('name', TextType::class)
->add('save', SubmitType::class)
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($subject);
$em->flush();
return $this->redirectToRoute('app_subject_index');
}
$subjects = $repo->findAll();
return $this->render('index/page.html.twig', [
'form' => $form,
'subjects' => $subjects,
]);
}
#[Route('/', 'subject_new', methods: ["POST"])]
public function save(): RedirectResponse
{
return $this->redirect('/');
}
}

11
src/Entity/Restaurant.php Normal file
View file

@ -0,0 +1,11 @@
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class Restaurant extends Subject
{
//
}

39
src/Entity/Subject.php Normal file
View file

@ -0,0 +1,39 @@
<?php
namespace App\Entity;
use App\Entity\Restaurant;
use App\Repository\SubjectRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: SubjectRepository::class)]
#[ORM\InheritanceType('SINGLE_TABLE')]
#[ORM\DiscriminatorColumn(name: 'type', type: 'string')]
#[ORM\DiscriminatorMap(['restaurant' => Restaurant::class])]
class Subject
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $name = null;
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): static
{
$this->name = $name;
return $this;
}
}

View file

@ -0,0 +1,43 @@
<?php
namespace App\Repository;
use App\Entity\Subject;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<Subject>
*/
class SubjectRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Subject::class);
}
// /**
// * @return Subject[] Returns an array of Subject objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('s')
// ->andWhere('s.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('s.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?Subject
// {
// return $this->createQueryBuilder('s')
// ->andWhere('s.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

View file

@ -1,4 +1,16 @@
{ {
"dama/doctrine-test-bundle": {
"version": "8.6",
"recipe": {
"repo": "github.com/symfony/recipes-contrib",
"branch": "main",
"version": "8.3",
"ref": "dfc51177476fb39d014ed89944cde53dc3326d23"
},
"files": [
"config/packages/dama_doctrine_test_bundle.yaml"
]
},
"doctrine/deprecations": { "doctrine/deprecations": {
"version": "1.1", "version": "1.1",
"recipe": { "recipe": {

View file

@ -4,5 +4,13 @@
</head> </head>
<body> <body>
<h1>Rater</h1> <h1>Rater</h1>
{{ form(form) }}
<h2>Existing</h2>
<ul>
{% for subject in subjects %}
<li>{{ subject.name }}</li>
{% endfor %}
</ul>
</body> </body>
</html> </html>

View file

@ -1,17 +0,0 @@
<?php
namespace App\Tests\Integration\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class IndexControllerTest extends WebTestCase
{
public function testSomething(): void
{
$client = static::createClient();
$crawler = $client->request('GET', '/');
$this->assertResponseIsSuccessful();
$this->assertSelectorTextContains('h1', 'Rater');
}
}

View file

@ -0,0 +1,27 @@
<?php
namespace App\Tests\Integration\Controller;
use App\Entity\Restaurant;
use App\Repository\SubjectRepository;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class SubjectControllerTest extends WebTestCase
{
public function testAddingNewSubject(): void
{
$client = static::createClient();
$crawler = $client->request('GET', '/');
$client->submitForm('form_save', ['form[name]' => 'Riviera']);
$this->assertResponseRedirects();
$subject = static::getContainer()
->get(SubjectRepository::class)
->findOneBy(['name' => 'Riviera']);
$this->assertNotNull($subject);
$this->assertInstanceOf(Restaurant::class, $subject);
}
}