This commit is contained in:
2024-11-26 20:42:13 +01:00
parent 60d8b8bd1d
commit 855570b685
27 changed files with 1590 additions and 108 deletions

View File

@ -7,13 +7,10 @@ use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasher;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
#[AsCommand(
@ -26,7 +23,7 @@ class InitCommand extends Command
private ParameterBagInterface $params;
private UserPasswordHasherInterface $passwordHasher;
public function __construct(EntityManagerInterface $em,ParameterBagInterface $params,UserPasswordHasherInterface $passwordHasher)
public function __construct(EntityManagerInterface $em, ParameterBagInterface $params, UserPasswordHasherInterface $passwordHasher)
{
$this->em = $em;
$this->params = $params;
@ -38,38 +35,41 @@ class InitCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$io->title("APP:INIT");
$io->text("Initialisation of the app");
$io->text("");
$io->title('APP:INIT');
$io->text('Initialisation of the app');
$io->text('');
// Création du compte admin
$io->text("> Création du compte admin");
$user = $this->em->getRepository("App\Entity\User")->findOneBy(["username"=>"admin"]);
if(!$user) {
$user=new User;
$io->text('> Création du compte admin');
$user = $this->em->getRepository("App\Entity\User")->findOneBy(['username' => 'admin']);
if (!$user) {
$user = new User();
$hashedPassword = $this->passwordHasher->hashPassword(
$user,
$this->params->get("appSecret")
$this->params->get('appSecret')
);
$user->setUsername("admin");
$user->setUsername('admin');
$user->setPassword($hashedPassword);
$user->setAvatar('medias/avatar/admin.jpg');
$user->setEmail($this->params->get('appNoreply'));
$this->em->persist($user);
}
$user->setRoles(["ROLE_ADMIN"]);
$user->setRoles(['ROLE_ADMIN']);
$this->em->flush();
// Création d'un company par defaut
$io->text("> Création d'un company par defaut");
$nbcompanys = $this->em->getRepository("App\Entity\Company")->count([]);
if($nbcompanys==0) {
$company=new Company;
$company->setTitle($this->params->get("appName"));
$company->setLogo("logo.png");
if (0 == $nbcompanys) {
$company = new Company();
$company->setTitle($this->params->get('appName'));
$company->setLogo('logo.png');
$this->em->persist($company);
$this->em->flush();
$this->em->flush();
}
return Command::SUCCESS;
}
}

View File

@ -14,7 +14,7 @@ class HomeController extends AbstractController
return $this->render('home/home.html.twig', [
'usemenu' => true,
'usesidebar' => false,
]);
]);
}
#[Route('/admin', name: 'app_admin')]
@ -23,6 +23,6 @@ class HomeController extends AbstractController
return $this->render('home/home.html.twig', [
'usemenu' => true,
'usesidebar' => true,
]);
}
]);
}
}

View File

@ -2,44 +2,107 @@
namespace App\Controller;
use App\Entity\User;
use App\Form\UserType;
use App\Repository\UserRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Attribute\Route;
class UserController extends AbstractController
{
#[Route('/admin/user', name: 'app_admin_user')]
public function list(): Response
public function list(UserRepository $userRepository): Response
{
$users = $userRepository->findAll();
return $this->render('user/list.html.twig', [
'usemenu' => true,
'usesidebar' => true,
'title' => 'Liste des Utilisateurs',
'routesubmit' => 'app_admin_user_submit',
'routeupdate' => 'app_admin_user_update',
'users' => $users,
]);
}
#[Route('/admin/user', name: 'app_admin_user_submit')]
public function submit(): Response
#[Route('/admin/user/submit', name: 'app_admin_user_submit')]
public function submit(Request $request, UserPasswordHasherInterface $passwordHasher, EntityManagerInterface $em): Response
{
$user = new User();
$form = $this->createForm(UserType::class, $user, ['mode' => 'submit']);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user = $form->getData();
$hashedPassword = $passwordHasher->hashPassword(
$user,
$user->getPassword()
);
$user->setPassword($hashedPassword);
$em->persist($user);
$em->flush();
return $this->redirectToRoute('app_admin_user');
}
return $this->render('user/edit.html.twig', [
'usemenu' => true,
'usesidebar' => true,
'title' => 'Création Utilisateur',
'routecancel' => 'app_admin_user',
'routedelete' => 'app_admin_user_delete',
'mode' => 'submit',
'form' => $form,
]);
}
#[Route('/admin/user/update', name: 'app_admin_user_update')]
public function update(): Response
#[Route('/admin/user/update/{id}', name: 'app_admin_user_update')]
public function update(int $id, Request $request, UserPasswordHasherInterface $passwordHasher, EntityManagerInterface $em): Response
{
$user = $em->getRepository(User::class)->find($id);
if (!$user) {
return $this->redirectToRoute('app_admin_user');
}
$form = $this->createForm(UserType::class, $user, ['mode' => 'update']);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user = $form->getData();
$hashedPassword = $passwordHasher->hashPassword(
$user,
$user->getPassword()
);
$user->setPassword($hashedPassword);
$em->persist($user);
$em->flush();
return $this->redirectToRoute('app_admin_user');
}
return $this->render('user/edit.html.twig', [
'usemenu' => true,
'usesidebar' => true,
'title' => 'Création Utilisateur',
'routecancel' => 'app_admin_user',
'routedelete' => 'app_admin_user_delete',
'mode' => 'update',
'form' => $form,
]);
}
#[Route('/admin/user/delete', name: 'app_admin_user_delete')]
public function delete(): Response
{
}
#[Route('/user', name: 'app_user_profil')]
public function profil(): Response
{
}
}

