Prevent a specific plugin custom field to update when I update a post - WordPress

I am using a specific plugin to count my post views.

It store in a postmeta custom field named "hits" the value and this value is updated in real time.

I just noticed that when, as an admin, I edit a post, the "hits" value does not increase while I am editing the post.

When I think about it seems logic because if "hits" value is 15 when I enter in a post edition, it will still be 15 when I finish my post edition because all postmeta are updated when I update a post. SO, even if 10 more people have visit my post my post counter still display a value of 15 when it should display 25.

So now I am trying very hard with my low PHP skill to prevent this field to be updated while I update my posts.

I tried different method but none of them worked :

  1. I tried to prevent this metadate to be updated before saving my post with the following code :
function exclude_hits_from_update($null, $object_id, $meta_key, $meta_value) {
        if ('hits' === $meta_key) {
            return true; 
        }
            return $null;
    }
    add_filter('pre_update_post_meta', 'exclude_hits_from_update', 10, 4);
  1. I also tried this code in order to try to get the value of the metadate just before updating the post but it did not work either (it seems that this just create more custom field named "hits") :
function prevent_hits_field_update( $post_id, $post, $update ) {

    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
        return;
    }
    if ( isset($_POST['hits']) ) {
        $current_hits = get_post_meta($post_id, 'hits', true);
        update_post_meta($post_id, 'hits', $current_hits);
    }
}
add_action('save_post', 'prevent_hits_field_update', 10, 3);
  1. I also tried to modify directly the save_post function in the plugin itself (by commenting the line "update_post_meta" but I know it is not enough :
public function adminSave( $post_id )
    {
        // skip for autosave
        if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
        {
            return;
        }

        // update hits count
        if( isset($_POST['post_type']) && in_array( $_POST['post_type'], array( 'post', 'page' ) ) )
        {    
            $hits = ( isset($_POST['hits']) && !empty($_POST['hits']) ? intval( preg_replace( '/[^0-9]/', '', $_POST['hits'] ) ) : 0 );
            
            if( $hits > 0 )
            {
                $hits_exists = get_post_meta( $post_id, 'hits', true );
                
                if( $hits_exists===false )
                {
                    add_post_meta( $post_id, 'hits', $hits, true );
                }
                else
                {
                    /*update_post_meta( $post_id, 'hits', $hits );*/ /* HERE */
                }
            }
        }
    
        // clear Popular Posts Widget
        $ahc_ppw = new AJAX_Hits_Counter_Popular_Posts_Widget();
        $ahc_ppw->clearCache();
        
        return true;
    }

Can anyone help me with this ? Unfortunately I can not change the plugin yet because it is linked to several blocks on my website and he use some efficient cache methods.

Thanks in advance for any help ! Jonathan

Upvotes: 0

Views: 43

Answers (1)

Uvindu Anuradha
Uvindu Anuradha

Reputation: 337

Jonathan, the issue lies in preventing the hits field from being overwritten during the post save process. Below is an approach to resolve this issue effectively:

Solution

We need to ensure that the hits value is not updated when saving the post, while still allowing other post meta fields to be updated as usual.

You can use the save_post action to handle this. Specifically, we will remove the hits value from the $_POST array before the post is saved. Here's how:

function prevent_hits_update_during_save($post_id) {
    // Skip for autosave
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }

    // Skip if it's not a post type we care about
    $post_type = get_post_type($post_id);
    if (!in_array($post_type, array('post', 'page'))) {
        return;
    }

    // Skip for REST API (to ensure compatibility with Gutenberg editor)
    if (defined('REST_REQUEST') && REST_REQUEST) {
        return;
    }

    // Remove 'hits' from the $_POST array to prevent update
    if (isset($_POST['hits'])) {
        unset($_POST['hits']);
    }
}
add_action('save_post', 'prevent_hits_update_during_save', 10);

This solution doesn’t involve modifying the plugin code, keeping it update-safe. If the plugin is handling hits updates outside of standard save_post or via JavaScript, further debugging would be required.

Let me know if this works for you!

Upvotes: 1

Related Questions