up schema

This commit is contained in:
Tykayn 2025-02-14 12:35:48 +01:00 committed by tykayn
parent 17e7fce7f8
commit 8e2da4f159
20 changed files with 879 additions and 4 deletions

View File

@ -7,6 +7,8 @@ Self hosted mobile and desktop Cash register and money management for your small
![alt_text][screenshot_home]
A Symfony project created on March 23, 2018.
Updated to Symfony 7 in 2025.
A note about vocabulary used in this project is available in the [vocabulary.md](docs/vocabulary.md) file.
## Features:
* live selling and stock update on phone and desktop

View File

@ -103,6 +103,8 @@
}
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^4.0",
"fakerphp/faker": "^1.24",
"phpunit/phpunit": "^9.5",
"symfony/browser-kit": "7.2.*",
"symfony/css-selector": "7.2.*",

234
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "404da16a19217b5f3b63c6d75d781c24",
"content-hash": "0d0236f64fc9e381cfc8b6c8c46ac667",
"packages": [
{
"name": "api-platform/doctrine-common",
@ -9195,6 +9195,238 @@
}
],
"packages-dev": [
{
"name": "doctrine/data-fixtures",
"version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/doctrine/data-fixtures.git",
"reference": "f7f1e12d6bceb58c204b3e77210a103c1c57601e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/f7f1e12d6bceb58c204b3e77210a103c1c57601e",
"reference": "f7f1e12d6bceb58c204b3e77210a103c1c57601e",
"shasum": ""
},
"require": {
"doctrine/persistence": "^3.1 || ^4.0",
"php": "^8.1",
"psr/log": "^1.1 || ^2 || ^3"
},
"conflict": {
"doctrine/dbal": "<3.5 || >=5",
"doctrine/orm": "<2.14 || >=4",
"doctrine/phpcr-odm": "<1.3.0"
},
"require-dev": {
"doctrine/coding-standard": "^12",
"doctrine/dbal": "^3.5 || ^4",
"doctrine/mongodb-odm": "^1.3.0 || ^2.0.0",
"doctrine/orm": "^2.14 || ^3",
"ext-sqlite3": "*",
"fig/log-test": "^1",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^10.5.3",
"symfony/cache": "^6.4 || ^7",
"symfony/var-exporter": "^6.4 || ^7"
},
"suggest": {
"alcaeus/mongo-php-adapter": "For using MongoDB ODM 1.3 with PHP 7 (deprecated)",
"doctrine/mongodb-odm": "For loading MongoDB ODM fixtures",
"doctrine/orm": "For loading ORM fixtures",
"doctrine/phpcr-odm": "For loading PHPCR ODM fixtures"
},
"type": "library",
"autoload": {
"psr-4": {
"Doctrine\\Common\\DataFixtures\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
}
],
"description": "Data Fixtures for all Doctrine Object Managers",
"homepage": "https://www.doctrine-project.org",
"keywords": [
"database"
],
"support": {
"issues": "https://github.com/doctrine/data-fixtures/issues",
"source": "https://github.com/doctrine/data-fixtures/tree/2.0.2"
},
"funding": [
{
"url": "https://www.doctrine-project.org/sponsorship.html",
"type": "custom"
},
{
"url": "https://www.patreon.com/phpdoctrine",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdata-fixtures",
"type": "tidelift"
}
],
"time": "2025-01-21T13:21:31+00:00"
},
{
"name": "doctrine/doctrine-fixtures-bundle",
"version": "4.0.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/DoctrineFixturesBundle.git",
"reference": "90185317e6bb3d845667c5ebd444d9c83ae19a01"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/90185317e6bb3d845667c5ebd444d9c83ae19a01",
"reference": "90185317e6bb3d845667c5ebd444d9c83ae19a01",
"shasum": ""
},
"require": {
"doctrine/data-fixtures": "^2.0",
"doctrine/doctrine-bundle": "^2.2",
"doctrine/orm": "^2.14.0 || ^3.0",
"doctrine/persistence": "^2.4 || ^3.0",
"php": "^8.1",
"psr/log": "^2 || ^3",
"symfony/config": "^5.4 || ^6.0 || ^7.0",
"symfony/console": "^5.4 || ^6.0 || ^7.0",
"symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0",
"symfony/deprecation-contracts": "^2.1 || ^3",
"symfony/doctrine-bridge": "^5.4.48 || ^6.4.16 || ^7.1.9",
"symfony/http-kernel": "^5.4 || ^6.0 || ^7.0"
},
"conflict": {
"doctrine/dbal": "< 3"
},
"require-dev": {
"doctrine/coding-standard": "^12",
"phpstan/phpstan": "^2",
"phpunit/phpunit": "^10.5.38 || ^11"
},
"type": "symfony-bundle",
"autoload": {
"psr-4": {
"Doctrine\\Bundle\\FixturesBundle\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Doctrine Project",
"homepage": "https://www.doctrine-project.org"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony DoctrineFixturesBundle",
"homepage": "https://www.doctrine-project.org",
"keywords": [
"Fixture",
"persistence"
],
"support": {
"issues": "https://github.com/doctrine/DoctrineFixturesBundle/issues",
"source": "https://github.com/doctrine/DoctrineFixturesBundle/tree/4.0.0"
},
"funding": [
{
"url": "https://www.doctrine-project.org/sponsorship.html",
"type": "custom"
},
{
"url": "https://www.patreon.com/phpdoctrine",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdoctrine-fixtures-bundle",
"type": "tidelift"
}
],
"time": "2024-12-05T18:35:55+00:00"
},
{
"name": "fakerphp/faker",
"version": "v1.24.1",
"source": {
"type": "git",
"url": "https://github.com/FakerPHP/Faker.git",
"reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5",
"reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0",
"psr/container": "^1.0 || ^2.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0"
},
"conflict": {
"fzaninotto/faker": "*"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.4.1",
"doctrine/persistence": "^1.3 || ^2.0",
"ext-intl": "*",
"phpunit/phpunit": "^9.5.26",
"symfony/phpunit-bridge": "^5.4.16"
},
"suggest": {
"doctrine/orm": "Required to use Faker\\ORM\\Doctrine",
"ext-curl": "Required by Faker\\Provider\\Image to download images.",
"ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.",
"ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.",
"ext-mbstring": "Required for multibyte Unicode string functionality."
},
"type": "library",
"autoload": {
"psr-4": {
"Faker\\": "src/Faker/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "François Zaninotto"
}
],
"description": "Faker is a PHP library that generates fake data for you.",
"keywords": [
"data",
"faker",
"fixtures"
],
"support": {
"issues": "https://github.com/FakerPHP/Faker/issues",
"source": "https://github.com/FakerPHP/Faker/tree/v1.24.1"
},
"time": "2024-11-21T13:46:39+00:00"
},
{
"name": "masterminds/html5",
"version": "2.9.0",

View File

@ -18,4 +18,5 @@ return [
Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true],
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
];

5
docs/vocabulary.md Normal file
View File

@ -0,0 +1,5 @@
# Vocabulary
The **users** are the central place for the vocabulary. They are managing the Caisse by having access to the **selling** history, their **products** are sold during **festivals** which can be parts of a **serie of festivals**.
These words are conveying concepts that are linked to the database to ease the production of statistics which you can check in your user space.

View File

@ -0,0 +1,39 @@
<?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 Version20250214102008 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('ALTER TABLE festival ADD frais_inscription DOUBLE PRECISION DEFAULT NULL, ADD fond_de_caisse_avant DOUBLE PRECISION DEFAULT NULL, ADD fond_de_caisse_apres DOUBLE PRECISION DEFAULT NULL, ADD date_creation DATE NOT NULL');
$this->addSql('ALTER TABLE product ADD image VARCHAR(255) NOT NULL, ADD comment VARCHAR(500) DEFAULT NULL');
$this->addSql('ALTER TABLE selling ADD festival_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE selling ADD CONSTRAINT FK_5A491BAB8AEBAF57 FOREIGN KEY (festival_id) REFERENCES festival (id)');
$this->addSql('CREATE INDEX IDX_5A491BAB8AEBAF57 ON selling (festival_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE festival DROP frais_inscription, DROP fond_de_caisse_avant, DROP fond_de_caisse_apres, DROP date_creation');
$this->addSql('ALTER TABLE selling DROP FOREIGN KEY FK_5A491BAB8AEBAF57');
$this->addSql('DROP INDEX IDX_5A491BAB8AEBAF57 ON selling');
$this->addSql('ALTER TABLE selling DROP festival_id');
$this->addSql('ALTER TABLE product DROP image, DROP comment');
}
}

