可以克服WP_QUERY在短码中的某些(站点崩溃)限制吗?

时间:2016-08-31 作者:CK MacLeod

在生成一个相对复杂的插件,该插件通过小部件、模板中插入的函数或短代码输出大量html时,我遇到了一个问题或一组限制,当用于帖子内容时,这些问题或限制仅适用于短代码版本。

该插件输出一个通过WP\\u查询构建的表。在这个新的绊脚石出现之前,我无法通过小部件或模板输出任何在短代码中也无法生成的内容。

为了将大量代码压缩为问题的简单语句,$query\\u 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”为空,则函数会根据任何其他参数生成一个帖子循环,但是,如果在post或page中通过短代码将“cat”留空(或者根本没有提供)(因此在主循环中),结果将是一场灾难性的站点崩溃,甚至不会出现快速的“致命错误”,而是出现一个慢速连接重置错误(ERR\\u connection\\u reset)。

允许“禁止‘cat’”对插件的主要用途来说并不重要,防止用户以这种方式破坏他们的网站并不难,但我仍然想知道是否还有其他因素需要考虑,或者有什么方法可以绕过这个问题。

我还想知道引擎盖下面到底发生了什么-所以任何关于调查检查工具问题的提示都会很好。

编辑:请参见下面自己的答案。

1 个回复
最合适的回答,由SO网友:CK MacLeod 整理而成

哎呀,我想现在撤回这个问题已经太迟了,但在出去散步时意识到答案是显而易见的:主查询中的查询创建了一个无限循环,因为包含短代码的帖子将位于主循环中,因此在宇宙中打开了一个洞等等。

将研究处理和隔离问题/危险的方法。。。

编辑:只想特别指出,另外,我相信the problem has nothing to do with the specific $query_args key or with shortcodes as such. 正如我刚才验证的那样,问题是放置一篇内容将包括帖子本身版本(包含帖子本身版本等)的帖子,因此是“重置重载”,而不是致命错误。

为了解决这个问题或避免将来出现这种可能的危险,我想我需要添加一个子例程,从插件输出的任何循环中排除任何有问题的帖子或任何有问题的帖子内容。既然我已经在WordPress开发人员的空间中探索这个(最初陈述错误)问题,我将发布一个更完整的答案,包括代码,如果/当我可以的话。

附录:解决方案

首先,请注意:我现在看到,在插件的早期版本中,甚至在我开始摆弄一系列$query\\u args之前,通过无限循环的无意中的站点崩溃总是一种危险,假定某些用户采取了正确的错误操作。

我认为最简单的解决方案就是从循环中的循环中排除所有包含短代码的帖子。在中插入以下内容new 查询循环或循环中的循环(在$my\\u query->the\\u post();)之后),假设短代码“tag”为“add\\u loopy\\u table”,是否会:

  //$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\\u shortcode()函数,允许我们编写如下函数,也使用has\\u shortcode(),但当循环表在其查询中发布内容时调用:

/***
 *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\\u shortcodes()不接受缩小其strip的参数。就strip\\u shortcodes()而言,它是完整的shortcode Monty或什么都没有。这似乎也意味着嵌入的推文和视频将被破坏,显然是因为它们依赖于内部化的短代码功能。

为了精确地定位特定代码(和变体),我们需要解析内容,也许可以使用WordPress自己的正则表达式上的一些变体,您可以在这里仔细阅读:https://core.trac.wordpress.org/browser/tags/4.5.3/src/wp-includes/shortcodes.php#L570 可以为特定的短代码“tag”(带或不带参数)编写一个可能非常可靠的版本,并返回经过处理和消息传递的内容。该函数看起来像上面的剥离器,但在$content上使用preg\\u replace()而不是strip\\u shortcode()。

或者,当危险代码出现时,我们可以有一些其他的替代方案或一系列替代方案:强制显示摘录,除非也是危险的,全部或部分替换为动画无限符号,同时播放“我的上帝离你更近”的音频。。。这类事情。

尽管有特殊效果,但这种解决方案的潜在缺点可能涉及到对更为尖锐的情况的担忧,在这种情况下,用户希望包含包含实际上并非无限循环表的帖子。

要启用这些用户,我想我要么必须能够测试潜在的无限循环表是否真的是一个糟糕的表,要么引入设置选项。对于我来说,执行测试的方法既不实用,也不符合用户的要求,任何需要用户遵循说明,或选中或取消选中方框等,并且可能依赖新的分类法或post-meta或更多分类法的操作,仍然可能存在意外包含实际无限循环表以及其他松散端的风险,总的来说,这是一种时间和精力的投资,可能对任何人都没有影响。

也许有人因为某种原因读了这么多书,有一个聪明简单的想法可以分享。现在,我倾向于第一个“has\\u shortcode/continue”版本,因为它很简单,而且似乎是最适合用户的:显示潜在无限循环表的帖子不会被显示,句号。我认为这将是规则,除非有人(可能包括我)公开表示支持特殊例外,否则我可能会这样做。

相关推荐

Shortcode to update user meta

我想在前端创建一个按钮,当用户单击时,值;“用户元”;更改“验证”function func_change_validate() { if (is_user_logged_in()) { $current_user = wp_get_current_user(); $new_value = \'validate\'; $updated = update_user_meta( $user_id, \'User_met