• Describe the bug
    I am uploading files to WP Media Library via code. I am using the wp_update_attachment_metadata function to update the metadata. The images are being uploaded to S3 while the videos aren’t. I have tested and the metadata is being generated and saved but the mp4 files still remain locally.

    To Reproduce
    Steps to reproduce the behavior:
    Upload a file using wp_handle_sideload, then use wp_insert_attachment to insert the sideloaded file in the media library (as attachment) and then use wp_generate_attachment_metadata to generate metadata and wp_update_attachment_metadata to update the attachment metadata.

    Expected behavior
    The video file needs to be uploaded to S3 at the end of all of this.

    Screenshots
    none

    debug.log
    I have enabled debug.log but the log file wp-content/debug.log remains empty.

    Diagnostic Info (from plugin’s “Support” tab):
    diagnostic-log-20240411203212.txt

    Additional context
    The code/process should work from what I’ve read about the developer options of the plugin and hooking into wp_update_attachment_metadata … but it doesn’t. Please help.

Viewing 5 replies - 1 through 5 (of 5 total)
  • Plugin Author Delicious Brains

    (@deliciousbrains)

    Hey @todordvv,

    Please could you share the custom code you’re using to perform the upload and insert into the Media Library?

    –IJ

    Thread Starter todordvv

    (@todordvv)

    @deliciousbrains yes for sure. I have a class to handle media so this is a function in that class that also uses a helper method from the same class. We get the media via URL so we use the upload_from_url function to do this, which creates a physical file which we then use in the upload_from_file function.

    function upload_from_url($media_url = '', $parent_post_id = 0) {
    
    $override_existing_check = false;
    
    $attachment_id = false;
    
    if (filter_var($media_url, FILTER_VALIDATE_URL)) {
    
        $ext  = pathinfo($media_url, PATHINFO_EXTENSION);
    
        if (!empty($ext)) {
            $key = 'url_media_upload';
            $key_value = $parent_post_id . '_' . $media_url;
    
            $existing_media = get_posts(
                array(
                    'post_type' => 'attachment',
                    'post_status' => 'any',
                    'posts_per_page' => -1,
                    'meta_query' => array(
                        array(
                            'key'     => $key,
                            'value'   => $key_value,
                            'compare' => '='
                        )
                    )
                )
            );
    
            if (!$override_existing_check && is_array($existing_media) && count($existing_media)) {
                return $existing_media[0]->ID;
            } else {
    
                if (!function_exists('download_url')) {
                    require_once ABSPATH . 'wp-admin/includes/file.php';
                }
    
                $tmp_name = download_url($media_url);
    
                if (!is_wp_error($tmp_name) && !empty($tmp_name) && is_string($tmp_name)) {
    
                    $attachment_id = $this->upload_from_file($tmp_name, $parent_post_id, $ext);
    
                    if (!empty($attachment_id)) {
                        update_post_meta($attachment_id, $key, $key_value);
                    }
    
                    @unlink($tmp_name);
                }
            }
        }
    }
    
    return $attachment_id;
    
    }
    
    function upload_from_file($filepath = '', $parent_post_id = 0, $ext = '') {
    
    if (!is_file($filepath)) {
        return false;
    }
    
    require_once(ABSPATH . 'wp-admin/includes/media.php');
    require_once(ABSPATH . 'wp-admin/includes/file.php');
    require_once(ABSPATH . 'wp-admin/includes/image.php');
    
    if (empty($ext)) {
        $ext = pathinfo(basename($filepath), PATHINFO_EXTENSION);
    }
    
    $file = array(
        'name'     => uniqid(md5(date('Y-m-d H:i:s:u'))) . '.' . $ext,
        'type'     => mime_content_type($filepath),
        'tmp_name' => $filepath,
        'size'     => filesize($filepath),
    );
    
    $sideload = wp_handle_sideload(
        $file,
        array(
            'test_form'   => false /* no need to check 'action' parameter */
        )
    );
    
    if (!empty($sideload['error'])) {
        return false;
    }
    
    $attachment_id = wp_insert_attachment(
        array(
            'guid'           => $sideload['url'],
            'post_mime_type' => $sideload['type'],
            'post_title'     => basename($sideload['file']),
            'post_content'   => '',
            'post_status'    => 'inherit',
        ),
        $sideload['file'],
        $parent_post_id
    );
    
    if (is_wp_error($attachment_id) || !$attachment_id) {
        return false;
    }
    
    $attachment_data = wp_generate_attachment_metadata($attachment_id, $sideload['file']);
    
    wp_update_attachment_metadata($attachment_id, $attachment_data);
    
    return $attachment_id;
    
    }

    EDIT: Just a confirmation that I have extensively tested this and $attachment_data does contain the correct metadata and mime info for MP4 files before being passed on to wp_update_attachment_metadata.

    • This reply was modified 11 months, 1 week ago by todordvv. Reason: Adding some additional info about testing the metadata
    Plugin Author Delicious Brains

    (@deliciousbrains)

    Thanks @todordvv, I can’t see anything obviously amiss in the code.

    Please can you run a couple of tests for me:

    1. Upload the test mp4 to the Media Library via the standard UI to check that it offloads as expected.
    2. Disable EWWW Image Optimizer and try uploading the test mp4 via the custom code.
    3. Try uploading a test png via the custom code.

    You mentioned nothing found in wp-content/debug.log, but your diagnostics say that debug errors go to logs/php-error.log, please check that after running your tests.

    I’m assuming the custom code is in the “WedSociety HUB 2.0” plugin, but if not, where is it?

    Have you tried debugging this to see whether \DeliciousBrains\WP_Offload_Media\Integrations\Media_Library::wp_update_attachment_metadata() gets called in response to the wp_update_attachment_metadata filter firing?

    Please also confirm when the upload_from_url function is run. Is it triggered from a manual admin UI function called by a user that’s entered a URL, or something automatic, e.g. cron?

    –IJ

    Thread Starter todordvv

    (@todordvv)

    @deliciousbrains thanks once again for the quick response. Here’s the answers to all your questions:

    0. I’m assuming the custom code is in the “REDUCTED” plugin, but if not, where is it?

    I would greatly appreciate @deliciousbrains if you can edit your comment to hide the plugin name due to privacy concerns. But yes the code is in a plugin.

    1. Upload the test mp4 to the Media Library via the standard UI to check that it offloads as expected.

    This works, and I tested it again just now to re-confirm. I tested both the WP-ADMIN media page as well as front-end ACF controls – manually uploading files to media library works without issue.

    2. Disable EWWW Image Optimizer and try uploading the test mp4 via the custom code.

    After the manual tests at 1. I did a test before disabling EWWW for error log purposes. The video didn’t get uploaded to S3 (it stayed with a local URL).

    After disabling EWWW the video uploaded to S3 and has a CDN domain URL!!! So this seems indicative that it is an issue with combining EWWW and Offload Media plugins.

    3. Try uploading a test png via the custom code.

    This always works but there is a slight issue I’ve noticed with PNG files that are on S3 – such that sometimes the wp_get_attachment_image_url and similar functions may return the local file URL which doesn’t work – resulting in broken images. Again no PHP or other errors with this and it only happens when uploading multiple images via code one after the other in short amount of time. Calling the function to get the URL again results in the correct URL. So I deduced this is a timing issue with something but it could be that it is again related to EWWW – this would be much harder to test since it’s not always happening. Regardless that’s why I now I do a find-replace on the URL for images. In my case this is something I can afford to do since I then store the URL and IMG tag in metadata (due to the nature of our system which I won’t go too much into) so it’s not something I do every time I display the image on the front end haha.

    4. You mentioned nothing found in wp-content/debug.log, but your diagnostics say that debug errors go to logs/php-error.log, please check that after running your tests.

    Yes I was already monitoring the php-error.log too, and during this whole ordeal there was never a PHP error related to this issue we’re discussing, in fact during the tests today there was no PHP error or warning whatsoever.

    5. Please also confirm when the upload_from_url function is run. Is it triggered from a manual admin UI function called by a user that’s entered a URL, or something automatic, e.g. cron?

    It is triggered on a webhook endpoint being called, so automatic/cron-like (not a manual action).

    FINALLY I am at your disposal if you want me to test some other things for your convenience. I presume you are the author of the plugin and as such since EWWW is quite a popular plugin too I would assume you might want to try and improve compatibility between the two. For me for now I can continue without using EWWW until such a time this issue is resolved.

    My 2 cents would be that maybe it’s an issue with timing, since videos probably take longer to process and then additionally be processed by EWWW – so maybe you could be checking whether EWWW is present and if so use a hook from EWWW for checking whether media finished uploading/registering in the media library instead of using the default WP hooks? I am sorry if I am overstepping and suggesting stupid ideas hahah.

    I will not mark this resolved for the time being, will wait on your response and thoughts.

    But thank you very much! I can’t believe I didn’t think to try without EWWW in my mind it didn’t make sense to not work with the popular image optimization plugins…

    Plugin Author Delicious Brains

    (@deliciousbrains)

    @todordvv, WP Offload Media (Pro) has built in integration with EWWW Image Optimizer, which we regularly test, but WP Offload Media Lite does not. If you’re dependent on EIO, it might be worth giving WP Offload Media a try, and if there are still problems, we’ll be in a better position to try and help you debug them via our dedicated and private support.

    Otherwise, EIO does have built in integration for WP Offload Media, so it might be worth checking with them if you have a Pro license to see whether they can help.

    –IJ

Viewing 5 replies - 1 through 5 (of 5 total)
  • The topic ‘Video files uploaded to media library via code do not get uploaded to S3’ is closed to new replies.