Compare commits

..

No commits in common. 'cleo' and 'main' have entirely different histories.
cleo ... main

@ -17,6 +17,7 @@
"phpstan/phpdoc-parser": "^1.14", "phpstan/phpdoc-parser": "^1.14",
"symfony/asset": "6.1.*", "symfony/asset": "6.1.*",
"symfony/console": "6.1.*", "symfony/console": "6.1.*",
"symfony/doctrine-messenger": "6.1.*",
"symfony/dotenv": "6.1.*", "symfony/dotenv": "6.1.*",
"symfony/expression-language": "6.1.*", "symfony/expression-language": "6.1.*",
"symfony/flex": "^2", "symfony/flex": "^2",
@ -31,7 +32,7 @@
"symfony/process": "6.1.*", "symfony/process": "6.1.*",
"symfony/property-access": "6.1.*", "symfony/property-access": "6.1.*",
"symfony/property-info": "6.1.*", "symfony/property-info": "6.1.*",
"symfony/runtime": "^6.3.2", "symfony/runtime": "6.1.*",
"symfony/security-bundle": "6.1.*", "symfony/security-bundle": "6.1.*",
"symfony/serializer": "6.1.*", "symfony/serializer": "6.1.*",
"symfony/string": "6.1.*", "symfony/string": "6.1.*",

223
composer.lock generated

