WordPress 使用工作缩略图重命名附件文件
WordPress rename attachment file with working thumbnails
我正在尝试编写一个函数来重命名附件文件,既可以在上传时重命名,也可以在上传后重命名。
我写了一个很好的函数可以做到这一点,但它会导致 WP 仪表板中缺少缩略图。我怀疑是因为 GUID 出错了,但是 WP 现在已经无法更改该 GUID(我认为),所以我不确定还能做什么。希望这里有人可以提供帮助。
这就是我所拥有的,基于我在网上可以找到的所有内容。
add_action("add_attachment", "rename_attachment", 10, 1);
function rename_attachment($post_id) {
custom_attachment_rename($post_id, "My name filename here");
}
function custom_attachment_rename( $post_id, $new_filename = 'new filename' ){
// Get path info of orginal file
$og_path = get_attached_file($post_id);
$path_info = pathinfo($og_path);
// Santize filename
$safe_filename = wp_unique_filename($path_info['dirname'], $new_filename);
// Build out path to new file
$new_path = $path_info['dirname']. "/" . $safe_filename . "." .$path_info['extension'];
// Rename the file and update it's location in WP
rename($og_path, $new_path);
update_attached_file( $post_id, $new_path );
// URL to the new file
$new_url = wp_get_attachment_url($post_id);
// Update attachment data
$id = wp_update_post([
'ID' => $post_id,
'post_title' => $new_filename,
'guid' => $new_url // Doesn't seem to work
]);
// Try this to reset the GUID for the attachment. Doesn't seem to actually reset it.
// global $wpdb;
// $result = $wpdb->update($wpdb->posts, ['guid' => $new_url], ['ID' => $post_id]);
// Update all links to old "sizes" files, or create it for new upload.
$metadata = get_post_meta($post_id, '_wp_attachment_metadata', true);
if( empty($metadata) ) {
// New upload.
$data = wp_generate_attachment_metadata($post_id, $new_path);
//update_post_meta($post_id, '_wp_attachment_metadata', $data); // Tried this. Doesn't work.
wp_update_attachment_metadata($post_id, $data); // Also doesn't work
} else {
// Regenerating an existing image
// TODO loop through $metadata and update the filename and resave? Maybe just delete it and regenerate instead?
}
// TODO Update use of the old filename in post_content throughout site
}
到目前为止,这些是我浏览过的有用帖子。
- https://wordpress.stackexchange.com/questions/166943/how-to-rename-an-image-attachment-filename-using-php
- https://wordpress.stackexchange.com/questions/30313/change-attachment-filename
- https://wordpress.stackexchange.com/a/221254/4562
奇怪的是,如果我在这个函数的末尾 die
,那么它就起作用了。所以我怀疑 WP 中的其他内容正在覆盖此附件的 _wp_attachment_metadata
。这就是为什么我怀疑 GUID 是问题所在。其他东西正在通过 GUID
查找附件并找到一个 URL 到一个不再存在的文件(因为我更改了文件名)和 运行 wp_generate_attachment_metadata
在一个坏文件上小路。这是我的预感。
我没有安装任何其他插件。
您的代码不起作用的原因与 GUID 无关。
这是因为,在 WP core 中,函数 wp_update_attachment_metadata() 在媒体上传请求处理结束时以原始文件名调用。钩子 add_attachment 在 wp_insert_attachment() 函数中被调用。
function media_handle_upload( $file_id, $post_id, $post_data = array(), $overrides = array( 'test_form' => false ) ) {
... ...
// Save the data.
$attachment_id = wp_insert_attachment( $attachment, $file, $post_id, true );
if ( ! is_wp_error( $attachment_id ) ) {
// Set a custom header with the attachment_id.
// Used by the browser/client to resume creating image sub-sizes after a PHP fatal error.
if ( ! headers_sent() ) {
header( 'X-WP-Upload-Attachment-ID: ' . $attachment_id );
}
// The image sub-sizes are created during wp_generate_attachment_metadata().
// This is generally slow and may cause timeouts or out of memory errors.
wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) );
}
return $attachment_id;
}
我们可以使用“wp_update_attachment_metadata”过滤器将元数据更改为新文件名。
请检查以下代码。我测试过,它运行良好。
class CustomAttachmentRename {
public $new_filename = 'custom file';
private $new_path;
function __construct () {
add_action("add_attachment", array($this, "rename_attachment"), 10, 1);
}
function rename_attachment($post_id) {
// Get path info of orginal file
$og_path = get_attached_file($post_id);
$path_info = pathinfo($og_path);
// Santize filename
$safe_filename = wp_unique_filename($path_info['dirname'], $this->new_filename);
// Build out path to new file
$this->new_path = $path_info['dirname']. "/" . $safe_filename . "." .$path_info['extension'];
// Rename the file and update it's location in WP
rename($og_path, $this->new_path);
update_attached_file( $post_id, $this->new_path );
// Register filter to update metadata.
add_filter('wp_update_attachment_metadata', array($this, 'custom_update_attachment_metadata'), 10, 2);
}
function custom_update_attachment_metadata($data, $post_id) {
return wp_generate_attachment_metadata($post_id, $this->new_path);
}
}
$customAttachmentRename = new CustomAttachmentRename();
$customAttachmentRename->new_filename = "test image" . time();
我把@chengmin answer 变成了这样一个函数:
/**
* Renames a file. Will also regenerate all the thumbnails that go with the file.
* @SEE
*
* @param string $post_id The WordPress post_id for the attachment
* @param string $new_file_name The filename (without extension) that you want to rename to
*/
function attachment_rename($post_id, $filename) {
// Get path info of orginal file
$og_url = wp_get_attachment_url($post_id);
$og_path = get_attached_file($post_id);
$path_info = pathinfo($og_path);
$og_meta = get_post_meta($post_id, '_wp_attachment_metadata', true);
// Santize filename
$safe_filename = wp_unique_filename($path_info['dirname'], $filename);
// Build out path to new file
$new_path = $path_info['dirname']. "/" . $safe_filename . "." .$path_info['extension'];
// Rename the file in the file system
rename($og_path, $new_path);
// Delete old image sizes if we have them
if( !empty($og_meta) ) {
delete_attachment_files($post_id);
}
// Now save new path to file in WP
update_attached_file( $post_id, $new_path );
// Register filter to update metadata
$new_data = wp_generate_attachment_metadata($post_id, $new_path);
return add_filter('wp_update_attachment_metadata', function($data, $post_id) use ($new_data) {
return $new_data;
}, 10, 2);
}
/**
* Delete all old image files, if they aren't used post_content anywhere.
* The dont-delete check isn't perfect, it will give a lot of false positives (keeping more files than it should), but it's best I could come up with.
* @SEE https://github.com/WordPress/WordPress/blob/f4cda1b62ffca52115e4b04d9d75047060d69e68/wp-includes/post.php#L5983
*
* @param string $post_id The WordPress post_id for the attachment
*/
function delete_attachment_files($post_id) {
$meta = wp_get_attachment_metadata( $post_id );
$backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true );
$file = get_attached_file( $post_id );
$url = wp_get_attachment_url($post_id);
// Remove og image so it doesn't get deleted in wp_delete_attachment_files()
$meta['original_image'] = "";
// Check if image is used in a post somehwere
$url_without_extension = substr($url, 0 , (strrpos($url, ".")));
$args = [
"s" => $url_without_extension,
"posts_per_page" => 1,
"post_type" => "any"
];
$found = get_posts($args);
if( empty($found) ) {
return wp_delete_attachment_files( $post_id, $meta, $backup_sizes, $file );
}
return false;
}
我正在尝试编写一个函数来重命名附件文件,既可以在上传时重命名,也可以在上传后重命名。
我写了一个很好的函数可以做到这一点,但它会导致 WP 仪表板中缺少缩略图。我怀疑是因为 GUID 出错了,但是 WP 现在已经无法更改该 GUID(我认为),所以我不确定还能做什么。希望这里有人可以提供帮助。
这就是我所拥有的,基于我在网上可以找到的所有内容。
add_action("add_attachment", "rename_attachment", 10, 1);
function rename_attachment($post_id) {
custom_attachment_rename($post_id, "My name filename here");
}
function custom_attachment_rename( $post_id, $new_filename = 'new filename' ){
// Get path info of orginal file
$og_path = get_attached_file($post_id);
$path_info = pathinfo($og_path);
// Santize filename
$safe_filename = wp_unique_filename($path_info['dirname'], $new_filename);
// Build out path to new file
$new_path = $path_info['dirname']. "/" . $safe_filename . "." .$path_info['extension'];
// Rename the file and update it's location in WP
rename($og_path, $new_path);
update_attached_file( $post_id, $new_path );
// URL to the new file
$new_url = wp_get_attachment_url($post_id);
// Update attachment data
$id = wp_update_post([
'ID' => $post_id,
'post_title' => $new_filename,
'guid' => $new_url // Doesn't seem to work
]);
// Try this to reset the GUID for the attachment. Doesn't seem to actually reset it.
// global $wpdb;
// $result = $wpdb->update($wpdb->posts, ['guid' => $new_url], ['ID' => $post_id]);
// Update all links to old "sizes" files, or create it for new upload.
$metadata = get_post_meta($post_id, '_wp_attachment_metadata', true);
if( empty($metadata) ) {
// New upload.
$data = wp_generate_attachment_metadata($post_id, $new_path);
//update_post_meta($post_id, '_wp_attachment_metadata', $data); // Tried this. Doesn't work.
wp_update_attachment_metadata($post_id, $data); // Also doesn't work
} else {
// Regenerating an existing image
// TODO loop through $metadata and update the filename and resave? Maybe just delete it and regenerate instead?
}
// TODO Update use of the old filename in post_content throughout site
}
到目前为止,这些是我浏览过的有用帖子。
- https://wordpress.stackexchange.com/questions/166943/how-to-rename-an-image-attachment-filename-using-php
- https://wordpress.stackexchange.com/questions/30313/change-attachment-filename
- https://wordpress.stackexchange.com/a/221254/4562
奇怪的是,如果我在这个函数的末尾 die
,那么它就起作用了。所以我怀疑 WP 中的其他内容正在覆盖此附件的 _wp_attachment_metadata
。这就是为什么我怀疑 GUID 是问题所在。其他东西正在通过 GUID
查找附件并找到一个 URL 到一个不再存在的文件(因为我更改了文件名)和 运行 wp_generate_attachment_metadata
在一个坏文件上小路。这是我的预感。
我没有安装任何其他插件。
您的代码不起作用的原因与 GUID 无关。
这是因为,在 WP core 中,函数 wp_update_attachment_metadata() 在媒体上传请求处理结束时以原始文件名调用。钩子 add_attachment 在 wp_insert_attachment() 函数中被调用。
function media_handle_upload( $file_id, $post_id, $post_data = array(), $overrides = array( 'test_form' => false ) ) {
... ...
// Save the data.
$attachment_id = wp_insert_attachment( $attachment, $file, $post_id, true );
if ( ! is_wp_error( $attachment_id ) ) {
// Set a custom header with the attachment_id.
// Used by the browser/client to resume creating image sub-sizes after a PHP fatal error.
if ( ! headers_sent() ) {
header( 'X-WP-Upload-Attachment-ID: ' . $attachment_id );
}
// The image sub-sizes are created during wp_generate_attachment_metadata().
// This is generally slow and may cause timeouts or out of memory errors.
wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) );
}
return $attachment_id;
}
我们可以使用“wp_update_attachment_metadata”过滤器将元数据更改为新文件名。
请检查以下代码。我测试过,它运行良好。
class CustomAttachmentRename {
public $new_filename = 'custom file';
private $new_path;
function __construct () {
add_action("add_attachment", array($this, "rename_attachment"), 10, 1);
}
function rename_attachment($post_id) {
// Get path info of orginal file
$og_path = get_attached_file($post_id);
$path_info = pathinfo($og_path);
// Santize filename
$safe_filename = wp_unique_filename($path_info['dirname'], $this->new_filename);
// Build out path to new file
$this->new_path = $path_info['dirname']. "/" . $safe_filename . "." .$path_info['extension'];
// Rename the file and update it's location in WP
rename($og_path, $this->new_path);
update_attached_file( $post_id, $this->new_path );
// Register filter to update metadata.
add_filter('wp_update_attachment_metadata', array($this, 'custom_update_attachment_metadata'), 10, 2);
}
function custom_update_attachment_metadata($data, $post_id) {
return wp_generate_attachment_metadata($post_id, $this->new_path);
}
}
$customAttachmentRename = new CustomAttachmentRename();
$customAttachmentRename->new_filename = "test image" . time();
我把@chengmin answer 变成了这样一个函数:
/**
* Renames a file. Will also regenerate all the thumbnails that go with the file.
* @SEE
*
* @param string $post_id The WordPress post_id for the attachment
* @param string $new_file_name The filename (without extension) that you want to rename to
*/
function attachment_rename($post_id, $filename) {
// Get path info of orginal file
$og_url = wp_get_attachment_url($post_id);
$og_path = get_attached_file($post_id);
$path_info = pathinfo($og_path);
$og_meta = get_post_meta($post_id, '_wp_attachment_metadata', true);
// Santize filename
$safe_filename = wp_unique_filename($path_info['dirname'], $filename);
// Build out path to new file
$new_path = $path_info['dirname']. "/" . $safe_filename . "." .$path_info['extension'];
// Rename the file in the file system
rename($og_path, $new_path);
// Delete old image sizes if we have them
if( !empty($og_meta) ) {
delete_attachment_files($post_id);
}
// Now save new path to file in WP
update_attached_file( $post_id, $new_path );
// Register filter to update metadata
$new_data = wp_generate_attachment_metadata($post_id, $new_path);
return add_filter('wp_update_attachment_metadata', function($data, $post_id) use ($new_data) {
return $new_data;
}, 10, 2);
}
/**
* Delete all old image files, if they aren't used post_content anywhere.
* The dont-delete check isn't perfect, it will give a lot of false positives (keeping more files than it should), but it's best I could come up with.
* @SEE https://github.com/WordPress/WordPress/blob/f4cda1b62ffca52115e4b04d9d75047060d69e68/wp-includes/post.php#L5983
*
* @param string $post_id The WordPress post_id for the attachment
*/
function delete_attachment_files($post_id) {
$meta = wp_get_attachment_metadata( $post_id );
$backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true );
$file = get_attached_file( $post_id );
$url = wp_get_attachment_url($post_id);
// Remove og image so it doesn't get deleted in wp_delete_attachment_files()
$meta['original_image'] = "";
// Check if image is used in a post somehwere
$url_without_extension = substr($url, 0 , (strrpos($url, ".")));
$args = [
"s" => $url_without_extension,
"posts_per_page" => 1,
"post_type" => "any"
];
$found = get_posts($args);
if( empty($found) ) {
return wp_delete_attachment_files( $post_id, $meta, $backup_sizes, $file );
}
return false;
}