Onclick et script inline du Fichier commentaires.php

WebstephWebsteph Member
novembre 2022 modifié dans Entraide

bonjour la communauté

Je voudrai savoir si le fichier commentaires.php sera réécrit pour la nouvelle version de Pluxml.
Car je souhaiterai faire fonctionner les commentaires avec une Content Security Policy (CSP).
Pour le moment j'ai réussi à externaliser le script dans un fichier php en lui apposant une balise Nonce.
Mais maintenant c'est le onclick qui me bloque
onclick="replyCom('<?php $plxShow->comIndex() ?>')">
Je pense qu'il faut remplacer le onclick par un Id mais je n'arrive plus à lancer la
function replyCom(idCom)
du dit script externalisé.

Merci de votre aide
Stéphane

Réponses

  • bazooka07bazooka07 PluXml Lead Developer, Moderator
    novembre 2022 modifié

    Bonjour,
    Non, il n'est pas prévu pour l'instant la ré-écriture de commentaires.php. Cela ne fait pas directement partie de PluXml mais d'un thème livré avec.
    Pour résoudre ton problème d'externalisation du script JS, il te faut récupérer la valeur renvoyée par $plxShow->comIndex(). Pour cela, on utilise un attribut data de l'élément HTML qui reçoit le clic. Il faut aussi un element HTML avec un id fixe comme container de la liste des commentaires

    # commentaires.php
    <div id="coms-list">
      <?php while($plxShow->plxMotor->plxRecord_coms->loop()): # On boucle sur les commentaires ?>
        // .....
        <a rel="nofollow" href="<?php $plxShow->artUrl(); ?>#form" data-index="<?php $plxShow->comIndex() ?>"><?php $plxShow->lang('REPLY'); ?></a>
        <?php endwhile; # Fin de la boucle sur les commentaires ?>
    </div>
    

    Et pour le JS :

    const container = document.getElementById('coms-list');
    if(container) {
       container.addEventListener('click', function(event) {
          if(event.target.hasAttribute('data-index')) {
             const index = event.target.dataset.index;
             // .......
          }
       }
    }
    

    Je n'ai pas tester ce code. C'est un début de piste.

  • WebstephWebsteph Member
    novembre 2022 modifié

    Bonjour,

    Merci à toi bazooka07 de m'avoir mis sur la piste( et c'était la bonne). J'étais clairement parti dans une autre direction, bref !
    En plus j l'avais regardé la fonction dans le PlxShow, et j'ai pas tilté sur l'Index de la fonction comIndex.
    Alors voilà pour ceux qui voudraient faire la même chose que moi.

    1. On entoure la boucle commentaire avec une Div et un ID fixe, comme l'a dit bazooka07.
    2. On remplace le onclick="replyCom('<?php $plxShow->comIndex() ?>')" par data-index="<?php $plxShow->comIndex() ?>"
    3. On crée un fichier PHP commentaires-script.php et on copie colle le script du fichier commentaires.php à l'intérieur.
    4. Et dans ce script on colle ça à la place de la function replyCom(idCom)
    const container = document.getElementById('coms-list');
    if(container) {
       container.addEventListener('click', function(event) {
          if(event.target.hasAttribute('data-index')) {
             const index = event.target.dataset.index;
                document.getElementById('id_answer').innerHTML='<?php $plxShow->lang('REPLY_TO'); ?> :';
                document.getElementById('id_answer').innerHTML+=document.getElementById('com-'+index).innerHTML;
                document.getElementById('id_answer').innerHTML+='<a rel="nofollow" href="<?php $plxShow->artUrl(); ?>#form" id="cancelCom"><?php $plxShow->lang('CANCEL'); ?></a>';
                document.getElementById('id_answer').style.display='inline-block';
                document.getElementById('id_parent').value=index;
                document.getElementById('id_content').focus();
          }
       })
    }
    
    1. Comme vous pouvez le voir, j'ai remplacé le onclick="cancelCom()" par un id="cancelCom"
    2. Donc on remplace la function cancelCom() par
    if (document.addEventListener){
            document.addEventListener('click', function(event){
        var targetElement = event.target || event.srcElement;
            document.getElementById('cancelCom').addEventListener('click', function(){
            document.getElementById('id_answer').style.display = 'none';        
            document.getElementById('id_parent').value='';      
            if (document = null) {
            document.getElementById('com_message').innerHTML='';
            }
            });
        });
    } 
    
    1. Et les 2 dernières lignes, on touche pas

    var parent = document.getElementById('id_parent').value; if(parent!='') { index(parent) }

    1. dans le fichier commentaires.php, on appelle le fichier commentaire-script.php à l'endroit où il y avait le script.

    <?php include(PLX_ROOT.$plxMotor->aConf['racine_themes'].$plxMotor->style.'/commentaires-script.php') ?>

    1. Après on peut rajouter la valeur Nonce au <script nonce=""> et l'ajouter donc à la CSP pour valider le script.

    Maintenant j'ai un nouveau problème.
    j'aurai vraiment bien aimé externaliser ce script sans l'inclure dans un fichier PHP.
    Mais quand je place tout ça dans un fichier JS, les variables PHP ne sont pas interprétées.
    Exemple: Au lieu d'avoir "répondre à:" j'ai "lang('REPLY_TO'); ?> "

    Si quelqu'un a une idée, je suis preneur

    En vous remerciant
    Stéphane

  • novembre 2022 modifié

    Bonjour,
    Voir pour récupérer les langues via des variables js depuis le template des commentaires ( commentaires.php ) , Les variables de langues sont facilement disponible à partir des fichiers PHP des thèmes.

    <script>
        // transfert des textes/traductions choisies a partir des tableaux des fichiers langues de pluxml en constantes javascript afin de rendre 
        // les JavaScript aussi multilingues
        const reply_to = '<?php $plxShow->lang('REPLY_TO'); ?>';
        const cancel='<?php $plxShow->lang('CANCEL'); ?>';
       // etc.
    </script>
    

    Idem pour les autres traductions.

    C'est l'astuce dont je me suis servi pour l'un de mes plugins. j'ai initialisé toutes les constantes de textes à insérer en récupérant celles fournis par $plxShow->lang('TEXT_DANS_LANGUE_ACTIVE') ou plutôt $plxPlugin->lang('TEXT_DANS_LANGUE_ACTIVE') pour le cas d'un plugin.

    Cdt


    Cordialement,
    gcyrillus

    Mon site PluXml: https://re7net.com | Plugins: https://ressources.pluxopolis.net/banque-plugins/index.php?all_versions | demos sur free http://gcyrillus.free.fr/new | Thèmes: tester et télécharger @ https://pluxthemes.com
    Indiquez [RESOLU] dans le titre de votre question une fois le soucis réglè, Merci

  • bazooka07bazooka07 PluXml Lead Developer, Moderator
    novembre 2022 modifié

    @Websteph,

    J'ai regardé plus en détail ton problème pour enlever le JS de commentaires.php.
    Il y a aussi les creations de contenu avec innerHTML qui ne me plaisent pas trop.
    J'avais déjà commencé à modifier le thème par défaut pour factoriser la boucle d'articles dans la homepage, les catégories, les tags, ...
    Je procède donc différemment.
    En JS, je recherche le noeud HTML qui contient le formulaire et je le déplace si besoin dans l'arbre DOM en cas de réponse à un commentaire précédent.
    J'utilise aussi le couple

    / pour masquer le formulaire pour un nouveau commentaire.
    Dans commentaires.php, le formulaire est bufférisé dans la variable $form pour le placer au bon endroit si un commentaire est invalide. Tout cela est dans le thème default-enhanced :
    https://kazimentou.fr/repo/index.php?theme=default-enhanced&download Il reste à ajouter le CSP. Je vous laisse tester. Je le mettrai dans la prochaine version de PluXml
  • Bonjour

    gcyrillus-nomade, j te remercie pour ta proposition mais j'essaie justement de ne pas insérer de script Inline.
    J'ai comme même fait le test en désactivant ma CSP, ton astuce fonctionne.

    bazooka07, j'ai jeté un œil sur ton site Démo avec le thème Enhanced, j'aime bien le concept pour les commentaires.
    Si j'avais juste quelque chose à modifier, je ne ferai pas un Toggle sur le bouton "ajouter un commentaire" mais plutôt un bouton Annuler à coté de celui pour envoyer.
    Pour remplacer le innerHTML, il faut se tourner vers la création d’éléments, ainsi que textContent, je pense.
    Mais pareil, là c'est un début de piste.

  • bazooka07bazooka07 PluXml Lead Developer, Moderator

    @Websteph,
    La création d'éléments se fait en PHP directement sur le serveur.
    Javascript ne sert qu'à déplacer les nodes dans l'arbre DOM. Plus clairement, il déplace le formulaire au bon endroit, selon qu'on répond à un commentaire ou qu'on en crée un nouveau. Il ajuste le champ caché parent dans le formulaire selon le contexte.
    Le toggle évite de distraire le visiteur en affichant directement le formulaire. On peut éventuellement changer le titre du bouton quand le formulaire est affiché.

    Comment tu installes ta CSP ?

    D'après ce que j'ai lu, il faut rajouter un header avant d'envoyer la page HTML.
    On peut aussi faire un checksum sur les scripts en JS.

  • @bazooka07,
    J'ai encore regardé un peu ce que tu avais fait sur ton thème enhanced.
    et c'est bien ce que je souhaitais faire, externaliser complétement le script Inline du fichier commentaires.php
    Et en plus, tu l'as clairement amélioré.
    Du coup je vais prochainement essayer de l'intégrer à un de mes thèmes personnalisés.
    Grand Merci

    Pour installer une CSP, j'ai préféré créer un nouveau sujet.
    https://forum.pluxml.org/discussion/7312/optimisation-et-securisation-de-pluxml#latest

  • bazooka07bazooka07 PluXml Lead Developer, Moderator

    Bonjour,
    Je souhaite intégrer mon thème default-enhanced dans la prochaine version de PluXml en remplacement du thème defaut.
    Avez-vous eu le temps de l'étudier plus en détail ?
    J'ai besoin de quelques retours d'expériences.

  • Je vais regarder ça. Retours à suivre.

  • décembre 2022 modifié

    @Websteph idem , je suis aussi très curieux des suites de ton approche et sur le sujet concernant tes questions pertinentes au nom de la communauté entière de PluXml si mon humble analyse et prétention le permet , ceci inclus ton autre sujet : https://forum.pluxml.org/discussion/7312/optimisation-et-securisation-de-pluxml
    Donc, et pour la communauté, ainsi que pour (et surtout) le CMS PluXml, je pense que nous sommes tous curieux et serions honorés ( et très avide d'en faire usage ... ah zut j'ai osé le dire ! ) de bénéficier d'une amélioration majeure de ce CMS bien franchouillard 100% français( du moins à ce que j'en et en ai ai compris so far ;) ) CMS mal vue/référencé, sur le net alors qu’il en vaut bien d'autres référencés comme flat file ....

    Alors donc, qu'as tu fait pour finaliseer ton code afin qu'il réponde à ton besoin initial et coneils donnés par @bazooka07 ?

    Cdt, CG


    Cordialement,
    gcyrillus

    Mon site PluXml: https://re7net.com | Plugins: https://ressources.pluxopolis.net/banque-plugins/index.php?all_versions | demos sur free http://gcyrillus.free.fr/new | Thèmes: tester et télécharger @ https://pluxthemes.com
    Indiquez [RESOLU] dans le titre de votre question une fois le soucis réglè, Merci

  • Je reviens sur ce sujet aujourd'hui pour le mettre à jour, car j'ai réussi à lui apposer un nonce aléatoire. Puis il y avait comme même un petit détail que je n'avais pas mentionné. Comme vous pouvez le voir, mon script est prévu pour fonctionner avec Bootstrap, mais vous pouvez facilement le modifier si c'est pas votre cas.

    <script nonce="<?php echo $GLOBALS['nonce']; ?>">
    const container = document.getElementById('coms-list');
    if(container) {
       container.addEventListener('click', function(event) {
          if(event.target.hasAttribute('data-index')) {
             const index = event.target.dataset.index;
                document.getElementById('id_answer').className='card col-md-12 bg-light rounded pt-2 ps-2 mb-3 d-block';
                document.getElementById('id_answer').innerHTML='<h5 class="me-2"><em><u><?php $plxShow->lang('REPLY_TO'); ?></u></em> :</h5>';
                document.getElementById('id_answer').innerHTML+=document.getElementById('com-'+index).innerHTML;
                document.getElementById('id_answer').innerHTML+='<a rel="nofollow" class="btn btn-danger mb-3" role="button" href="<?php $plxShow->artUrl(); ?>#form" id="cancelCom"><i class="fas fa-times-circle me-2"></i><?php $plxShow->lang('CANCEL'); ?></a>';
                document.getElementById('id_parent').value=index;
                document.getElementById('id_content').focus();
          }
       })
    }
    
    if (document.addEventListener){
            document.addEventListener('click', function(event){
        var targetElement = event.target || event.srcElement;
            document.getElementById('cancelCom').addEventListener('click', function(){
            document.getElementById('id_answer').className='d-none';        
            document.getElementById('id_parent').value='';      
            if (document = null) {
            document.getElementById('com_message').innerHTML='';
            }
            });
        });
    } 
    
    var parent = document.getElementById('id_parent').value;
    if(parent!='') { index(parent) }
    </script>
    

    Pour générer le nonce, je l'ai fait à partir de mon fichier que je vous avais déjà présenté ici

    $nonce = hash('sha256', uniqid('', true));
    $GLOBALS['nonce'] = $nonce;
    
    header("Content-Security-Policy: default-src 'none'; manifest-src 'self'; script-src 'self' 'unsafe-inline' 'nonce-".$GLOBALS['nonce']."'; style-src 'self'; img-src 'self'; font-src 'self'; connect-src 'self'; media-src 'none'; object-src 'none'; frame-src 'self'; frame-ancestors 'none'; form-action 'self'; base-uri 'self';");
    

    J'ai choisi Sha256 et Uniqid parce qu’ils sont compatible, de PHP 5.6.34 pour Les pages persos Free que j'utilise encore, à PHP 8 !

Connectez-vous ou Inscrivez-vous pour répondre.