@ -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": "a904471bc7e1136f2c1810044504fcc9", "content-hash": "d0596df364527b4a2e7e00a9d7213e87",
"packages": [ "packages": [
{ {
"name": "doctrine/cache", "name": "doctrine/cache",
@ -2558,6 +2558,78 @@
], ],
"time": "2023-01-10T18:53:01+00:00" "time": "2023-01-10T18:53:01+00:00"
}, },
{
"name": "symfony/doctrine-messenger",
"version": "v6.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/doctrine-messenger.git",
"reference": "e4b775d2dadcc801d2404c701555c2638690811e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/e4b775d2dadcc801d2404c701555c2638690811e",
"reference": "e4b775d2dadcc801d2404c701555c2638690811e",
"shasum": ""
},
"require": {
"doctrine/dbal": "^2.13|^3.0",
"php": ">=8.1",
"symfony/messenger": "^5.4|^6.0",
"symfony/service-contracts": "^1.1|^2|^3"
},
"conflict": {
"doctrine/persistence": "<1.3"
},
"require-dev": {
"doctrine/persistence": "^1.3|^2|^3",
"symfony/property-access": "^5.4|^6.0",
"symfony/serializer": "^5.4|^6.0"
},
"type": "symfony-messenger-bridge",
"autoload": {
"psr-4": {
"Symfony\\Component\\Messenger\\Bridge\\Doctrine\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Doctrine Messenger Bridge",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/doctrine-messenger/tree/v6.1.11"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2023-01-01T08:36:55+00:00"
},
{ {
"name": "symfony/dotenv", "name": "symfony/dotenv",
"version": "v6.1.11", "version": "v6.1.11",
@ -3053,16 +3125,16 @@
}, },
{ {
"name": "symfony/flex", "name": "symfony/flex",
"version": "v2.7.1", "version": "v2.7.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/flex.git", "url": "https://github.com/symfony/flex.git",
"reference": "4ae50d368415a06820739e54d38a4a29d6df9155" "reference": "5d743b3b78fabe9f3146586d77b0a1f9292851fc"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/flex/zipball/4ae50d368415a06820739e54d38a4a29d6df9155", "url": "https://api.github.com/repos/symfony/flex/zipball/5d743b3b78fabe9f3146586d77b0a1f9292851fc",
"reference": "4ae50d368415a06820739e54d38a4a29d6df9155", "reference": "5d743b3b78fabe9f3146586d77b0a1f9292851fc",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3101,7 +3173,7 @@
"description": "Composer plugin for Symfony", "description": "Composer plugin for Symfony",
"support": { "support": {
"issues": "https://github.com/symfony/flex/issues", "issues": "https://github.com/symfony/flex/issues",
"source": "https://github.com/symfony/flex/tree/v2.7.1" "source": "https://github.com/symfony/flex/tree/v2.7.0"
}, },
"funding": [ "funding": [
{ {
@ -3117,7 +3189,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-05-28T14:22:54+00:00" "time": "2025-05-23T11:41:40+00:00"
}, },
{ {
"name": "symfony/form", "name": "symfony/form",
@ -3873,6 +3945,92 @@
], ],
"time": "2023-01-10T18:53:01+00:00" "time": "2023-01-10T18:53:01+00:00"
}, },
{
"name": "symfony/messenger",
"version": "v6.1.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/messenger.git",
"reference": "e3b7323b1d59fc77f5870735809bf39ce1596aee"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/messenger/zipball/e3b7323b1d59fc77f5870735809bf39ce1596aee",
"reference": "e3b7323b1d59fc77f5870735809bf39ce1596aee",
"shasum": ""
},
"require": {
"php": ">=8.1",
"psr/log": "^1|^2|^3"
},
"conflict": {
"symfony/event-dispatcher": "<5.4",
"symfony/event-dispatcher-contracts": "<2",
"symfony/framework-bundle": "<5.4",
"symfony/http-kernel": "<5.4",
"symfony/serializer": "<5.4"
},
"require-dev": {
"psr/cache": "^1.0|^2.0|^3.0",
"symfony/console": "^5.4|^6.0",
"symfony/dependency-injection": "^5.4|^6.0",
"symfony/event-dispatcher": "^5.4|^6.0",
"symfony/http-kernel": "^5.4|^6.0",
"symfony/process": "^5.4|^6.0",
"symfony/property-access": "^5.4|^6.0",
"symfony/routing": "^5.4|^6.0",
"symfony/serializer": "^5.4|^6.0",
"symfony/service-contracts": "^1.1|^2|^3",
"symfony/stopwatch": "^5.4|^6.0",
"symfony/validator": "^5.4|^6.0"
},
"suggest": {
"enqueue/messenger-adapter": "For using the php-enqueue library as a transport."
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Messenger\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Samuel Roze",
"email": "samuel.roze@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Helps applications send and receive messages to/from other applications or via message queues",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/messenger/tree/v6.1.11"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2023-01-20T17:44:30+00:00"
},
{ {
"name": "symfony/mime", "name": "symfony/mime",
"version": "v6.1.11", "version": "v6.1.11",
@ -5135,16 +5293,16 @@
}, },
{ {
"name": "symfony/runtime", "name": "symfony/runtime",
"version": "v6.4.22", "version": "v6.1.11",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/runtime.git", "url": "https://github.com/symfony/runtime.git",
"reference": "832c3ce3b810509815050434ccb7ead68d06395b" "reference": "717cb91d66893a27a4607f227e28eb74ff007fde"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/runtime/zipball/832c3ce3b810509815050434ccb7ead68d06395b", "url": "https://api.github.com/repos/symfony/runtime/zipball/717cb91d66893a27a4607f227e28eb74ff007fde",
"reference": "832c3ce3b810509815050434ccb7ead68d06395b", "reference": "717cb91d66893a27a4607f227e28eb74ff007fde",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5156,10 +5314,10 @@
}, },
"require-dev": { "require-dev": {
"composer/composer": "^1.0.2|^2.0", "composer/composer": "^1.0.2|^2.0",
"symfony/console": "^5.4.9|^6.0.9|^7.0", "symfony/console": "^5.4|^6.0",
"symfony/dotenv": "^5.4|^6.0|^7.0", "symfony/dotenv": "^5.4|^6.0",
"symfony/http-foundation": "^5.4|^6.0|^7.0", "symfony/http-foundation": "^5.4|^6.0",
"symfony/http-kernel": "^5.4|^6.0|^7.0" "symfony/http-kernel": "^5.4|^6.0"
}, },
"type": "composer-plugin", "type": "composer-plugin",
"extra": { "extra": {
@ -5190,11 +5348,8 @@
], ],
"description": "Enables decoupling PHP applications from global state", "description": "Enables decoupling PHP applications from global state",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"keywords": [
"runtime"
],
"support": { "support": {
"source": "https://github.com/symfony/runtime/tree/v6.4.22" "source": "https://github.com/symfony/runtime/tree/v6.1.11"
}, },
"funding": [ "funding": [
{ {
@ -5210,7 +5365,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-05-07T21:15:03+00:00" "time": "2023-01-20T17:44:30+00:00"
}, },
{ {
"name": "symfony/security-bundle", "name": "symfony/security-bundle",
@ -6468,16 +6623,16 @@
}, },
{ {
"name": "symfony/var-exporter", "name": "symfony/var-exporter",
"version": "v6.4.22", "version": "v6.4.21",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-exporter.git", "url": "https://github.com/symfony/var-exporter.git",
"reference": "f28cf841f5654955c9f88ceaf4b9dc29571988a9" "reference": "717e7544aa99752c54ecba5c0e17459c48317472"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/f28cf841f5654955c9f88ceaf4b9dc29571988a9", "url": "https://api.github.com/repos/symfony/var-exporter/zipball/717e7544aa99752c54ecba5c0e17459c48317472",
"reference": "f28cf841f5654955c9f88ceaf4b9dc29571988a9", "reference": "717e7544aa99752c54ecba5c0e17459c48317472",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -6525,7 +6680,7 @@
"serialize" "serialize"
], ],
"support": { "support": {
"source": "https://github.com/symfony/var-exporter/tree/v6.4.22" "source": "https://github.com/symfony/var-exporter/tree/v6.4.21"
}, },
"funding": [ "funding": [
{ {
@ -6541,7 +6696,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-05-14T13:00:13+00:00" "time": "2025-04-27T21:06:26+00:00"
}, },
{ {
"name": "symfony/web-link", "name": "symfony/web-link",
@ -8990,16 +9145,16 @@
}, },
{ {
"name": "symfony/phpunit-bridge", "name": "symfony/phpunit-bridge",
"version": "v7.3.0", "version": "v7.2.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/phpunit-bridge.git", "url": "https://github.com/symfony/phpunit-bridge.git",
"reference": "2eabda563921f21cbce1d1e3247b3c36568905e6" "reference": "6106ae85a0e3ed509d339b7f924788c9cc4e7cfb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/2eabda563921f21cbce1d1e3247b3c36568905e6", "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/6106ae85a0e3ed509d339b7f924788c9cc4e7cfb",
"reference": "2eabda563921f21cbce1d1e3247b3c36568905e6", "reference": "6106ae85a0e3ed509d339b7f924788c9cc4e7cfb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -9052,7 +9207,7 @@
"description": "Provides utilities for PHPUnit, especially user deprecation notices management", "description": "Provides utilities for PHPUnit, especially user deprecation notices management",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/phpunit-bridge/tree/v7.3.0" "source": "https://github.com/symfony/phpunit-bridge/tree/v7.2.6"
}, },
"funding": [ "funding": [
{ {
@ -9068,7 +9223,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-05-23T07:26:30+00:00" "time": "2025-04-09T08:35:42+00:00"
}, },
{ {
"name": "symfony/web-profiler-bundle", "name": "symfony/web-profiler-bundle",
@ -9201,7 +9356,7 @@
], ],
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": [], "stability-flags": {},
"prefer-stable": true, "prefer-stable": true,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
@ -9209,6 +9364,6 @@
"ext-ctype": "*", "ext-ctype": "*",
"ext-iconv": "*" "ext-iconv": "*"
}, },
"platform-dev": [], "platform-dev": {},
"plugin-api-version": "2.6.0" "plugin-api-version": "2.6.0"
} }

@ -0,0 +1,29 @@
framework:
messenger:
failure_transport: failed
transports:
# https://symfony.com/doc/current/messenger.html#transport-configuration
async:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
options:
use_notify: true
check_delayed_interval: 60000
retry_strategy:
max_retries: 3
multiplier: 2
failed: 'doctrine://default?queue_name=failed'
# sync: 'sync://'
default_bus: messenger.bus.default
buses:
messenger.bus.default: []
routing:
Symfony\Component\Mailer\Messenger\SendEmailMessage: async
Symfony\Component\Notifier\Message\ChatMessage: async
Symfony\Component\Notifier\Message\SmsMessage: async
# Route your messages to the transports
# 'App\Message\YourMessage': async

@ -6,10 +6,6 @@
parameters: parameters:
services: services:
App\Repository\RarityRepository:
public: true
App\Repository\EmojiRepository:
public: true
# default configuration for services in *this* file # default configuration for services in *this* file
_defaults: _defaults:
autowire: true # Automatically injects dependencies in your services. autowire: true # Automatically injects dependencies in your services.

@ -1,48 +0,0 @@
création entity :
php bin/console make:entity Emoji
Réinstaller orm + doctrine_bundle :
composer require doctrine/orm doctrine/doctrine-bundle
Recompiler l'autoload (utile si ça persiste)
- composer dump-autoload
Vérifie ensuite que lentité est bien reconnue :
- php bin/console doctrine:mapping:info
'''Found 1 mapped entity:
[OK] App\Entity\Emoji'''
php bin/console make:migration
php bin/console doctrine:migrations:migrate
-------
Récréation BDD quand pb migrations :
php bin/console doctrine:database:drop --force
php bin/console doctrine:database:create
php bin/console doctrine:migrations:migrate
-------
Solution : Forcer la mise à jour de phpstan/phpdoc-parser
- composer require phpstan/phpdoc-parser:^1.26
Cree la BDD :
''' Modification .env (pour retirer URL_BDD)
Ajout .env.local (pour ajouter URL_BDD)'''
- symfony console doctrine:database:create
ok j'ai creer ma BDD avec symfony console doctrine:database:create comment j'applique mon entity dans la BDD que j'avais créer précedement avec symfony console

@ -10,7 +10,7 @@ use Doctrine\Migrations\AbstractMigration;
/** /**
* Auto-generated Migration: Please modify to your needs! * Auto-generated Migration: Please modify to your needs!
*/ */
final class Version20250529203532 extends AbstractMigration final class Version20250528130332 extends AbstractMigration
{ {
public function getDescription(): string public function getDescription(): string
{ {
@ -24,10 +24,16 @@ final class Version20250529203532 extends AbstractMigration
CREATE TABLE emoji (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, nom VARCHAR(255) NOT NULL, code VARCHAR(255) NOT NULL, force DOUBLE PRECISION NOT NULL, robustesse DOUBLE PRECISION NOT NULL, intelligence DOUBLE PRECISION NOT NULL, vitesse DOUBLE PRECISION NOT NULL, nb_combat_gagne INTEGER NOT NULL, rarete INTEGER NOT NULL) CREATE TABLE emoji (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, nom VARCHAR(255) NOT NULL, code VARCHAR(255) NOT NULL, force DOUBLE PRECISION NOT NULL, robustesse DOUBLE PRECISION NOT NULL, intelligence DOUBLE PRECISION NOT NULL, vitesse DOUBLE PRECISION NOT NULL, nb_combat_gagne INTEGER NOT NULL, rarete INTEGER NOT NULL)
SQL); SQL);
$this->addSql(<<<'SQL' $this->addSql(<<<'SQL'
CREATE TABLE rarity (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name VARCHAR(50) NOT NULL, drop_rate DOUBLE PRECISION NOT NULL) CREATE TABLE messenger_messages (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, body CLOB NOT NULL, headers CLOB NOT NULL, queue_name VARCHAR(190) NOT NULL, created_at DATETIME NOT NULL, available_at DATETIME NOT NULL, delivered_at DATETIME DEFAULT NULL)
SQL); SQL);
$this->addSql(<<<'SQL' $this->addSql(<<<'SQL'
CREATE UNIQUE INDEX UNIQ_B7C0BE465E237E06 ON rarity (name) CREATE INDEX IDX_75EA56E0FB7336F0 ON messenger_messages (queue_name)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX IDX_75EA56E0E3BD61CE ON messenger_messages (available_at)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX IDX_75EA56E016BA31DB ON messenger_messages (delivered_at)
SQL); SQL);
} }
@ -38,7 +44,7 @@ final class Version20250529203532 extends AbstractMigration
DROP TABLE emoji DROP TABLE emoji
SQL); SQL);
$this->addSql(<<<'SQL' $this->addSql(<<<'SQL'
DROP TABLE rarity DROP TABLE messenger_messages
SQL); SQL);
} }
} }