View File

@ -6,8 +6,11 @@ use App\Repository\AccountingRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
#[ORM\Entity(repositoryClass: AccountingRepository::class)]
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_ACCOUNTING', fields: ['num01', 'num02'])]
#[UniqueEntity(fields: ['num01', 'num02'], message: 'Ce numéro de compte est déjà utilisé.')]
class Accounting
{
#[ORM\Id]

View File

@ -7,8 +7,11 @@ use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
#[ORM\Entity(repositoryClass: CompanyRepository::class)]
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_COMPANY', fields: ['title'])]
#[UniqueEntity(fields: ['email'], message: 'Ce nom de companie est déjà utilisé.')]
class Company
{
#[ORM\Id]
@ -16,7 +19,7 @@ class Company
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
#[ORM\Column(length: 255, unique: true)]
private ?string $title = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
@ -260,5 +263,4 @@ class Company
return $this;
}
}

View File

@ -95,5 +95,4 @@ class Operation
return $this;
}
}

View File

@ -6,11 +6,16 @@ use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity(repositoryClass: UserRepository::class)]
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_USERNAME', fields: ['username'])]
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_EMAIL', fields: ['email'])]
#[UniqueEntity(fields: ['email'], message: 'Cet email est déjà utilisé.')]
#[UniqueEntity(fields: ['username'], message: 'Ce nom dutilisateur est déjà pris.')]
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
#[ORM\Id]
@ -18,24 +23,26 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 180)]
#[ORM\Column(length: 180, unique: true)]
private ?string $username = null;
/**
* @var list<string> The user roles
*/
#[ORM\Column]
private array $roles = [];
/**
* @var string The hashed password
*/
#[ORM\Column]
#[Assert\Regex(
pattern: '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\W).{8,}$/',
message: 'Le mot de passe doit contenir au moins 8 caractères, une lettre majuscule, une lettre minuscule et un caractère spécial.'
)]
private ?string $password = null;
/**
* @var Collection<int, Company>
*/
#[ORM\Column(length: 255, nullable: true)]
private ?string $avatar = null;
#[ORM\Column(length: 255, unique: true)]
#[Assert\Email(message: 'Veuillez entrer un email valide.')]
private ?string $email = null;
#[ORM\ManyToMany(targetEntity: Company::class, inversedBy: 'users')]
private Collection $companys;
@ -119,6 +126,30 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
// $this->plainPassword = null;
}
public function getAvatar(): ?string
{
return $this->avatar ? $this->avatar : 'medias/avatar/noavatar.png';
}
public function setAvatar(?string $avatar): static
{
$this->avatar = $avatar;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): static
{
$this->email = $email;
return $this;
}
/**
* @return Collection<int, Company>
*/

View File

