Home > Net >  Save image programmatically in WP
Save image programmatically in WP

Time:06-21

Im trying to save a post programmatically with an image, the post has been inserted successfully, but with no image, when I go to edit post page I cant find the image,

I have an external URL for the image that I want to save

        $postData = array(
            'post_title' => "feroferofero",
            'post_content' => 'posts',
            'post_status' => 'publish',
            'post_type' => 'publications',
            'meta_input' => array(
                'publications_title' => 'feroferofero',
                'publications_body' => $description,
                'publications_type' => $type
            ),
        );
        $newpost_id = wp_insert_post($postData);
        if ($newpost_id != 0) {

            $image = pathinfo($image_url); //Extracting information into array.
            $image_name = $image['basename'];
            $upload_dir = wp_upload_dir();
            $image_data = file_get_contents($image_url);
            $unique_file_name = wp_unique_filename($upload_dir['path'], $image_name);
            $filename = basename($image_name);

            if (!is_wp_error($newpost_id)) {
                if ($image != '') {
                    // Check folder permission and define file location
                    if (wp_mkdir_p($upload_dir['path'])) {
                        $file = $upload_dir['path'] . '/' . $filename;
                    } else {
                        $file = $upload_dir['basedir'] . '/' . $filename;
                    }
                    // Create the image  file on the server
                    file_put_contents($file, $image_data);
                    // Check image file type
                    $wp_filetype = wp_check_filetype($filename, null);
                    // Set attachment data
                    $attachment = array(
                        'post_mime_type' => $wp_filetype['type'],
                        'post_title' => sanitize_file_name($filename),
                        'post_content' => '',
                        'post_status' => 'inherit',
                        'post_parent' => $newpost_id,
                        'guid' => $upload_dir['url'] . '/' . $filename,
                    );
                    // Create the attachment
                    $attach_id = wp_insert_attachment($attachment, $file, $newpost_id);
                    // Include image.php
                    require_once ABSPATH . 'wp-admin/includes/image.php';
                    // Define attachment metadata
                    $attach_data = wp_generate_attachment_metadata($attach_id, $file);
                    // Assign metadata to attachment
                    wp_update_attachment_metadata($attach_id, $attach_data);
                    // And finally assign featured image to post
                    $thumbnail = set_post_thumbnail($newpost_id, $attach_id);
                }
            } 
            add_post_meta($newpost_id, 'publications_image', $attach_id);
        }

Any idea?

CodePudding user response:

I had good results with the following code:

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

$title = get_the_title($post_id);
$attachment_id = media_sideload_image($url, $post_id, $title, 'id');

//debug/error log
if(is_wp_error($attachment_id)){
    //debug/error message
} else {
    wp_update_post(array(
       'ID'     => $attachment_id,
       'post_title' => $title, //you can apply your own logic here
       'post_excerpt'   => $title, //you can apply your own logic here
       'post_content'   => $title, //you can apply your own logic here
    ));
}

So as you can see my code tries a dfifferent approach to the idea so give it a try and let me know if it works.

CodePudding user response:

you can use the below code for image upload from url.

<?php

// upload image from url...
function wp_upload_from_url($image_url, $attach_to_post = 0, $add_to_media = true)
{
    $remote_image = fopen($image_url, 'r');

    if (!$remote_image) {
        return false;
    }

    $meta = stream_get_meta_data($remote_image);

    $image_meta = false;
    $image_filetype = false;

    if ($meta && !empty($meta['wrapper_data'])) {
        foreach ($meta['wrapper_data'] as $v) {
            if (preg_match('/Content\-Type: ?((image)\/?(jpe?g|png|gif|bmp))/i', $v, $matches)) {
                $image_meta = $matches[1];
                $image_filetype = $matches[3];
            }
        }
    }

    // Resource did not provide an image.
    if (!$image_meta) {
        return false;
    }

    $v = basename($image_url);
    if ($v && strlen($v) > 6) {
        // Create a filename from the URL's file, if it is long enough
        $path = $v;
    } else {
        // Short filenames should use the path from the URL (not domain)
        $url_parsed = parse_url($image_url);
        $path = isset($url_parsed['path']) ? $url_parsed['path'] : $image_url;
    }

    $path = preg_replace('/(https?:|\/|www\.|\.[a-zA-Z]{2,4}$)/i', '', $path);
    $filename_no_ext = sanitize_title_with_dashes($path, '', 'save');

    $extension = $image_filetype;
    $filename = $filename_no_ext . "." . $extension;

    // Simulate uploading a file through $_FILES. We need a temporary file for this.
    $stream_content = stream_get_contents($remote_image);

    $tmp = tmpfile();
    $tmp_path = stream_get_meta_data($tmp)['uri'];
    fwrite($tmp, $stream_content);
    fseek($tmp, 0); // If we don't do this, WordPress thinks the file is empty

    $fake_FILE = array(
        'name'     => $filename,
        'type'     => 'image/' . $extension,
        'tmp_name' => $tmp_path,
        'error'    => UPLOAD_ERR_OK,
        'size'     => strlen($stream_content),
    );

    // Trick is_uploaded_file() by adding it to the superglobal
    $_FILES[basename($tmp_path)] = $fake_FILE;

    // For wp_handle_upload to work:
    include_once ABSPATH . 'wp-admin/includes/media.php';
    include_once ABSPATH . 'wp-admin/includes/file.php';
    include_once ABSPATH . 'wp-admin/includes/image.php';

    $result = wp_handle_upload($fake_FILE, array(
        'test_form' => false,
        'action'    => 'local',
    ));

    fclose($tmp); // Close tmp file
    @unlink($tmp_path); // Delete the tmp file. Closing it should also delete it, so hide any warnings with @
    unset($_FILES[basename($tmp_path)]); // Clean up our $_FILES mess.

    fclose($remote_image); // Close the opened image resource

    $result['attachment_id'] = 0;

    if (empty($result['error']) && $add_to_media) {
        $args = array(
            'post_title'     => $filename_no_ext,
            'post_content'   => '',
            'post_status'    => 'publish',
            'post_mime_type' => $result['type'],
        );

        $result['attachment_id'] = wp_insert_attachment($args, $result['file'], $attach_to_post);

        $attach_data = wp_generate_attachment_metadata($result['attachment_id'], $result['file']);
        wp_update_attachment_metadata($result['attachment_id'], $attach_data);

        if (is_wp_error($result['attachment_id'])) {
            $result['attachment_id'] = 0;
        }
    }

    return $result;
}

