Evitar posts duplicados en wp_insert_post usando campos personalizados
Mis enlaces de origen son algo como esto:
http://sample.com/entertainment/default.aspx?tabid=2305&conid=102950
http://sample.com/entertainment/default.aspx?tabid=2418&conid=104330
http://sample.com/entertainment/default.aspx?tabid=2429&conid=104264
http://sample.com/entertainment/default.aspx?tabid=2305&conid=102949
.
.
.
Almaceno en caché el contenido de los enlaces. Uso wp_insert_post para publicar el contenido almacenado desde el sitio fuente a WordPress:
$my_post = array(
'post_title' => "$title",
'post_content' => "$content",
'post_status' => 'draft',
'post_author' => 1,
'post_category' => array(1),
);
wp_insert_post( $my_post );
Quiero guardar cada enlace en campos personalizados y en la próxima carga, antes de publicar en WP, verificar los nuevos enlaces con los enlaces en los campos personalizados. Si el enlace está repetido, evitar insertar el contenido.
Disculpen mi mala explicación.
Ese es un problema bastante extraño al que todos se enfrentarán, especialmente si llaman a esta función dentro de algún bucle como <foreach>
, <for>
o <while>
, etc.
Deberías probar esto:
if (!get_page_by_title($title, 'OBJECT', 'post') ){
$my_post = array('post_title' => $title,
'post_content' => 'Contenido',
'tags_input' => $tags,
'post_category' => array(2),
'post_status' => 'publish'
);
$result = wp_insert_post( $my_post );
}
Observa la función get_page_by_title
que determina si ya existe un post con el mismo título o no. Si existe, no llama a wp_insert_post
.
Espero que esto ayude a alguien que esté lidiando con el mismo problema.

Para guardar el enlace en el meta del post puedes usar update_post_meta
como por ejemplo:
$url = "http://sample.com/entertainment/default.aspx?tabid=2305&conid=102950"
$my_post = array(
'post_title' => "$title",
'post_content' => "$content",
'post_status' => 'draft',
'post_author' => 1,
'post_category' => array(1),
);
$post_id = wp_insert_post( $my_post );
update_post_meta($post_id,'source_link',$url);
y para prevenir la inserción añade una simple verificación condicional:
$args = array("meta_key" => "source_link", "meta_value" =>$url);
$posts = get_posts($args);
if (count($posts) < 0){
//añadir nuevo post
}
if (count($posts) < 0){
//añadir nuevo post
}
no está funcionando, cámbialo por
if (empty($posts)){
//añadir nuevo post
}

Quizás si usas algo como una consulta wpdb incluyendo wp_posts y wp_postmeta buscando este meta antes de insertar el post...
$string = 'the_url.html';
$output = $wpdb->get_var($wpdb->prepare("SELECT count(id)
FROM $wpdb->posts wpo, $wpdb->postmeta wpm
WHERE wpo.ID = wpm.post_id
AND wpm.meta_key = 'name_of_ur_meta'
AND wpm.meta_value = '$string'"));
if(empty($output)) {
/* Inserta tu post */
} else {
/* Actualiza el post o haz otra cosa */
};

Si el problema, como se menciona en una respuesta anterior, es que la función se está ejecutando dentro de algún tipo de bucle, entonces la forma clásica -y menos intensiva en recursos- de resolverlo es introducir una bandera.
$ran_already_flag = false;
{comienza el bucle}
if ( ! $ran_already_flag ) {
$my_post = array('post_title' => $title,
'post_content' => 'Contenido',
'tags_input' => $tags,
'post_category' => array(2),
'post_status' => 'publicar'
);
$result = wp_insert_post( $my_post );
$ran_already_flag = true;
}
{termina el bucle}
Si el problema no es que la función se ejecutó dentro de un bucle, entonces me interesaría saber qué lo causó: Podría ser que la función está vinculada a un hook que se ejecuta dos veces durante el script: Tal vez "update_post" se ejecuta dos veces, por ejemplo. En ese caso, podrías recurrir a una de las otras opciones ofrecidas en las demás respuestas, aunque realmente equivalen a crear banderas por otros medios (el título designado del post es una bandera), y el tipo más simple de variable bandera podría pasarse si es necesario.