@ -1,62 +0,0 @@
<?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 Version20250529204111 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(<<<'SQL'
CREATE TEMPORARY TABLE __temp__emoji AS SELECT id, nom, code, intelligence FROM emoji
SQL);
$this->addSql(<<<'SQL'
DROP TABLE emoji
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE emoji (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, rarity_id INTEGER NOT NULL, name VARCHAR(255) NOT NULL, code VARCHAR(255) NOT NULL, intelligence DOUBLE PRECISION NOT NULL, strength DOUBLE PRECISION NOT NULL, toughness DOUBLE PRECISION NOT NULL, speed DOUBLE PRECISION NOT NULL, fights_won INTEGER NOT NULL, CONSTRAINT FK_B64BF632F3747573 FOREIGN KEY (rarity_id) REFERENCES rarity (id) NOT DEFERRABLE INITIALLY IMMEDIATE)
SQL);
$this->addSql(<<<'SQL'
INSERT INTO emoji (id, name, code, intelligence) SELECT id, nom, code, intelligence FROM __temp__emoji
SQL);
$this->addSql(<<<'SQL'
DROP TABLE __temp__emoji
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX IDX_B64BF632F3747573 ON emoji (rarity_id)
SQL);
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql(<<<'SQL'
CREATE TEMPORARY TABLE __temp__emoji AS SELECT id, name, code, intelligence FROM emoji
SQL);
$this->addSql(<<<'SQL'
DROP TABLE emoji
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE emoji (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, nom VARCHAR(255) NOT NULL, code VARCHAR(255) NOT NULL, intelligence DOUBLE PRECISION NOT NULL, force DOUBLE PRECISION NOT NULL, robustesse DOUBLE PRECISION NOT NULL, vitesse DOUBLE PRECISION NOT NULL, nb_combat_gagne INTEGER NOT NULL, rarete INTEGER NOT NULL)
SQL);
$this->addSql(<<<'SQL'
INSERT INTO emoji (id, nom, code, intelligence) SELECT id, name, code, intelligence FROM __temp__emoji
SQL);
$this->addSql(<<<'SQL'
DROP TABLE __temp__emoji
SQL);
}
}