View File

@ -0,0 +1,47 @@
<?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 Version20250214102313 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 serie_festival (id INT AUTO_INCREMENT NOT NULL, user_id INT DEFAULT NULL, name VARCHAR(255) NOT NULL, date_creation DATE NOT NULL, INDEX IDX_4DFA58B1A76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE serie_festival ADD CONSTRAINT FK_4DFA58B1A76ED395 FOREIGN KEY (user_id) REFERENCES user (id)');
$this->addSql('ALTER TABLE festival ADD serie_festival_id INT DEFAULT NULL, ADD frais_inscription DOUBLE PRECISION DEFAULT NULL, ADD fond_de_caisse_avant DOUBLE PRECISION DEFAULT NULL, ADD fond_de_caisse_apres DOUBLE PRECISION DEFAULT NULL, ADD date_creation DATE NOT NULL');
$this->addSql('ALTER TABLE festival ADD CONSTRAINT FK_57CF7898DD79D04 FOREIGN KEY (serie_festival_id) REFERENCES serie_festival (id)');
$this->addSql('CREATE INDEX IDX_57CF7898DD79D04 ON festival (serie_festival_id)');
$this->addSql('ALTER TABLE product ADD image VARCHAR(255) NOT NULL, ADD comment VARCHAR(500) DEFAULT NULL');
$this->addSql('ALTER TABLE selling ADD festival_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE selling ADD CONSTRAINT FK_5A491BAB8AEBAF57 FOREIGN KEY (festival_id) REFERENCES festival (id)');
$this->addSql('CREATE INDEX IDX_5A491BAB8AEBAF57 ON selling (festival_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE festival DROP FOREIGN KEY FK_57CF7898DD79D04');
$this->addSql('ALTER TABLE serie_festival DROP FOREIGN KEY FK_4DFA58B1A76ED395');
$this->addSql('DROP TABLE serie_festival');
$this->addSql('DROP INDEX IDX_57CF7898DD79D04 ON festival');
$this->addSql('ALTER TABLE festival DROP serie_festival_id, DROP frais_inscription, DROP fond_de_caisse_avant, DROP fond_de_caisse_apres, DROP date_creation');
$this->addSql('ALTER TABLE selling DROP FOREIGN KEY FK_5A491BAB8AEBAF57');
$this->addSql('DROP INDEX IDX_5A491BAB8AEBAF57 ON selling');
$this->addSql('ALTER TABLE selling DROP festival_id');
$this->addSql('ALTER TABLE product DROP image, DROP comment');
}
}

