Agregar imágenes programáticamente a la biblioteca de medios

17 feb 2017, 13:56:45
Vistas: 64.9K
Votos: 33

Estoy intentando agregar múltiples imágenes programáticamente a la biblioteca de medios. Ya subí las imágenes a wp-content/uploads, y ahora estoy tratando de usar wp_insert_attachement.

Aquí está el código, sin embargo no está funcionando como se espera. Creo que los metadatos no se están generando correctamente. Puedo ver los archivos en la biblioteca de medios, pero sin miniatura, y además cuando edito la imagen obtengo un error que me pide volver a subir la imagen.

$filename_array = array(
   'article1.jpg',
   'article2.jpg',
);

// El ID de la entrada a la que pertenece este adjunto.
$parent_post_id = 0;

// Obtener la ruta al directorio de subidas.
$wp_upload_dir = wp_upload_dir();

foreach ($filename_array as $filename) {

    // Verificar el tipo de archivo. Lo usaremos como 'post_mime_type'.
    $filetype = wp_check_filetype( basename( $filename ), null );

    // Preparar un array de datos para el adjunto.
    $attachment = array(
        'guid'           => $wp_upload_dir['url'] . '/' . basename( $filename ), 
        'post_mime_type' => $filetype['type'],
        'post_title'     => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
        'post_content'   => '',
        'post_status'    => 'inherit'
    );

    // Insertar el adjunto.
    $attach_id = wp_insert_attachment( $attachment, $filename, $parent_post_id );

    // Asegurarse de que este archivo está incluido, ya que wp_generate_attachment_metadata() depende de él.
    require_once( ABSPATH . 'wp-admin/includes/image.php' );

    // Generar los metadatos para el adjunto y actualizar el registro en la base de datos.
    $attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
    wp_update_attachment_metadata( $attach_id, $attach_data );

}
0
Todas las respuestas a la pregunta 4
8
39
$image_url = 'dirección de la imagen'; // URL de la imagen a subir

$upload_dir = wp_upload_dir(); // Obtiene el directorio de subida de WordPress

$image_data = file_get_contents( $image_url ); // Obtiene los datos binarios de la imagen

$filename = basename( $image_url ); // Extrae el nombre del archivo de la URL

// Crea el directorio si no existe y define la ruta del archivo
if ( wp_mkdir_p( $upload_dir['path'] ) ) {
  $file = $upload_dir['path'] . '/' . $filename;
}
else {
  $file = $upload_dir['basedir'] . '/' . $filename;
}

// Guarda la imagen en el servidor
file_put_contents( $file, $image_data );

// Verifica el tipo de archivo
$wp_filetype = wp_check_filetype( $filename, null );

// Prepara los datos del attachment
$attachment = array(
  'post_mime_type' => $wp_filetype['type'], // Tipo MIME
  'post_title' => sanitize_file_name( $filename ), // Título sanitizado
  'post_content' => '', // Contenido vacío
  'post_status' => 'inherit' // Establece el estado
);

// Inserta el attachment en la base de datos
$attach_id = wp_insert_attachment( $attachment, $file );
// Incluye las funciones necesarias para procesar imágenes
require_once( ABSPATH . 'wp-admin/includes/image.php' );
// Genera los metadatos del attachment (tamaños, etc.)
$attach_data = wp_generate_attachment_metadata( $attach_id, $file );
// Actualiza los metadatos en la base de datos
wp_update_attachment_metadata( $attach_id, $attach_data );
17 feb 2017 14:27:16
Comentarios

¿de dónde viene $attach_id?

user1889580 user1889580
27 sept 2017 17:23:34

faltaba... lo he añadido

Omtara Omtara
30 oct 2017 18:30:56

Archivo descargado pero no hay miniatura disponible, la URL del adjunto también devuelve error 404

Umair Hamid Umair Hamid
22 may 2018 22:51:46

@UmairHamid Lo mismo aquí. Esto se debe a que el segundo argumento de wp_insert_attachment debería ser la ruta del archivo (por lo que $file en este ejemplo), no el nombre del archivo. Edité la respuesta, esperando aprobación.

philippe_b philippe_b
23 oct 2018 00:24:09

¿y cómo puedo obtener la nueva URL?

zEn feeLo zEn feeLo
3 may 2019 21:19:02

no funciona, ¿alguien tiene la respuesta?

zEn feeLo zEn feeLo
8 may 2019 10:55:31

Usa wp_get_attachment_image_src para obtener la URL, ej. wp_get_attachment_image_src($attach_id) - https://developer.wordpress.org/reference/functions/wp_get_attachment_image_src

Ian Jamieson Ian Jamieson
3 jul 2019 23:28:03

¿cómo puedo subir una imagen como archivo desde mi computadora y no como URL?

