Renaming an image leaves the old URL in comments and term descriptions, with "Unknown column 'ID'" database errors
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 74/100
Hướng nghiên cứu
Bắt đầu từ inc/media_rename/attachment_db_renamer.php: sql_handle_column() (khoảng L249-280) đang tạo WHERE ID, trong khi php_handle_column() (L364-375) đã tạo mệnh đề where từ $primary_keys. Truyền $primary_keys qua hàm, chỉ tăng $count khi $wpdb->update() thành công, và so sánh danh sách bỏ qua với tên bảng có tiền tố. Hoàn thành khi đổi tên một ảnh ghi lại wp_comments.comment_content và wp_term_taxonomy.description mà không có lỗi Unknown column 'ID' trong debug.log.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Description
When you rename an image with "Rename attached file", Optimole searches the database for the old URL and rewrites it. For columns with no serialized data it uses sql_handle_column(), which always runs the update as WHERE ID = <value>. Of the core single-site tables, only wp_posts and wp_users have an ID column. On the others the UPDATE fails with Unknown column 'ID' in 'where clause' and the row keeps the old URL. The old file has already been moved, so those images break.
Tables this affects on a normal site:
wp_comments(comment_content,comment_author_url), keycomment_IDwp_term_taxonomy.description(category, tag and product category descriptions), keyterm_taxonomy_id.$skip_tablesliststerm_taxonomy, but it is compared with prefixed names, so it never matches.wp_termmeta,wp_commentmeta,wp_links, when none of that column's rows are serialized
On any real site, wp_postmeta, wp_options and wp_usermeta contain serialized rows (attachment metadata, roles, capabilities), so their value columns go to php_handle_column() instead and never reach this UPDATE.
replace() also counts these failed updates as replacements, because ++$count runs even when $wpdb->update() returns false.
Expected: every reference to the old file is rewritten, using each table's own primary key, and no database errors are logged.
Step-by-step reproduction instructions
- On a test site with Optimole 4.2.17 active (no Optimole account is needed for rename), add
define( 'WP_DEBUG', true );anddefine( 'WP_DEBUG_LOG', true );towp-config.php. - Import an image and get its URL:
ID=$(wp media import photo.jpg --porcelain); URL=$(wp eval "echo wp_get_original_image_url($ID);") - Add three references to it:
wp post create --post_status=publish --post_title=Control --post_content="<img src=\"$URL\">"wp term create category Gallery --description="<img src=\"$URL\">"wp comment create --comment_post_ID=1 --comment_content="<img src=\"$URL\">"
- In wp-admin, go to Media > Library (list view), hover the image and click "Replace or Rename". Type
renamedin "Rename attached file" and click Rename. - Check the three references:
wp post list --title=Control --field=post_contentshowsrenamed.jpg(correct).wp term get category gallery --by=slug --field=descriptionstill showsphoto.jpg.wp comment list --fields=comment_ID,comment_contentstill showsphoto.jpg.
wp-content/debug.loghas one error for each failed table, for example:
WordPress database error Unknown column 'ID' in 'where clause' for query UPDATE `wp_comments` SET `comment_content` = '<img src=\"http://example.test/wp-content/uploads/2026/10/renamed.jpg\">...' WHERE `ID` = '7'
I have not run steps 1 to 6 on a live site. I ran the 4.2.17 Optml_Attachment_Db_Renamer class against WordPress core table definitions on MySQL 9.6. A minimal $wpdb built the UPDATE the same way wpdb::update() does. Output:
replace() returned: 4
WordPress database error Unknown column 'ID' in 'where clause' for query UPDATE `wp_comments` ... WHERE `ID` = '7'
WordPress database error Unknown column 'ID' in 'where clause' for query UPDATE `wp_term_taxonomy` ... WHERE `ID` = '3'
WordPress database error Unknown column 'ID' in 'where clause' for query UPDATE `wp_termmeta` ... WHERE `ID` = '1'
wp_posts.post_content renamed
wp_comments.comment_content STILL OLD URL
wp_term_taxonomy.description STILL OLD URL
wp_termmeta.meta_value STILL OLD URL
Screenshots, screen recording, code snippet or Help Scout ticket
Columns with no serialized rows are sent to sql_handle_column(), and the table's primary keys are not passed in, https://github.com/Codeinwp/optimole-wp/blob/v4.2.17/inc/media_rename/attachment_db_renamer.php#L177-L183
The ID is the value of the first field whose name contains "id" (comment_ID, term_taxonomy_id, meta_id...), but the WHERE column is always ID, https://github.com/Codeinwp/optimole-wp/blob/v4.2.17/inc/media_rename/attachment_db_renamer.php#L249-L280
$id_field = $row->ID ?? $row->id ?? null;
// ...falls back to the first field containing "id"
$wpdb->update(
$table,
[ $column => $new_content ],
[ 'ID' => $id_field ]
);
++$count;
php_handle_column() already builds the WHERE clause from $primary_keys, https://github.com/Codeinwp/optimole-wp/blob/v4.2.17/inc/media_rename/attachment_db_renamer.php#L364-L375. Passing $primary_keys to sql_handle_column() and doing the same there would likely fix it. Only counting rows where update() succeeds would fix the count.
The skip list never matches because wpdb::tables() returns prefixed names, https://github.com/Codeinwp/optimole-wp/blob/v4.2.17/inc/media_rename/attachment_db_renamer.php#L20 and https://github.com/Codeinwp/optimole-wp/blob/v4.2.17/inc/media_rename/attachment_db_renamer.php#L67-L70 (core: https://github.com/WordPress/WordPress/blob/7.1.3/wp-includes/class-wpdb.php#L1159-L1166).
Core keys: comment_ID https://github.com/WordPress/WordPress/blob/7.1.3/wp-admin/includes/schema.php#L101-L117, term_taxonomy_id https://github.com/WordPress/WordPress/blob/7.1.3/wp-admin/includes/schema.php#L74-L81, meta_id https://github.com/WordPress/WordPress/blob/7.1.3/wp-admin/includes/schema.php#L56-L61. wpdb::update() writes the $where keys into the query as given, https://github.com/WordPress/WordPress/blob/7.1.3/wp-includes/class-wpdb.php#L2706-L2722, and logs the failure with error_log(), https://github.com/WordPress/WordPress/blob/7.1.3/wp-includes/class-wpdb.php#L1815-L1823.
Environment info
- Optimole 4.2.17. This code is the same on
mastertoday and has not changed since 4.0.0. - WordPress 6.2 to 7.1 (the core table keys are the same in all of them), any MySQL or MariaDB version
- PHP 7.4 and later
Is the issue you are reporting a regression
No. The same [ 'ID' => $id_field ] update was already in 4.0.0, when rename was added (#903).
Found while writing the WordPress compatibility checks for Optimole.
- Ngôn ngữ chính
- PHP
- Star
- 74
- Fork
- 14
- Merge trung bình
- 1 ngày 23 giờ
- Pull request đã merge (30 ngày)
- 28
Chuẩn bị môi trường
- Có Dockerfile hoặc tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của Codeinwp/optimole-wp
-
Page profiler endpoint fatals on PHP 8 when the request has no `b` (background selectors) fieldĐang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
Codeinwp/optimole-wp#1204 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Codeinwp/optimole-wp#1203 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
Codeinwp/optimole-wp#1202 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
Codeinwp/optimole-wp#1200 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Media rename and video block break on WordPress below 6.2, although the plugin says it requires 5.5Có thể đã có người làm @girishpanchal30 đã nhận hôm nay. Đang mởbug
Codeinwp/optimole-wp#1201 · 1 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của Codeinwp/optimole-wp
Issue tương tự
-
Impact: Medium Level: Easy Type: Bug Value: Users
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 88/100
vigetlabs/wordpress-site-starter#315 ·
Maintainer thường phản hồi trong vòng 15 ngày
-
PHP 8.6: bundled guzzlehttp/promises loads class `Is` → "Using "is" as a class name is deprecated"Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 67/100
google/site-kit-wp#14004 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
jwage/phpamqplib-messenger#159 ·
-
facilities.uiowa.edu needs grooming
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
Maintainer thường phản hồi trong vòng 1 ngày