¿Es posible dentro de la acción save_post determinar si se está creando una nueva publicación o si se está actualizando una publicación existente?
¿Es posible dentro de la acción save_post determinar si se está creando una nueva publicación o si se está actualizando una publicación existente?
Respuestas:
Desde WordPress versión 3.7. - IIRC - el save_post
gancho - más información sobre el gancho y su uso en Code Reference:save_post
y Codex:save_post
- tiene un tercer parámetro $update
que puede usarse para determinar exactamente eso.
@param int $ post_ID ID de publicación.
@param WP_Post $ post Publicar objeto.
@param bool $ update Si esta es una publicación existente que se está actualizando o no.
Nota:
$update
no siempre es así true
: puede verlo y probarlo usted mismo con el siguiente código. Sin embargo, no está bien documentado, posiblemente lejos de tener un nombre óptimo y, por lo tanto, crea expectativas engañosas. El siguiente código se puede usar para algunas depuraciones, juegue con cuándo interceptar la ejecución del código, porque de lo contrario no verá la información / mensajes. Creo que el culpable del comportamiento engañoso es el manejo de revisiones y guardados automáticos, que podrían desactivarse, pero no lo recomiendo y no lo he probado. No estoy seguro de si esto justifica un ticket de Trac , así que no abrí uno, si lo cree, siga el enlace y hágalo usted mismo. Aparte de eso, como se indica en los comentarios, si tiene un problema específico, publique una nueva pregunta.
add_action( 'save_post', 'debug_save_post_update', 10, 3 );
function debug_save_post_update( $ID, $post, $update ) {
echo '<pre>';
print_r( $post ); echo '<br>';
echo '$update == ';
echo $update ? 'true' : 'false';
//conditions
if( ! $update && $post->post_status == "auto-draft" ) {
// applies to new post
echo ' && $post->post_status == "auto-draft"';
//die();
} else if ( ! $update ) {
// applies basically to the (auto saved) revision
//die();
} else {
// applies to updating a published post
// when there is a revision, which is normally the case,
// standard behavior of WordPress, then it is considered
// an update, which is where the confusion sets in
// there are other methods, like checking time or post status
// depending on your use case it might be more appropriate
// to use one of those alternatives
//die();
}
echo '</pre>';
//die();
}
$update
parámetro SIEMPRE es verdadero incluso cuando se trata de una nueva publicación. Entonces este parámetro es inútil. No estoy seguro de si alguna vez funcionó, pero de seguro no funciona de la manera que está documentada en la última versión de WordPress 4.8.
wp_publish_post
, entonces sí. Pero eso no es cierto para su uso en wp_insert_post
. He escrito una función de depuración, la agrego a la respuesta.
save_post
gancho tiene un tercer parámetro que siempre se establece en VERDADERO, por lo que no estoy seguro de qué tiene que ver con otros ganchos, sin hablar de otros ganchos. Estoy hablando del gancho en tu respuesta. Esto es incorrecto.
wp_insert_post()
, wp_publish_post()
. Este último es solo publicaciones futuras, $update
está configurado para ser siempre true
. De lo contrario, en lo que respecta wp_insert_post()
, $update
no es siempre true
.
La forma en que realizo esta verificación (dentro de una función enganchada) es comparar la fecha de publicación y la fecha de modificación (en GMT para la estandarización)
function check_new_vs_update( $post_id ){
$myPost = get_post($post_id);
$post_created = new DateTime( $myPost->post_date_gmt );
$post_modified = new DateTime( $myPost->post_modified_gmt );
if( abs( $post_created->diff( $post_modified )->s ) <= 1 ){
// New post
}else{
// Updated post
}
}
add_action('save_post', 'check_new_vs_update' );
Esto funciona porque incluso en la creación, la publicación tiene una fecha 'modificada' adjunta, que es exactamente la misma que la fecha 'creada', pero permitimos una variación de 1 segundo en cualquier caso en caso de que un segundo marque durante la creación de el cargo.
post_date_gmt
es 2019-03-12 01:31:30
y el post_modified_gmt
es 2019-03-12 01:31:31
. :(
Terminé simplemente comprobando la existencia de un valor personalizado antes de configurarlo. De esa manera, si se trata de una publicación recién creada, el valor personalizado aún no existiría.
function attributes_save_postdata($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!wp_verify_nonce($_POST['_attributes_noncename'], plugin_basename(__FILE__))) return;
if ('page' == $_POST['post_type']) {
if (!current_user_can('edit_page', $post_id)) return;
} else {
if (!current_user_can('edit_post', $post_id)) return;
}
$termid = get_post_meta($post_id, '_termid', true);
if ($termid != '') {
// it's a new record
$termid = 'update';
} else {
// it's an existing record
}
update_post_meta($post_id, '_termid', $termid);
}
add_action('save_post', 'attributes_save_postdata');
Ejemplo de respuesta de ialocina con paremeter "update":
function save_func($ID, $post,$update) {
if($update == false) {
// do something if its first time publish
} else {
// Do something if its update
}
}
add_action( 'save_post', 'save_func', 10, 3 );
if($update)
o mantener el nuevo bloque primero pero usando if( ! $update )
. Este último llevará a OP a una mejor práctica y es preferible a su método por los estándares de codificación de WordPress en casos como el operador ternario
Puede usar el enlace de acción pre_post_update para el código de actualización y save_post para el nuevo código postal. Funciona antes de que se actualice una publicación.
save_post
gancho se disparó tanto cuando se crea un poste y actualiza (después de WordPress se ha guardado en la base de datos). pre_post_update
se activa cuando se actualiza una publicación, pero antes de que se actualice, esto puede ser importante.
Como Darshan Thanki insinuó (y Stephen Harris dio más detalles), puede utilizarlo pre_post_update
para su ventaja.
global $___new_post;
$___new_post = true;
add_action(
'pre_post_update',
function() {
global $___new_post;
$___new_post = false;
},
0
);
function is_new_post() {
global $___new_post;
return $___new_post;
}
La razón por la que usé globals es porque function is_new_post() use ( &$new_post )
no es válido en PHP (impactante ...), por lo que incorporar esa variable en el alcance de la función no funciona, de ahí el global.
Tenga en cuenta que esto realmente solo se puede usar de manera confiable dentro / después del save_post
evento (que generalmente es suficiente, al menos para lo que estamos haciendo con él).
Cuando se activa save_post, toda la información sobre esa publicación ya está disponible, por lo que, en teoría, podría usar
function f4553265_check_post() {
if (!get_posts($post_id)) {
// if this is a new post get_posts($post_id) should return null
} else {
// $post_id already exists on the database
}
}
add_action('save_post','f4553265_check_post');
Sin embargo, esto no ha sido probado. =)
save_post
la publicación en sí, ya se habría guardado en la base de datos, por get_posts
lo que devolvería la publicación actual.
Otro enfoque que utiliza una función incorporada y no implicaría ninguna adición a la base de datos get_post_status()
.
$post_status = get_post_status();
if ( $post_status != 'draft' ) {
//draft
} else {
//not a draft: can be published, pending, etc.
}
Sin embargo, tenga en cuenta que es posible que no sea apropiado si luego planea volver a establecer el estado en "borrador"; sus instrucciones se repetirán la próxima vez que actualice la publicación. Dependiendo del contexto, es posible que desee considerar las diversas cadenas que puede devolver get_post_status()
para crear un escenario más apropiado.
Ver Codex para get_post_status () y estado de publicación
Los valores posibles son:
- 'publicar': una publicación o página publicada
- 'pendiente': la publicación está pendiente de revisión
- 'borrador': una publicación en estado de borrador
- 'borrador automático': una publicación recién creada, sin contenido
- 'futuro' - una publicación para publicar en el futuro
- 'privado': no visible para los usuarios que no han iniciado sesión
- 'heredar': una revisión. ver get_children.
- 'basura': la publicación está en la papelera. agregado con la versión 2.9.
save_post()
se ejecuta por primera vez, pero durante esa ejecución get_post_status()
ya devuelve 'publicar' y no 'borrador', aunque solo esté en proceso de publicación.