From 8b13d5deaba7d9bdda251e8181969f09d182e13c Mon Sep 17 00:00:00 2001 From: David Stone Date: Thu, 25 Sep 2025 10:50:15 -0600 Subject: [PATCH 1/6] Fix possible error when option value is '' Somehow (maybe old AS version?) the option value can get set to ''. In this case the code will attempt to insert the option but it will give a duplicate key error. So the lock can never be set until someone manually deletes this option. Now the option will be updated if it's '' so the code can work. --- classes/ActionScheduler_OptionLock.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/classes/ActionScheduler_OptionLock.php b/classes/ActionScheduler_OptionLock.php index 547857a0a..6f9f1cdcb 100644 --- a/classes/ActionScheduler_OptionLock.php +++ b/classes/ActionScheduler_OptionLock.php @@ -32,7 +32,7 @@ public function set( $lock_type ) { $new_lock_value = $this->new_lock_value( $lock_type ); // The lock may not exist yet, or may have been deleted. - if ( empty( $existing_lock_value ) ) { + if ( null === $existing_lock_value ) { return (bool) $wpdb->insert( $wpdb->options, array( @@ -65,7 +65,7 @@ public function set( $lock_type ) { * @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire. */ public function get_expiration( $lock_type ) { - return $this->get_expiration_from( $this->get_existing_lock( $lock_type ) ); + return $this->get_expiration_from( (string) $this->get_existing_lock( $lock_type ) ); } /** @@ -106,13 +106,13 @@ protected function get_key( $lock_type ) { * * @param string $lock_type A string to identify different lock types. * - * @return string + * @return string|null */ private function get_existing_lock( $lock_type ) { global $wpdb; // Now grab the existing lock value, if there is one. - return (string) $wpdb->get_var( + return $wpdb->get_var( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s", $this->get_key( $lock_type ) From 24097197d8114e048e0ea457bef2f81561f95405 Mon Sep 17 00:00:00 2001 From: David Stone Date: Thu, 25 Sep 2025 10:54:58 -0600 Subject: [PATCH 2/6] Avoid type warnings --- classes/ActionScheduler_OptionLock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/ActionScheduler_OptionLock.php b/classes/ActionScheduler_OptionLock.php index 6f9f1cdcb..8a9beb0b8 100644 --- a/classes/ActionScheduler_OptionLock.php +++ b/classes/ActionScheduler_OptionLock.php @@ -43,7 +43,7 @@ public function set( $lock_type ) { ); } - if ( $this->get_expiration_from( $existing_lock_value ) >= time() ) { + if ( $this->get_expiration_from( (string) $existing_lock_value ) >= time() ) { return false; } From ee8f8812fdfc2ab0901da0c6b8c166486639b266 Mon Sep 17 00:00:00 2001 From: David Stone Date: Thu, 25 Sep 2025 11:09:13 -0600 Subject: [PATCH 3/6] remove unnecessary cast --- classes/ActionScheduler_OptionLock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/ActionScheduler_OptionLock.php b/classes/ActionScheduler_OptionLock.php index 8a9beb0b8..d2cbf9b14 100644 --- a/classes/ActionScheduler_OptionLock.php +++ b/classes/ActionScheduler_OptionLock.php @@ -43,7 +43,7 @@ public function set( $lock_type ) { ); } - if ( $this->get_expiration_from( (string) $existing_lock_value ) >= time() ) { + if ( $this->get_expiration_from($existing_lock_value ) >= time() ) { return false; } From 14a54c84b502d27ea845caf85ba22000a6be77a9 Mon Sep 17 00:00:00 2001 From: David Stone Date: Thu, 25 Sep 2025 13:29:45 -0600 Subject: [PATCH 4/6] fix code style --- classes/ActionScheduler_OptionLock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/ActionScheduler_OptionLock.php b/classes/ActionScheduler_OptionLock.php index d2cbf9b14..6f9f1cdcb 100644 --- a/classes/ActionScheduler_OptionLock.php +++ b/classes/ActionScheduler_OptionLock.php @@ -43,7 +43,7 @@ public function set( $lock_type ) { ); } - if ( $this->get_expiration_from($existing_lock_value ) >= time() ) { + if ( $this->get_expiration_from( $existing_lock_value ) >= time() ) { return false; } From 70baa7fb54be533bfa605a793d858f3283f6ad3b Mon Sep 17 00:00:00 2001 From: David Stone Date: Thu, 25 Sep 2025 17:27:30 -0600 Subject: [PATCH 5/6] use get_row which does not return null for '' --- classes/ActionScheduler_OptionLock.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/classes/ActionScheduler_OptionLock.php b/classes/ActionScheduler_OptionLock.php index 6f9f1cdcb..1049a0e1a 100644 --- a/classes/ActionScheduler_OptionLock.php +++ b/classes/ActionScheduler_OptionLock.php @@ -112,12 +112,18 @@ private function get_existing_lock( $lock_type ) { global $wpdb; // Now grab the existing lock value, if there is one. - return $wpdb->get_var( + // get_val() returns null for the empty string ('') so we must use get_row(). + $row = $wpdb->get_row( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s", - $this->get_key( $lock_type ) + $this->get_key($lock_type) ) ); + + if ($row) { + return $row->option_value; + } + return null; } /** From 517f7ae4e0a492ba8755f651361a6db98a36562a Mon Sep 17 00:00:00 2001 From: David Stone Date: Thu, 25 Sep 2025 17:28:31 -0600 Subject: [PATCH 6/6] style change --- classes/ActionScheduler_OptionLock.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/ActionScheduler_OptionLock.php b/classes/ActionScheduler_OptionLock.php index 1049a0e1a..4b8d9750d 100644 --- a/classes/ActionScheduler_OptionLock.php +++ b/classes/ActionScheduler_OptionLock.php @@ -112,11 +112,11 @@ private function get_existing_lock( $lock_type ) { global $wpdb; // Now grab the existing lock value, if there is one. - // get_val() returns null for the empty string ('') so we must use get_row(). + // get_var() returns null for the empty string ('') so we must use get_row(). $row = $wpdb->get_row( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s", - $this->get_key($lock_type) + $this->get_key( $lock_type ) ) );