Insérer un maximum/minimum de mots avant de poster un message

2 participants

Voir le sujet précédent Voir le sujet suivant Aller en bas

Résolu Insérer un maximum/minimum de mots avant de poster un message

Message par IzumiRK Sam 26 Mai 2018 - 12:24

Détails techniques

Version du forum : phpBB2
Poste occupé : Fondateur
Navigateur(s) concerné(s) : Google Chrome
Capture d'écran du problème :
Voir l'image:

Personnes concernées par le problème : Plusieurs utilisateurs
Lien du forum : http://indare-division.forumactif.com/

Description du problème

Bonjour,

J'avais déjà posté une demande à ce sujet mais comme j'ai eu des imprévus, je n'ai pas pu la up, donc je reviens la poster ^^
Sur mon forum, une section en particulier exige un maximum de 230 mots par message. Je dispose déjà d'un code de compteur de mots intégré, que je vous mets juste après, et c'est sur le décompte de celui-ci que j'aimerai me baser, étant donné qu'il ne prend pas en compte les balises BBcode et HTML.
Code compteur:

J'ai trouvé ce tutoriel qui permet d'imposer un minimum de mots, je sais comment le modifier pour que ce soit un maximum au lieu d'un minimum et pour qu'il ne s'applique qu'à une section du forum, mais le soucis c'est que lui prend en compte le contenu des balises html et BBcode, et que du coup le compte final est très différent. J'aimerais savoir s'il est possible de faire en sorte :
- soit qu'il prenne directement en compte le résultat de l'autre compteur pour imposer un maximum
- soit qu'il ignore les balises html et bbcode pour donner le même résultat

J'aimerais aussi savoir s'il est possible d'intégrer le code aux réponses postées dans ce sous-forum (car pour l'instant il ne s'applique qu'aux nouveaux topics). Sinon je pense avoir une solution alternative au cas par cas, mais s'il y en avais une générale ça serait plus simple ^^

Actuellement, mon code pour le maximum de mots ressemble à ça :
Code:
location.pathname=="/post" && /^\?f=24&mode=newtopic$/.test(location.search) && jQuery(function(){jQuery(function () {
          var NombreDeMots = 230;
          var NombreLettresParMot = 2;
          var icone_incomplet = 'http://2img.net/i/fa/admin/icones/supprimer.png';
          if (jQuery('#text_editor_textarea').length != 0) {
            jQuery('input[type=\'submit\'][name=\'post\']').attr('disabled', true).css('opacity', '0.5');
            jQuery('.sceditor-container').after('<div id=\'div_minchars_info\'></div>');
            /*
            gestion de 4 encodages FA:
            windows-1252 [anciens forums]
                cp-1252 [anciens forums]
              iso-8859-1 [anciens forums]
                  utf-8 [nouveaux forums]
            */
            var metas = document.getElementsByTagName('meta'),
            charset = '0';
            for (var i = 0; i < metas.length; i++) {
              var meta_charset = metas[i].hasAttribute('http-equiv') && metas[i].getAttribute('http-equiv').toLowerCase() === 'content-type' ? metas[i].getAttribute('content')  : 0;
              if (meta_charset) charset = meta_charset.substring(meta_charset.indexOf('=') + 1).toLowerCase();
            }
            switch (charset) {
              case 'utf-8':
                var regex = new RegExp('[\\w\\u00DF-\\u00F6\\u00F8-\\u00FD\\u0153]{' + NombreLettresParMot + ',}', 'gi');
                break;
              default:
                var regex = new RegExp('[\\w\\u00C0-\\u00F6\\u00F8-\\u00FF\\u0152]{' + NombreLettresParMot + ',}', 'gi');
            }
            /*fin gestion des encodages*/
      
            var sceditor = jQuery('#text_editor_textarea').sceditor('instance'),
            str = sceditor.val(),
            str_arr = str.match(regex),
            str_len = str_arr == null ? 0 : str_arr.length;
            if (str_len <= NombreDeMots)
            jQuery('input[type=\'submit\'][name=\'post\']').attr('disabled', false).css('opacity', '1');
            sceditor.keyUp(function (e) {
              str = sceditor.val();
              str_arr = str.match(regex);
              str_len = str_arr == null ? 0 : str_arr.length;
              if (str_len <= NombreDeMots) {
                jQuery('input[type=\'submit\'][name=\'post\']').attr('disabled', false).css('opacity', '1');
              } else {
                jQuery('#div_minchars_info').html('<img src=\'' + icone_incomplet + '\' alt=\'\' /> Vous avez écrit <span style=\'color:red\'>' + str_len + '</span> mot(s). Votre message est trop long pour être posté dans cette section.');
                jQuery('input[type=\'submit\'][name=\'post\']').attr('disabled', true).css('opacity', '0.5');
              }
            });
          }
        })});

