3

I'm using a plugin, and I'm trying to auto-populate a custom field (dropdown) for the subscriber form, because it should list some dynamic data (related to the websites content).

The plugin has, as far as I can see, no filters or actions for this purpose. This forces me to think in any alternative ways to deal with this.

The plugin uses custom tables (not WP native/ built-in ones), so I was thinking if there's any action or filter that is fired when data is saved in any of these custom tables.

  • ask the plugin author to add filters. there is no other sane way – Mark Kaplun Mar 5 '17 at 13:04
  • Well, I wanted to be sure that I have no other way to solve the problem... – Capiedge Mar 5 '17 at 13:22
  • @MarkKaplun Sorry, but this is not true. – kaiser Mar 5 '17 at 13:57
  • @kaiser, I should have emphasized sane ;). You can do as your answer suggests but you still depend on the plugin author not changing the format of the data or how he uses it. If going to extreme low level manipulation you can also buffer the output and manipulate it – Mark Kaplun Mar 5 '17 at 15:31
  • @MarkKaplun The OP just wants to know if and when the plugin triggers any change. At this point, they can queue a later transaction where they fetch the result and add either their own modification in a second query or just do something else. I agree that it would be stupid if one would try to alter the string, but anything else is possible and not really a shaky solution as long as you know the table name. – kaiser Mar 5 '17 at 17:12
3

The plugin probably (or: hopefully) used the $wpdb object, an instance of the wpdb-class, to add the custom table. If so (and only if so), then its author probably also uses $wpdb->insert() to add rows/ entries to the table.

Taking a look at wpdb::insert(), and looking at its source, you will find out that this method just is a convenience wrapper around wpdb::_insert_replace_helper(), which sets the $type argument to INSERT. While this method does NOT have any filter, the source reveals that this function actually uses

return $this->query( $this->prepare( $sql, $values ) );

While wpdb::prepare() does not allow any modification via filters, let's take a look at wpdb::query(). There you will find the following filter:

$query = apply_filters( 'query', $query );

Now that we have an entry point, where we can add modifications, let's talk about how to identify the custom table that is filled with data. Looking at the SQL statement that gets shoveled into the statement for execution, you will notice the following line:

$sql = "$type INTO `$table` ($fields) VALUES ($formats)";

The $table variable comes from the function definition, which is the first argument of the $wpdb->insert() call. Normally any sane developer would use "{$wpdb->prefix}custom_table_name" there, to avoid a broken plugin if the table prefixed was changed away from wp_ inside wp-config.php.

Finally:

<?
/* Plugin Name: Do something when a custom table gets data added or altered */
add_filter( 'query', function( $query ) {
    // Return SQL unmodified. Not the table we are targeting.
    if ( false === strstr( $query, "{$wpdb->prefix}custom_table_name" ) ) {
        return $query;
    }

    // Return SQL unmodified. Not the actions we are targeting.
    # @TODO If you only want to act on either of them, modify the if-clause
    if ( 
        false === strstr( $query, "INSERT" ) 
        AND false === strstr( $query, "REPLACE" )
    ) {
        return $query;
    }

    # @TODO Do your custom task here and…
    # …modify according the query to your likings.

    return $query;
} );

Keep in mind that this plugin runs on each single query now. You might want to add checks like is_admin() and wrap the whole block of code in a function that is attached to a more exclusive hook to reduce the number of executions for it. Else you might slow down your site significantly.

  • 1
    Thank you very much for your time, Kaiser and @MarkKaplun. This is what I love about WP, there is always a way through which a solution can be worked out! – Capiedge Mar 6 '17 at 10:12
  • 1
    Excellent answer... A remaining question, though, is whether it would not be easier just to fork the plugin. That's often the case, esp if the developer is unresponsive to reasonable feature requests. – CK MacLeod Mar 7 '17 at 5:58
  • Holy shit! @kaiser flirts with demons!!! This answer is cold and hard. I agree with CKMacLeod fork the plugin at this point. Kick ass solution tho kaiser. – Nathan Powell Mar 7 '17 at 6:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.