La acción save_post no se ejecuta en el tipo de entrada personalizada
Disculpa si esto ya ha sido respondido aquí. Busqué pero no pude encontrar respuestas a mi pregunta, así que decidí publicar la mía.
Estoy desarrollando un plugin para un cliente que recopila comentarios de los clientes sobre un proyecto que se ha completado recientemente.
El administrador usaría el sistema para enviar un "recordatorio" al cliente solicitando sus comentarios con un enlace a un formulario en el sitio.
He creado un tipo de entrada personalizada llamado "customer_prompts" que solo tiene un campo de título y algunos campos personalizados que se almacenan en una tabla personalizada de la base de datos, no en post meta.
A continuación está mi código para la acción save_post. Parece que cuando presiono publicar, no ejecuta la acción save_post y solo guarda el valor del título en wp_posts.
add_action('save_post', 'save_prompt');
function save_prompt($post_id){
$post = get_post($post_id);
// Si es un autoguardado, salir
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
// Verificar permisos
if ( 'customer_prompt' == $_POST['post_type'] )
{
if ( !current_user_can( 'edit_page', $post_id ) )
return;
}
else
{
if ( !current_user_can( 'edit_post', $post_id ) )
return;
}
global $wpdb;
$prompt_id = com_create_guid();
$customer_feedback_name = $_POST['_sdg_customer_feedback_name'];
$customer_feedback_email = $_POST['_sdg_customer_feedback_email'];
$salesperson = $_POST['_sdg_salesperson'];
$values = array(
'id' => $prompt_id,
'sdg_customer_name' => $customer_feedback_name,
'sdg_customer_email' => $customer_feedback_email,
'sdg_salesperson' => $salesperson,
'sdg_post_id' => $post->id
);
$insert = $wpdb->insert($table_name, $values);
if($insert) {
mail($customer_feedback_email, 'hello', 'hello');
}
}
Cualquier ayuda sería muy apreciada ya que no puedo descifrar qué está pasando aquí.
Gracias, Jamie.

La acción "save_post" solo se llama cuando realmente cambiamos algo en el formulario de la página del post. Si simplemente presionamos el botón de actualizar sin hacer ningún cambio, la acción "save_post" no se llama.
Esto es importante si estamos editando un tipo de contenido personalizado (custom post type) que tiene meta boxes personalizados. Si dependemos de la acción "save_post" y solo cambiamos cosas en nuestros meta boxes personalizados, no pasará nada.
La solución es usar el hook de acción "pre_post_update" en lugar de "save_post"
http://wordpress.org/support/topic/save_post-not-working-getting-called#post-2335557

editar ¿Has intentado colocar print_r('hello world'); die();
después de function save_prompt($post_id){
para asegurarte de que la función realmente es capturada por el hook de acción? /editar
Pueden estar ocurriendo varios problemas:
1: Tu global wpdb
debe estar al principio de tu función, antes de todas tus sentencias condicionales if.
2: Tus variables $_POST
deberían tener condicionales como if(isset($_POST['food']))
para verificar si los datos que se envían realmente están establecidos antes de llegar a tu función, de lo contrario podría causar un error fatal e impedir que los datos se inserten en la BD.
3: Prueba con global $post
al principio de la función, luego puedes acceder a las variables del post como $post->post_type
como un objeto a través de la variable $post
.
4: Agrega $wpdb->print_errors; die();
después de $insert = $wpdb->insert($table_name, $values);
en caso de que tu consulta a la BD sea incorrecta.
Con suerte, alguna de estas sugerencias resolverá tu problema.

Tomar una variable global dentro del alcance de la función debe ocurrir antes de que se use, pero no necesariamente en la parte superior de una función.

Sin embargo, para seguir las mejores prácticas, me he encontrado con varios casos en los que las variables globales fallaron por no estar en la parte superior de una función.

Intenté mostrar algo con echo en la parte superior de la función, lo cual apareció en la parte superior de la página después de hacer clic en "Añadir nuevo" en la barra lateral, pero una vez que haces clic en publicar, esto desaparece como si la función no se estuviera ejecutando cuando se hace clic en publicar.
Probé todas tus otras sugerencias y todavía no tuve éxito. Creo que puede ser un caso de que la función no se esté ejecutando en absoluto, pero no puedo entender por qué.

Primero, te sugiero configurar tu sitio WordPress para que sea fácil de depurar http://codex.wordpress.org/Debugging_in_WordPress
De esa manera, es fácil ver las cosas ;)
Para el hook de acción, creo que necesitas engancharlo así:
add_action('save_post', 'save_prompt', 10, 2);
function save_prompt( $post_id, $post ){
//haz lo que sea
}
El hook save_post
pasa 2 argumentos.

Esto me sucedió. Resultó que tenía una plantilla de página configurada (un valor post-meta para _wp_page_template
) apuntando a una plantilla que ya no existía, después de haber cambiado de tema. Este fragmento de código en wp-includes/post.php
:
if ( ! empty( $postarr['page_template'] ) ) {
$post->page_template = $postarr['page_template'];
$page_templates = wp_get_theme()->get_page_templates( $post );
if ( 'default' != $postarr['page_template'] && ! isset( $page_templates[ $postarr['page_template'] ] ) ) {
if ( $wp_error ) {
return new WP_Error( 'invalid_page_template', __( 'Plantilla de página inválida.' ) );
}
...
aborta antes de ejecutar save_post
.

Yo tuve este mismo problema y pensé en añadir a las posibles respuestas, para ayudar a ahorrar tiempo a alguien. Era un problema muy simple que me tomó días identificar (ahora estoy un poco más calvo - y me siento un poco tonto)...
Resultó que un formulario de metabox que se estaba generando contenía un campo "action" que estaba sobrescribiendo el campo "action" del formulario generado por WordPress. El formulario solo se usaba en un post personalizado y, por lo tanto, se pasaba la acción incorrecta a WordPress al hacer POST a 'wp-admin/post.php', lo que hacía que fuera manejado por el controlador predeterminado (al final de la sentencia switch).
Otro efecto secundario fue que, al actualizar o publicar, WordPress redirigía al índice de posts integrado, en lugar de volver directamente al post editado.
La solución fue eliminar el elemento oculto 'action' del formulario del metabox.
Espero que esto le ayude a alguien por ahí...
