feat(website): Ajoute l'importation de sites web et supprime options inutiles.

This commit is contained in:
Serreau Jovann
2025-11-12 16:23:40 +01:00
parent 1d4db08c4f
commit c3a1c8143b
8 changed files with 280 additions and 15 deletions

View File

@@ -9,9 +9,13 @@ use App\Entity\EsyWeb\WebsiteDns;
use App\Entity\EsyWeb\WebsiteKey;
use App\Entity\EsyWeb\WebsiteLicense;
use App\Form\Artemis\EsyWeb\DnsType;
use App\Form\Artemis\EsyWeb\WebsiteImportType;
use App\Form\Artemis\EsyWeb\WebsiteType;
use App\Repository\ComputeRepository;
use App\Repository\CustomerRepository;
use App\Repository\EsyWeb\WebsiteRepository;
use App\Repository\EsyWebTutoRepository;
use App\Repository\RevendeurRepository;
use App\Service\Cloudflare\Client;
use App\Service\License\LicenseManager;
use App\Service\Logger\LoggerService;
@@ -72,6 +76,13 @@ class EsyWebController extends AbstractController
$vd = $licenseManager->generateAndSaveLicense($website, 'main_license');
$entityManager->persist($vd);
$websiteKeyFolder = new WebsiteKey();
$websiteKeyFolder->setType("folder");
$websiteKeyFolder->setApiKey($slug->slugify($website->getTitle()));
$websiteKeyFolder->setWebsitre($website);
$entityManager->persist($websiteKeyFolder);
$websiteKeyDatabase = new WebsiteKey();
$websiteKeyDatabase->setType("db_name");
$websiteKeyDatabase->setApiKey($vaultClient->encrypt('website_db', $slug->slugify($website->getTitle())));
@@ -122,7 +133,6 @@ class EsyWebController extends AbstractController
if (is_null($website)) {
return $this->redirectToRoute('artemis_esyweb');
}
if ($request->query->has('idSendDns')) {
$ndd = $entityManager->getRepository(WebsiteDns::class)->find($request->query->get('idSendDns'));
$customer = $website->getCustomer();
@@ -234,6 +244,78 @@ class EsyWebController extends AbstractController
'formDns' => $formDns->createView(),
]);
}
#[Route(path: '/artemis/esyweb/website/import', name: 'artemis_esyweb_import', methods: ['GET', 'POST'], priority: 5)]
public function websiteImport(VaultClient $vaultClient,LicenseManager $licenseManager,Request $request,EntityManagerInterface $entityManager,RevendeurRepository $revendeurRepository,CustomerRepository $customerRepository,ComputeRepository $computeRepository)
{
$website = new Website();
$website->setState("deploy");
$website->setUuid(Uuid::v4());
$form = $this->createForm(WebsiteImportType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $_POST['website_import'];
$website->setTitle($data['title']);
$website->setMainDns($data['mainDns']);
$website->setType($data['type']);
$website->setOffert($data['offert']);
$website->setRevendeur($revendeurRepository->find($data['revendeur']));
$website->setCustomer($customerRepository->find($data['customer']));
$website->setServer($computeRepository->find($data['server']));
$entityManager->persist($website);
$webDates = new WebsiteDates();
$webDates->setWebsite($website);
$webDates->setCreateAt(\DateTimeImmutable::createFromFormat('Y-m-d',$data['createAt']));
$webDates->setOpenAt(\DateTimeImmutable::createFromFormat('Y-m-d',$data['openAt']));
$webDates->setNextHosting(\DateTimeImmutable::createFromFormat('Y-m-d',$data['hostingAt']));
$entityManager->persist($webDates);
$websiteKey = new WebsiteKey();
$websiteKey->setType("dma_key");
$websiteKey->setApiKey($data['keyDma']);
$websiteKey->setWebsitre($website);
$entityManager->persist($websiteKey);
$vd = $licenseManager->generateAndSaveLicense($website, 'main_license');
$entityManager->persist($vd);
$websiteKeyFolder = new WebsiteKey();
$websiteKeyFolder->setType("folder");
$websiteKeyFolder->setApiKey($data['folder']);
$websiteKeyFolder->setWebsitre($website);
$entityManager->persist($websiteKeyFolder);
$websiteKeyDatabase = new WebsiteKey();
$websiteKeyDatabase->setType("db_name");
$websiteKeyDatabase->setApiKey($vaultClient->encrypt('website_db', $data['db_name']));
$websiteKeyDatabase->setWebsitre($website);
$entityManager->persist($websiteKeyDatabase);
$websiteKeyDatabasePassword = new WebsiteKey();
$websiteKeyDatabasePassword->setType("db_password");
$websiteKeyDatabasePassword->setApiKey($vaultClient->encrypt('website_db', $data['db_password']));
$websiteKeyDatabasePassword->setWebsitre($website);
$entityManager->persist($websiteKeyDatabasePassword);
$websiteKeyDatabaseUsername = new WebsiteKey();
$websiteKeyDatabaseUsername->setType("db_username");
$websiteKeyDatabaseUsername->setApiKey($vaultClient->encrypt('website_db',$data['db_username']));
$websiteKeyDatabaseUsername->setWebsitre($website);
$entityManager->persist($websiteKeyDatabaseUsername);
$websiteKeyRedis = new WebsiteKey();
$websiteKeyRedis->setType("redis_port");
$websiteKeyRedis->setApiKey($vaultClient->encrypt('website_db', $data['redis']));
$websiteKeyRedis->setWebsitre($website);
$entityManager->persist($websiteKeyRedis);
$entityManager->flush();
return $this->redirectToRoute('artemis_esyweb');
}
return $this->render('artemis/esyweb/import.twig', [
'form' => $form->createView(),
]);
}
#[Route(path: '/artemis/esyweb/website/add', name: 'artemis_esyweb_add', methods: ['GET', 'POST'], priority: 5)]
public function websiteAdd(LoggerService $loggerService, Request $request, EntityManagerInterface $entityManager, EventDispatcherInterface $eventDispatcher)