View File

@ -0,0 +1,31 @@
<?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 Version20250214103429 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('ALTER TABLE user ADD last_login DATE DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE user DROP last_login');
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class AccountController extends AbstractController
{
#[Route('/account', name: 'app_account')]
public function index(): Response
{
return $this->render('account/index.html.twig', [
'controller_name' => 'AccountController',
]);
}
/***
page d'exemple
**/
#[Route('/account/history', name: 'app_account_history')]
public function history(): Response
{
return $this->render('account/history.html.twig', [
]);
}
}

View File

@ -5,6 +5,7 @@ namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
final class DefaultController extends AbstractController
{
@ -94,12 +95,15 @@ final class DefaultController extends AbstractController
#[Route('/logged/get-my-products', name: 'get_my_products')]
public function get_my_products(): Response
public function get_my_products(): JsonResponse
{
// TODO: replace this with actual logic to get products of the logged user
// récupérer les produits de l'user connecté
$products = $this->getUser()->get_my_products();
return $this->json([
'mock_response' => 'TODO',
'products' => $products,
'user' => $this->getUser(),
]);
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends AbstractController
{
#[Route(path: '/login', name: 'app_login')]
public function login(AuthenticationUtils $authenticationUtils): Response
{
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
]);
}
#[Route(path: '/logout', name: 'app_logout')]
public function logout(): void
{
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\DataFixtures;
use Doctrine\Persistence\ObjectManager;
use App\Entity\Product;
use App\Entity\User;
use Faker\Factory;
use Faker\Generator;
use Doctrine\Bundle\FixturesBundle\Fixture;
class AppFixtures extends Fixture
{
/**
* @var Generator
*/
private Generator $faker;
public function __construct()
{
$this->faker = Factory::create('fr_FR');
}
public function load(ObjectManager $manager): void
{
$demoUser = new User();
$demoUser->setName('demo')
->setEmail('demo@example.com')
// ->setRoles(['ROLE_ADMIN'])
->setPassword('demo');
;
for ($i=1; $i <= 5; $i++) {
$product = new Group();
}
for ($i=1; $i <= 5; $i++) {
$product = new Product();
$product
->setName($this->faker->sentence(2))
->setPrice($this->faker->randomFloat(2, 1, 100))
->setImage($this->faker->imageUrl(640, 480))
->setStock($this->faker->numberBetween(1, 100))
->setComment($this->faker->text(200))
;
$demoUser->addProduct($product);
$product->setUser($demoUser);
$manager->persist($product);
}
$manager->persist($demoUser);
$manager->flush();
}
}

View File

@ -34,9 +34,31 @@ class Festival
#[ORM\ManyToOne(inversedBy: 'festivals')]
private ?User $user = null;
#[ORM\Column(nullable: true)]
private ?float $fraisInscription = null;
#[ORM\Column(nullable: true)]
private ?float $fondDeCaisseAvant = null;
#[ORM\Column(nullable: true)]
private ?float $fondDeCaisseApres = null;
#[ORM\Column(type: Types::DATE_MUTABLE)]
private ?\DateTimeInterface $dateCreation = null;
/**
* @var Collection<int, Selling>
*/
#[ORM\OneToMany(targetEntity: Selling::class, mappedBy: 'festival')]
private Collection $sellings;
#[ORM\ManyToOne(inversedBy: 'festivals')]
private ?SerieFestival $serieFestival = null;
public function __construct()
{
$this->users = new ArrayCollection();
$this->sellings = new ArrayCollection();
}
public function getId(): ?int
@ -121,4 +143,94 @@ class Festival
return $this;
}
public function getFraisInscription(): ?float
{
return $this->fraisInscription;
}
public function setFraisInscription(?float $fraisInscription): static
{
$this->fraisInscription = $fraisInscription;
return $this;
}
public function getFondDeCaisseAvant(): ?float
{
return $this->fondDeCaisseAvant;
}
public function setFondDeCaisseAvant(?float $fondDeCaisseAvant): static
{
$this->fondDeCaisseAvant = $fondDeCaisseAvant;
return $this;
}
public function getFondDeCaisseApres(): ?float
{
return $this->fondDeCaisseApres;
}
public function setFondDeCaisseApres(?float $fondDeCaisseApres): static
{
$this->fondDeCaisseApres = $fondDeCaisseApres;
return $this;
}
public function getDateCreation(): ?\DateTimeInterface
{
return $this->dateCreation;
}
public function setDateCreation(\DateTimeInterface $dateCreation): static
{
$this->dateCreation = $dateCreation;
return $this;
}
/**
* @return Collection<int, Selling>
*/
public function getSellings(): Collection
{
return $this->sellings;
}
public function addSelling(Selling $selling): static
{
if (!$this->sellings->contains($selling)) {
$this->sellings->add($selling);
$selling->setFestival($this);
}
return $this;
}
public function removeSelling(Selling $selling): static
{
if ($this->sellings->removeElement($selling)) {
// set the owning side to null (unless already changed)
if ($selling->getFestival() === $this) {
$selling->setFestival(null);
}
}
return $this;
}
public function getSerieFestival(): ?SerieFestival
{
return $this->serieFestival;
}
public function setSerieFestival(?SerieFestival $serieFestival): static
{
$this->serieFestival = $serieFestival;
return $this;
}
}

View File

@ -39,6 +39,12 @@ class Product
#[ORM\ManyToOne(inversedBy: 'products')]
private ?User $user = null;
#[ORM\Column(length: 255)]
private ?string $image = null;
#[ORM\Column(length: 500, nullable: true)]
private ?string $comment = null;
public function __construct()
{
$this->groupOfProducts = new ArrayCollection();
@ -151,4 +157,28 @@ class Product
return $this;
}
public function getImage(): ?string
{
return $this->image;
}
public function setImage(string $image): static
{
$this->image = $image;
return $this;
}
public function getComment(): ?string
{
return $this->comment;
}
public function setComment(?string $comment): static
{
$this->comment = $comment;
return $this;
}
}

View File

@ -37,6 +37,9 @@ class Selling
#[ORM\ManyToMany(targetEntity: Product::class, inversedBy: 'sellings')]
private Collection $products;
#[ORM\ManyToOne(inversedBy: 'sellings')]
private ?Festival $festival = null;
public function __construct()
{
$this->groupOfProducts = new ArrayCollection();
@ -138,4 +141,16 @@ class Selling
return $this;
}
public function getFestival(): ?Festival
{
return $this->festival;
}
public function setFestival(?Festival $festival): static
{
$this->festival = $festival;
return $this;
}
}

View File

@ -0,0 +1,109 @@
<?php
namespace App\Entity;
use App\Repository\SerieFestivalRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: SerieFestivalRepository::class)]
class SerieFestival
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $name = null;
/**
* @var Collection<int, Festival>
*/
#[ORM\OneToMany(targetEntity: Festival::class, mappedBy: 'serieFestival')]
private Collection $festivals;
#[ORM\Column(type: Types::DATE_MUTABLE)]
private ?\DateTimeInterface $dateCreation = null;
#[ORM\ManyToOne(inversedBy: 'seriesFestival')]
private ?User $user = null;
public function __construct()
{
$this->festivals = new ArrayCollection();
}
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;
}
/**
* @return Collection<int, Festival>
*/
public function getFestivals(): Collection
{
return $this->festivals;
}
public function addFestival(Festival $festival): static
{
if (!$this->festivals->contains($festival)) {
$this->festivals->add($festival);
$festival->setSerieFestival($this);
}
return $this;
}
public function removeFestival(Festival $festival): static
{
if ($this->festivals->removeElement($festival)) {
// set the owning side to null (unless already changed)
if ($festival->getSerieFestival() === $this) {
$festival->setSerieFestival(null);
}
}
return $this;
}
public function getDateCreation(): ?\DateTimeInterface
{
return $this->dateCreation;
}
public function setDateCreation(\DateTimeInterface $dateCreation): static
{
$this->dateCreation = $dateCreation;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): static
{
$this->user = $user;
return $this;
}
}

View File

@ -21,6 +21,10 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $name = null;
#[ORM\Column(length: 180)]
private ?string $email = null;
@ -39,9 +43,14 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
#[ORM\Column]
private bool $isVerified = false;
#[ORM\Column(type: Types::DATE_MUTABLE, nullable: true)]
private ?\DateTimeInterface $last_login = null;
#[ORM\ManyToOne(inversedBy: 'users')]
private ?Festival $currentFestival = null;
/**
* @var Collection<int, Expense>
*/
@ -72,6 +81,13 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
#[ORM\OneToMany(targetEntity: Category::class, mappedBy: 'user')]
private Collection $categories;
/**
* @var Collection<int, SerieFestival>
*/
#[ORM\OneToMany(targetEntity: SerieFestival::class, mappedBy: 'user')]
private Collection $seriesFestival;
public function __construct()
{
$this->expenses = new ArrayCollection();
@ -79,6 +95,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
$this->groupOfProducts = new ArrayCollection();
$this->festivals = new ArrayCollection();
$this->categories = new ArrayCollection();
$this->seriesFestival = new ArrayCollection();
}
public function getId(): ?int
@ -345,4 +362,60 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
return $this;
}
/**
* @return Collection<int, SerieFestival>
*/
public function getSeriesFestival(): Collection
{
return $this->seriesFestival;
}
public function addSeriesFestival(SerieFestival $seriesFestival): static
{
if (!$this->seriesFestival->contains($seriesFestival)) {
$this->seriesFestival->add($seriesFestival);
$seriesFestival->setUser($this);
}
return $this;
}
public function removeSeriesFestival(SerieFestival $seriesFestival): static
{
if ($this->seriesFestival->removeElement($seriesFestival)) {
// set the owning side to null (unless already changed)
if ($seriesFestival->getUser() === $this) {
$seriesFestival->setUser(null);
}
}
return $this;
}
public function getLastLogin(): ?\DateTimeInterface
{
return $this->last_login;
}
public function setLastLogin(?\DateTimeInterface $last_login): static
{
$this->last_login = $last_login;
return $this;
}
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\SerieFestival;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<SerieFestival>
*/
class SerieFestivalRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, SerieFestival::class);
}
// /**
// * @return SerieFestival[] Returns an array of SerieFestival 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): ?SerieFestival
// {
// return $this->createQueryBuilder('s')
// ->andWhere('s.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

View File

@ -27,6 +27,18 @@
"src/Repository/.gitignore"
]
},
"doctrine/doctrine-fixtures-bundle": {
"version": "4.0",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "3.0",
"ref": "1f5514cfa15b947298df4d771e694e578d4c204d"
},
"files": [
"src/DataFixtures/AppFixtures.php"
]
},
"doctrine/doctrine-migrations-bundle": {
"version": "3.4",
"recipe": {

View File

@ -20,7 +20,7 @@
<tr>
<th>Id</th>
<th>Name</th>
<th>Datecreation</th>
<th>dateCreation</th>
<th>Actions</th>
</tr>
</thead>