I have a quite complex PHP class, reponsible for creating and printing meta_boxes, generating and saving meta fields, …
Each meta_box (object of class) has its own save function, that updates meta data of post (fields for them are instances of another class) as well as its post_excerpt
and post_content
. Yep, it’s probably a little complicated, but as I’m only starting with OOP, I’m pretty happy with it so far.
TL;DR, THE PROBLEM: With wp_update_post()
called on save_post
hook, I get an infinite loop. This issue is documented on WP codex as well as mentioned here on WPSE: How to avoid infinite loop in save_post callback.
If you are calling a function such as wp_update_post that includes the save_post hook,
your hooked function will create an infinite loop. To avoid this, unhook your function
before calling the function you need, then re-hook it afterward.Source: Codex
This is a very simplified version of a code I am using:
class MetaBox {
public function __construct() {
// a lot of stuff, hooks and other function initiations
add_action('save_post',array($this,'save_box'), 20);
}
// more stuff
function save_box() {
// verify nonces, bail out on autosave, ajax, cron, ...
switch ($this->id) {
case 'editor':
case 'postexcerpt':
// remove action
remove_action('save_post', array($this,'save_box'));
// bail out on post_revision
if (!wp_is_post_revision($post_id) ){
$post = array(
// post id
'id' => $post_id,
// tosave: either post_content or post_excerpt
// value: pulled from static associative multi-array inside MetaBox
$tosave => self::$meta[$this->id][$this->id]
);
wp_update_post($post);
}
// add action back
add_action('save_post', array($this, 'save_box'));
break;
default:
// some saving functionality for meta values, that WORKS just fine
break;
}
}
}
I am getting an infinite loop with PHP error notice: Undefined index: ID in XXX/web/wp-includes/post.php on line 2987
Am I removing/adding save hook wrong? Does it have something in common with using the save function non-statically?
I am of course happy to provide the rest of the relevant code, if there’s no apparent problem with this structure.
EDIT
The infinite loop problem is gone – as @TheDeadMedic mentioned, problem lied at not matching priority.
To remove a hook, the $function_to_remove and $priority arguments must match when the
hook was added. This goes for both filters and actions. No warning will be given on
removal failure.Codex: http://codex.wordpress.org/Function_Reference/remove_action
EDIT 2
As PHP is a case sensitive language, Undefined index ID
notice problem lied in my $post array (parameter of wp_update_meta
). The ID key must be specified uppercase.
$post = array(
'ID' => $post_id // ID must be uppercase
)
/////
As my question turned out to be very localized, feel free to delete it. And thanks again for helping me!
Thanks in advance!
You need to match the
$priority
you used to hook the action:http://codex.wordpress.org/Function_Reference/remove_action
Make sure you take the
$post_id
argument in yoursave_box
method too: