Parcourir la source

Création Lc/AdminBundle - premier commit

master
Fab il y a 3 ans
révision
e3513152e4
38 fichiers modifiés avec 1454 ajouts et 0 suppressions
  1. +106
    -0
      Authenticator/LoginFormAuthenticator.php
  2. +125
    -0
      Command/CreateUserCommand.php
  3. +0
    -0
      Controller/.gitignore
  4. +22
    -0
      Controller/Admin/AbstractCrudController.php
  5. +60
    -0
      Controller/Admin/DashboardController.php
  6. +38
    -0
      Controller/Admin/PageCrudController.php???
  7. +72
    -0
      Controller/Admin/SecurityController.php
  8. +24
    -0
      DependencyInjection/LcAdminExtension.php
  9. +30
    -0
      Event/EntityManager/EntityManagerEvent.php
  10. +9
    -0
      IModel/Cms/BlameableInterface.php
  11. +8
    -0
      IModel/Cms/DevAliasInterface.php
  12. +11
    -0
      IModel/Cms/ImageInterface.php
  13. +10
    -0
      IModel/Cms/SeoInterface.php
  14. +8
    -0
      IModel/Cms/SluggableInterface.php
  15. +8
    -0
      IModel/Cms/SortableInterface.php
  16. +8
    -0
      IModel/Cms/StatusInterface.php
  17. +9
    -0
      IModel/Cms/TimestampableInterface.php
  18. +22
    -0
      IModel/Cms/TreeInterface.php
  19. +7
    -0
      IModel/EntityInterface.php
  20. +8
    -0
      IModel/User/UserInterface.php
  21. +15
    -0
      LcAdminBundle.php
  22. +90
    -0
      Manager/EntityManager.php
  23. +66
    -0
      Model/Cms/AbstractDocument.php
  24. +51
    -0
      Model/Cms/BlameableTrait.php
  25. +27
    -0
      Model/Cms/DevAliasTrait.php
  26. +52
    -0
      Model/Cms/ImageTrait.php
  27. +63
    -0
      Model/Cms/SeoTrait.php
  28. +27
    -0
      Model/Cms/SluggableTrait.php
  29. +34
    -0
      Model/Cms/SortableTrait.php
  30. +25
    -0
      Model/Cms/StatusTrait.php
  31. +46
    -0
      Model/Cms/TimestampableTrait.php
  32. +11
    -0
      Model/Cms/TreeTrait.php
  33. +155
    -0
      Model/User/User.php
  34. +10
    -0
      README.md
  35. +0
    -0
      Repository/.gitignore
  36. +114
    -0
      Repository/BaseRepository.php
  37. +15
    -0
      Repository/BaseRepositoryInterface.php
  38. +68
    -0
      Repository/User/UserRepository.php

+ 106
- 0
Authenticator/LoginFormAuthenticator.php Voir le fichier

@@ -0,0 +1,106 @@
<?php

namespace Lc\AdminBundle\Authenticator;

use Lc\AdminBundle\IModel\User\UserInterface;
use Lc\AdminBundle\Manager\EntityManager;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\User\UserInterface as SfUserInterface;
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\UserProviderInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface;
use Symfony\Component\Security\Http\Util\TargetPathTrait;

class LoginFormAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface
{
use TargetPathTrait;

public const LOGIN_ROUTE = 'login';

private $entityManager;
private $urlGenerator;
private $csrfTokenManager;
private $passwordEncoder;

public function __construct(EntityManager $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 self::LOGIN_ROUTE === $request->attributes->get('_route')
&& $request->isMethod('POST');
}

public function getCredentials(Request $request)
{
$credentials = [
'email' => $request->request->get('email'),
'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(UserInterface::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, SfUserInterface $user)
{
return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
}

/**
* Used to upgrade (rehash) the user's password automatically over time.
*/
public function getPassword($credentials): ?string
{
return $credentials['password'];
}

public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
{
if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
return new RedirectResponse($targetPath);
}

return new RedirectResponse($this->urlGenerator->generate('lc_admin_dashboard'));
}

protected function getLoginUrl()
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}

+ 125
- 0
Command/CreateUserCommand.php Voir le fichier

@@ -0,0 +1,125 @@
<?php

namespace Lc\AdminBundle\Command;


use Lc\AdminBundle\IModel\User\UserInterface;
use Lc\AdminBundle\Manager\EntityManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class CreateUserCommand extends Command
{
private $passwordEncoder;
private $em;

public function __construct(UserPasswordEncoderInterface $passwordEncoder, EntityManager $entityManager)
{
parent::__construct();

$this->passwordEncoder = $passwordEncoder;
$this->em = $entityManager;
}

/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('user:create')
->setDescription('Create a user.')
->setDefinition(array(
new InputArgument('email', InputArgument::REQUIRED, 'The email'),
new InputArgument('password', InputArgument::REQUIRED, 'The password'),
new InputArgument('role', InputArgument::REQUIRED, 'ROLE'),
))
->setHelp('');
}

/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{

$email = $input->getArgument('email');
$password = $input->getArgument('password');
$role = $input->getArgument('role');

$user = $this->em->new(UserInterface::class);
$user->setEmail($email);
$user->setRoles(array($role));

$password = $this->passwordEncoder->encodePassword($user, $password);

$user->setPassword($password);

$this->em->create($user);
$this->em->flush();

$output->writeln(sprintf('Created user <comment>%s</comment>', $email));
return Command::SUCCESS;
}

/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$questions = array();

if (!$input->getArgument('email')) {
$question = new Question('Email : ');
$question->setValidator(function ($password) {
if (empty($password)) {
throw new \Exception('Email can not be empty');
}

return $password;
});
$questions['email'] = $question;
}

if (!$input->getArgument('password')) {
$question = new Question('Password : ');
$question->setValidator(function ($password) {
if (empty($password)) {
throw new \Exception('Password can not be empty');
}

return $password;
});
$question->setHidden(true);
$questions['password'] = $question;
}

if (!$input->getArgument('role')) {
$question = new Question('Rôle [admin/superadmin/user] : ');
$question->setValidator(function ($role) {
if ($role == 'admin') {
$role = 'ROLE_ADMIN';
} else if ($role == 'superadmin') {
$role = 'ROLE_SUPER_ADMIN';
} else if ($role == 'user') {
$role = 'ROLE_USER';
} else {
throw new \Exception('Choose a role');

}
return $role;
});
$questions['role'] = $question;
}


foreach ($questions as $name => $question) {
$answer = $this->getHelper('question')->ask($input, $output, $question);
$input->setArgument($name, $answer);
}
}
}

+ 0
- 0
Controller/.gitignore Voir le fichier


+ 22
- 0
Controller/Admin/AbstractCrudController.php Voir le fichier

@@ -0,0 +1,22 @@
<?php

namespace Lc\AdminBundle\Controller\Admin;

use App\Entity\Page;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController as EaAbstractCrudController;

abstract class AbstractCrudController extends EaAbstractCrudController
{

/*
public function configureFields(string $pageName): iterable
{
return [
IdField::new('id'),
TextField::new('title'),
TextEditorField::new('description'),
];
}
*/
}

+ 60
- 0
Controller/Admin/DashboardController.php Voir le fichier

@@ -0,0 +1,60 @@
<?php

namespace Lc\AdminBundle\Controller\Admin;

use App\Entity\Page;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class DashboardController extends AbstractDashboardController
{

public function index(): Response
{
return parent::index();
}

public function configureDashboard(): Dashboard
{
return Dashboard::new()
// the name visible to end users
->setTitle('LA CLIC !')
// you can include HTML contents too (e.g. to link to an image)
->setTitle('<img src="assets/img/laclic.png" width="100px">')
// the path defined in this method is passed to the Twig asset() function
->setFaviconPath('favicon.svg')
// the domain used by default is 'messages'
->setTranslationDomain('lcadmin');
}

public function configureCrud(): Crud
{
$crud = Crud::new();
return $crud
->addFormTheme('@FOSCKEditor/Form/ckeditor_widget.html.twig');
}

public function configureMenuItems(): iterable
{
return [
MenuItem::linkToDashboard('Tableau de bord', 'fa fa-home'),
MenuItem::linkToCrud('Pages', 'fa fa-tags', Page::class),


/*
MenuItem::section('Blog'),
MenuItem::linkToCrud('Categories', 'fa fa-tags', Category::class),
MenuItem::linkToCrud('Blog Posts', 'fa fa-file-text', BlogPost::class),

MenuItem::section('Users'),
MenuItem::linkToCrud('Comments', 'fa fa-comment', Comment::class),
MenuItem::linkToCrud('Users', 'fa fa-user', User::class),*/

//MenuItem::linkToLogout('Déconnexion', 'fa fa-exit'),
];
}
}

+ 38
- 0
Controller/Admin/PageCrudController.php??? Voir le fichier

@@ -0,0 +1,38 @@
<?php

namespace App\Controller\Admin;

use App\Entity\Page;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ImageField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;

class PageCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Page::class;
}


public function configureFields(string $pageName): iterable
{
return [
TextField::new('title'),
TextEditorField::new('description'),
ImageField::new('image')
->setBasePath('/uploads/')
->setUploadDir('public/uploads/'),
TextField::new('devAlias'),
ChoiceField::new('status')
->setChoices(['En ligne'=> 1, 'Hors ligne'=>0])
->setFormTypeOption('expanded', true)
->setFormTypeOption('multiple', false)
->setCustomOption('widget', false)
];
}

}

+ 72
- 0
Controller/Admin/SecurityController.php Voir le fichier

@@ -0,0 +1,72 @@
<?php

namespace Lc\AdminBundle\Controller\Admin;


use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;

class SecurityController extends AbstractController
{

public function login(AuthenticationUtils $authenticationUtils): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('lc_');
}

// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();

return $this->render('@EasyAdmin/page/login.html.twig', [
// parameters usually defined in Symfony login forms
'error' => $error,
'last_username' => $lastUsername,

// OPTIONAL parameters to customize the login form:

// the translation_domain to use (define this option only if you are
// rendering the login template in a regular Symfony controller; when
// rendering it from an EasyAdmin Dashboard this is automatically set to
// the same domain as the rest of the Dashboard)
'translation_domain' => 'admin',

// the title visible above the login form (define this option only if you are
// rendering the login template in a regular Symfony controller; when rendering
// it from an EasyAdmin Dashboard this is automatically set as the Dashboard title)
'page_title' => '<img src="assets/img/laclic.png" >',

// the string used to generate the CSRF token. If you don't define
// this parameter, the login form won't include a CSRF token
'csrf_token_intention' => 'authenticate',

// the URL users are redirected to after the login (default: '/admin')
'target_path' => $this->generateUrl('lc_admin_dashboard'),

// the label displayed for the username form field (the |trans filter is applied to it)
'username_label' => 'Your username',

// the label displayed for the password form field (the |trans filter is applied to it)
'password_label' => 'Your password',

// the label displayed for the Sign In form button (the |trans filter is applied to it)
'sign_in_label' => 'Log in',

// the 'name' HTML attribute of the <input> used for the username field (default: '_username')
'username_parameter' => 'email',

// the 'name' HTML attribute of the <input> used for the password field (default: '_password')
'password_parameter' => 'password',
]);
}


public function logout()
{
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
}

+ 24
- 0
DependencyInjection/LcAdminExtension.php Voir le fichier

@@ -0,0 +1,24 @@
<?php

namespace Lc\AdminBundle\DependencyInjection;

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

class LcAdminExtension extends Extension implements PrependExtensionInterface
{
public function load(array $configs, ContainerBuilder $container)
{

}

public function prepend(ContainerBuilder $container)
{
/*$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config/easy_admin'));
$loader->load('base.yaml');
$loader->load('entities/merchant.yaml');*/
}
}

