init
This commit is contained in:
parent
a00741861a
commit
6ed74c2284
8
.env
8
.env
|
@ -17,3 +17,11 @@
|
||||||
APP_ENV=dev
|
APP_ENV=dev
|
||||||
APP_SECRET=23cbc3b31c910f18a9822666f2bdb3ef
|
APP_SECRET=23cbc3b31c910f18a9822666f2bdb3ef
|
||||||
###< symfony/framework-bundle ###
|
###< symfony/framework-bundle ###
|
||||||
|
|
||||||
|
###> doctrine/doctrine-bundle ###
|
||||||
|
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
|
||||||
|
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
|
||||||
|
#
|
||||||
|
DATABASE_URL="mysql://app:password@mysql:3306/app"
|
||||||
|
|
||||||
|
###< doctrine/doctrine-bundle ###
|
||||||
|
|
|
@ -8,3 +8,5 @@
|
||||||
/var/
|
/var/
|
||||||
/vendor/
|
/vendor/
|
||||||
###< symfony/framework-bundle ###
|
###< symfony/framework-bundle ###
|
||||||
|
|
||||||
|
/.idea/
|
||||||
|
|
|
@ -7,14 +7,23 @@
|
||||||
"php": ">=7.2.5",
|
"php": ">=7.2.5",
|
||||||
"ext-ctype": "*",
|
"ext-ctype": "*",
|
||||||
"ext-iconv": "*",
|
"ext-iconv": "*",
|
||||||
|
"composer/package-versions-deprecated": "1.11.99.4",
|
||||||
|
"doctrine/doctrine-bundle": "^2.5",
|
||||||
|
"doctrine/doctrine-migrations-bundle": "^3.2",
|
||||||
|
"doctrine/orm": "^2.10",
|
||||||
"symfony/console": "5.4.*",
|
"symfony/console": "5.4.*",
|
||||||
"symfony/dotenv": "5.4.*",
|
"symfony/dotenv": "5.4.*",
|
||||||
"symfony/flex": "^1.17|^2",
|
"symfony/flex": "^1.17|^2",
|
||||||
"symfony/framework-bundle": "5.4.*",
|
"symfony/framework-bundle": "5.4.*",
|
||||||
|
"symfony/maker-bundle": "^1.36",
|
||||||
|
"symfony/proxy-manager-bridge": "5.4.*",
|
||||||
"symfony/runtime": "5.4.*",
|
"symfony/runtime": "5.4.*",
|
||||||
"symfony/yaml": "5.4.*"
|
"symfony/security-bundle": "5.4.*",
|
||||||
},
|
"symfony/twig-bundle": "5.4.*",
|
||||||
"require-dev": {
|
"symfony/web-profiler-bundle": "5.4.*",
|
||||||
|
"symfony/yaml": "5.4.*",
|
||||||
|
"twig/extra-bundle": "^2.12|^3.0",
|
||||||
|
"twig/twig": "^2.12|^3.0"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"allow-plugins": {
|
"allow-plugins": {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,4 +2,11 @@
|
||||||
|
|
||||||
return [
|
return [
|
||||||
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
||||||
|
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||||
|
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
|
||||||
|
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
|
||||||
|
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
|
||||||
|
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
|
||||||
|
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
|
||||||
|
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
||||||
];
|
];
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
web_profiler:
|
||||||
|
toolbar: true
|
||||||
|
intercept_redirects: false
|
||||||
|
|
||||||
|
framework:
|
||||||
|
profiler: { only_exceptions: false }
|
|
@ -0,0 +1,17 @@
|
||||||
|
doctrine:
|
||||||
|
dbal:
|
||||||
|
url: '%env(resolve:DATABASE_URL)%'
|
||||||
|
|
||||||
|
# IMPORTANT: You MUST configure your server version,
|
||||||
|
# either here or in the DATABASE_URL env var (see .env file)
|
||||||
|
#server_version: '13'
|
||||||
|
orm:
|
||||||
|
auto_generate_proxy_classes: true
|
||||||
|
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
|
||||||
|
auto_mapping: true
|
||||||
|
mappings:
|
||||||
|
App:
|
||||||
|
is_bundle: false
|
||||||
|
dir: '%kernel.project_dir%/src/Entity'
|
||||||
|
prefix: 'App\Entity'
|
||||||
|
alias: App
|
|
@ -0,0 +1,6 @@
|
||||||
|
doctrine_migrations:
|
||||||
|
migrations_paths:
|
||||||
|
# namespace is arbitrary but should be different from App\Migrations
|
||||||
|
# as migrations classes should NOT be autoloaded
|
||||||
|
'DoctrineMigrations': '%kernel.project_dir%/migrations'
|
||||||
|
enable_profiler: '%kernel.debug%'
|
|
@ -0,0 +1,17 @@
|
||||||
|
doctrine:
|
||||||
|
orm:
|
||||||
|
auto_generate_proxy_classes: false
|
||||||
|
query_cache_driver:
|
||||||
|
type: pool
|
||||||
|
pool: doctrine.system_cache_pool
|
||||||
|
result_cache_driver:
|
||||||
|
type: pool
|
||||||
|
pool: doctrine.result_cache_pool
|
||||||
|
|
||||||
|
framework:
|
||||||
|
cache:
|
||||||
|
pools:
|
||||||
|
doctrine.result_cache_pool:
|
||||||
|
adapter: cache.app
|
||||||
|
doctrine.system_cache_pool:
|
||||||
|
adapter: cache.system
|
|
@ -0,0 +1,49 @@
|
||||||
|
security:
|
||||||
|
enable_authenticator_manager: true
|
||||||
|
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
|
||||||
|
password_hashers:
|
||||||
|
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
|
||||||
|
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
|
||||||
|
providers:
|
||||||
|
# used to reload user from session & other features (e.g. switch_user)
|
||||||
|
app_user_provider:
|
||||||
|
entity:
|
||||||
|
class: App\Entity\User
|
||||||
|
property: username
|
||||||
|
firewalls:
|
||||||
|
dev:
|
||||||
|
pattern: ^/(_(profiler|wdt)|css|images|js)/
|
||||||
|
security: false
|
||||||
|
main:
|
||||||
|
lazy: true
|
||||||
|
provider: app_user_provider
|
||||||
|
custom_authenticator: App\Security\UserAuthenticator
|
||||||
|
logout:
|
||||||
|
path: app_logout
|
||||||
|
# where to redirect after logout
|
||||||
|
# target: app_any_route
|
||||||
|
|
||||||
|
# activate different ways to authenticate
|
||||||
|
# https://symfony.com/doc/current/security.html#the-firewall
|
||||||
|
|
||||||
|
# https://symfony.com/doc/current/security/impersonating_user.html
|
||||||
|
# switch_user: true
|
||||||
|
|
||||||
|
# Easy way to control access for large sections of your site
|
||||||
|
# Note: Only the *first* access control that matches will be used
|
||||||
|
access_control:
|
||||||
|
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||||
|
- { path: ^/, roles: ROLE_USER }
|
||||||
|
|
||||||
|
when@test:
|
||||||
|
security:
|
||||||
|
password_hashers:
|
||||||
|
# By default, password hashers are resource intensive and take time. This is
|
||||||
|
# important to generate secure password hashes. In tests however, secure hashes
|
||||||
|
# are not important, waste resources and increase test times. The following
|
||||||
|
# reduces the work factor to the lowest possible values.
|
||||||
|
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
|
||||||
|
algorithm: auto
|
||||||
|
cost: 4 # Lowest possible value for bcrypt
|
||||||
|
time_cost: 3 # Lowest possible value for argon
|
||||||
|
memory_cost: 10 # Lowest possible value for argon
|
|
@ -0,0 +1,4 @@
|
||||||
|
doctrine:
|
||||||
|
dbal:
|
||||||
|
# "TEST_TOKEN" is typically set by ParaTest
|
||||||
|
dbname_suffix: '_test%env(default::TEST_TOKEN)%'
|
|
@ -0,0 +1,6 @@
|
||||||
|
web_profiler:
|
||||||
|
toolbar: false
|
||||||
|
intercept_redirects: false
|
||||||
|
|
||||||
|
framework:
|
||||||
|
profiler: { collect: false }
|
|
@ -0,0 +1,6 @@
|
||||||
|
twig:
|
||||||
|
default_path: '%kernel.project_dir%/templates'
|
||||||
|
|
||||||
|
when@test:
|
||||||
|
twig:
|
||||||
|
strict_variables: true
|
|
@ -0,0 +1,7 @@
|
||||||
|
controllers:
|
||||||
|
resource: ../../src/Controller/
|
||||||
|
type: annotation
|
||||||
|
|
||||||
|
kernel:
|
||||||
|
resource: ../../src/Kernel.php
|
||||||
|
type: annotation
|
|
@ -0,0 +1,7 @@
|
||||||
|
web_profiler_wdt:
|
||||||
|
resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
|
||||||
|
prefix: /_wdt
|
||||||
|
|
||||||
|
web_profiler_profiler:
|
||||||
|
resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
|
||||||
|
prefix: /_profiler
|
|
@ -0,0 +1,43 @@
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
mysql:
|
||||||
|
image: mysql:8.0.22
|
||||||
|
container_name: mysql
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./var/mysql:/var/lib/mysql
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: 123456
|
||||||
|
MYSQL_DATABASE: app
|
||||||
|
MYSQL_USER: app
|
||||||
|
MYSQL_PASSWORD: password
|
||||||
|
ports:
|
||||||
|
- "3306:3306"
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: nginx:stable
|
||||||
|
container_name: nginx
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./:/app
|
||||||
|
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
links:
|
||||||
|
- php-fpm
|
||||||
|
|
||||||
|
php-fpm:
|
||||||
|
build: docker/php-fpm
|
||||||
|
restart: always
|
||||||
|
container_name: php-fpm
|
||||||
|
volumes:
|
||||||
|
- ./:/app
|
||||||
|
- ./docker/php-fpm/php.ini:/usr/local/etc/php/php.ini
|
||||||
|
links:
|
||||||
|
- mysql
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
###> doctrine/doctrine-bundle ###
|
||||||
|
db-data:
|
||||||
|
###< doctrine/doctrine-bundle ###
|
|
@ -0,0 +1,40 @@
|
||||||
|
worker_processes 1;
|
||||||
|
events {
|
||||||
|
worker_connections 2048;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
client_max_body_size 200M;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
chunked_transfer_encoding off;
|
||||||
|
server_name platform.local;
|
||||||
|
|
||||||
|
root /app/public;
|
||||||
|
index index.php;
|
||||||
|
|
||||||
|
try_files $uri $uri/ /index.php?$query_string;
|
||||||
|
default_type text/html;
|
||||||
|
access_log /app/var/log/nginx-access.log;
|
||||||
|
error_log /app/var/log/nginx-error.log error;
|
||||||
|
location ~ /upload/\. {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
location ~* /upload/.*$ {
|
||||||
|
add_header Content-Disposition "attachment";
|
||||||
|
add_header Content-Type application/octet-stream;
|
||||||
|
}
|
||||||
|
location ~* \.php$ {
|
||||||
|
fastcgi_pass php-fpm:9000;
|
||||||
|
include fastcgi_params;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
FROM php:8.1.0-fpm
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN docker-php-ext-install pdo pdo_mysql
|
|
@ -0,0 +1,3 @@
|
||||||
|
date.timezone=Europe/Moscow
|
||||||
|
upload_max_filesize = 200M
|
||||||
|
post_max_size = 200M
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?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 Version20220108091848 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TABLE `user` (id INT AUTO_INCREMENT NOT NULL, username VARCHAR(180) NOT NULL, score INT NOT NULL, log TINYINT(1) NOT NULL, roles JSON NOT NULL, UNIQUE INDEX UNIQ_8D93D649F85E0677 (username), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
|
||||||
|
$this->addSql('CREATE TABLE user_log (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT NULL, score INT NOT NULL, created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('DROP TABLE `user`');
|
||||||
|
$this->addSql('DROP TABLE user_log');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?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 Version20220108121138 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE INDEX IDX_8D93D649F85E0677 ON user (username)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_8D93D64932993751 ON user (score)');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('DROP INDEX IDX_8D93D649F85E0677 ON `user`');
|
||||||
|
$this->addSql('DROP INDEX IDX_8D93D64932993751 ON `user`');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
shortlist)
|
||||||
|
echo consumer-restart consumer-restart-all
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
up)
|
||||||
|
docker-compose up -d --force-recreate --remove-orphans $2
|
||||||
|
;;
|
||||||
|
down)
|
||||||
|
docker-compose down $2
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
docker-compose stop $2
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
docker-compose restart $2
|
||||||
|
;;
|
||||||
|
update)
|
||||||
|
git pull
|
||||||
|
composer install
|
||||||
|
docker-compose exec php-fpm php /app/bin/console doctrine:migrations:migrate --no-interaction
|
||||||
|
docker-compose exec php-fpm php /app/bin/console c:c
|
||||||
|
;;
|
||||||
|
migrate-run)
|
||||||
|
docker-compose exec php-fpm php /app/bin/console doctrine:migrations:migrate --no-interaction
|
||||||
|
;;
|
||||||
|
migrate-redo)
|
||||||
|
docker-compose exec php-fpm php /app/bin/console doctrine:migrations:execute $2 --down --no-interaction
|
||||||
|
docker-compose exec php-fpm php /app/bin/console doctrine:migrations:execute $2 --up --no-interaction
|
||||||
|
;;
|
||||||
|
migrate-create)
|
||||||
|
docker-compose exec php-fpm php /app/bin/console doctrine:migrations:generate
|
||||||
|
;;
|
||||||
|
build)
|
||||||
|
docker-compose build
|
||||||
|
;;
|
||||||
|
cc)
|
||||||
|
docker-compose exec php-fpm php /app/bin/console c:c
|
||||||
|
;;
|
||||||
|
command)
|
||||||
|
docker-compose exec php-fpm php /app/bin/console $2 ${@:3}
|
||||||
|
;;
|
||||||
|
composer-install)
|
||||||
|
docker-compose exec cron composer install
|
||||||
|
;;
|
||||||
|
composer-update)
|
||||||
|
docker-compose exec cron composer update
|
||||||
|
;;
|
||||||
|
dump-sql-schema)
|
||||||
|
docker-compose exec php-fpm php /app/bin/console doctrine:schema:create --dump-sql > config/base.sql
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 {command}
|
||||||
|
consumer-restart {consumer} - restart consumer
|
||||||
|
consumer-restart-all - restart all consumer
|
||||||
|
consumer-reread - reread supervisor config file (docker/supervisor/supervisord.conf -> /etc/supervisor/conf.d/supervisord.conf)
|
||||||
|
up - up docker
|
||||||
|
down - down docker
|
||||||
|
stop {name] - stop single docker container
|
||||||
|
restart {name} - restart all or single docker container
|
||||||
|
update - update project (git puul, composer install, run migrate, clear cache)
|
||||||
|
migrate-run - run migrate
|
||||||
|
migrate-redo {id} - redo single migrate
|
||||||
|
migrate-create - Generate a blank migration class
|
||||||
|
build - build project
|
||||||
|
cc - clear cache
|
||||||
|
command {name} - execute command
|
||||||
|
composer-install - composer install
|
||||||
|
composer-update - composer update
|
||||||
|
dump-sql-schema - create sql schema
|
||||||
|
" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Command;
|
||||||
|
|
||||||
|
use App\Entity\User;
|
||||||
|
use Doctrine\ORM\EntityManager;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
|
||||||
|
#[AsCommand(
|
||||||
|
name: 'app:create-user',
|
||||||
|
description: 'Add a short description for your command',
|
||||||
|
)]
|
||||||
|
class CreateUserCommand extends Command
|
||||||
|
{
|
||||||
|
private EntityManager $entityManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param EntityManager $entityManager
|
||||||
|
*/
|
||||||
|
public function __construct(EntityManagerInterface $entityManager)
|
||||||
|
{
|
||||||
|
$this->entityManager = $entityManager;
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
|
{
|
||||||
|
$io = new SymfonyStyle($input, $output);
|
||||||
|
|
||||||
|
|
||||||
|
for ($i=0;$i<100000;$i++) {
|
||||||
|
$user = new User();
|
||||||
|
$user->setUsername('user' . random_int(10000000000, 99999999999))
|
||||||
|
->setScore(random_int(0, 1000))
|
||||||
|
->setLog(false);
|
||||||
|
$this->entityManager->persist($user);
|
||||||
|
}
|
||||||
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
return Command::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Command;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
|
||||||
|
#[AsCommand(
|
||||||
|
name: 'app:update-user-score',
|
||||||
|
description: 'Add a short description for your command',
|
||||||
|
)]
|
||||||
|
class UpdateUserScoreCommand extends Command
|
||||||
|
{
|
||||||
|
private EntityManagerInterface $entityManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param EntityManagerInterface $entityManager
|
||||||
|
*/
|
||||||
|
public function __construct(EntityManagerInterface $entityManager)
|
||||||
|
{
|
||||||
|
$this->entityManager = $entityManager;
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
|
{
|
||||||
|
$io = new SymfonyStyle($input, $output);
|
||||||
|
|
||||||
|
$this->entityManager->getConnection()->executeQuery('
|
||||||
|
UPDATE `user` SET score = RAND() * 1000
|
||||||
|
');
|
||||||
|
|
||||||
|
return Command::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Repository\UserRepository;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
|
||||||
|
class MainController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route('/', name: 'main')]
|
||||||
|
public function index(): Response
|
||||||
|
{
|
||||||
|
return $this->render('main.html.twig');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||||
|
|
||||||
|
class SecurityController extends AbstractController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Route("/login", name="app_login")
|
||||||
|
*/
|
||||||
|
public function login(AuthenticationUtils $authenticationUtils): Response
|
||||||
|
{
|
||||||
|
// if ($this->getUser()) {
|
||||||
|
// return $this->redirectToRoute('target_path');
|
||||||
|
// }
|
||||||
|
|
||||||
|
// get the login error if there is one
|
||||||
|
$error = $authenticationUtils->getLastAuthenticationError();
|
||||||
|
// last username entered by the user
|
||||||
|
$lastUsername = $authenticationUtils->getLastUsername();
|
||||||
|
|
||||||
|
return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Route("/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.');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Repository\UserRepository;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||||
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
|
|
||||||
|
#[ORM\Entity(repositoryClass: UserRepository::class)]
|
||||||
|
#[ORM\Table(name: '`user`')]
|
||||||
|
#[ORM\Index(columns: ['username'])]
|
||||||
|
#[ORM\Index(columns: ['score'])]
|
||||||
|
class User implements UserInterface
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column(type: 'integer')]
|
||||||
|
private int $id;
|
||||||
|
|
||||||
|
#[ORM\Column(type: 'string', length: 180, unique: true)]
|
||||||
|
private string $username;
|
||||||
|
|
||||||
|
#[ORM\Column(type: 'integer')]
|
||||||
|
private int $score;
|
||||||
|
|
||||||
|
#[ORM\Column(type: 'boolean')]
|
||||||
|
private bool $log;
|
||||||
|
|
||||||
|
#[ORM\Column(type: 'json')]
|
||||||
|
private array $roles = [];
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated since Symfony 5.3, use getUserIdentifier instead
|
||||||
|
*/
|
||||||
|
public function getUsername(): string
|
||||||
|
{
|
||||||
|
return (string) $this->username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUsername(string $username): self
|
||||||
|
{
|
||||||
|
$this->username = $username;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getScore(): ?int
|
||||||
|
{
|
||||||
|
return $this->score;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setScore(int $score): self
|
||||||
|
{
|
||||||
|
$this->score = $score;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLog(): ?bool
|
||||||
|
{
|
||||||
|
return $this->log;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLog(bool $log): self
|
||||||
|
{
|
||||||
|
$this->log = $log;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A visual identifier that represents this user.
|
||||||
|
*
|
||||||
|
* @see UserInterface
|
||||||
|
*/
|
||||||
|
public function getUserIdentifier(): string
|
||||||
|
{
|
||||||
|
return (string) $this->username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UserInterface
|
||||||
|
*/
|
||||||
|
public function getRoles(): array
|
||||||
|
{
|
||||||
|
$roles = $this->roles;
|
||||||
|
// guarantee every user at least has ROLE_USER
|
||||||
|
$roles[] = 'ROLE_USER';
|
||||||
|
|
||||||
|
return array_unique($roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setRoles(array $roles): self
|
||||||
|
{
|
||||||
|
$this->roles = $roles;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords.
|
||||||
|
*
|
||||||
|
* @see PasswordAuthenticatedUserInterface
|
||||||
|
*/
|
||||||
|
public function getPassword(): ?string
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords.
|
||||||
|
*
|
||||||
|
* @see UserInterface
|
||||||
|
*/
|
||||||
|
public function getSalt(): ?string
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UserInterface
|
||||||
|
*/
|
||||||
|
public function eraseCredentials()
|
||||||
|
{
|
||||||
|
// If you store any temporary, sensitive data on the user, clear it here
|
||||||
|
// $this->plainPassword = null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Repository\UserLogRepository;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
#[ORM\Entity(repositoryClass: UserLogRepository::class)]
|
||||||
|
class UserLog
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column(type: 'integer')]
|
||||||
|
private int $id;
|
||||||
|
|
||||||
|
#[ORM\Column(type: 'integer')]
|
||||||
|
private int $user_id;
|
||||||
|
|
||||||
|
#[ORM\Column(type: 'integer')]
|
||||||
|
private int $score;
|
||||||
|
|
||||||
|
#[ORM\Column(type: 'datetime_immutable')]
|
||||||
|
private \DateTimeImmutable $created_at;
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserId(): ?int
|
||||||
|
{
|
||||||
|
return $this->user_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUserId(int $user_id): self
|
||||||
|
{
|
||||||
|
$this->user_id = $user_id;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getScore(): ?int
|
||||||
|
{
|
||||||
|
return $this->score;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setScore(int $score): self
|
||||||
|
{
|
||||||
|
$this->score = $score;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCreatedAt(): ?\DateTimeImmutable
|
||||||
|
{
|
||||||
|
return $this->created_at;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCreatedAt(\DateTimeImmutable $created_at): self
|
||||||
|
{
|
||||||
|
$this->created_at = $created_at;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Entity\UserLog;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method UserLog|null find($id, $lockMode = null, $lockVersion = null)
|
||||||
|
* @method UserLog|null findOneBy(array $criteria, array $orderBy = null)
|
||||||
|
* @method UserLog[] findAll()
|
||||||
|
* @method UserLog[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||||
|
*/
|
||||||
|
class UserLogRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(ManagerRegistry $registry)
|
||||||
|
{
|
||||||
|
parent::__construct($registry, UserLog::class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Entity\User;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method User|null find($id, $lockMode = null, $lockVersion = null)
|
||||||
|
* @method User|null findOneBy(array $criteria, array $orderBy = null)
|
||||||
|
* @method User[] findAll()
|
||||||
|
* @method User[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||||
|
*/
|
||||||
|
class UserRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(ManagerRegistry $registry)
|
||||||
|
{
|
||||||
|
parent::__construct($registry, User::class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Security;
|
||||||
|
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CredentialsInterface;
|
||||||
|
|
||||||
|
class EmptyPassword implements CredentialsInterface
|
||||||
|
{
|
||||||
|
public function isResolved(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Security;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
|
||||||
|
use Symfony\Component\Security\Http\Util\TargetPathTrait;
|
||||||
|
|
||||||
|
class UserAuthenticator extends AbstractLoginFormAuthenticator
|
||||||
|
{
|
||||||
|
use TargetPathTrait;
|
||||||
|
|
||||||
|
public const LOGIN_ROUTE = 'app_login';
|
||||||
|
|
||||||
|
private UrlGeneratorInterface $urlGenerator;
|
||||||
|
|
||||||
|
public function __construct(UrlGeneratorInterface $urlGenerator)
|
||||||
|
{
|
||||||
|
$this->urlGenerator = $urlGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function authenticate(Request $request): Passport
|
||||||
|
{
|
||||||
|
$username = $request->request->get('username', '');
|
||||||
|
|
||||||
|
$request->getSession()->set(Security::LAST_USERNAME, $username);
|
||||||
|
|
||||||
|
return new Passport(
|
||||||
|
new UserBadge($username),
|
||||||
|
new EmptyPassword(),
|
||||||
|
[
|
||||||
|
new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token')),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
|
||||||
|
{
|
||||||
|
return new RedirectResponse($this->urlGenerator->generate('main'));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getLoginUrl(Request $request): string
|
||||||
|
{
|
||||||
|
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
|
||||||
|
}
|
||||||
|
}
|
182
symfony.lock
182
symfony.lock
|
@ -1,4 +1,96 @@
|
||||||
{
|
{
|
||||||
|
"composer/package-versions-deprecated": {
|
||||||
|
"version": "1.11.99.4"
|
||||||
|
},
|
||||||
|
"doctrine/annotations": {
|
||||||
|
"version": "1.13",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "master",
|
||||||
|
"version": "1.0",
|
||||||
|
"ref": "a2759dd6123694c8d901d0ec80006e044c2e6457"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"config/routes/annotations.yaml"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"doctrine/cache": {
|
||||||
|
"version": "2.1.1"
|
||||||
|
},
|
||||||
|
"doctrine/collections": {
|
||||||
|
"version": "1.6.8"
|
||||||
|
},
|
||||||
|
"doctrine/common": {
|
||||||
|
"version": "3.2.1"
|
||||||
|
},
|
||||||
|
"doctrine/dbal": {
|
||||||
|
"version": "3.2.1"
|
||||||
|
},
|
||||||
|
"doctrine/deprecations": {
|
||||||
|
"version": "v0.5.3"
|
||||||
|
},
|
||||||
|
"doctrine/doctrine-bundle": {
|
||||||
|
"version": "2.5",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "master",
|
||||||
|
"version": "2.4",
|
||||||
|
"ref": "f98f1affe028f8153a459d15f220ada3826b5aa2"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"config/packages/doctrine.yaml",
|
||||||
|
"config/packages/prod/doctrine.yaml",
|
||||||
|
"config/packages/test/doctrine.yaml",
|
||||||
|
"src/Entity/.gitignore",
|
||||||
|
"src/Repository/.gitignore"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"doctrine/doctrine-migrations-bundle": {
|
||||||
|
"version": "3.2",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "master",
|
||||||
|
"version": "3.1",
|
||||||
|
"ref": "ee609429c9ee23e22d6fa5728211768f51ed2818"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"config/packages/doctrine_migrations.yaml",
|
||||||
|
"migrations/.gitignore"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"doctrine/event-manager": {
|
||||||
|
"version": "1.1.1"
|
||||||
|
},
|
||||||
|
"doctrine/inflector": {
|
||||||
|
"version": "2.0.4"
|
||||||
|
},
|
||||||
|
"doctrine/instantiator": {
|
||||||
|
"version": "1.4.0"
|
||||||
|
},
|
||||||
|
"doctrine/lexer": {
|
||||||
|
"version": "1.2.1"
|
||||||
|
},
|
||||||
|
"doctrine/migrations": {
|
||||||
|
"version": "3.3.2"
|
||||||
|
},
|
||||||
|
"doctrine/orm": {
|
||||||
|
"version": "2.10.4"
|
||||||
|
},
|
||||||
|
"doctrine/persistence": {
|
||||||
|
"version": "2.2.3"
|
||||||
|
},
|
||||||
|
"doctrine/sql-formatter": {
|
||||||
|
"version": "1.1.2"
|
||||||
|
},
|
||||||
|
"friendsofphp/proxy-manager-lts": {
|
||||||
|
"version": "v1.0.5"
|
||||||
|
},
|
||||||
|
"laminas/laminas-code": {
|
||||||
|
"version": "4.5.1"
|
||||||
|
},
|
||||||
|
"nikic/php-parser": {
|
||||||
|
"version": "v4.13.2"
|
||||||
|
},
|
||||||
"psr/cache": {
|
"psr/cache": {
|
||||||
"version": "2.0.0"
|
"version": "2.0.0"
|
||||||
},
|
},
|
||||||
|
@ -38,6 +130,9 @@
|
||||||
"symfony/deprecation-contracts": {
|
"symfony/deprecation-contracts": {
|
||||||
"version": "v3.0.0"
|
"version": "v3.0.0"
|
||||||
},
|
},
|
||||||
|
"symfony/doctrine-bridge": {
|
||||||
|
"version": "v5.4.2"
|
||||||
|
},
|
||||||
"symfony/dotenv": {
|
"symfony/dotenv": {
|
||||||
"version": "v5.4.2"
|
"version": "v5.4.2"
|
||||||
},
|
},
|
||||||
|
@ -93,6 +188,18 @@
|
||||||
"symfony/http-kernel": {
|
"symfony/http-kernel": {
|
||||||
"version": "v5.4.2"
|
"version": "v5.4.2"
|
||||||
},
|
},
|
||||||
|
"symfony/maker-bundle": {
|
||||||
|
"version": "1.36",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "master",
|
||||||
|
"version": "1.0",
|
||||||
|
"ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"symfony/password-hasher": {
|
||||||
|
"version": "v5.4.2"
|
||||||
|
},
|
||||||
"symfony/polyfill-intl-grapheme": {
|
"symfony/polyfill-intl-grapheme": {
|
||||||
"version": "v1.24.0"
|
"version": "v1.24.0"
|
||||||
},
|
},
|
||||||
|
@ -111,6 +218,15 @@
|
||||||
"symfony/polyfill-php81": {
|
"symfony/polyfill-php81": {
|
||||||
"version": "v1.24.0"
|
"version": "v1.24.0"
|
||||||
},
|
},
|
||||||
|
"symfony/property-access": {
|
||||||
|
"version": "v5.4.2"
|
||||||
|
},
|
||||||
|
"symfony/property-info": {
|
||||||
|
"version": "v5.4.2"
|
||||||
|
},
|
||||||
|
"symfony/proxy-manager-bridge": {
|
||||||
|
"version": "v5.4.2"
|
||||||
|
},
|
||||||
"symfony/routing": {
|
"symfony/routing": {
|
||||||
"version": "5.4",
|
"version": "5.4",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
|
@ -127,19 +243,85 @@
|
||||||
"symfony/runtime": {
|
"symfony/runtime": {
|
||||||
"version": "v5.4.1"
|
"version": "v5.4.1"
|
||||||
},
|
},
|
||||||
|
"symfony/security-bundle": {
|
||||||
|
"version": "5.4",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "master",
|
||||||
|
"version": "5.3",
|
||||||
|
"ref": "09b5e809bd7a992061febd05b797c64a2d93b5cd"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"config/packages/security.yaml"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"symfony/security-core": {
|
||||||
|
"version": "v5.4.2"
|
||||||
|
},
|
||||||
|
"symfony/security-csrf": {
|
||||||
|
"version": "v5.4.0"
|
||||||
|
},
|
||||||
|
"symfony/security-guard": {
|
||||||
|
"version": "v5.4.0"
|
||||||
|
},
|
||||||
|
"symfony/security-http": {
|
||||||
|
"version": "v5.4.2"
|
||||||
|
},
|
||||||
"symfony/service-contracts": {
|
"symfony/service-contracts": {
|
||||||
"version": "v2.4.1"
|
"version": "v2.4.1"
|
||||||
},
|
},
|
||||||
|
"symfony/stopwatch": {
|
||||||
|
"version": "v5.4.0"
|
||||||
|
},
|
||||||
"symfony/string": {
|
"symfony/string": {
|
||||||
"version": "v5.4.2"
|
"version": "v5.4.2"
|
||||||
},
|
},
|
||||||
|
"symfony/translation-contracts": {
|
||||||
|
"version": "v2.5.0"
|
||||||
|
},
|
||||||
|
"symfony/twig-bridge": {
|
||||||
|
"version": "v5.4.0"
|
||||||
|
},
|
||||||
|
"symfony/twig-bundle": {
|
||||||
|
"version": "5.4",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "master",
|
||||||
|
"version": "5.4",
|
||||||
|
"ref": "bffbb8f1a849736e64006735afae730cb428b6ff"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"config/packages/twig.yaml",
|
||||||
|
"templates/base.html.twig"
|
||||||
|
]
|
||||||
|
},
|
||||||
"symfony/var-dumper": {
|
"symfony/var-dumper": {
|
||||||
"version": "v5.4.2"
|
"version": "v5.4.2"
|
||||||
},
|
},
|
||||||
"symfony/var-exporter": {
|
"symfony/var-exporter": {
|
||||||
"version": "v5.4.2"
|
"version": "v5.4.2"
|
||||||
},
|
},
|
||||||
|
"symfony/web-profiler-bundle": {
|
||||||
|
"version": "5.4",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "master",
|
||||||
|
"version": "3.3",
|
||||||
|
"ref": "6bdfa1a95f6b2e677ab985cd1af2eae35d62e0f6"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"config/packages/dev/web_profiler.yaml",
|
||||||
|
"config/packages/test/web_profiler.yaml",
|
||||||
|
"config/routes/dev/web_profiler.yaml"
|
||||||
|
]
|
||||||
|
},
|
||||||
"symfony/yaml": {
|
"symfony/yaml": {
|
||||||
"version": "v5.4.2"
|
"version": "v5.4.2"
|
||||||
|
},
|
||||||
|
"twig/extra-bundle": {
|
||||||
|
"version": "v3.3.7"
|
||||||
|
},
|
||||||
|
"twig/twig": {
|
||||||
|
"version": "v3.3.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>{% block title %}Welcome!{% endblock %}</title>
|
||||||
|
<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 #}
|
||||||
|
{% block stylesheets %}
|
||||||
|
{{ encore_entry_link_tags('app') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block javascripts %}
|
||||||
|
{{ encore_entry_script_tags('app') }}
|
||||||
|
{% endblock %}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% block body %}{% endblock %}
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,7 @@
|
||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}Main!{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
Main
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}Log in!{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<form method="post">
|
||||||
|
{% if error %}
|
||||||
|
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if app.user %}
|
||||||
|
<div class="mb-3">
|
||||||
|
You are logged in as {{ app.user.username }}, <a href="{{ path('app_logout') }}">Logout</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
|
||||||
|
<label for="inputUsername">Username</label>
|
||||||
|
<input type="text" value="{{ last_username }}" name="username" id="inputUsername" class="form-control" autocomplete="username" required autofocus>
|
||||||
|
|
||||||
|
<input type="hidden" name="_csrf_token"
|
||||||
|
value="{{ csrf_token('authenticate') }}"
|
||||||
|
>
|
||||||
|
|
||||||
|
<button class="btn btn-lg btn-primary" type="submit">
|
||||||
|
Sign in
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue