web-dev-qa-db-ja.com

ショートコードでのWP_Queryの特定の(サイトクラッシュ)制限を克服することはできますか?

ウィジェット、テンプレートに挿入された関数、またはショートコードのいずれかを介して大量のHTMLを出力する比較的複雑なプラグインを作成する際に、投稿コンテンツで使用するとショートコードバージョンにのみ適用される問題または一連の制限が発生しました。

プラグインはWP_Queryを介して構築されたテーブルを出力します。この新しい障害になるまでは、ウィジェットやテンプレートを介して出力できたもので、ショートコードでも生成できなかったものはありませんでした。

多くのコードを問題の単純なステートメントにまとめるために、$ query_args配列には "cat"引数が含まれています。

だから、のようなもの:

$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

プラグイン、またはそれが生成するループベースのテーブルの通常の使用では、キー 'cat'は常にカテゴリIDによって識別されるカテゴリ(またはカテゴリのリスト)を値として持ちます。ウィジェットやテンプレート関数で 'cat'を空のままにした場合、他のパラメータに応じて関数はポストのループを生成しますが、ショートコードを使用してポストまたはページで 'cat'が空のままの場合(またはまったく指定されない場合)そのため、メインループ内では、結果はかなり壊滅的なサイトのクラッシュになります。高速の「致命的なエラー」ではなく、到達の遅い接続リセットエラー(ERR_CONNECTION_RESET)でも発生します。

"no 'cat"を許可することによって達成される目的は、プラグインの主な用途にとって重要ではなく、ユーザーが自分のサイトをこのようにクラッシュさせないようにすることは難しいことではありません。私は、問題を回避するために、または何らかの方法で検討する必要があります。

私はまた、フードの下で何が起こっているのか正確に疑問に思っています - そのため、検査ツールで問題を調査する上でのどんなヒントも素晴らしいでしょう。

編集:下記の独自の答えを参照してください。

2
CK MacLeod

おっと - 質問を撤回するには遅すぎる、と思うが - 答えをはっきりさせるために散歩しているうちに気付いた:ショートコードを含むポストはメインループの中にあるので、メインクエリ内のクエリは無限ループを作る。宇宙などに穴を開ける.

問題/危険に対処して分離する方法を検討しています...

編集:特に、私は問題が特定の$ query_argsキーやショートコードとは何の関係もないと確信しています。先ほど確認したように、問題は、投稿自体のバージョン(投稿自体のバージョンを含むなど)を含むコンテンツを含む投稿を配置することです。したがって、致命的なエラーではなく「リセットオーバーロード」が発生します。

この問題を解決したり将来のこの危険を回避したりするためには、問題のある投稿や問題のある投稿のコンテンツを、プラグインのループ内ループから除外するサブルーチンを追加する必要があると思います。出力。私はWordPress Devのこの(最初に誤って述べられた)問題を探るスペースを取り上げたので、可能であれば/コードを含めて、より完全な答えを投稿します。

補遺:ソリューション

最初に注意してください。以前のバージョンのプラグインでは、$ query_argsの範囲をいじり始める前でさえも、無限ループによる不注意によるサイトクラッシュは常に危険であることがわかりました。何人かのユーザー.

私は、最も簡単で簡単な解決策は、ループ内ループからショートコードを含むすべての投稿を除外することだと思います。 "add_loopy_table"というショートコード "tag"を仮定して、newクエリループまたはloop-within-the-loop($ my_query-> the_post();の後)に次のコードを挿入します。 「やります:

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

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

      continue ;

  } 

上記の、または抜粋を含むわずかに拡張されたバージョン(抜粋内のショートコードがアクティブになるまれなケース用)は、この時点で適用しようとしている解決策です。

他の代替案は、ループ内のループに無限に不快な投稿を含めることを許可するが、表示する前にそれらのコンテンツを変更することである。

WordPressには以下のような関数を書くことを可能にするstrip_shortcodes()関数も含まれています。これもhas_shortcode()を使用していますが、loopyテーブルがクエリ内にコンテンツを投稿するときに呼び出されます。

/***
 *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 ;

 }

このアプローチでは、既知の危険なショートコードを削除して他の人はそのままにしないのは、strip_shortcodes()がそのストリップを狭めるパラメータを受け付けないためです。それは完全なshortcode-Montyであるか、strip_shortcodes()に関する限りは何もありません。それはまた、内蔵のツイートやビデオが廃止されることを意味するようです。これは、内部のショートコード機能に依存しているためと考えられます。

特定のコード(およびそのバリエーション)を正確にターゲットとするには、おそらくWordPress自身の正規表現のバリエーションを使用してコンテンツを解析する必要があります。 https:// core.trac.wordpress.org/browser/tags/4.5.3/src/wp-includes/shortcodes.php#L570 おそらく非常に信頼性の高いバージョンが特定のショートコードのために書かれるかもしれません "タグ#〜msgstr "(引数付きまたは引数なしで)、メッセージ付きのメッセージ付きのコンテンツを返します。この関数は上記のストリッパーのように見えますが、$ contentに対してstrip_shortcodes()の代わりにpreg_replace()を使用しています。

あるいは、危険なコードが表示されたときに他の代替手段または代替手段のチェーンを用意することもできます。危険でない限り、抜粋を強制的に表示します。そのようなこと。

そのような解決法に対する潜在的な欠点、それにもかかわらず特殊効果は、実際には無限ループではないテーブルを含む投稿をユーザが含みたいというさらに厄介な場合に対する懸念の可能性を含むであろう。

これらのユーザーを有効にするには、無限ループの可能性があるテーブルが本当に悪いテーブルであるかどうかをテストするか、設定オプションを導入する必要があると思います。テストを実行するための実用的でユーザーに適した方法はありません。ユーザーが指示に従うこと、またはボックスをチェックまたはチェック解除することなどを必要とし、さらに新しい分類法またはメタ投稿以上に頼ることはなおさらです。実際には無限ループのテーブルが他のルーズエンドと一緒に偶然に含まれる可能性があります。

多分何らかの理由でこれまでに読んだ人は、明るくシンプルな追加のアイデアを共有する必要があります。今のところ、私は最初の "has_shortcode/continue"バージョンに傾いています、なぜならそれはシンプルでそして最もユーザープルーフのようです:無限ループテーブルを表示する投稿は表示されません、期間。私はそれがルールになると思います、そして、誰か(おそらく私も含む)が特別な例外を支持して話すまで、そして私はおそらくそのようにします。

2
CK MacLeod