+ 30
- 0
Event/EntityManager/EntityManagerEvent.php Voir le fichier

@@ -0,0 +1,30 @@
<?php

namespace Lc\AdminBundle\Event\EntityManager;

use Lc\AdminBundle\IModel\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';

protected EntityInterface $entity;

public function __construct(EntityInterface $entity)
{
$this->entity = $entity;
}

public function getEntity(): EntityInterface
{
return $this->entity;
}
}

+ 9
- 0
IModel/Cms/BlameableInterface.php Voir le fichier

@@ -0,0 +1,9 @@
<?php

namespace Lc\AdminBundle\IModel\Cms;

interface BlameableInterface
{

}

+ 8
- 0
IModel/Cms/DevAliasInterface.php Voir le fichier

@@ -0,0 +1,8 @@
<?php

namespace Lc\AdminBundle\IModel\Cms;

interface DevAliasInterface
{

}

+ 11
- 0
IModel/Cms/ImageInterface.php Voir le fichier

@@ -0,0 +1,11 @@
<?php

namespace Lc\AdminBundle\IModel\Cms;


interface ImageInterface
{



}

+ 10
- 0
IModel/Cms/SeoInterface.php Voir le fichier

@@ -0,0 +1,10 @@
<?php

namespace Lc\AdminBundle\IModel\Cms;

interface SeoInterface
{



}

+ 8
- 0
IModel/Cms/SluggableInterface.php Voir le fichier

@@ -0,0 +1,8 @@
<?php

namespace Lc\AdminBundle\IModel\Cms;

interface SluggableInterface
{

}

+ 8
- 0
IModel/Cms/SortableInterface.php Voir le fichier

@@ -0,0 +1,8 @@
<?php

namespace Lc\AdminBundle\IModel\Cms;

interface SortableInterface
{

}

+ 8
- 0
IModel/Cms/StatusInterface.php Voir le fichier

@@ -0,0 +1,8 @@
<?php

namespace Lc\AdminBundle\IModel\Cms;

interface StatusInterface
{

}

+ 9
- 0
IModel/Cms/TimestampableInterface.php Voir le fichier

@@ -0,0 +1,9 @@
<?php

namespace Lc\AdminBundle\IModel\Cms;

interface TimestampableInterface
{


}

+ 22
- 0
IModel/Cms/TreeInterface.php Voir le fichier

@@ -0,0 +1,22 @@
<?php

namespace Lc\AdminBundle\IModel\Cms;

interface TreeInterface
{
/**
* Retourne le parent d'une entité
*
* @return entity
*/
public function getParent();


/**
* Retourne les enfants d'une entité
*
* @return entity
*/

public function getChildrens();
}

+ 7
- 0
IModel/EntityInterface.php Voir le fichier

@@ -0,0 +1,7 @@
<?php

namespace Lc\AdminBundle\IModel;

interface EntityInterface
{
}

+ 8
- 0
IModel/User/UserInterface.php Voir le fichier

@@ -0,0 +1,8 @@
<?php

namespace Lc\AdminBundle\IModel\User;

interface UserInterface
{

}

+ 15
- 0
LcAdminBundle.php Voir le fichier

@@ -0,0 +1,15 @@
<?php

namespace Lc\AdminBundle;

use Lc\AdminBundle\DependencyInjection\LcAdminExtension;
use Symfony\Component\HttpKernel\Bundle\Bundle;


class LcAdminBundle extends Bundle
{
public function getContainerExtension()
{
return new LcAdminExtension();
}
}

+ 90
- 0
Manager/EntityManager.php Voir le fichier

@@ -0,0 +1,90 @@
<?php

namespace Lc\AdminBundle\Manager;

use Doctrine\ORM\EntityManager as DoctrineEntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Lc\AdminBundle\Event\EntityManager\EntityManagerEvent;
use Lc\AdminBundle\IModel\EntityInterface;
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 getRepository($className)
{
return $this->entityManager->getRepository($this->getEntityName($className));
}

public function new($className)
{
return new $this->getEntityName($className);
}

public function create(EntityInterface $entity): self
{
$this->persist($entity);
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::CREATE_EVENT);

return $this;
}

public function update(EntityInterface $entity): self
{
$this->persist($entity);
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::UPDATE_EVENT);

return $this;
}

public function delete(EntityInterface $entity): self
{
$this->remove($entity);
$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;
}

protected function persist(EntityInterface $entity)
{
$this->entityManager->persist($entity);
}

public function getEntityName($className)
{
if (substr($className, -9) === 'Interface') {
return $this->entityManager->getClassMetadata($className)->getName();
}else{
return $className;
}

}
}

+ 66
- 0
Model/Cms/AbstractDocument.php Voir le fichier

@@ -0,0 +1,66 @@
<?php

namespace Lc\AdminBundle\Model\Cms;

use Lc\AdminBundle\IModel\Cms\BlameableInterface;
use Lc\AdminBundle\IModel\Cms\DevAliasInterface;
use Lc\AdminBundle\IModel\Cms\SeoInterface;
use Lc\AdminBundle\IModel\Cms\SluggableInterface;
use Lc\AdminBundle\IModel\Cms\SortableInterface;
use Lc\AdminBundle\IModel\Cms\TimestampableInterface;
use Lc\AdminBundle\IModel\Cms\StatusInterface;
use Doctrine\ORM\Mapping as ORM;
use Lc\AdminBundle\IModel\EntityInterface;

/**
* @ORM\MappedSuperclass
*/
abstract class AbstractDocument implements BlameableInterface, SeoInterface, SluggableInterface, SortableInterface, StatusInterface, TimestampableInterface, DevAliasInterface, EntityInterface
{

use BlameableTrait;
use SeoTrait;
use SluggableTrait;
use SortableTrait;
use StatusTrait;
use TimestampableTrait;
use DevAliasTrait;

/**
* @ORM\Column(type="string", length=255)
*/
protected $title;

/**
* @ORM\Column(type="text", nullable=true)
*/
protected $description;


public function getTitle(): ?string
{
return $this->title;
}

public function setTitle(string $title): self
{
$this->title = $title;

return $this;
}


public function getDescription(): ?string
{
return $this->description;
}

public function setDescription(?string $description): self
{
$this->description = $description;

return $this;
}


}

+ 51
- 0
Model/Cms/BlameableTrait.php Voir le fichier

@@ -0,0 +1,51 @@
<?php

namespace Lc\AdminBundle\Model\Cms;

use App\IModel\UserInterface;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

trait BlameableTrait
{

/**
* @Gedmo\Blameable(on="create")
* @ORM\ManyToOne(targetEntity="App\Entity\User")
* @ORM\JoinColumn(nullable=false)
*/
protected $createdBy;

/**
* @Gedmo\Blameable(on="update")
* @ORM\ManyToOne(targetEntity="App\Entity\User")
* @ORM\JoinColumn(nullable=false)
*/
protected $updatedBy;


public function getCreatedBy(): ?UserInterface
{
return $this->createdBy;
}

public function setCreatedBy(?UserInterface $createdBy): self
{
$this->createdBy = $createdBy;

return $this;
}

public function getUpdatedBy(): ?UserInterface
{
return $this->updatedBy;
}

public function setUpdatedBy(?UserInterface $updatedBy): self
{
$this->updatedBy = $updatedBy;

return $this;
}

}

+ 27
- 0
Model/Cms/DevAliasTrait.php Voir le fichier

@@ -0,0 +1,27 @@
<?php

namespace Lc\AdminBundle\Model\Cms;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

trait DevAliasTrait
{

/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $devAlias;

public function getDevAlias(): ?string
{
return $this->devAlias;
}

public function setDevAlias(?string $devAlias): self
{
$this->devAlias = $devAlias;

return $this;
}
}

+ 52
- 0
Model/Cms/ImageTrait.php Voir le fichier

