web-dev-qa-db-fra.com

Est-il possible de surmonter certaines limitations (de crash de site) sur WP_Query dans un shortcode?

En produisant un plugin relativement complexe produisant beaucoup de code HTML via un widget, une fonction insérée dans un modèle ou un shortcode, j'ai rencontré un problème ou un ensemble de limitations qui s'applique uniquement à la version shortcode utilisée dans le contenu de publication.

Le plug-in génère une table construite via WP_Query. Jusqu'à ce nouveau point d'achoppement, je ne pouvais rien produire via un widget ou un modèle que je ne pouvais pas produire également dans le shortcode.

Pour condenser beaucoup de code dans une simple déclaration du problème, le tableau $ query_args inclut un argument "cat":

Donc, quelque chose comme:

$query_args = array(

    'order'             => $order,
    'orderby'           => $orderby,
    'showposts'         => $number_posts,
    'post_status'       => 'publish',
    'cat'               => $cat_id,
    'category__not_in'  => $exclude_array,
    'category__in'      => $include_array,
    'date_query'        => $date_query,

) ;

$my_query = new WP_Query( 
        apply_filters( 'cks_lpa_table_query_sc' , $query_args ) 
        ) ;

if ( $my_query->have_posts() ) {

//assemble and output the table

Dans les utilisations normales du plug-in ou de la table basée sur les boucles qu'il produit, la clé 'cat' a toujours pour valeur une catégorie (ou liste de catégories) identifiée par son ID. Si 'cat' est laissé vide dans les widgets ou la fonction de modèle, les fonctions produisent une boucle de publications en fonction de tout autre paramètre, mais si 'cat' est laissé vide (ou n'est pas fourni du tout) dans la publication ou la page via shortcode ( ainsi dans la boucle principale), le résultat est un crash de site plutôt catastrophique - et pas même avec une "erreur fatale" rapide, mais avec une erreur de réinitialisation de connexion lente (ERR_CONNECTION_RESET).

Les objectifs atteints en permettant "aucun" chat "ne sont pas critiques pour les utilisations principales du plug-in, et empêcher les utilisateurs de planter leurs sites de cette manière n'est pas difficile, mais je me demande toujours s'il existe un autre facteur. Je devrais envisager, ou un moyen de contourner le problème.

Je me demande également ce qui se passe exactement sous le capot. Il serait donc utile de donner des conseils pour enquêter sur le problème des outils d’inspection.

EDIT: Voir sa propre réponse ci-dessous.

2
CK MacLeod

Oups - trop tard pour retirer la question, je suppose - mais je me suis rendu compte au cours d'une promenade que la réponse était évidente: la requête dans la requête principale crée une boucle infinie, car la publication contenant le code court serait dans la boucle principale, donc ouvre un trou dans l'univers etc.

Nous examinerons les moyens de traiter et d'isoler le problème/le danger ...

EDIT: Je veux juste noter en plus, en plus, que je crois que le problème n’a rien à voir avec la clé spécifique $ query_args ou avec les codes courts en tant que tels . Comme je viens de le vérifier, le problème est de placer une publication dont le contenu inclurait une version de la publication elle-même (contenant une version de la publication elle-même, etc.), d'où la "réinitialisation de la surcharge" plutôt qu'une erreur fatale.

Pour résoudre ce problème ou éviter ce danger éventuel à l'avenir, je pense qu'il est nécessaire d'ajouter une sous-routine qui exclut tout message offensant ou tout contenu signalant, de la boucle dans la boucle à laquelle se trouve le plug-in. sortie. Depuis que j'occupe l'espace de WordPress Dev en explorant ce problème (initialement incorrect), je posterai une réponse plus complète, code inclus, si/quand je le pourrai.

ADDENDA: SOLUTIONS

Tout d’abord, une remarque: je vois maintenant que, dans les versions précédentes du plug-in, avant même de commencer à jouer avec une plage de $ query_args, un crash de site involontaire via un bouclage infini était toujours un danger, présumant que le bon coup mal choisi par un utilisateur.

Je pense que la solution la plus simple et la plus simple consiste simplement à exclure toutes les publications contenant le shortcode de la boucle dans la boucle. L’insertion de ce qui suit dans la nouvelle boucle de requête ou dans la boucle (après $ my_query-> the_post ();), en supposant qu’un shortcode "tag" de "add_loopy_table," il:

  //$post was already here for other purposes, but anyway we need it
  global $post ;

  if ( has_shortcode( $post->post_content, 'add_loopy_table' ) ) {

      continue ;

  } 

La version ci-dessus, ou une version légèrement augmentée de celle-ci, comprenant des extraits, pour les rares cas d'activation de codes courts dans des extraits, est la solution que j'ai l'intention d'appliquer, pour les raisons que je vais aborder plus tôt.

Une autre solution consisterait à autoriser l’inclusion des publications potentiellement infiniment offensives dans n’importe quelle boucle dans une boucle, mais à en modifier le contenu avant leur affichage.

WordPress inclut une fonction strip_shortcodes () qui nous permet d’écrire une fonction semblable à celle qui suit, utilisant également has_shortcode (), mais appelée lorsque la table loopy doit publier du contenu dans sa requête:

/***
 *AVOID INFINITE LOOPS BY STRIPPING
 *Strips shortcodes from potentially infinitely loopy posts
 *With message indicating deed has been done
***/
function ck_vs_infinity( $content ) {

    if ( has_shortcode( $content, 'add_loopy_table' ) ) {

         $content = '<p>Shortcodes removed to avoid danger of site crash.</p>' . 
             strip_shortcodes( $content ) ;

    }

    return $content ;

 }

La raison pour laquelle, dans cette approche, nous ne supprimons pas le shortcode connu comme dangereux et en ne laissons aucun autre, c'est que strip_shortcodes () n'accepte pas les paramètres rétrécissant sa bande. C'est shortcode-Monty complet ou rien en ce qui concerne strip_shortcodes (). Cela semble également signifier que les tweets et les vidéos incorporés seront ruinés, apparemment parce qu'ils reposent sur une fonctionnalité de shortcode intériorisée.

Pour cibler précisément le code (et les variantes), nous devons analyser le contenu, en utilisant éventuellement une variante de la regex de WordPress que vous pouvez parcourir à votre guise ici: https: // core.trac.wordpress.org/browser/tags/4.5.3/src/wp-includes/shortcodes.php#L570 Une version probablement très fiable pourrait être écrite pour la balise "shortcode" spécifique "(avec ou sans arguments), et avec le contenu massé et message renvoyé. La fonction ressemblerait à la strip-teaseuse ci-dessus, mais avec une preg_replace () sur $ content au lieu de strip_shortcodes ().

Alternativement, nous pourrions avoir d'autres alternatives ou chaînes d'alternatives disponibles lorsque le code dangereux apparaît: Forcer l'affichage de l'extrait sauf en cas de remplacement dangereux, en tout ou en partie, par le signe de l'infini animé pendant la lecture de l'audio "Nearer My God to thee" ... Ce genre de chose.

L’inconvénient potentiel de ces solutions, à l’exception des effets spéciaux, impliquerait des préoccupations éventuelles concernant des cas encore plus délicats dans lesquels un utilisateur souhaite inclure des publications contenant des tables qui ne sont pas réellement infinies.

Pour activer ces utilisateurs, je pense que je devrais soit être capable de tester si la table potentiellement infiniment bouclée était vraiment mauvaise, soit introduire une option de paramètres. Il n’existe aucun moyen pratique ni sûr d’effectuer le test, et tout ce qui oblige l’utilisateur à suivre des instructions, à cocher ou décocher une case, etc., et éventuellement à s’appuyer sur une nouvelle taxonomie ou sur une méta ou plus, encore risque probablement l'inclusion accidentelle d'une table en réalité avec une infinité de boucles, et représente en tout un investissement de temps et d'efforts sur quelque chose qui ne fera jamais la différence pour personne.

Peut-être que quelqu'un qui, pour une raison quelconque, a lu jusqu'à présent a une autre idée brillante et simple à partager. Pour l'instant, je me penche sur la première version, "has_shortcode/continue", parce que c'est simple et que cela semble le plus sûr pour l'utilisateur: les publications qui affichent des tables potentiellement infiniment bouclées ne seront pas affichées, point. Je pense que ce sera la règle, et jusqu'à ce que quelqu'un (y compris éventuellement moi-même) se prononce en faveur d'exceptions spéciales, je laisserai probablement les choses de cette façon.

2
CK MacLeod