Stocker mes image en BDD avec TinyMce

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Stocker mes image en BDD avec TinyMce

Re: Stocker mes image en BDD avec TinyMce

par semsem » 06 mars 2024, 16:50

Merci infiniment pour ton retour @ynx et surtout de ton temps ! Je vais faire le nécessaire alors !

mon composer.json :

Image
Image

Re: Stocker mes image en BDD avec TinyMce

par ynx » 06 mars 2024, 13:51

Tu aurais gagné du temps en consultant le readme du bundle : https://github.com/eckinox/tinymce-bundle
"Quand tout le reste a échoué, lisez le mode d'emploi..."

Commence par corriger les erreurs pour tes assets.
Sans voir ton composer.json, je ne sais pas sur quelle version de Symfony tu es ni comment tu gères les assets. Tu utilises le composant AssetMapper ?
Execute la commande php bin/console assets:install dans ton projet, puis déplace le dossier public/bundles/tinymce dans public/assets/bundles/tinymce

Pour utiliser l'éditeur Tinymce, tu n'as pas besoin de créer une surcharge Twig avec les balises script, le textarea et les code javascript puisque le bundle le fait déjà pour toi.

Crée un fichier templates/admin/form.html.twig dans lequel tu peux surcharger uniquement le champ "contenu" de ton entité Article (_Article_contenu_widget) en utilisant la fonction twig du bundle :
{% block _Article_contenu_widget %}
  {{ tinymce(value, { name: "Article[contenu]" }) }}
{% endblock %}

Dans ton CrudController, ajoute ce fichier au début du tableau passé à setFormThemes :
<?php

namespace App\Controller\Admin;

use App\Entity\Article;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;

class ArticleCrudController extends AbstractCrudController
{
    public static function getEntityFqcn(): string
    {
        return Article::class;
    }

    public function configureCrud(Crud $crud): Crud
    {
        return $crud->setFormThemes(['admin/form.html.twig', '@EasyAdmin/crud/form_theme.html.twig']);
    }

    public function configureFields(string $pageName): iterable
    {
        return [
            TextField::new('titre'),
            TextareaField::new('contenu'),
        ];
    }
}

L'éditeur devrait alors s'afficher correctement sans erreur dans la console du navigateur.

Tu peux créer un fichier de configuration pour définir la config par défaut de l'éditeur, voir "Default configurations" dans le readme.
Le readme propose également un exemple d'implémentation dans Symfony pour l'upload des fichiers.

Re: Stocker mes image en BDD avec TinyMce

par semsem » 06 mars 2024, 10:58

J'ai installé avec composer "eckinox/tinymce-bundle": "^1.1",

Après sache que ça fonctionne bien mais j'ai des erreurs comme ça, je ne sais pas si c'est méchant ou pas ?

Image

Re: Stocker mes image en BDD avec TinyMce

par semsem » 06 mars 2024, 10:57

Alors, j'ai réussi !!! il s'inscrit en BDD !!!!! C'était mon "$imageFolder = "assets/images/";"...... J'avais mis un "/" avant assets... Voilà la solution pour ceux qui affrontera ce problème à l'avenir !! vive le code !!! Merci à tous !!!

Re: Stocker mes image en BDD avec TinyMce

par ynx » 06 mars 2024, 10:14

Comment a été installé Tinymce dans ton projet ? Via un bundle ?
Peux tu nous montrer ton fichier composer.json ?

Re: Stocker mes image en BDD avec TinyMce

par semsem » 05 mars 2024, 21:55

Alors j'ai tenter de mettre ("http://127.0.0.1:8000"); à la place de http://localhost:8000 / https://localhost:8000...
Alors là, je n'ai plus l'erreur 403 par contre j'ai un chargement infini, quand je sélectionne la photo, encore une étape de passer, j'ai l'impression que c'était : ("http://127.0.0.1:8000");

Image

Re: Stocker mes image en BDD avec TinyMce

