1

I am trying to modify post data on post save action.

Firstly I tried to use save_post hook like that

function post_save_action($post_id, $post, $update)
    {
        if ($this->is_temp_saving_post($post, $post_id)) {
            return;
        }
        // Check user permissions
        if (!current_user_can('edit_post', $post_id))
            return;
        // Update post
        if (!$this->is_proper_post_type($post)) {
            return;
        }
        $processed_content = $this->process_post_data($post);
        $update_data = [
            self::POST_ID => $post_id,
            self::POST_CONTENT => $processed_content
        ];
        // Prevent infinite loop
        remove_action('save_post', array($this, 'post_save_action'), 99);
        // Update the post into the database
        wp_update_post($update_data);
        // Add hook again
        add_action('save_post', array($this, 'post_save_action'), 99);
    }

The problem here is that wp_update_post($update_data); triggers save_post action again for other plugins, so all plugins except mine are being executed twice, and that is bad.

Then I found another hook wp_insert_post_data and add my processing logic

public function post_insert_filter($data, $postattr)
    {
        $post_id = $postattr['ID'];
        $post_object = $this->convertToObject($data);
        $post_object->ID = $post_id;
        if ($this->is_temp_saving_post($post_object, $post_id)) {
            return $data;
        }
        if (!current_user_can('edit_post', $post_id)) {
            return $data;
        }
        // Update post
        if (!$this->is_proper_post_type($post_object)) {
            return $data;
        }
        $processed_content = $this->process_post_data($post_object);
        $data[self::POST_CONTENT] = $processed_content;
        return $data;
    }

It works hook is not called twice, but the problem for the time wp_insert_post_data is triggerd, data already has been escaped(parentheses) somewhere, but I need raw data here.

Please suggest the right way to modify data considering all requirements.

1 Answer 1

1

At first, Data was sanitized here (line 2997).

If you don't want any plugin/theme run on action save_post. User function remove_all_actions to remove all functions hooked to action save_post.

function post_save_action($post_id, $post, $update)
 {
    if ($this->is_temp_saving_post($post, $post_id)) {
        return;
    }
    // Check user permissions
    if (!current_user_can('edit_post', $post_id))
        return;
    // Update post
    if (!$this->is_proper_post_type($post)) {
        return;
    }
    $processed_content = $this->process_post_data($post);
    $update_data = [
        self::POST_ID => $post_id,
        self::POST_CONTENT => $processed_content
    ];
    // Backup actions
    global $wp_filter, $merged_filters;
    $backup_wp_filter = $wp_filter;
    $backup_merged_filters = $merged_filters;
    // Remove all functions which hooked to this action, to prevent run twice.
    remove_all_actions('save_post');
    // Update the post into the database
    wp_update_post($update_data);
   // restore actions
    $wp_filter = $backup_wp_filter;
    $merged_filters = $backup_merged_filters;
 }
2
  • Thank you so much this works, but maybe there are other ways. Because I fill little bit confused about backing up global variables, this may change in wordpress core and this won't work. Commented Dec 18, 2016 at 11:37
  • it's global vars, used in a lot of core functions, I don't think it will be changed in short term. :) Commented Dec 18, 2016 at 12:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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