There are situations when a plugin/theme use some filter hooks to change the default behaviour of the wordpress functionality and then forgets to remove the change they have applied or sometimes intentionaly because of such requirement. But this affects all over the website and causes problem, where as we want to use the default behaviour and not this changed one.
Now, the question is ” how can we override a funtion that is already applied for a particular filter hook “.
Option 1: remove_filter
If we know which function is called for a particular hook which is causing the issue, then we can use
1 2 3 4 5 |
<?php remove_filter($hook_tag, $function_to_remove, $priority, $accepted_args); ?> |
http://codex.wordpress.org/Function_Reference/remove_filter
Ex:
1 2 3 |
<?php remove_filter(‘posts_orderby’, ‘TESTOrderPosts’); ?> |
Option 2: remove_all_filters
Remove all the call_back functions those are added for a particular filter hook.(Helpfull when we don’t know the functions that are applied for a particular filter)
1 2 3 |
<?php remove_all_filters( $hook_tag, $priority ); ?> |
http://codex.wordpress.org/Function_Reference/remove_all_filters
But again,this might cause issues as we are completly removing all the functions(whatever is the priority) for that filter hook. There is a solution too.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php global $wp_filter; /* Store the global wp_filter functions assigned to that hook in variable */ $temp = $wp_filter[‘posts_orderby’]; /* Remove all the filters applied for that hook */ remove_all_filters( ‘posts_orderby’ ); /* …………………. */ /* perform the tasks here */ /* …………………. */ /* Re-assign the stored value to the global wp_filter for that hook */ $wp_filter[‘posts_orderby’] = $temp; ?> |
Option 3: add_filter with high priority
Call a custom defined function with high priority for the filter hook.
1 2 3 |
<?php add_filter( $tag, $function_to_add, $priority, $accepted_args ); ?> |
http://codex.wordpress.org/Function_Reference/add_filter
Default priority number is 10. So I am passing 99 as the $priority parameter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php add_filter(‘posts_orderby’, ‘test_posts_orderby_commentscount’, 99); if(!function_exists(‘test_posts_orderby_commentscount’)) { function test_posts_orderby_commentscount($orderBy) { global $wpdb; if(!is_admin()){ $orderBy = ‘{$wpdb->posts}.comment_count DESC, {$wpdb->posts}.post_date DESC’; } return($orderBy); } } ?> |
Don’t forget to remove the filter once you are done with your task.
1 2 3 |
<?php remove_filter(‘posts_orderby’, ‘test_posts_orderby_commentscount’); ?> |
Simple example to understand the exact situation:
* A plugin uses a function to change the default sorting order of posts.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php add_filter(‘posts_orderby’, ‘TESTOrderPosts’); function TESTOrderPosts($orderBy) { global $wpdb; if (is_admin()){ $orderBy = ‘{$wpdb->posts}.menu_order, {$wpdb->posts}.post_date DESC’; } else { $orderBy = ‘{$wpdb->posts}.menu_order, {$wpdb->posts}.post_date DESC’; } return($orderBy); } ?> |
* Now we have a widget(say Popular Posts by Comments count) which fetches and displays the most commented posts.
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php $args = array( ‘posts_per_page’ => 5, ‘orderby’ => ‘comment_count’, ‘ignore_sticky_posts’ => 1, ‘order’ => ‘DESC’ ); $test_popular_posts = new WP_Query($args); while($test_popular_posts->have_posts()): $test_popular_posts->the_post(); ?> |
1 2 3 |
<h1><?php the_title(); ?></h1> |
1 2 3 |
<?php endwhile; ?> |
* Now the problem is that the Popular Posts by Comments count widget does not display the posts as intended i.e. orderby most commented. ๐
Solution:
Write a function which will be called to override the previous funtion(mentioned above). Now call this function for that filter hook with high priority. ๐
* So the modified code will be as below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?php /* To override any filters applied to the ‘posts_orderby’ hook */ if(!function_exists(‘test_posts_orderby_commentscount’)) { function test_posts_orderby_commentscount($orderBy) { global $wpdb; if(!is_admin()){ $orderBy = ‘{$wpdb->posts}.comment_count DESC, {$wpdb->posts}.post_date DESC’; } return($orderBy); } } add_filter(‘posts_orderby’, ‘test_posts_orderby_commentscount’, 99); $args = array( ‘posts_per_page’ => 5, ‘orderby’ => ‘comment_count’, ‘ignore_sticky_posts’ => 1, ‘order’ => ‘DESC’ ); $test_popular_posts = new WP_Query($args); while($test_popular_posts->have_posts()): $test_popular_posts->the_post(); ?> <h1><?php the_title(); ?></h1> <?php endwhile; remove_filter(‘posts_orderby’, ‘test_posts_orderby_commentscount’, 99); ?> |
Hope this post will help somebody someday !! ๐