Añadir imagen a la biblioteca multimedia desde URL en directorio de subidas

6 sept 2012, 04:05:09
Vistas: 16.8K
Votos: 2

El plugin "Video Embed & Thumbnail Generator" hace un excelente trabajo generando miniaturas a partir de videos. Guarda la URL de la miniatura como metadato para el adjunto. La miniatura se añade al directorio de subidas. ¿Hay alguna forma de tomar esta imagen y añadirla a la biblioteca multimedia para poder pasar la imagen por la función image_downsize y crear una miniatura de un tamaño diferente?

wp_insert_attachment parece que necesita una ruta a un archivo y no una URL, ¿o estoy equivocado? ¿Cómo puedo añadir una URL a la biblioteca multimedia?

Esto posiblemente sea un duplicado de ¿Cómo puedo obtener una imagen del directorio de subidas y agregarla a la biblioteca multimedia? pero esa pregunta nunca obtuvo respuestas.

0
Todas las respuestas a la pregunta 2
6

Si la imagen está en el contenido fuente puedes extraerla y usar media_sideload_image(); para importarla a la biblioteca de medios.

Este código de ejemplo es de mi plugin Media Tools. Que realiza esta acción a través de una página de administración vía AJAX. También establece la imagen extraída como imagen destacada para la entrada. El ID de la entrada se pasa a esta función mediante AJAX. Para ver el código completo consulta: http://plugins.trac.wordpress.org/browser/media-tools/trunk/media-tools.php?rev=581988

   function process_image( $post_id ) {
        $response = '';
        $error = 0;
        $post = get_post( $post_id );
        $img = $this->extract_image( $post );
        if( empty( $img ) ) {
            $response .=  'No se encontraron imágenes <br>';
            die( sprintf( $response . '<br>Herramienta de medios completada (ID de entrada %1$s) en %2$s segundos. %3$d errores', esc_html( $post->ID ), timer_stop(), $error = $error  > 0 ? $error : 'ninguno' ) );
         }
        /** @var $file string o WP_Error de la imagen adjunta a la entrada  */
        $file = media_sideload_image( $img, (int)$post->ID );
        if ( is_wp_error( $file ) ) {
            $response .= '<span style="color:red">Error de carga: No se pudo subir la imagen. Verifica si hay URL src malformada en la imagen</span><br>';
            $error++;
        } else {

         $atts = $this->get_attach( $post->ID );
         foreach ( $atts as $a ) {
             $img = set_post_thumbnail( $post->ID, $a['ID'] );
             if ( $img ) {
                  $thumb = wp_get_attachment_thumb_url( $a['ID'] );
                  $response .= '<img src="'.esc_url( $thumb ).'" /><br>';
                  $response .= '<a href="'.wp_nonce_url( get_edit_post_link( $a['ID'], true ) ).'" >'.get_the_title( $a['ID'] ).'</a>  Establecida como Imagen Destacada</p><br>';
                        }
                    }
                    unset( $atts );
                    unset( $a );
                }
            die( sprintf( $response.'<br>Herramienta de medios completada (ID de entrada %1$s) en %2$s segundos. %3$d errores', esc_html( $post->ID ), timer_stop(), $error = $error > 0 ? $error : 'ninguno' ) );
    }


    /**
     * Extrae la primera imagen en el contenido de la entrada
     * @param object $post el objeto de la entrada
     * @return bool|string false si no hay imágenes o src de la imagen
     */
    function extract_image( $post ) {
        $html = $post->post_content;
        if ( stripos( $html, '<img' ) !== false ) {
            $regex = '#<\s*img [^\>]*src\s*=\s*(["\'])(.*?)\1#im';
            preg_match( $regex, $html, $matches );
            unset( $regex );
            unset( $html );
            if ( is_array( $matches ) && ! empty( $matches ) ) {
                return  $matches[2];

            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * Consulta las imágenes adjuntas
     * @param int $post_id El ID de la entrada para verificar si existen adjuntos
     * @return array|bool El primer adjunto en éxito, false si no hay adjuntos
     */
    function get_attach( $post_id ) {
        return get_children( array (
                'post_parent'    => $post_id,
                'post_type'      => 'attachment',
                'post_mime_type' => 'image',
                'posts_per_page'  => (int)1
            ), ARRAY_A );
    }
6 sept 2012 06:08:37
Comentarios

media_sideload_image() parece prometedor, pero ¿cómo se obtiene el ID del adjunto para la imagen cargada de forma externa?

helgatheviking helgatheviking
6 sept 2012 21:41:15

Mira la función get_attach. Se ejecuta después de media_sideload_image.

Chris_O Chris_O
6 sept 2012 22:00:08

¿te refieres a get_attachment? eso necesita el ID que aún no tengo. Voy a echar un vistazo a media_handle_sideload()

helgatheviking helgatheviking
6 sept 2012 22:32:31

además, la carga lateral de medios no es del todo correcta porque duplica imágenes que ya están en la carpeta wp-uploads (donde el plugin de video embedder las está agregando)

helgatheviking helgatheviking
6 sept 2012 22:58:21

Bueno, el video embedder debería agregarlas a tu biblioteca de medios en lugar de simplemente volcarlas en tu directorio de uploads.

Chris_O Chris_O
7 sept 2012 00:11:41

Estoy de acuerdo. Terminé modificando el plugin para hacer exactamente eso. Envié mi nuevo código al autor, así que quizás se incluya en una futura versión.

helgatheviking helgatheviking
7 sept 2012 16:25:09
Mostrar los 1 comentarios restantes
4

Aquí están las partes relevantes que cambié de la función kg_video_attachment_fields_to_save() que filtra attachment_fields_to_save:

    $thumb_url = $attachment['kgflashmediaplayer-poster'];

    //inserta la $thumb_url en la biblioteca de medios si no existe ya
    if ( ! ($thumb_id = get_attachment_id_from_src( $thumb_url ) ) ) {

        $post_id = $post['ID'];
        $desc = $attachment['post_title'] . ' miniatura';

        //¿está la imagen en el directorio de uploads?
        $upload_dir = wp_upload_dir();

        if ( FALSE !== strpos( $url, $upload_dir['baseurl'] ) ) {
            $wp_filetype = wp_check_filetype(basename($thumb_url), null );
            $filename = preg_replace('/\.[^.]+$/', '', basename($thumb_url));

            $attachment = array(
               'guid' => $thumb_url, 
               'post_mime_type' => $wp_filetype['type'],
               'post_title' => $desc,
               'post_content' => '',
               'post_status' => 'inherit'
            );
            $thumb_id = wp_insert_attachment( $attachment, basename($thumb_url), $post_id );
            // primero debes incluir el archivo image.php
            // para que la función wp_generate_attachment_metadata() funcione
            require_once(ABSPATH . 'wp-admin/includes/image.php');
            $attach_data = wp_generate_attachment_metadata( $thumb_id, basename($thumb_url) );
            wp_update_attachment_metadata( $thumb_id, $attach_data );
        } else { //no está en uploads así que tendremos que sideloadearlo
            $tmp = download_url( $thumb_url );

            // Establece variables para almacenamiento
            // corrige el nombre del archivo para query strings
            preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $thumb_url, $matches);
            $file_array['name'] = basename($matches[0]);
            $file_array['tmp_name'] = $tmp;

            // Si hay error almacenando temporalmente, elimina
            if ( is_wp_error( $tmp ) ) {
                @unlink($file_array['tmp_name']);
                $file_array['tmp_name'] = '';
            }

            // hace la validación y almacenamiento
            $thumb_id = media_handle_sideload( $file_array, $post_id, $desc );

            // Si hay error almacenando permanentemente, elimina
            if ( is_wp_error($thumb_id) ) {
                @unlink($file_array['tmp_name']);
                return $thumb_id;
            }

            if ( $local_src = wp_get_attachment_url( $thumb_id ) ) {
                update_post_meta($post['ID'], '_kgflashmediaplayer-poster', $local_src);
            }

        } //fin sideload

    } //fin get_attachment_id_from_src

    if(!is_wp_error($thumb_id)) {
        $thumb_id = intval( $thumb_id );
        update_post_meta($post['ID'], '_kgflashmediaplayer-poster-id', $thumb_id);
    } 

Y el ID de la miniatura personalizada del video ahora se almacena en el campo meta: _kgflashmediaplayer-poster-id

function get_attachment_id_from_src ($image_src) {
    global $wpdb;

    $query = "SELECT ID FROM {$wpdb->posts} WHERE guid='$image_src'";
    $id = $wpdb->get_var($query);
    return $id;

}

No me encanta la función get_attachment_id_from_src() pero no hay una forma integrada de hacer esto. Debería agregar una verificación para que si la src actual es la misma que la anterior, esta consulta no necesite ejecutarse. El plugin de inserción crea muchas miniaturas potenciales para cada video y no hay necesidad de insertarlas todas en la biblioteca de medios... así que esto se ejecuta cada vez que se guarda un archivo adjunto de medios y debería cubrir imágenes que ya están en la biblioteca de medios, imágenes que están en el directorio de medios pero no en la biblioteca e imágenes en otros servidores (que se cargan de forma remota y la URL se ajusta a la nueva URL local)

7 sept 2012 16:35:50
Comentarios

Función maravillosa... necesitó un poco de ajustes pero funcionó genial para mis necesidades ;)

Sagive Sagive
29 sept 2015 02:22:12

Como esto tiene 3 años, asumo que ahora hay una forma mucho mejor de hacerlo.

helgatheviking helgatheviking
29 sept 2015 12:17:39

aún funcionó para mí - que es todo lo que necesitaba ;) - un código detallado, rápido y listo para usar. gracias.

Sagive Sagive
1 oct 2015 07:55:36

¡buena función get_attachment_id_from_src, no muy elegante, pero realmente efectiva!

Magico Magico
5 ene 2017 12:59:18