@@ -302,7 +302,24 @@ private function delete_expired() {
302302 private function delete_all () {
303303 global $ wpdb ;
304304
305- $ count = $ wpdb ->query (
305+ // To ensure proper count values we first delete all transients with a timeout
306+ // and then the remaining transients without a timeout.
307+ $ count = 0 ;
308+
309+ $ deleted = $ wpdb ->query (
310+ $ wpdb ->prepare (
311+ "DELETE a, b FROM {$ wpdb ->options } a, {$ wpdb ->options } b
312+ WHERE a.option_name LIKE %s
313+ AND a.option_name NOT LIKE %s
314+ AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) ) " ,
315+ Utils \esc_like ( '_transient_ ' ) . '% ' ,
316+ Utils \esc_like ( '_transient_timeout_ ' ) . '% '
317+ )
318+ );
319+
320+ $ count += $ deleted / 2 ; // Ignore affected rows for timeouts.
321+
322+ $ count += $ wpdb ->query (
306323 $ wpdb ->prepare (
307324 "DELETE FROM $ wpdb ->options WHERE option_name LIKE %s " ,
308325 Utils \esc_like ( '_transient_ ' ) . '% '
@@ -311,6 +328,19 @@ private function delete_all() {
311328
312329 if ( ! is_multisite () ) {
313330 // Non-Multisite stores site transients in the options table.
331+ $ deleted = $ wpdb ->query (
332+ $ wpdb ->prepare (
333+ "DELETE a, b FROM {$ wpdb ->options } a, {$ wpdb ->options } b
334+ WHERE a.option_name LIKE %s
335+ AND a.option_name NOT LIKE %s
336+ AND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) ) " ,
337+ Utils \esc_like ( '_site_transient_ ' ) . '% ' ,
338+ Utils \esc_like ( '_site_transient_timeout_ ' ) . '% '
339+ )
340+ );
341+
342+ $ count += $ deleted / 2 ; // Ignore affected rows for timeouts.
343+
314344 $ count += $ wpdb ->query (
315345 $ wpdb ->prepare (
316346 "DELETE FROM $ wpdb ->options WHERE option_name LIKE %s " ,
@@ -319,6 +349,19 @@ private function delete_all() {
319349 );
320350 } else {
321351 // Multisite stores site transients in the sitemeta table.
352+ $ deleted = $ wpdb ->query (
353+ $ wpdb ->prepare (
354+ "DELETE a, b FROM {$ wpdb ->sitemeta } a, {$ wpdb ->sitemeta } b
355+ WHERE a.meta_key LIKE %s
356+ AND a.meta_key NOT LIKE %s
357+ AND b.meta_key = CONCAT( '_site_transient_timeout_', SUBSTRING( a.meta_key, 17 ) ) " ,
358+ Utils \esc_like ( '_site_transient_ ' ) . '% ' ,
359+ Utils \esc_like ( '_site_transient_timeout_ ' ) . '% '
360+ )
361+ );
362+
363+ $ count += $ deleted / 2 ; // Ignore affected rows for timeouts.
364+
322365 $ count += $ wpdb ->query (
323366 $ wpdb ->prepare (
324367 "DELETE FROM $ wpdb ->sitemeta WHERE meta_key LIKE %s " ,
@@ -327,9 +370,6 @@ private function delete_all() {
327370 );
328371 }
329372
330- // The above queries delete the transient and the transient timeout if exists
331- // thus some transients may be counted twice.
332-
333373 if ( $ count > 0 ) {
334374 WP_CLI ::success (
335375 sprintf (
0 commit comments