Skip to content

Instantly share code, notes, and snippets.

@hearvox
Last active October 19, 2021 08:29
Show Gist options
  • Save hearvox/b10b3ebac75b3cf37e89e03a93ea1fc7 to your computer and use it in GitHub Desktop.
Save hearvox/b10b3ebac75b3cf37e89e03a93ea1fc7 to your computer and use it in GitHub Desktop.
WordPress script adds files to Media Library; attaches files to posts.
<?php
/**
* Add files to Media Library; attach files to posts.
*
* This is for adding files to Media Library already in /uploads/.
* If files are elsewhere, adapt script.
*
* Attempts to attach file to post:
* Searches thru post content for the filename.
* If a post is found, then uses post ID and publish-date
* as attachemnt's parent ID and upload-date.
* If no post found, parent ID set to 0 and date to file mod date.
*
* See this gist to generate list fo files:
* @link https://gist.github.com/hearvox/b5f3b70bcb92170ff091486224c9a2ad
* Based on example at:
* @link https://developer.wordpress.org/reference/functions/wp_insert_attachment/
*/
// Array of GUIDs of files to add to Media Library.
$files = array(
'2010/01/example-file.pdf',
'2010/01/next-example-file.pdf',
'2010/02/nother-example-file.pdf',
);
/* UNCOMMENT foreach() TO RUN SCRIPT */
// Traverse array of file names.
foreach ( $files as $filename ) {
// Default attachment meta.
$filedate = date( 'Y-m-d H:i:s' );
$parent_id = 0;
$attach_id = 0;
// Get the path to the file
$filepath = $wp_upload_dir['path'] . '/' . $filename;
// Check for file.
if ( file_exists( $filepath ) ) {
// Check the type of file. We'll use this as the 'post_mime_type'.
$filetype = wp_check_filetype( basename( $filename ), null );
// Attach file to post: Search for filename in content.
$args = array(
'post_type' => 'post',
'fields' => 'ids',
'posts_per_page' => 1,
's' => $filename,
);
$query = new WP_Query( $args );
// If post found, get post's ID and date (to set attachment's parent and date).
if ( isset( $query->posts[0] ) ) {
$parent_id = $query->posts[0];
$filedate = get_the_date( 'Y-m-d H:i:s', $parent_id );
} else {
// Get the file's modification timestamp.
$filemtime = filemtime( $filepath );
$filedate = date( 'Y-m-d H:i:s', $filemtime );
}
// Prepare an array of post data for the attachment.
$attachment = array(
'guid' => $wp_upload_dir['url'] . '/' . basename( $filename ),
'post_mime_type' => $filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
'post_content' => '',
'post_date' => $filedate,
'post_status' => 'inherit'
);
// Make sure that this file is included, as wp_generate_attachment_metadata() depends on it.
require_once( ABSPATH . 'wp-admin/includes/image.php' );
// Insert the attachment, generate the metadata for the attachment,
// and update the database record.
// UNCOMMENT these 3 lines to run:
// $attach_id = wp_insert_attachment( $attachment, $filename, $parent_id );
// $attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
// wp_update_attachment_metadata( $attach_id, $attach_data );
// Prints results for tests and reference.
echo "$filename | <a href='/?p=$attach_id'>$attach_id</a> | $filedate | $parent_id<br >";
} else { // Not inserted: file doesn't exist at specified path.
echo "$filename | 0<br >";
}
}
@robertsharp
Copy link

Can you explain how I would run this in WordPress?

@com2
Copy link

com2 commented Oct 19, 2021

The file paths need to be provided in the array $files. I am no WP specialist but it seems that this only works for posts that have actually the files attached (but do not appear so in Media Library?). Not sure if that is always the case. Like I use Elementor pages and the used images they don't appear to be attached when I look in the WP page editor.

FYI I found by accident a way to manually but bulk attach images in the media library (works in WP 5.8.1). Here are the steps.

  1. Find in the media library the media files that are not attached but do belong to one content item (page, post etc).
  2. Select them
  3. Click the attach link
  4. Find the content to which these media files belong
  5. Select its line in the search results
  6. Click the select button.
  7. Now all the previously selected media should be attached.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment