diff --git a/README.md b/README.md index 406430d4..48b6c8d0 100755 --- a/README.md +++ b/README.md @@ -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 diff --git a/composer.json b/composer.json index cc271be5..083e9ed6 100644 --- a/composer.json +++ b/composer.json @@ -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.*", diff --git a/composer.lock b/composer.lock index 065c2397..bc43fad8 100644 --- a/composer.lock +++ b/composer.lock @@ -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", diff --git a/config/bundles.php b/config/bundles.php index a21beb84..fc49295e 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -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], ]; diff --git a/docs/vocabulary.md b/docs/vocabulary.md new file mode 100644 index 00000000..4ad47446 --- /dev/null +++ b/docs/vocabulary.md @@ -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. \ No newline at end of file diff --git a/migrations/Version20250214102008.php b/migrations/Version20250214102008.php new file mode 100644 index 00000000..dc22247d --- /dev/null +++ b/migrations/Version20250214102008.php @@ -0,0 +1,39 @@ +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'); + } +} diff --git a/migrations/Version20250214102313.php b/migrations/Version20250214102313.php new file mode 100644 index 00000000..48404002 --- /dev/null +++ b/migrations/Version20250214102313.php @@ -0,0 +1,47 @@ +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'); + } +} diff --git a/migrations/Version20250214103429.php b/migrations/Version20250214103429.php new file mode 100644 index 00000000..ee4846af --- /dev/null +++ b/migrations/Version20250214103429.php @@ -0,0 +1,31 @@ +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'); + } +} diff --git a/src/Controller/AccountController.php b/src/Controller/AccountController.php new file mode 100644 index 00000000..f44bed13 --- /dev/null +++ b/src/Controller/AccountController.php @@ -0,0 +1,27 @@ +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', [ + ]); + } +} diff --git a/src/Controller/DefaultController.php b/src/Controller/DefaultController.php index 48244b1e..930b9fa5 100644 --- a/src/Controller/DefaultController.php +++ b/src/Controller/DefaultController.php @@ -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(), ]); } diff --git a/src/Controller/SecurityController.php b/src/Controller/SecurityController.php new file mode 100644 index 00000000..5e4022d1 --- /dev/null +++ b/src/Controller/SecurityController.php @@ -0,0 +1,32 @@ +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.'); + } +} diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/AppFixtures.php new file mode 100644 index 00000000..edfba27e --- /dev/null +++ b/src/DataFixtures/AppFixtures.php @@ -0,0 +1,59 @@ +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(); + } +} diff --git a/src/Entity/Festival.php b/src/Entity/Festival.php index 86e3fd41..09b6ad20 100644 --- a/src/Entity/Festival.php +++ b/src/Entity/Festival.php @@ -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 + */ + #[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 + */ + 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; + } } diff --git a/src/Entity/Product.php b/src/Entity/Product.php index 3ce16226..651a072d 100644 --- a/src/Entity/Product.php +++ b/src/Entity/Product.php @@ -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; + } } diff --git a/src/Entity/Selling.php b/src/Entity/Selling.php index 46341f5e..3b7f5bbc 100644 --- a/src/Entity/Selling.php +++ b/src/Entity/Selling.php @@ -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; + } } diff --git a/src/Entity/SerieFestival.php b/src/Entity/SerieFestival.php new file mode 100644 index 00000000..00de936b --- /dev/null +++ b/src/Entity/SerieFestival.php @@ -0,0 +1,109 @@ + + */ + #[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 + */ + 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; + } +} diff --git a/src/Entity/User.php b/src/Entity/User.php index 2bf95170..d60c20fc 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -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 */ @@ -72,6 +81,13 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\OneToMany(targetEntity: Category::class, mappedBy: 'user')] private Collection $categories; + /** + * @var Collection + */ + #[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 + */ + 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; + } + } diff --git a/src/Repository/SerieFestivalRepository.php b/src/Repository/SerieFestivalRepository.php new file mode 100644 index 00000000..f2072ab3 --- /dev/null +++ b/src/Repository/SerieFestivalRepository.php @@ -0,0 +1,43 @@ + + */ +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() + // ; + // } +} diff --git a/symfony.lock b/symfony.lock index d81cd171..40b82e79 100644 --- a/symfony.lock +++ b/symfony.lock @@ -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": { diff --git a/templates/toMigrate/seriefestival/index.html.twig b/templates/toMigrate/seriefestival/index.html.twig index d76570ee..186221e9 100755 --- a/templates/toMigrate/seriefestival/index.html.twig +++ b/templates/toMigrate/seriefestival/index.html.twig @@ -20,7 +20,7 @@ Id Name - Datecreation + dateCreation Actions