Renaming an image leaves the old URL in comments and term descriptions, with "Unknown column 'ID'" database errors
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 74/100
Direzione di ricerca
Inizia da inc/media_rename/attachment_db_renamer.php: sql_handle_column() (intorno a L249-280) costruisce WHERE ID, mentre php_handle_column() (L364-375) costruisce già la clausola where da $primary_keys. Fai passare $primary_keys attraverso la funzione, incrementa $count solo quando $wpdb->update() ha successo e confronta la lista di esclusione con i nomi delle tabelle con prefisso. Il lavoro è completo quando rinominare un'immagine riscrive wp_comments.comment_content e wp_term_taxonomy.description senza errori Unknown column 'ID' in debug.log.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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.
- Lingua principale
- PHP
- Stelle
- 74
- Fork
- 14
- Merge medio
- 1g 23h
- PR unite (30g)
- 31
Preparare l'ambiente
- Include un Dockerfile o un file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di Codeinwp/optimole-wp
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
Codeinwp/optimole-wp#1216 ·
I maintainer di solito rispondono entro 1 giorno
-
Page profiler endpoint fatals on PHP 8 when the request has no `b` (background selectors) fieldForse già presa @girishpanchal30 l’ha presa 2 giorni fa. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
Codeinwp/optimole-wp#1204 · 4 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
Background image with a gradient is not lazy-loaded on WordPress 7.1 (Quote, Pullquote, Verse, Post Content, Accordion)Forse già presa @girishpanchal30 l’ha presa 2 giorni fa. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
Codeinwp/optimole-wp#1203 · 3 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
Page profiler never treats the detected LCP image as LCP, so it gets no fetchpriority="high" (stored ID is a string, compared with === to an int)Forse già presa @girishpanchal30 l’ha presa 2 giorni fa. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
Codeinwp/optimole-wp#1202 · 3 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
Account sign-up fatals when the Optimole API returns an empty or non-JSON responseForse già presa @girishpanchal30 l’ha presa 2 giorni fa. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
Codeinwp/optimole-wp#1200 · 3 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di Codeinwp/optimole-wp
Issue simili
-
bug webbackend
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
DOMjudge/domjudge#3886 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
opensourcepos/opensourcepos#4794 ·
I maintainer di solito rispondono entro 1 giorno
-
repo:cms
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
craftcms/cms#20235 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
I maintainer di solito rispondono entro 1 giorno
-
REST API: decimal ids like 1.5 give 500 on folder and report endpointsForse già presa @console-log-life l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
I maintainer di solito rispondono entro 3 giorni