Разработка плагинов: WordPress обрабатывает два раза после обновления. Как пропустить процесс на первом?

Когда вы создаете плагин и настраиваете функцию процесса, WordPress дважды запустит функцию процесса плагина, нажав кнопку обновления. Я считаю, что первый процесс для публикации версии (ревизии), а второй – фактический пост.

Теперь у меня есть функция INSERT в моем процессе, поэтому теперь она вставляет данные дважды.

Каков наилучший способ гарантировать, что обработка не будет выполняться при создании ревизии и только при фактической последующей обработке?

* Примечание: Ориентация WordPress 3.0+ *

Пример (полный плагин):

<?php /* Plugin Name: Something Amazing Plugin URI: http://www.somewhere.com/ Description: Displays something. Author: Some guy Version: 1.0 Author URI: http://www.somewhere.com/ */ function call_something() { return new something(); } if (is_admin()) add_action('load-post.php','call_something'); class something { public function __construct() { add_action('add_meta_boxes',array(&$this,'something_add_boxes')); add_action('save_post',array(&$this,'something_process'),1,1); } public function something_add_boxes() { add_meta_box('something','Some Thing',array(&$this,'something_form'),'post','side','default'); } public function something_form($post,$args) { echo '<p><input type="text" name="somethingnew" /></p>'; } public function something_process($id) { echo 'hey there! I\'m going to cause a redirect warning, but you will see this line twice per submit!'; //do_something_amazing(); } } ?> 

Возможно, есть лучший крючок для обработки, который не заставляет его писать дважды?

Solutions Collecting From Web of "Разработка плагинов: WordPress обрабатывает два раза после обновления. Как пропустить процесс на первом?"

@Steve Функция hook to save_post всегда вызывается дважды, функции вызова WordPress подключены к save_post дважды, потому что:

  • первый раз он сохраняет пост-ревизию.
  • второй раз он сохраняет фактический пост.

ПРИМЕЧАНИЕ. Если вы отключили пост-ревизии, используя define('WP_POST_REVISIONS', false); то квест save_post будет запущен только один раз, когда фактическое сообщение будет сохранено.

Я просто протестировал следующий код, и он работает как ожидалось, и эхо работает только один раз в функции something_process.

ПРИМЕЧАНИЕ. Как я привязался к save_post

 <?php /* Plugin Name: Something Amazing Plugin URI: http://www.somewhere.com/ Description: Displays something. Author: Some guy Version: 1.0 Author URI: http://www.somewhere.com/ */ function call_something() { return new something(); } if (is_admin()) add_action('load-post.php','call_something'); class something { public function __construct() { add_action('add_meta_boxes',array(&$this,'something_add_boxes')); add_action('save_post',array(&$this,'something_process'),1,2); } public function something_add_boxes() { add_meta_box('something','Some Thing',array(&$this,'something_form'),'post','side','default'); } public function something_form($post,$args) { echo '<p><input type="text" name="somethingnew" /></p>'; } public function something_process($id, $post_object) { // don't run the echo if this is an auto save if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return; // don't run the echo if the function is called for saving revision. if ( $post_object->post_type == 'revision' ) return; echo 'hey there! I\'m going to cause a redirect warning, but you will see this line twice per submit!'; //do_something_amazing(); } } ?> 

Вам нужно убедиться, что ваш код запускается только при сохранении сообщения, а не при выполнении ревизии или автоматического сохранения.

Проверьте, действительно ли текущий идентификатор сообщения действительно является фактическим сообщением, а не ревизией или автосохранением, делая это (фактическое сообщение всегда возвращает значение FALSE):

 if ( is_int( wp_is_post_revision( $id ) ) ) return; if( is_int( wp_is_post_autosave( $id ) ) ) return; 

вы можете избежать автосохранения с помощью простой проверки вашей функции, что-то вроде

 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return ''; } 

Обновить

Как я уже опубликовал, просто добавьте вышеприведенный фрагмент к самой вершине вашей функции something_process прежде чем что-либо еще.

В моих плагинах я проверяю статус сообщения – это ревизия. Вы можете сделать что-то подобное в функции «что-то процесса».

 public function something_process($id, $post) { if ($post->post_type == 'revision') return; echo 'hey there! I\'m going to cause a redirect warning, but you will see this line twice per submit!'; //do_something_amazing(); } 

Добавление if ($post->post_type == 'revision') return; line, вы «отмените» первый вызов функции на WP.

Вы также должны сделать вторую замену на крючке действия. Просто измените строку:

 add_action('save_post',array(&$this,'something_process'),1,1); 

к этому:

 add_action('save_post',array(&$this,'something_process'),1,2); 

Подобно этому вы передаете второй параметр в действие «save_post» (переменная $post )

Я слышал, что вы ищете «лучший» способ … ну, это зависит. Код должен обрабатывать пользовательские проблемы – так же, как вы не выбрали бы кадиллак, чтобы отправиться в путь, и вы не могли (вероятно) взять джип на ночь в оперу.

У меня есть плагин, который обрабатывает оба процесса, которые запускаются с сохранением. Я использую статический var и условно выбираю, какой код я хочу запустить. Я также проверяю идентификатор post parent, используя вышеприведенную функцию wp_is_post_revision (), и имею большую гибкость при настройке условий для удовлетворения моих потребностей именно на основе этих результатов.

 function complex_meta_update_on_save($id){ $ppid = wp_is_post_revision($id); (can also employ) if($post_parent_id === false) $ppid = $id; ...set environmentals... static $tc; if($tc < 1){ execute conditions essential for revisions, or preprocess for ppid } //note no else- i can do stuff here that is ok to duplicate, processing, etc. if($tc > 0) { execute conditions and statements essential for post parents update custom tables with custom queries, register newly processed taxonomies, et. al. keep in mind, on Save hook, post data has been saved in db. My plugin uses special metadata that needs to know whether I've got a revision, or the parent. update_post_meta($id, $blah);now is ok to use $id in } //oh the staticness of it all $tc++; }//end function и function complex_meta_update_on_save($id){ $ppid = wp_is_post_revision($id); (can also employ) if($post_parent_id === false) $ppid = $id; ...set environmentals... static $tc; if($tc < 1){ execute conditions essential for revisions, or preprocess for ppid } //note no else- i can do stuff here that is ok to duplicate, processing, etc. if($tc > 0) { execute conditions and statements essential for post parents update custom tables with custom queries, register newly processed taxonomies, et. al. keep in mind, on Save hook, post data has been saved in db. My plugin uses special metadata that needs to know whether I've got a revision, or the parent. update_post_meta($id, $blah);now is ok to use $id in } //oh the staticness of it all $tc++; }//end function 

Я не знаю, что любой из них блестящий или даже лучшая идея, это то, что работает там, где мне нужно, – и мне не нужно управлять гораздо большим количеством крючков, чем редактировать и сохранять … довольно просто в одном отношении.