Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Renaming an image leaves the old URL in comments and term descriptions, with "Unknown column 'ID'" database errors

未关闭 适合新手
#1,199 3 条评论 0 个 reaction 已指派 1 人 在 GitHub 查看

维护者通常 1 天内回复

@girishpanchal30 已经在做这个了。

开始于 2026年10月29日。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
74/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
mysql, php, wordpress
领域
database

调研方向

从 inc/media_rename/attachment_db_renamer.php 开始:sql_handle_column()(约 L249-280)构建 WHERE ID,而 php_handle_column()(L364-375)已经基于 $primary_keys 构建了 where 子句。将 $primary_keys 传递下去,仅在 $wpdb->update() 成功时才递增 $count,并将跳过列表与带前缀的表名进行比较。完成的标准是:重命名一张图片时能改写 wp_comments.comment_content 和 wp_term_taxonomy.description,且 debug.log 中没有 Unknown column 'ID' 错误。

由索引模型根据 Issue 内容生成。

描述

bug
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), key comment_ID
  • wp_term_taxonomy.description (category, tag and product category descriptions), key term_taxonomy_id. $skip_tables lists term_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
  1. On a test site with Optimole 4.2.17 active (no Optimole account is needed for rename), add define( 'WP_DEBUG', true ); and define( 'WP_DEBUG_LOG', true ); to wp-config.php.
  2. Import an image and get its URL:
    ID=$(wp media import photo.jpg --porcelain); URL=$(wp eval "echo wp_get_original_image_url($ID);")
  3. 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\">"
  4. In wp-admin, go to Media > Library (list view), hover the image and click "Replace or Rename". Type renamed in "Rename attached file" and click Rename.
  5. Check the three references:
    • wp post list --title=Control --field=post_content shows renamed.jpg (correct).
    • wp term get category gallery --by=slug --field=description still shows photo.jpg.
    • wp comment list --fields=comment_ID,comment_content still shows photo.jpg.
  6. wp-content/debug.log has 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 master today 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.

主要语言
PHP
星标
74
派生
14
平均合并
1 天 21 小时
30 天内合并 PR
30

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

Codeinwp/optimole-wp 的其他 Issue

查看 Codeinwp/optimole-wp 的全部 Issue

相似的 Issue

更多 PHP Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。