diff --git a/.env b/.env index 3766ec3..511b784 100755 --- a/.env +++ b/.env @@ -3,6 +3,10 @@ APP_ENV=dev APP_SECRET=changeme APP_SESSIONTIME=1440 +# Webpack +APP_PUBLIC_PATH=/nineskeletor/build +APP_MANIFEST_KEY_PREFIX=nineskeletor + # Messenger MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 @@ -96,8 +100,8 @@ LDAP_GROUPGID=gidnumber # Attribut gid d LDAP_GROUPNAME=cn # Attribut name d'un groupe LDAP_GROUPMEMBER=memberuid # Attribut stockant les membres d'un groupe LDAP_GROUPMEMBERISDN=0 # LDAP_GROUPMEMBER stocke un uid ou un dn ? 0/1 -LDAP_FILTERGROUP=(cn=*) # requete ldap pour rechercher les groupes -LDAP_FILTERUSER=(uid=*) # requete ldap pour rechercher les users +LDAP_FILTERGROUP="(cn=*)" # requete ldap pour rechercher les groupes +LDAP_FILTERUSER="(uid=*)" # requete ldap pour rechercher les users LDAP_AUTOSUBMIT=1 # if APP_AUTH = LDAP autocréer les users non existant LDAP_AUTOUPDATE=1 # if APP_AUTH = LDAP automodifier les users existant diff --git a/config/routes.yaml b/config/routes.yaml index fe676df..43b9989 100755 --- a/config/routes.yaml +++ b/config/routes.yaml @@ -1608,6 +1608,32 @@ app_all_pagewidget_view_groupmessage: controller: App\Controller\PagewidgetController::viewgroupmessage defaults: { access: all } +#== DOCUMENT ================================================================================================================ +#-- Access admin +app_admin_document: + path: /admin/document + controller: App\Controller\DocumentController::list + defaults: { access: admin } + +app_admin_document_submit: + path: /admin/document/submit + controller: App\Controller\DocumentController::submit + defaults: { access: admin } + +app_admin_document_update: + path: /admin/document/update/{id} + controller: App\Controller\DocumentController::update + defaults: { access: admin } + +app_admin_document_delete: + path: /admin/document/delete/{id} + controller: App\Controller\DocumentController::delete + +app_admin_document_render: + path: /admin/document/render/{idcategory} + controller: App\Controller\DocumentController::renderid + defaults: { access: admin } + #== DOCUMENTCATEGORY ======================================================================================================== #-- Access admin app_admin_documentcategory: diff --git a/misc/docker/Dockerfile b/misc/docker/Dockerfile index 715e34b..ce6fd17 100644 --- a/misc/docker/Dockerfile +++ b/misc/docker/Dockerfile @@ -1,14 +1,14 @@ FROM reg.cadoles.com/envole/nineapache:8.1 +COPY ./misc/docker/apache.conf /etc/apache2/conf.d/nine/site.conf + RUN echo "* * * * * /app/bin/console app:Cron --env=prod" >> /var/spool/cron/crontabs/root WORKDIR /app COPY . . - -RUN yarn install -RUN yarn encore dev -RUN yarn encore prod +# Installation des dépendances composer +RUN composer install --no-interaction RUN mkdir -p /app/public/uploads RUN chown apache /app/public/uploads -R @@ -18,5 +18,4 @@ RUN mkdir -p /app/var RUN chown apache /app/var -R RUN chmod u+w /app/var -R -CMD /app/misc/script/reconfigure.sh && /etc/apache2/apache2.sh -#CMD /etc/apache2/apache2.sh +CMD /app/misc/script/reconfigure.sh && /etc/apache2/apache2.sh \ No newline at end of file diff --git a/misc/docker/apache.conf b/misc/docker/apache.conf new file mode 100755 index 0000000..385bb5a --- /dev/null +++ b/misc/docker/apache.conf @@ -0,0 +1,19 @@ +LoadModule rewrite_module modules/mod_rewrite.so +ServerName nineapache.local +DocumentRoot "/app/public" +Alias /nineskeletor /app/public + + Options Indexes FollowSymLinks + AllowOverride All + Require all granted + + RewriteEngine On + RewriteCond %{REQUEST_URI}::$0 ^(/.+)/(.*)::\2$ + RewriteRule .* - [E=BASE:%1] + RewriteCond %{HTTP:Authorization} .+ + RewriteRule ^ - [E=HTTP_AUTHORIZATION:%0] + RewriteCond %{ENV:REDIRECT_STATUS} ="" + RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L] + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ %{ENV:BASE}/index.php [L] + \ No newline at end of file diff --git a/misc/script/reconfigure.sh b/misc/script/reconfigure.sh index 951f42e..ae58dde 100755 --- a/misc/script/reconfigure.sh +++ b/misc/script/reconfigure.sh @@ -7,11 +7,21 @@ cd ${DIR} cd ../.. DIR=$(pwd) -# Installation des dépendances composer -composer install --no-interaction - bin/console d:s:u --force --complete +# Si l'alias courrant est différent que celui généré = on compile encore +last_alias="" +if [ -f .alias ]; then + last_alias=$(cat .alias) +fi + +if [ "$APP_MANIFEST_KEY_PREFIX" != "$last_alias" ]; then + echo "Alias a changé. Recompilation nécessaire." + echo "$APP_MANIFEST_KEY_PREFIX" > .alias + yarn encore dev + yarn encore prod +fi + bin/console app:Init exec $@ \ No newline at end of file diff --git a/package.json b/package.json index 25e4af3..d54cf26 100755 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "ckeditor4": "^4.19.0", "crop-select-js": "^1.0.1", "datatables.net-bs4": "^1.12.1", + "dotenv": "^16.4.5", "dropzone": "^6.0.0-beta.2", "file-loader": "^6.2.0", "iframe-resizer": "^4.3.2", diff --git a/src/Controller/DocumentController.php b/src/Controller/DocumentController.php new file mode 100644 index 0000000..ba6ed80 --- /dev/null +++ b/src/Controller/DocumentController.php @@ -0,0 +1,137 @@ +getRepository("App\Entity\Documentcategory")->findBy(['parent' => null], ['roworder' => 'ASC']); + $datas = $em->getRepository("App\Entity\Document")->findAll(['documentcategory' => null], ['roworder' => 'ASC']); + + return $this->render($this->twig.'list.html.twig', [ + 'useheader' => true, + 'usemenu' => false, + 'usesidebar' => ('admin' == $access), + 'access' => $access, + 'documentcategorys' => $documentcategorys, + $this->data.'s' => $datas, + ]); + } + + public function submit($access, Request $request, ManagerRegistry $em): Response + { + // Initialisation de l'enregistrement + $data = new Document(); + $data->setRoworder(0); + + // Création du formulaire + $form = $this->createForm(DocumentType::class, $data, ['mode' => 'submit', 'access' => $access]); + + // Récupération des data du formulaire + $form->handleRequest($request); + + // Sur validation + if ($form->get('submit')->isClicked() && $form->isValid()) { + $data = $form->getData(); + + // Sauvegarde + $em->getManager()->persist($data); + $em->getManager()->flush(); + + // Retour à la liste + return $this->redirectToRoute(str_replace('_admin_', '_'.$access.'_', $this->route)); + } + + // Affichage du formulaire + return $this->render($this->twig.'edit.html.twig', [ + 'useheader' => true, + 'usemenu' => false, + 'usesidebar' => ('admin' == $access), + 'access' => $access, + $this->data => $data, + 'mode' => 'submit', + 'form' => $form->createView(), + ]); + } + + public function update($id, $access, Request $request, ManagerRegistry $em): Response + { + // Initialisation de l'enregistrement + $data = $em->getRepository($this->entity)->find($id); + if (!$data) { + throw $this->createNotFoundException('Unable to find entity.'); + } + + // Création du formulaire + $form = $this->createForm(DocumentType::class, $data, ['mode' => 'update']); + + // Récupération des data du formulaire + $form->handleRequest($request); + + // Sur validation + if ($form->get('submit')->isClicked() && $form->isValid()) { + $data = $form->getData(); + + // Sauvegarde + $em->getManager()->flush(); + + // Retour à la liste + return $this->redirectToRoute(str_replace('_admin_', '_'.$access.'_', $this->route)); + } + + // Affichage du formulaire + return $this->render($this->twig.'edit.html.twig', [ + 'useheader' => true, + 'usemenu' => false, + 'usesidebar' => ('admin' == $access), + 'access' => $access, + $this->data => $data, + 'mode' => 'update', + 'form' => $form->createView(), + ]); + } + + public function delete($id, $access, Request $request, ManagerRegistry $em): Response + { + // Initialisation de l'enregistrement + $data = $em->getRepository($this->entity)->find($id); + if (!$data) { + throw $this->createNotFoundException('Unable to find entity.'); + } + + // Tentative de suppression + try { + $em->getManager()->remove($data); + $em->getManager()->flush(); + } catch (\Exception $e) { + $request->getSession()->getFlashBag()->add('error', $e->getMessage()); + + return $this->redirectToRoute($this->route.'_update', ['id' => $id]); + } + + return $this->redirectToRoute(str_replace('_admin_', '_'.$access.'_', $this->route)); + } + + public function renderid($idcategory, $access, ManagerRegistry $em): Response + { + $data = $em->getRepository("App\Entity\Documentcategory")->find($idcategory); + + return $this->render($this->twig.'render.html.twig', [ + 'access' => $access, + 'documentcategory' => $data, + ]); + } +} diff --git a/src/Controller/DocumentcategoryController.php b/src/Controller/DocumentcategoryController.php index 36124f2..83a6ca6 100644 --- a/src/Controller/DocumentcategoryController.php +++ b/src/Controller/DocumentcategoryController.php @@ -24,7 +24,7 @@ class DocumentcategoryController extends AbstractController return $this->render($this->twig.'list.html.twig', [ 'useheader' => true, 'usemenu' => false, - 'usesidebar' => true, + 'usesidebar' => ('admin' == $access), 'access' => $access, $this->data.'s' => $datas, ]); @@ -68,7 +68,7 @@ class DocumentcategoryController extends AbstractController return $this->render($this->twig.'edit.html.twig', [ 'useheader' => true, 'usemenu' => false, - 'usesidebar' => true, + 'usesidebar' => ('admin' == $access), 'access' => $access, $this->data => $data, 'mode' => 'submit', @@ -105,7 +105,7 @@ class DocumentcategoryController extends AbstractController return $this->render($this->twig.'edit.html.twig', [ 'useheader' => true, 'usemenu' => false, - 'usesidebar' => true, + 'usesidebar' => ('admin' == $access), 'access' => $access, $this->data => $data, 'mode' => 'update', diff --git a/src/Entity/Documentcategory.php b/src/Entity/Documentcategory.php index 0ee4857..89b7b01 100755 --- a/src/Entity/Documentcategory.php +++ b/src/Entity/Documentcategory.php @@ -52,9 +52,19 @@ class Documentcategory */ private $childs; + /** + * @var ArrayCollection + * @var Document + * + * @ORM\OneToMany(targetEntity="Document", mappedBy="documentcategory", cascade={"persist"}, orphanRemoval=false) + * @ORM\OrderBy({"roworder" = "ASC"}) + */ + private $documents; + public function __construct() { $this->childs = new ArrayCollection(); + $this->documents = new ArrayCollection(); } public function getId(): ?int @@ -127,4 +137,34 @@ class Documentcategory return $this; } + + /** + * @return Collection + */ + public function getDocuments(): Collection + { + return $this->documents; + } + + public function addDocument(Document $document): self + { + if (!$this->documents->contains($document)) { + $this->documents->add($document); + $document->setDocumentcategory($this); + } + + return $this; + } + + public function removeDocument(Document $document): self + { + if ($this->documents->removeElement($document)) { + // set the owning side to null (unless already changed) + if ($document->getDocumentcategory() === $this) { + $document->setDocumentcategory(null); + } + } + + return $this; + } } diff --git a/src/Form/DocumentType.php b/src/Form/DocumentType.php new file mode 100755 index 0000000..8532178 --- /dev/null +++ b/src/Form/DocumentType.php @@ -0,0 +1,37 @@ +add('submit', + SubmitType::class, [ + 'label' => 'Valider', + 'attr' => ['class' => 'btn btn-success'], + ] + ); + + $builder->add('label', + TextType::class, [ + 'label' => 'Label', + ] + ); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => 'App\Entity\Document', + 'access' => 'string', + 'mode' => 'string', + ]); + } +} diff --git a/templates/Document/edit.html.twig b/templates/Document/edit.html.twig new file mode 100755 index 0000000..0b5ebae --- /dev/null +++ b/templates/Document/edit.html.twig @@ -0,0 +1,62 @@ +{% extends 'base.html.twig' %} + +{% block body %} +{{ form_start(form) }} +