@ -6,7 +6,6 @@ use App\Entity\Accounting;
use App\Entity\Company;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\PostPersistEventArgs;
use Doctrine\ORM\Events;
class CompanySubscriber
{
@ -16,7 +15,7 @@ class CompanySubscriber
{
$this->em = $em;
}
public function postPersist(PostPersistEventArgs $args): void
{
$company = $args->getObject();
@ -27,19 +26,19 @@ class CompanySubscriber
$entityManager = $args->getObjectManager();
// Génération des accounting par défaut
$this->insertAccounting($company,"512","000","Banque","actif","fa-building-columns");
$this->insertAccounting($company,"530","000","Caisse","actif","fa-piggy-bank");
$this->insertAccounting($company,"600","000","Charge","charge",null);
$this->insertAccounting($company,"700","000","Produit","produit",null);
$this->insertAccounting($company, '512', '000', 'Banque', 'actif', 'fa-building-columns');
$this->insertAccounting($company, '530', '000', 'Caisse', 'actif', 'fa-piggy-bank');
$this->insertAccounting($company, '600', '000', 'Charge', 'charge', null);
$this->insertAccounting($company, '700', '000', 'Produit', 'produit', null);
// Génération du year par
}
private function insertAccounting(Company $company,string $num01, string $num02, string $title, string $category, ?string $icon): void
private function insertAccounting(Company $company, string $num01, string $num02, string $title, string $category, ?string $icon): void
{
$accounting=$this->em->getRepository("App\Entity\Accounting")->findOneBy(["company"=>$company,"num01"=>$num01,"num02"=>$num02]);
if(!$accounting) {
$accounting = new Accounting;
$accounting = $this->em->getRepository("App\Entity\Accounting")->findOneBy(['company' => $company, 'num01' => $num01, 'num02' => $num02]);
if (!$accounting) {
$accounting = new Accounting();
$accounting->setCompany($company);
$accounting->setNum01($num01);
$accounting->setNum02($num02);
@ -48,7 +47,5 @@ class CompanySubscriber
$this->em->persist($accounting);
$this->em->flush();
}
}
}
}

67
src/Form/UserType.php Normal file
View File

@ -0,0 +1,67 @@
<?php
namespace App\Form;
use App\Entity\Company;
use App\Entity\User;
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\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('submit', SubmitType::class, [
'label' => 'Valider',
'attr' => ['class' => 'btn btn-success no-print'],
])
->add('username', TextType::class, [
'label' => 'Login',
])
->add('roles', ChoiceType::class, [
'choices' => ['ROLE_ADMIN' => 'ROLE_ADMIN', 'ROLE_USER' => 'ROLE_USER'],
'multiple' => true,
'expanded' => true,
])
->add('password', RepeatedType::class, [
'type' => PasswordType::class,
'required' => ('submit' == $options['mode'] ? true : false),
'options' => ['always_empty' => true],
'first_options' => ['label' => 'Mot de Passe', 'attr' => ['class' => 'form-control', 'style' => 'margin-bottom:15px', 'autocomplete' => 'new-password']],
'second_options' => ['label' => 'Confirmer Mot de Passe', 'attr' => ['class' => 'form-control', 'style' => 'margin-bottom:15px']],
])
->add('avatar')
->add('email', EmailType::class, [
'label' => 'Email',
])
->add('companys', EntityType::class, [
'class' => Company::class,
'choice_label' => 'id',
'multiple' => true,
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => User::class,
'mode' => 'submit',
]);
}
}

View File

@ -16,28 +16,28 @@ class AccountingRepository extends ServiceEntityRepository
parent::__construct($registry, Accounting::class);
}
// /**
// * @return Accounting[] Returns an array of Accounting objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('a')
// ->andWhere('a.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('a.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// /**
// * @return Accounting[] Returns an array of Accounting objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('a')
// ->andWhere('a.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('a.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?Accounting
// {
// return $this->createQueryBuilder('a')
// ->andWhere('a.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
// public function findOneBySomeField($value): ?Accounting
// {
// return $this->createQueryBuilder('a')
// ->andWhere('a.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

View File

@ -16,28 +16,28 @@ class OperationRepository extends ServiceEntityRepository
parent::__construct($registry, Operation::class);
}
// /**
// * @return Operation[] Returns an array of Operation objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('o')
// ->andWhere('o.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('o.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// /**
// * @return Operation[] Returns an array of Operation objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('o')
// ->andWhere('o.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('o.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?Operation
// {
// return $this->createQueryBuilder('o')
// ->andWhere('o.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
// public function findOneBySomeField($value): ?Operation
// {
// return $this->createQueryBuilder('o')
// ->andWhere('o.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}