diff --git a/assets/styles/pages/global.scss b/assets/styles/pages/global.scss index b5731618..c24d073c 100755 --- a/assets/styles/pages/global.scss +++ b/assets/styles/pages/global.scss @@ -9,6 +9,11 @@ body { line-height: 2rem; } +.masthead-avatar { + width: 2rem; + max-height: 2rem; + display: inline-block; +} #wrapper { min-height: 100vh; @@ -30,6 +35,7 @@ body { .bg-img { background-attachment: fixed; background-size: cover; + background-repeat: no-repeat; overflow: hidden; background-position: center; min-height: 100vh; @@ -37,12 +43,13 @@ body { .bg-accessories { @extend .bg-img; - // background-image: url('img/accessories.jpg'); + // background-image: url('assets/img/accessories.jpg'); } .bg-girl { @extend .bg-img; - // background-image: url('img/girl_computer.jpg'); + // background-image: url('../img/girl_computer.jpg'); + // background-image: url('assets/img/girl_computer.jpg'); } .bg-color { diff --git a/config/packages/security.yaml b/config/packages/security.yaml index f882a2de..0936e9ef 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -1,33 +1,36 @@ +# config/packages/security.yaml security: - # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords + # Hashers pour les mots de passe password_hashers: - Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto' - # https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider + App\Entity\User: + algorithm: auto + + # Fournisseurs d'utilisateurs providers: - # used to reload user from session & other features (e.g. switch_user) app_user_provider: entity: class: App\Entity\User property: email + + # Firewalls firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: - lazy: true - provider: app_user_provider + form_login: + # "app_login" is the name of the route created previously + login_path: app_login + check_path: app_login + # access_token: + # token_handler: App\Security\AccessTokenHandler - # 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 + # Contrôle d'accès access_control: - - { path: ^/admin, roles: ROLE_ADMIN } - - { path: ^/logged, roles: ROLE_USER } + - { path: ^/admin, roles: ROLE_ADMIN } + - { path: ^/logged, roles: ROLE_USER } + # - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } # Autoriser l'accès à la page de connexion + # - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY } # Autoriser l'accès anonyme à toutes les autres pages when@test: security: diff --git a/config/services.yaml b/config/services.yaml index fcab339f..bd4f3c43 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -25,3 +25,7 @@ services: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler: arguments: - '%env(DATABASE_URL)%' + + App\Filter\UserProductsFilter: + arguments: [ '@security.helper' ] + tags: [ 'api_platform.filter' ] \ No newline at end of file diff --git a/src/Controller/LoginController.php b/src/Controller/LoginController.php new file mode 100644 index 00000000..0fb6e52a --- /dev/null +++ b/src/Controller/LoginController.php @@ -0,0 +1,18 @@ +render('login/index.html.twig', [ + 'controller_name' => 'LoginController', + ]); + } +} diff --git a/src/Controller/SecurityController.php b/src/Controller/SecurityController.php index 5e4022d1..7dd6e53d 100644 --- a/src/Controller/SecurityController.php +++ b/src/Controller/SecurityController.php @@ -25,8 +25,9 @@ class SecurityController extends AbstractController } #[Route(path: '/logout', name: 'app_logout')] - public function logout(): void + public function logout(): Response { - throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.'); + return $this->redirectToRoute('app_default'); + } } diff --git a/src/Entity/Product.php b/src/Entity/Product.php index adbf6e37..038ccb91 100644 --- a/src/Entity/Product.php +++ b/src/Entity/Product.php @@ -3,12 +3,17 @@ namespace App\Entity; use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\ApiProperty; use App\Repository\ProductRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; +use App\Filter\UserProductsFilter; +use App\DTO\UserDTO; + #[ApiResource(paginationEnabled: false)] +#[UserProductsFilter] #[ORM\Entity(repositoryClass: ProductRepository::class)] class Product { @@ -30,12 +35,14 @@ class Product * @var Collection */ #[ORM\ManyToMany(targetEntity: GroupOfProducts::class, mappedBy: 'products')] + #[ApiProperty(readable: false)] private Collection $groupOfProducts; /** * @var Collection */ #[ORM\ManyToMany(targetEntity: Selling::class, mappedBy: 'products')] + #[ApiProperty(readable: false)] private Collection $sellings; #[ORM\ManyToOne(inversedBy: 'products')] diff --git a/src/EventSubscriber/NotShownCountSubscriber.php b/src/EventSubscriber/NotShownCountSubscriber.php new file mode 100644 index 00000000..bf8f55b8 --- /dev/null +++ b/src/EventSubscriber/NotShownCountSubscriber.php @@ -0,0 +1,27 @@ + ['addNotShownCount', EventPriorities::PRE_WRITE], + ]; + } + + public function addNotShownCount(FilterCollectionEvent $event): void + { + $context = $event->getContext(); + if (isset($context['notShownCount'])) { + $event->getResponse()->setData(array_merge($event->getResponse()->getData(), [ + 'notShownCount' => $context['notShownCount'], + ])); + } + } +} \ No newline at end of file diff --git a/src/Filter/UserProductsFilter.php b/src/Filter/UserProductsFilter.php new file mode 100644 index 00000000..5bea99b1 --- /dev/null +++ b/src/Filter/UserProductsFilter.php @@ -0,0 +1,52 @@ +security = $security; + } + + protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, ?Operation $operation = null, array $context = []): void + { + if ($property === 'user' && $this->security->isGranted('ROLE_USER')) { + $user = $this->security->getUser(); + $queryBuilder->andWhere('o.user = :user')->setParameter('user', $user); + + // Compter le nombre total de produits pour l'utilisateur + $totalProducts = $queryBuilder->getEntityManager()->getRepository('App\Entity\Product')->count(['user' => $user]); + $filteredProducts = $queryBuilder->getQuery()->getResult(); + $notShownCount = $totalProducts - count($filteredProducts); + + // Ajouter le nombre de produits non montrés au contexte + $context['notShownCount'] = $notShownCount; + } + } + + public function getDescription(string $resourceClass): array + { + return [ + 'user' => [ + 'property' => 'user', + 'type' => 'string', + 'required' => false, + 'swagger' => [ + 'description' => 'Filtrer les produits par utilisateur connecté', + ], + ], + ]; + } +} \ No newline at end of file diff --git a/src/Security/AccessTokenHandler.php b/src/Security/AccessTokenHandler.php new file mode 100644 index 00000000..661d662f --- /dev/null +++ b/src/Security/AccessTokenHandler.php @@ -0,0 +1,30 @@ +repository->findOneByValue($accessToken); + if (null === $accessToken || !$accessToken->isValid()) { + throw new BadCredentialsException('Invalid credentials.'); + } + + // and return a UserBadge object containing the user identifier from the found token + // (this is the same identifier used in Security configuration; it can be an email, + // a UUID, a username, a database ID, etc.) + return new UserBadge($accessToken->getUserId()); + } +} \ No newline at end of file diff --git a/templates/base.html.twig b/templates/base.html.twig index 1c48dcb9..62463f7e 100755 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -32,13 +32,16 @@ + {% include 'default/login-choices.html.twig' %} + +
- ... + ...

Caisse Bliss

diff --git a/templates/default/header.html.twig b/templates/default/header.html.twig index cb15e9d8..ca19e067 100755 --- a/templates/default/header.html.twig +++ b/templates/default/header.html.twig @@ -3,7 +3,7 @@
- {% include 'default/login-choices.html.twig' %} +