Cómo actualizar campos personalizados usando la función wp_insert_post()
La función de WordPress se utiliza para enviar datos programáticamente. Los campos estándar para enviar incluyen el contenido, extracto, título, fecha y muchos más.
Lo que no está documentado es cómo enviar a un campo personalizado. Sé que es posible con la función add_post_meta($post_id, $meta_key, $meta_value, $unique);
.
Pero, ¿cómo incluir eso en la función estándar wp_insert_post
?
<?php
$my_post = array(
'post_title' => $_SESSION['booking-form-title'],
'post_date' => $_SESSION['cal_startdate'],
'post_content' => 'This is my post.',
'post_status' => 'publish',
'post_type' => 'booking',
);
wp_insert_post( $my_post );
?>

Si lees la documentación de wp_insert_post
, verás que devuelve el ID del post que acabas de crear.
Si combinas eso con la siguiente función __update_post_meta
(una función personalizada que obtuve de este sitio y adapté un poco)
/**
* Actualiza los meta datos de un post. También elimina o añade automáticamente el valor al campo especificado si es necesario
*
* @access protected
* @param integer El ID del post que estamos actualizando
* @param string El campo que estamos actualizando/añadiendo/eliminando
* @param string [Opcional] El valor para actualizar/añadir al campo. Si se deja vacío, se eliminarán los datos.
* @return void
*/
public function __update_post_meta( $post_id, $field_name, $value = '' )
{
if ( empty( $value ) OR ! $value )
{
delete_post_meta( $post_id, $field_name );
}
elseif ( ! get_post_meta( $post_id, $field_name ) )
{
add_post_meta( $post_id, $field_name, $value );
}
else
{
update_post_meta( $post_id, $field_name, $value );
}
}
Obtendrás lo siguiente:
$my_post = array(
'post_title' => $_SESSION['booking-form-title'],
'post_date' => $_SESSION['cal_startdate'],
'post_content' => 'Este es mi post.',
'post_status' => 'publish',
'post_type' => 'booking',
);
$the_post_id = wp_insert_post( $my_post );
__update_post_meta( $the_post_id, 'my-custom-field', 'my_custom_field_value' );

Muchas gracias. ¿Podrías darme una idea sobre la implementación? Es decir, qué parte del código va dónde. Muchas gracias.

Bien hecho. El segundo bloque de código reemplaza al tuyo, los valores de la función son el par clave/valor del campo personalizado. Coloca la función ya sea al comienzo del script, o en un archivo .php separado que se incluya al inicio del script.

Como nota, yo sí uso POO (Programación Orientada a Objetos) por eso está el modificador public
delante de "function". Si estás incluyendo la función directamente sin ponerla dentro de una clase, no necesitas agregar public

Hola Zack, Aendrew y Philip. Todo está funcionando perfectamente, pero intenté aplicarlo también a una consulta sin éxito. No logro entender por qué. Aquí está el enlace ya que ustedes conocen cómo funcionaba inicialmente el nuevo post con campos personalizados, pensé que podrían ver mi error. http://wordpress.stackexchange.com/questions/8622/wp-insert-post-php-function-dynamically-generated-custom-fields

@Zack - Buena respuesta. Pero tendería a evitar usar guiones bajos al inicio en los nombres de funciones, solo porque los nombres con guiones bajos iniciales suelen ser usados por los desarrolladores de plataformas cuando quieren crear funciones "reservadas" o (pseudo) "ocultas", por lo que quienes las vean podrían pensar que son funciones de la plataforma, o peor aún, podrían entrar en conflicto con una futura función del núcleo de WordPress. Solo un pensamiento.