par semsem » 05 mars 2024, 20:52

Alors, j'avais "http://localhost:8000" sans le "s", j'ai rajouté le "s"... Est-ce que cela pourrait-il venir de EasyAdmin ? ou autre ? Sinon le texte, le titre s'enregistre en BDD sans problème. J'ai l'impression que je suis pas loin pour mon image :?

<?php

/***************************************************
 * Only these origins are allowed to upload images *
 ***************************************************/
$accepted_origins = array("https://localhost:8000");

/*********************************************
 * Change this line to set the upload folder *
 *********************************************/
$imageFolder = "/public/assets/images/";
$name = uniqid();

if (isset($_SERVER['HTTP_ORIGIN'])) {
  // same-origin requests won't set an origin. If the origin is set, it must be valid.
  if (in_array($_SERVER['HTTP_ORIGIN'], $accepted_origins)) {
    header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
  } else {
    header("HTTP/1.1 403 Origin Denied");
    return;
  }
}

// Don't attempt to process the upload on an OPTIONS request
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  header("Access-Control-Allow-Methods: POST, OPTIONS");
  return;
}

reset($_FILES);
$temp = current($_FILES);
if (is_uploaded_file($temp['tmp_name'])) {
  /*
      If your script needs to receive cookies, set images_upload_credentials : true in
      the configuration and enable the following two headers.
    */
  // header('Access-Control-Allow-Credentials: true');
  // header('P3P: CP="There is no P3P policy."');

  // Sanitize input
  if (preg_match("/([^\w\s\d\-_~,;:\[\]\(\).])|([\.]{2,})/", $temp['name'])) {
    header("HTTP/1.1 400 Invalid file name.");
    return;
  }

  // Verify extension
  if (!in_array(strtolower(pathinfo($temp['name'], PATHINFO_EXTENSION)), array("gif", "jpg", "png"))) {
    header("HTTP/1.1 400 Invalid extension.");
    return;
  }

  // Accept upload if there was no origin, or if it is an accepted origin
  // assets/images/
  $extension = pathinfo($temp['name'], PATHINFO_EXTENSION);
  $filetowrite = $imageFolder . $name . "." . $extension;
  move_uploaded_file($temp['tmp_name'], $filetowrite);

  // Determine the base URL
  $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? "https://" : "http://";
  $baseurl = $protocol . $_SERVER["HTTP_HOST"] . rtrim(dirname($_SERVER['REQUEST_URI']), "/") . "/";

  // Respond to the successful upload with JSON.
  // Use a location key to specify the path to the saved image resource.
  // { location : '/your/uploaded/image/file'}
  echo json_encode(array('location' => $filetowrite));
} else {
  // Notify editor that the upload failed
  header("HTTP/1.1 500 Server Error");
}

Code : Tout sélectionner

