0

On my site I have to custom post types and a function that let's users import photos from post type A to post type B, copying the meta values and it copy's the image to the folder specified for post type B ---

<?php
// File: import-pics.php

require_once $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php';

global $current_user, $imic_options; // Use global
wp_get_current_user(); // Make sure global is set, if not set it.

$yourID = $current_user->ID;
$propertyID = $_POST['propertyID'];
$vidID = $_POST['videoID'];

$path = '/path/to/wp-content/uploads/'.$yourID.'/'.$vidID;

// Get the attachments (IDs) attached to the `property` CPT.
$prop_att_ids = (array) get_post_meta( $propertyID, 'imic_property_sights', false );

// Copy the meta value (attachments) to the `v_editor` CPT.
$vid_pix = get_post_meta( $vidID, 'vid_pix', false ); // test
//delete_post_meta( $vidID, 'vid_pix' );
foreach ( $prop_att_ids as $att_id ) {
    add_post_meta( $vidID, 'vid_pix', $att_id );
$filename = basename ( get_attached_file( $att_id ));
$url = wp_get_attachment_url( $att_id ) : '';
        copy($url, $path.'/'.$filename.'.png');
//echo $url;
}

$vid_pix2 = get_post_meta( $vidID, 'vid_pix', false ); // test
//var_dump( $vid_pix, $vid_pix2, $url ); // test

?>

The issue Im having now is that the attachment url still for the imported images are still the same as post type A even though I copied the image files over to post type B's folder.

**A -** /wp-content/uploads/2018/10
**B -** $path = '/path/to/wp-content/uploads/'.$yourID.'/'.$vidID;

How can I change the attachment url when importing the images using my above function?

2
  • Why do you need to copy it rather than just attach it to both post types?
    – WebElaine
    Commented Oct 11, 2018 at 14:53
  • cause im doing different things with each post type, so the post type b attachments need to be independent from post type a.
    – 730wavy
    Commented Oct 11, 2018 at 15:14

1 Answer 1

1

If you want the image's URL to be different, you need to first copy the image file to the user-specific folder and then create a new attachment for that copied image — i.e. clone the image's "post" data.

So replace this:

// Get the attachments (IDs) attached to the `property` CPT.
$prop_att_ids = (array) get_post_meta( $propertyID, 'imic_property_sights', false );

// Copy the meta value (attachments) to the `v_editor` CPT.
$vid_pix = get_post_meta( $vidID, 'vid_pix', false ); // test
//delete_post_meta( $vidID, 'vid_pix' );
foreach ( $prop_att_ids as $att_id ) {
    ... including the other code here ...
}

$vid_pix2 = get_post_meta( $vidID, 'vid_pix', false ); // test
//var_dump( $vid_pix, $vid_pix2, $url ); // test

with this one:

$path2 = $yourID . '/' . $vidID; // relative to wp-content/uploads
$prop_att_ids = (array) get_post_meta( $propertyID, 'imic_property_sights', false );

foreach ( $prop_att_ids as $att_id ) {
    // Check if we have a valid image/attachment.
    if ( $att_id && $file = get_attached_file( $att_id ) ) {
        $filename = basename( $file );
        $file2 = $path . '/' . wp_unique_filename( $path, $filename );

        // Copy the image file to $path.
        if ( @copy( $file, $file2 ) ) {
            // Copy the attachment (post) data.
            $att = get_post( $att_id, ARRAY_A );
            unset( $att['ID'] );
            $att_id2 = wp_insert_attachment( $att, $file2 );

            // Then add the meta data `vid_pix`.
            add_post_meta( $vidID, 'vid_pix', $att_id2 );

            // Copy the attachment's meta data. (no thumbnails)
            $data = wp_get_attachment_metadata( $att_id );
            $data['file'] = $path2 . '/' . basename( $file2 );
            $data['sizes'] = [];
            wp_update_attachment_metadata( $att_id2, $data );
        }
    }
}

Note that since we're creating a new attachment post, I used wp_unique_filename() to generate a unique file name for the image file that we're copying to the $path.


UPDATE

If you want to generate all thumbnails, replace this part:

// Copy the attachment's meta data. (no thumbnails)
$data = wp_get_attachment_metadata( $att_id );
$data['file'] = $path2 . '/' . basename( $file2 );
$data['sizes'] = [];
wp_update_attachment_metadata( $att_id2, $data );

with this one:

// Create the attachment's meta data. (with thumbnails)
$att2 = get_post( $att_id2 );
wp_maybe_generate_attachment_metadata( $att2 );

UPDATE #2

Here's the full code I used:

<?php
// File: import-pics.php

require_once $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php';

global $current_user, $imic_options; // Use global
wp_get_current_user(); // Make sure global is set, if not set it.

$yourID = $current_user->ID;
$propertyID = $_POST['propertyID'];
$vidID = $_POST['videoID'];

$path = WP_CONTENT_DIR . '/uploads/' . $yourID . '/' . $vidID;
$path2 = $yourID . '/' . $vidID; // relative to wp-content/uploads
$prop_att_ids = (array) get_post_meta( $propertyID, 'imic_property_sights', false );

$to_copy = count( $prop_att_ids ); // test
$copied = 0; // test
foreach ( $prop_att_ids as $att_id ) {
    // Check if we have a valid image/attachment.
    if ( $att_id && $file = get_attached_file( $att_id ) ) {
        $filename = basename( $file );
        $file2 = $path . '/' . wp_unique_filename( $path, $filename );

        // Copy the image file to $path.
        if ( @copy( $file, $file2 ) ) {
            // Copy the attachment (post) data.
            $att = get_post( $att_id, ARRAY_A );
            unset( $att['ID'] );
            $att_id2 = wp_insert_attachment( $att, $file2 );

            // Then add the meta data `vid_pix`.
            add_post_meta( $vidID, 'vid_pix', $att_id2 );

            // Copy the attachment's meta data. (no thumbnails)
            $data = wp_get_attachment_metadata( $att_id );
            $data['file'] = $path2 . '/' . basename( $file2 );
            $data['sizes'] = [];
            wp_update_attachment_metadata( $att_id2, $data );

            $copied++; // test
        }
    } else {
        $to_copy--; // test
    }
}
echo $copied . ' image(s) out of ' . $to_copy . ' copied.<br>'; // test
var_dump( get_post_meta( $vidID, 'vid_pix', false ) ); // test

?>

PS: I previously misplaced the $to_copy--;, though that's for testing only.

8
  • hi thanks for the reply. I tried your code and now the function doesnt import the photos at all. any ideas?
    – 730wavy
    Commented Oct 17, 2018 at 12:24
  • @Rich, try the full code and let me know.
    – Sally CJ
    Commented Oct 18, 2018 at 9:49
  • 1
    I'm glad to hear that @Rich! =) And I updated the answer, mainly because the code I posted on Pastebin will be deleted in about 1 week from now.
    – Sally CJ
    Commented Oct 18, 2018 at 14:25
  • 1
    Hi Rich. I'm sure there is, and I'll see what I can do.
    – Sally CJ
    Commented Oct 30, 2018 at 17:22
  • 1
    Please check and try this. The approach I used is: We save the ID of copied attachments into a custom field, and when copying the property's attachments, we compare the IDs with the ones in the custom field - so copied attachments won't be re-copied. Not a bullet-proof, but I hope it works for you. Let me know.
    – Sally CJ
    Commented Nov 3, 2018 at 7:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.