防止 WordPress 转义简码属性

Prevent WordPress from escaping shortcode attributes

目前我正在开发一个连接到内容编辑器的插件。我的回调在编辑后收到 post 内容并调用 do_shortcode(),但出现问题,我不知道如何解决。

add_filter('wp_insert_post_data',   'prepareContentSaving', 99, 2);
add_filter('wp_update_post_data',   'prepareContentSaving', 99, 2);

例如,如果我的 post 看起来像(显然看起来像有效的简码语法):

[foo bar="two words"]

我的回调收到:

[foo bar=\"two words\"]

看起来不错吧?但是现在只要通过 do_shortcode() 解析简码,参数就会像

一样被解析
[tag argument1=value1 argument2]

而不是

[tag argument="Foo bar"]

然后在 PHP 中看起来像这样:

array(
[0]=>   string "bar=\"two"
[1]=>   string "words\""
)

那么如何防止短代码中的引号被转义呢? post 数据挂钩有问题吗?将优先级从 99 更改为 0 也不会改变什么。我使用的过滤器正确吗?

您可以尝试这样修改您的代码:

$post = array_map('stripslashes_deep', $_POST);

更多信息link:http://codex.wordpress.org/Function_Reference/stripslashes_deep

WordPress 实际上没有任何防止短代码被转义的选项。撤消它的唯一方法是在函数 'prepareContentSaving':

内将所有 '\"' 转换回 '"'(单引号相同)
add_filter('wp_insert_post_data',   'prepareContentSaving', 99, 2);
add_filter('wp_update_post_data',   'prepareContentSaving', 99, 2);



function prepareContentSaving($data, $post) {
  $content = $post['post_content'];
  $content = correctShortcodeSlashes($content);

  ... any further processing ...

  $data['post_content'] = $content;
  return $data;
}

保存 post 后,wordpress 不仅转义引号,还转义反斜杠。所以 '"' 变成 '\"' 并且 '\"'(如果编辑器想要转义引号)变成 '\\"'。

第一个给定的 PCRE 将短代码括号内的所有单转义引号转换回普通引号,第二个给定的 PCRE 将括号内的所有双转义引号转换回普通引号。这样内容保持不变,减少了代码注入的机会。

PHP Manual on preg_replace

function correct_shortcode_slashes($text) {
  $attribute_escaped_slashes_pattern = '/(\[)((.|\s)*?)([^\\])\\("|\')(.*?)(\])/';
  $attribute_escaped_slashes_replacement = '"';

  $attribute_double_slashes_pattern = '/(\[)((.|\s)*?)\\+("|\')(.*?)(\])/';
  $attribute_double_slashes_replacement = '"';

  $result = $text;
  $counter = 0;
  while(true) {
    $result = preg_replace($attribute_escaped_slashes_pattern, $attribute_escaped_slashes_replacement, $result, -1, $counter);
    if($counter === 0) {
        break;
    }
  }
  while(true) {
    $result = preg_replace($attribute_double_slashes_pattern, $attribute_double_slashes_replacement, $result, -1, $counter);
    if($counter === 0) {
        break;
    }
  }
  return $result;
}

请随时完善此答案。