wordpress: detecting rewrite rules flush - wordpress

I have my own plugin that, on activation, adds some rewrite rules which map url's to single page applications.
Now, I lose the rules once in a while, after some other plugin updates or maybe another process that triggers flush_rewrite_rules in Wordpress.
The problem is, I do not know when, how or why it happens. And by whom.
So I have searched globally in my WP files and come up with the following actions that trigger a refresh
add_action( 'woocommerce_settings_saved', array( $this, 'load' ) );
add_action( 'woocommerce_attribute_added', array( $this, 'load' ) );
add_action( 'woocommerce_attribute_updated', array( $this, 'load' ) );
add_action( 'woocommerce_attribute_deleted', array( $this, 'load' ) );
add_action( 'wp_install', array( $this, 'load' ) );
add_action( 'after_db_upgrade', array( $this, 'load' ) );
add_action( 'after_switch_theme', array( $this, 'load' ) );
When one of those actions are triggered, I reload my rules.
That works, when one of those triggers.
So probably, once in a while another one triggers that I can't find.
Or maybe the flush happens after the action triggers, rendering my load useless.
So, is there a better way to hook into a flush so that I can add my own rules there automatically?
Now we figure it out a couple of days later when someone complains that the app is not working and I have to load the rules again.
Any suggestions are appreciated.
Cheers

I can see a couple of options; fixing the symptoms, or tracking down the cause.
Fixing the symptoms
At the end of the WP_Rewrite::rewrite_rules() function is a filter rewrite_rules_array:
$this->rules = apply_filters( 'rewrite_rules_array', $this->rules );
You could hook into that and make your rules are there (adding them if they don't exist). Hook it with a high number for the $priority argument, in case the rules are being removed using the same hook.
Tracking down the cause
Alternatively, you could change the flush_rewrite_rules function itself (assuming that's the entry point for the rogue changes that are deleting your rules), and have it email you a stack trace whenever it's called. It might help you track down the cause. Something like (completely untested):
function flush_rewrite_rules( $hard = true ) {
global $wp_rewrite;
$e = new Exception();
wp_mail ( 'you#example.com', 'flush_rewrite_rules called', $e->getTraceAsString() );
$wp_rewrite->flush_rules( $hard );
}
Obviously that change is only temporary, until you have a lead on the problem - I'd never advocate changing core code permanently.
If that doesn't work, you may need to put it deeper into $wp_rewrite, like the generate_rewrite_rules function.

Related

Remove license message in Wordpress

I'm trying to disable the license notification for a plugin a bought a few months ago. Now my license for updates is not longer valid but I don't want to receive any updates anymore because I've changed a lot in the plugin. This is the message:
I've tried to remove it this way:
add_filter( 'site_transient_update_plugins', 'filter_plugin_updates' );
function filter_plugin_updates( $value ) {
unset( $value->response['cred-frontend-editor/plugin.php'] );
return $value;
}
But when I refresh the page the notification is still there. How can I remove it?
This depends on the plugin. But the steps I would take.
Search to plugin codebase for variations of add_action( 'admin_notices', 'callback_notice function')
Then try to use remove_action to de-hook that notice.
Keep in mind remove_action has to run after the add_action, So if that add_action is done inside an add_action('admin_init', ...,10) (prio 10) you should run the remove action in an add_action('admin_init', ...,11)
Yes this part is confusing.
Good luck
Edit
Given the code you provided the remove should be:
add_action( 'init', function() {
remove_action( 'admin_notices', array( WP_Installer::instance(), 'setup_plugins_page_notices' ) );
remove_action( 'admin_notices', array( WP_Installer::instance(), 'setup_plugins_renew_warnings' ), 10 );
remove_action( 'admin_notices', array( WP_Installer::instance(), 'queue_plugins_renew_warnings' ), 20 );
}, 100);
The add_actions are run in the init function. the init function is hooked in the , well the init hook, at default priority (10)
So we run the removes after that in the init hook at prio 11.
Probably you don't need to remove the setup_plugins_page_notices hook.

Can't use WordPress Plugin Hooks

I'm using the WordPress plugin Ultimate member which has a hook called um_user_register which should happen after a user fills out a registration form. According to the documentation (https://docs.ultimatemember.com/article/1308-umuserregister) I should be able to use that hook and do my thing. Unfortunately nothing happens.
The code I have added to my theme's functions.php file:
//Ultimate Member - Extra stuff after user registers
add_action( 'um_user_register', 'my_user_register', 10, 2 );
function my_user_register( $user_id, $args ) {
add_user_meta( $user_id, 'user_utlimate_member_signup', 'Yes');
}
Am I putting my add_action or function in the wrong place or is there something I'm overlooking?

WP Plugin Development - Conditional CSS on shortcode

I'm currently developing a plugin for wordpress.
My plugin-content gets fired on defined shortcode. I pass a parameter to the shortcode to make some conditionals. I am able to load JS conditionally, but I also need to load CSS conditionally.
Lets say I use the shortcode: [myshortcode css="dark"]
I make a database query and inject the wanted css.
Is this somehow possible?
I have read some threads about it. I know it is because the Code fires after head is loaded. I wasn't able to find a solution.
What options do I have?
Thank you!
Probably you are searching for these functions:
has_shortcode()
get_shortcode_regex() - here you can find nice example, which is close to your request
You can check your post, page or custom post type on hook by add_action ( 'wp', 'yourCustomFunction' ) and test if your get_post_field ( 'post_content' ) contains specified shortcode and conditionally enqueue CSS file based on specified attribute.
There is a better way. You can simply register your css and scripts with wp_enqueue_scripts by wp_register_style or wp_register_script and then enqueue the registered scripts from your shortcode. You will have opportunity to enqueue scripts based on certain condition there.
Here is a code example.
/**
* Register scripts
*/
function my_plugin_scripts() {
wp_register_style( 'dark-css', $css_path );
wp_register_script( 'script-name', $js_path, array(), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'my_plugin_scripts' );
/**
* My Shortcode
*/
function my_plugin_shortcode( $atts ) {
$atts = shortcode_atts( array(
'css' => 'default'
), $atts );
if ( $atts['css'] == 'dark') {
wp_enqueue_style('dark-css')
}
// do shortcode actions here
}
add_shortcode( 'shortcode-id','my_plugin_shortcode' );
If I understand your question correctly, you could do something like this to load one stylesheet or the other:
function aw_shortcode_function($atts) {
$a = shortcode_atts( array(
'css' => 'light', // this is the default value
), $atts );
$colorTheme = $a['css'];
if ($colorTheme == 'dark') {
// load/enqueue/get/do whatever based on the css="dark" shortcode attribute
}
}

Woocommerce override plugin action

The file email-order-items.php has the following line of code:
echo "\n" . sprintf( __( 'Cost: %s', 'woocommerce' ), $order->get_formatted_line_subtotal( $item ) );
The following action hook has been added to a plugin I am using (Woocommerce Composite Products):
add_action( 'woocommerce_order_formatted_line_subtotal', array( $this, 'wc_cp_order_item_subtotal' ), 10, 3 );
I would like to override the function wc_cp_order_item_subtotal to change the way to item subtotal is displayed. I have tried adding the following to my child theme functions.php, but it doesn't do anything.
remove_action( 'woocommerce_order_formatted_line_subtotal', 'wc_cp_order_item_subtotal', 10);
add_action( 'woocommerce_order_formatted_line_subtotal', 'child_wc_cp_order_item_subtotal', 10, 3);
function child_wc_cp_add_order_item_meta( $order_item_id, $cart_item_values, $cart_item_key = '' ) {
return 'xxxxxxx';
}
Any tips to help me get this working would be greatly appreciated.
It isn't mentioned in the Codex, but I usually call the remove_action() function from a hook.
Also, as covered in the Codex example for action added from classes, you need to access the class instance or variable.
I don't see wc_cp_order_item_subtotal in the Composite plugin anywhere, so I presume you aren't using Woo's version. In which case, I don't have access to the code and can't tell you exactly how to access the class variable.
But if you were using Woo's Composite Products it would be as follows:
Edited for Composites 2.4
function so_remove_action(){
global $woocommerce_composite_products;
remove_action( 'woocommerce_order_formatted_line_subtotal', array( $woocommerce_composite_products->order, 'wc_cp_order_item_subtotal' ), 10, 3 ); //not sure why it isn't a filter, but also not sure if there is a huge difference
}
add_action('init', 'so_remove_action');

WordPress plugins wp_enque_script()

so i'm developing my first WordPress plugin and i am having some difficulties...
I am doing it Object Oriented...
In the bottom, when 'plugins_loaded', i Create a new instance of myClass. It also enques a javascript, everytime any page is loaded. This script registration works, because i get a console.log every page load. It then registers an action on 'publish_post' that is fired when an admin publishes(saves) a new post and invokes my publish_post() method.
The method is called, when a post is published; i know it because if i uncomment it's two first lines, the sctipt dies with my var_dump.
My problem is that wp_enque_script() is not working in this method. For some reason my script isn't called...
Here's the code:
<?php
class myClass{
function __construct(){
// hooks & filters..
add_action( 'publish_post', array($this, 'publish_post'));
wp_enqueue_script(
'plugin', //$handle
plugins_url('/js/plugin.js', __FILE__)//$src
);
}
function publish_post(){
//global $wp_query;
//die(var_dump($wp_query));
wp_enqueue_script(
'publish', //$handle
plugins_url('/js/publish.js', __FILE__)//$src
);
}
}
/* Initialise outselves */
add_action( 'plugins_loaded', create_function( '', 'global $myObject; $myObject = new myClass;' ));
?>
Anyone has any idea why this is happening? thanx
Just had the same problem. You have to add it to a hook, for example the init (I tried with admin_head hook but that didn't work so I picked init because I saw it in another plugin. And it seem to work fine for me)
In you construct add:
add_action('init', array($this, 'loadMyScripts'));
and in the function called by the action:
public function loadMyScripts()
{
wp_enqueue_script(
'publish', //$handle
plugins_url('/js/publish.js', __FILE__)//$src
);
}

Resources