@@ -0,0 +1,52 @@
<?php

namespace Lc\AdminBundle\Model\Cms;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;

trait ImageTrait
{
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $image;

/* /**
* @Vich\UploadableField(mapping="images", fileNameProperty="image")
* @var File
*/
//protected $imageFile;*/
/*
public function setImageFile(File $image = null)
{
$this->imageFile = $image;

// VERY IMPORTANT:
// It is required that at least one field changes if you are using Doctrine,
// otherwise the event listeners won't be called and the file is lost
if ($image) {
// if 'updatedAt' is not defined in your entity, use another property
$this->updatedAt = new \DateTime('now');
}
}

public function getImageFile()
{
return $this->imageFile;
}*/

public function getImage(): ?string
{
return $this->image;
}

public function setImage(?string $image): self
{
$this->image = $image;

return $this;
}


}

+ 63
- 0
Model/Cms/SeoTrait.php Voir le fichier

@@ -0,0 +1,63 @@
<?php

namespace Lc\AdminBundle\Model\Cms;

use Doctrine\ORM\Mapping as ORM;

trait SeoTrait
{
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $metaTitle;


/**
* @ORM\Column(type="text", nullable=true)
*/
protected $metaDescription;


/**
* @var array
* @ORM\Column(type="array", nullable=true)
*/
protected $oldUrls;


public function getMetaTitle(): ?string
{
return $this->metaTitle;
}

public function setMetaTitle(?string $metaTitle): self
{
$this->metaTitle = $metaTitle;

return $this;
}

public function getMetaDescription(): ?string
{
return $this->metaDescription;
}

public function setMetaDescription(?string $metaDescription): self
{
$this->metaDescription = $metaDescription;

return $this;
}

public function setOldUrls($oldUrls): self
{
$this->oldUrls = $oldUrls;

return $this;
}

public function getOldUrls(): ?array
{
return $this->oldUrls;
}
}

+ 27
- 0
Model/Cms/SluggableTrait.php Voir le fichier

@@ -0,0 +1,27 @@
<?php

namespace Lc\AdminBundle\Model\Cms;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

trait SluggableTrait
{
/**
* @ORM\Column(type="string", length=255)
* @Gedmo\Slug(fields={"title"})
*/
protected $slug;

public function getSlug(): ?string
{
return $this->slug;
}

public function setSlug(?string $slug): self
{
$this->slug = $slug;

return $this;
}
}

+ 34
- 0
Model/Cms/SortableTrait.php Voir le fichier

@@ -0,0 +1,34 @@
<?php

namespace Lc\AdminBundle\Model\Cms;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;


trait SortableTrait
{
/**
* @var string
* @ORM\Column(type="float")
*/
protected $position = 0;

/**
* @return float
*/
public function getPosition(): float
{
return $this->position;
}

/**
* @param float $position
* @return $this
*/
public function setPosition(float $position): self
{
$this->position = $position;
return $this;
}
}

+ 25
- 0
Model/Cms/StatusTrait.php Voir le fichier

@@ -0,0 +1,25 @@
<?php

namespace Lc\AdminBundle\Model\Cms;

use Doctrine\ORM\Mapping as ORM;

trait StatusTrait
{
/**
* @ORM\Column(type="float")
*/
protected $status;

public function getStatus(): ?float
{
return $this->status;
}

public function setStatus(float $status): self
{
$this->status = $status;

return $this;
}
}

+ 46
- 0
Model/Cms/TimestampableTrait.php Voir le fichier

@@ -0,0 +1,46 @@
<?php

namespace Lc\AdminBundle\Model\Cms;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

trait TimestampableTrait
{
/**
* @ORM\Column(type="datetime")
* @Gedmo\Timestampable(on="create")
*/
protected $createdAt;

/**
* @ORM\Column(type="datetime")
* @Gedmo\Timestampable(on="update")
*/
protected $updatedAt;

public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}

public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;

return $this;
}

public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updatedAt;
}

public function setUpdatedAt(\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;

return $this;
}

}

