• Troll hunter - Le Monolecte
    https://blog.monolecte.fr/2021/02/14/troll-hunter
    https://blog.monolecte.fr/wp-content/uploads/2021/02/eliandstevePT.webp

    Sur internet, il n’y a personne et en même temps, il y a tout le monde. Tu peux éclater la gueule de quelqu’un à grands coups d’insultes ou de rhétorique tordue, tu peux harceler ou invisibiliser, tu peux démolir systématiquement une personne, son œuvre, sa pensée, sa vie, comme ça, bien tranquille derrière ton clavier, sans aucune espèce de conscience, sans ne jamais être exposé aux conséquences. Tu peux décharger ta frustration, ta colère, ta haine, ton trop-plein de merditude, sans l’impact sourd du gnon dans la bidoche, sans les cris qui pètent le tympan, sans le sang et les ratiches qui te sautent à la gueule. Tu peux boxer sans te niquer les jointures et sans risquer de te faire éclater la tronche ou réajuster le portrait.
    Sauf que ce n’est pas aussi simple que ça.

  • Un critere {par_ordre_liste champ,#LISTE{...}} qui permet d’ordonner explicitement les resultat d’une boucle selon un tableau · 1b6c328268 - spip - SPIP on GIT
    https://git.spip.net/spip/spip/commit/1b6c32826813ac67144a96bb94b95ce5e834a290

    Doc temporaire d’une nouvelle (super !) feature : le critère par_ordre_liste :

    Un critere {par_ordre_liste champ,#LISTE{...}} qui permet d’ordonner explicitement les resultat d’une boucle selon un tableau

    Cela donne le meme resultat que si on utilise un {champ IN ...} sauf que
    – le critere IN classe uniquement par defaut selon le tableau fournit, et cet ordre est ecrase si on a un autre critere, ou une jointure
    – le {par_ordre_liste} permet de separer la selection du classement
    – on peut le combiner avec d’autres {par...} dans l’ordre que l’on veut

    #spip #critère #par_ordre_liste

  • À l’aide, @SPIP : j’essaie de convertir un de mes plugins qui permet d’uploader un fichier via un formulaire CVT dans l’espace privé, pour qu’il fonctionne avec BigUp.

    J’arrive maintenant à obtenir l’interface, et le glisser-déposer d’un gros fichier semble se faire jusqu’au bout. Mais à la fin de l’upload (avec la prévisuation, la vignette et la barre de progression), ça se contente de faire disparaître la barre de progression et ça remplace le bouton « Annuler » par le bouton « Enlever ».

    Mais l’action voulue (traiter l’image dans la partie traiter du formulaire) n’est pas du tout déclenchée.

    Mais je ne trouve ni exemple d’utilisation de BigUp en dehors des éléments natifs de l’interface, dans un autre plugin par exemple, ni documentation détaillée de ce qu’il faut faire côté PHP.

    Est-ce qu’il y a un /formulaire quelque part dans l’espace SPIP, par exemple dans un plugin, qui me permettrait de comprendre comment je dois procéder ?

    • Oui. Et notamment ceci que je ne comprends pas :

      Pour recréer le tableu $_FILES tel que le crée habituellement PHP, il faut connaître la valeur de l’attribut name de la balise input.

      Cette valeur est transmise avec le token calculé, et est inscrite dans le chemin de cache des fichiers reçu. Cela permet, à partir d’un fichier cache donné, de recréer le $_FILES qui lui correspondait.

      Apparemment, je ne récupères pas de valeur $_FILES dans mon _traiter ($_FILES qui fonctionne en mode « non bigup ») . Est-ce qu’il y a quelque chose à faire pour récupérer ce tableau calculé à partir du token, et si oui : quoi ?

    • Non plus. J’avais déjà ajouté :

              if (!$_FILES) {
                      $_FILES = isset($GLOBALS['HTTP_POST_FILES']) ? $GLOBALS['HTTP_POST_FILES'] : array();
              }

      qui ne m’apporter rien (je ne vois pas d’infos concernant le fichier installé ni dans $_FILES ni dans $_GLOBALS).

    • Ah… il faut ajouter

      $valeurs['_bigup_rechercher_fichiers'] = true;

      dans la partie _charger du formulaire.

      C’est écrit de manière un peu critique dans le README :

      Au chargement d’un formulaire CVT, si la clé _bigup_rechercher_fichiers est présente, le plugin Bigup se chargera de retrouver les fichiers déjà chargés pour ce formulaire et d’ajouter leur liste, pour chaque champ concerné du formulaire, dans l’environnement.

    • Grrrr, ça marchait ça marche plus, et je n’arrive pas à voir pourquoi.

      Quand je valide mon formulaire (après l’upload via Bigup), je me cogne un vilain écran d’erreur :

      Fatal error: Uncaught Error: [] operator not supported for strings in /home/clients/d674084bbe9c0c511a4685e13dee1efb/web/fabre/plugins-dist/bigup/inc/Bigup/Files.php:163 Stack trace: #0 /home/clients/d674084bbe9c0c511a4685e13dee1efb/web/fabre/plugins-dist/bigup/inc/Bigup.php(93): Spip\Bigup\Files::integrer_fichier('upload_fond_hot...', Array) #1 /home/clients/d674084bbe9c0c511a4685e13dee1efb/web/fabre/plugins-dist/bigup/bigup_pipelines.php(169): Spip\Bigup\Bigup->reinserer_fichiers(Array) #2 /home/clients/d674084bbe9c0c511a4685e13dee1efb/web/fabre/ecrire/inc/utils.php(199): bigup_formulaire_receptionner(Array) #3 /home/clients/d674084bbe9c0c511a4685e13dee1efb/web/fabre/tmp/cache/charger_pipelines.php(640): minipipe('bigup_formulair...', Array) #4 /home/clients/d674084bbe9c0c511a4685e13dee1efb/web/fabre/ecrire/inc/utils.php(265): execute_pipeline_formulaire_receptionner(Array) #5 /home/clients/d674084bbe9c0c511a4685e13dee1efb/web/fabre/ecrire/public/aiguiller.php(212): pipeline('formulaire_rece...', Array) #6 /home/clients in /home/clients/d674084bbe9c0c511a4685e13dee1efb/web/fabre/plugins-dist/bigup/inc/Bigup/Files.php on line 163

      [EDIT] Corrigé : il faut que le formulaire soit dans une classe .ajax (donc formulaire Ajax).

    • En revanche, il me reste un truc que je ne trouve pas : comment je fais pour que le formulaire se valide dès que ça a terminé l’upload ?

      Ça le fait pour les logos et pour les documents joints, mais je ne trouve pas comment faire pour mon propre formulaire. Parce que pour l’instant, j’ai le barre d’upload, puis ça affiche la petit vignette, le nom du fichier et son poids, mais il faut encore que le valide le formulaire (« Téléverser »).

    • ça peut être fait en surchargeant l’appel de bigup de la façon suivante :

      $('input.bigup').bigup({}, {
              complete: function(){
                      $('.formulaire_bigform form').submit();
              }
      }).on('bigup.fileSuccess', function(){
              setTimeout("ajaxReload('docs_ressource')", 2000);
      });

      (dans cet exemple qui se joue en page publique, la 2ème partie permet de recharger la liste des docs affichés)

    • En tout cas, merci les amis, c’est vraiment une belle bête ce Big-Up. J’avais hâte de réussir à faire tourner mon propre formulaire avec. Surtout que c’est précisément un endroit où j’ai généralement besoin d’installer des gros fichiers…

  • @spip, je viens d’installer un #SPIP_3.2.7, sur un serveur où il est possible que j’ai des droits un peu bizarres (c’est pas moi qui héberge). Et ça m’indique :

    Le cache est temporairement désactivé.

    Le bouton « réactiver le cache » n’y fait rien. J’ai vu un message dans les archives de la liste, mais pas de réponse. Il y a des pistes ?

  • J’ai un comportement bizarre (et j’ai l’impression que c’est très très récent) avec Inscriptions3. Il s’agit du champ « Date de naissance ».

    Au premier affichage du formulaire, au lieu d’avoir les 3 cases Day/Month/Year, j’ai un simple champ texte avec marqué « 0000-00-00 ». C’est ce comportement que je ne comprends pas. Et qui me semble être apparu très récemment (genre ces jours-ci).

    Si je renseigne avec ma date de naissance, c’est très marrant (je m’amuse de peu) : les 3 champs séparés reviennent, correctement remplis (sauf que Month a un zéro-cinq, alors que Day a cinq-tout-court…). Et cette question : « Avez-vous vraiment plus de 110 ans ? », alors que les champs sont correctement remplis.

    Je resoumets le formulaire (en naissance d’autres champs vides histoire de pas valider), et cette entrée « Birthday » semble désormais correcte (pas de message d’erreur à ce niveau, mais toujours le même affichage de 5-05-1970).

    • Message d’erreur Javascript : j’ai du code avec jQuery() qui s’insère dans la page, et même un appel à saisies.js, alors que mes squelettes concatènet tout les JS, et que je fais l’appel asynchrone par ma propre méthode. Alors ça plante.

      Pourquoi Saisies n’a pas le fonctionnement standard pour insérer du JS ? Et je fais quoi maintenant ?

    • Et effectivement, en virant mon propre code qui insère async dans l’appel des JS, et en ajoutant le fameux :

      define("_JS_ASYNC_LOAD", true);

      ça refonctionne.

      Mais je continue à penser que les plugins devraient avoir un fonctionnement compatible avec un chargement asynchrone des scripts avec la méthode la plus basique – <script async>

    • De ma courte expérience des plugins de SPIP, c’est le seul qui fait ça, et qui du coup provoque une erreur dans mes pages, où j’utilise un #FILTRE en fin de traitement pour, assez simplement, transformer <script href> en <script async href>.

      Et là, comme c’est balancé en affichage_final, je ne peux donc pas le modifier. Et donc je suis obligé de me plier à la méthode intégrée à SPIP 3.1, avec _JS_ASYNC_LOAD, qui transforme profondément la façon d’appeler le Javascript avec insertion de code façon usine à gaz.

      Je veux bien que ça marche, mais m’embête tout de même beaucoup de voir ajouté à mes pages un code que je ne contrôle pas du tout, qui est rigoureusement incompréhensible, et qui ressemble à ceci :

      var jQl={q:[],dq:[],gs:[],ready:function(a){"function"==typeof a&&jQl.q.push(a);return jQl},getScript:function(a,c){jQl.gs.push([a,c])},unq:function(){for(var a=0;a<jQl.q.length;a++)jQl.q[a]();jQl.q=[]},ungs:function(){for(var a=0;a<jQl.gs.length;a++)jQuery.getScript(jQl.gs[a][0],jQl.gs[a][1]);jQl.gs=[]},bId:null,boot:function(a){"undefined"==typeof window.jQuery.fn?jQl.bId||(jQl.bId=setInterval(function(){jQl.boot(a)},25)):(jQl.bId&&clearInterval(jQl.bId),jQl.bId=0,jQl.unqjQdep(),jQl.ungs(),jQuery(jQl.unq()), "function"==typeof a&&a())},booted:function(){return 0===jQl.bId},loadjQ:function(a,c){setTimeout(function(){var b=document.createElement("script");b.src=a;document.getElementsByTagName("head")[0].appendChild(b)},1);jQl.boot(c)},loadjQdep:function(a){jQl.loadxhr(a,jQl.qdep)},qdep:function(a){a&&("undefined"!==typeof window.jQuery.fn&&!jQl.dq.length?jQl.rs(a):jQl.dq.push(a))},unqjQdep:function(){if("undefined"==typeof window.jQuery.fn)setTimeout(jQl.unqjQdep,50);else{for(var a=0;a<jQl.dq.length;a++)jQl.rs(jQl.dq[a]); jQl.dq=[]}},rs:function(a){var c=document.createElement("script");document.getElementsByTagName("head")[0].appendChild(c);c.text=a},loadxhr:function(a,c){var b;b=jQl.getxo();b.onreadystatechange=function(){4!=b.readyState||200!=b.status||c(b.responseText,a)};try{b.open("GET",a,!0),b.send("")}catch(d){}},getxo:function(){var a=!1;try{a=new XMLHttpRequest}catch(c){for(var b=["MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"],d=0;d<b.length;++d){try{a= new ActiveXObject(b[d])}catch(e){continue}break}}finally{return a}}};if("undefined"==typeof window.jQuery){var $=jQl.ready,jQuery=$;$.getScript=jQl.getScript};

      Une grosse grosse partie de mon temps de travail est consacré à chercher pourquoi tel script ne fonctionne pas selon mes besoins, et assez souvent pourquoi tel script a cessé de fonctionner alors qu’avant il fonctionnait. Des bouts de code pareil, avant même de charger quelque script que ce soit (dont, pour une large part, je serais l’auteur), c’est pas du tout rassurant. :-)

      (Et en plus, c’est typiquement une façon d’appeler les scripts qui fait que je ne peux plus aspirer simplement un site avec mon wget usuel.)

      Je pense que, tout en profitant des avantages de ce script, on devrait s’astreindre à coder nos plugins pour que leur Javascript fonctionne déjà avec la méthode usuelle désormais conseillée, c’est-à-dire le simple appel <script href async>.

    • Mais saisies.js je le répète est bien inséré avec une balise <script> tout ce qu’il y a de plus normale, le script n’a rien de bizarre et il est parfaitement compatible avec un appel avec async, pour peu que quelque chose le rajoute (ou bien faudrait le mettre par défaut ?).

      Le code que tu colles est volontairement minifié pour qu’il soit plus rapide à charger alors ça n’a aucun sens de dire qu’il est incompréhensible. La vraie version étant en plus juste à côté, longue et bien commentée :
      https://git.spip.net/SPIP/compresseur/src/branch/master/lib/jQl/jQl.js

    • Sauf erreur : comme saisies.js est inséré par affichage_final, je n’y ai pas accès avec mon #FILTRE ramasse-miettes qui, justement, transforme les <script en <script async.

      Par ailleurs, si j’y avais accès, je ne sais pas comment se comporteraient des appels async à deux fichiers différents, sachant que saisies.js a besoin que jQuery.js soit chargé avant.

      Enfin, il reste le fait que du code Javascript, faisant appel à la variable jQuery, est inséré « en dur » dans la page elle-même :

      jQuery(document).ready(function(){
              activer_dateur_b0a2d9();
      });

      Et du coup je me rend compte que BigUpload aussi insère du code fautif directement dans ma page :

      jQuery.bigup_config = {maxFileSize: 10, formatsLogos: ["gif","jpg","png"]}

      Donc dans tous les cas, si je n’active pas la méthode _JS_ASYNC_LOAD, ces deux plugins planteront forcément avec un appel simple de type <script href async>.

    • Bé oui, c’est le principe dans un CMS dynamique modulaire, avec des plugins, tu ne pourras jamais, absolument jamais, t’assurer que 100% des JS sont tous ensemble, dans le bon ordre et qu’ils peuvent être appelés en async sans que toi tu connaisses leur ordre. Il y en a forcément qui pour tel ou tel besoin (GIS aussi par exemple) vont devoir charger du JS inline ici ou là.

      C’est bien pour ça que même avec la nouvelle méthode HTML5, la librairie JQL est utile, puisqu’elle permet avec un minuscule JS qui se charge obligatoirement en tout premier, de prendre en charge TOUS les morceaux de JS, y compris ceux inline n’importe où dans la page, et s’assurer qu’ils seront lancés uniquement lorsque jQuery sera certain d’être chargé, c’est son boulot.

    • Je ne comprends pas que, tout d’un coup, je me retrouve dans la position de celui qui demande à ce qu’on code proprement. :-))

      Ce n’est pas difficile de ne pas insérer de code jQuery dans le corps de la page, quand on prévoit que jQuery sera chargé et déclenché après le chargement de la page. À partir du moment où tout est prévu, niveau Web, pour travailler avec <script async>, ça devient vraiment farfelu de décider de faire reposer notre écosystème sur une bibliothèque (vraiment compliquée, même dans sa version d’origine), alors que toute la planète fait autrement, au motif qu’il y a deux bouts de ligne de code dans un de nos plugins qu’on pourrait décider de coder autrement (et généralement pas compliqué).

      Faire dépendre la compatibilité future de nos sites Web avec les futures versions de jQuery sur un morceau de code dont je suis persuadé que seul Cédric est capable de le maintenir, ou au moins de le modifier rapidement, ce n’est pas sain.