Je sais que c'est cette partie-là du premier code qui permet de ne pas prendre en compte les balises, mais je ne sais pas comment l'adapter pour l'intégrer au deuxième :
Code:
var wc= function(){
      var t= e.val().replace(/\[.*?\]/g,' ').replace(/<.*?>/g,' ').replace(/[\x00-\x40\x5b-\x60\x7b-\x7e]/g,' ');
      w.html('Mots : '+(t.match(/\S{2,}/g)||[]).length);
      wordcount_signaled= false
    };

Merci d'avance si quelqu'un peut m'aider =)
IzumiRK

IzumiRK
****

Messages : 206
Inscrit(e) le : 25/02/2015

http://indare.forumactif.com/
IzumiRK a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Insérer un maximum/minimum de mots avant de poster un message

Message par IzumiRK Dim 27 Mai 2018 - 22:57

Up
IzumiRK

IzumiRK
****

Messages : 206
Inscrit(e) le : 25/02/2015

http://indare.forumactif.com/
IzumiRK a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Insérer un maximum/minimum de mots avant de poster un message

Message par w00tw00t Lun 28 Mai 2018 - 17:12

Bonjour IzumiRK,

Insérer un maximum/minimum de mots avant de poster un message JKEXZc5

J'ai refactor les différents codes pour répondre à vos besoins :