+ {% if mode=="update" %} + Modification Catégorie de Document = {{document.label}} + {% elseif mode=="submit" %} + Création Catégorie de Document + {% endif %} +

+ + {{ form_widget(form.submit) }} + Annuler + {% if mode=="update" %} + Supprimer + {% endif %} + + {% if app.session.flashbag.has('error') %} +
+ Erreur
+ {% for flashMessage in app.session.flashbag.get('error') %} + {{ flashMessage }}
+ {% endfor %} +
+ {% endif %} + + {% if app.session.flashbag.has('notice') %} +
+ Information
+ {% for flashMessage in app.session.flashbag.get('notice') %} + {{ flashMessage }}
+ {% endfor %} +
+ {% endif %} + +
+
+ Informations +
+ +
+ {{ form_row(form.label) }} +
+
+ + {% if auditUse and mode=="update" and (access=="admin" or access=="modo" or access=="audit") %} +
+ {{ render(path("app_"~access~"_audit_renderid",{entityname:"Document",entityid:document.id})) }} +
+ {% endif %} +{{ form_end(form) }} +{% endblock %} + +{% block localscript %} + +{% endblock %} diff --git a/templates/Document/list.html.twig b/templates/Document/list.html.twig new file mode 100755 index 0000000..77e4973 --- /dev/null +++ b/templates/Document/list.html.twig @@ -0,0 +1,66 @@ +{% extends 'base.html.twig' %} + +{% block localstyle %} + +{% endblock %} + +{% block body %} +

Gestion des Documents

+ + + Ajouter + {% if auditUse and (access=="admin" or access=="audit") %} + Audit + {% endif %} +

+ +
+
+ Liste des Catégories de Document +
+ +
+
+ {% for documentcategory in documentcategorys %} + {{ render(path("app_"~access~"_document_render",{idcategory:documentcategory.id})) }} + {% endfor %} +
+ + {% for document in documents %} +
+
+
+ +
+ +
+
+ +
+
+ {% endfor %} +
+
+{% endblock %} + +{% block localscript %} + +{% endblock %} + diff --git a/templates/Document/render.html.twig b/templates/Document/render.html.twig new file mode 100644 index 0000000..0f034e5 --- /dev/null +++ b/templates/Document/render.html.twig @@ -0,0 +1,29 @@ +
+
+
+ +
+
+ +
+ {% if not documentcategory.childs is empty %} + {% for documentcategory in documentcategory.childs %} + {% if loop.first %}
 
{%endif%} + {{ render(path("app_"~access~"_document_render",{idcategory:documentcategory.id,access:access})) }} + {% endfor %} + {% endif %} + + {% if not documentcategory.documents is empty %} + {% for document in documentcategory.documents %} + + {% endfor %} + {% endif %} +
+
+ diff --git a/templates/Include/sidebaradmin.html.twig b/templates/Include/sidebaradmin.html.twig index 85aa909..02326ba 100755 --- a/templates/Include/sidebaradmin.html.twig +++ b/templates/Include/sidebaradmin.html.twig @@ -101,6 +101,11 @@ 'icon': 'fa fa-file fa-fw', 'name' : 'DOCUMENTS', 'items' : [ + { + icon: 'fa fa-cogs', + route: 'app_admin_document', + name: 'Documents', + }, { icon: 'fa fa-cogs', route: 'app_admin_documentcategory', @@ -134,7 +139,7 @@ {% for section in sidebar %} {% set sectionactive=false %} {% for item in section.items %} - {% if item.route in app.request.get('_route') %} + {% if item.route==app.request.get('_route') or (item.route~"_") in app.request.get('_route') %} {% set sectionactive=true %} {% endif %} {% endfor %} @@ -161,7 +166,7 @@ {% if item.route=="app_admin_group" and not appGroupuse %} {% set toshow=false %} {% endif %} {%if toshow %} - + {{item.name}} diff --git a/webpack.config.js b/webpack.config.js index 14ef7e4..06007ae 100755 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,4 +1,6 @@ const Encore = require('@symfony/webpack-encore'); +const dotenv = require('dotenv'); +const path = require('path'); // Manually configure the runtime environment if not already configured yet by the "encore" command. // It's useful when you use tools that rely on webpack.config.js file. @@ -10,9 +12,8 @@ Encore // directory where compiled assets will be stored .setOutputPath('public/build/') // public path used by the web server to access the output path - .setPublicPath('/build') - // only needed for CDN's or sub-directory deploy - //.setManifestKeyPrefix('build/') + .setPublicPath(process.env.APP_PUBLIC_PATH || '/build') + .setManifestKeyPrefix(process.env.APP_MANIFEST_KEY_PREFIX || '') /* * ENTRY CONFIG diff --git a/yarn.lock b/yarn.lock index 0dfa1ac..c5b88d8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2449,6 +2449,11 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" +dotenv@^16.4.5: + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== + dropzone@^6.0.0-beta.2: version "6.0.0-beta.2" resolved "https://registry.yarnpkg.com/dropzone/-/dropzone-6.0.0-beta.2.tgz#098be8fa84bdc08674cf0b74f4c889e2679083d6"