@ -1,71 +0,0 @@
<?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 Version20250530163653 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(<<<'SQL'
CREATE TEMPORARY TABLE __temp__emoji AS SELECT id, rarity_id, name, code, intelligence, strength, toughness, speed, fights_won FROM emoji
SQL);
$this->addSql(<<<'SQL'
DROP TABLE emoji
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE emoji (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, rarity_id INTEGER NOT NULL, parent1_id INTEGER DEFAULT NULL, parent2_id INTEGER DEFAULT NULL, name VARCHAR(255) NOT NULL, code VARCHAR(255) NOT NULL, intelligence DOUBLE PRECISION NOT NULL, strength DOUBLE PRECISION NOT NULL, toughness DOUBLE PRECISION NOT NULL, speed DOUBLE PRECISION NOT NULL, fights_won INTEGER NOT NULL, CONSTRAINT FK_B64BF632F3747573 FOREIGN KEY (rarity_id) REFERENCES rarity (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_B64BF632861B2665 FOREIGN KEY (parent1_id) REFERENCES emoji (id) NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_B64BF63294AE898B FOREIGN KEY (parent2_id) REFERENCES emoji (id) NOT DEFERRABLE INITIALLY IMMEDIATE)
SQL);
$this->addSql(<<<'SQL'
INSERT INTO emoji (id, rarity_id, name, code, intelligence, strength, toughness, speed, fights_won) SELECT id, rarity_id, name, code, intelligence, strength, toughness, speed, fights_won FROM __temp__emoji
SQL);
$this->addSql(<<<'SQL'
DROP TABLE __temp__emoji
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX IDX_B64BF632F3747573 ON emoji (rarity_id)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX IDX_B64BF632861B2665 ON emoji (parent1_id)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX IDX_B64BF63294AE898B ON emoji (parent2_id)
SQL);
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql(<<<'SQL'
CREATE TEMPORARY TABLE __temp__emoji AS SELECT id, rarity_id, name, code, strength, toughness, intelligence, speed, fights_won FROM emoji
SQL);
$this->addSql(<<<'SQL'
DROP TABLE emoji
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE emoji (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, rarity_id INTEGER NOT NULL, name VARCHAR(255) NOT NULL, code VARCHAR(255) NOT NULL, strength DOUBLE PRECISION NOT NULL, toughness DOUBLE PRECISION NOT NULL, intelligence DOUBLE PRECISION NOT NULL, speed DOUBLE PRECISION NOT NULL, fights_won INTEGER NOT NULL, CONSTRAINT FK_B64BF632F3747573 FOREIGN KEY (rarity_id) REFERENCES rarity (id) NOT DEFERRABLE INITIALLY IMMEDIATE)
SQL);
$this->addSql(<<<'SQL'
INSERT INTO emoji (id, rarity_id, name, code, strength, toughness, intelligence, speed, fights_won) SELECT id, rarity_id, name, code, strength, toughness, intelligence, speed, fights_won FROM __temp__emoji
SQL);
$this->addSql(<<<'SQL'
DROP TABLE __temp__emoji
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX IDX_B64BF632F3747573 ON emoji (rarity_id)
SQL);
}
}

@ -1,248 +0,0 @@
body {
background-color: #314e57;
font-family: 'Georgia', serif;
text-align: center;
}
h1 {
font-size: 3rem;
margin-bottom: 30px;
text-shadow: 2px 2px 4px #000;
color: #f8b435;
}
.emoji-container {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 30px;
margin-bottom: 10rem;
}
.emoji-card {
background: #f2e6c9;
width: 180px;
height: 220px;
border: 4px solid #000;
border-radius: 12px;
box-shadow: 0 0 20px rgba(0,0,0,0.5);
padding: 20px;
text-align: center;
font-family: 'Georgia', serif;
position: relative;
transition: transform 0.2s ease, box-shadow 0.2s ease;
cursor: pointer;
}
.emoji-card:hover {
transform: translateY(-8px) scale(1.03);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5);
z-index: 2;
}
/* Animation brillance pour rareté légendaire */
@keyframes shine {
0% { background-position: 0px; }
100% { background-position: 177px; }
}
.emoji-card.gold {
position: relative;
z-index: 1;
}
.emoji-card.gold::before {
content: '';
position: absolute;
top: 0;
left: 1%;
width: 98%;
height: 100%;
background: linear-gradient(
120deg,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.5) 50%,
rgba(255, 255, 255, 0) 100%
);
animation: shine 5s infinite;
pointer-events: none;
z-index: -1;
}
.emoji-card > * {
position: relative;
z-index: 1;
}
/*---------------------------*/
.emoji-card.gray { border-color: gray; }
@keyframes auraGlow {
0% { box-shadow: 0 0 10px 0 rgba(0,0,0,0.3); }
50% { box-shadow: 0 0 25px 8px currentColor; }
100% { box-shadow: 0 0 10px 0 rgba(0,0,0,0.3); }
}
/* Applique une animation d'aura par rareté */
.emoji-card.green {
color: darkgreen;
animation: auraGlow 3s infinite ease-in-out;
}
.emoji-card.purple {
color: purple;
animation: auraGlow 3s infinite ease-in-out;
}
.emoji-card.red {
color: darkred;
animation: auraGlow 3s infinite ease-in-out;
}
.emoji-card.gold {
color: goldenrod;
animation: auraGlow 3s infinite ease-in-out;
}
/* Couleurs des noms selon rareté */
.emoji-name.green { color: darkgreen; }
.emoji-name.purple { color: purple; }
.emoji-name.red { color: darkred; }
.emoji-name.gold { color: goldenrod; }
.emoji-name.gray { color: gray; }
.emoji-card .emoji {
font-size: 50px;
margin-bottom: 10px;
}
.emoji-name {
font-weight: bold;
font-size: 1.2rem;
margin-top: 5px;
color: purple;
}
.emoji-level {
font-size: 1rem;
font-weight: bold;
color: #3c2f2f;
margin-bottom: 10px;
}
.action-buttons {
display: flex;
justify-content: center;
gap: 60px;
margin-top: 20px;
}
.btn {
background: #f2e6c9;
border: 3px solid #000;
padding: 10px 25px;
font-size: 1.2rem;
font-weight: bold;
border-radius: 8px;
cursor: pointer;
transition: transform 0.2s ease;
box-shadow: 3px 3px 0 #000;
}
.btn:hover {
transform: scale(1.05);
background-color: #e5d6b8;
}
.detail-icon {
position: absolute;
top: 8px;
right: 10px;
cursor: pointer;
font-size: 18px;
color: #555;
}
.popup {
position: absolute;
top: 110%;
left: 50%;
transform: translateX(-50%);
background: #fff8e1;
color: #000;
padding: 10px;
border: 2px solid #000;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.3);
display: none;
z-index: 10;
width: 180px;
font-size: 14px;
}
/* Filtre et Tri*/
.filter-bar {
margin-bottom: 30px;
color: #f8f5e0;
font-size: 1rem;
}
.filter-bar select {
margin: 0 10px;
padding: 5px 10px;
border-radius: 6px;
border: 2px solid #000;
background: #f2e6c9;
font-family: 'Georgia', serif;
}
/* Champs de Recherche */
.filter-bar input[type="text"] {
padding: 5px 10px;
border-radius: 6px;
border: 2px solid #000;
background: #f2e6c9;
font-family: 'Georgia', serif;
margin-right: 10px;
}
/* Style séléction créature pour combat / accouplement */
/* Etat séléctionné */
.emoji-card.selected {
outline: 4px solid #f8b435;
outline-offset: -4px;
box-shadow: 0 0 30px 10px rgba(248, 180, 53, 0.6);
}
#selection-status {
font-size: 1.1rem;
margin-bottom: 20px;
font-weight: bold;
color: #f9e8c0;
}
.selection-visual {
display: flex;
justify-content: center;
align-items: center;
gap: 15px;
margin-bottom: 30px;
}
.creature-tag {
padding: 8px 15px;
background: #f2e6c9;
border: 2px solid #000;
border-radius: 8px;
font-weight: bold;
font-size: 1.1rem;
box-shadow: 2px 2px 0 #000;
}
.vs-text {
font-size: 1.5rem;
font-weight: bold;
}

