É possível, dentro da ação save_post, determinar se é uma nova postagem sendo criada ou uma postagem existente sendo atualizada?
É possível, dentro da ação save_post, determinar se é uma nova postagem sendo criada ou uma postagem existente sendo atualizada?
Respostas:
Desde a versão 3.7 do WordPress. - IIRC - o save_post
gancho - mais informações sobre o gancho e seu uso em Referência de Código:save_post
e Codex:save_post
- possui um terceiro parâmetro $update
que pode ser usado para determinar exatamente isso.
@param int $ post_ID ID da postagem.
@param WP_Post $ post Objeto Post.
@param bool $ update Se esta é uma publicação existente que está sendo atualizada ou não.
Nota:
$update
nem sempre é possível true
- você pode ver e testar você mesmo com o código abaixo. No entanto, ele não está bem documentado, possivelmente longe de ser o ideal, e, portanto, cria expectativas enganosas. O código abaixo pode ser usado para alguma depuração, brinque com quando interceptar a execução do código, porque, caso contrário, você não verá as informações / mensagens. Penso que o culpado de comportamento enganoso é o tratamento de revisões e salvamentos automáticos - que podem ser desativados, mas eu não recomendo e ainda não os testei. Não tenho certeza se isso merece um bilhete Trac , então eu não abri um, se você acha, siga o link e faça você mesmo. Além disso, conforme declarado nos comentários, se você tiver um problema específico, poste uma nova pergunta.
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 SEMPRE é verdadeiro mesmo quando é uma nova postagem. Portanto, este parâmetro é inútil. Não tenho certeza se alguma vez funcionou, mas com certeza não está funcionando da maneira que está documentada na versão mais recente do wordpress 4.8.
wp_publish_post
, então sim. Mas isso não é verdade para seu uso no wp_insert_post
. Eu escrevi uma função de depuração, adiciono-a à resposta.
save_post
gancho tem um terceiro parâmetro que é sempre definido como TRUE, portanto, não saiba o que isso tem a ver com outros ganchos, sem falar sobre outros ganchos. Estou falando do gancho na sua resposta. Isto está incorreto.
wp_insert_post()
, wp_publish_post()
. Este último é apenas posts futuros, $update
está definido para ser sempre true
. Caso contrário, no que diz respeito wp_insert_post()
, $update
nem sempre é true
.
A maneira como realizo essa verificação (dentro de uma função ligada) é comparar a data de postagem e a data de modificação (em GMT para padronização)
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' );
Isso funciona porque, mesmo na criação, a postagem tem uma data 'modificada' anexada a ela, que é exatamente a mesma que a data 'criada', mas permitimos uma variação de 1 segundo de qualquer maneira, caso um segundo passe durante a criação de o post.
post_date_gmt
é 2019-03-12 01:31:30
e o post_modified_gmt
é 2019-03-12 01:31:31
. :(
Acabei verificando a existência de um valor personalizado antes de defini-lo. Dessa forma, se for uma postagem recém-criada, o valor personalizado ainda não existiria.
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');
Exemplo para resposta de ialocina com o parâmetro "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)
ou manter o novo bloco em primeiro lugar, mas usando if( ! $update )
. Este último terá OP em melhor prática e é preferido sobre o seu método pelo WordPress padrões de codificação em casos como o operador ternário
Você pode usar o gancho de ação pre_post_update para o código de atualização e save_post para o novo código postal. Funciona antes de uma postagem ser atualizada.
save_post
gancho é acionado tanto quando um post é criado e atualizado (após WordPress salvou-lo para o banco de dados). pre_post_update
é acionado quando uma postagem é atualizada, mas antes da atualização, isso pode ser importante.
Como Darshan Thanki sugeriu (e Stephen Harris elaborou mais adiante), você pode usar pre_post_update
a seu favor.
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;
}
A razão pela qual eu usei globals é porque function is_new_post() use ( &$new_post )
não é válido em PHP (chocante ...), portanto, puxar essa variável para o escopo da função não funciona - daí o global.
Observe que isso só pode ser usado de maneira confiável dentro / após o save_post
evento (o que geralmente é suficiente, pelo menos para o que estamos fazendo com ele).
Quando save_post é acionado, todas as informações sobre essa postagem já estão disponíveis; portanto, em teoria, você pode 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');
isso não foi testado, no entanto. =)
save_post
postagem, ela já estará salva no banco de dados - get_posts
retornando a postagem atual.
Outra abordagem que usa uma função interna e nenhuma adição ao banco de dados envolveria get_post_status()
.
$post_status = get_post_status();
if ( $post_status != 'draft' ) {
//draft
} else {
//not a draft: can be published, pending, etc.
}
Observe, no entanto, que talvez não seja apropriado se você planeja definir o status novamente como "rascunho" - suas instruções serão repetidas na próxima vez que você atualizar a postagem. Dependendo do contexto, convém considerar as várias cadeias que podem ser retornadas get_post_status()
para criar um cenário mais apropriado.
Veja Codex para obter get_post_status () e Status da postagem
Os valores possíveis são:
- 'publicar' - uma postagem ou página publicada
- 'pendente' - a publicação está com revisão pendente
- 'rascunho' - uma postagem no status de rascunho
- 'rascunho automático' - uma postagem recém-criada, sem conteúdo
- 'futuro' - um post para publicar no futuro
- 'privado' - não visível para usuários que não estão conectados
- 'herdar' - uma revisão. veja get_children.
- 'lixeira' - a postagem está na lixeira. adicionado com a versão 2.9.
save_post()
é executado pela primeira vez, mas durante essa execução get_post_status()
já retorna 'publicar' e não 'rascunho', mesmo que seja apenas no processo de publicação.