Support

Account

Home Forums ACF PRO Rename files upon uploading

Solved

Rename files upon uploading

  • I want to rename files upon upload. After renaming the file, the thumbnails need to be generated again, done with use of the plugin “Regenerate Thumbnails”.

    This code works perfectly for the basic uploader but I can’t get it to work properly for the wp uploader (photo gallery), since it’s a different ‘technique’. I can get it to work, IF I can ‘ignore’ the add_attachment function for gallery uploads.

    For the default uploader, I generate the thumbnails after save (see code below), but for the wp uploader throws an error if I run add_attachment after upload.

    The fix I am looking for is an IF statement (in add_attachment) which check if the uploaded image is a profile image (basic) or the gallery upload (wp).

    I did consider changing (back) the profile photo to wp uploader (which makes add_attachment not needed anymore) but I’d like to limit the number of files uploaded through the profile photo uploader, hence why the basic is used.

    Any insight ?

    function add_attachment( $attachment_id ) {
        $file = $this->get_location_of_attachment_file( $attachment_id );
        if ( false !== $file ) {
            $path        = pathinfo( $file );
            $newfilename = $this->getToken( 10 );
            $newfile = $path[ 'dirname' ] . "/" . $newfilename . "." . $path[ 'extension' ];
    
            rename( $file, $newfile );
            update_attached_file( $attachment_id, $newfile );
        }
    }
    add_action( 'add_attachment', 'add_attachment', 999, 1 );
    function after_save_post( $post_id ) {
        if ( PostTypes::PROFILE == get_post_type( $post_id ) ) {
            $stored_profile_pic = get_field( 'sd_profile_photo', $post_id );
            $image_is_approved  = get_post_meta( $stored_profile_pic, '_image_approved', 1 );
            if ( false == $image_is_approved ) {
                global $wpdb;
                $wpdb->update(
                    $wpdb->posts,
                    array(
                        'guid' => wp_upload_dir()[ 'baseurl' ] . '/' . get_post_meta( $stored_profile_pic, '_wp_attached_file', 1 ),
                    ),
                    array(
                        'ID' => $stored_profile_pic
                    )
                );
                if ( class_exists( 'RegenerateThumbnails_Regenerator' ) ) {
                    $regenerator = RegenerateThumbnails_Regenerator::get_instance( $stored_profile_pic );
                    $regenerator->regenerate();
                }
    
                // https://dfactory.eu/support/topic/do_watermark-inside-functions-php/
                if ( class_exists( 'Image_Watermark' ) ) {
                    $image_sizes = array(
                        'gallerybig',
                        'large',
                        'medium_large',
                        'profile',
                        'profileheader',
                    );
                    $upload_dir  = wp_upload_dir();
                    $data        = wp_get_attachment_metadata( $post_id, false );
                    $watermark   = new Image_Watermark;
                    foreach ( $image_sizes as $image_size ) {
                        $filepath = scaled_image_path( $stored_profile_pic, $image_size );
                        $watermark->do_watermark( $stored_profile_pic, $filepath, $image_size, $upload_dir );
                    }
                }
            }
    
            $stored_gallery = get_field( 'sd_gallery', $post_id );
            if ( is_array( $stored_gallery ) ) {
                foreach ( $stored_gallery as $image ) {
                    $file             = $this->get_location_of_attachment_file( $image[ 'ID' ] );
                    $image_is_pending = get_post_meta( $image[ 'ID' ], '_image_pending', 1 );
                    if ( $file && true == $image_is_pending ) {
                        $path        = pathinfo( $file );
                        $newfilename = $this->getToken( 10 ); // @TODO create setting for this
                        $newfile     = $path[ 'dirname' ] . "/" . $newfilename . "." . $path[ 'extension' ];
    
                        rename( $file, $newfile );
                        update_attached_file( $image[ 'ID' ], $newfile );
    
                        if ( class_exists( 'RegenerateThumbnails_Regenerator' ) ) {
                            $regenerator = RegenerateThumbnails_Regenerator::get_instance( $image[ 'ID' ] );
                            $regenerator->regenerate();
                        }
    
                        if ( class_exists( 'Image_Watermark' ) ) {
                            $image_sizes = array(
                                'gallerybig',
                                'large',
                                'medium_large',
                                'profile',
                                'profileheader',
                            );
                            $upload_dir  = wp_upload_dir();
                            $data        = wp_get_attachment_metadata( $post_id, false );
                            $watermark   = new Image_Watermark;
                            foreach ( $image_sizes as $image_size ) {
                                $filepath = scaled_image_path( $image[ 'ID' ], $image_size );
                                $watermark->do_watermark( $image[ 'ID' ], $filepath, $image_size, $upload_dir );
                            }
                        }
                    }
                }
            }
       }
    }
    add_action( 'acf/save_post', 'after_save_post', 20 );
  • If I insert the code from add_attachment to after_save_post as below, then I end up with ‘double images’ because the image does gets renamed, but in a new file. It doesn’t rename the current file.

    The new files names are linked to the post, the original file names are not and thus they can not be deleted with a function, otherwise the issue would be solved.

    if ( false == $image_is_approved ) {
    
        $file = $this->get_location_of_attachment_file( $stored_profile_pic );
        if ( false !== $file ) {
            $path        = pathinfo( $file );
            $newfilename = $this->getToken( 10 );
            $newfile = $path[ 'dirname' ] . "/" . $newfilename . "." . $path[ 'extension' ];
    
            rename( $file, $newfile );
            update_attached_file( $stored_profile_pic, $newfile );
        }
    
        global $wpdb;
  • It took quite a few hours, but I fixed it myself… so if someone needs a working example, see below.

    I added an IF clause which checks if the meta field ‘_wp_attachment_context’ is set. If so, it’s the default (basic) uploader, so I can exclude this when an image is uploaded to a gallery field.

    function add_attachment( $attachment_id ) {
        $file = $this->get_location_of_attachment_file( $attachment_id );
        if ( false !== $file ) {
            if ( 'acf-upload' == get_post_meta( $attachment_id, '_wp_attachment_context', 1 ) ) {
                $path        = pathinfo( $file );
                $newfilename = $this->getToken( 10 ); // @TODO: get from setting
                $newfile = $path[ 'dirname' ] . "/" . $newfilename . "." . $path[ 'extension' ];
    
                rename( $file, $newfile );
                update_attached_file( $attachment_id, $newfile );
            }
        }
    }

    To delete the redundant images, I check for the file name before it’s renamed and use a mask to delete all files with a certain syntax.

    NOTE: If your file name has a dot in it (and not the one before the extension), then it probably won’t work. Still need a fix for it, but I’ll add an error for it…

    function after_save_post( $post_id ) {
        if ( PostTypes::PROFILE == get_post_type( $post_id ) ) {
            
            // profile pic part removed, because nothing changed
    
            $stored_gallery = get_field( 'sd_gallery', $post_id );
            if ( is_array( $stored_gallery ) ) {
                foreach ( $stored_gallery as $image ) {
                    $file             = $this->get_location_of_attachment_file( $image[ 'ID' ] );
                    $image_is_pending = get_post_meta( $image[ 'ID' ], '_image_pending', 1 );
                    if ( $file && true == $image_is_pending ) {
                        $path        = pathinfo( $file );
                        $newfilename = $this->getToken( 10 ); // @TODO: get from setting
                        $newfile     = $path[ 'dirname' ] . "/" . $newfilename . "." . $path[ 'extension' ];
    
                        rename( $file, $newfile );
                        update_attached_file( $image[ 'ID' ], $newfile );
                        if ( class_exists( 'RegenerateThumbnails_Regenerator' ) ) {
                            $regenerator = RegenerateThumbnails_Regenerator::get_instance( $image[ 'ID' ] );
                            $regenerator->regenerate();
                        }
    
                        preg_match( '~.+(/.+)~', $file, $result );
                        $file_name  = substr( $result[ 1 ], 1 );
                        $file_noext = strstr( $file_name, '.', 1 );
                        $mask       = $file_noext . '*';
                        array_map('unlink', glob(wp_upload_dir()['path'] . "/" . $mask ) );
                    }
                }
            }
        }
    }
Viewing 3 posts - 1 through 3 (of 3 total)

The topic ‘Rename files upon uploading’ is closed to new replies.