I am working on a way to disable a specific plugin on a certain product page. I've cobbled this together from things I found online and the plugins code itself but its not working. Curious to have some fresh eyes have a look and let me know what might be failing. The post id of the product is 2679320. The actions I have set to remove are the ones referenced in the plugin wp_enqueue_scripts. Here is the code I'm trying by loading to snippets:
function remove__construct() {
global $post;
$ids = array(2679320);
if(in_array($post->ID,$ids)):
remove_action(‘wp_enqueue_scripts’,array($this,’enqueue_scripts’));
remove_action(‘plugins_loaded’,array($this,’load_txt_domain’),99);
remove_action(‘wp_footer’,array($this,’get_popup_markup’));
remove_filter( ‘pre_option_woocommerce_cart_redirect_after_add’, array($this,’prevent_cart_redirect’),10,1);
endif;
}
add_action(‘wp_head’, ‘remove__construct’, 1);
Any ideas why this isn't working? What did I miss? Anyone have better way to do this?
You can use Plugin Organizer. It allows you to selectively disable a plugin on a page or a complete post type.
There are 2 ways to disable plugin.
The first way is to create a custom plugin that removes the action that used to initialize your target plugin. The second way is to remove actions and filters which add scripts, styles and makes changes on a page.
Either way you choose, you have to remove actions after they've been added and before they actually worked. That means that for the first way in most cases you have to use plugins_loaded hook which can't be used in your functions.php (the first hook which can be used in functions.php is load_textdomain hook). in case you want to disable the plugin on certain pages you have to somehow get the current post ID, which isn't so easy because global $post variable is not available yet (The earliest hook with $post is wp).
Parameters for your remove_action depend on plugin add_action. The main point here is that all parameters of your remove_action must be the same as add_action parameters. Here are some examples :
add_action('plugins_loaded', 'init_function_name');
remove_action('plugins_loaded', 'init_function_name');
add_action('plugins_loaded', 'init_function_name', 100);
remove_action('plugins_loaded', 'init_function_name', 100);
class Plugin_Classname {
public static function init() {
add_action( 'plugins_loaded', array( __CLASS__, 'on_init' ) );
}
}
remove_action( 'plugins_loaded', array( 'Plugin_Classname', 'on_init' ) );
class Plugin_Classname {
public function __construct(){
add_action('plugins_loaded', array($this, 'init'), 99);
}
public static function get_instance(){
if(self::$instance === null){
self::$instance = new self();
}
return self::$instance;
}
}
remove_action('plugins_loaded', array( Plugin_Classname::get_instance() , 'init'), 99);
Let's begin with the easiest way. Assume that removing scripts and styles is enough. Then you have to find wp_enqueue_scripts hooks in the plugin source. Eq.:
class Xoo_CP_Public{
protected static $instance = null;
public function __construct(){
add_action('plugins_loaded',array($this,'load_txt_domain'),99);
add_action('wp_enqueue_scripts',array($this,'enqueue_scripts'));
add_action('wp_footer',array($this,'get_popup_markup'));
add_filter( 'pre_option_woocommerce_cart_redirect_after_add', array($this,'prevent_cart_redirect'),10,1);
}
public static function get_instance(){
if(self::$instance === null){
self::$instance = new self();
}
return self::$instance;
}
}
As we need global $post variable we gonna use wp hook. Place the code below in functions.php:
function disable_plugin() {
global $post;
$ids = array( 2679320 ); // Disable plugin at page with ID = 2679320
if( in_array( $post->ID ,$ids ) ) {
remove_action('wp_enqueue_scripts',array( Xoo_CP_Public::get_instance(),'enqueue_scripts'));
remove_action('plugins_loaded',array(Xoo_CP_Public::get_instance(),'load_txt_domain'),99);
remove_action('wp_footer',array(Xoo_CP_Public::get_instance(),'get_popup_markup'));
remove_filter( 'pre_option_woocommerce_cart_redirect_after_add', array(Xoo_CP_Public::get_instance(),'prevent_cart_redirect'),10,1);
}
}
add_action( 'wp', 'disable_plugin' );
What if we want to remove an action is used to initialize this plugin? Let's take a look at add_action:
add_action('plugins_loaded','xoo_cp_rock_the_world');
In this case we can't use plugins_loaded hook because add_action is being called without priority parameter. If it's being called with priority parameter we could just create disable-plugin.php file in /wp-content/plugins folder and place this code there:
function disable_plugin() {
remove_action('plugins_loaded', 'xoo_cp_rock_the_world', 100);
}
add_action('plugins_loaded','disable_plugin');
But it's useless in this case without priority parameter. Yet we can cheat! We don't have to use any hooks and call remove_action directly. We should call it after target plugin add_action was called. Plugins are loaded in alphabetical order so if we named our plugin 'zzz-disable-plugin.php` with this lines of code:
/* Plugin Name: zzz-disable-plugin */
remove_action('plugins_loaded', 'xoo_cp_rock_the_world');
The target plugin will be disabled. At all pages though. I haven't find a way to get ID of current page on such an early hook. But we can use URI :
/* Plugin Name: zzz-disable-plugin */
if( 'product/polo' == trim( $_SERVER[ 'REQUEST_URI' ], '/' ) ) {
remove_action('plugins_loaded', 'xoo_cp_rock_the_world');
}
Related
I have a plugin that is creating a custom template via add_filter:
// Create a template view for the new CPT
add_filter('single_template', [$this, 'setTemplateAVATAR'] );
public function setTemplateAVATAR ($template) {
global $post;
if ( $post->post_type == 'AVATAR' ) {
return self::generateCustomTemplate('avatar.php');
}
return $template;
}
I need to disable this somehow via functions file so that that instead of using it's custom template is uses the template defined in my theme. How would I go about disabling this filter from running?
You would take the add_filter() hook and use remove_filter() and try the hook name and function name parameters the same.
remove_filter('single_template', 'setTemplateAVATAR' );
I am trying to replace or overwrite an action hook declared inside a wordpress plugin class
class WCFM_Withdrawal {
public function __construct() {
global $WCFM;
// WCFMu Thirdparty Ajax Controller
add_action( 'after_wcfm_ajax_controller', array( &$this, 'wcfm_withdrawal_ajax_controller' ) );
}
Here the add_action hook which points the function. I want to replace "wcfm_withdrawal_ajax_controller" with my own function.
add_action("init", function () {
// removing the woocommerce hook
global $WCFM;
remove_action( 'after_wcfm_ajax_controller', array( $WCFM, 'wcfm_withdrawal_ajax_controller' ) );
});
add_action( 'after_wcfm_ajax_controller', 'my_new_function' );
function my_new_function(){
//Do something here
}
i have tried to remove_action and add my own function, but didn't work.
Make sure you have the correct Class instance. Your example shows $WCFM, but the class declaration is WCFM_Withdrawal. Is $WCFM an instance of WCFM_Withdrawal? If you have determined that you do have the appropriate class instance, you may be running the remove_action too early (before the one you want to remove is added).
You can try lowering the priority of your init function:
add_action( 'init', function () {
// removing the woocommerce hook
global $WCFM;
remove_action( 'after_wcfm_ajax_controller', array( $WCFM, 'wcfm_withdrawal_ajax_controller' ) );
}, 99 );
I'd say you could also try a later Action Hook than init, but since this appears to be an AJAX handler, that probably won't suffice. Start by making sure that you've got the correct class instance variable, and then bump down the priority of your removal.
I'm currently using Foobox lightbox (free) plugin, and apparently the plugins' files are loaded on every page regardless of whether it's used or not. However I would like to change this, but I can't seem to find any handles to dequeue the scripts through.
It seems that the scripts are called by the code beneath, which to me at least, doesn't show any handles. I've tried using remove_action(...) to "counter" them as well as various inputs in wp_dequeue_script() to try and target the files directly - e.g. wp_dequeue_script('foobox.free.min.js')
class Foobox_Free extends Foo_Plugin_Base_v2_1 {
const JS = 'foobox.free.min.js';
const CSS = 'foobox.free.min.css';
const CSS_NOIE7 = 'foobox.noie7.min.css';
const FOOBOX_URL = 'http://fooplugins.com/plugins/foobox/?utm_source=fooboxfreeplugin&utm_medium=fooboxfreeprolink&utm_campaign=foobox_free_pro_tab';
const BECOME_AFFILIATE_URL = 'http://fooplugins.com/affiliate-program/';
private static $instance;
public static function get_instance() {
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Foobox_Free ) ) {
self::$instance = new Foobox_Free();
}
return self::$instance;
}
/**
* Initialize the plugin by setting localization, filters, and administration functions.
*/
private function __construct() {
//init FooPluginBase
$this->init( FOOBOXFREE_FILE, FOOBOXFREE_SLUG, FOOBOX_BASE_VERSION, 'FooBox FREE' );
if (is_admin()) {
add_action('admin_head', array($this, 'admin_inline_content'));
add_action('foobox-free-settings_custom_type_render', array($this, 'custom_admin_settings_render'));
new FooBox_Free_Settings();
add_action( FOOBOX_ACTION_ADMIN_MENU_RENDER_GETTING_STARTED, array( $this, 'render_page_getting_started' ) );
add_action( FOOBOX_ACTION_ADMIN_MENU_RENDER_SETTINGS, array( $this, 'render_page_settings' ) );
add_action( 'admin_notices', array( $this, 'admin_notice_foogallery_lightboxes' ) );
add_action( 'wp_ajax_foobox_foogallery_lightboxes_ignore_notice', array( $this, 'admin_notice_foogallery_lightboxes_ignore' ) );
add_action( 'wp_ajax_foobox_foogallery_lightboxes_update', array( $this, 'admin_notice_foogallery_lightboxes_update' ) );
add_action( 'admin_print_scripts', array( $this, 'admin_notice_foogallery_lightboxes_inline_js' ), 999 );
add_filter( 'foobox-free-has_settings_page', '__return_false' );
} else {
// Render JS to the front-end pages
add_action('wp_enqueue_scripts', array($this, 'frontend_print_scripts'), 20);
add_action('foobox-free_inline_scripts', array($this, 'inline_dynamic_js'));
// Render CSS to the front-end pages
add_action('wp_enqueue_scripts', array($this, 'frontend_print_styles'));
if ( $this->is_option_checked('disable_others') ) {
add_action('wp_footer', array($this, 'disable_other_lightboxes'), 200);
}
}
}
How, if possible, do I dequeue these scripts (and styles) without editing the plugin file directly?
Edit
Below I've added the things I've tried doing to remove the scripts (all added to functions.php):
add_action( 'wp_enqueue_scripts', 'remove_foobox_scripts', 100 );
function remove_foobox_scripts() {
if ( !is_page('my-page') ) {
wp_deregister_script( 'foobox.free.min.js' );
wp_dequeue_script( 'foobox.free.min.js' );
}
}
Also tried the below, which is just a straight copy from the foobox file:
remove_action('wp_enqueue_scripts', array($this, 'frontend_print_scripts'), 20);
remove_action('foobox-free_inline_scripts', array($this, 'inline_dynamic_js'));
remove_action('wp_enqueue_scripts', array($this, 'frontend_print_styles'));
Also tried the below, where the array( part is removed:
remove_action('wp_enqueue_scripts','frontend_print_scripts', 20);
remove_action('foobox-free_inline_scripts', 'inline_dynamic_js');
remove_action('wp_enqueue_scripts', 'frontend_print_styles');
The problem with the way you are trying to do this stems from the order in which things happen in Wordpress.
You are relying on the conditional tags like is_page('my-page') to determine whether or not to load the plugin. These conditional tags do not become available until Wordpress has parsed the URL for the current query, and at this point all the plugins and your theme have already been loaded. Even if you parse the URL yourself instead of using the conditional tags you cannot be sure your code will run before the plugins are loaded.
The solution is to add your code as an mu-plugin. These are loaded before normal plugins so you can use an option (option name) filter here to alter the plugins you want to be loaded.
Option filters pass an array to your function containing the values which are set for that option, so in this case you want to hook option_active_plugins.
You can find the values to use for by running print_r(get_option('active_plugins')); or look through the plugins folder of your wordpress install.
The following example is specific to your question, but you could modify it to make a more comprehensive set of rules, adding and removing multiple plugins on different pages based on many conditions.
My function checks you are not in wp-admin and then has 2 conditions. The first disables a normally active plugin on the specified pages, the second enables a normally disabled plugin on the specified pages.
<?php
add_filter( 'option_active_plugins', 'add_or_remove_plugins' );
function add_or_remove_plugins( $plugins ) {
if (strpos( $_SERVER['REQUEST_URI'], '/wp-admin/' ) !== 0) { // Disable in admin pages or admin plugin settings stop working properly
if (strpos( $_SERVER['REQUEST_URI'], '/remove-plugin-here/' ) === 0) { // Conditonal tags still unavailable so you have to parse urls yourself
$k = array_search( 'foobox-image-lightbox/foobox-free.php', $plugins ); // This will stop an active plugin from loading
if( false !== $k ){
unset( $plugins[$k] );
}
}
if (strpos( $_SERVER['REQUEST_URI'], '/add-plugin-here/' ) === 0) {
$plugins[] = 'foobox-image-lightbox/foobox-free.php'; // This will load the plugin along with all the active plugins
}
}
return $plugins;
}
?>
To install just change the values to suit, paste into a file and upload into your mu-plugins folder
EDIT
Looks like your inline js is added to wp_head during the constructor of the Foobox_Free class. You could try adding this to your functions.php:
add_action( 'wp_head', 'remove_dynamic_js' );
function remove_dynamic_js(){
$foo = Foobox_Free::getInstance();
remove_action('wp_head', array($foo, 'inline_dynamic_js'));
}
or if that doesn't work then maybe this:
add_action( 'wp_head', 'remove_dynamic_js' );
function remove_dynamic_js(){
remove_action('wp_head', array('Foobox_Free', 'inline_dynamic_js'));
}
The action is added inside a private function, so I don't know if either of those will actually work. Give it a shot. If not my first answer will as it stops the plugin from loading at all on the specified pages.
UPDATE
Well, I was close... Here's the code to remove the scripts, as supplied by the plugin author.
$foobox = Foobox_Free::get_instance();
remove_action('foobox-free_inline_scripts', array($foobox, 'inline_dynamic_js'));
I have a theme that is adding a custom, full-screen background image via jQuery. The theme is doing this via a class object called td_background. Within the class is a function called wp_head_hook(), and within this hook, a filter is being added for the custom bg. It looks something like this:
class td_background {
// ..some stuff
function __construct() {
add_action('wp_head', array($this, 'wp_head_hook'), 10);
}
function wp_head_hook() {
add_filter( 'td_js_buffer_footer_render', array($this, 'add_js_hook'));
}
function add_js_hook($js) {
// Custom JS added here for background image
return $js
}
}
new td_background();
I'm now trying to de-register the add_js_hook in a custom plugin I'm writing, but am having trouble wrapping my mind around how to do it with all this nesting. I've tried a few things, such as:
<?php
// This...
remove_filter( 'wp_footer', array($td_background, 'td_js_buffer_footer_render'));
// ...and this
remove_filter( 'wp_footer', 'td_js_buffer_footer_render');
// ...and even
remove_filter( 'wp_footer', 'add_js_hook', 100);
?>
I've also tried changing the above to wp_head.
Thoughts? My end goal is to de-register this JavaScript in the footer, so that I can add my own in place of it.
As it's being instantiated anonymously, we have to use the handy function remove_anonymous_object_filter() from WPSE, it would be something like:
// Run this from a plugin
add_action( 'template_redirect', 'kill_anonymous_example', 0 );
function kill_anonymous_example() {
remove_anonymous_object_filter(
'wp_head',
'td_background',
'wp_head_hook'
);
}
I tested killing wp_head as I don't have a td_js_buffer_footer_render running.
How to get following to work properly in Wordress Theme functions.php file?
I haven't figured out how to make the top function available to the bottom function within the theme's functions.php file. I'm not grasping how to setup hooks so they can work together. Thank you.
Filter/helper/whateveryoucallit function:
function poohToPee( $pooh_log )
{
switch( $pooh_log )
{
case 'gross-poop':
$pee_equivalent = 'Grossest of Pees';
break;
case 'ok-poop':
$pee_equivalent = 'Bland Snack Pee';
break;
case 'shang-tsung-plop':
$pee-equivalent = 'Random U-Stream';
break;
}
return $pee_equivalent;
}
Ajax handler function:
function screw_loose()
{
if( isset($_REQUEST['pooh_log']) )
{
echo poohToPee( $_REQUEST['pooh_log'] );
}
}
add_action('wp_ajax_priv_screw_loose', 'screw_loose')
The add_action usually calls the function you are passing through at the point that hook is called.
Since you are using some sort of ajax hook are you really able to make sure your function isn't being called? It wouldn't be echo-ing anything out to the screen since it is running in the background.
Normally any function you define in functions.php is readily available to use within the theme.
It is obviously normally best to organize and have classes, in which case you'd pass the method to the hook as an array, for example add_action( 'admin_init', array( $this, 'someFunction' ) ); and that add_action I just did would be put in the __construct function of the class.
For instance you could do this:
class helloWorld
{
function __construct()
{
add_action( 'admin_init', array( $this, 'echoItOut' ) );
}
function echoItOut()
{
echo 'Hello World';
}
}
$helloWorld = new helloWorld;
Alternatively you could also do this:
class helloWorld
{
function echoItOut()
{
echo 'Hello World';
}
}
$helloWorld = new helloWorld;
add_action( 'admin_init', array( $helloWorld, 'echoItOut' ) );
Or simply:
function echoItOut()
{
echo 'Hello World';
}
add_action( 'admin_init', 'echoItOut' );
If you put any of these blocks of code I provided in your functions.php file and go to your Dashboard you will see 'Hello World' printed out at the top under the admin bar most likely (might vary from theme to theme if the dashboard has custom styling).