@MikeSchinkel: Al principio, originalmente comencé usando "__" para funciones protegidas dentro de una clase, pero luego cambié la estructura de mi plugin a un punto donde la función necesitaba ser pública. También la hubiera nombrado simplemente "update_post_meta" pero eso definitivamente habría entrado en conflicto con las funciones principales de WordPress. Así que no supe cómo nombrarla :(

@Zack - ¿Quizás zacks_update_post_meta()
? :) El otro problema que no mencioné con los guiones bajos iniciales es que alguien igualmente creativo podría usar la misma convención en un plugin y así entrar en conflicto con el tuyo. Por cierto, ¿sabías que update_post_meta()
añade si no existe? add_post_meta()
solo es necesario cuando quieres añadir claves duplicadas.

@MikeSchinkel: Originalmente encontré la función en otro lugar de este sitio, me gustó y la refactoricé solo porque soy así. También supuse que update_post_meta()
ya hacía eso, pero no estaba seguro. Cuando encontré la función, salté a conclusiones.

@Zack - Aprender WordPress es un viaje. Calculo que todavía me queda al menos un 50% más de ese viaje, ¡si no es mucho más!

Puedes simplemente agregar el 'add_post_meta' después del 'wp_insert_post'
<?php
$my_post = array(
'post_title' => $_SESSION['booking-form-title'],
'post_date' => $_SESSION['cal_startdate'],
'post_content' => 'Este es mi post.',
'post_status' => 'publish',
'post_type' => 'booking',
);
$post_id = wp_insert_post($my_post);
add_post_meta($post_id, 'META-KEY-1', 'META_VALUE-1', true);
add_post_meta($post_id, 'META-KEY-2', 'META_VALUE-2', true);
?>

Puedes agregar el elemento 'meta_input' en los parámetros del post como un arreglo de valores meta del post indexados por su clave meta
<?php
$my_post = array(
'post_title' => $_SESSION['booking-form-title'],
'post_date' => $_SESSION['cal_startdate'],
'post_content' => 'Este es mi post.',
'post_status' => 'publish',
'post_type' => 'booking',
'meta_input' => array(
'your_custom_meta_field_name' => $_SESSION['your_custom_meta_field_value']
)
);
wp_insert_post( $my_post );
?>

No es útil. $post->ID no está disponible para wp_insert_post_data, lo cual es necesario para crear campos personalizados.

@aendrew La acción save_post
está al final de la función, tiene el ID del post y el objeto pasado a ella, la respuesta es válida.

Estoy bastante seguro de que esto fue editado, Rarst. De todos modos, ahora tiene sentido.

No creo que puedas usarlo con wp_insert_post();.
La razón es debido a cómo WordPress almacena los dos tipos de datos. Las entradas se almacenan en una gran tabla monolítica con una docena de columnas diferentes (wp_posts); los campos personalizados se almacenan en una tabla más simple de 4 columnas (wp_postmeta) compuesta principalmente por una clave meta y un valor, asociados a una entrada.
En consecuencia, no puedes realmente almacenar campos personalizados hasta que no tengas el ID de la entrada.
Prueba esto:
function myplugin_insert_customs($pid){
$customs = array(
'post_id' => $pid,
'meta_key' => 'Tu clave meta',
'meta_value' => 'Tu valor meta',
);
add_post_meta($customs);
}
add_action('save_post', 'myplugin_insert_customs', 99);
Esta entrada del codex ayudó -- es un poco lo opuesto a lo que estás haciendo (es decir, eliminar una fila de la base de datos al borrar una entrada): http://codex.wordpress.org/Plugin_API/Action_Reference/delete_post

En ese caso, la única solución que veo es usar una sesión, ¿sería correcto?

No; supongo que tu plugin está intentando insertar campos personalizados al mismo tiempo que se guarda una publicación, ¿verdad? Creo que lo que necesitas hacer es engancharte a WP después de que se guarde la publicación, obtener el nuevo número de ID de la publicación y luego proporcionarlo a add_post_meta(); para crear los CFs. Actualizaré mi respuesta en un segundo con algo de código.

Gracias por la ayuda. Por cierto, no es un plugin. Lo escribí para que podamos personalizarlo tanto como sea necesario. (pero no tomes eso como que soy bueno con php, solo prueba y error)