+ 11
- 0
Model/Cms/TreeTrait.php Voir le fichier

@@ -0,0 +1,11 @@
<?php

namespace Lc\AdminBundle\Model\Cms;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

trait TreeTrait
{

}

+ 155
- 0
Model/User/User.php Voir le fichier

@@ -0,0 +1,155 @@
<?php

namespace Lc\AdminBundle\Model\User;

use Doctrine\ORM\Mapping as ORM;
use Lc\AdminBundle\IModel\EntityInterface;
use Symfony\Component\Security\Core\User\UserInterface;

/**
* @ORM\MappedSuperclass()
*/
abstract class User implements EntityInterface, UserInterface
{
/**
* @ORM\Column(type="string", length=180, unique=true)
*/
protected $email;

/**
* @ORM\Column(type="json")
*/
protected $roles = [];

/**
* @var string The hashed password
* @ORM\Column(type="string")
*/
protected $password;

/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $lastname;

/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $firstname;

/**
* @ORM\Column(type="boolean")
*/
protected $isVerified = false;



public function getEmail(): ?string
{
return $this->email;
}

public function setEmail(string $email): self
{
$this->email = $email;

return $this;
}

/**
* A visual identifier that represents this user.
*
* @see UserInterface
*/
public function getUsername(): string
{
return (string)$this->email;
}

/**
* @see UserInterface
*/
public function getRoles(): array
{
$roles = $this->roles;
// guarantee every user at least has ROLE_USER
$roles[] = 'ROLE_USER';

return array_unique($roles);
}

public function setRoles(array $roles): self
{
$this->roles = $roles;

return $this;
}

/**
* @see UserInterface
*/
public function getPassword(): string
{
return (string)$this->password;
}

public function setPassword(string $password): self
{
$this->password = $password;

return $this;
}

/**
* @see UserIn
*/
public function getSalt()
{
// not needed when using the "bcrypt" algorithm in security.yaml
}

/**
* @see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}

public function getLastname(): ?string
{
return $this->lastname;
}

public function setLastname(?string $lastname): self
{
$this->lastname = $lastname;

return $this;
}

public function getFirstname(): ?string
{
return $this->firstname;
}

public function setFirstname(?string $firstname): self
{
$this->firstname = $firstname;

return $this;
}

public function isVerified(): bool
{
return $this->isVerified;
}

public function setIsVerified(bool $isVerified): self
{
$this->isVerified = $isVerified;

return $this;
}
}

+ 10
- 0
README.md Voir le fichier

@@ -0,0 +1,10 @@
#Laclic LcAdminBundle

Administration basé sur EasyAdmin 3. Développé par <a href="https://www.laclic.fr">la Clic!</a>

Require :

- Symfony > 5.3
- EasyAdmin > 5.3
- FOS/Ckeditor-bundle: "^2.2",


+ 0
- 0
Repository/.gitignore Voir le fichier


+ 114
- 0
Repository/BaseRepository.php Voir le fichier

@@ -0,0 +1,114 @@
<?php

namespace Lc\AdminBundle\Repository;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Lc\AdminBundle\IModel\Cms\StatusInterface;

abstract class BaseRepository extends EntityRepository implements ServiceEntityRepositoryInterface, BaseRepositoryInterface
{
protected $merchantUtils;
protected $utils;


public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($entityManager, $entityManager->getClassMetadata($this->getInterfaceClass()));
}



public function findByTerm($field, $term, $limit=10){
$qb = $this->findByMerchantQuery();

if($this->utils->hasFilterAssociation($field, '_')){
$aliasRelation = $this->utils->getFilterAssociationAlias($field, '_');

$qb->innerJoin('e.'.$aliasRelation, $aliasRelation);
$qb->select($this->utils->getFilterPropertyInit($field));
$qb->groupBy($this->utils->getFilterPropertyInit($field));
$qb->andWhere(
$qb->expr()->like($this->utils->getFilterPropertyInit($field), ':term'));
}else {
$qb->select('e.' . $field);
$qb->groupBy('e.' . $field);
$qb->andWhere(
$qb->expr()->like('e.' . $field, ':term'));
}
$qb->setParameter('term', '%'.$term.'%');
$qb->setMaxResults($limit);

return $qb->getQuery()->getResult();

}




public function findOneByOldUrl($url)
{
$qb = $this->createQueryBuilder('entity')
->where('entity.oldUrls LIKE :oldUrl')
->andWhere('entity.status = 1')
->setParameter(':oldUrl', '%'.$url.'%');

return $qb->getQuery()->getOneOrNullResult();
}

public function findByMerchantQuery() :QueryBuilder
{
return $this->createQueryBuilder('e')
->where('e.merchant = :currentMerchant')
->setParameter('currentMerchant', $this->merchantUtils->getMerchantCurrent()->getId()) ;
}

public function findAll()
{
return $this->findBy(array());
}

public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
{
$className = $this->getClassMetadata()->getName();
$entity = new $className;

if($entity instanceof StatusInterface){
if (!isset($criteria['status'])) $criteria['status'] = 1;
if ($criteria['status'] === false) unset($criteria['status']);
}

return parent::findBy($criteria, $orderBy, $limit, $offset);

}

public function findOneBy(array $criteria, array $orderBy = null)
{

$className = $this->getClassMetadata()->getName();
$entity = new $className;

if($entity instanceof StatusInterface){
if (!isset($criteria['status'])) $criteria['status'] = 1;
if ($criteria['status'] === false) unset($criteria['status']);
}

return parent::findOneBy($criteria, $orderBy);
}

public function findSimilarSlug($merchant){
$qb = $this->createQueryBuilder('entity')
->select('entity.id, COUNT(entity.slug) as niche')
->andWhere('entity.status>=0')
->andWhere('entity.merchant= :merchant')
->setParameter('merchant', $merchant)

->groupBy('entity.slug')
->having('COUNT(entity.slug) >1');

return $qb->getQuery()->getResult();
}

}

+ 15
- 0
Repository/BaseRepositoryInterface.php Voir le fichier

@@ -0,0 +1,15 @@
<?php

namespace Lc\AdminBundle\Repository;


interface BaseRepositoryInterface
{

/**
* Retourne la class ou l'interface correspondant à ce repository
*
* @return string
*/
public function getInterfaceClass();
}