{% extends '@EasyAdmin/crud/form_theme.html.twig' %} {% block ea_text_editor_widget %} <textarea id="{{ id }}" name="Article[contenu]"class="trix-content tinymce" role="textbox">{{ data }}</textarea> <script src="{{ asset('assets/bundles/tinymce/ext/tinymce/tinymce.min.js') }}"></script> <script src="{{ asset('bundles/tinymce/ext/tinymce-webcomponent.js') }}" type="module"></script> <script> tinymce.init({ selector: '.tinymce', width: '1100px', plugins: 'anchor autolink charmap codesample emoticons image link lists media searchreplace table visualblocks wordcount checklist mediaembed casechange export formatpainter pageembed linkchecker a11ychecker tinymcespellchecker permanentpen powerpaste advtable advcode editimage tinycomments tableofcontents footnotes mergetags autocorrect typography inlinecss', toolbar: 'undo redo | blocks fontfamily fontsize | bold italic underline strikethrough | link image media table mergetags | addcomment showcomments | spellcheckdialog a11ycheck typography | align lineheight | checklist numlist bullist indent outdent | emoticons charmap | removeformat', tinycomments_mode: 'embedded', // images_upload_url: 'upload.php', images_upload_handler: (blobInfo, progress) => new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.withCredentials = false; xhr.open('POST', 'upload.php'); xhr.upload.onprogress = (e) => { progress(e.loaded / e.total * 100); }; xhr.onload = () => { if (xhr.status === 403) { reject({ message: 'HTTP Error: ' + xhr.status, remove: true }); return; } if (xhr.status < 200 || xhr.status >= 300) { console.log(xhr); reject('HTTP Error: ' + xhr.status + ' ' + xhr.statusText); return; } const json = JSON.parse(xhr.responseText); if (!json || typeof json.location != 'string') { reject('Invalid JSON: ' + xhr.responseText); return; } resolve(json.location); }; xhr.onerror = () => { reject('Image upload failed due to a XHR Transport error. Code: ' + xhr.status); }; const formData = new FormData(); formData.append('file', blobInfo.blob(), blobInfo.filename()); xhr.send(formData); }) }); // colocar imagem no tinymce const images = document.querySelectorAll('.image'); images.forEach(image => { image.addEventListener('click', event => { // tinymce.activeEditor.execCommand('mceInsertContent', false, image.outerHTML); tinymce.get('image').execCommand('mceInsertContent', false, image.outerHTML); // tinymce.activeEditor.setContent(image.outerHTML); console.log(event); }) }) </script> {% endblock %}

Re: Stocker mes image en BDD avec TinyMce

par ynx » 05 mars 2024, 19:39

Le script d'upload que tu as repris de la doc vérifie l'origine et retourne le code 403 si le domaine est invalide : header("HTTP/1.1 403 Origin Denied");

Le tableau $accepted_origins ne contient pas le bon domaine à priori.
Le serveur de dev de Symfony utilise https (https://localhost:8000)

Re: Stocker mes image en BDD avec TinyMce

par or 1 » 05 mars 2024, 19:02

Merci pour ta réponse, donc avec seulement du JS, je peux régler mon problème ? Sans besoin de passer par un contrôleur et tout ? Je suis débutant... ^^
pas de miracle, il faut indiquer une url valide et que cette url fasse ce qu'elle doit faire : faires des éventuelles vérifications et sauver le fichier en local.

Re: Stocker mes image en BDD avec TinyMce

par semsem » 05 mars 2024, 18:59

Ahhhhhh super, c'est un peu mieux ! J'ai une erreur 403 lorsque je mets un image... J'ai l'impression que c'est un problème d'autorisation non ?

Re: Stocker mes image en BDD avec TinyMce

par ynx » 05 mars 2024, 17:54

tinymce.init({
  selector: '#image',

Tu as modifié par erreur le sélecteur dans l'initialisation, remet le bon sélecteur '.tinymce' comme dans ton premier code.

Re: Stocker mes image en BDD avec TinyMce

par semsem » 05 mars 2024, 16:25

Mon TinyMCE ne s'affiche plus... je vois seulement l'éditeur par défaut d'EasyAdmin... 8-|

<?php

/***************************************************
 * Only these origins are allowed to upload images *
 ***************************************************/
$accepted_origins = array("http://localhost:8000");

/*********************************************
 * Change this line to set the upload folder *
 *********************************************/
$imageFolder = "assets/images/";
$name = uniqid();

if (isset($_SERVER['HTTP_ORIGIN'])) {
  // same-origin requests won't set an origin. If the origin is set, it must be valid.
  if (in_array($_SERVER['HTTP_ORIGIN'], $accepted_origins)) {
    header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
  } else {
    header("HTTP/1.1 403 Origin Denied");
    return;
  }
}

// Don't attempt to process the upload on an OPTIONS request
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  header("Access-Control-Allow-Methods: POST, OPTIONS");
  return;
}

reset($_FILES);
$temp = current($_FILES);
if (is_uploaded_file($temp['tmp_name'])) {
  /*
      If your script needs to receive cookies, set images_upload_credentials : true in
      the configuration and enable the following two headers.
    */
  // header('Access-Control-Allow-Credentials: true');
  // header('P3P: CP="There is no P3P policy."');

  // Sanitize input
  if (preg_match("/([^\w\s\d\-_~,;:\[\]\(\).])|([\.]{2,})/", $temp['name'])) {
    header("HTTP/1.1 400 Invalid file name.");
    return;
  }

  // Verify extension
  if (!in_array(strtolower(pathinfo($temp['name'], PATHINFO_EXTENSION)), array("gif", "jpg", "png"))) {
    header("HTTP/1.1 400 Invalid extension.");
    return;
  }

  // Accept upload if there was no origin, or if it is an accepted origin
  // assets/images/
  $extension = pathinfo($temp['name'], PATHINFO_EXTENSION);
  $filetowrite = $imageFolder . $name . "." . $extension;
  move_uploaded_file($temp['tmp_name'], $filetowrite);

  // Determine the base URL
  $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? "https://" : "http://";
  $baseurl = $protocol . $_SERVER["HTTP_HOST"] . rtrim(dirname($_SERVER['REQUEST_URI']), "/") . "/";

  // Respond to the successful upload with JSON.
  // Use a location key to specify the path to the saved image resource.
  // { location : '/your/uploaded/image/file'}
  echo json_encode(array('location' => $filetowrite));
} else {
  // Notify editor that the upload failed
  header("HTTP/1.1 500 Server Error");
}

Code : Tout sélectionner

{% extends '@EasyAdmin/crud/form_theme.html.twig' %} {% block ea_text_editor_widget %} <textarea id="{{ id }}" name="Article[contenu]"class="trix-content tinymce" role="textbox">{{ data }}</textarea> <script src="{{ asset('assets/bundles/tinymce/ext/tinymce/tinymce.min.js') }}"></script> <script src="{{ asset('bundles/tinymce/ext/tinymce-webcomponent.js') }}" type="module"></script> <script> tinymce.init({ selector: '#image', height: 1000, plugins: 'anchor autolink charmap codesample emoticons image link lists media searchreplace table visualblocks wordcount checklist mediaembed casechange export formatpainter pageembed linkchecker a11ychecker tinymcespellchecker permanentpen powerpaste advtable advcode editimage tinycomments tableofcontents footnotes mergetags autocorrect typography inlinecss', toolbar: 'undo redo | blocks fontfamily fontsize | bold italic underline strikethrough | link image media table mergetags | addcomment showcomments | spellcheckdialog a11ycheck typography | align lineheight | checklist numlist bullist indent outdent | emoticons charmap | removeformat', tinycomments_mode: 'embedded', // images_upload_url: 'upload.php', images_upload_handler: (blobInfo, progress) => new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.withCredentials = false; xhr.open('POST', 'upload.php'); xhr.upload.onprogress = (e) => { progress(e.loaded / e.total * 100); }; xhr.onload = () => { if (xhr.status === 403) { reject({ message: 'HTTP Error: ' + xhr.status, remove: true }); return; } if (xhr.status < 200 || xhr.status >= 300) { console.log(xhr); reject('HTTP Error: ' + xhr.status + ' ' + xhr.statusText); return; } const json = JSON.parse(xhr.responseText); if (!json || typeof json.location != 'string') { reject('Invalid JSON: ' + xhr.responseText); return; } resolve(json.location); }; xhr.onerror = () => { reject('Image upload failed due to a XHR Transport error. Code: ' + xhr.status); }; const formData = new FormData(); formData.append('file', blobInfo.blob(), blobInfo.filename()); xhr.send(formData); }) }); // colocar imagem no tinymce const images = document.querySelectorAll('.image'); images.forEach(image => { image.addEventListener('click', event => { // tinymce.activeEditor.execCommand('mceInsertContent', false, image.outerHTML); tinymce.get('image').execCommand('mceInsertContent', false, image.outerHTML); // tinymce.activeEditor.setContent(image.outerHTML); console.log(event); }) }) </script> {% endblock %}

<?php
 
namespace App\Controller\Admin;
 
use App\Entity\Article;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
 
class ArticleCrudController extends AbstractCrudController
{
    
    public static function getEntityFqcn(): string
    {
        return Article::class;
    }

    public function configureCrud(Crud $crud): Crud
    {
        return $crud
            ->setFormThemes(['@EasyAdmin/crud/form_theme.html.twig', 'admin/articleForm.html.twig']); // On ajoute un thème pour le formulaire
    }
 
    public function configureFields(string $pageName): iterable
    {
        return [
            TextField::new('titre'),
            TextEditorField::new('contenu'),
            AssociationField::new('sousCategorie') // Champ pour sélectionner une sous-catégorie
                ->setLabel('Sous-catégorie')
                ->setRequired(true),
            // AssociationField::new('categorie') // Champ pour sélectionner une sous-catégorie
            //     ->setLabel('Catégorie')
            //     ->setRequired(true),
        ];
    }
}


Et Mon JS de BASE qui fonctionne mais avec le blob/base64 :

Code : Tout sélectionner

{% extends '@EasyAdmin/crud/form_theme.html.twig' %} {% block ea_text_editor_widget %} <textarea id="{{ id }}" name="Article[contenu]"class="trix-content tinymce" role="textbox">{{ data }}</textarea> <script src="{{ asset('assets/bundles/tinymce/ext/tinymce/tinymce.min.js') }}"></script> <script src="{{ asset('bundles/tinymce/ext/tinymce-webcomponent.js') }}" type="module"></script> <script> tinymce.init({ selector: '.tinymce', plugins: 'image file-manager link', // Ajoutez le plugin 'link' à la liste des plugins activés toolbar: 'undo redo | formatselect | bold italic underline | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | image | filemanager | link | exportpdf', // Ajoutez le bouton 'link' à la barre d'outils file_picker_callback: function(cb, value, meta) { const input = document.createElement('input'); input.setAttribute('type', 'file'); // Event listeners input.addEventListener('change', (e) => { const file = e.target.files[0]; const reader = new FileReader(); reader.addEventListener('load', () => { // Handle data processing with a blob const id = 'blobid' + (new Date()).getTime(); const blobCache = tinymce.activeEditor.editorUpload.blobCache; const base64 = reader.result.split(',')[1]; const blobInfo = blobCache.create(id, file, base64); blobCache.add(blobInfo); cb(blobInfo.blobUri(), { title: file.name }); }); reader.readAsDataURL(file); }); input.click(); }, images_reuse_filename: true, paste_data_images: true, // content_css: '/style.css', setup: function (editor) { // Ajoutez la fonction pour exporter en PDF avec html2pdf editor.ui.registry.addButton('exportpdf', { text: 'Exporter au format PDF', onAction: function () { exportToPDF(editor.getContent()); } }); } }); function exportToPDF(content) { var element = document.createElement('div'); element.innerHTML = content; html2pdf(element, { margin: 10, filename: 'output.pdf', image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2 }, jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' } }); } </script> {% endblock %}

Re: Stocker mes image en BDD avec TinyMce

par two3d » 04 mars 2024, 22:55

Je connais pas bien TinyMCE pour te dire, voilà la traduction de la catégorie en question :

https://www-tiny-cloud.translate.goog/d ... upload_url

Re: Stocker mes image en BDD avec TinyMce

par semsem » 04 mars 2024, 22:45

Merci pour ta réponse, donc avec seulement du JS, je peux régler mon problème ? Sans besoin de passer par un contrôleur et tout ? Je suis débutant... ^^

Re: Stocker mes image en BDD avec TinyMce

par two3d » 04 mars 2024, 16:37