remove core from app
This commit is contained in:
parent
fed3c1b3ae
commit
079e52eb42
|
@ -72,7 +72,8 @@
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"App\\": "src/"
|
"App\\": "src/",
|
||||||
|
"App\\Core\\": "core/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload-dev": {
|
"autoload-dev": {
|
||||||
|
|
|
@ -17,5 +17,5 @@ return [
|
||||||
Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle::class => ['all' => true],
|
Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle::class => ['all' => true],
|
||||||
Scheb\TwoFactorBundle\SchebTwoFactorBundle::class => ['all' => true],
|
Scheb\TwoFactorBundle\SchebTwoFactorBundle::class => ['all' => true],
|
||||||
Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true],
|
Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true],
|
||||||
App\Bundle\AppBundle::class => ['all' => true],
|
App\Core\Bundle\AppBundle::class => ['all' => true],
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
app:
|
app:
|
||||||
site:
|
site:
|
||||||
pages:
|
pages:
|
||||||
App\Site\Page\SimplePage:
|
App\Entity\Page\SimplePage:
|
||||||
name: 'Page simple'
|
name: 'Page simple'
|
||||||
templates:
|
templates:
|
||||||
- {name: "Template 1", file: "site/page/simple/page.html.twig"}
|
- {name: "Template 1", file: "site/page/simple/page.html.twig"}
|
||||||
|
|
|
@ -10,17 +10,18 @@ doctrine:
|
||||||
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
|
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
|
||||||
auto_mapping: true
|
auto_mapping: true
|
||||||
mappings:
|
mappings:
|
||||||
|
App\Core\Entity:
|
||||||
|
is_bundle: false
|
||||||
|
type: annotation
|
||||||
|
dir: '%kernel.project_dir%/core/Entity'
|
||||||
|
prefix: 'App\Core\Entity'
|
||||||
|
alias: App\Core\Entity
|
||||||
App\Entity:
|
App\Entity:
|
||||||
is_bundle: false
|
is_bundle: false
|
||||||
type: annotation
|
type: annotation
|
||||||
dir: '%kernel.project_dir%/src/Entity'
|
dir: '%kernel.project_dir%/src/Entity'
|
||||||
prefix: 'App\Entity'
|
prefix: 'App\Entity'
|
||||||
alias: App\Entity
|
alias: App\Entity
|
||||||
App\Site\Page:
|
|
||||||
is_bundle: false
|
|
||||||
type: annotation
|
|
||||||
dir: '%kernel.project_dir%/src/Site/Page'
|
|
||||||
prefix: 'App\Site\Page'
|
|
||||||
gedmo_tree:
|
gedmo_tree:
|
||||||
type: annotation
|
type: annotation
|
||||||
prefix: Gedmo\Tree\Entity
|
prefix: Gedmo\Tree\Entity
|
||||||
|
|
|
@ -26,7 +26,7 @@ security:
|
||||||
check_path: 2fa_login_check # The route name you have used in the routes.yaml
|
check_path: 2fa_login_check # The route name you have used in the routes.yaml
|
||||||
guard:
|
guard:
|
||||||
authenticators:
|
authenticators:
|
||||||
- App\Authenticator\LoginFormAuthenticator
|
- App\Core\Authenticator\LoginFormAuthenticator
|
||||||
form_login:
|
form_login:
|
||||||
login_path: auth_login
|
login_path: auth_login
|
||||||
check_path: auth_login
|
check_path: auth_login
|
||||||
|
|
|
@ -2,6 +2,10 @@ controllers:
|
||||||
resource: ../../src/Controller/
|
resource: ../../src/Controller/
|
||||||
type: annotation
|
type: annotation
|
||||||
|
|
||||||
|
core_controllers:
|
||||||
|
resource: ../../core/Controller/
|
||||||
|
type: annotation
|
||||||
|
|
||||||
kernel:
|
kernel:
|
||||||
resource: ../../src/Kernel.php
|
resource: ../../src/Kernel.php
|
||||||
type: annotation
|
type: annotation
|
||||||
|
|
|
@ -13,6 +13,11 @@ services:
|
||||||
|
|
||||||
# makes classes in src/ available to be used as services
|
# makes classes in src/ available to be used as services
|
||||||
# this creates a service per class whose id is the fully-qualified class name
|
# this creates a service per class whose id is the fully-qualified class name
|
||||||
|
App\Core\:
|
||||||
|
resource: '../core/'
|
||||||
|
exclude:
|
||||||
|
- '../core/DependencyInjection/'
|
||||||
|
- '../core/Entity/'
|
||||||
App\:
|
App\:
|
||||||
resource: '../src/'
|
resource: '../src/'
|
||||||
exclude:
|
exclude:
|
||||||
|
@ -23,12 +28,16 @@ services:
|
||||||
|
|
||||||
# controllers are imported separately to make sure services can be injected
|
# controllers are imported separately to make sure services can be injected
|
||||||
# as action arguments even if you don't extend any base controller class
|
# as action arguments even if you don't extend any base controller class
|
||||||
|
App\Core\Controller\:
|
||||||
|
resource: '../core/Controller/'
|
||||||
|
tags: ['controller.service_arguments']
|
||||||
|
|
||||||
App\Controller\:
|
App\Controller\:
|
||||||
resource: '../src/Controller/'
|
resource: '../src/Controller/'
|
||||||
tags: ['controller.service_arguments']
|
tags: ['controller.service_arguments']
|
||||||
|
|
||||||
site.route_loader:
|
site.route_loader:
|
||||||
class: App\Router\SiteRouteLoader
|
class: App\Core\Router\SiteRouteLoader
|
||||||
tags: [routing.loader]
|
tags: [routing.loader]
|
||||||
|
|
||||||
gedmo.listener.tree:
|
gedmo.listener.tree:
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Authenticator;
|
|
||||||
|
|
||||||
use App\Entity\User;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
|
||||||
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
|
|
||||||
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
|
|
||||||
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
|
|
||||||
use Symfony\Component\Security\Core\Security;
|
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
|
||||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
|
||||||
use Symfony\Component\Security\Csrf\CsrfToken;
|
|
||||||
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
|
|
||||||
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
|
|
||||||
use Symfony\Component\Security\Http\Util\TargetPathTrait;
|
|
||||||
|
|
||||||
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
|
|
||||||
{
|
|
||||||
use TargetPathTrait;
|
|
||||||
|
|
||||||
private EntityManagerInterface $entityManager;
|
|
||||||
|
|
||||||
private UrlGeneratorInterface $urlGenerator;
|
|
||||||
|
|
||||||
private CsrfTokenManagerInterface $csrfTokenManager;
|
|
||||||
|
|
||||||
private UserPasswordEncoderInterface $passwordEncoder;
|
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
|
|
||||||
{
|
|
||||||
$this->entityManager = $entityManager;
|
|
||||||
$this->urlGenerator = $urlGenerator;
|
|
||||||
$this->csrfTokenManager = $csrfTokenManager;
|
|
||||||
$this->passwordEncoder = $passwordEncoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function supports(Request $request)
|
|
||||||
{
|
|
||||||
return 'auth_login' === $request->attributes->get('_route') && $request->isMethod('POST');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCredentials(Request $request)
|
|
||||||
{
|
|
||||||
$credentials = [
|
|
||||||
'email' => $request->request->get('_username'),
|
|
||||||
'password' => $request->request->get('_password'),
|
|
||||||
'csrf_token' => $request->request->get('_csrf_token'),
|
|
||||||
];
|
|
||||||
|
|
||||||
$request->getSession()->set(Security::LAST_USERNAME, $credentials['email']);
|
|
||||||
|
|
||||||
return $credentials;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUser($credentials, UserProviderInterface $userProvider)
|
|
||||||
{
|
|
||||||
$token = new CsrfToken('authenticate', $credentials['csrf_token']);
|
|
||||||
|
|
||||||
if (!$this->csrfTokenManager->isTokenValid($token)) {
|
|
||||||
throw new InvalidCsrfTokenException();
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $credentials['email']]);
|
|
||||||
|
|
||||||
if (!$user) {
|
|
||||||
// fail authentication with a custom error
|
|
||||||
throw new CustomUserMessageAuthenticationException('Email could not be found.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function checkCredentials($credentials, UserInterface $user)
|
|
||||||
{
|
|
||||||
return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
|
|
||||||
{
|
|
||||||
if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
|
|
||||||
return new RedirectResponse($targetPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RedirectResponse($this->urlGenerator->generate('admin_dashboard_index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getLoginUrl()
|
|
||||||
{
|
|
||||||
return $this->urlGenerator->generate('auth_login');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of Twig.
|
|
||||||
*
|
|
||||||
* (c) Fabien Potencier
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Bundle;
|
|
||||||
|
|
||||||
use App\DependencyInjection\AppExtension;
|
|
||||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
|
||||||
|
|
||||||
class AppBundle extends Bundle
|
|
||||||
{
|
|
||||||
public function getContainerExtension()
|
|
||||||
{
|
|
||||||
return new AppExtension();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,153 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\Account;
|
|
||||||
|
|
||||||
use App\Controller\Admin\AdminController;
|
|
||||||
use App\Manager\EntityManager;
|
|
||||||
use App\Repository\UserRepository;
|
|
||||||
use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticatorInterface;
|
|
||||||
use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticatorInterface as TotpAuthenticatorInterface;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
|
|
||||||
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
|
|
||||||
use ZxcvbnPhp\Zxcvbn;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/admin/account")
|
|
||||||
*/
|
|
||||||
class AccountAdminController extends AdminController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @Route("/", name="admin_account")
|
|
||||||
*/
|
|
||||||
public function account(Request $request, TotpAuthenticatorInterface $totpAuthenticatorService): Response
|
|
||||||
{
|
|
||||||
$account = $this->getUser();
|
|
||||||
|
|
||||||
return $this->render('account/admin/edit.html.twig', [
|
|
||||||
'account' => $account,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/2fa", name="admin_account_2fa")
|
|
||||||
*/
|
|
||||||
public function twoFactorAuthentication(
|
|
||||||
Request $request,
|
|
||||||
GoogleAuthenticatorInterface $totpAuthenticatorService,
|
|
||||||
EntityManager $entityManager
|
|
||||||
): Response {
|
|
||||||
if ($request->isMethod('GET')) {
|
|
||||||
return $this->redirectToRoute('admin_account');
|
|
||||||
}
|
|
||||||
|
|
||||||
$account = $this->getUser();
|
|
||||||
$csrfToken = $request->request->get('_csrf_token');
|
|
||||||
$enable = (bool) $request->request->get('enable');
|
|
||||||
$code = $request->request->get('code', '');
|
|
||||||
$secret = $request->request->get('secret', '');
|
|
||||||
$qrCodeContent = null;
|
|
||||||
|
|
||||||
if ($this->isCsrfTokenValid('2fa', $csrfToken)) {
|
|
||||||
if ($enable && !$account->isTotpAuthenticationEnabled()) {
|
|
||||||
if (empty($secret)) {
|
|
||||||
$secret = $totpAuthenticatorService->generateSecret();
|
|
||||||
|
|
||||||
$account->setTotpSecret($secret);
|
|
||||||
|
|
||||||
$qrCodeContent = $totpAuthenticatorService->getQRContent($account);
|
|
||||||
} else {
|
|
||||||
$account->setTotpSecret($secret);
|
|
||||||
|
|
||||||
$qrCodeContent = $totpAuthenticatorService->getQRContent($account);
|
|
||||||
|
|
||||||
if (!$totpAuthenticatorService->checkCode($account, $code)) {
|
|
||||||
$this->addFlash('error', 'Le code n\'est pas valide.');
|
|
||||||
} else {
|
|
||||||
$this->addFlash('success', 'Double authentification activée.');
|
|
||||||
|
|
||||||
$entityManager->update($account);
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_account');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$enable && $account->isTotpAuthenticationEnabled()) {
|
|
||||||
$account->setTotpSecret(null);
|
|
||||||
|
|
||||||
$entityManager->update($account);
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Double authentification désactivée.');
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_account');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('account/admin/edit.html.twig', [
|
|
||||||
'account' => $account,
|
|
||||||
'twoFaKey' => $secret,
|
|
||||||
'twoFaQrCodeContent' => $qrCodeContent,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/password", name="admin_account_password", methods={"POST"})
|
|
||||||
*/
|
|
||||||
public function password(
|
|
||||||
Request $request,
|
|
||||||
UserRepository $repository,
|
|
||||||
TokenGeneratorInterface $tokenGenerator,
|
|
||||||
UserPasswordEncoderInterface $encoder,
|
|
||||||
EntityManager $entityManager
|
|
||||||
): Response {
|
|
||||||
$account = $this->getUser();
|
|
||||||
$csrfToken = $request->request->get('_csrf_token');
|
|
||||||
|
|
||||||
if ($this->isCsrfTokenValid('password', $csrfToken)) {
|
|
||||||
$password = $request->request->get('password');
|
|
||||||
|
|
||||||
if (!$encoder->isPasswordValid($account, $password)) {
|
|
||||||
$this->addFlash('error', 'Le formulaire n\'est pas valide.');
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_account');
|
|
||||||
}
|
|
||||||
|
|
||||||
$password1 = $request->request->get('password1');
|
|
||||||
$password2 = $request->request->get('password2');
|
|
||||||
|
|
||||||
$zxcvbn = new Zxcvbn();
|
|
||||||
$strength = $zxcvbn->passwordStrength($password1, []);
|
|
||||||
|
|
||||||
if (4 === $strength['score'] && $password1 === $password2) {
|
|
||||||
$account
|
|
||||||
->setPassword($encoder->encodePassword(
|
|
||||||
$account,
|
|
||||||
$password1
|
|
||||||
))
|
|
||||||
->setConfirmationToken($tokenGenerator->generateToken())
|
|
||||||
;
|
|
||||||
|
|
||||||
$entityManager->update($account);
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Mot de passe modifié !');
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_account');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->addFlash('error', 'Le formulaire n\'est pas valide.');
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_account');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
protected function getSection(): string
|
|
||||||
{
|
|
||||||
return 'account';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\Admin;
|
|
||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
|
|
||||||
abstract class AdminController extends AbstractController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
protected function render(string $view, array $parameters = [], Response $response = null): Response
|
|
||||||
{
|
|
||||||
$parameters['section'] = $this->getSection();
|
|
||||||
|
|
||||||
return parent::render($view, $parameters, $response);
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected function getSection(): string;
|
|
||||||
}
|
|
|
@ -1,159 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\Auth;
|
|
||||||
|
|
||||||
use App\Event\Account\PasswordRequestEvent;
|
|
||||||
use App\Manager\EntityManager;
|
|
||||||
use App\Repository\UserRepository;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
|
|
||||||
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
|
|
||||||
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
|
||||||
use ZxcvbnPhp\Zxcvbn;
|
|
||||||
|
|
||||||
class AuthController extends AbstractController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @Route("/login", name="auth_login")
|
|
||||||
*/
|
|
||||||
public function login(AuthenticationUtils $authenticationUtils): Response
|
|
||||||
{
|
|
||||||
if ($this->getUser()) {
|
|
||||||
return $this->redirectToRoute('admin_dashboard_index');
|
|
||||||
}
|
|
||||||
|
|
||||||
$error = $authenticationUtils->getLastAuthenticationError();
|
|
||||||
$lastUsername = $authenticationUtils->getLastUsername();
|
|
||||||
|
|
||||||
return $this->render('auth/login.html.twig', [
|
|
||||||
'last_username' => $lastUsername,
|
|
||||||
'error' => $error,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/resetting/request", name="auth_resetting_request")
|
|
||||||
*/
|
|
||||||
public function requestResetting(
|
|
||||||
Request $request,
|
|
||||||
UserRepository $repository,
|
|
||||||
TokenGeneratorInterface $tokenGenerator,
|
|
||||||
EntityManager $entityManager,
|
|
||||||
EventDispatcherInterface $eventDispatcher
|
|
||||||
): Response {
|
|
||||||
if ($this->getUser()) {
|
|
||||||
return $this->redirectToRoute('admin_dashboard_index');
|
|
||||||
}
|
|
||||||
|
|
||||||
$emailSent = false;
|
|
||||||
|
|
||||||
if ($request->isMethod('POST')) {
|
|
||||||
$csrfToken = $request->request->get('_csrf_token');
|
|
||||||
|
|
||||||
if ($this->isCsrfTokenValid('resetting_request', $csrfToken)) {
|
|
||||||
$username = trim((string) $request->request->get('username'));
|
|
||||||
|
|
||||||
if ($username) {
|
|
||||||
$account = $repository->findOneByEmail($username);
|
|
||||||
|
|
||||||
if ($account) {
|
|
||||||
$passwordRequestedAt = $account->getPasswordRequestedAt();
|
|
||||||
|
|
||||||
if (null !== $passwordRequestedAt && $passwordRequestedAt->getTimestamp() > (time() - 3600 / 2)) {
|
|
||||||
$emailSent = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$emailSent) {
|
|
||||||
$account->setConfirmationToken($tokenGenerator->generateToken());
|
|
||||||
$account->setPasswordRequestedAt(new \DateTime('now'));
|
|
||||||
|
|
||||||
$entityManager->update($account);
|
|
||||||
$eventDispatcher->dispatch(new PasswordRequestEvent($account), PasswordRequestEvent::EVENT);
|
|
||||||
|
|
||||||
$emailSent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('auth/resetting_request.html.twig', [
|
|
||||||
'email_sent' => $emailSent,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/resetting/update/{token}", name="auth_resetting_update")
|
|
||||||
*/
|
|
||||||
public function requestUpdate(
|
|
||||||
string $token,
|
|
||||||
Request $request,
|
|
||||||
UserRepository $repository,
|
|
||||||
TokenGeneratorInterface $tokenGenerator,
|
|
||||||
UserPasswordEncoderInterface $encoder,
|
|
||||||
EntityManager $entityManager
|
|
||||||
): Response {
|
|
||||||
if ($this->getUser()) {
|
|
||||||
return $this->redirectToRoute('admin_dashboard_index');
|
|
||||||
}
|
|
||||||
|
|
||||||
$account = $repository->findOneByConfirmationToken($token);
|
|
||||||
$passwordUpdated = false;
|
|
||||||
$expired = false;
|
|
||||||
|
|
||||||
if ($account) {
|
|
||||||
$passwordRequestedAt = $account->getPasswordRequestedAt();
|
|
||||||
|
|
||||||
if (null !== $passwordRequestedAt && $passwordRequestedAt->getTimestamp() < (time() - 3600 * 2)) {
|
|
||||||
$expired = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$expired = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->isMethod('POST') && !$expired) {
|
|
||||||
$csrfToken = $request->request->get('_csrf_token');
|
|
||||||
|
|
||||||
if ($this->isCsrfTokenValid('resetting_update', $csrfToken)) {
|
|
||||||
$password = $request->request->get('password');
|
|
||||||
$password2 = $request->request->get('password2');
|
|
||||||
|
|
||||||
$zxcvbn = new Zxcvbn();
|
|
||||||
$strength = $zxcvbn->passwordStrength($password, []);
|
|
||||||
|
|
||||||
if (4 === $strength['score'] && $password === $password2) {
|
|
||||||
$account
|
|
||||||
->setPassword($encoder->encodePassword(
|
|
||||||
$account,
|
|
||||||
$password
|
|
||||||
))
|
|
||||||
->setConfirmationToken($tokenGenerator->generateToken())
|
|
||||||
->setPasswordRequestedAt(new \DateTime('now'))
|
|
||||||
;
|
|
||||||
|
|
||||||
$entityManager->update($account);
|
|
||||||
|
|
||||||
$passwordUpdated = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('auth/resetting_update.html.twig', [
|
|
||||||
'password_updated' => $passwordUpdated,
|
|
||||||
'token' => $token,
|
|
||||||
'expired' => $expired,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/logout", name="auth_logout")
|
|
||||||
*/
|
|
||||||
public function logout()
|
|
||||||
{
|
|
||||||
throw new \Exception('This method can be blank - it will be intercepted by the logout key on your firewall');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
namespace App\Controller\Blog;
|
namespace App\Controller\Blog;
|
||||||
|
|
||||||
use App\Controller\Admin\AdminController;
|
use App\Core\Controller\Admin\AdminController;
|
||||||
use App\Entity\Blog\Category as Entity;
|
use App\Entity\Blog\Category as Entity;
|
||||||
use App\Factory\Blog\CategoryFactory as EntityFactory;
|
use App\Factory\Blog\CategoryFactory as EntityFactory;
|
||||||
use App\Form\Blog\CategoryType as EntityType;
|
use App\Form\Blog\CategoryType as EntityType;
|
||||||
use App\Manager\EntityManager;
|
use App\Core\Manager\EntityManager;
|
||||||
use App\Repository\Blog\CategoryRepositoryQuery as RepositoryQuery;
|
use App\Repository\Blog\CategoryRepositoryQuery as RepositoryQuery;
|
||||||
use App\Repository\Blog\PostRepositoryQuery;
|
use App\Repository\Blog\PostRepositoryQuery;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
namespace App\Controller\Blog;
|
namespace App\Controller\Blog;
|
||||||
|
|
||||||
use App\Controller\Admin\AdminController;
|
use App\Core\Controller\Admin\AdminController;
|
||||||
use App\Entity\Blog\Post as Entity;
|
use App\Entity\Blog\Post as Entity;
|
||||||
use App\Factory\Blog\PostFactory as EntityFactory;
|
use App\Factory\Blog\PostFactory as EntityFactory;
|
||||||
use App\Form\Blog\PostType as EntityType;
|
use App\Form\Blog\PostType as EntityType;
|
||||||
use App\Form\FileUploadHandler;
|
use App\Core\Form\FileUploadHandler;
|
||||||
use App\Manager\EntityManager;
|
use App\Core\Manager\EntityManager;
|
||||||
use App\Repository\Blog\PostRepositoryQuery as RepositoryQuery;
|
use App\Repository\Blog\PostRepositoryQuery as RepositoryQuery;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\Dashboard;
|
|
||||||
|
|
||||||
use App\Controller\Admin\AdminController;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/admin")
|
|
||||||
*/
|
|
||||||
class DashboardAdminController extends AdminController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @Route("/", name="admin_dashboard_index")
|
|
||||||
*/
|
|
||||||
public function index(): Response
|
|
||||||
{
|
|
||||||
return $this->render('dashboard/admin/index.html.twig', [
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getSection(): string
|
|
||||||
{
|
|
||||||
return 'dashboard';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\Site;
|
|
||||||
|
|
||||||
use App\Controller\Admin\AdminController;
|
|
||||||
use App\Entity\Site\Menu as Entity;
|
|
||||||
use App\Entity\Site\Navigation;
|
|
||||||
use App\Factory\Site\MenuFactory as EntityFactory;
|
|
||||||
use App\Form\Site\MenuType as EntityType;
|
|
||||||
use App\Manager\EntityManager;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/admin/site/menu")
|
|
||||||
*/
|
|
||||||
class MenuAdminController extends AdminController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @Route("/new/{navigation}", name="admin_site_menu_new", methods={"POST"})
|
|
||||||
*/
|
|
||||||
public function new(Navigation $navigation, EntityFactory $factory, EntityManager $entityManager, Request $request): Response
|
|
||||||
{
|
|
||||||
$entity = $factory->create($navigation);
|
|
||||||
$form = $this->createForm(EntityType::class, $entity);
|
|
||||||
$form->handleRequest($request);
|
|
||||||
|
|
||||||
if ($form->isValid()) {
|
|
||||||
$entityManager->create($entity);
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Donnée enregistrée.');
|
|
||||||
} else {
|
|
||||||
$this->addFlash('warning', 'Le formulaire est invalide.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_tree_navigation', [
|
|
||||||
'navigation' => $navigation->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/edit/{entity}", name="admin_site_menu_edit", methods={"POST"})
|
|
||||||
*/
|
|
||||||
public function edit(Entity $entity, EntityManager $entityManager, Request $request): Response
|
|
||||||
{
|
|
||||||
$form = $this->createForm(EntityType::class, $entity);
|
|
||||||
$form->handleRequest($request);
|
|
||||||
|
|
||||||
if ($form->isValid()) {
|
|
||||||
$entityManager->update($entity);
|
|
||||||
$this->addFlash('success', 'Donnée enregistrée.');
|
|
||||||
} else {
|
|
||||||
$this->addFlash('warning', 'Le formulaire est invalide.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_tree_navigation', [
|
|
||||||
'navigation' => $entity->getNavigation()->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/delete/{entity}", name="admin_site_menu_delete", methods={"DELETE"})
|
|
||||||
*/
|
|
||||||
public function delete(Entity $entity, EntityManager $entityManager, Request $request): Response
|
|
||||||
{
|
|
||||||
if ($this->isCsrfTokenValid('delete'.$entity->getId(), $request->request->get('_token'))) {
|
|
||||||
$entityManager->delete($entity);
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Données supprimée..');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_tree_navigation', [
|
|
||||||
'navigation' => $entity->getNavigation()->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSection(): string
|
|
||||||
{
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\Site;
|
|
||||||
|
|
||||||
use App\Controller\Admin\AdminController;
|
|
||||||
use App\Entity\Site\Navigation as Entity;
|
|
||||||
use App\Factory\Site\NavigationFactory as EntityFactory;
|
|
||||||
use App\Form\Site\NavigationType as EntityType;
|
|
||||||
use App\Manager\EntityManager;
|
|
||||||
use App\Repository\Site\NavigationRepositoryQuery as RepositoryQuery;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/admin/site/navigation")
|
|
||||||
*/
|
|
||||||
class NavigationAdminController extends AdminController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @Route("/{page}", name="admin_site_navigation_index", requirements={"page": "\d+"})
|
|
||||||
*/
|
|
||||||
public function index(int $page = 1, RepositoryQuery $query, Request $request): Response
|
|
||||||
{
|
|
||||||
$pager = $query->paginate($page);
|
|
||||||
|
|
||||||
return $this->render('site/navigation_admin/index.html.twig', [
|
|
||||||
'pager' => $pager,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/new", name="admin_site_navigation_new")
|
|
||||||
*/
|
|
||||||
public function new(EntityFactory $factory, EntityManager $entityManager, Request $request): Response
|
|
||||||
{
|
|
||||||
$entity = $factory->create();
|
|
||||||
$form = $this->createForm(EntityType::class, $entity);
|
|
||||||
|
|
||||||
if ($request->isMethod('POST')) {
|
|
||||||
$form->handleRequest($request);
|
|
||||||
|
|
||||||
if ($form->isValid()) {
|
|
||||||
$entityManager->create($entity);
|
|
||||||
$this->addFlash('success', 'Donnée enregistrée.');
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_navigation_edit', [
|
|
||||||
'entity' => $entity->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
$this->addFlash('warning', 'Le formulaire est invalide.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('site/navigation_admin/new.html.twig', [
|
|
||||||
'form' => $form->createView(),
|
|
||||||
'entity' => $entity,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/edit/{entity}", name="admin_site_navigation_edit")
|
|
||||||
*/
|
|
||||||
public function edit(Entity $entity, EntityManager $entityManager, Request $request): Response
|
|
||||||
{
|
|
||||||
$form = $this->createForm(EntityType::class, $entity);
|
|
||||||
|
|
||||||
if ($request->isMethod('POST')) {
|
|
||||||
$form->handleRequest($request);
|
|
||||||
|
|
||||||
if ($form->isValid()) {
|
|
||||||
$entityManager->update($entity);
|
|
||||||
$this->addFlash('success', 'Donnée enregistrée.');
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_navigation_edit', [
|
|
||||||
'entity' => $entity->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->addFlash('warning', 'Le formulaire est invalide.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('site/navigation_admin/edit.html.twig', [
|
|
||||||
'form' => $form->createView(),
|
|
||||||
'entity' => $entity,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/show/{entity}", name="admin_site_navigation_show")
|
|
||||||
*/
|
|
||||||
public function show(Entity $entity): Response
|
|
||||||
{
|
|
||||||
return $this->render('site/navigation_admin/show.html.twig', [
|
|
||||||
'entity' => $entity,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/delete/{entity}", name="admin_site_navigation_delete", methods={"DELETE"})
|
|
||||||
*/
|
|
||||||
public function delete(Entity $entity, EntityManager $entityManager, Request $request): Response
|
|
||||||
{
|
|
||||||
if ($this->isCsrfTokenValid('delete'.$entity->getId(), $request->request->get('_token'))) {
|
|
||||||
$entityManager->delete($entity);
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Données supprimée..');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_navigation_index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSection(): string
|
|
||||||
{
|
|
||||||
return 'site_navigation';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,263 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\Site;
|
|
||||||
|
|
||||||
use App\Controller\Admin\AdminController;
|
|
||||||
use App\Entity\Site\Node;
|
|
||||||
use App\Entity\Site\Node as Entity;
|
|
||||||
use App\Entity\Site\Page\Page;
|
|
||||||
use App\Event\EntityManager\EntityManagerEvent;
|
|
||||||
use App\Factory\Site\NodeFactory as EntityFactory;
|
|
||||||
use App\Factory\Site\Page\PageFactory;
|
|
||||||
use App\Form\Site\NodeMoveType;
|
|
||||||
use App\Form\Site\NodeType as EntityType;
|
|
||||||
use App\Manager\EntityManager;
|
|
||||||
use App\Repository\Site\NodeRepository;
|
|
||||||
use App\Site\PageLocator;
|
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|
||||||
use Symfony\Component\Form\FormError;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/admin/site/node")
|
|
||||||
*/
|
|
||||||
class NodeAdminController extends AdminController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @Route("/new/{node}", name="admin_site_node_new")
|
|
||||||
*/
|
|
||||||
public function new(
|
|
||||||
Node $node,
|
|
||||||
EntityFactory $factory,
|
|
||||||
PageFactory $pageFactory,
|
|
||||||
EntityManager $entityManager,
|
|
||||||
NodeRepository $nodeRepository,
|
|
||||||
PageLocator $pageLocator,
|
|
||||||
Request $request
|
|
||||||
): Response {
|
|
||||||
$entity = $factory->create($node->getMenu());
|
|
||||||
$form = $this->createForm(EntityType::class, $entity, [
|
|
||||||
'pages' => $pageLocator->getPages(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($request->isMethod('POST')) {
|
|
||||||
$form->handleRequest($request);
|
|
||||||
|
|
||||||
if ($form->isValid()) {
|
|
||||||
$position = $form->get('position')->getData();
|
|
||||||
|
|
||||||
$parent = 'above' === $position ? $node : $node->getParent();
|
|
||||||
$entity->setParent($parent);
|
|
||||||
|
|
||||||
if ('above' === $position) {
|
|
||||||
$nodeRepository->persistAsLastChild($entity, $node);
|
|
||||||
} else {
|
|
||||||
if ('after' === $position) {
|
|
||||||
$nodeRepository->persistAsNextSiblingOf($entity, $node);
|
|
||||||
} elseif ('before' === $position) {
|
|
||||||
$nodeRepository->persistAsPrevSiblingOf($entity, $node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->handlePageAssociation(
|
|
||||||
$form->get('pageAction')->getData(),
|
|
||||||
$form->get('pageEntity')->getData(),
|
|
||||||
$form->get('pageType')->getData(),
|
|
||||||
$entity,
|
|
||||||
$pageFactory,
|
|
||||||
$pageLocator
|
|
||||||
);
|
|
||||||
|
|
||||||
$entityManager->update($entity);
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Donnée enregistrée.');
|
|
||||||
} else {
|
|
||||||
$this->addFlash('warning', 'Le formulaire est invalide.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_tree_navigation', [
|
|
||||||
'navigation' => $node->getMenu()->getNavigation()->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('site/node_admin/new.html.twig', [
|
|
||||||
'form' => $form->createView(),
|
|
||||||
'node' => $node,
|
|
||||||
'entity' => $entity,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/edit/{entity}", name="admin_site_node_edit")
|
|
||||||
*/
|
|
||||||
public function edit(
|
|
||||||
Entity $entity,
|
|
||||||
EntityManager $entityManager,
|
|
||||||
PageFactory $pageFactory,
|
|
||||||
PageLocator $pageLocator,
|
|
||||||
Request $request
|
|
||||||
): Response {
|
|
||||||
$form = $this->createForm(EntityType::class, $entity, [
|
|
||||||
'pages' => $pageLocator->getPages(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($request->isMethod('POST')) {
|
|
||||||
$form->handleRequest($request);
|
|
||||||
|
|
||||||
if ($form->isValid()) {
|
|
||||||
$this->handlePageAssociation(
|
|
||||||
$form->get('pageAction')->getData(),
|
|
||||||
$form->get('pageEntity')->getData(),
|
|
||||||
$form->get('pageType')->getData(),
|
|
||||||
$entity,
|
|
||||||
$pageFactory,
|
|
||||||
$pageLocator
|
|
||||||
);
|
|
||||||
|
|
||||||
$entityManager->update($entity);
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Donnée enregistrée.');
|
|
||||||
} else {
|
|
||||||
$this->addFlash('warning', 'Le formulaire est invalide.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_tree_navigation', [
|
|
||||||
'navigation' => $entity->getMenu()->getNavigation()->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('site/node_admin/edit.html.twig', [
|
|
||||||
'form' => $form->createView(),
|
|
||||||
'entity' => $entity,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/move/{entity}", name="admin_site_node_move")
|
|
||||||
*/
|
|
||||||
public function move(
|
|
||||||
Entity $entity,
|
|
||||||
EntityManager $entityManager,
|
|
||||||
NodeRepository $nodeRepository,
|
|
||||||
Request $request
|
|
||||||
): Response {
|
|
||||||
$form = $this->createForm(NodeMoveType::class, null, [
|
|
||||||
'menu' => $entity->getMenu(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($request->isMethod('POST')) {
|
|
||||||
$form->handleRequest($request);
|
|
||||||
|
|
||||||
if ($form->get('node')->getData()->getId() === $entity->getId()) {
|
|
||||||
$form->get('node')->addError(new FormError('Élement de référence invalide.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($form->isValid()) {
|
|
||||||
$position = $form->get('position')->getData();
|
|
||||||
$node = $form->get('node')->getData();
|
|
||||||
|
|
||||||
$parent = 'above' === $position ? $node : $node->getParent();
|
|
||||||
$entity->setParent($parent);
|
|
||||||
|
|
||||||
if ('above' === $position) {
|
|
||||||
$nodeRepository->persistAsLastChild($entity, $node);
|
|
||||||
$entityManager->flush();
|
|
||||||
} else {
|
|
||||||
if ('after' === $position) {
|
|
||||||
$nodeRepository->persistAsNextSiblingOf($entity, $node);
|
|
||||||
} elseif ('before' === $position) {
|
|
||||||
$nodeRepository->persistAsPrevSiblingOf($entity, $node);
|
|
||||||
}
|
|
||||||
|
|
||||||
$entityManager->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Donnée enregistrée.');
|
|
||||||
} else {
|
|
||||||
$this->addFlash('warning', 'Le formulaire est invalide.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_tree_navigation', [
|
|
||||||
'navigation' => $entity->getMenu()->getNavigation()->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('site/node_admin/move.html.twig', [
|
|
||||||
'form' => $form->createView(),
|
|
||||||
'entity' => $entity,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/toggle/visibility/{entity}", name="admin_site_node_toggle_visibility", methods={"POST"})
|
|
||||||
*/
|
|
||||||
public function toggleVisibility(Entity $entity, EntityManager $entityManager, Request $request): Response
|
|
||||||
{
|
|
||||||
if ($this->isCsrfTokenValid('toggle_visibility'.$entity->getId(), $request->request->get('_token'))) {
|
|
||||||
$entity->setIsVisible(!$entity->getIsVisible());
|
|
||||||
|
|
||||||
$entityManager->update($entity);
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Donnée enregistrée.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_tree_navigation', [
|
|
||||||
'navigation' => $entity->getMenu()->getNavigation()->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/delete/{entity}", name="admin_site_node_delete", methods={"DELETE"})
|
|
||||||
*/
|
|
||||||
public function delete(
|
|
||||||
Entity $entity,
|
|
||||||
NodeRepository $nodeRepository,
|
|
||||||
EventDispatcherInterface $eventDispatcher,
|
|
||||||
Request $request
|
|
||||||
): Response {
|
|
||||||
if ($this->isCsrfTokenValid('delete'.$entity->getId(), $request->request->get('_token'))) {
|
|
||||||
$eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::PRE_DELETE_EVENT);
|
|
||||||
$nodeRepository->removeFromTree($entity);
|
|
||||||
$nodeRepository->reorder($entity->getMenu()->getRootNode());
|
|
||||||
$eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::DELETE_EVENT);
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Donnée supprimée.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_tree_navigation', [
|
|
||||||
'navigation' => $entity->getMenu()->getNavigation()->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSection(): string
|
|
||||||
{
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function handlePageAssociation(
|
|
||||||
string $pageAction,
|
|
||||||
?Page $pageEntity,
|
|
||||||
string $pageType,
|
|
||||||
Entity $entity,
|
|
||||||
PageFactory $pageFactory,
|
|
||||||
PageLocator $pageLocator
|
|
||||||
) {
|
|
||||||
if ('new' === $pageAction) {
|
|
||||||
$pageConfiguration = $pageLocator->getPage($pageType);
|
|
||||||
$page = $pageFactory->create($pageType, $entity->getLabel());
|
|
||||||
$page->setTemplate($pageConfiguration->getTemplates()[0]['file']);
|
|
||||||
|
|
||||||
$entity->setPage($page);
|
|
||||||
} elseif ('existing' === $pageAction) {
|
|
||||||
if ($pageEntity) {
|
|
||||||
$entity->setPage($pageEntity);
|
|
||||||
} else {
|
|
||||||
$this->addFlash('info', 'Aucun changement de page effectué.');
|
|
||||||
}
|
|
||||||
} elseif ('none' === $pageAction) {
|
|
||||||
$entity->setPage(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\Site;
|
|
||||||
|
|
||||||
use App\Controller\Admin\AdminController;
|
|
||||||
use App\Entity\Site\Page\Page as Entity;
|
|
||||||
use App\Factory\Site\Page\PageFactory as EntityFactory;
|
|
||||||
use App\Form\Site\Page\PageType as EntityType;
|
|
||||||
use App\Manager\EntityManager;
|
|
||||||
use App\Page\FooPage;
|
|
||||||
use App\Page\SimplePage;
|
|
||||||
use App\Repository\Site\Page\PageRepositoryQuery as RepositoryQuery;
|
|
||||||
use App\Site\PageLocator;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/admin/site/page")
|
|
||||||
*/
|
|
||||||
class PageAdminController extends AdminController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @Route("/{page}", name="admin_site_page_index", requirements={"page": "\d+"})
|
|
||||||
*/
|
|
||||||
public function index(int $page = 1, RepositoryQuery $query, Request $request): Response
|
|
||||||
{
|
|
||||||
$pager = $query->paginate($page);
|
|
||||||
|
|
||||||
return $this->render('site/page_admin/index.html.twig', [
|
|
||||||
'pager' => $pager,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/new", name="admin_site_page_new")
|
|
||||||
*/
|
|
||||||
public function new(EntityFactory $factory, EntityManager $entityManager): Response
|
|
||||||
{
|
|
||||||
// $entity = $factory->create(FooPage::class);
|
|
||||||
$entity = $factory->create(SimplePage::class);
|
|
||||||
$entity->setName('Page de test '.mt_rand());
|
|
||||||
|
|
||||||
$entityManager->create($entity);
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Donnée enregistrée.');
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_page_edit', [
|
|
||||||
'entity' => $entity->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/edit/{entity}", name="admin_site_page_edit")
|
|
||||||
*/
|
|
||||||
public function edit(
|
|
||||||
int $entity,
|
|
||||||
EntityFactory $factory,
|
|
||||||
EntityManager $entityManager,
|
|
||||||
RepositoryQuery $repositoryQuery,
|
|
||||||
PageLocator $pageLocator,
|
|
||||||
Request $request
|
|
||||||
): Response {
|
|
||||||
$entity = $repositoryQuery->filterById($entity)->findOne();
|
|
||||||
$form = $this->createForm(EntityType::class, $entity, [
|
|
||||||
'pageConfiguration' => $pageLocator->getPage(get_class($entity)),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($request->isMethod('POST')) {
|
|
||||||
$form->handleRequest($request);
|
|
||||||
|
|
||||||
if ($form->isValid()) {
|
|
||||||
$entityManager->update($entity);
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Donnée enregistrée.');
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_page_edit', [
|
|
||||||
'entity' => $entity->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->addFlash('warning', 'Le formulaire est invalide.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('site/page_admin/edit.html.twig', [
|
|
||||||
'form' => $form->createView(),
|
|
||||||
'entity' => $entity,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/delete/{entity}", name="admin_site_page_delete", methods={"DELETE"})
|
|
||||||
*/
|
|
||||||
public function delete(Entity $entity, EntityManager $entityManager, Request $request): Response
|
|
||||||
{
|
|
||||||
if ($this->isCsrfTokenValid('delete'.$entity->getId(), $request->request->get('_token'))) {
|
|
||||||
$entityManager->delete($entity);
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Données supprimée..');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_page_index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSection(): string
|
|
||||||
{
|
|
||||||
return 'site_page';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\Site;
|
|
||||||
|
|
||||||
use App\Site\SiteRequest;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
|
|
||||||
class PageController extends AbstractController
|
|
||||||
{
|
|
||||||
public function show(Request $request, SiteRequest $siteRequest): Response
|
|
||||||
{
|
|
||||||
if (!$siteRequest->getPage()) {
|
|
||||||
throw $this->createNotFoundException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render($siteRequest->getPage()->getTemplate(), [
|
|
||||||
'_node' => $siteRequest->getNode(),
|
|
||||||
'_page' => $siteRequest->getPage(),
|
|
||||||
'_menu' => $siteRequest->getMenu(),
|
|
||||||
'_navigation' => $siteRequest->getNavigation(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\Site;
|
|
||||||
|
|
||||||
use App\Controller\Admin\AdminController;
|
|
||||||
use App\Entity\Site\Navigation;
|
|
||||||
use App\Factory\Site\MenuFactory;
|
|
||||||
use App\Form\Site\MenuType;
|
|
||||||
use App\Repository\Site\NavigationRepositoryQuery;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/admin/site/tree")
|
|
||||||
*/
|
|
||||||
class TreeAdminController extends AdminController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @Route("/", name="admin_site_tree_index")
|
|
||||||
*/
|
|
||||||
public function index(NavigationRepositoryQuery $navigationQuery): Response
|
|
||||||
{
|
|
||||||
$navigation = $navigationQuery->create()->findOne();
|
|
||||||
|
|
||||||
if (null === $navigation) {
|
|
||||||
$this->addFlash('warning', 'Vous devez ajouter une navigation.');
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_navigation_new');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_site_tree_navigation', [
|
|
||||||
'navigation' => $navigation->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/navigation/{navigation}", name="admin_site_tree_navigation")
|
|
||||||
*/
|
|
||||||
public function navigation(
|
|
||||||
Navigation $navigation,
|
|
||||||
NavigationRepositoryQuery $navigationQuery,
|
|
||||||
MenuFactory $menuFactory
|
|
||||||
): Response {
|
|
||||||
$navigations = $navigationQuery->create()->find();
|
|
||||||
|
|
||||||
$forms = [
|
|
||||||
'menu' => $this->createForm(MenuType::class, $menuFactory->create())->createView(),
|
|
||||||
'menus' => [],
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($navigation->getMenus() as $menu) {
|
|
||||||
$forms['menus'][$menu->getId()] = $this->createForm(MenuType::class, $menu)->createView();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('site/tree_admin/navigation.html.twig', [
|
|
||||||
'navigation' => $navigation,
|
|
||||||
'navigations' => $navigations,
|
|
||||||
'forms' => $forms,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSection(): string
|
|
||||||
{
|
|
||||||
return 'site_tree';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,157 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller\User;
|
|
||||||
|
|
||||||
use App\Controller\Admin\AdminController;
|
|
||||||
use App\Entity\User as Entity;
|
|
||||||
use App\Event\Account\PasswordRequestEvent;
|
|
||||||
use App\Factory\UserFactory as EntityFactory;
|
|
||||||
use App\Form\UserType as EntityType;
|
|
||||||
use App\Manager\EntityManager;
|
|
||||||
use App\Repository\Blog\PostRepositoryQuery;
|
|
||||||
use App\Repository\UserRepositoryQuery as RepositoryQuery;
|
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
|
|
||||||
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/admin/user")
|
|
||||||
*/
|
|
||||||
class UserAdminController extends AdminController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @Route("/{page}", name="admin_user_index", requirements={"page": "\d+"})
|
|
||||||
*/
|
|
||||||
public function index(int $page = 1, RepositoryQuery $query, Request $request): Response
|
|
||||||
{
|
|
||||||
$pager = $query->paginate($page);
|
|
||||||
|
|
||||||
return $this->render('user/user_admin/index.html.twig', [
|
|
||||||
'pager' => $pager,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/new", name="admin_user_new")
|
|
||||||
*/
|
|
||||||
public function new(
|
|
||||||
EntityFactory $factory,
|
|
||||||
EntityManager $entityManager,
|
|
||||||
UserPasswordEncoderInterface $encoder,
|
|
||||||
Request $request
|
|
||||||
): Response {
|
|
||||||
$entity = $factory->create($this->getUser());
|
|
||||||
$form = $this->createForm(EntityType::class, $entity);
|
|
||||||
|
|
||||||
if ($request->isMethod('POST')) {
|
|
||||||
$form->handleRequest($request);
|
|
||||||
|
|
||||||
if ($form->isValid()) {
|
|
||||||
$entityManager->create($entity);
|
|
||||||
$this->addFlash('success', 'Donnée enregistrée.');
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_user_edit', [
|
|
||||||
'entity' => $entity->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
$this->addFlash('warning', 'Le formulaire est invalide.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('user/user_admin/new.html.twig', [
|
|
||||||
'form' => $form->createView(),
|
|
||||||
'entity' => $entity,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/edit/{entity}", name="admin_user_edit")
|
|
||||||
*/
|
|
||||||
public function edit(Entity $entity, EntityManager $entityManager, Request $request): Response
|
|
||||||
{
|
|
||||||
$form = $this->createForm(EntityType::class, $entity);
|
|
||||||
|
|
||||||
if ($request->isMethod('POST')) {
|
|
||||||
$form->handleRequest($request);
|
|
||||||
|
|
||||||
if ($form->isValid()) {
|
|
||||||
$entityManager->update($entity);
|
|
||||||
$this->addFlash('success', 'Donnée enregistrée.');
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_user_edit', [
|
|
||||||
'entity' => $entity->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
$this->addFlash('warning', 'Le formulaire est invalide.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render('user/user_admin/edit.html.twig', [
|
|
||||||
'form' => $form->createView(),
|
|
||||||
'entity' => $entity,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/show/{entity}", name="admin_user_show")
|
|
||||||
*/
|
|
||||||
public function show(Entity $entity, PostRepositoryQuery $postQuery): Response
|
|
||||||
{
|
|
||||||
$posts = $postQuery->create()
|
|
||||||
->orderBy('.publishedAt', 'DESC')
|
|
||||||
->orderBy('.createdAt', 'DESC')
|
|
||||||
->filterByAuthor($entity)
|
|
||||||
->paginate(1, 10)
|
|
||||||
;
|
|
||||||
|
|
||||||
return $this->render('user/user_admin/show.html.twig', [
|
|
||||||
'entity' => $entity,
|
|
||||||
'posts' => $posts,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/resetting_request/{entity}", name="admin_user_resetting_request", methods={"POST"})
|
|
||||||
*/
|
|
||||||
public function requestResetting(
|
|
||||||
Entity $entity,
|
|
||||||
EntityManager $entityManager,
|
|
||||||
TokenGeneratorInterface $tokenGenerator,
|
|
||||||
EventDispatcherInterface $eventDispatcher,
|
|
||||||
Request $request
|
|
||||||
): Response {
|
|
||||||
if ($this->isCsrfTokenValid('resetting_request'.$entity->getId(), $request->request->get('_token'))) {
|
|
||||||
$entity->setConfirmationToken($tokenGenerator->generateToken());
|
|
||||||
$entity->setPasswordRequestedAt(new \DateTime('now'));
|
|
||||||
|
|
||||||
$entityManager->update($entity);
|
|
||||||
$eventDispatcher->dispatch(new PasswordRequestEvent($entity), PasswordRequestEvent::EVENT);
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Demande envoyée.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_user_edit', [
|
|
||||||
'entity' => $entity->getId(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/delete/{entity}", name="admin_user_delete", methods={"DELETE"})
|
|
||||||
*/
|
|
||||||
public function delete(Entity $entity, EntityManager $entityManager, Request $request): Response
|
|
||||||
{
|
|
||||||
if ($this->isCsrfTokenValid('delete'.$entity->getId(), $request->request->get('_token'))) {
|
|
||||||
$entityManager->delete($entity);
|
|
||||||
|
|
||||||
$this->addFlash('success', 'Données supprimée..');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->redirectToRoute('admin_user_index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSection(): string
|
|
||||||
{
|
|
||||||
return 'user';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\DependencyInjection;
|
|
||||||
|
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|
||||||
use Symfony\Component\DependencyInjection\Extension\Extension;
|
|
||||||
|
|
||||||
class AppExtension extends Extension
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function load(array $configs, ContainerBuilder $container)
|
|
||||||
{
|
|
||||||
$configuration = $this->getConfiguration($configs, $container);
|
|
||||||
$config = $this->processConfiguration($configuration, $configs);
|
|
||||||
|
|
||||||
$container->setParameter('app', $config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getConfiguration(array $configs, ContainerBuilder $container)
|
|
||||||
{
|
|
||||||
return new Configuration();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\DependencyInjection;
|
|
||||||
|
|
||||||
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
|
|
||||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
|
||||||
|
|
||||||
class Configuration implements ConfigurationInterface
|
|
||||||
{
|
|
||||||
public function getConfigTreeBuilder(): TreeBuilder
|
|
||||||
{
|
|
||||||
$treeBuilder = new TreeBuilder('app');
|
|
||||||
|
|
||||||
$treeBuilder->getRootNode()
|
|
||||||
->children()
|
|
||||||
->arrayNode('site')
|
|
||||||
->children()
|
|
||||||
->arrayNode('pages')
|
|
||||||
->prototype('array')
|
|
||||||
->children()
|
|
||||||
->scalarNode('name')
|
|
||||||
->isRequired()
|
|
||||||
->cannotBeEmpty()
|
|
||||||
->end()
|
|
||||||
->arrayNode('templates')
|
|
||||||
->prototype('array')
|
|
||||||
->children()
|
|
||||||
->scalarNode('name')
|
|
||||||
->cannotBeEmpty()
|
|
||||||
->end()
|
|
||||||
->scalarNode('file')
|
|
||||||
->cannotBeEmpty()
|
|
||||||
->end()
|
|
||||||
->end()
|
|
||||||
->end()
|
|
||||||
->end()
|
|
||||||
->end()
|
|
||||||
->end()
|
|
||||||
->end()
|
|
||||||
->end();
|
|
||||||
|
|
||||||
return $treeBuilder;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
namespace App\Entity\Blog;
|
namespace App\Entity\Blog;
|
||||||
|
|
||||||
use App\Doctrine\Timestampable;
|
use App\Core\Doctrine\Timestampable;
|
||||||
use App\Entity\EntityInterface;
|
|
||||||
use App\Repository\Blog\CategoryRepository;
|
use App\Repository\Blog\CategoryRepository;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use App\Core\Entity\EntityInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Entity(repositoryClass=CategoryRepository::class)
|
* @ORM\Entity(repositoryClass=CategoryRepository::class)
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
namespace App\Entity\Blog;
|
namespace App\Entity\Blog;
|
||||||
|
|
||||||
use App\Doctrine\Timestampable;
|
use App\Core\Doctrine\Timestampable;
|
||||||
use App\Entity\EntityInterface;
|
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Repository\Blog\PostRepository;
|
use App\Repository\Blog\PostRepository;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use App\Core\Entity\EntityInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Entity(repositoryClass=PostRepository::class)
|
* @ORM\Entity(repositoryClass=PostRepository::class)
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Entity;
|
|
||||||
|
|
||||||
interface EntityInterface
|
|
||||||
{
|
|
||||||
}
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Site\Page;
|
namespace App\Entity\Page;
|
||||||
|
|
||||||
use App\Entity\Site\Page\Block;
|
use App\Core\Entity\Site\Page\Block;
|
||||||
use App\Entity\Site\Page\Page;
|
use App\Core\Entity\Site\Page\Page;
|
||||||
use App\Form\Site\Page\TextareaBlockType;
|
use App\Form\Site\Page\TextareaBlockType;
|
||||||
use App\Form\Site\Page\TextBlockType;
|
use App\Form\Site\Page\TextBlockType;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
|
@ -1,146 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Entity\Site;
|
|
||||||
|
|
||||||
use App\Doctrine\Timestampable;
|
|
||||||
use App\Entity\EntityInterface;
|
|
||||||
use App\Repository\Site\MenuRepository;
|
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
|
||||||
use Doctrine\Common\Collections\Collection;
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Entity(repositoryClass=MenuRepository::class)
|
|
||||||
* @ORM\HasLifecycleCallbacks
|
|
||||||
*/
|
|
||||||
class Menu implements EntityInterface
|
|
||||||
{
|
|
||||||
use Timestampable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Id
|
|
||||||
* @ORM\GeneratedValue
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
*/
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255)
|
|
||||||
*/
|
|
||||||
private $label;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255)
|
|
||||||
*/
|
|
||||||
private $code;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\ManyToOne(targetEntity=Navigation::class, inversedBy="menus")
|
|
||||||
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
|
|
||||||
*/
|
|
||||||
private $navigation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\OneToMany(targetEntity=Node::class, mappedBy="menu", orphanRemoval=true, cascade={"remove", "persist"})
|
|
||||||
*/
|
|
||||||
private $nodes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\OneToOne(targetEntity=Node::class, cascade={"persist"})
|
|
||||||
* @ORM\JoinColumn(onDelete="CASCADE")
|
|
||||||
*/
|
|
||||||
private $rootNode;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->nodes = new ArrayCollection();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getId(): ?int
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLabel(): ?string
|
|
||||||
{
|
|
||||||
return $this->label;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setLabel(string $label): self
|
|
||||||
{
|
|
||||||
$this->label = $label;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCode(): ?string
|
|
||||||
{
|
|
||||||
return $this->code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCode(string $code): self
|
|
||||||
{
|
|
||||||
$this->code = $code;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getNavigation(): ?Navigation
|
|
||||||
{
|
|
||||||
return $this->navigation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setNavigation(?Navigation $navigation): self
|
|
||||||
{
|
|
||||||
$this->navigation = $navigation;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection|Node[]
|
|
||||||
*/
|
|
||||||
public function getNodes(): Collection
|
|
||||||
{
|
|
||||||
return $this->nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addNode(Node $node): self
|
|
||||||
{
|
|
||||||
if (!$this->nodes->contains($node)) {
|
|
||||||
$this->nodes[] = $node;
|
|
||||||
$node->setMenu($this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeNode(Node $node): self
|
|
||||||
{
|
|
||||||
if ($this->nodes->removeElement($node)) {
|
|
||||||
// set the owning side to null (unless already changed)
|
|
||||||
if ($node->getMenu() === $this) {
|
|
||||||
$node->setMenu(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRootNode(): ?Node
|
|
||||||
{
|
|
||||||
return $this->rootNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setRootNode(?Node $rootNode): self
|
|
||||||
{
|
|
||||||
$this->rootNode = $rootNode;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRouteName(): string
|
|
||||||
{
|
|
||||||
return $this->getNavigation()->getRouteName().'_'.($this->getCode() ? $this->getCode() : $this->getId());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,127 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Entity\Site;
|
|
||||||
|
|
||||||
use App\Doctrine\Timestampable;
|
|
||||||
use App\Entity\EntityInterface;
|
|
||||||
use App\Repository\Site\NavigationRepository;
|
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
|
||||||
use Doctrine\Common\Collections\Collection;
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Entity(repositoryClass=NavigationRepository::class)
|
|
||||||
* @ORM\HasLifecycleCallbacks
|
|
||||||
*/
|
|
||||||
class Navigation implements EntityInterface
|
|
||||||
{
|
|
||||||
use Timestampable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Id
|
|
||||||
* @ORM\GeneratedValue
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
*/
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255)
|
|
||||||
*/
|
|
||||||
private $label;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255)
|
|
||||||
*/
|
|
||||||
private $code;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255)
|
|
||||||
*/
|
|
||||||
private $domain;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\OneToMany(targetEntity=Menu::class, mappedBy="navigation")
|
|
||||||
*/
|
|
||||||
private $menus;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->menus = new ArrayCollection();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getId(): ?int
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLabel(): ?string
|
|
||||||
{
|
|
||||||
return $this->label;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setLabel(string $label): self
|
|
||||||
{
|
|
||||||
$this->label = $label;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCode(): ?string
|
|
||||||
{
|
|
||||||
return $this->code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCode(string $code): self
|
|
||||||
{
|
|
||||||
$this->code = $code;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDomain(): ?string
|
|
||||||
{
|
|
||||||
return $this->domain;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setDomain(string $domain): self
|
|
||||||
{
|
|
||||||
$this->domain = $domain;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection|Menu[]
|
|
||||||
*/
|
|
||||||
public function getMenus(): Collection
|
|
||||||
{
|
|
||||||
return $this->menus;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addMenu(Menu $menu): self
|
|
||||||
{
|
|
||||||
if (!$this->menus->contains($menu)) {
|
|
||||||
$this->menus[] = $menu;
|
|
||||||
$menu->setNavigation($this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeMenu(Menu $menu): self
|
|
||||||
{
|
|
||||||
if ($this->menus->removeElement($menu)) {
|
|
||||||
// set the owning side to null (unless already changed)
|
|
||||||
if ($menu->getNavigation() === $this) {
|
|
||||||
$menu->setNavigation(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRouteName(): string
|
|
||||||
{
|
|
||||||
return $this->getCode() ? $this->getCode() : 'navigation_'.$this->getId();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,304 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Entity\Site;
|
|
||||||
|
|
||||||
use App\Doctrine\Timestampable;
|
|
||||||
use App\Entity\EntityInterface;
|
|
||||||
use App\Entity\Site\Page\Page;
|
|
||||||
use App\Repository\Site\NodeRepository;
|
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
|
||||||
use Doctrine\Common\Collections\Collection;
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
|
||||||
use Gedmo\Mapping\Annotation as Gedmo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Gedmo\Tree(type="nested")
|
|
||||||
* @ORM\HasLifecycleCallbacks
|
|
||||||
* @ORM\Entity(repositoryClass=NodeRepository::class)
|
|
||||||
*/
|
|
||||||
class Node implements EntityInterface
|
|
||||||
{
|
|
||||||
use Timestampable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Id
|
|
||||||
* @ORM\GeneratedValue
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
*/
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\ManyToOne(targetEntity=Menu::class, inversedBy="nodes", cascade={"persist", "remove"})
|
|
||||||
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
|
|
||||||
*/
|
|
||||||
private $menu;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $label;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $url;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="boolean", options={"default"=0})
|
|
||||||
*/
|
|
||||||
private $isVisible = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Gedmo\TreeLeft
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
*/
|
|
||||||
private $treeLeft;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Gedmo\TreeLevel
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
*/
|
|
||||||
private $treeLevel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Gedmo\TreeRight
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
*/
|
|
||||||
private $treeRight;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Gedmo\TreeRoot
|
|
||||||
* @ORM\ManyToOne(targetEntity="Node")
|
|
||||||
* @ORM\JoinColumn(referencedColumnName="id", onDelete="CASCADE")
|
|
||||||
*/
|
|
||||||
private $treeRoot;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Gedmo\TreeParent
|
|
||||||
* @ORM\ManyToOne(targetEntity="Node", inversedBy="children")
|
|
||||||
* @ORM\JoinColumn(referencedColumnName="id", onDelete="CASCADE")
|
|
||||||
*/
|
|
||||||
private $parent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\OneToMany(targetEntity="Node", mappedBy="parent")
|
|
||||||
* @ORM\OrderBy({"treeLeft"="ASC"})
|
|
||||||
*/
|
|
||||||
private $children;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\ManyToOne(targetEntity=Page::class, inversedBy="nodes", cascade={"persist"})
|
|
||||||
* @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
|
|
||||||
*/
|
|
||||||
private $page;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $code;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->children = new ArrayCollection();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getId(): ?int
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMenu(): ?Menu
|
|
||||||
{
|
|
||||||
return $this->menu;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setMenu(?Menu $menu): self
|
|
||||||
{
|
|
||||||
$this->menu = $menu;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTreeLeft(): ?int
|
|
||||||
{
|
|
||||||
return $this->treeLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTreeLeft(int $treeLeft): self
|
|
||||||
{
|
|
||||||
$this->treeLeft = $treeLeft;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTreeLevel(): ?int
|
|
||||||
{
|
|
||||||
return $this->treeLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTreeLevel(int $treeLevel): self
|
|
||||||
{
|
|
||||||
$this->treeLevel = $treeLevel;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTreeRight(): ?int
|
|
||||||
{
|
|
||||||
return $this->treeRight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTreeRight(int $treeRight): self
|
|
||||||
{
|
|
||||||
$this->treeRight = $treeRight;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTreeRoot(): ?self
|
|
||||||
{
|
|
||||||
return $this->treeRoot;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTreeRoot(?self $treeRoot): self
|
|
||||||
{
|
|
||||||
$this->treeRoot = $treeRoot;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getParent(): ?self
|
|
||||||
{
|
|
||||||
return $this->parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setParent(?self $parent): self
|
|
||||||
{
|
|
||||||
$this->parent = $parent;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection|Node[]
|
|
||||||
*/
|
|
||||||
public function getChildren(): Collection
|
|
||||||
{
|
|
||||||
return $this->children;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addChild(Node $child): self
|
|
||||||
{
|
|
||||||
if (!$this->children->contains($child)) {
|
|
||||||
$this->children[] = $child;
|
|
||||||
$child->setParent($this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeChild(Node $child): self
|
|
||||||
{
|
|
||||||
if ($this->children->removeElement($child)) {
|
|
||||||
// set the owning side to null (unless already changed)
|
|
||||||
if ($child->getParent() === $this) {
|
|
||||||
$child->setParent(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllChildren(): ArrayCollection
|
|
||||||
{
|
|
||||||
$children = [];
|
|
||||||
|
|
||||||
$getChildren = function (Node $node) use (&$children, &$getChildren) {
|
|
||||||
foreach ($node->getChildren() as $nodeChildren) {
|
|
||||||
$children[] = $nodeChildren;
|
|
||||||
|
|
||||||
$getChildren($nodeChildren);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$getChildren($this);
|
|
||||||
|
|
||||||
usort($children, function ($a, $b) {
|
|
||||||
return $a->getTreeLeft() < $b->getTreeLeft() ? -1 : 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
return new ArrayCollection($children);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLabel(): ?string
|
|
||||||
{
|
|
||||||
return $this->label;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setLabel(?string $label): self
|
|
||||||
{
|
|
||||||
$this->label = $label;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUrl(): ?string
|
|
||||||
{
|
|
||||||
return $this->url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setUrl(?string $url): self
|
|
||||||
{
|
|
||||||
$this->url = $url;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getIsVisible(): ?bool
|
|
||||||
{
|
|
||||||
return $this->isVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setIsVisible(bool $isVisible): self
|
|
||||||
{
|
|
||||||
$this->isVisible = $isVisible;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTreeLabel()
|
|
||||||
{
|
|
||||||
$prefix = str_repeat('-', ($this->getTreeLevel() - 1) * 5);
|
|
||||||
|
|
||||||
return trim($prefix.' '.$this->getLabel());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPage(): ?Page
|
|
||||||
{
|
|
||||||
return $this->page;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setPage(?Page $page): self
|
|
||||||
{
|
|
||||||
$this->page = $page;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRouteName(): string
|
|
||||||
{
|
|
||||||
return $this->getMenu()->getRouteName().'_'.($this->getCode() ? $this->getCode() : $this->getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCode(): ?string
|
|
||||||
{
|
|
||||||
return $this->code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCode(?string $code): self
|
|
||||||
{
|
|
||||||
$this->code = $code;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Entity\Site\Page;
|
|
||||||
|
|
||||||
use App\Doctrine\Timestampable;
|
|
||||||
use App\Repository\Site\Page\BlockRepository;
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Entity(repositoryClass=BlockRepository::class)
|
|
||||||
* @ORM\HasLifecycleCallbacks
|
|
||||||
*/
|
|
||||||
class Block
|
|
||||||
{
|
|
||||||
use Timestampable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Id
|
|
||||||
* @ORM\GeneratedValue
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
*/
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255)
|
|
||||||
*/
|
|
||||||
private $name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="text", nullable=true)
|
|
||||||
*/
|
|
||||||
private $value;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\ManyToOne(targetEntity=Page::class, inversedBy="blocks")
|
|
||||||
* @ORM\JoinColumn(onDelete="CASCADE")
|
|
||||||
*/
|
|
||||||
private $page;
|
|
||||||
|
|
||||||
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 getValue(): ?string
|
|
||||||
{
|
|
||||||
return $this->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setValue(string $value): self
|
|
||||||
{
|
|
||||||
$this->value = $value;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPage(): ?Page
|
|
||||||
{
|
|
||||||
return $this->page;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setPage(?Page $page): self
|
|
||||||
{
|
|
||||||
$this->page = $page;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,248 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Entity\Site\Page;
|
|
||||||
|
|
||||||
use App\Doctrine\Timestampable;
|
|
||||||
use App\Entity\EntityInterface;
|
|
||||||
use App\Entity\Site\Node;
|
|
||||||
use App\Repository\Site\Page\PageRepository;
|
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
|
||||||
use Doctrine\Common\Collections\Collection;
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Entity(repositoryClass=PageRepository::class)
|
|
||||||
* @ORM\DiscriminatorColumn(name="class_key", type="string")
|
|
||||||
* @ORM\InheritanceType("SINGLE_TABLE")
|
|
||||||
* @ORM\HasLifecycleCallbacks
|
|
||||||
*/
|
|
||||||
class Page implements EntityInterface
|
|
||||||
{
|
|
||||||
use Timestampable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Id
|
|
||||||
* @ORM\GeneratedValue
|
|
||||||
* @ORM\Column(type="integer")
|
|
||||||
*/
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255)
|
|
||||||
*/
|
|
||||||
private $name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $template;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\OneToMany(targetEntity=Block::class, mappedBy="page", cascade={"persist"})
|
|
||||||
*/
|
|
||||||
private $blocks;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $metaTitle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $metaDescrition;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $ogTitle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
|
||||||
*/
|
|
||||||
private $ogDescription;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\OneToMany(targetEntity=Node::class, mappedBy="page")
|
|
||||||
*/
|
|
||||||
private $nodes;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->blocks = new ArrayCollection();
|
|
||||||
$this->nodes = new ArrayCollection();
|
|
||||||
}
|
|
||||||
|
|
||||||
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 getTemplate(): ?string
|
|
||||||
{
|
|
||||||
return $this->template;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTemplate(?string $template): self
|
|
||||||
{
|
|
||||||
$this->template = $template;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection|Block[]
|
|
||||||
*/
|
|
||||||
public function getBlocks(): Collection
|
|
||||||
{
|
|
||||||
return $this->blocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addBlock(Block $block): self
|
|
||||||
{
|
|
||||||
if (!$this->blocks->contains($block)) {
|
|
||||||
$this->blocks[] = $block;
|
|
||||||
$block->setPage($this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeBlock(Block $block): self
|
|
||||||
{
|
|
||||||
if ($this->blocks->removeElement($block)) {
|
|
||||||
// set the owning side to null (unless already changed)
|
|
||||||
if ($block->getPage() === $this) {
|
|
||||||
$block->setPage(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBlock($name)
|
|
||||||
{
|
|
||||||
foreach ($this->getBlocks() as $block) {
|
|
||||||
if ($block->getName() === $name) {
|
|
||||||
return $block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$block = new Block();
|
|
||||||
$block->setName($name);
|
|
||||||
$block->setPage($this);
|
|
||||||
|
|
||||||
return $block;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setBlock(Block $block): self
|
|
||||||
{
|
|
||||||
foreach ($this->blocks->toArray() as $key => $value) {
|
|
||||||
if ($value->getName() === $block->getName()) {
|
|
||||||
$this->blocks->remove($key);
|
|
||||||
$this->blocks->add($block);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->blocks->add($block);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMetaTitle(): ?string
|
|
||||||
{
|
|
||||||
return $this->metaTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setMetaTitle(?string $metaTitle): self
|
|
||||||
{
|
|
||||||
$this->metaTitle = $metaTitle;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMetaDescrition(): ?string
|
|
||||||
{
|
|
||||||
return $this->metaDescrition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setMetaDescrition(?string $metaDescrition): self
|
|
||||||
{
|
|
||||||
$this->metaDescrition = $metaDescrition;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getOgTitle(): ?string
|
|
||||||
{
|
|
||||||
return $this->ogTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setOgTitle(?string $ogTitle): self
|
|
||||||
{
|
|
||||||
$this->ogTitle = $ogTitle;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getOgDescription(): ?string
|
|
||||||
{
|
|
||||||
return $this->ogDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setOgDescription(?string $ogDescription): self
|
|
||||||
{
|
|
||||||
$this->ogDescription = $ogDescription;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection|Node[]
|
|
||||||
*/
|
|
||||||
public function getNodes(): Collection
|
|
||||||
{
|
|
||||||
return $this->nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addNode(Node $node): self
|
|
||||||
{
|
|
||||||
if (!$this->nodes->contains($node)) {
|
|
||||||
$this->nodes[] = $node;
|
|
||||||
$node->setPage($this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeNode(Node $node): self
|
|
||||||
{
|
|
||||||
if ($this->nodes->removeElement($node)) {
|
|
||||||
// set the owning side to null (unless already changed)
|
|
||||||
if ($node->getPage() === $this) {
|
|
||||||
$node->setPage(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,18 +2,19 @@
|
||||||
|
|
||||||
namespace App\Entity;
|
namespace App\Entity;
|
||||||
|
|
||||||
use App\Doctrine\Timestampable;
|
use App\Core\Doctrine\Timestampable;
|
||||||
use App\Entity\Blog\Post;
|
|
||||||
use App\Repository\UserRepository;
|
use App\Repository\UserRepository;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Scheb\TwoFactorBundle\Model\Google\TwoFactorInterface;
|
use Scheb\TwoFactorBundle\Model\Google\TwoFactorInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
|
use App\Core\Entity\EntityInterface;
|
||||||
|
use App\Entity\Blog\Post;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Entity(repositoryClass=UserRepository::class)
|
* @ORM\Entity(repositoryClass=UserRepository::class)
|
||||||
* @ORM\HasLifecycleCallbacks
|
* @ORM\HasLifecycleCallbacks()
|
||||||
*/
|
*/
|
||||||
class User implements UserInterface, TwoFactorInterface, EntityInterface
|
class User implements UserInterface, TwoFactorInterface, EntityInterface
|
||||||
{
|
{
|
||||||
|
@ -66,21 +67,51 @@ class User implements UserInterface, TwoFactorInterface, EntityInterface
|
||||||
*/
|
*/
|
||||||
private $isAdmin;
|
private $isAdmin;
|
||||||
|
|
||||||
/**
|
|
||||||
* @ORM\OneToMany(targetEntity=Post::class, mappedBy="author")
|
|
||||||
*/
|
|
||||||
private $posts;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="boolean", options={"default"=0})
|
* @ORM\Column(type="boolean", options={"default"=0})
|
||||||
*/
|
*/
|
||||||
private $isWriter;
|
private $isWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\OneToMany(targetEntity=Post::class, mappedBy="author")
|
||||||
|
*/
|
||||||
|
private $posts;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->posts = new ArrayCollection();
|
$this->posts = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection|Post[]
|
||||||
|
*/
|
||||||
|
public function getPosts(): Collection
|
||||||
|
{
|
||||||
|
return $this->posts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addPost(Post $post): self
|
||||||
|
{
|
||||||
|
if (!$this->posts->contains($post)) {
|
||||||
|
$this->posts[] = $post;
|
||||||
|
$post->setAuthor($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removePost(Post $post): self
|
||||||
|
{
|
||||||
|
if ($this->posts->removeElement($post)) {
|
||||||
|
// set the owning side to null (unless already changed)
|
||||||
|
if ($post->getAuthor() === $this) {
|
||||||
|
$post->setAuthor(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
|
@ -113,6 +144,8 @@ class User implements UserInterface, TwoFactorInterface, EntityInterface
|
||||||
*/
|
*/
|
||||||
public function getRoles(): array
|
public function getRoles(): array
|
||||||
{
|
{
|
||||||
|
$roles = [];
|
||||||
|
|
||||||
if ($this->getIsWriter()) {
|
if ($this->getIsWriter()) {
|
||||||
$roles[] = 'ROLE_WRITER';
|
$roles[] = 'ROLE_WRITER';
|
||||||
}
|
}
|
||||||
|
@ -251,36 +284,6 @@ class User implements UserInterface, TwoFactorInterface, EntityInterface
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection|Post[]
|
|
||||||
*/
|
|
||||||
public function getPosts(): Collection
|
|
||||||
{
|
|
||||||
return $this->posts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addPost(Post $post): self
|
|
||||||
{
|
|
||||||
if (!$this->posts->contains($post)) {
|
|
||||||
$this->posts[] = $post;
|
|
||||||
$post->setAuthor($this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removePost(Post $post): self
|
|
||||||
{
|
|
||||||
if ($this->posts->removeElement($post)) {
|
|
||||||
// set the owning side to null (unless already changed)
|
|
||||||
if ($post->getAuthor() === $this) {
|
|
||||||
$post->setAuthor(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getIsWriter(): ?bool
|
public function getIsWriter(): ?bool
|
||||||
{
|
{
|
||||||
return $this->isWriter;
|
return $this->isWriter;
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Event\Account;
|
|
||||||
|
|
||||||
use App\Entity\User;
|
|
||||||
use Symfony\Contracts\EventDispatcher\Event;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class PasswordRequestEvent.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class PasswordRequestEvent extends Event
|
|
||||||
{
|
|
||||||
const EVENT = 'account_event.password_request';
|
|
||||||
|
|
||||||
protected User $user;
|
|
||||||
|
|
||||||
public function __construct(User $user)
|
|
||||||
{
|
|
||||||
$this->user = $user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUser(): USer
|
|
||||||
{
|
|
||||||
return $this->user;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Event\EntityManager;
|
|
||||||
|
|
||||||
use App\Entity\EntityInterface;
|
|
||||||
use Symfony\Contracts\EventDispatcher\Event;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class EntityEvent.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class EntityManagerEvent extends Event
|
|
||||||
{
|
|
||||||
const CREATE_EVENT = 'entity_manager_event.create';
|
|
||||||
const UPDATE_EVENT = 'entity_manager_event.update';
|
|
||||||
const DELETE_EVENT = 'entity_manager_event.delete';
|
|
||||||
const PRE_CREATE_EVENT = 'entity_manager_event.pre_create';
|
|
||||||
const PRE_UPDATE_EVENT = 'entity_manager_event.pre_update';
|
|
||||||
const PRE_DELETE_EVENT = 'entity_manager_event.pre_delete';
|
|
||||||
|
|
||||||
protected EntityInterface $entity;
|
|
||||||
|
|
||||||
public function __construct(EntityInterface $entity)
|
|
||||||
{
|
|
||||||
$this->entity = $entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEntity(): EntityInterface
|
|
||||||
{
|
|
||||||
return $this->entity;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\EventSuscriber\Account;
|
|
||||||
|
|
||||||
use App\Event\Account\PasswordRequestEvent;
|
|
||||||
use App\Notification\MailNotifier;
|
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class EventListener.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class PasswordRequestEventSubscriber implements EventSubscriberInterface
|
|
||||||
{
|
|
||||||
protected MailNotifier $notifier;
|
|
||||||
protected UrlGeneratorInterface $urlGenerator;
|
|
||||||
|
|
||||||
public function __construct(MailNotifier $notifier, UrlGeneratorInterface $urlGenerator)
|
|
||||||
{
|
|
||||||
$this->notifier = $notifier;
|
|
||||||
$this->urlGenerator = $urlGenerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getSubscribedEvents()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
PasswordRequestEvent::EVENT => 'onRequest',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onRequest(PasswordRequestEvent $event)
|
|
||||||
{
|
|
||||||
$this->notifier
|
|
||||||
->setFrom('system@tinternet.net')
|
|
||||||
->setSubject('[Tinternet & cie] Mot de passe perdu')
|
|
||||||
->addRecipient($event->getUser()->getEmail())
|
|
||||||
->notify('resetting_request', [
|
|
||||||
'reseting_update_link' => $this->urlGenerator->generate(
|
|
||||||
'auth_resetting_update',
|
|
||||||
[
|
|
||||||
'token' => $event->getUser()->getConfirmationToken(),
|
|
||||||
],
|
|
||||||
UrlGeneratorInterface::ABSOLUTE_URL
|
|
||||||
),
|
|
||||||
])
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,9 +3,9 @@
|
||||||
namespace App\EventSuscriber\Blog;
|
namespace App\EventSuscriber\Blog;
|
||||||
|
|
||||||
use App\Entity\Blog\Post;
|
use App\Entity\Blog\Post;
|
||||||
use App\Entity\EntityInterface;
|
use App\Core\Entity\EntityInterface;
|
||||||
use App\Event\EntityManager\EntityManagerEvent;
|
use App\Core\Event\EntityManager\EntityManagerEvent;
|
||||||
use App\EventSuscriber\EntityManagerEventSubscriber;
|
use App\Core\EventSuscriber\EntityManagerEventSubscriber;
|
||||||
use App\Repository\Blog\PostRepositoryQuery;
|
use App\Repository\Blog\PostRepositoryQuery;
|
||||||
use Symfony\Component\Filesystem\Filesystem;
|
use Symfony\Component\Filesystem\Filesystem;
|
||||||
use Symfony\Component\Finder\Finder;
|
use Symfony\Component\Finder\Finder;
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\EventSuscriber;
|
|
||||||
|
|
||||||
use App\Event\EntityManager\EntityManagerEvent;
|
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class EntityManagerEventSubscriber.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
abstract class EntityManagerEventSubscriber implements EventSubscriberInterface
|
|
||||||
{
|
|
||||||
public static function getSubscribedEvents()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
EntityManagerEvent::CREATE_EVENT => 'onCreate',
|
|
||||||
EntityManagerEvent::UPDATE_EVENT => 'onUpdate',
|
|
||||||
EntityManagerEvent::DELETE_EVENT => 'onDelete',
|
|
||||||
EntityManagerEvent::PRE_CREATE_EVENT => 'onPreCreate',
|
|
||||||
EntityManagerEvent::PRE_UPDATE_EVENT => 'onPreUpdate',
|
|
||||||
EntityManagerEvent::PRE_DELETE_EVENT => 'onPreDelete',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onCreate(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onUpdate(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onDelete(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onPreCreate(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onPreUpdate(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onPreDelete(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\EventSuscriber\Site;
|
|
||||||
|
|
||||||
use App\Entity\EntityInterface;
|
|
||||||
use App\Entity\Site\Menu;
|
|
||||||
use App\Event\EntityManager\EntityManagerEvent;
|
|
||||||
use App\EventSuscriber\EntityManagerEventSubscriber;
|
|
||||||
use App\Factory\Site\NodeFactory;
|
|
||||||
use App\Manager\EntityManager;
|
|
||||||
use App\Repository\Site\NodeRepository;
|
|
||||||
use App\Slugify\CodeSlugify;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class MenuEventSubscriber.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class MenuEventSubscriber extends EntityManagerEventSubscriber
|
|
||||||
{
|
|
||||||
protected NodeFactory $nodeFactory;
|
|
||||||
protected NodeRepository $nodeRepository;
|
|
||||||
protected EntityManager $entityManager;
|
|
||||||
protected CodeSlugify $slugify;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
NodeFactory $nodeFactory,
|
|
||||||
NodeRepository $nodeRepository,
|
|
||||||
EntityManager $entityManager,
|
|
||||||
CodeSlugify $slugify
|
|
||||||
) {
|
|
||||||
$this->nodeFactory = $nodeFactory;
|
|
||||||
$this->nodeRepository = $nodeRepository;
|
|
||||||
$this->entityManager = $entityManager;
|
|
||||||
$this->slugify = $slugify;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function support(EntityInterface $entity)
|
|
||||||
{
|
|
||||||
return $entity instanceof Menu;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onPreUpdate(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
if (!$this->support($event->getEntity())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$menu = $event->getEntity();
|
|
||||||
$menu->setCode($this->slugify->slugify($menu->getCode()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onCreate(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
if (!$this->support($event->getEntity())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$menu = $event->getEntity();
|
|
||||||
|
|
||||||
if (0 !== count($menu->getNodes())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$rootNode = $this->nodeFactory->create($menu);
|
|
||||||
$childNode = $this->nodeFactory->create($menu, '/');
|
|
||||||
$childNode
|
|
||||||
->setParent($rootNode)
|
|
||||||
->setLabel('Premier élément')
|
|
||||||
;
|
|
||||||
|
|
||||||
$menu->setRootNode($rootNode);
|
|
||||||
|
|
||||||
$this->entityManager->getEntityManager()->persist($rootNode);
|
|
||||||
$this->entityManager->getEntityManager()->persist($childNode);
|
|
||||||
|
|
||||||
$this->entityManager->getEntityManager()->persist($menu);
|
|
||||||
$this->entityManager->flush();
|
|
||||||
|
|
||||||
$this->nodeRepository->persistAsFirstChild($childNode, $rootNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onUpdate(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
return $this->onCreate($event);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onPreCreate(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
return $this->onPreUpdate($event);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\EventSuscriber\Site;
|
|
||||||
|
|
||||||
use App\Entity\EntityInterface;
|
|
||||||
use App\Entity\Site\Navigation;
|
|
||||||
use App\Event\EntityManager\EntityManagerEvent;
|
|
||||||
use App\EventSuscriber\EntityManagerEventSubscriber;
|
|
||||||
use App\Manager\EntityManager;
|
|
||||||
use App\Slugify\CodeSlugify;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class NavigationEventSubscriber.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class NavigationEventSubscriber extends EntityManagerEventSubscriber
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
EntityManager $entityManager,
|
|
||||||
CodeSlugify $slugify
|
|
||||||
) {
|
|
||||||
$this->entityManager = $entityManager;
|
|
||||||
$this->slugify = $slugify;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function support(EntityInterface $entity)
|
|
||||||
{
|
|
||||||
return $entity instanceof Navigation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onPreUpdate(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
if (!$this->support($event->getEntity())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$menu = $event->getEntity();
|
|
||||||
$menu->setCode($this->slugify->slugify($menu->getCode()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onPreCreate(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
return $this->onPreUpdate($event);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\EventSuscriber\Site;
|
|
||||||
|
|
||||||
use App\Entity\EntityInterface;
|
|
||||||
use App\Entity\Site\Node;
|
|
||||||
use App\Event\EntityManager\EntityManagerEvent;
|
|
||||||
use App\EventSuscriber\EntityManagerEventSubscriber;
|
|
||||||
use App\Factory\Site\NodeFactory;
|
|
||||||
use App\Manager\EntityManager;
|
|
||||||
use App\Repository\Site\NodeRepository;
|
|
||||||
use App\Slugify\Slugify;
|
|
||||||
use Symfony\Component\HttpKernel\KernelInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class NodeEventSubscriber.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class NodeEventSubscriber extends EntityManagerEventSubscriber
|
|
||||||
{
|
|
||||||
protected NodeFactory $nodeFactory;
|
|
||||||
protected EntityManager $entityManager;
|
|
||||||
protected KernelInterface $kernel;
|
|
||||||
protected Slugify $slugify;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
NodeFactory $nodeFactory,
|
|
||||||
NodeRepository $nodeRepository,
|
|
||||||
EntityManager $entityManager,
|
|
||||||
Slugify $slugify
|
|
||||||
) {
|
|
||||||
$this->nodeFactory = $nodeFactory;
|
|
||||||
$this->nodeRepository = $nodeRepository;
|
|
||||||
$this->entityManager = $entityManager;
|
|
||||||
$this->slugify = $slugify;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function support(EntityInterface $entity)
|
|
||||||
{
|
|
||||||
return $entity instanceof Node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onPreUpdate(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
if (!$this->support($event->getEntity())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$node = $event->getEntity();
|
|
||||||
|
|
||||||
if ($node->getUrl()) {
|
|
||||||
$generatedUrl = $node->getUrl();
|
|
||||||
} else {
|
|
||||||
$path = [];
|
|
||||||
$parent = $node->getParent();
|
|
||||||
|
|
||||||
if ($parent && $parent->getUrl()) {
|
|
||||||
$pPath = trim($parent->getUrl(), '/');
|
|
||||||
|
|
||||||
if ($pPath) {
|
|
||||||
$path[] = $pPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$path[] = $this->slugify->slugify($node->getLabel());
|
|
||||||
|
|
||||||
$generatedUrl = '/'.implode('/', $path);
|
|
||||||
}
|
|
||||||
|
|
||||||
$urlExists = $this->nodeRepository->urlExists($generatedUrl, $node);
|
|
||||||
|
|
||||||
if ($urlExists) {
|
|
||||||
$number = 1;
|
|
||||||
|
|
||||||
while ($this->nodeRepository->urlExists($generatedUrl.'-'.$number, $node)) {
|
|
||||||
++$number;
|
|
||||||
}
|
|
||||||
|
|
||||||
$generatedUrl = $generatedUrl.'-'.$number;
|
|
||||||
}
|
|
||||||
|
|
||||||
$node->setUrl($generatedUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onDelete(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
if (!$this->support($event->getEntity())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$menu = $event->getEntity()->getMenu();
|
|
||||||
$rootNode = $menu->getRootNode();
|
|
||||||
|
|
||||||
if (0 !== count($rootNode->getChildren())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$childNode = $this->nodeFactory->create($menu);
|
|
||||||
$childNode
|
|
||||||
->setParent($rootNode)
|
|
||||||
->setLabel('Premier élément')
|
|
||||||
;
|
|
||||||
|
|
||||||
$this->entityManager->update($rootNode, false);
|
|
||||||
$this->entityManager->create($childNode, false);
|
|
||||||
$this->nodeRepository->persistAsFirstChild($childNode, $rootNode);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\EventSuscriber\Site;
|
|
||||||
|
|
||||||
use App\Entity\EntityInterface;
|
|
||||||
use App\Entity\Site\Node;
|
|
||||||
use App\Event\EntityManager\EntityManagerEvent;
|
|
||||||
use App\EventSuscriber\EntityManagerEventSubscriber;
|
|
||||||
use App\Factory\Site\NodeFactory;
|
|
||||||
use App\Manager\EntityManager;
|
|
||||||
use App\Repository\Site\NodeRepository;
|
|
||||||
use App\Slugify\Slugify;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
|
||||||
use Symfony\Component\Console\Input\ArrayInput;
|
|
||||||
use Symfony\Component\Console\Output\BufferedOutput;
|
|
||||||
use Symfony\Component\HttpKernel\KernelInterface;
|
|
||||||
use App\Entity\Site\Menu;
|
|
||||||
use App\Entity\Site\Navigation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class SiteEventSubscriber.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class SiteEventSubscriber extends EntityManagerEventSubscriber
|
|
||||||
{
|
|
||||||
protected KernelInterface $kernel;
|
|
||||||
|
|
||||||
public function __construct(KernelInterface $kernel) {
|
|
||||||
$this->kernel = $kernel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function support(EntityInterface $entity)
|
|
||||||
{
|
|
||||||
return $entity instanceof Node || $entity instanceof Menu || $entity instanceof Navigation;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function cleanCache()
|
|
||||||
{
|
|
||||||
$application = new Application($this->kernel);
|
|
||||||
$application->setAutoExit(false);
|
|
||||||
|
|
||||||
$input = new ArrayInput([
|
|
||||||
'command' => 'cache:clear',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$output = new BufferedOutput();
|
|
||||||
$application->run($input, $output);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onUpdate(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
if (!$this->support($event->getEntity())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->cleanCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onCreate(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
return $this->onUpdate($event);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onDelete(EntityManagerEvent $event)
|
|
||||||
{
|
|
||||||
return $this->onUpdate($event);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Factory\Site;
|
|
||||||
|
|
||||||
use App\Entity\Site\Menu;
|
|
||||||
use App\Entity\Site\Navigation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class MenuFactory.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class MenuFactory
|
|
||||||
{
|
|
||||||
public function create(?Navigation $navigation = null): Menu
|
|
||||||
{
|
|
||||||
$entity = new Menu();
|
|
||||||
|
|
||||||
if (null !== $navigation) {
|
|
||||||
$entity->setNavigation($navigation);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $entity;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Factory\Site;
|
|
||||||
|
|
||||||
use App\Entity\Site\Navigation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class NavigationFactory.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class NavigationFactory
|
|
||||||
{
|
|
||||||
public function create(): Navigation
|
|
||||||
{
|
|
||||||
return new Navigation();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Factory\Site;
|
|
||||||
|
|
||||||
use App\Entity\Site\Menu;
|
|
||||||
use App\Entity\Site\Node;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class NodeFactory.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class NodeFactory
|
|
||||||
{
|
|
||||||
public function create(?Menu $menu = null, string $url = null): Node
|
|
||||||
{
|
|
||||||
$entity = new Node();
|
|
||||||
|
|
||||||
if (null !== $menu) {
|
|
||||||
$entity->setMenu($menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null !== $url) {
|
|
||||||
$entity->setUrl($url);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return $entity;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Factory\Site\Page;
|
|
||||||
|
|
||||||
use App\Entity\Site\Page\Page;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class PageFactory.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class PageFactory
|
|
||||||
{
|
|
||||||
public function create(string $className, string $name): Page
|
|
||||||
{
|
|
||||||
$entity = new $className();
|
|
||||||
$entity->setName($name);
|
|
||||||
|
|
||||||
return $entity;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,32 +5,13 @@ namespace App\Factory;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
|
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
|
||||||
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
|
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
|
||||||
|
use App\Core\Factory\UserFactory as BaseUserFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class UserFactory.
|
* class UserFactory.
|
||||||
*
|
*
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
* @author Simon Vieille <simon@deblan.fr>
|
||||||
*/
|
*/
|
||||||
class UserFactory
|
class UserFactory extends BaseUserFactory
|
||||||
{
|
{
|
||||||
protected TokenGeneratorInterface $tokenGenerator;
|
|
||||||
protected UserPasswordEncoderInterface $encoder;
|
|
||||||
|
|
||||||
public function __construct(TokenGeneratorInterface $tokenGenerator, UserPasswordEncoderInterface $encoder)
|
|
||||||
{
|
|
||||||
$this->tokenGenerator = $tokenGenerator;
|
|
||||||
$this->encoder = $encoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create(): User
|
|
||||||
{
|
|
||||||
$entity = new User();
|
|
||||||
|
|
||||||
$entity->setPassword($this->encoder->encodePassword(
|
|
||||||
$entity,
|
|
||||||
$this->tokenGenerator->generateToken()
|
|
||||||
));
|
|
||||||
|
|
||||||
return $entity;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Form;
|
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class FileUploadHandler.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class FileUploadHandler
|
|
||||||
{
|
|
||||||
public function handleForm(?UploadedFile $uploadedFile, string $path, callable $afterUploadCallback): void
|
|
||||||
{
|
|
||||||
if (null === $uploadedFile) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$originalFilename = pathinfo($uploadedFile->getClientOriginalName(), PATHINFO_FILENAME);
|
|
||||||
$safeFilename = transliterator_transliterate('Any-Latin; Latin-ASCII; [^A-Za-z0-9_] remove; Lower()', $originalFilename);
|
|
||||||
$filename = date('Ymd-his').$safeFilename.'.'.$uploadedFile->guessExtension();
|
|
||||||
|
|
||||||
$uploadedFile->move($path, $filename);
|
|
||||||
|
|
||||||
$afterUploadCallback($filename);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Form\Site;
|
|
||||||
|
|
||||||
use App\Entity\Site\Menu;
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
|
||||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
|
||||||
|
|
||||||
class MenuType extends AbstractType
|
|
||||||
{
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
|
||||||
{
|
|
||||||
$builder->add(
|
|
||||||
'label',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Libellé',
|
|
||||||
'required' => true,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
new NotBlank(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'code',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Code',
|
|
||||||
'required' => true,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
new NotBlank(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
|
||||||
{
|
|
||||||
$resolver->setDefaults([
|
|
||||||
'data_class' => Menu::class,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Form\Site;
|
|
||||||
|
|
||||||
use App\Entity\Site\Navigation;
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
|
||||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
|
||||||
|
|
||||||
class NavigationType extends AbstractType
|
|
||||||
{
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
|
||||||
{
|
|
||||||
$builder->add(
|
|
||||||
'label',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Libellé',
|
|
||||||
'required' => true,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
new NotBlank(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'code',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Code',
|
|
||||||
'required' => true,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
new NotBlank(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'domain',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Nom de domaine',
|
|
||||||
'required' => true,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
new NotBlank(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
|
||||||
{
|
|
||||||
$resolver->setDefaults([
|
|
||||||
'data_class' => Navigation::class,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Form\Site;
|
|
||||||
|
|
||||||
use App\Entity\Site\Node;
|
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
|
||||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
|
||||||
|
|
||||||
class NodeMoveType extends AbstractType
|
|
||||||
{
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
|
||||||
{
|
|
||||||
$builder->add(
|
|
||||||
'position',
|
|
||||||
ChoiceType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Position',
|
|
||||||
'required' => true,
|
|
||||||
'choices' => [
|
|
||||||
'Après' => 'after',
|
|
||||||
'Avant' => 'before',
|
|
||||||
'En dessous' => 'above',
|
|
||||||
],
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
new NotBlank(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'node',
|
|
||||||
EntityType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Élement de référence',
|
|
||||||
'class' => Node::class,
|
|
||||||
'choices' => call_user_func(function () use ($options) {
|
|
||||||
return $options['menu']->getRootNode()->getAllChildren();
|
|
||||||
}),
|
|
||||||
'choice_label' => 'treeLabel',
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
new NotBlank(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
|
||||||
{
|
|
||||||
$resolver->setDefaults([
|
|
||||||
'data_class' => null,
|
|
||||||
'menu' => null,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,158 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Form\Site;
|
|
||||||
|
|
||||||
use App\Entity\Site\Node;
|
|
||||||
use App\Entity\Site\Page\Page;
|
|
||||||
use Doctrine\ORM\EntityRepository;
|
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
|
||||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
|
||||||
|
|
||||||
class NodeType extends AbstractType
|
|
||||||
{
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
|
||||||
{
|
|
||||||
$builder->add(
|
|
||||||
'label',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Libellé',
|
|
||||||
'required' => true,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
new NotBlank(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'url',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'URL',
|
|
||||||
'required' => false,
|
|
||||||
'help' => 'Laisser vide pour une génération automatique',
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'code',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Code',
|
|
||||||
'required' => false,
|
|
||||||
'help' => 'Sans espace, en minusule, sans caractère spécial',
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$actions = [
|
|
||||||
'Nouvelle page' => 'new',
|
|
||||||
'Associer à une page existante' => 'existing',
|
|
||||||
'Aucune page' => 'none',
|
|
||||||
];
|
|
||||||
|
|
||||||
if ($builder->getData()->getId()) {
|
|
||||||
$actions['Garder la configuration actuelle'] = 'keep';
|
|
||||||
}
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'pageAction',
|
|
||||||
ChoiceType::class,
|
|
||||||
[
|
|
||||||
'label' => false,
|
|
||||||
'required' => true,
|
|
||||||
'expanded' => true,
|
|
||||||
'mapped' => false,
|
|
||||||
'choices' => $actions,
|
|
||||||
'constraints' => [
|
|
||||||
new NotBlank(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'pageType',
|
|
||||||
ChoiceType::class,
|
|
||||||
[
|
|
||||||
'label' => false,
|
|
||||||
'required' => true,
|
|
||||||
'mapped' => false,
|
|
||||||
'choices' => call_user_func(function () use ($options) {
|
|
||||||
$choices = [];
|
|
||||||
|
|
||||||
foreach ($options['pages'] as $page) {
|
|
||||||
$choices[$page->getName()] = $page->getClassName();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $choices;
|
|
||||||
}),
|
|
||||||
'constraints' => [
|
|
||||||
new NotBlank(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'pageEntity',
|
|
||||||
EntityType::class,
|
|
||||||
[
|
|
||||||
'label' => false,
|
|
||||||
'required' => true,
|
|
||||||
'mapped' => false,
|
|
||||||
'class' => Page::class,
|
|
||||||
'choice_label' => 'name',
|
|
||||||
'query_builder' => function (EntityRepository $repo) {
|
|
||||||
return $repo->createQueryBuilder('p')
|
|
||||||
->orderBy('p.name', 'ASC')
|
|
||||||
;
|
|
||||||
},
|
|
||||||
'constraints' => [
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (null === $builder->getData()->getId()) {
|
|
||||||
$builder->add(
|
|
||||||
'position',
|
|
||||||
ChoiceType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Position',
|
|
||||||
'required' => true,
|
|
||||||
'mapped' => false,
|
|
||||||
'choices' => [
|
|
||||||
'Après' => 'after',
|
|
||||||
'Avant' => 'before',
|
|
||||||
'En dessous' => 'above',
|
|
||||||
],
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
new NotBlank(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
|
||||||
{
|
|
||||||
$resolver->setDefaults([
|
|
||||||
'data_class' => Node::class,
|
|
||||||
'pages' => [],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Form\Site\Page;
|
|
||||||
|
|
||||||
use App\Entity\Site\Page\Page;
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
|
||||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
|
||||||
|
|
||||||
class PageType extends AbstractType
|
|
||||||
{
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
|
||||||
{
|
|
||||||
$builder->add(
|
|
||||||
'name',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Nom',
|
|
||||||
'required' => true,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
new NotBlank(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'metaTitle',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Titre',
|
|
||||||
'required' => false,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'metaDescrition',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Description',
|
|
||||||
'required' => false,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'ogTitle',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Titre',
|
|
||||||
'required' => false,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'ogDescription',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Description',
|
|
||||||
'required' => false,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'template',
|
|
||||||
ChoiceType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Rendu',
|
|
||||||
'required' => true,
|
|
||||||
'choices' => call_user_func(function () use ($options) {
|
|
||||||
$choices = [];
|
|
||||||
|
|
||||||
foreach ($options['pageConfiguration']->getTemplates() as $template) {
|
|
||||||
$choices[$template['name']] = $template['file'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $choices;
|
|
||||||
}),
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
new NotBlank(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->getData()->buildForm($builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
|
||||||
{
|
|
||||||
$resolver->setDefaults([
|
|
||||||
'data_class' => Page::class,
|
|
||||||
'pageConfiguration' => null,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Form\Site\Page;
|
|
||||||
|
|
||||||
use App\Entity\Site\Page\Block;
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
|
||||||
|
|
||||||
class TextBlockType extends AbstractType
|
|
||||||
{
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
|
||||||
{
|
|
||||||
$builder->add(
|
|
||||||
'value',
|
|
||||||
TextType::class,
|
|
||||||
array_merge([
|
|
||||||
'required' => false,
|
|
||||||
'label' => false,
|
|
||||||
], $options['options']),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
|
||||||
{
|
|
||||||
$resolver->setDefaults([
|
|
||||||
'data_class' => Block::class,
|
|
||||||
'options' => [],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Form\Site\Page;
|
|
||||||
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
|
|
||||||
class TextareaBlockType extends TextBlockType
|
|
||||||
{
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
|
||||||
{
|
|
||||||
$builder->add(
|
|
||||||
'value',
|
|
||||||
TextareaType::class,
|
|
||||||
array_merge([
|
|
||||||
'required' => false,
|
|
||||||
'label' => false,
|
|
||||||
], $options['options']),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,82 +10,8 @@ use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
use Symfony\Component\Validator\Constraints\Email;
|
use Symfony\Component\Validator\Constraints\Email;
|
||||||
|
use App\Core\Form\UserType as BaseUserType;
|
||||||
|
|
||||||
class UserType extends AbstractType
|
class UserType extends BaseUserType
|
||||||
{
|
{
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
|
||||||
{
|
|
||||||
$builder->add(
|
|
||||||
'email',
|
|
||||||
EmailType::class,
|
|
||||||
[
|
|
||||||
'label' => 'E-mail',
|
|
||||||
'required' => true,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
new Email(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'displayName',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Nom complet',
|
|
||||||
'required' => true,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'displayName',
|
|
||||||
TextType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Nom complet',
|
|
||||||
'required' => true,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'isAdmin',
|
|
||||||
CheckboxType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Administrateur⋅trice',
|
|
||||||
'required' => false,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$builder->add(
|
|
||||||
'isWriter',
|
|
||||||
CheckboxType::class,
|
|
||||||
[
|
|
||||||
'label' => 'Rédacteur⋅trice',
|
|
||||||
'required' => false,
|
|
||||||
'attr' => [
|
|
||||||
],
|
|
||||||
'constraints' => [
|
|
||||||
],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
|
||||||
{
|
|
||||||
$resolver->setDefaults([
|
|
||||||
'data_class' => User::class,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Manager;
|
|
||||||
|
|
||||||
use App\Entity\EntityInterface;
|
|
||||||
use App\Event\EntityManager\EntityManagerEvent;
|
|
||||||
use Doctrine\ORM\EntityManager as DoctrineEntityManager;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class EntityManager.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class EntityManager
|
|
||||||
{
|
|
||||||
protected EventDispatcherInterface $eventDispatcher;
|
|
||||||
|
|
||||||
protected DoctrineEntityManager $entityManager;
|
|
||||||
|
|
||||||
public function __construct(EventDispatcherInterface $eventDispatcher, EntityManagerInterface $entityManager)
|
|
||||||
{
|
|
||||||
$this->eventDispatcher = $eventDispatcher;
|
|
||||||
$this->entityManager = $entityManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create(EntityInterface $entity, bool $dispatchEvent = true): self
|
|
||||||
{
|
|
||||||
if ($dispatchEvent) {
|
|
||||||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::PRE_CREATE_EVENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->persist($entity);
|
|
||||||
|
|
||||||
if ($dispatchEvent) {
|
|
||||||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::CREATE_EVENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(EntityInterface $entity, bool $dispatchEvent = true): self
|
|
||||||
{
|
|
||||||
if ($dispatchEvent) {
|
|
||||||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::PRE_UPDATE_EVENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->persist($entity);
|
|
||||||
|
|
||||||
if ($dispatchEvent) {
|
|
||||||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::UPDATE_EVENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete(EntityInterface $entity, bool $dispatchEvent = true): self
|
|
||||||
{
|
|
||||||
if ($dispatchEvent) {
|
|
||||||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::PRE_DELETE_EVENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->entityManager->remove($entity);
|
|
||||||
$this->flush();
|
|
||||||
|
|
||||||
if ($dispatchEvent) {
|
|
||||||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::DELETE_EVENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function flush(): self
|
|
||||||
{
|
|
||||||
$this->entityManager->flush();
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function clear(): self
|
|
||||||
{
|
|
||||||
$this->entityManager->clear();
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEntityManager(): EntityManagerInterface
|
|
||||||
{
|
|
||||||
return $this->entityManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function persist(EntityInterface $entity)
|
|
||||||
{
|
|
||||||
$this->entityManager->persist($entity);
|
|
||||||
$this->flush();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,338 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Notification;
|
|
||||||
|
|
||||||
use Swift_Attachment;
|
|
||||||
use Swift_Mailer;
|
|
||||||
use Swift_Message;
|
|
||||||
use Twig\Environment as TwigEnvironment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class MailNotifier.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class MailNotifier
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var Swift_Mailer
|
|
||||||
*/
|
|
||||||
protected $mailer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $attachments = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $recipients = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $bccRecipients = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $subject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $from;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $replyTo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param BasicNotifier $basicNotifier
|
|
||||||
* @param Swift_Mailer $mail
|
|
||||||
*/
|
|
||||||
public function __construct(TwigEnvironment $twig, Swift_Mailer $mailer)
|
|
||||||
{
|
|
||||||
$this->mailer = $mailer;
|
|
||||||
$this->twig = $twig;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function setMailer(Swift_Mailer $mailer): self
|
|
||||||
{
|
|
||||||
$this->mailer = $mailer;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMailer(): Swift_Mailer
|
|
||||||
{
|
|
||||||
return $this->mailer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function setRecipients(array $recipients): self
|
|
||||||
{
|
|
||||||
$this->recipients = $recipients;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRecipients(): array
|
|
||||||
{
|
|
||||||
return $this->recipients;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function setBccRecipients(array $bccRecipients): self
|
|
||||||
{
|
|
||||||
$this->bccRecipients = $bccRecipients;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBccRecipients(): array
|
|
||||||
{
|
|
||||||
return $this->bccRecipients;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $subject
|
|
||||||
*
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function setSubject(?string $subject): self
|
|
||||||
{
|
|
||||||
$this->subject = $subject;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSubject(): string
|
|
||||||
{
|
|
||||||
return $this->subject;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mixed $from
|
|
||||||
*
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function setFrom($from): self
|
|
||||||
{
|
|
||||||
$this->from = $from;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getFrom(): ?string
|
|
||||||
{
|
|
||||||
return $this->from;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of "replyTo".
|
|
||||||
*
|
|
||||||
* @param string $replyTo
|
|
||||||
*
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function setReplyTo($replyTo): self
|
|
||||||
{
|
|
||||||
$this->replyTo = $replyTo;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the value of "replyTo".
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getReplyTo(): ?string
|
|
||||||
{
|
|
||||||
return $this->replyTo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function setAttachments(array $attachments): self
|
|
||||||
{
|
|
||||||
$this->attachments = $attachments;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAttachments(): array
|
|
||||||
{
|
|
||||||
return $this->attachments;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function addRecipient(string $email, bool $isBcc = false): self
|
|
||||||
{
|
|
||||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
||||||
throw new \InvalidArgumentException(sprintf('Invalid email "%s".', $email));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($isBcc) {
|
|
||||||
if (!in_array($email, $this->bccRecipients)) {
|
|
||||||
$this->bccRecipients[] = $email;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!in_array($email, $this->recipients)) {
|
|
||||||
$this->recipients[] = $email;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function addRecipients(array $emails, bool $isBcc = false): self
|
|
||||||
{
|
|
||||||
foreach ($emails as $email) {
|
|
||||||
$this->addRecipient($email, $isBcc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function addRecipientByAccount(Account $account, bool $isBcc = false): self
|
|
||||||
{
|
|
||||||
return $this->addRecipient($account->getEmail(), $isBcc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mixed $accounts
|
|
||||||
*
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function addRecipientsByAccounts($accounts, bool $isBcc = false)
|
|
||||||
{
|
|
||||||
if (!is_array($accounts)) {
|
|
||||||
throw new InvalidArgumentException('The "accounts" parameter must be an array or an instance of ObjectCollection');
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($accounts as $account) {
|
|
||||||
$this->addRecipientByAccount($account, $isBcc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function addAttachment(string $attachment): self
|
|
||||||
{
|
|
||||||
if (!in_array($attachment, $this->attachments)) {
|
|
||||||
$this->attachments[] = $attachment;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function addAttachments(array $attachments): self
|
|
||||||
{
|
|
||||||
foreach ($attachments as $attachment) {
|
|
||||||
$this->addAttachment($attachment);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function init(): self
|
|
||||||
{
|
|
||||||
$this
|
|
||||||
->setSubject(null)
|
|
||||||
->setRecipients([])
|
|
||||||
->setBccRecipients([])
|
|
||||||
->setAttachments([])
|
|
||||||
;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return EmailNotifier
|
|
||||||
*/
|
|
||||||
public function notify(string $template, array $data = [], string $type = 'text/html'): self
|
|
||||||
{
|
|
||||||
$message = $this->createMessage(
|
|
||||||
$this->twig->render(
|
|
||||||
sprintf('mail/%s.html.twig', $template),
|
|
||||||
$data
|
|
||||||
),
|
|
||||||
$type
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->mailer->send($message);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function createMessage(string $body, string $type = 'text/html'): Swift_Message
|
|
||||||
{
|
|
||||||
$message = new Swift_Message();
|
|
||||||
|
|
||||||
if ($this->getSubject()) {
|
|
||||||
$message->setSubject($this->getSubject());
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->getFrom()) {
|
|
||||||
$message->setFrom($this->getFrom());
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->getReplyTo()) {
|
|
||||||
$message->setReplyTo($this->getReplyTo());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($this->getRecipients()) > 0) {
|
|
||||||
$message->setTo($this->getRecipients());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($this->getBccRecipients()) > 0) {
|
|
||||||
$message->setBcc($this->getBccRecipients());
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($this->getAttachments() as $attachment) {
|
|
||||||
if (is_object($attachment) && $attachment instanceof Swift_Attachment) {
|
|
||||||
$message->attach($attachment);
|
|
||||||
} elseif (is_string($attachment) && file_exists($attachment) && is_readable($attachment) && !is_dir($attachment)) {
|
|
||||||
$message->attach(Swift_Attachment::fromPath($attachment));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$message->setBody($body, $type);
|
|
||||||
|
|
||||||
return $message;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
namespace App\Repository\Blog;
|
namespace App\Repository\Blog;
|
||||||
|
|
||||||
use App\Repository\RepositoryQuery;
|
|
||||||
use Knp\Component\Pager\PaginatorInterface;
|
use Knp\Component\Pager\PaginatorInterface;
|
||||||
|
use App\Core\Repository\RepositoryQuery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class CategoryRepositoryQuery.
|
* class CategoryRepositoryQuery.
|
||||||
|
|
|
@ -4,8 +4,8 @@ namespace App\Repository\Blog;
|
||||||
|
|
||||||
use App\Entity\Blog\Category;
|
use App\Entity\Blog\Category;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Repository\RepositoryQuery;
|
|
||||||
use Knp\Component\Pager\PaginatorInterface;
|
use Knp\Component\Pager\PaginatorInterface;
|
||||||
|
use App\Core\Repository\RepositoryQuery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class PostRepositoryQuery.
|
* class PostRepositoryQuery.
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Repository;
|
|
||||||
|
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
|
||||||
use Knp\Component\Pager\PaginatorInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class RepositoryQuery.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
abstract class RepositoryQuery
|
|
||||||
{
|
|
||||||
protected ServiceEntityRepository $repository;
|
|
||||||
protected QueryBuilder $query;
|
|
||||||
protected PaginatorInterface $paginator;
|
|
||||||
protected string $id;
|
|
||||||
|
|
||||||
public function __construct(ServiceEntityRepository $repository, string $id, PaginatorInterface $paginator = null)
|
|
||||||
{
|
|
||||||
$this->repository = $repository;
|
|
||||||
$this->query = $repository->createQueryBuilder($id);
|
|
||||||
$this->paginator = $paginator;
|
|
||||||
$this->id = $id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __call(string $name, $params): self
|
|
||||||
{
|
|
||||||
$fn = function (&$data) {
|
|
||||||
if (is_string($data)) {
|
|
||||||
$words = explode(' ', $data);
|
|
||||||
|
|
||||||
foreach ($words as $k => $v) {
|
|
||||||
if (isset($v[0]) && '.' === $v[0]) {
|
|
||||||
$words[$k] = $this->id.$v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = implode(' ', $words);
|
|
||||||
} elseif (is_array($data)) {
|
|
||||||
foreach ($data as $k => $v) {
|
|
||||||
$fn($data[$k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach ($params as $key => $value) {
|
|
||||||
$fn($params[$key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
call_user_func_array([$this->query, $name], $params);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create()
|
|
||||||
{
|
|
||||||
$class = get_called_class();
|
|
||||||
|
|
||||||
return new $class($this->repository, $this->paginator);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function call(callable $fn): self
|
|
||||||
{
|
|
||||||
$fn($this->query, $this);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function findOne()
|
|
||||||
{
|
|
||||||
return $this->query->getQuery()
|
|
||||||
->setMaxResults(1)
|
|
||||||
->getOneOrNullResult()
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function find()
|
|
||||||
{
|
|
||||||
return $this->query->getQuery()->getResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function paginate(int $page = 1, int $limit = 20)
|
|
||||||
{
|
|
||||||
return $this->paginator->paginate($this->query->getQuery(), $page, $limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRepository(): ServiceEntityRepository
|
|
||||||
{
|
|
||||||
return $this->repository;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Repository\Site;
|
|
||||||
|
|
||||||
use App\Entity\Site\Menu;
|
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
|
||||||
|
|
||||||
class MenuRepository extends ServiceEntityRepository
|
|
||||||
{
|
|
||||||
public function __construct(ManagerRegistry $registry)
|
|
||||||
{
|
|
||||||
parent::__construct($registry, Menu::class);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Repository\Site;
|
|
||||||
|
|
||||||
use App\Repository\RepositoryQuery;
|
|
||||||
use Knp\Component\Pager\PaginatorInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class MenuRepositoryQuery.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class MenuRepositoryQuery extends RepositoryQuery
|
|
||||||
{
|
|
||||||
public function __construct(MenuRepository $repository, PaginatorInterface $paginator)
|
|
||||||
{
|
|
||||||
parent::__construct($repository, 'm', $paginator);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Repository\Site;
|
|
||||||
|
|
||||||
use App\Entity\Site\Navigation;
|
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
|
||||||
|
|
||||||
class NavigationRepository extends ServiceEntityRepository
|
|
||||||
{
|
|
||||||
public function __construct(ManagerRegistry $registry)
|
|
||||||
{
|
|
||||||
parent::__construct($registry, Navigation::class);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Repository\Site;
|
|
||||||
|
|
||||||
use App\Repository\RepositoryQuery;
|
|
||||||
use Knp\Component\Pager\PaginatorInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class NavigationRepositoryQuery.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class NavigationRepositoryQuery extends RepositoryQuery
|
|
||||||
{
|
|
||||||
public function __construct(NavigationRepository $repository, PaginatorInterface $paginator)
|
|
||||||
{
|
|
||||||
parent::__construct($repository, 'n', $paginator);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Repository\Site;
|
|
||||||
|
|
||||||
use App\Entity\Site\Node;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Gedmo\Tree\Entity\Repository\NestedTreeRepository;
|
|
||||||
|
|
||||||
class NodeRepository extends NestedTreeRepository
|
|
||||||
{
|
|
||||||
public function __construct(EntityManagerInterface $manager)
|
|
||||||
{
|
|
||||||
parent::__construct($manager, $manager->getClassMetadata(Node::class));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function urlExists($url, Node $node)
|
|
||||||
{
|
|
||||||
$query = $this->createQueryBuilder('n')
|
|
||||||
->join('n.menu', 'm')
|
|
||||||
->where('n.url = :url')
|
|
||||||
->andWhere('m.navigation = :navigation')
|
|
||||||
->setParameter(':url', $url)
|
|
||||||
->setParameter(':navigation', $node->getMenu()->getNavigation())
|
|
||||||
;
|
|
||||||
|
|
||||||
if ($node->getId()) {
|
|
||||||
$query
|
|
||||||
->andWhere('n.id != :id')
|
|
||||||
->setParameter(':id', $node->getId())
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $query->getQuery()
|
|
||||||
->setMaxResults(1)
|
|
||||||
->getOneOrNullResult()
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Repository\Site\Page;
|
|
||||||
|
|
||||||
use App\Entity\Site\Page\Block;
|
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
|
||||||
|
|
||||||
class BlockRepository extends ServiceEntityRepository
|
|
||||||
{
|
|
||||||
public function __construct(ManagerRegistry $registry)
|
|
||||||
{
|
|
||||||
parent::__construct($registry, Block::class);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Repository\Site\Page;
|
|
||||||
|
|
||||||
use App\Repository\RepositoryQuery;
|
|
||||||
use Knp\Component\Pager\PaginatorInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class BlockRepositoryQuery.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class BlockRepositoryQuery extends RepositoryQuery
|
|
||||||
{
|
|
||||||
public function __construct(BlockRepository $repository, PaginatorInterface $paginator)
|
|
||||||
{
|
|
||||||
parent::__construct($repository, 'b', $paginator);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Repository\Site\Page;
|
|
||||||
|
|
||||||
use App\Entity\Site\Page\Page;
|
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
|
||||||
|
|
||||||
class PageRepository extends ServiceEntityRepository
|
|
||||||
{
|
|
||||||
public function __construct(ManagerRegistry $registry)
|
|
||||||
{
|
|
||||||
parent::__construct($registry, Page::class);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Repository\Site\Page;
|
|
||||||
|
|
||||||
use App\Repository\RepositoryQuery;
|
|
||||||
use Knp\Component\Pager\PaginatorInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class PageRepositoryQuery.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class PageRepositoryQuery extends RepositoryQuery
|
|
||||||
{
|
|
||||||
public function __construct(PageRepository $repository, PaginatorInterface $paginator)
|
|
||||||
{
|
|
||||||
parent::__construct($repository, 'p', $paginator);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function filterById($id)
|
|
||||||
{
|
|
||||||
$this
|
|
||||||
->where('.id = :id')
|
|
||||||
->setParameter(':id', $id)
|
|
||||||
;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Repository;
|
namespace App\Repository;
|
||||||
|
|
||||||
use Knp\Component\Pager\PaginatorInterface;
|
use Knp\Component\Pager\PaginatorInterface;
|
||||||
|
use App\Core\Repository\RepositoryQuery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class UserRepositoryQuery.
|
* class UserRepositoryQuery.
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Router;
|
|
||||||
|
|
||||||
use App\Controller\Site\PageController;
|
|
||||||
use App\Repository\Site\NavigationRepositoryQuery;
|
|
||||||
use Symfony\Component\Config\Loader\Loader;
|
|
||||||
use Symfony\Component\Routing\Route;
|
|
||||||
use Symfony\Component\Routing\RouteCollection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class SiteRouteLoader.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class SiteRouteLoader extends Loader
|
|
||||||
{
|
|
||||||
protected NavigationRepositoryQuery $navigationQuery;
|
|
||||||
protected $isLoaded = false;
|
|
||||||
|
|
||||||
public function __construct(NavigationRepositoryQuery $navigationQuery)
|
|
||||||
{
|
|
||||||
$this->navigationQuery = $navigationQuery;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function load($resource, ?string $type = null)
|
|
||||||
{
|
|
||||||
if (true === $this->isLoaded) {
|
|
||||||
throw new \RuntimeException('Do not add the "extra" loader twice');
|
|
||||||
}
|
|
||||||
|
|
||||||
$routes = new RouteCollection();
|
|
||||||
$navigations = $this->navigationQuery->find();
|
|
||||||
|
|
||||||
foreach ($navigations as $navigation) {
|
|
||||||
foreach ($navigation->getMenus() as $menu) {
|
|
||||||
foreach ($menu->getRootNode()->getAllChildren() as $node) {
|
|
||||||
if ($node->getParent() === null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$requirements = [];
|
|
||||||
|
|
||||||
$defaults = [
|
|
||||||
'_controller' => PageController::class.'::show',
|
|
||||||
'_node' => $node->getId(),
|
|
||||||
'_menu' => $menu->getId(),
|
|
||||||
'_page' => $node->getPage() ? $node->getPage()->getId() : null,
|
|
||||||
'_navigation' => $navigation->getId(),
|
|
||||||
];
|
|
||||||
|
|
||||||
$route = new Route($node->getUrl(), $defaults, $requirements);
|
|
||||||
$route->setHost($navigation->getDomain());
|
|
||||||
|
|
||||||
$routes->add($node->getRouteName(), $route);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->isLoaded = true;
|
|
||||||
|
|
||||||
return $routes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function supports($resource, string $type = null)
|
|
||||||
{
|
|
||||||
return 'extra' === $type;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Security;
|
|
||||||
|
|
||||||
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
|
|
||||||
|
|
||||||
class TokenGenerator implements TokenGeneratorInterface
|
|
||||||
{
|
|
||||||
public function generateToken(): string
|
|
||||||
{
|
|
||||||
return rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Site;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class PageConfiguration.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class PageConfiguration
|
|
||||||
{
|
|
||||||
protected string $className;
|
|
||||||
protected string $name;
|
|
||||||
protected array $templates;
|
|
||||||
|
|
||||||
public function setClassName(string $className): self
|
|
||||||
{
|
|
||||||
$this->className = $className;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getClassName(): string
|
|
||||||
{
|
|
||||||
return $this->className;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setName(string $name): self
|
|
||||||
{
|
|
||||||
$this->name = $name;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName(): string
|
|
||||||
{
|
|
||||||
return $this->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTemplates(array $templates): self
|
|
||||||
{
|
|
||||||
$this->templates = $templates;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTemplates(): array
|
|
||||||
{
|
|
||||||
return $this->templates;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Site;
|
|
||||||
|
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class PageLocator.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class PageLocator
|
|
||||||
{
|
|
||||||
protected array $params;
|
|
||||||
protected array $pages;
|
|
||||||
|
|
||||||
public function __construct(ParameterBagInterface $bag)
|
|
||||||
{
|
|
||||||
$this->params = $bag->get('app');
|
|
||||||
$this->loadPages();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPages(): array
|
|
||||||
{
|
|
||||||
return $this->pages;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPage($className)
|
|
||||||
{
|
|
||||||
return $this->pages[$className] ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function loadPages(): void
|
|
||||||
{
|
|
||||||
$params = $this->params['site']['pages'] ?? [];
|
|
||||||
|
|
||||||
foreach ($params as $className => $conf) {
|
|
||||||
$pageConfiguration = new PageConfiguration();
|
|
||||||
$pageConfiguration
|
|
||||||
->setClassName($className)
|
|
||||||
->setName($conf['name'])
|
|
||||||
->setTemplates($conf['templates'])
|
|
||||||
;
|
|
||||||
|
|
||||||
$this->pages[$className] = $pageConfiguration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Site;
|
|
||||||
|
|
||||||
use App\Entity\Site\Menu;
|
|
||||||
use App\Entity\Site\Navigation;
|
|
||||||
use App\Entity\Site\Node;
|
|
||||||
use App\Entity\Site\Page\Page;
|
|
||||||
use App\Repository\Site\NavigationRepositoryQuery;
|
|
||||||
use App\Repository\Site\NodeRepository;
|
|
||||||
use App\Repository\Site\Page\PageRepositoryQuery;
|
|
||||||
use Symfony\Component\HttpFoundation\RequestStack;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class SiteRequest.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class SiteRequest
|
|
||||||
{
|
|
||||||
protected RequestStack $requestStack;
|
|
||||||
protected NodeRepository $nodeRepository;
|
|
||||||
protected NavigationRepositoryQuery $navigationRepositoryQuery;
|
|
||||||
protected PageRepositoryQuery $pageRepositoryQuery;
|
|
||||||
|
|
||||||
public function __construct(RequestStack $requestStack, NodeRepository $nodeRepository)
|
|
||||||
{
|
|
||||||
$this->requestStack = $requestStack;
|
|
||||||
$this->nodeRepository = $nodeRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getNode(): ?Node
|
|
||||||
{
|
|
||||||
$request = $this->requestStack->getCurrentRequest();
|
|
||||||
|
|
||||||
if ($request->attributes->has('_node')) {
|
|
||||||
return $this->nodeRepository->findOneBy([
|
|
||||||
'id' => $request->attributes->get('_node'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPage(): ?Page
|
|
||||||
{
|
|
||||||
$node = $this->getNode();
|
|
||||||
|
|
||||||
if ($node && $node->getPage()) {
|
|
||||||
return $node->getPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMenu(): ?Menu
|
|
||||||
{
|
|
||||||
$node = $this->getNode();
|
|
||||||
|
|
||||||
return null !== $node ? $node->getMenu() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getNavigation(): ?Navigation
|
|
||||||
{
|
|
||||||
$menu = $this->getMenu();
|
|
||||||
|
|
||||||
return null !== $menu ? $menu->getNavigation() : null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Slugify;
|
|
||||||
|
|
||||||
use Cocur\Slugify\Slugify as BaseSlugify;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class CodeSlugify.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class CodeSlugify extends Slugify
|
|
||||||
{
|
|
||||||
protected function create(): BaseSlugify
|
|
||||||
{
|
|
||||||
$slugify = new BaseSlugify([
|
|
||||||
'separator' => '_',
|
|
||||||
'lowercase' => true,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$slugify->activateRuleSet('french');
|
|
||||||
$slugify->addRule("'", '');
|
|
||||||
|
|
||||||
return $slugify;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Slugify;
|
|
||||||
|
|
||||||
use Cocur\Slugify\Slugify as BaseSlugify;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class Slugify.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class Slugify
|
|
||||||
{
|
|
||||||
public function slugify($data)
|
|
||||||
{
|
|
||||||
return $this->create()->slugify($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function create(): BaseSlugify
|
|
||||||
{
|
|
||||||
$slugify = new BaseSlugify([
|
|
||||||
'separator' => '-',
|
|
||||||
'lowercase' => true,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$slugify->activateRuleSet('french');
|
|
||||||
$slugify->addRule("'", '');
|
|
||||||
|
|
||||||
return $slugify;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -48,37 +48,5 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12">
|
|
||||||
<table class="table">
|
|
||||||
<thead class="thead-light">
|
|
||||||
<tr>
|
|
||||||
<th>Derniers articles</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for item in posts %}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a href="{{ path('admin_blog_post_show', {entity: item.id}) }}" class="text-body">
|
|
||||||
{{ item.title }}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% else %}
|
|
||||||
<tr>
|
|
||||||
<td class="text-center p-4 text-black-50">
|
|
||||||
<div class="display-1">
|
|
||||||
<span class="fa fa-search"></span>
|
|
||||||
</div>
|
|
||||||
<div class="display-5 mt-3">
|
|
||||||
Aucun résultat
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
Loading…
Reference in a new issue