Remove an action from an external Class

I’m trying to do something similar to this question here: remove_action or remove_filter with external classes?

I’m trying to remove the

Read More

<!-- This site is optimized with the Yoast WordPress SEO plugin v1.0.3 - http;//yoast.com/wordpress/seo/ -->

message from the plugin.

And before you yell at me about how this may be unethical the author says it’s okay to do here: http://wordpress.org/support/topic/plugin-wordpress-seo-by-yoast-how-to-remove-dangerous-inserted-yoast-message-in-page-headers?replies=29#post-2503475

I have found the class that adds the comment here: http://plugins.svn.wordpress.org/wordpress-seo/tags/1.2.8.7/frontend/class-frontend.php

Basically the WPSEO_Frontend class has a function named debug_marker which is then called by a function named head which is then added to wp_head in __Construct

I’m new to classes but I found a way to completely remove the head by doing

global $wpseo_front;    
remove_action( 'wp_head', array($wpseo_front,'head'), 1, 1 );

but I only want to remove the debug_marker part from it. I tried this but it dosen’t work
remove_action( 'wp_head', array($wpseo_front,'head','debug_marker'), 1, 1 );

As I said I’m new to classes so any help would be great.

Related posts

Leave a Reply

10 comments

  1. A simple way to achieve this (but without the Class approach) is by filtering the output of wp_head action hook using the output buffering.

    In your theme’s header.php, wrap the wp_head() call with ob_start($cb) and ob_end_flush(); functions like:

    ob_start('ad_filter_wp_head_output');
    wp_head();
    ob_end_flush();
    

    Now in theme functions.php file, declare your output callback function (ad_filter_wp_head_output in this case):

    function ad_filter_wp_head_output($output) {
        if (defined('WPSEO_VERSION')) {
            $output = str_ireplace('<!-- This site is optimized with the Yoast WordPress SEO plugin v' . WPSEO_VERSION . ' - http://yoast.com/wordpress/seo/ -->', '', $output);
            $output = str_ireplace('<!-- / Yoast WordPress SEO plugin. -->', '', $output);
        }
        return $output;
    }
    

    If you want to do all that through the functions.php without editing header.php file, you can hook to get_header and wp_head action hooks to define the output buffering session:

    add_action('get_header', 'ad_ob_start');
    add_action('wp_head', 'ad_ob_end_flush', 100);
    function ad_ob_start() {
        ob_start('ad_filter_wp_head_output');
    }
    function ad_ob_end_flush() {
        ob_end_flush();
    }
    function ad_filter_wp_head_output($output) {
        if (defined('WPSEO_VERSION')) {
            $output = str_ireplace('<!-- This site is optimized with the Yoast WordPress SEO plugin v' . WPSEO_VERSION . ' - http://yoast.com/wordpress/seo/ -->', '', $output);
            $output = str_ireplace('<!-- / Yoast WordPress SEO plugin. -->', '', $output);
        }
        return $output;
    }
    
  2. Thanks for all your help, i finally resolved it.
    I created a functions.php for my child theme, then add

    // we get the instance of the class
    $instance = WPSEO_Frontend::get_instance();
    /* then we remove the function
        You can remove also others functions, BUT remember that when you remove an action or a filter, arguments MUST MATCH with the add_action
        In our case, we had :
        add_action( 'wpseo_head', array( $this, 'debug_marker' ), 2 );
    
        so we do : 
        remove_action( 'wpseo_head', array( $this, 'debug_marker' ), 2 );
        */
        remove_action( 'wpseo_head', array( $instance, 'debug_marker' ), 2 );
    
  3. I don’t think you are going to be able to do that using remove_action. The function argument in remove_action will not help you as the debug_marker() function was not the function that was used in the add_action() call.

    Yoast presumably has something like add_action( "wp_head", "head" ) in his code. So you can remove the “head” function, but debug_marker was not explicitly added as an action.

    You could

    1. Edit Yoast’s source file and remove the debug comment line.
    2. Extend the WPSEO_Frontend class and overload the debug_marker function to return “”. TBH, I’m not sure how this would work in terms of WP loading the plugin, but could be worth investigating.
  4. Finding this thread after working on the same solution as the one mentioned by Steve Claridge, that is:

    Extend the WPSEO_Frontend class and overload the debug_marker function to return “”

    I detailed the steps below, although I’m getting stuck in the final step.


    Create a customization plugin

    As mentioned in this article from WP Tavern, “the easiest way to accomplish this is to create a functionality plugin that will run alongside it”.

    So I went on to creating my first plugin following this article from ElegantTheme.

    Extend the relevant class.

    That’s when things got complicated. I added the following but my overriding function is still not triggered for some reason.

    //get the base class
    if(!class_exists('WPSEO_Frontend')) {
        require_once $_SERVER['DOCUMENT_ROOT'] . '/wp-content/plugins/wordpress-seo/frontend/class-frontend.php';
    }
    
    /**
     * Class Definition
     */
    class WPSEO_Frontend_GUP extends WPSEO_Frontend{
    
        /**
         * 
         * OVERRIDES function from YOAST SEO
         * 
         * Outputs or returns the debug marker, which is also used for title replacement when force rewrite is active.
         *
         * @param bool $echo Whether or not to echo the debug marker.
         *
         * @return string
         */
        public function debug_marker( $echo = true ) {
            return '';
        }
    
    }
    
  5. I’ve found that you can remove the debug_marker action in functions.php.
    Yoast plugin is executed in the wp_head action. I just took the action hook which follows directly after that, namely wp_enqueue_scripts and there I hooked a function that removed the debug_marker output. For this you also have to pass the plugin object. Also the priority number has to be the same as the one set from within the plugin.

    function remove_debugmarker(){
    global $wpseo_front;
    remove_action( 'wpseo_head', array($wpseo_front, 'debug_marker') , 2 );
    }
    add_action('wp_enqueue_scripts','remove_debugmarker');
    

    However this does not remove the

    <!-- / Yoast WordPress SEO plugin. -->
    

    part, because that is echoed in the plugin’s crucial wrapper function head.
    You could try overwriting that.

  6. To add to Ahmad’s answer you could just remove all html comments with the same amount of code, since Yoast isn’t the only plugin that does that.

       <?php
       function remove_html_comments_buffer_callback($buffer) {
            $buffer = preg_replace('/<!--[^[><](.|s)*?-->/', '', $buffer);
            return $buffer;
        }
        function remove_html_comments_buffer_start() {
            ob_start("remove_html_comments_buffer_callback");
        }
        function remove_html_comments_buffer_end() {
            ob_end_flush();
        }
        add_action('template_redirect', 'remove_html_comments_buffer_start', -1);
        add_action('get_header', 'remove_html_comments_buffer_start'); 
        add_action('wp_footer', 'remove_html_comments_buffer_end', 999);
    
  7. I’ve came across a snippet that removes all Yoast WordPress SEO comments from the front end. It also modifies the output buffering approach that @bryan-willis and @ahmad-m’s answers use.

    Simply place the snippet on your theme’s functions.php or a custom plugin/theme php file.

    I’ll leave it here as a reference – credit goes to the snippet’s author

    /**
     * Yoast WordPress SEO Plugin - Remove All Yoast HTML Comments
     * See at: https://gist.github.com/paulcollett/4c81c4f6eb85334ba076
    **/
    if (defined('WPSEO_VERSION')){
      add_action('get_header',function (){ ob_start(function ($o){
      return preg_replace('/n?<.*?yoast.*?>/mi','',$o); }); });
      add_action('wp_head',function (){ ob_end_flush(); }, 999);
    }
    
  8. This is a modified version of @ahmad-m Answer, by applying filters you can make multiple content changes to the header html .

    function header_str_replace_start(){
        ob_start('header_str_replace_output');
    }
    function header_str_replace_output($output){
        return apply_filters('header_str_replace', $output);
    }
    function header_str_replace_finish(){
        ob_end_flush();
    }
    add_action('get_header', 'header_str_replace_start',-1);
    add_action('wp_head', 'header_str_replace_finish', 999);
    
    
    add_filter( 'header_str_replace', 'remove_yeost_seo_comments' ) ;
    add_filter( 'header_str_replace', 'remove_white_space');
    
    
    function remove_yeost_seo_comments($output) {
        $output = str_ireplace('<!-- / Yoast SEO plugin. -->', '', $output);
        return $output;
    }
    
    
    function remove_white_space($content){
         return trim(preg_replace('/s+/', ' ', $content));
    }
    
  9. Found a similar solution for functions.php which does not use hardcoded priority 2 but dynamically reads and uses the priority from Yoast add_action().

    // disable 'This site is optimized with the Yoast SEO ...'
    if ( class_exists( 'WPSEO_Frontend') && method_exists( 'WPSEO_Frontend', 'get_instance' ) ) {
        $wpseo_front = WPSEO_Frontend::get_instance();
        if ( $wpseo_dbg_prio = has_action( 'wpseo_head', array( $wpseo_front, 'debug_mark' ) ) ) {
            remove_action( 'wpseo_head', array( $wpseo_front, 'debug_mark'), $wpseo_dbg_prio );
        }
    }
    
  10. See flush_cache function in wordpress-seo/frontend/class-frontend.php

    Find this line of code

    $content = str_replace( $this->debug_marker( false ), $this->debug_marker( false ) . "n" . '<title>' . $title . '</title>', $content );
    

    Replace with

    $content = str_replace( $this->debug_marker( false ), '<title>' . $title . '</title>', $content );
    

    Thanks to the creator of this great plugin.