Code:
/* On retourne immédiatement, si l'on est pas sur une page de réponse (rapide ou complète) ou de prévisualisation */
if( window.location.pathname.indexOf('/t') === 0 || 0 === window.location.pathname.indexOf('/post') ){

    const SCEDITOR_MAX_WORDS = 10;
    const SCEDITOR_LETTERS_BY_WORD = 2;

    const SCEDITOR_PARENTS = ['/c1','/f1']; /* ici seulement dans le forum f1 de la catégorie c1 */
                                                                /* mettre null pour le mettre en place sur tous les forums */

    const SCEDITOR_WORDS_FILTER_REGEX = new RegExp('[\\w\\u00DF-\\u00F6\\u00F8-\\u00FD\\u0153]{' + SCEDITOR_LETTERS_BY_WORD + ',}', 'gi');

    const SCEDITOR_ICON_1 = 'https://2img.net/i/fa/admin/icones/ajouter.png';
    const SCEDITOR_ICON_2 = 'https://2img.net/i/fa/admin/icones/supprimer.png';

    $(function(){$(function(){
        const $editor = $('#text_editor_textarea:first');
        const $editor_form = $editor.parents('form:first');
        const $sc_container = $('.sceditor-container:first');
        const $sc_submit = $('input[type="submit"][name="post"]:first');
        const sc_chars_info_id = 'div_chars_info';
        const sc_add_html = '<div id="'+sc_chars_info_id+'"></div>';
        let $sc_chars_info = null;
        if( $editor.length !== 0 && typeof $.fn.sceditor !== "undefined" ){

            const editor = $editor.sceditor('instance');
            if( typeof editor !== "undefined" ){

                const checkParentsLinks = ( parents ) => {
                    try {
                        const rdf_raw = $('script[type="application/ld+json"]:first').html();
                        const rdf = JSON.parse(rdf_raw);
                        let i = 0;
                        if( rdf.hasOwnProperty('@type') && 'BreadcrumbList' === rdf['@type'] ){
                            const items = rdf['itemListElement'];
                            for(item of items){
                                if( typeof item['item'] !== "undefined" && "undefined" !== typeof item['item']['@id']){
                                    const uri = item['item']['@id'];
                                    if( uri.indexOf(parents[i]) !== -1 ){
                                        i++;
                                    }
                                } else {
                                    return false;
                                }
                            }
                            return i === parents.length;
                        }
                    } catch(e){
                        console.error(e);
                    }
                    return false;
                };

                const SCEditorFormGetTID = () => {
                    return Number.parseInt($editor_form.find('input[name="t"]').val());
                };

                const SCEditorSubmitDisable = () => {
                    $sc_submit
                        .attr('disabled', true)
                        .css('opacity', '0.5');
                };
                const SCEditorSubmitEnable = () => {
                    $sc_submit
                        .attr('disabled', false)
                        .css('opacity', '1');
                };
                const SCEditorBuildHTMLCount = (color,words_count) => {
                    return '<span style="color:'+color+'">' + words_count + '</span>';
                };
                const SCEditorBuildHTMLMessageCommon = (img_src,img_alt,words_count,color) => {
                    return '<img src="' + img_src + '" alt="'+img_alt+'" /> Vous avez écrit '+SCEditorBuildHTMLCount(color,words_count)+' mot'+(words_count > 1?'s':'')+'.';
                };
                const SCEditorBuildHTMLMessageRemaining = (words_count,color) => {
                    const x = SCEDITOR_MAX_WORDS - words_count;
                    const p = x>1?'s':'';
                    return ' ' + SCEditorBuildHTMLCount(color,x) + ' mot'+p+' restant'+p+'.';
                };
                const SCEditorBuildHTMLMessageDelete = (words_count,color) => {
                    const x = words_count - SCEDITOR_MAX_WORDS;
                    const p = x>1?'s':'';
                    return ' Retirez '+SCEditorBuildHTMLCount(color,x)+' mot'+p+' pour pouvoir poster.';
                };
                const SCEditorCheckWords = () => {

                    const words_count = (
                        editor
                            .val()
                            .replace(/\[.*?\]/g,' ')
                            .replace(/<.*?>/g,' ')
                            .match(SCEDITOR_WORDS_FILTER_REGEX)
                        || []
                    ).length;

                    if( words_count <= SCEDITOR_MAX_WORDS ){
                        const color = 'green';
                        $sc_chars_info.html( SCEditorBuildHTMLMessageCommon(SCEDITOR_ICON_1,'Vous pouvez continuer à écrire',words_count,color) + SCEditorBuildHTMLMessageRemaining(words_count,color) );
                        SCEditorSubmitEnable();
                    } else {
                        const color = 'red';
                        $sc_chars_info.html( SCEditorBuildHTMLMessageCommon(SCEDITOR_ICON_2,'Supprimer des mots pour pouvoir poster',words_count,color) + SCEditorBuildHTMLMessageDelete(words_count,color) );
                        SCEditorSubmitDisable();
                    }

                };

                [SCEDITOR_ICON_1,SCEDITOR_ICON_2].forEach(i => {(new Image()).src = i;});

                if( typeof SCEDITOR_PARENTS !== "undefined" && SCEDITOR_PARENTS !== null ){
                    if( !checkParentsLinks( SCEDITOR_PARENTS ) ){
                        return ;
                    }
                }

                SCEditorSubmitDisable();

                $sc_container.after(sc_add_html);
                $sc_chars_info = $('#' + sc_chars_info_id);

                SCEditorCheckWords();
                editor.keyUp(SCEditorCheckWords);
            }
        }
    });});
}

J'ai testé le tout avec succès sur des installations propres phpBB2 / phpBB3 / ModernBB, mais il peut nécessiter des modifications selon votre environnement.