AndiM AndiM
5 sept 2019 08:45:38
Mostrar los 3 comentarios restantes
2
15

Si utilizas la función de carga lateral (sideload) de WordPress, puedes hacer esto más fácilmente (y dejar que WordPress maneje toda la sanitización por ti).

<?php
// ejemplo:
//   $file = 'http://www.example.com/image.png';
//   $description = 'alguna descripción';

function my_upload_image( $file, $description ) {
   $file_array  = [ 'name' => wp_basename( $file ), 'tmp_name' => download_url( $file ) ];

   // Si hay 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 almacenamiento.
   $id = media_handle_sideload( $file_array, 0, $description );

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

   return true;
}
19 jul 2020 06:46:56
Comentarios

Ten en cuenta que esto solo funciona desde dentro de /wp-admin/. Fuera de ahí, debes asegurarte de hacer require_once de estos tres archivos: ABSPATH . 'wp-admin/includes/file.php', ABSPATH . 'wp-admin/includes/media.php', ABSPATH . 'wp-admin/includes/image.php'

KittMedia KittMedia
7 sept 2021 12:58:13

Esto también funciona para imágenes ya almacenadas en el servidor, simplemente usa la ruta de la imagen en lugar de download_url( $file ). Pero si haces esto, ten en cuenta que al usar media_handle_sideload, la imagen se eliminará automáticamente después del procesamiento. Si no quieres que esto ocurra, simplemente copia la imagen al directorio tmp mediante $tmp_path = get_temp_dir() . basename( $file ); copy( $file, $tmp_path );, luego puedes usar 'tmp_name' => $tmp_path en su lugar.

Smithee Smithee
19 ene 2023 13:19:20
0

Tuve problemas con la solución de @TrubinE donde los archivos de imagen no se cargaban correctamente.

Aquí hay un ejemplo completo que funcionó para mí: https://gist.github.com/m1r0/f22d5237ee93bcccb0d9

Esta es una idea similar pero utiliza la biblioteca HTTP de WordPress para obtener el contenido en lugar de file_get_contents(). Aquí está el contenido de la solución del gist de github de m1r0:

    if ( ! class_exists( 'WP_Http' ) ) {
        include_once( ABSPATH . WPINC . '/class-http.php' );
    }

    $http = new WP_Http();
    $response = $http->request( $meta['image_url'] );
    if ( $response['response']['code'] !== 200 ) {
        return false;
    }

    $upload = wp_upload_bits( basename( $meta['image_url'] ), null, $response['body'] );
    if ( !empty( $upload['error'] ) ) {
        return false;
    }
    $file_path = $upload['file'];
    $file_name = basename( $file_path );
    $file_type = wp_check_filetype( $file_name, null );
    $attachment_title = sanitize_file_name( pathinfo( $file_name, PATHINFO_FILENAME ) );
    $wp_upload_dir = wp_upload_dir();
    
    $post_info = array(
        'guid'           => $wp_upload_dir['url'] . '/' . $file_name,
        'post_mime_type' => $file_type['type'],
        'post_title'     => $attachment_title,
        'post_content'   => '',
        'post_status'    => 'inherit',
    );
    
    $attach_id = wp_insert_attachment( $post_info, $file_path, $parent_post_id );
    require_once( ABSPATH . 'wp-admin/includes/image.php' );
    $attach_data = wp_generate_attachment_metadata( $attach_id, $file_path );
    wp_update_attachment_metadata( $attach_id,  $attach_data );
    return $attach_id; código aquí
4 dic 2018 18:57:47
2
<?php  
// método más simple para subir una imagen  
$url_image = "http://example.com/any_image.jpg" ;  
$new_image_id = upload_image_by_url ( $url_image );  

function upload_image_by_url ($url) {
    $title = basename($url) ; 
    $image_for_post_id = 0 ; // 0 significa que la imagen no está asociada a un post 
    $imgid = media_sideload_image( $url, $image_for_post_id, $title, 'id' );  
    if ( is_wp_error($imgid) ) {  
        echo "<br>Error en upload_image_by_url($url): ";
        echo $imgid->get_error_message();
        return false;  
    }  
    else {  
        echo "<br>upload_image_by_url($url) = $imgid";
        return $imgid;
    }
}?>
12 feb 2024 07:57:07
Comentarios

Tal como está escrito actualmente, tu respuesta no es clara. Por favor, [edita] para agregar detalles adicionales que ayuden a otros a entender cómo esto responde a la pregunta planteada. Puedes encontrar más información sobre cómo escribir buenas respuestas en el centro de ayuda.

User User
14 feb 2024 00:34:40

Parece que es el mismo enfoque básico que las respuestas de Paul. ¿Aplican aquí también los comentarios allí mencionados, por ejemplo, sobre eliminar las subidas fallidas?

Rup Rup
16 feb 2024 02:21:02