@ -1,141 +0,0 @@
document.addEventListener('DOMContentLoaded', () => {
// Copie tout ici
let selectedCards = [];
function toggleSelection(card) {
const id = card.dataset.id;
if (card.classList.contains('selected')) {
card.classList.remove('selected');
selectedCards = selectedCards.filter(c => c.dataset.id !== id);
} else {
if (selectedCards.length < 2) {
card.classList.add('selected');
selectedCards.push(card);
} else {
alert("Tu ne peux sélectionner que 2 créatures à la fois.");
}
}
updateSelectionDisplay();
}
function updateSelectionDisplay() {
const status = document.getElementById("selection-status");
const visual = document.getElementById("selection-visual");
if (selectedCards.length === 0) {
status.textContent = "Sélectionnez 2 créatures...";
visual.innerHTML = "";
} else if (selectedCards.length === 1) {
status.textContent = `1ère sélection : ${selectedCards[0].dataset.name}`;
visual.innerHTML = "";
} else {
status.textContent = "2 créatures sélectionnées !";
visual.innerHTML = `
<div class="creature-tag">${selectedCards[0].dataset.name}</div>
<span class="vs-text"> et </span>
<div class="creature-tag">${selectedCards[1].dataset.name}</div>
`;
}
}
function handleAction(type) {
if (selectedCards.length !== 2) {
alert("Tu dois sélectionner 2 créatures.");
return;
}
const name1 = selectedCards[0].dataset.name;
const name2 = selectedCards[1].dataset.name;
if (type === 'combat') {
console.log(`Combat : ${name1} contre ${name2}`);
} else if (type === 'reproduction') {
console.log(`Accouplement : ${name1} et ${name2}`);
}
// Réinitialiser après l'action
selectedCards.forEach(card => card.classList.remove('selected'));
selectedCards = [];
updateSelectionDisplay();
}
// Ouvre / Ferme la popup d'information
function togglePopup(id) {
const popup = document.getElementById('popup-' + id);
popup.style.display = (popup.style.display === 'block') ? 'none' : 'block';
}
// Fermer les autres popups en cliquant ailleurs
document.addEventListener('click', function(e) {
document.querySelectorAll('.popup').forEach(p => {
if (!p.contains(e.target) && !p.previousElementSibling.contains(e.target)) {
p.style.display = 'none';
}
});
});
// Fonction pour appliquer la recherche, les filtres et le tri
function applyFilters() {
const selectedColor = document.getElementById('rarete-filter').value;
const sortBy = document.getElementById('sort-select').value;
const searchTerm = document.getElementById('search-input').value.toLowerCase();
const cards = Array.from(document.querySelectorAll('.emoji-card'));
cards.forEach(card => {
const color = card.dataset.color;
const name = card.querySelector('.emoji-name')?.textContent.toLowerCase() ?? "";
const matchColor = !selectedColor || color === selectedColor;
const matchName = !searchTerm || name.includes(searchTerm);
if (matchColor && matchName) {
card.style.display = 'block';
} else {
card.style.display = 'none';
}
});
if (sortBy !== 'none') {
const container = document.querySelector('.emoji-container');
const visibleCards = cards.filter(c => c.style.display !== 'none');
visibleCards.sort((a, b) => {
const aVal = parseFloat(a.dataset[sortBy]);
const bVal = parseFloat(b.dataset[sortBy]);
return bVal - aVal;
});
visibleCards.forEach(card => container.appendChild(card));
}
}
// Appel Fonctionnalité de popup d'information
document.querySelectorAll('.detail-icon').forEach(icon => {
icon.addEventListener('click', (e) => {
const id = icon.parentElement.dataset.id;
togglePopup(id);
e.stopPropagation(); // empêche le clic daller à la carte
});
});
// Appel Fonctionnalité de sélection des cartes
document.querySelectorAll('.emoji-card').forEach(card => {
card.addEventListener('click', () => toggleSelection(card));
});
// Appel Fonctionnalité de combat et reproduction
document.querySelectorAll('.btn').forEach(button => {
button.addEventListener('click', () => {
const type = button.textContent.includes('Combattre') ? 'combat' : 'reproduction';
handleAction(type);
});
});
// Appel Fonctionnalité de recherche et filtres
document.getElementById('search-input').addEventListener('input', applyFilters);
document.getElementById('rarete-filter').addEventListener('change', applyFilters);
document.getElementById('sort-select').addEventListener('change', applyFilters);
});

