两个不同的WordPress钩子使用相同的回调


Two different WordPress hooks with the same callback

我做了一个插件,将任何uri转换为超链接,如果它发现超链接,它将忽略它,只转换没有超链接的uri。在插件管理页面,我设置了两个选项,第一个转换链接仅为前端,第二个选项是转换uri时,任何帖子/评论保存到数据库。

// permanently means before save to database
if ( $this->plugin_options['uri2links_convert_method'] == 'permanently' ) {
    add_action( 'wp_insert_post_data', array($this, 'make_post_url_clickable' ) );
        //add_action( 'preprocess_comment', array($this, 'make_comment_url_clickable' ) );
}
else {
    add_filter( 'the_content', array($this, 'make_post_url_clickable' ) );
    //add_filter( 'preprocess_comment', array($this, 'make_comment_url_clickable' ) );
} 

我的问题在这里,如果我设置插件选项转换uri的前端,它会忽略超链接和转换其他的uri,但如果我设置它转换保存到数据库之前,它不会忽略超链接,并将其视为正常的uri女巫使结果看起来像这样:

<a class="sdf" href=" <a href="http://test.test-75.1474.stackoverflow.com/" >http://test.test-75.1474.stackoverflow.com/</a> " target="_blank" rel=" <a href="http://127.0.0.1/wplu" >http://127.0.0.1/wplu</a> "> <a href="http://test.test-75.1474.stackoverflow.com/" >http://test.test-75.1474.stackoverflow.com/</a> </a>
<a class="sdf" href=" <a href="https://www.stackoverflow.com" >https://www.stackoverflow.com</a> " target="_blank" rel=" <a href="http://127.0.0.1/wplu" >http://127.0.0.1/wplu</a> "> <a href="https://www.stackoverflow.com" >https://www.stackoverflow.com</a> </a>

完整的插件源代码:

<?php
  /*
    Plugin name: URIs to a click-able links
    Plugin URI:
    Description: Convert URI's to a click-able links
    Author: h Abdou
    Author URI: habdou.me
    Version: 1.0
  */
  // The admin page for the plugin
  require_once( 'uri2links-menu.php' );
  class Uri2Links {
    protected $css                 = '';
    protected $rel                 = '';
    protected $target              = '';
    protected $convert_links       = '';
    protected $convert_emails      = '';
    protected $plugin_options      = array();
    protected $url_match_pattern   = '/[a-zA-Z0-9'.'/'?':@'-_=#]+'.([a-zA-Z0-9'.'/'?':@'-_=#])+/';
    protected $email_match_pattern = '/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+'.[a-zA-Z0-9-.]+$/';
    //protected $links_match_pattern = '/<a(?:"[^"]*"[''"]*|''[^'']*''[''"]*|[^''">])+>^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+'.[a-zA-Z0-9-.]+$<'/a>/';
    protected $links_match_pattern = '/<a[^>]*>(.*?)<'/a>/';
    protected $links_matched       = array();
    public function __construct() {
      //$this->plugin_options = get_option( 'uri2links_plugin_options' );
      $this->plugin_options = array( 'uri2links_convertLinksEmails' => array( 'Links', 'Emails' ), 'uri2links_convert_method' => 'permanently' );
      $this->css            = isset( $this->plugin_options['uri2links_custom_css'] ) ? ' class="' . $this->plugin_options['uri2links_custom_css']  . '"' : '';
      $this->rel            = isset( $this->plugin_options['uri2links_rel_attr'] ) ? ' rel="' . $this->plugin_options['uri2links_rel_attr']  . '"' : '';
      if ( isset( $this->plugin_options['uri2links_open_links_method'] ) && $this->plugin_options['uri2links_open_links_method'] == 'new')
        $this->target = ' target="_blank"';
      $this->convert_links  = isset( $this->plugin_options['uri2links_convertLinksEmails'][0] ) ? $this->plugin_options['uri2links_convertLinksEmails'][0] : '';
      $this->convert_emails = isset( $this->plugin_options['uri2links_convertLinksEmails'][1] ) ? $this->plugin_options['uri2links_convertLinksEmails'][1] : '';
      if ( $this->plugin_options['uri2links_convert_method'] == 'permanently' ) {
        add_action( 'wp_insert_post_data', array($this, 'make_post_url_clickable' ) );
        //add_action( 'preprocess_comment', array($this, 'make_comment_url_clickable' ) );
      }
      else {
        add_filter( 'the_content', array($this, 'make_post_url_clickable' ) );
        //add_filter( 'preprocess_comment', array($this, 'make_comment_url_clickable' ) );
      }
      // The admin page for the plugin
      new Uri2LinksMenu;
    }
    // Convert all URI in a post to hyper-links.
    public function make_post_url_clickable( $content ) {
      $links = $this->hash_links( $content );
      if ( $this->convert_links == 'Links' ) {
        $content =  preg_replace($this->url_match_pattern, ' <a href="''0"' . $this->css . $this->rel . $this->target . ' >''0</a> ', $content);
      }
      if ( $this->convert_emails == 'Emails' ) {
        $content =  preg_replace($this->email_match_pattern, ' <a href="mailto:''0"' . $this->css . $this->rel . $this->target . ' >''0</a> ', $content);
      }
      // Replace back the hashed 'a' tags to the original status.
      foreach ( $links as $link_hash => $link_text ) {
        $content = str_replace( $link_hash, $link_text, $content );
      }
      return $content;
    }
    // Same as 'make_post_url_clickable' but this for comments
    public function make_comment_url_clickable( $content ) {
      $links = hash_links( $content['comment_content']['comment_content'] );
      if ( $this->convert_links == 'Links' ) {
        $content['comment_content'] =  preg_replace($this->url_match_pattern, ' <a href="''0"' . $this->css . $this->rel . $this->target . ' >''0</a> ', $content['comment_content']);
      }
      if ( $this->convert_emails == 'Emails' ) {
        $content['comment_content'] =  preg_replace($this->email_match_pattern, ' <a href="mailto:''0"' . $this->css . $this->rel . $this->target . ' >''0</a> ', $content['comment_content']);
      }
      foreach ( $links as $link_hash => $link_text ) {
        $content['comment_content'] = str_replace( $link_hash, $link_text, $content['comment_content'] );
      }
      return $content;
    }
    // hash all 'a' tags so 'make_*_url_clickable' will ignore them.
    public function hash_links( &$content ) {
      $links = array();
      if ( preg_match_all( $this->links_match_pattern, $content, $matches ) ) {
        $array_size = sizeof( $matches[0] );
        for ( $i = 0; $i < $array_size; ++$i ) {
          $link_hash = md5( $matches[0][$i] );
          $links[$link_hash] = $matches[0][$i];
          $content = str_replace( $matches[0][$i], $link_hash, $content );
        }
      }
      //die('hash_links called!');
      return $links;
    }
  }
  new Uri2Links;
?>

我只是想提一下WordPress已经获得了make_clickable()函数,该函数将文本uri用于HTML链接。

要激活post内容,我们只需要这个简单的插件:

<?php 
/** Plugin Name: Make text uri to HTML links in the post content **/
add_filter( 'the_content', 'make_clickable', 9 );

默认情况下,该函数在注释文本上运行:

add_filter( 'comment_text', 'make_clickable', 9 );