View File

@@ -0,0 +1,112 @@
<?php
namespace App\Form\Artemis\EsyWeb;
use App\Entity\Compute;
use App\Entity\Customer;
use App\Entity\Revendeur;
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\DateType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class WebsiteImportType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title',TextType::class,[
'label' => 'Nom du site internet',
])
->add('folder',TextType::class,[
'label' => 'Dossier du site internet',
])
->add('customer',EntityType::class,[
'label' => 'Client',
'attr' =>[
'is' => 'search-customer'
],
'class' => Customer::class,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('c')
->orderBy('c.raisonSocial', 'ASC');
},
'choice_label' => function (Customer $category): string {
return $category->getRaisonSocial()." - ".$category->mainContact()->getName()." ".$category->mainContact()->getSurname();
}
])
->add('type',ChoiceType::class,[
'label' => 'Type de site internet',
'required' => true,
'choices' => [
'Vitrine' => 'vitrine',
'E-commerce' => 'e-trade',
]
])
->add('offert',ChoiceType::class,[
'label' => 'Offre',
'required' => true,
'choices' => [
'Esy-Perso' => 'Esy-Perso',
'Esy-Start' => 'Esy-Start',
'Esy-Business' => 'Esy-Business',
'Esy-Premium' => 'Esy-Premium',
'E-COMMERCE - START' => 'E-COMMERCE - START',
'E-COMMERCE - BUSINESS' => 'E-COMMERCE - BUSINESS',
'E-COMMERCE - PREMIUM' => 'E-COMMERCE - PREMIUM',
]
])
->add('server',EntityType::class,[
'label' => 'Serveur',
'class' => Compute::class,
'choice_label'=> function (Compute $compute) {
return $compute->getName();
}
])
->add('revendeur',EntityType::class,[
'label' => 'Revendeur',
'attr' =>[
'is' => 'search-customer'
],
'class' => Revendeur::class,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('c')
->orderBy('c.raisonSocial', 'ASC');
},
'choice_label' => function (Revendeur $category): string {
return $category->getRaisonSocial()." - ".$category->getName()." ".$category->getSurname()." - ".$category->getEmail()." ".$category->getCode();
}
])
->add('db_username',TextType::class,[
'label' => 'Utilisateur de la base de donnée',
])
->add('db_password',TextType::class,[
'label' => 'Mot de passe de la base de donnée',
])
->add('db_name',TextType::class,[
'label' => 'Base de donnée',
])
->add('redis',TextType::class,[
'label' => 'Port de Redis',
])
->add('keyDma',TextType::class,[
'label' => 'Clé dma',
])
->add('createAt',DateType::class,[
'label' => 'Date de création',
])
->add('openAt',DateType::class,[
'label' => 'Date d\'ouverture',
])
->add('hostingAt',DateType::class,[
'label' => 'Date de la prochaine facturation hébergement',
])
->add('mainDns',TextType::class,[
'label' => 'Nom de domaine principale',
])
;
}
}

View File