A noter que le script est configurable :
Code:
const SCEDITOR_MAX_WORDS = 10;
const SCEDITOR_LETTERS_BY_WORD = 2;
const SCEDITOR_PARENTS = ['/c1','/f1'];

Donc avec 230 mots, en ne considérant des mots que de plus de 2 caractères, et exclusivement dans la catégorie "c1" :
Code:
const SCEDITOR_MAX_WORDS = 230;
const SCEDITOR_LETTERS_BY_WORD = 2;
const SCEDITOR_PARENTS = ['/c1'];

Forumactif intègre du RDF (Web Sémantique), c'est pourquoi ce code se base la dessus pour récupérer la hiérarchie de forums et de catégories. On aurait aussi pu procéder avec une requête AJAX fallback.

A noter qu'il s'agit d'empêcher quelqu'un d'écrire plus de X mots coté client (JavaScript), mais qu'une personne compétente pourra toujours contourner cette limitation.

Je reste à votre disposition pour plus de détails,

Cordialement,
w00tw00t


Dernière édition par w00tw00t le Mar 29 Mai 2018 - 13:01, édité 1 fois
w00tw00t

w00tw00t
***

Messages : 118
Inscrit(e) le : 09/05/2018

http://forum.forumactif.org
w00tw00t a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Insérer un maximum/minimum de mots avant de poster un message

Message par IzumiRK Mar 29 Mai 2018 - 2:32

Ca ne marche pas chez moi, il n'y a aucune différence entre avant ou après l'installation du code =/
Rien en s'affiche, et rien ne bloque le postage de nouveaux messages ou de réponses si le texte est trop long. J'ai tenté en supprimant l'autre compteur de mots, mais ça n'a rien changé =/
IzumiRK

IzumiRK
****

Messages : 206
Inscrit(e) le : 25/02/2015

http://indare.forumactif.com/
IzumiRK a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Insérer un maximum/minimum de mots avant de poster un message

Message par w00tw00t Mar 29 Mai 2018 - 7:06

Bonjour IzumiRK,

Il semble que vous avez utilisé le script sans le personnaliser.

Suivez ces étapes simples :
1. supprimer le script que je vous ai fourni.
2. copier/coller le à nouveau depuis ce sujet pour le mettre en tant que nouveau JavaScript sur toutes vos pages.
3. remplacer :

Code:
const SCEDITOR_PARENTS = ['/c1','/f1'];

Par :

Code:
const SCEDITOR_PARENTS = null;

En mettant la valeur à null, le script devrait s'exécuter sur toutes vos réponses rapides / réponses, peu importe la catégorie / sous-forum.

Si ça fonctionne, cela veut dire que vous aviez laisser la configuration par défaut ['/c1','/f1'], qui signifie que le système se déclenche uniquement lorsque vous écrivez une réponse dans le forum "f1" et de la catégorie "c1". Or votre forum ne possède peut être pas de forum "f1" dans une catégorie "c1". Cette option est donc à adapter à vos besoins.

N'hésitez pas à revenir vers moi au besoin,

Cordialement,
w00tw00t
w00tw00t

w00tw00t
***

Messages : 118
Inscrit(e) le : 09/05/2018

http://forum.forumactif.org
w00tw00t a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Insérer un maximum/minimum de mots avant de poster un message

Message par IzumiRK Sam 2 Juin 2018 - 12:58

Je l'avais personnalisé, mais je l'ai remis à la version par défaut pour voir si c'était ma personnalisation qui ne fonctionnait pas, en allant le tester du coup dans le forum f1. C'est pour ça que c'est la version par défaut qui est sur mon forum. Le message était assez bien expliqué pour que je sache à quoi correspondait cette ligne de code
IzumiRK

IzumiRK
****

Messages : 206
Inscrit(e) le : 25/02/2015

http://indare.forumactif.com/
IzumiRK a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Insérer un maximum/minimum de mots avant de poster un message

Message par w00tw00t Sam 2 Juin 2018 - 13:34