@ -1,62 +0,0 @@
<?php
namespace App\Command;
use Doctrine\DBAL\Connection;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class PopulateDBCommand extends Command
{
protected static $defaultName = 'app:populateDB';
private Connection $connection;
public function __construct(Connection $connection)
{
parent::__construct();
$this->connection = $connection;
}
protected function configure()
{
$this
->setDescription('Populate the database.');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
try {
// On supprime la table si elle existe déjà
$this->connection->executeStatement('DROP TABLE IF EXISTS rarity');
// On crée la table
$this->connection->executeStatement('
CREATE TABLE rarity (
id INT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
drop_rate FLOAT NOT NULL
)
');
// On peuple la table
$this->connection->executeStatement("INSERT INTO rarity (id, name, drop_rate) VALUES
(1, 'Common', 0.6),
(2, 'Rare', 0.2),
(3, 'Epic', 0.1),
(4, 'Mythical', 0.085),
(5, 'Legendary', 0.015)
");
$output->writeln('Base de données peuplée.');
} catch (\Exception $e) {
$output->writeln('<error>Erreur : ' . $e->getMessage() . '</error>');
return Command::FAILURE;
}
return Command::SUCCESS;
}
}

@ -2,29 +2,12 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\Emoji; use App\Entity\Emoji;
use App\Entity\Rarity;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use App\Repository\RarityRepository;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use App\Repository\EmojiRepository;
#[Route('/emoji', name: 'emoji')]
class EmojiController extends AbstractController class EmojiController extends AbstractController
{ {
private RarityRepository $rarityRepository;
private HttpClientInterface $httpClient;
public function __construct(RarityRepository $rarityRepository, HttpClientInterface $httpClient)
{
$this->rarityRepository = $rarityRepository;
$this->httpClient = $httpClient;
}
#[Route('/emoji', name: 'app_emoji')] #[Route('/emoji', name: 'app_emoji')]
public function index(): Response public function index(): Response
{ {
@ -33,144 +16,7 @@ class EmojiController extends AbstractController
]); ]);
} }
#[Route('/add/{code}', name: 'add')] public function reproduceEmoji(Emoji $emoji1, Emoji $emoji2): Emoji {
public function addEmojiDebug(string $code, EntityManagerInterface $entityManager) { return new Emoji();
$emoji = new Emoji();
$emoji->setCode($code);
$emoji->setName('Default Name');
$emoji->setStrength(1.0);
$emoji->setToughness(1.0);
$emoji->setIntelligence(1.0);
$emoji->setSpeed(1.0);
$emoji->setFightsWon(0);
// On récupère une instance de Rarity existante (par exemple, la première)
$rarity = $this->getRarity();
if (!$rarity) {
throw new \RuntimeException('Aucun objet Rarity trouvé en base.');
}
$emoji->setRarity($rarity);
// Optionnel : définir parent1 et parent2 si tu veux tester avec des relations
// $emoji->setParent1(null);
// $emoji->setParent2(null);
$entityManager->persist($emoji);
$entityManager->flush();
return new Response();
}
private function getRarity(): Rarity {
$rarity = $this->rarityRepository->findAll();
$rand = mt_rand() / mt_getrandmax();
$sum = 0.0;
foreach($rarity as $r) {
$sum += $r->getDropRate();
if($sum > $rand) {
return $r;
}
}
return $rarity[0];
}
// Renvoi l'url de l'image issue de la fusion de deux emojis. Fonctionne avec un code et un emoji directement
private function getFusionUrl(string $emoji1, string $emoji2): string
{
$baseUrl = 'https://emojik.vercel.app/s/';
$size = 256;
// On encode les string pour l'url
$encodedEmoji1 = urlencode($emoji1);
$encodedEmoji2 = urlencode($emoji2);
return sprintf('%s%s_%s?size=%d', $baseUrl, $encodedEmoji1, $encodedEmoji2, $size);
}
#[Route('/fusion/{emoji1_id}/{emoji2_id}', name: 'fusion')]
public function reproduceEmoji(int $emoji1_id, int $emoji2_id, EntityManagerInterface $entityManager, EmojiRepository $emojiRepository): JsonResponse {
$emoji1 = $emojiRepository->find($emoji1_id);
$emoji2 = $emojiRepository->find($emoji2_id);
if (!$emoji1 || !$emoji2) {
return new JsonResponse(['error' => 'One or both emojis not found'], 404);
}
$child = new Emoji();
$child->setName("Testenfant");
// Chance de fusion
$fusionRand = mt_rand() / mt_getrandmax();
if($fusionRand > 0.8) {
// Si les emoji parents sont des fusions on remonte l'arbre généalogique jusqu'à trouver un smiley normal
// On ne peut pas fusionner un smiley déjà fusionné
$temp1 = $emoji1;
while(str_contains($temp1->getCode(), "vercel")) {
$temp1 = $temp1->getParent1();
}
$temp2 = $emoji2;
while(str_contains($temp2->getCode(), "vercel")) {
$temp2 = $temp2->getParent2();
}
$child->setCode($this->getFusionUrl($temp1->getCode(), $temp2->getCode()));
} else {
$rand = mt_rand() / mt_getrandmax();
if($rand > 0.5) {
$child->setCode($emoji1->getCode());
} else {
$child->setCode($emoji2->getCode());
}
}
// Lors d'une fusion un emoji récupère chaque stat d'un de ces deux parents de manière aléatoire
$rand = mt_rand() / mt_getrandmax();
if($rand > 0.5) {
$child->setStrength($emoji1->getStrength());
} else {
$child->setStrength($emoji2->getStrength());
}
$rand = mt_rand() / mt_getrandmax();
if($rand > 0.5) {
$child->setToughness($emoji1->getToughness());
} else {
$child->setToughness($emoji2->getToughness());
}
$rand = mt_rand() / mt_getrandmax();
if($rand > 0.5) {
$child->setIntelligence($emoji1->getIntelligence());
} else {
$child->setIntelligence($emoji2->getIntelligence());
}
$rand = mt_rand() / mt_getrandmax();
if($rand > 0.5) {
$child->setSpeed($emoji1->getSpeed());
} else {
$child->setSpeed($emoji2->getSpeed());
}
$child->setFightsWon(0);
$child->setRarity($this->getRarity());
$child->setParent1($emoji1);
$child->setParent2($emoji2);
$entityManager->persist($child);
$entityManager->flush();
return new JsonResponse([
'message' => 'Child created',
'mommy' => $child->getParent1()->getCode(),
'daddy' => $child->getParent2()->getCode(),
'baby' => $child->getCode()
]);
} }
} }