@@ -37,8 +37,18 @@ class TwigOrderExtensions extends AbstractExtension
new TwigFilter('licNumber',[$this,'licNumber']),
new TwigFilter('mainKey',[$this,'mainKey']),
new TwigFilter('webDb',[$this,'webDb']),
new TwigFilter('folder',[$this,'folder']),
];
}
public function folder(Website $website): ?string
{
/** @var WebsiteKey $apiKey */
$apiKey = $website->getWebsiteKeys()->filter(function (WebsiteKey $websiteKey){
return $websiteKey->getType() == "folder";
})->first();
return $apiKey->getApiKey();
}
public function webDb(Website $website,string $type): ?string
{
/** @var WebsiteKey $apiKey */

View File

@@ -1,4 +1,4 @@
[website_deploy]
{% for website in websites %}
{{ website.mainDns}} ansible_connection=ssh ansible_user=bot ansible_python_interpreter=/usr/bin/python3 path=/var/www/{{ website.title|slugify }} website_id={{ website.id }} api_key={{ website|mainKey }} dma_key={{ website|dmaKey }} public_key={{ website|pubKey }} license_number={{ website|licNumber }} db_name={{ website|webDb('db_name') }} db_password={{ website|webDb('db_password') }} db_username={{ website|webDb('db_username') }} redis_port={{ website|webDb('redis_port') }}
{{ website.mainDns}} ansible_connection=ssh ansible_user=bot ansible_python_interpreter=/usr/bin/python3 path=/var/www/{{ website|folder }} website_id={{ website.id }} api_key={{ website|mainKey }} dma_key={{ website|dmaKey }} public_key={{ website|pubKey }} license_number={{ website|licNumber }} db_name={{ website|webDb('db_name') }} db_password={{ website|webDb('db_password') }} db_username={{ website|webDb('db_username') }} redis_port={{ website|webDb('redis_port') }}
{% endfor %}

View File

@@ -0,0 +1,70 @@
{% extends 'artemis/base.twig' %}
{% block title %}Importation d'un site internet{% endblock %}
{% block content %}
<h2 class="text-3xl font-semibold text-gray-800 dark:text-gray-200">Crée un site internet</h2>
<div class="mt-5 bg-gray-800 rounded-lg shadow-lg p-6 space-y-4">
{{ form_start(form) }}
<div class="flex space-x-4">
<div class="flex-1">
{{ form_row(form.title) }}
</div>
<div class="flex-1">
{{ form_row(form.folder) }}
</div>
<div class="flex-1">
{{ form_row(form.customer) }}
</div>
<div class="flex-1">
{{ form_row(form.server) }}
</div>
</div>
<div class="flex space-x-4">
<div class="flex-1">
{{ form_row(form.type) }}
</div>
<div class="flex-1">
{{ form_row(form.offert) }}
</div>
<div class="flex-1">
{{ form_row(form.revendeur) }}
</div>
<div class="flex-1">
{{ form_row(form.keyDma) }}
</div>
</div>
<div class="flex space-x-4">
<div class="flex-1">
{{ form_row(form.db_username) }}
</div>
<div class="flex-1">
{{ form_row(form.db_password) }}
</div>
<div class="flex-1">
{{ form_row(form.db_name) }}
</div>
<div class="flex-1">
{{ form_row(form.redis) }}
</div>
</div>
<div class="flex space-x-4">
<div class="flex-1">
{{ form_row(form.createAt) }}
</div>
<div class="flex-1">
{{ form_row(form.openAt) }}
</div>
<div class="flex-1">
{{ form_row(form.hostingAt) }}
</div>
</div>
<div class="flex space-x-4">
<div class="flex-1">
{{ form_row(form.mainDns) }}
</div>
</div>
<button type="submit" class="w-full bg-purple-600 hover:bg-purple-700 text-white font-semibold px-4 py-2 rounded">Crée le site internet</button>
{{ form_end(form) }}
</div>
{% endblock %}

View File

@@ -23,11 +23,9 @@
</div>
<div class="flex items-center">
{# NOUVEAU BOUTON D'EXTRACTION XLS #}
<button id="exportXlsBtn" class="inline-flex items-center px-4 py-2 mr-3 border border-transparent text-sm font-medium rounded-md shadow-sm text-gray-900 bg-gray-300 hover:bg-gray-400 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-400 focus:ring-offset-gray-900">
Extraire en XLS
</button>
<a href="{{ path('artemis_esyweb_import') }}" class="inline-flex items-center mr-3 px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 focus:ring-offset-gray-900">
+ Importer un site internet
</a>
{# Bouton Ajouter un nouveau site #}
<a href="{{ path('artemis_esyweb_add') }}" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 focus:ring-offset-gray-900">
+ Ajouter un nouveau site

View File

@@ -27,14 +27,6 @@
<i class="fad fa-home"></i>
Nom de domaine
</a>
<a href="{{ path('artemis_esyweb_view',{id:website.id,current:'options'}) }}" class="px-4 py-2 font-semibold {% if current == "ndd" %}{{ active }}{% else %}{{ desactive }}{% endif %}">
<i class="fad fa-home"></i>
Options du site
</a>
<a href="{{ path('artemis_esyweb_view',{id:website.id,current:'key'}) }}" class="px-4 py-2 font-semibold {% if current == "ndd" %}{{ active }}{% else %}{{ desactive }}{% endif %}">
<i class="fad fa-home"></i>
Clé du site internet
</a>
<a href="{{ path('artemis_esyweb_view',{id:website.id,current:'ctrl'}) }}" class="px-4 py-2 font-semibold {% if current == "ctrl" %}{{ active }}{% else %}{{ desactive }}{% endif %}">
<i class="fad fa-cog"></i>
Contrôle du site internet

View File

@@ -82,6 +82,7 @@ dns_email: Nom de Domaine + Emails
esyWeb_created: Créer en attends de validation
esyWeb_validate: Validation - En Attends de déploiement
esyWeb_deploy: En ligne
vadvert-ndd : Renouvellement nom de domaine
f-created: Facture Crée
f-send: Facture envoyée