Bonjour IzumiRK,

D'accord, il me faudrait constater plus en détails les spécificités de votre forum.

Pouvez-vous me fournir par MP un compte de test sur votre forum ? Cela facilitera grandement le débogage

Cordialement,
w00tw00t
w00tw00t

w00tw00t
***

Messages : 118
Inscrit(e) le : 09/05/2018

http://forum.forumactif.org
w00tw00t a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Insérer un maximum/minimum de mots avant de poster un message

Message par IzumiRK Dim 3 Juin 2018 - 19:09

Qu'est-ce que vous appelez un "compte de test" ? Ce n'est pas possible de juste ajouter une ligne dans le deuxième code, tout simplement ?
IzumiRK

IzumiRK
****

Messages : 206
Inscrit(e) le : 25/02/2015

http://indare.forumactif.com/
IzumiRK a été remercié(e) par l'auteur de ce sujet.
  • 0

Résolu Re: Insérer un maximum/minimum de mots avant de poster un message

Message par w00tw00t Dim 3 Juin 2018 - 21:31

Bonjour IzumiRK,

En fait le compte de test est juste un compte sur votre forum sans droits particuliers que vous fournissez à la personne qui vous aide. Il est souvent nécessaire dans le cas ou un script fonctionne avec succès dans un environnement de base, mais ne fonctionne plus sur un environnement plus spécifique.

J'ai néanmoins réussi à me débrouiller autrement. Je vous propose le nouveau code suivant :

