¿Cómo establecer una imagen destacada (miniatura) mediante URL de imagen al usar wp_insert_post()?

26 ene 2012, 23:56:46
Vistas: 139K
Votos: 71

Mientras revisaba la entrada de referencia de la función wp_insert_post(), noté que no hay ningún parámetro en el array requerido que permita establecer la 'Imagen Destacada' para una entrada, que se muestra como la miniatura de la entrada en mi tema.

He investigado funciones como set_post_thumbnail(), como sugirió el Sr. Bennett, pero esta parece ser una adición relativamente nueva a WordPress y al codex de WordPress. Como tal, no hay fuentes que pueda encontrar que expliquen cómo se debe obtener y proporcionar el parámetro $thumbnail_id. Si esta es realmente la función que se debe usar, ¿de qué manera podría proporcionarle un parámetro $thumbnail_id válido cuando todo lo que tengo es una URL de imagen?

¡Gracias de antemano!

0
Todas las respuestas a la pregunta 6
13
121

Puedes establecer una imagen como imagen destacada (thumbnail) cuando está en tu biblioteca de medios. Para añadir una imagen a tu biblioteca de medios necesitas subirla a tu servidor. WordPress ya tiene una función para colocar imágenes en tu biblioteca de medios, solo necesitas un script que suba tu archivo.

Uso:

Generate_Featured_Image( '../wp-content/mi_imagen.jpg', $post_id );

// $post_id es un ID numérico... También puedes obtener el ID con:
wp_insert_post()

Función:

function Generate_Featured_Image( $image_url, $post_id  ){
    $upload_dir = wp_upload_dir();
    $image_data = file_get_contents($image_url);
    $filename = basename($image_url);
    if(wp_mkdir_p($upload_dir['path']))
      $file = $upload_dir['path'] . '/' . $filename;
    else
      $file = $upload_dir['basedir'] . '/' . $filename;
    file_put_contents($file, $image_data);

    $wp_filetype = wp_check_filetype($filename, null );
    $attachment = array(
        'post_mime_type' => $wp_filetype['type'],
        'post_title' => sanitize_file_name($filename),
        'post_content' => '',
        'post_status' => 'inherit'
    );
    $attach_id = wp_insert_attachment( $attachment, $file, $post_id );
    require_once(ABSPATH . 'wp-admin/includes/image.php');
    $attach_data = wp_generate_attachment_metadata( $attach_id, $file );
    $res1= wp_update_attachment_metadata( $attach_id, $attach_data );
    $res2= set_post_thumbnail( $post_id, $attach_id );
}

http://codex.wordpress.org/Function_Reference/wp_upload_dir

http://codex.wordpress.org/Function_Reference/wp_insert_attachment


EDITADO: Añadida creación de ruta

http://codex.wordpress.org/Function_Reference/wp_mkdir_p

6 feb 2012 00:07:36
Comentarios

¡Gracias por tus esfuerzos! Esto solo funciona cuando se usa $upload_dir['basedir'] (en lugar de path), porque cuando inspecciono el adjunto a través de la interfaz de edición de la publicación, se referencia como .../uploads/NOMBRE_DEL_ARCHIVO.EXT mientras que $upload_dir['path'] lo almacenaría en algo como .../uploads/2012/02/NOMBRE_DEL_ARCHIVO.EXT.

Podría ser incluso mejor cambiar cómo se referencia el archivo, pero no sabría cómo hacerlo.

Chris Chris
6 feb 2012 20:02:03

Agregué la creación de ruta en mi respuesta.

Rob Vermeer Rob Vermeer
6 feb 2012 20:47:16

Aprecio tu rápida respuesta :). Sin embargo, sigo obteniendo el mismo resultado, aquí hay una captura de pantalla que muestra mi problema: http://i.imgur.com/iKTNs.png. La sección superior es el resultado de colocar un echo en tu condicional, solo para ver qué está pasando.

Chris Chris
6 feb 2012 22:17:22

Lo cambié nuevamente, no pasé la ruta completa a wp_insert_attachment y wp_generate_attachment_metadata. Espero que esto resuelva el problema.

Rob Vermeer Rob Vermeer
6 feb 2012 22:28:38

¡Funciona perfectamente, muchas gracias! Esto también solucionó un problema de tamaño, que aparentemente era causado por rutas incorrectas (aunque la imagen se mostraba). ¡No podría ser mejor!

Chris Chris
6 feb 2012 22:56:26

Gracias por tu excelente código. Solo se necesitó una modificación para que funcionara con mi importación CSV y fue anteponer el postid al nombre del archivo para garantizar que los archivos de imagen permanezcan únicos.

Dave Hilditch Dave Hilditch
7 dic 2012 19:46:25

Permíteme también unirme a los elogios. Me encanta este fragmento de código. ¡Gracias por ahorrarme horas de trabajo!

