Descargue una imagen de una página web a la carpeta de cargas predeterminada

8

Estoy escribiendo un tema / complemento personalizado en el que necesito descargar imágenes mediante programación desde ciertas páginas web a la carpeta de carga y luego insertarlas como parte de la publicación.

Entonces, pude encontrar la url de la imagen mediante programación, y luego necesito guardarla en la carpeta de carga en wp-content, sin embargo, esa carpeta tiene una estructura de carpeta específica de WordPress dentro de ella para las imágenes guardadas.

Ahora mi pregunta es, ¿hay una API o función o método de WordPress que me permita descargar imágenes de la web y guardarlas en la carpeta de cargas? Y si es así, qué es.

De lo contrario, ¿qué debo hacer para guardar esas imágenes?

Hasta ahora, estoy haciendo esto

$filetype = wp_check_filetype(basename($image_file_name), null );

$upload_dir = wp_upload_dir();

$attachment = array(
    'guid' => $upload_dir['url'] . '/' . basename( $image_file_name ), 
    'post_mime_type' => $filetype['type'],
    'post_title' => preg_replace('/\.[^.]+$/', '', basename($image_file_name)),
    'post_content' => '',
    'post_status' => 'inherit'
);

$attachment_id = wp_insert_attachment( $attachment, $image_file_name, $post_id );

$attachment_data = wp_generate_attachment_metadata( $attachment_id, $image_file_name );

wp_update_attachment_metadata( $attachment_id,  $attachment_data );
set_post_thumbnail( $post_id, $attachment_id );

Pero el código anterior me está dando el siguiente error

imagejpeg(http://wscdn.bbc.co.uk/worldservice/assets/images/2013/07/21/130721173402_egypts_new_foreign_minister_fahmy_304x171_reuters-150x150.jpg): failed to open stream: HTTP wrapper does not support writeable connections in C:\dev\wordpress\pterodactylus\wp-includes\class-wp-image-editor.php on line 334

Y después de una investigación más profunda, parece que el error es causado por

$attachment_data = wp_generate_attachment_metadata( $attachment_id, $image_file_name );

Y después de una investigación más profunda, la documentación para los wp_insert_attachment()estados que The file MUST be on the uploads directoryen lo que respecta a la$image_file_name

Entonces, ¿cómo descargo una imagen y la guardo en mi publicación correctamente?

Muchas gracias.

Greeso
fuente
Tuve problemas con esto cuando era un problema de permisos en las imágenes en el directorio de cargas: debían ser propiedad del usuario del servidor (por ejemplo, www-data en apache / linux)
icc97
este tema de soporte de WordPress tiene más información
icc97

Respuestas:

11

Recientemente tuve que hacer esto a través de un script cron nocturno para una transmisión de redes sociales. $ parent_id es el ID de la publicación a la que desea adjuntar la imagen.

function uploadRemoteImageAndAttach($image_url, $parent_id){

    $image = $image_url;

    $get = wp_remote_get( $image );

    $type = wp_remote_retrieve_header( $get, 'content-type' );

    if (!$type)
        return false;

    $mirror = wp_upload_bits( basename( $image ), '', wp_remote_retrieve_body( $get ) );

    $attachment = array(
        'post_title'=> basename( $image ),
        'post_mime_type' => $type
    );

    $attach_id = wp_insert_attachment( $attachment, $mirror['file'], $parent_id );

    require_once(ABSPATH . 'wp-admin/includes/image.php');

    $attach_data = wp_generate_attachment_metadata( $attach_id, $mirror['file'] );

    wp_update_attachment_metadata( $attach_id, $attach_data );

    return $attach_id;

}

ex:

uploadRemoteImageAndAttach('http://some-external-site.com/the-image.jpg', 122);
divisiones
fuente
1

No ha publicado el código utilizado para recuperar y guardar la imagen, por lo que es imposible decir dónde está el error.

Pruebe este código para agarrar y guardar la imagen:

function my_grab_image($url = NULL, $name = NULL ) {
  $url = stripslashes($url);
  if ( ! filter_var($url, FILTER_VALIDATE_URL) ) return false;
  if ( empty($name )) $name = basename($url);
  $dir = wp_upload_dir();
  $filename = wp_unique_filename( $uploads['path'], $name, NULL );
  $filetype = wp_check_filetype($filename, NULL );
  if ( ! substr_count($filetype['type'], 'image') ) return false;
  try {
    $image = my_fetch_image($url);
    if ( ! is_string($image) || empty($image) ) return false;
    $save = file_put_contents( $dir['path'] . "/" . $filename, $image );
    if ( ! $save ) return false;
    return $dir['path'] . "/" . $filename;
  } catch ( Exception $e ) {
    // echo $e->getMessage(); // Is a good idea log this error
    return false;
  }
}

function my_fetch_image($url) {
  if ( function_exists("curl_init") ) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $image = curl_exec($ch);
    curl_close($ch);
    return $image;
  } elseif ( ini_get("allow_url_fopen") ) {
    $image = file_get_contents($url, false);
    return $image;
  } else {
    throw new Exception('curl is not available and fopen url is disallowed');
  }
}

Luego, simplemente use estas funciones en combinación con su código, así:

$image_file_name =  @my_grab_image('http://this.is.the.image.url/image.jpg');
if ( $image_file_name && file_exists($image_file_name) ) {
  // PUT HERE YOUR CODE
}

Recuerde también que debe incluir wp-admin / includes / image.php en su código para que la función wp_generate_attachment_metadata()funcione, consulte el Codex

Espero esta ayuda, pero tenga en cuenta que todo el código aquí no se prueba.

gmazzap
fuente
2
La solución de @Jeffrey Barrett es buena. Es más wordpress que el mío (y un poco más lento, porque la API HTTP de WP hace muchas cosas ). Puede ser mejor si la comprobación de errores en la carga antes de insertar poste de fijación: if ( $mirror['error'] ) return false; //maybe log error. Además, no se verifica si el contenido recuperado es en realidad una imagen$filetype = wp_check_filetype($filename, NULL ); if ( ! substr_count($filetype['type'], 'image') ) return false;
gmazzap
0

Puede usar esta función para cargar remotamente una imagen para cargar la carpeta y configurarla como imagen destacada.

function set_remote_featured_image($file, $post_id) {
    if ( ! empty($file) ) {
        // Download file to temp location
        $tmp = download_url( $file );

        // Set variables for storage
        // fix file filename for query strings
        preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches );
        $file_array['name'] = basename($matches[0]);
        $file_array['tmp_name'] = $tmp;

        // If error storing temporarily, unlink
        if ( is_wp_error( $tmp ) ) {
            @unlink($file_array['tmp_name']);
            $file_array['tmp_name'] = '';
        }

        // do the validation and storage stuff
        $id = media_handle_sideload( $file_array, $post_id, $desc );
        // If error storing permanently, unlink
        if ( is_wp_error($id) ) {
            @unlink($file_array['tmp_name']);
            return $id;
        }

        set_post_thumbnail( $post_id, $id );
    }
}

Uso:

set_remote_featured_image("http://example.com/image.jpg", 1);
shankshera
fuente
0

Solo use la función predeterminada wp (v2.6.0 +):

media_sideload_image ($ archivo, $ post_id, $ desc, $ return);

fdrv
fuente