@ -1,66 +0,0 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class HomeController extends AbstractController
{
#[Route('/', name: 'home')]
public function index(): Response
{
$emojis = [
[
'id' => 1,
'nom' => 'Bob',
'code' => '😊',
'force' => 12.5,
'robustesse' => 9.3,
'intelligence' => 7.8,
'vitesse' => 10.0,
'nbCombatGagne' => 3,
'rarete' => 2, // épique
],
[
'id' => 2,
'nom' => 'John',
'code' => '😭',
'force' => 5.1,
'robustesse' => 4.2,
'intelligence' => 3.3,
'vitesse' => 6.0,
'nbCombatGagne' => 1,
'rarete' => 1, // commun
],
[
'id' => 3,
'nom' => 'Rodolph',
'code' => '😁',
'force' => 20.0,
'robustesse' => 15.0,
'intelligence' => 18.0,
'vitesse' => 17.0,
'nbCombatGagne' => 10,
'rarete' => 4, // légendaire
]
];
// Ajout de la couleur selon la rareté
foreach ($emojis as &$emoji) {
$emoji['color'] = match ($emoji['rarete']) {
1 => 'green', // commun
2 => 'purple', // épique
3 => 'red', // mythique
4 => 'gold', // légendaire
default => 'gray'
};
}
return $this->render('home/index.html.twig', [
'emojis' => $emojis,
]);
}
}

@ -14,73 +14,42 @@ class Emoji
private ?int $id = null; private ?int $id = null;
#[ORM\Column(length: 255)] #[ORM\Column(length: 255)]
private ?string $name = null; private ?string $nom = null;
#[ORM\Column(length: 255)] #[ORM\Column(length: 255)]
private ?string $code = null; private ?string $code = null;
#[ORM\Column] #[ORM\Column]
private ?float $strength = null; private ?float $force = null;
#[ORM\Column] #[ORM\Column]
private ?float $toughness = null; private ?float $robustesse = null;
#[ORM\Column] #[ORM\Column]
private ?float $intelligence = null; private ?float $intelligence = null;
#[ORM\Column] #[ORM\Column]
private ?float $speed = null; private ?float $vitesse = null;
#[ORM\Column] #[ORM\Column]
private ?int $fightsWon = null; private ?int $nbCombatGagne = null;
#[ORM\ManyToOne(targetEntity: Rarity::class)] #[ORM\Column]
#[ORM\JoinColumn(nullable: false)] private ?int $rarete = null;
private ?Rarity $rarity = null;
#[ORM\ManyToOne(targetEntity: self::class)]
#[ORM\JoinColumn(nullable: true)]
private ?Emoji $parent1 = null;
#[ORM\ManyToOne(targetEntity: self::class)]
#[ORM\JoinColumn(nullable: true)]
private ?Emoji $parent2 = null;
public function getParent1(): ?self
{
return $this->parent1;
}
public function setParent1(?self $parent1): self
{
$this->parent1 = $parent1;
return $this;
}
public function getParent2(): ?self
{
return $this->parent2;
}
public function setParent2(?self $parent2): self
{
$this->parent2 = $parent2;
return $this;
}
public function getId(): ?int public function getId(): ?int
{ {
return $this->id; return $this->id;
} }
public function getName(): ?string public function getNom(): ?string
{ {
return $this->name; return $this->nom;
} }
public function setName(string $name): self public function setNom(string $nom): self
{ {
$this->name = $name; $this->nom = $nom;
return $this; return $this;
} }
@ -95,25 +64,25 @@ class Emoji
return $this; return $this;
} }
public function getStrength(): ?float public function getForce(): ?float
{ {
return $this->strength; return $this->force;
} }
public function setStrength(float $strength): self public function setForce(float $force): self
{ {
$this->strength = $strength; $this->force = $force;
return $this; return $this;
} }
public function getToughness(): ?float public function getRobustesse(): ?float
{ {
return $this->toughness; return $this->robustesse;
} }
public function setToughness(float $toughness): self public function setRobustesse(float $robustesse): self
{ {
$this->toughness = $toughness; $this->robustesse = $robustesse;
return $this; return $this;
} }
@ -128,36 +97,36 @@ class Emoji
return $this; return $this;
} }
public function getSpeed(): ?float public function getVitesse(): ?float
{ {
return $this->speed; return $this->vitesse;
} }
public function setSpeed(float $speed): self public function setVitesse(float $vitesse): self
{ {
$this->speed = $speed; $this->vitesse = $vitesse;
return $this; return $this;
} }
public function getFightsWon(): ?int public function getNbCombatGagne(): ?int
{ {
return $this->fightsWon; return $this->nbCombatGagne;
} }
public function setFightsWon(int $fightsWon): self public function setNbCombatGagne(int $nbCombatGagne): self
{ {
$this->fightsWon = $fightsWon; $this->nbCombatGagne = $nbCombatGagne;
return $this; return $this;
} }
public function getRarity(): ?Rarity public function getRarete(): ?int
{ {
return $this->rarity; return $this->rarete;
} }
public function setRarity(Rarity $rarity): self public function setRarete(int $rarete): self
{ {
$this->rarity = $rarity; $this->rarete = $rarete;
return $this; return $this;
} }
} }

@ -1,48 +0,0 @@
<?php
namespace App\Entity;
use App\Repository\RarityRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: RarityRepository::class)]
class Rarity
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 50, unique: true)]
private string $name;
#[ORM\Column(type: 'float')]
private float $dropRate;
public function getId(): ?int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getDropRate(): float
{
return $this->dropRate;
}
public function setDropRate(float $dropRate): self
{
$this->dropRate = $dropRate;
return $this;
}
}

@ -1,48 +0,0 @@
<?php
namespace App\Repository;
use App\Entity\Rarity;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<Rarity>
*
* @method Rarity|null find($id, $lockMode = null, $lockVersion = null)
* @method Rarity|null findOneBy(array $criteria, array $orderBy = null)
* @method Rarity[] findAll()
* @method Rarity[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class RarityRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Rarity::class);
}
// /**
// * @return Rarity[] Returns an array of Rarity objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('r')
// ->andWhere('r.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('r.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?Rarity
// {
// return $this->createQueryBuilder('r')
// ->andWhere('r.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

@ -1,13 +1,4 @@
{ {
"doctrine/deprecations": {
"version": "1.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "1.0",
"ref": "87424683adc81d7dc305eefec1fced883084aab9"
}
},
"doctrine/doctrine-bundle": { "doctrine/doctrine-bundle": {
"version": "2.13", "version": "2.13",
"recipe": { "recipe": {
@ -126,6 +117,18 @@
"ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f" "ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
} }
}, },
"symfony/messenger": {
"version": "6.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "6.0",
"ref": "ba1ac4e919baba5644d31b57a3284d6ba12d52ee"
},
"files": [
"./config/packages/messenger.yaml"
]
},
"symfony/monolog-bundle": { "symfony/monolog-bundle": {
"version": "3.10", "version": "3.10",
"recipe": { "recipe": {

@ -3,7 +3,6 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title> <title>{% block title %}Welcome!{% endblock %}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text></svg>"> <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text></svg>">
{# Run `composer require symfony/webpack-encore-bundle` to start using Symfony UX #} {# Run `composer require symfony/webpack-encore-bundle` to start using Symfony UX #}
{% block stylesheets %} {% block stylesheets %}

@ -1,69 +0,0 @@
{% extends 'base.html.twig' %}
{% block title %}Accueil - Ma collection de créatures{% endblock %}
{% block stylesheets %}
<link rel="stylesheet" href="{{ asset('css/home.css') }}">
{% endblock %}
{% block body %}
<h1>🧬 Ma collection de créatures 🐾</h1>
<div class="filter-bar">
<label for="search-input">🔍 Rechercher un nom :</label>
<input type="text" id="search-input" placeholder="ex: Bob..." />
<label for="rarete-filter">Filtrer par rareté :</label>
<select id="rarete-filter">
<option value="">Toutes</option>
<option value="green">Communes</option>
<option value="purple">Épiques</option>
<option value="red">Mythiques</option>
<option value="gold">Légendaires</option>
</select>
<label for="sort-select">Trier par :</label>
<select id="sort-select">
<option value="none">--</option>
<option value="level">Level</option>
<option value="force">Force</option>
<option value="vitesse">Vitesse</option>
</select>
</div>
<div id="selection-status">Sélectionnez 2 créatures...</div>
<div class="emoji-container">
{% for emoji in emojis %}
<div class="emoji-card {{ emoji.color }}" data-id="{{ emoji.id }}" data-name="{{ emoji.nom }}"
data-color="{{ emoji.color }}" data-level="{{ emoji.nbCombatGagne }}"
data-force="{{ emoji.force }}" data-vitesse="{{ emoji.vitesse }}">
<div class="emoji-level">Level {{ emoji.nbCombatGagne }}</div>
<div class="emoji">{{ emoji.code }}</div>
<div class="emoji-name {{ emoji.color }}">{{ emoji.nom }}</div>
<div class="detail-icon"></div>
<div class="popup" id="popup-{{ emoji.id }}">
<strong>Stats :</strong><br>
Force: {{ emoji.force }}<br>
Robustesse: {{ emoji.robustesse }}<br>
Intelligence: {{ emoji.intelligence }}<br>
Vitesse: {{ emoji.vitesse }}
</div>
</div>
{% endfor %}
</div>
<div id="selection-visual" class="selection-visual"></div>
<div class="action-buttons">
<button class="btn" ">⚔️ Combattre</button>
<button class="btn" ">💞 Reproduire</button>
</div>
{% endblock %}
{% block javascripts %}
<script src="{{ asset('js/home.js') }}"></script>
{% endblock %}

@ -1,90 +0,0 @@
<?php
namespace App\Tests\Controller;
use App\Entity\Emoji;
use App\Entity\Rarity;
use App\Repository\EmojiRepository;
use App\Repository\RarityRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Response;
class EmojiControllerTest extends WebTestCase
{
private $client;
private EntityManagerInterface $em;
protected function setUp(): void
{
$this->client = static::createClient();
$this->em = static::getContainer()->get(EntityManagerInterface::class);
// Démarre une transaction pour pouvoir annuler les modifications des tests
$this->em->getConnection()->beginTransaction();
}
protected function tearDown(): void
{
// Rollback la transaction pour annuler les changements des tests
$this->em->getConnection()->rollBack();
parent::tearDown();
}
public function testReproduceEmoji(): void
{
$emoji1 = (new Emoji())
->setCode('😀')
->setName('Parent1')
->setStrength(1.0)
->setToughness(1.0)
->setIntelligence(1.0)
->setSpeed(1.0)
->setFightsWon(5);
$emoji2 = (new Emoji())
->setCode('😎')
->setName('Parent2')
->setStrength(2.0)
->setToughness(2.0)
->setIntelligence(2.0)
->setSpeed(2.0)
->setFightsWon(3);
$rr = $this->em->getRepository(Rarity::class);
$rarity = $rr->findOneBy([], ['id' => 'ASC']);
$emoji1->setRarity($rarity);
$emoji2->setRarity($rarity);
$this->em->persist($emoji1);
$this->em->persist($emoji2);
$this->em->flush();
$id1 = $emoji1->getId();
$id2 = $emoji2->getId();
$this->client->request('GET', "/emoji/fusion/$id1/$id2");
$response = $this->client->getResponse();
$this->assertEquals(Response::HTTP_OK, $response->getStatusCode());
$data = json_decode($response->getContent(), true);
$this->assertArrayHasKey('baby', $data);
$this->assertEquals('Child created', $data['message']);
}
public function testFusionEmojiNotFound(): void
{
$emojiRepo = $this->createMock(EmojiRepository::class);
$emojiRepo->method('find')->willReturn(null);
$this->client->request('GET', '/emoji/fusion/999/998');
$response = $this->client->getResponse();
$this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode());
$data = json_decode($response->getContent(), true);
$this->assertEquals('One or both emojis not found', $data['error']);
}
}
Loading…
Cancel
Save