在Wordpress中允许在kses过滤器中使用短划线的自定义标签

时间:2016-05-26 08:58:47

标签: php html wordpress

我写了一个小的Wordpress插件,允许将用户定义的HTML自定义元素标签(如<my-element>)添加到帖子的HTML中。因此,没有能力unfiltered_html的用户至少能够使用此类预定义的自定义标签。

问题是我是否添加了这样的过滤器:

add_filter('wp_kses_allowed_html', 'returnAllowedCustomTags', 10, 2);
function returnAllowedCustomTags($allowedTags, $context) {
    $myAllowedTags = array('my-element' = > array(), 'myelement' = > array());
    $allowedTags = array_merge($allowedTags, $myAllowedTags);
    return $allowedTags;
}

可以保存html <myelement>blah</myelement>。但是保存html <my-element>blah</my-element>是不可能的。我认为这是因为在过滤之前,带有破折号的HTML标签将从HTML字符串中删除。

有没有一个很好的解决方案(没有调整wordpress核心文件)来防止wordpress kses过滤带有破折号的html标签?

而且我不想为用户提供unfiltered_html功能。

1 个答案:

答案 0 :(得分:0)

最后,在尝试了几种方法之后,我提出了以下解决方案:

add_filter('wp_kses_allowed_html', 'returnAllowedCustomTags', 10, 2);
// use this filter to replace all custom tags with dashes before kses filter is applied
add_filter('content_save_pre', 'transformCustomTags', 9);
// use this to retransform filtered html before saving
add_filter('content_save_pre', 'retransformCustomTags', 11);

function transformCustomTags($html) {
  $customTags = array('my-element', 'my-element1', 'my-element2');
  // iterate over all allowed custom tags and replace them so they won't get stripped out by kses filter
  foreach ($customTags as $tag) {
    // transform each tag name replacing dash with '0000'
    // e.g. <my-element ...> will be replaced with <my0000element ...>
    // with that we can pevent kses from stripping them out
    $pattern = '<' . $tag;
    $replace = '<' . str_ireplace('-', '0000', $tag);
    $html = str_ireplace($pattern, $replace, $html);
    // replace all closing tags analog to opening tags above
    $pattern = '</' . $tag;
    $replace = '</' . str_ireplace('-', '0000', $tag);
    $html = str_ireplace($pattern, $replace, $html);
  }
  return $html;
}

function retransformCustomTags($html) {
  $customTags = array('my-element', 'my-element1', 'my-element2');
  // iterate over all allowed tags and reverse transformation to get the dash again in tag names
  foreach ($customTags as $tag) {
    // e.g. <my0000element ...> will be replaced with <my-element" ...>
    $pattern = '<' . str_ireplace('-', '0000', $tag);
    $replace = '<' . $tag;
    $html = str_ireplace($pattern, $replace, $html);
    // replace all closing tags analog to opening tags above
    $pattern = '</' . str_ireplace('-', '0000', $tag);
    $replace = '</' . $tag;
    $html = str_ireplace($pattern, $replace, $html);
  }
  return $html;
}

function returnAllowedCustomTags($allowedTags, $context) {
  $myAllowedTags = array('my-element', 'my-element1', 'my-element2');
  foreach ($myAllowedTags as $tag) {
    $tagNameEscaped =  str_ireplace('-', '0000', $tag);
    $allowedTags[$tagNameEscaped] = array();
  }
  return $allowedTags;
}

基本上,我将标签名称中的短划线替换为任何允许的自定义标签。 <my-element ...>...</my-element>已转换为<my0000element ...>...</my0000element>。之后kses过滤器可以正常工作但接受标记<my0000element>。在完成kses过滤后,但在将$html保存到数据库之前,我将<my0000element ...>...</my0000element>重新转换回<my-element ...>...</my-element>

使用该解决方案,标签名称中的破折号不会被定义为允许标签的自定义标签。因此,没有能力unfiltered_html的用户可以使用一组预定义的自定义元素。

当然,破折号的替换模式可能会更安全一些错误的匹配。但是对于示范需求0000就足够了。

注意:使用这种方法,wordpress核心代码没有调整。只使用它提供的钩子。