Skip to content

Commit

Permalink
Fix issue with previous main merge
Browse files Browse the repository at this point in the history
  • Loading branch information
alexmigf committed Sep 9, 2024
1 parent 53e7438 commit 8b5c107
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 44 deletions.
130 changes: 105 additions & 25 deletions includes/Semaphore.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@

class Semaphore {

/**
* Prefix for the lock in the WP options table
*
* @var string
*/
protected static $option_prefix = 'wpo_ips_semaphore_lock_';

/**
* Hook name suffix for the cleanup of released locks
*
* @var string
*/
protected static $hook_name_suffix = 'cleanup';

/**
* Name for the lock in the WP options table
*
Expand Down Expand Up @@ -62,11 +76,11 @@ class Semaphore {
* @param array $context - an array of context for the loggers
*/
public function __construct( string $name, int $locked_for = 300, int $retries = 0, array $loggers = array(), array $context = array() ) {
$this->option_name = 'wpo_ips_semaphore_lock_' . $name;
$this->locked_for = apply_filters( 'wpo_ips_semaphore_lock_time', $locked_for > 0 ? $locked_for : 300, $this->option_name );
$this->retries = apply_filters( 'wpo_ips_semaphore_lock_retries', $retries > 0 ? $retries : 0, $this->option_name );
$this->loggers = apply_filters( 'wpo_ips_semaphore_lock_loggers', empty( $loggers ) ? array( wc_get_logger() ) : $loggers, $this->option_name );
$this->context = apply_filters( 'wpo_ips_semaphore_lock_context', empty( $context ) ? array( 'source' => 'wpo-ips-semaphore' ) : $context, $this->option_name );
$this->option_name = self::$option_prefix . $name;
$this->locked_for = apply_filters( self::$option_prefix . 'time', $locked_for > 0 ? $locked_for : 300, $this->option_name );
$this->retries = apply_filters( self::$option_prefix . 'retries', $retries > 0 ? $retries : 0, $this->option_name );
$this->loggers = apply_filters( self::$option_prefix . 'loggers', empty( $loggers ) ? array( wc_get_logger() ) : $loggers, $this->option_name );
$this->context = apply_filters( self::$option_prefix . 'context', empty( $context ) ? array( 'source' => 'wpo-ips-semaphore' ) : $context, $this->option_name );
}

/**
Expand Down Expand Up @@ -247,43 +261,109 @@ public function get_loggers(): array {
}

/**
* Cleanup expired locks from the database
* Cleanup released locks from the database
*
* @return void
*/
public static function cleanup_expired_locks(): void {
public static function cleanup_released_locks(): void {
global $wpdb;

// Cleanup legacy expired locks
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE 'updraft_lock_%'" );

// Cleanup expired locks
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE 'wpo_ips_semaphore_lock_%'" );
$wpdb->query(
$wpdb->prepare(
"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s AND option_value = '0'",
$wpdb->esc_like( self::$option_prefix ) . '%'
)
);
}

/**
* Count the number of expired locks in the database
* Count the number of released locks in the database
*
* @return int - the number of expired locks
* @return int - the number of released locks
*/
public static function count_expired_locks(): int {
public static function count_released_locks(): int {
global $wpdb;

$count = 0;

// Count legacy expired locks
$count += (int) $wpdb->get_var(
"SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name LIKE 'updraft_lock_%'"
);

// Count expired locks
$count += (int) $wpdb->get_var(
"SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name LIKE 'wpo_ips_semaphore_lock_%'"
$count = (int) $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name LIKE %s AND option_value = '0'",
$wpdb->esc_like( self::$option_prefix ) . '%'
)
);

return $count;
}

/**
* Get the hook name for the cleanup of released locks
*
* @return string - the hook name
*/
private static function get_cleanup_hook_name(): string {
return self::$option_prefix . self::$hook_name_suffix;
}

/**
* Check if the cleanup of released locks is scheduled
*
* @return bool - whether the cleanup is scheduled
*/
public static function is_cleanup_scheduled(): bool {
return function_exists( 'as_next_scheduled_action' ) && as_next_scheduled_action( self::get_cleanup_hook_name() );
}

/**
* Get the next scheduled cleanup of released locks
*
* @return object|null - the next scheduled cleanup action or null
*/
public static function get_cleanup_action(): ?object {
$action = null;

if ( self::is_cleanup_scheduled() ) {
$args = array(
'hook' => self::get_cleanup_hook_name(),
'status' => \ActionScheduler_Store::STATUS_PENDING,
'orderby' => 'timestamp',
'order' => 'ASC',
'limit' => 1,
);

$actions = as_get_scheduled_actions( $args );

if ( ! empty( $actions ) && 1 === count( $actions ) ) {
$action = reset( $actions );
}
}

return $action;
}

/**
* Schedule the cleanup of released locks
*
* @return void
*/
public static function schedule_semaphore_cleanup(): void {
if ( ! self::is_cleanup_scheduled() ) {
$interval = apply_filters( self::get_cleanup_hook_name() . '_interval', 30 * DAY_IN_SECONDS ); // default: every 30 days
as_schedule_recurring_action( time(), $interval, self::get_cleanup_hook_name() );
}
}

/**
* Initialize the cleanup of released locks
*
* @return void
*/
public static function init_cleanup(): void {
// Schedule cleanup of released locks
self::schedule_semaphore_cleanup();

// Cleanup released locks
add_action( self::get_cleanup_hook_name(), array( __CLASS__, 'cleanup_released_locks' ) );
}

}

endif; // class_exists
8 changes: 4 additions & 4 deletions includes/Settings/SettingsDebug.php
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,11 @@ private function clear_tmp( $data ) {
exit;
}
}

private function clear_semaphore_expired_locks( $data ) {
\WPO\WC\PDF_Invoices\Updraft_Semaphore_3_0::cleanup_expired_locks();

$message = esc_html__( 'Semaphore expired locks cleaned up!', 'woocommerce-pdf-invoices-packing-slips' );
private function clear_released_semaphore_locks( $data ) {
\WPO\WC\PDF_Invoices\Updraft_Semaphore_3_0::cleanup_released_locks();

$message = esc_html__( 'Released semaphore locks have been cleaned up!', 'woocommerce-pdf-invoices-packing-slips' );
wcpdf_log_error( $message, 'info' );
wp_send_json_success( compact( 'message' ) );
}
Expand Down
48 changes: 33 additions & 15 deletions views/advanced-tools.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,42 +57,60 @@
</form>
</div>
<!-- /clear_tmp -->
<!-- clear_semaphore_expired_locks -->
<!-- clear_released_semaphore_locks -->
<div class="tool">
<h4><?php _e( 'Remove Semaphore expired locks', 'woocommerce-pdf-invoices-packing-slips' ); ?></h4>
<p><?php _e( 'Clean up the expired locks from the database.', 'woocommerce-pdf-invoices-packing-slips' ); ?></p>
<form method="post" id="clear_semaphore_expired_locks">
<input type="hidden" name="debug_tool" value="clear_semaphore_expired_locks">
<input type="submit" class="button button-secondary submit" value="<?php _e( 'Remove expired locks', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
<h4><?php _e( 'Remove released semaphore locks', 'woocommerce-pdf-invoices-packing-slips' ); ?></h4>
<p><?php _e( 'Clean up the released semaphore locks from the database.', 'woocommerce-pdf-invoices-packing-slips' ); ?></p>
<form method="post" id="clear_released_semaphore_locks">
<input type="hidden" name="debug_tool" value="clear_released_semaphore_locks">
<input type="submit" class="button button-secondary submit" value="<?php _e( 'Remove released locks', 'woocommerce-pdf-invoices-packing-slips' ); ?>">
<fieldset>
<div class="notice inline" style="display:none;"><p></p></div>
</fieldset>
</form>
<?php $semaphore_expired_locks = \WPO\WC\PDF_Invoices\Updraft_Semaphore_3_0::count_expired_locks(); ?>
<?php if ( $semaphore_expired_locks > 0 ) : ?>
<?php $released_semaphore_locks = \WPO\WC\PDF_Invoices\Updraft_Semaphore_3_0::count_released_locks(); ?>
<?php if ( $released_semaphore_locks > 0 ) : ?>
<div class="notice notice-warning inline">
<p>
<?php
printf(
/* translators: 1: number of expired locks */
/* translators: 1: number of released semaphore locks */
_n(
'There is %s expired lock in the database.',
'There are %s expired locks in the database.',
$semaphore_expired_locks,
'There is %s released semaphore lock in the database.',
'There are %s released semaphore locks in the database.',
$released_semaphore_locks,
'woocommerce-pdf-invoices-packing-slips'
),
'<strong>' . $semaphore_expired_locks . '</strong>'
'<strong>' . $released_semaphore_locks . '</strong>'
);
?>
</p>
</div>
<?php else : ?>
<div class="notice notice-success inline">
<p><?php _e( 'There are no expired locks in the database.', 'woocommerce-pdf-invoices-packing-slips' ); ?></p>
<p><?php _e( 'There are no released semaphore locks in the database.', 'woocommerce-pdf-invoices-packing-slips' ); ?></p>
</div>
<?php endif; ?>
<?php $cleanup_action = \WPO\WC\PDF_Invoices\Updraft_Semaphore_3_0::get_cleanup_action(); ?>
<?php if ( $cleanup_action ) : ?>
<div class="notice notice-info inline">
<p>
<?php
$schedule = $cleanup_action->get_schedule();
$current_time = new \DateTime();
$next_run_date = $schedule->get_next( $current_time );

printf(
/* translators: 1: next run date */
__( 'The next cleanup action is scheduled to run on %s.', 'woocommerce-pdf-invoices-packing-slips' ),
'<strong>' . $next_run_date->format( 'Y-m-d H:i:s' ) . '</strong>'
);
?>
</p>
</div>
<?php endif; ?>
</div>
<!-- /clear_semaphore_expired_locks -->
<!-- /clear_released_semaphore_locks -->
<!-- run_wizard -->
<div class="tool">
<h4><?php _e( 'Run the Setup Wizard', 'woocommerce-pdf-invoices-packing-slips' ); ?></h4>
Expand Down
1 change: 1 addition & 0 deletions woocommerce-pdf-invoices-packingslips.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public function __construct() {
add_action( 'admin_notices', array( $this, 'mailpoet_mta_detected' ) );
add_action( 'admin_notices', array( $this, 'rtl_detected' ) );
add_action( 'admin_notices', array( $this, 'legacy_addon_notices' ) );
add_action( 'init', array( '\\WPO\\WC\\PDF_Invoices\\Updraft_Semaphore_3_0', 'init_cleanup' ), 999 ); // wait AS to initialize

// deactivate legacy extensions if activated
register_activation_hook( __FILE__, array( $this, 'deactivate_legacy_addons' ) );
Expand Down

0 comments on commit 8b5c107

Please sign in to comment.