How to override a theme function (within a class) using a plugin

I am working a website which utilises a highly complex theme (essentially a whole bunch of other software tacked onto WordPress), so complex in fact, that child themes wont work with it.

I want to override a function (inside a class) within the theme by using a functionality plugin. When I refer to the class from within the plugin, I get this error message:

Fatal error: Class ‘OptimizePress_Default_Asset’ not found in [redacted]\wp-content\plugins\functions.php on line 17

class Foo extends OptimizePress_Default_Asset {
   function recent_posts($atts){

        // Decode encoded chars
        $atts = op_urldecode($atts);

        extract(shortcode_atts(array(
            'style' => '',
            'posts_num' => ''
        ), $atts));

        //Get recent posts
        $recent_posts = wp_get_recent_posts(array(
            'numberposts' => $posts_num,
            'post_status' => 'publish'
        ));
        $recent_html="";
        foreach( $recent_posts as $recent ){
            $img_src = wp_get_attachment_image_src(get_post_thumbnail_id($recent['ID']), 'single-post-thumbnail');
            $img_src = $img_src[0];
            if ( is_front_page() ) {
                $date = "";
            }
            else {
                $date="<span>".date(OP_DATE_POSTS, strtotime($recent['post_date'])).'</span>';
            }   
            $recent_html .= '<li><div class="thumb"><img src="'.$img_src.'" class="scale-with-grid" /></div><div class="content"><a href="'.get_permalink($recent["ID"]).'">'.$recent["post_title"].'</a>'.$date.'</div></li>';

        }

        return '
            <ul class="recent-posts-style-'.$style.'">
                '.$recent_html.'
            </ul>
        ';
    }
}

Is it possible to refer to a class in a theme from within a plugin? If so how can this be done? Is this something which has to be referred to after theme set-up?

Thank you in advance

1 Answer
1

You have to know that child theme functions.php is loaded before parent theme functions.php.

It means that inside a child theme functions.php parent theme classes are not available yet, so you get that fatal error.

If the class is in parent theme functions.php you can use 'after_setup_theme' hook to wait for when the parent theme class is defined:

add_action('after_setup_theme', function() {
  // assuming class-foo.php is the file that contains your Foo class
  require_once get_stylesheet_directory() . '/class-foo.php';
});

However code above may not work because it assumes that the parent theme class is loaded immediately when parent theme functions.php is loaded, but if that class is loaded using a different hook you have to wait for that hook is fired, instead of 'after_setup_theme'.

As example, if your parent theme contains something like:

add_action('init', function() {
  // assuming class-optimizepress-default-asset.php is the file that contain the class
  require_once get_template_directory() . '/class-optimizepress-default-asset.php';
});

you need to wait that 'init' hook is fired before load your class. In that case you can use the same 'init' hook with a lower priority:

add_action('init', function() {
  require_once get_stylesheet_directory() . '/class-foo.php';
}, 99); // default priority is 10, higher number means lower priority

In summary, there is no a code that works for all classes and all themes, you have to look at parent theme code to understand which is the proper hook to use to be sure parent theme class is available.

Leave a Comment