bkwdesign bkwdesign
11 feb 2013 04:47:47

Solo por curiosidad: ¿Es esto seguro? ¿Existe el riesgo de que alguien disfrace una imagen, o wp_check_filetype() se encarga de eso?

LOLapalooza LOLapalooza
14 feb 2015 06:20:56

Usé el código anterior y lo modifiqué ligeramente para obtener imágenes destacadas que tienen el nombre del slug del post (lo cual consume bastante tiempo si tienes miles de posts): code <?php $slug = basename(get_permalink());
$featuredimageurl = '[TU RUTA]/wp-content/uploads/featuredimages/' . $slug . '.png'; Generate_Featured_Image( $featuredimageurl, $post_id ); ?>

Traveler Traveler
19 ene 2017 10:45:49

el uso de file_get_contents con una URL no funcionará si allow_url_fopen está deshabilitado en php.ini - wp_remote_get tendrá mayor compatibilidad en diferentes entornos de WordPress

highvolt highvolt
24 feb 2017 16:39:44

Advertencia: Esta respuesta sobrescribe el archivo si tiene el mismo nombre, ten cuidado. Debería generar nombres usando $post_id o al menos uniqid()

Ivan Castellanos Ivan Castellanos
1 jun 2017 00:59:37

Cuando uso esto, las imágenes creadas en "uploads" tienen un tamaño de archivo de cero.

Jay Brunet Jay Brunet
23 mar 2018 02:57:04

Para aquellas URLs que contengan espacios, utiliza esto para $image_data: $image_data = file_get_contents(str_replace(' ', '%20', $image_url));

user45288 user45288
8 dic 2020 05:39:50
Mostrar los 8 comentarios restantes
4
23

Me gustaría mejorar la respuesta de Rob utilizando las funciones principales de WP download_url y media_handle_sideload

<?php
/**
* Descarga una imagen desde la URL especificada y la adjunta a una publicación como imagen destacada.
*
* @param string $file    La URL de la imagen a descargar.
* @param int    $post_id El ID de la publicación a la que se asociará la imagen destacada.
* @param string $desc    Opcional. Descripción de la imagen.
* @return string|WP_Error ID del adjunto, objeto WP_Error en caso de error.
*/
function Generate_Featured_Image( $file, $post_id, $desc ){
    // Establece variables para almacenamiento, corrige el nombre del archivo para cadenas de consulta.
    preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches );
    if ( ! $matches ) {
         return new WP_Error( 'image_sideload_failed', __( 'URL de imagen inválida' ) );
    }

    $file_array = array();
    $file_array['name'] = basename( $matches[0] );

    // Descarga el archivo a una ubicación temporal.
    $file_array['tmp_name'] = download_url( $file );

    // Si hay un error al almacenar temporalmente, devuelve el error.
    if ( is_wp_error( $file_array['tmp_name'] ) ) {
        return $file_array['tmp_name'];
    }

    // Realiza la validación y el almacenamiento.
    $id = media_handle_sideload( $file_array, $post_id, $desc );

    // Si hay un error al almacenar permanentemente, elimina el archivo temporal.
    if ( is_wp_error( $id ) ) {
        @unlink( $file_array['tmp_name'] );
        return $id;
    }
    return set_post_thumbnail( $post_id, $id );

}
2 mar 2016 09:23:22
Comentarios

Usar las funciones nativas de WordPress es la mejor práctica, gracias.

Mostafa Soufi Mostafa Soufi
15 sept 2018 18:39:56

Por alguna razón, esta versión me dio errores diciendo "No se proporcionó una URL válida", mientras que la respuesta de Rob Vermeer funcionó.

Flimm Flimm
28 ago 2019 20:09:19

Puedo confirmar que el código modificado no funciona, lo cual es una pena porque la carga lateral de URL sería increíble.

Zach Nicodemous Zach Nicodemous
10 nov 2020 01:16:01

Este código funciona perfectamente para mí, a pesar de que tuve problemas con la respuesta original.

Jsilvermist Jsilvermist
19 nov 2020 00:47:39
5
10

Prueba usando set_post_thumbnail().

Edición por Otto: Has aclarado tu pregunta, así que aclararé la respuesta que dio Chip.

Básicamente, necesitas crear el 'attachment' para la publicación también. Cuando una imagen se sube a la biblioteca de medios de WordPress, se crea una entrada especial de publicación para ella con un tipo de publicación de attachment. Este attachment está vinculado a una publicación específica a través del identificador post_parent.

Entonces, si conoces el ID del attachment, llamar a set_post_thumbnail con el objeto o ID de la publicación y el ID del attachment simplemente establecerá la bandera de miniatura de la publicación.

