diff --git a/bin/console.php b/bin/console.php new file mode 100755 index 0000000000000000000000000000000000000000..ef2b2d8c11df9ba79e083ce645eace090f4a74c1 --- /dev/null +++ b/bin/console.php @@ -0,0 +1,30 @@ +<?php + +use App\Console\CreateDatabaseCommand; +use App\Console\PopulateDatabaseCommand; +use DI\ContainerBuilder; +use Psr\Container\ContainerInterface; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Input\ArgvInput; + +require_once __DIR__ . '/../vendor/autoload.php'; + +/** @var ContainerInterface $container */ +$container = (new ContainerBuilder()) + ->addDefinitions(__DIR__ . '/../config/container.php') + ->build(); + +try { + /** @var Application $application */ + $application = $container->get(Application::class); + + // Register your console commands here + $application->add($container->get(CreateDatabaseCommand::class)); + $application->add($container->get(PopulateDatabaseCommand::class)); + + exit($application->run()); +} catch (Throwable $exception) { + echo $exception->getMessage(); + exit(1); +} + diff --git a/composer.json b/composer.json index 74819381526698bdf3e4a20cfb4d284c200bce50..65c5c82cd92b5c02732e743e7ddb8a9d1d7a6e4e 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,8 @@ "php-di/php-di": "^7.0", "slim/twig-view": "^3.3", "slim/flash": "^0.4.0", - "illuminate/database": "^10.40" + "illuminate/database": "^10.40", + "symfony/console": "^7.0" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 00ad321e27e3f04d87381ecbe34ecfd9c83a91bc..e0e257f5f92356f7f227ee548ea731f00edf46e8 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": "7bfe79116cde5d38c3a4dd8560d53674", + "content-hash": "18e538bffe52268407e25caef89fe5e0", "packages": [ { "name": "brick/math", @@ -1985,6 +1985,99 @@ }, "time": "2022-01-02T05:14:45+00:00" }, + { + "name": "symfony/console", + "version": "v7.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "f8587c4cdc5acad67af71c37db34ef03af91e59c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/f8587c4cdc5acad67af71c37db34ef03af91e59c", + "reference": "f8587c4cdc5acad67af71c37db34ef03af91e59c", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "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": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.0.2" + }, + "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-12-10T16:54:46+00:00" + }, { "name": "symfony/deprecation-contracts", "version": "v3.4.0", @@ -2134,6 +2227,171 @@ ], "time": "2023-01-26T09:26:14+00:00" }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "875e90aeea2777b6f135677f618529449334a612" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" + }, + "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-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" + }, + "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-26T09:26:14+00:00" + }, { "name": "symfony/polyfill-mbstring", "version": "v1.28.0", @@ -2379,6 +2637,174 @@ ], "time": "2023-01-26T09:26:14+00:00" }, + { + "name": "symfony/service-contracts", + "version": "v3.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" + }, + "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-12-26T14:02:43+00:00" + }, + { + "name": "symfony/string", + "version": "v7.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "cc78f14f91f5e53b42044d0620961c48028ff9f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/cc78f14f91f5e53b42044d0620961c48028ff9f5", + "reference": "cc78f14f91f5e53b42044d0620961c48028ff9f5", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.0.2" + }, + "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-12-10T16:54:46+00:00" + }, { "name": "symfony/translation", "version": "v6.4.2", diff --git a/config/container.php b/config/container.php index 02981867626bb1c24fad32a9e9700a6aa2f65443..4ffe6ec8cd730d510c66c0e3a40ff445a9e7b890 100644 --- a/config/container.php +++ b/config/container.php @@ -10,13 +10,17 @@ return [ 'settings' => function () { return require __DIR__ . '/settings.php'; }, - App::class => function (ContainerInterface $container) { + 'db' => function (ContainerInterface $container) { $capsule = new \Illuminate\Database\Capsule\Manager; $capsule->addConnection($container->get('settings')['db']); $capsule->setAsGlobal(); $capsule->bootEloquent(); + return $capsule; + }, + App::class => function (ContainerInterface $container) { + $container->get('db'); AppFactory::setContainer($container); return AppFactory::create(); }, diff --git a/readme.md b/readme.md index 742acafeeeff4ecd828f17ec37dd9c222fe3f3e7..14e05d0cc96568a09c5e5e2426bacaa8602fc790 100644 --- a/readme.md +++ b/readme.md @@ -27,5 +27,11 @@ Il permet de lister plusieurs entreprise, et d'en voir leur bureau et employées `docker compose up` ## (re)Créer et alimenter la base de données -1) Créer la base de données -`docker compose run --rm db mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS annuaire;"` +Il faut que le container database soit lancé pour effectuer ces commandes. + +**Supprimer et re-créer la base de données** +`dexec php php bin/console.php db:create` + +**Alimenter la base de données** +`dexec php php bin/console.php db:populate` + diff --git a/sql/create_database.sql b/sql/create_database.sql index eb984cb49dc39f03fda416605fd242f1c50f52fe..34cac67ffc760ca6cdd5039bb6b173d2269813a0 100644 --- a/sql/create_database.sql +++ b/sql/create_database.sql @@ -1,7 +1,8 @@ -ALTER TABLE IF EXISTS companies DROP FOREIGN KEY companies_id_fk_1; +SET FOREIGN_KEY_CHECKS=0; DROP TABLE IF EXISTS employees; DROP TABLE IF EXISTS offices; DROP TABLE IF EXISTS companies; +SET FOREIGN_KEY_CHECKS=1; CREATE TABLE companies ( @@ -44,4 +45,3 @@ CREATE TABLE employees PRIMARY KEY (id), FOREIGN KEY (office_id) REFERENCES offices (id) ); - diff --git a/src/Console/CreateDatabaseCommand.php b/src/Console/CreateDatabaseCommand.php new file mode 100644 index 0000000000000000000000000000000000000000..bc0fa5c698e4b0ac18ac324fcecf120cf1ce0e70 --- /dev/null +++ b/src/Console/CreateDatabaseCommand.php @@ -0,0 +1,87 @@ +<?php + +namespace App\Console; + +use Slim\App; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class CreateDatabaseCommand extends Command +{ + private App $app; + + public function __construct(App $app) + { + $this->app = $app; + parent::__construct(); + } + + protected function configure(): void + { + $this->setName('db:create'); + $this->setDescription('Create database'); + } + + protected function execute(InputInterface $input, OutputInterface $output ): int + { + $output->writeln('Creating database...'); + $db = $this->app->getContainer()->get('db'); + + $db->getConnection()->statement("SET FOREIGN_KEY_CHECKS=0"); + $db->getConnection()->statement("DROP TABLE IF EXISTS `employees`"); + $db->getConnection()->statement("DROP TABLE IF EXISTS `offices`"); + $db->getConnection()->statement("DROP TABLE IF EXISTS `companies`"); + $db->getConnection()->statement("SET FOREIGN_KEY_CHECKS=1"); + $db->getConnection()->statement(" + CREATE TABLE companies +( + id INT AUTO_INCREMENT NOT NULL, + name VARCHAR(255) NOT NULL, + phone VARCHAR(255) , + email VARCHAR(255) , + website VARCHAR(255) , + image VARCHAR(255) , + head_office_id INT , + PRIMARY KEY (id) +); + "); + + $db->getConnection()->statement(" + CREATE TABLE offices +( + id INT AUTO_INCREMENT NOT NULL, + name VARCHAR(255) NOT NULL, + address VARCHAR(255) NOT NULL, + city VARCHAR(255) NOT NULL, + zip_code VARCHAR(255) NOT NULL, + country VARCHAR(255) NOT NULL, + email VARCHAR(255) , + phone VARCHAR(255) , + company_id INT NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (company_id) REFERENCES companies (id) +); + "); + + $db->getConnection()->statement(" + CREATE TABLE employees +( + id INT AUTO_INCREMENT NOT NULL, + first_name VARCHAR(255) NOT NULL, + last_name VARCHAR(255) NOT NULL, + office_id INT NOT NULL, + email VARCHAR(255) , + phone VARCHAR(255) , + job_title VARCHAR(255) , + PRIMARY KEY (id), + FOREIGN KEY (office_id) REFERENCES offices (id) +); + "); + + $db->getConnection()->statement("ALTER TABLE companies ADD CONSTRAINT companies_id_fk_1 FOREIGN KEY (head_office_id) REFERENCES offices (id);"); + + $output->writeln('Database created successfully!'); + return 0; + } +} diff --git a/src/Console/PopulateDatabaseCommand.php b/src/Console/PopulateDatabaseCommand.php new file mode 100644 index 0000000000000000000000000000000000000000..8c8fbdecc769c1706e8b9a9fd3c49c8c4d741bac --- /dev/null +++ b/src/Console/PopulateDatabaseCommand.php @@ -0,0 +1,73 @@ +<?php + +namespace App\Console; + +use App\Models\Company; +use App\Models\Employee; +use App\Models\Office; +use Illuminate\Support\Facades\Schema; +use Slim\App; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class PopulateDatabaseCommand extends Command +{ + private App $app; + + public function __construct(App $app) + { + $this->app = $app; + parent::__construct(); + } + + protected function configure(): void + { + $this->setName('db:populate'); + $this->setDescription('Populate database'); + } + + protected function execute(InputInterface $input, OutputInterface $output ): int + { + $output->writeln('Populate database...'); + + /** @var \Illuminate\Database\Capsule\Manager $db */ + $db = $this->app->getContainer()->get('db'); + + $db->getConnection()->statement("SET FOREIGN_KEY_CHECKS=0"); + $db->getConnection()->statement("TRUNCATE `employees`"); + $db->getConnection()->statement("TRUNCATE `offices`"); + $db->getConnection()->statement("TRUNCATE `companies`"); + $db->getConnection()->statement("SET FOREIGN_KEY_CHECKS=1"); + + + $db->getConnection()->statement("INSERT INTO `companies` VALUES + (1,'Stack Exchange','0601010101','stack@exchange.com','https://stackexchange.com/','https://i.stack.imgur.com/UPdHB.jpg',null), + (2,'Google','0602020202','contact@google.com','https://www.google.com','https://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/Google_office_%284135991953%29.jpg/800px-Google_office_%284135991953%29.jpg?20190722090506',null) + "); + + $db->getConnection()->statement("INSERT INTO `offices` VALUES + (1,'Bureau de Nancy','1 rue Stanistlas','Nancy','54000','France','nancy@stackexchange.com',NULL,1), + (2,'Burea de Vandoeuvre','46 avenue Jeanne d\'Arc','Vandoeuvre','54500','France',NULL,NULL,1), + (3,'Siege sociale','2 rue de la primatiale','Paris','75000','France',NULL,NULL,2), + (4,'Bureau Berlinois','192 avenue central','Berlin','12277','Allemagne',NULL,NULL,2) + "); + + $db->getConnection()->statement("INSERT INTO `employees` VALUES + (1,'Camille','La Chenille',1,'camille.la@chenille.com',NULL,'Ingénieur'), + (2,'Albert','Mudhat',2,'albert.mudhat@aqume.net',NULL,'Superviseur'), + (3,'Sylvie','Tesse',3,'sylive.tesse@factice.local',NULL,'PDG'), + (4,'John','Doe',4,'john.doe@generique.org',NULL,'Testeur'), + (5,'Jean','Bon',1,'jean@test.com',NULL,'Developpeur'), + (6,'Anais','Dufour',2,'anais@aqume.net',NULL,'DBA'), + (7,'Sylvain','Poirson',3,'sylvain@factice.local',NULL,'Administrateur réseau'), + (8,'Telma','Thiriet',4,'telma@generique.org',NULL,'Juriste') + "); + + $db->getConnection()->statement("update companies set head_office_id = 1 where id = 1;"); + $db->getConnection()->statement("update companies set head_office_id = 3 where id = 2;"); + + $output->writeln('Database created successfully!'); + return 0; + } +}