// insert post...
$postData = array(
    'post_title' => "feroferofero",
    'post_content' => 'posts',
    'post_status' => 'publish',
    'post_type' => 'publications',
    'meta_input' => array(
        'publications_title' => 'feroferofero',
        'publications_body' => $description,
        'publications_type' => $type
    ),
);

$newpost_id = wp_insert_post($postData);
$image_url = 'https://img.freepik.com/free-photo/aerial-view-mountain-covered-fog-beautiful-pink-sky_181624-4676.jpg?w=2000';

if ( wp_upload_from_url($image_url, $newpost_id) ) {
    $attach_id = wp_upload_from_url($image_url, $newpost_id)['attachment_id'];

    if ($attach_id != 0):
      if( !is_null(get_post($newpost_id)) ){
        add_post_meta($newpost_id, 'publications_image', $attach_id);
      }
    endif;
}
else {
  echo "error occured!";
}

//  ...... below code is for debug only.....................................................................
    function pr($val=null, $name='')
    {
        print("<pre> $name" . print_r($val, true) . "</pre>");
    }

    /**************** sample output ****************
    post_id --> 60
    return array --> Array
 (
       [file] => /mnt/sdb2/local/test/app/public/wp-content/uploads/2022/06/tree-576847__480-5.png
       [url] => http://test.local/wp-content/uploads/2022/06/tree-576847__480-5.png
       [type] => image/png
       [attachment_id] => 62
 )
 ************************************************/
    pr($newpost_id, 'post_id --> ');
    pr(wp_upload_from_url($image_url, $newpost_id), 'return array --> ');
    pr('<a href="'. wp_upload_from_url($image_url, $newpost_id)['url'] .'" target="_blank"> Show Uploaded Image </a>', 'image --> ');

    pr( get_post_meta($newpost_id, 'publications_image'), 'publications_image --> ' );

    pr( wp_get_attachment_image( get_post_meta($newpost_id, 'publications_image', true) ), 'show image from id --> ' );

/*** wp_upload_from_url function reference: https://gist.github.com/RadGH/966f8c756c5e142a5f489e86e751eacb ***/

if you want to test this function you can add a test page in wordpress admin (code goes in functions.php or your plugin code)

<?php

if ( is_admin() ) {

   add_action( 'admin_menu', 'add_testxd_menu_entry', 100 );
}
function add_testxd_menu_entry() {
   add_menu_page(
     __( 'Test Page', 'textdomain' ),
     'testxd',
     'manage_options',
     'testxd',
     'func_testxd',
     'dashicons-admin-network',
     6
   );
}

// to view this page --> WP Admin -> testxd
function func_testxd () {

echo '<br><br><div style="color: #fff; background: #000;"><br><br>';

// upload image from url...
function wp_upload_from_url($image_url, $attach_to_post = 0, $add_to_media = true)
{
    $remote_image = fopen($image_url, 'r');

    if (!$remote_image) {
        return false;
    }

    $meta = stream_get_meta_data($remote_image);

    $image_meta = false;
    $image_filetype = false;

    if ($meta && !empty($meta['wrapper_data'])) {
        foreach ($meta['wrapper_data'] as $v) {
            if (preg_match('/Content\-Type: ?((image)\/?(jpe?g|png|gif|bmp))/i', $v, $matches)) {
                $image_meta = $matches[1];
                $image_filetype = $matches[3];
            }
        }
    }

    // Resource did not provide an image.
    if (!$image_meta) {
        return false;
    }

    $v = basename($image_url);
    if ($v && strlen($v) > 6) {
        // Create a filename from the URL's file, if it is long enough
        $path = $v;
    } else {
        // Short filenames should use the path from the URL (not domain)
        $url_parsed = parse_url($image_url);
        $path = isset($url_parsed['path']) ? $url_parsed['path'] : $image_url;
    }

    $path = preg_replace('/(https?:|\/|www\.|\.[a-zA-Z]{2,4}$)/i', '', $path);
    $filename_no_ext = sanitize_title_with_dashes($path, '', 'save');

    $extension = $image_filetype;
    $filename = $filename_no_ext . "." . $extension;

    // Simulate uploading a file through $_FILES. We need a temporary file for this.
    $stream_content = stream_get_contents($remote_image);

    $tmp = tmpfile();
    $tmp_path = stream_get_meta_data($tmp)['uri'];
    fwrite($tmp, $stream_content);
    fseek($tmp, 0); // If we don't do this, WordPress thinks the file is empty

    $fake_FILE = array(
        'name'     => $filename,
        'type'     => 'image/' . $extension,
        'tmp_name' => $tmp_path,
        'error'    => UPLOAD_ERR_OK,
        'size'     => strlen($stream_content),
    );

    // Trick is_uploaded_file() by adding it to the superglobal
    $_FILES[basename($tmp_path)] = $fake_FILE;

    // For wp_handle_upload to work:
    include_once ABSPATH . 'wp-admin/includes/media.php';
    include_once ABSPATH . 'wp-admin/includes/file.php';
    include_once ABSPATH . 'wp-admin/includes/image.php';

    $result = wp_handle_upload($fake_FILE, array(
        'test_form' => false,
        'action'    => 'local',
    ));

    fclose($tmp); // Close tmp file
    @unlink($tmp_path); // Delete the tmp file. Closing it should also delete it, so hide any warnings with @
    unset($_FILES[basename($tmp_path)]); // Clean up our $_FILES mess.

    fclose($remote_image); // Close the opened image resource

    $result['attachment_id'] = 0;

    if (empty($result['error']) && $add_to_media) {
        $args = array(
            'post_title'     => $filename_no_ext,
            'post_content'   => '',
            'post_status'    => 'publish',
            'post_mime_type' => $result['type'],
        );

        $result['attachment_id'] = wp_insert_attachment($args, $result['file'], $attach_to_post);

        $attach_data = wp_generate_attachment_metadata($result['attachment_id'], $result['file']);
        wp_update_attachment_metadata($result['attachment_id'], $attach_data);

        if (is_wp_error($result['attachment_id'])) {
            $result['attachment_id'] = 0;
        }
    }

    return $result;
}

// insert post...
$postData = array(
    'post_title' => "feroferofero",
    'post_content' => 'posts',
    'post_status' => 'publish',
    'post_type' => 'publications',
    'meta_input' => array(
        'publications_title' => 'feroferofero',
        'publications_body' => $description,
        'publications_type' => $type
    ),
);

$newpost_id = wp_insert_post($postData);
$image_url = 'https://img.freepik.com/free-photo/aerial-view-mountain-covered-fog-beautiful-pink-sky_181624-4676.jpg?w=2000';

if ( wp_upload_from_url($image_url, $newpost_id) ) {
    $attach_id = wp_upload_from_url($image_url, $newpost_id)['attachment_id'];

    if ($attach_id != 0):
      if( !is_null(get_post($newpost_id)) ){
        add_post_meta($newpost_id, 'publications_image', $attach_id);
      }
    endif;
}
else {
  echo "error occured!";
}

//  ...... below code is for debug only.....................................................................
    function pr($val=null, $name='')
    {
        print("<pre> $name" . print_r($val, true) . "</pre>");
    }

    /**************** sample output ****************
    post_id --> 60
    return array --> Array
 (
       [file] => /mnt/sdb2/local/test/app/public/wp-content/uploads/2022/06/tree-576847__480-5.png
       [url] => http://test.local/wp-content/uploads/2022/06/tree-576847__480-5.png
       [type] => image/png
       [attachment_id] => 62
 )
 ************************************************/
    pr($newpost_id, 'post_id --> ');
    pr(wp_upload_from_url($image_url, $newpost_id), 'return array --> ');
    pr('<a href="'. wp_upload_from_url($image_url, $newpost_id)['url'] .'" target="_blank"> Show Uploaded Image </a>', 'image --> ');

    pr( get_post_meta($newpost_id, 'publications_image'), 'publications_image --> ' );

    pr( wp_get_attachment_image( get_post_meta($newpost_id, 'publications_image', true) ), 'show image from id --> ' );

/*** wp_upload_from_url function reference: https://gist.github.com/RadGH/966f8c756c5e142a5f489e86e751eacb ***/

// end testx...
echo '<br><br></div><br><br>';
}
  • Related