Si aún no has creado el attachment, entonces necesitarás hacerlo primero. La forma más fácil de hacerlo es con wp_insert_attachment(). Esta función toma un array de algunos parámetros, el nombre del archivo (el archivo ya debe estar en el directorio correcto de subidas), y el ID de la publicación padre a la que quieres adjuntar el attachment.

Simplemente tener un archivo subido y adjunto a una publicación no hace nada automáticamente. Esto es simplemente un mecanismo de categorización. El mecanismo de galería, por ejemplo, usa las imágenes adjuntas de una publicación para construir la [galería] de esa publicación. Una miniatura para una publicación es solo una de las imágenes adjuntas que se ha configurado como miniatura.

Puedes encontrar más información sobre cómo usar wp_insert_attachment en el codex (enlace arriba).

27 ene 2012 00:08:09
Comentarios

¡Gracias por tu respuesta! ¿Pero cómo obtendría el ID de la miniatura? Estoy comenzando con una URL de imagen, así que supongo que debería agregar una imagen a la biblioteca de WordPress usando otra función, ¿no?

Chris Chris
27 ene 2012 19:44:57

Como ya estás insertando una publicación, había asumido que ya estabas adjuntando imágenes a la publicación que estás insertando. ¿No es una suposición válida?

Chip Bennett Chip Bennett
27 ene 2012 20:15:28

Lo siento, pero aún no he descubierto cómo adjuntar imágenes a una publicación mediante una URL. Además, no quiero que la imagen se muestre realmente en la publicación en sí. Actualmente estoy buscando la función que devolverá el $thumbnail_id, y pensé que tal vez wp_insert_attachment() funcionaría, hasta que noté que ya requería que el adjunto estuviera en el directorio de subida. No sé cómo obtener un archivo de imagen allí por su URL, y no estoy seguro de si esta es la función que estoy buscando en primer lugar. ¡Gracias por tu ayuda!

Chris Chris
27 ene 2012 22:59:37

¿Podrías reescribir tu pregunta con esta información, para describir mejor lo que estás tratando de lograr? (O deja esta tal como está y crea una nueva pregunta para preguntar cómo obtener el ID del adjunto al insertar una publicación).

Chip Bennett Chip Bennett
27 ene 2012 23:03:35

La pregunta original ha sido editada y parcialmente reformulada, por favor revísala :).

Chris Chris
27 ene 2012 23:38:45
0

Acabo de encontrar esto y lo he simplificado mucho, funciona pero no soy un experto en seguridad

if(!empty($_FILES)){
    require_once( ABSPATH . 'wp-admin/includes/post.php' );
    require_once( ABSPATH . 'wp-admin/includes/image.php' );
    require_once( ABSPATH . 'wp-admin/includes/file.php' );
    require_once( ABSPATH . 'wp-admin/includes/media.php' );

    $post_ID = "tu id de post!";  // Reemplaza con el ID de tu post

    $attachment_id = media_handle_upload( 'file', $post_ID );
    set_post_thumbnail( $post_ID, $attachment_id );
}

¿Simple o no? Después de incluir los archivos necesarios, WordPress se encargará del media y lo subirá, luego lo establecerá como imagen destacada.

21 feb 2015 01:45:56
0

set_post_thumbnail() es la mejor función para este requisito.

Creo que puedes encontrar el ID de un adjunto mediante get_children() o get_posts(). El resultado es un array y dentro de este array está el ID. El siguiente ejemplo es para pruebas; espero que funcione; lo escribí sin probarlo, solo como borrador.

Para tu requisito es importante que reemplaces get_the_ID() con tu post-ID; esto devuelve el ID del Adjunto y puedes usarlo para set_post_thumbnail().

$attachments = get_children( 
    array(
        'post_parent' => get_the_ID(), 
        'post_type' => 'attachment', 
        'post_mime_type' => 'image'
    )
);
foreach ( $attachments as $attachment_id => $attachment ) {
    echo wp_get_attachment_image($attachment_id);
}
6 feb 2012 17:14:25
0

Necesitas cargar algunas bibliotecas principales para mantenerlo simple.

function attach_image_from_url_to_post($image_url, $post_id) {
    // Verifica si la función existe (es parte de media.php)
    if (!function_exists('media_sideload_image')) {
        require_once(ABSPATH . 'wp-admin/includes/image.php');
        require_once(ABSPATH . 'wp-admin/includes/file.php');
        require_once(ABSPATH . 'wp-admin/includes/media.php');
    }

    // Descarga y carga lateralmente la imagen
    $image = media_sideload_image($image_url, $post_id, null, 'id');

    // Si hay un error, devuélvelo
    if (is_wp_error($image)) {
        return $image;
    }

    // Establece la imagen como imagen destacada (thumbnail del post)
    set_post_thumbnail($post_id, $image);

    return true;
}
15 mar 2025 23:00:39