+ 68
- 0
Repository/User/UserRepository.php Voir le fichier

@@ -0,0 +1,68 @@
<?php

namespace Lc\AdminBundle\Repository\User;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Lc\AdminBundle\IModel\User\UserInterface;
use Lc\AdminBundle\Repository\BaseRepository;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
use Symfony\Component\Security\Core\User\UserInterface as SfUserInterface;

/**
* @method UserInterface|null find($id, $lockMode = null, $lockVersion = null)
* @method UserInterface|null findOneBy(array $criteria, array $orderBy = null)
* @method UserInterface[] findAll()
* @method UserInterface[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class UserRepository extends BaseRepository implements PasswordUpgraderInterface
{
public function getInterfaceClass()
{
return UserInterface::class;
}

/**
* Used to upgrade (rehash) the user's password automatically over time.
*/
public function upgradePassword(SfUserInterface $user, string $newEncodedPassword): void
{
if (!$user instanceof SfUserInterface) {
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', \get_class($user)));
}

$user->setPassword($newEncodedPassword);
$this->_em->persist($user);
$this->_em->flush();
}

// /**
// * @return User[] Returns an array of User objects
// */
/*
public function findByExampleField($value)
{
return $this->createQueryBuilder('u')
->andWhere('u.exampleField = :val')
->setParameter('val', $value)
->orderBy('u.id', 'ASC')
->setMaxResults(10)
->getQuery()
->getResult()
;
}
*/

/*
public function findOneBySomeField($value): ?User
{
return $this->createQueryBuilder('u')
->andWhere('u.exampleField = :val')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
*/
}

Chargement…
Annuler
Enregistrer