Code:
/* On retourne immédiatement, si l'on est pas sur une page de réponse (rapide ou complète) ou de prévisualisation */
if( window.location.pathname.indexOf('/t') === 0 || 0 === window.location.pathname.indexOf('/post') ){

    const SCEDITOR_MAX_WORDS = 10;
    const SCEDITOR_LETTERS_BY_WORD = 2;

    const SCEDITOR_PARENTS = ['/c9','f39']; /* ici seulement dans le forum c9 de la catégorie f39 */
                                            /* mettre null pour le mettre en place sur tous les forums */

    const SCEDITOR_WORDS_FILTER_REGEX = new RegExp('[\\w\\u00DF-\\u00F6\\u00F8-\\u00FD\\u0153]{' + SCEDITOR_LETTERS_BY_WORD + ',}', 'gi');

    const SCEDITOR_ICON_1 = 'https://2img.net/i/fa/admin/icones/ajouter.png';
    const SCEDITOR_ICON_2 = 'https://2img.net/i/fa/admin/icones/supprimer.png';

    $(function(){$(function(){
        const $editor = $('#text_editor_textarea:first');
        const $editor_form = $editor.parents('form:first');
        const $sc_container = $('.sceditor-container:first');
        const $sc_submit = $('input[type="submit"][name="post"]:first');
        const sc_chars_info_id = 'div_chars_info';
        const sc_add_html = '<div id="'+sc_chars_info_id+'"></div>';
        let $sc_chars_info = null;
        if( $editor.length !== 0 && typeof $.fn.sceditor !== "undefined" ){

            const editor = $editor.sceditor('instance');
            if( typeof editor !== "undefined" ){

                const checkParentsLinks = ( parents ) => {
                    try {
                        let i = 0;
                        const seen = [];
                        $('#page-body span.nav a.nav[href^="/"]').each(function(){
                            const $this = $(this);
                            const href = $this.attr('href');
                      if(typeof href !== "undefined" && href !== null && (seen.length === 0 || -1 === $.inArray(href,seen))){
                                if( href.indexOf(parents[i]) !== -1 ){
                                    seen.push(href);
                                    i++;
                                }
                            }
                        });
                        return i >= parents.length;
                    } catch(e){
                        console.error(e);
                    }
                    return false;
                };

                const SCEditorFormGetTID = () => {
                    return Number.parseInt($editor_form.find('input[name="t"]').val());
                };

                const SCEditorSubmitDisable = () => {
                    $sc_submit
                        .attr('disabled', true)
                        .css('opacity', '0.5');
                };
                const SCEditorSubmitEnable = () => {
                    $sc_submit
                        .attr('disabled', false)
                        .css('opacity', '1');
                };
                const SCEditorBuildHTMLCount = (color,words_count) => {
                    return '<span style="color:'+color+'">' + words_count + '</span>';
                };
                const SCEditorBuildHTMLMessageCommon = (img_src,img_alt,words_count,color) => {
                    return '<img src="' + img_src + '" alt="'+img_alt+'" /> Vous avez écrit '+SCEditorBuildHTMLCount(color,words_count)+' mot'+(words_count > 1?'s':'')+'.';
                };
                const SCEditorBuildHTMLMessageRemaining = (words_count,color) => {
                    const x = SCEDITOR_MAX_WORDS - words_count;
                    const p = x>1?'s':'';
                    return ' ' + SCEditorBuildHTMLCount(color,x) + ' mot'+p+' restant'+p+'.';
                };
                const SCEditorBuildHTMLMessageDelete = (words_count,color) => {
                    const x = words_count - SCEDITOR_MAX_WORDS;
                    const p = x>1?'s':'';
                    return ' Retirez '+SCEditorBuildHTMLCount(color,x)+' mot'+p+' pour pouvoir poster.';
                };
                const SCEditorCheckWords = () => {

                    const words_count = (
                        editor
                            .val()
                            .replace(/\[.*?\]/g,' ')
                            .replace(/<.*?>/g,' ')
                            .match(SCEDITOR_WORDS_FILTER_REGEX)
                        || []
                    ).length;

                    if( words_count <= SCEDITOR_MAX_WORDS ){
                        const color = 'green';
                        $sc_chars_info.html( SCEditorBuildHTMLMessageCommon(SCEDITOR_ICON_1,'Vous pouvez continuer à écrire',words_count,color) + SCEditorBuildHTMLMessageRemaining(words_count,color) );
                        SCEditorSubmitEnable();
                    } else {
                        const color = 'red';
                        $sc_chars_info.html( SCEditorBuildHTMLMessageCommon(SCEDITOR_ICON_2,'Supprimer des mots pour pouvoir poster',words_count,color) + SCEditorBuildHTMLMessageDelete(words_count,color) );
                        SCEditorSubmitDisable();
                    }

                };

                [SCEDITOR_ICON_1,SCEDITOR_ICON_2].forEach(i => {(new Image()).src = i;});

                if( typeof SCEDITOR_PARENTS !== "undefined" && SCEDITOR_PARENTS !== null ){
                    if( !checkParentsLinks( SCEDITOR_PARENTS ) ){
                        return ;
                    }
                }

                SCEditorSubmitDisable();

                $sc_container.after(sc_add_html);
                $sc_chars_info = $('#' + sc_chars_info_id);

                SCEditorCheckWords();
                editor.keyUp(SCEditorCheckWords);
            }
        }
    });});
}

Puisque j'ai configuré l'exécution pour le forum f39 de la catégorie c9, il vous faudra tester dans un premier temps avec ce topic par exemple :
http://indare-division.forumactif.com/t1408-ralentissement

Pensez également à désactiver tout anciens scripts sur le sujet.

Laissez moi savoir si cela fonctionne sur votre environnement,

Cordialement,
w00tw00t
w00tw00t

w00tw00t
***

Messages : 118
Inscrit(e) le : 09/05/2018

http://forum.forumactif.org
w00tw00t a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Insérer un maximum/minimum de mots avant de poster un message

Message par IzumiRK Mar 5 Juin 2018 - 11:16

Ca fonctionne parfaitement merci beaucoup =)
IzumiRK

IzumiRK
****

Messages : 206
Inscrit(e) le : 25/02/2015

http://indare.forumactif.com/
IzumiRK a été remercié(e) par l'auteur de ce sujet.

Voir le sujet précédent Voir le sujet suivant Revenir en haut

- Sujets similaires

Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum