PluginProbe
WooCommerce / 11.1.0-beta.1
WooCommerce v11.1.0-beta.1
11.1.0 11.1.0-rc.2 11.1.0-rc.1 11.1.0-beta.2 11.1.0-beta.1 11.0.1 11.0.0 11.0.0-rc.3 11.0.0-rc.2 11.0.0-rc.1 11.0.0-beta.2 11.0.0-beta.1 10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 All 648 releases
woocommerce / packages / action-scheduler / classes / ActionScheduler_OptionLock.php
ActionScheduler_OptionLock.php
137 lines 4.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Provide a way to set simple transient locks to block behaviour
5 * for up-to a given duration.
6 *
7 * Class ActionScheduler_OptionLock
8 *
9 * @since 3.0.0
10 */
11 class ActionScheduler_OptionLock extends ActionScheduler_Lock {
12
13 /**
14 * Set a lock using options for a given amount of time (60 seconds by default).
15 *
16 * Using an autoloaded option avoids running database queries or other resource intensive tasks
17 * on frequently triggered hooks, like 'init' or 'shutdown'.
18 *
19 * For example, ActionScheduler_QueueRunner->maybe_dispatch_async_request() uses a lock to avoid
20 * calling ActionScheduler_QueueRunner->has_maximum_concurrent_batches() every time the 'shutdown',
21 * hook is triggered, because that method calls ActionScheduler_QueueRunner->store->get_claim_count()
22 * to find the current number of claims in the database.
23 *
24 * @param string $lock_type A string to identify different lock types.
25 * @bool True if lock value has changed, false if not or if set failed.
26 */
27 public function set( $lock_type ) {
28 global $wpdb;
29
30 $lock_key = $this->get_key( $lock_type );
31 $existing_lock_value = $this->get_existing_lock( $lock_type );
32 $new_lock_value = $this->new_lock_value( $lock_type );
33
34 // The lock may not exist yet, or may have been deleted.
35 if ( empty( $existing_lock_value ) ) {
36 return (bool) $wpdb->insert(
37 $wpdb->options,
38 array(
39 'option_name' => $lock_key,
40 'option_value' => $new_lock_value,
41 'autoload' => 'no',
42 )
43 );
44 }
45
46 if ( $this->get_expiration_from( $existing_lock_value ) >= time() ) {
47 return false;
48 }
49
50 // Otherwise, try to obtain the lock.
51 return (bool) $wpdb->update(
52 $wpdb->options,
53 array( 'option_value' => $new_lock_value ),
54 array(
55 'option_name' => $lock_key,
56 'option_value' => $existing_lock_value,
57 )
58 );
59 }
60
61 /**
62 * If a lock is set, return the timestamp it was set to expiry.
63 *
64 * @param string $lock_type A string to identify different lock types.
65 * @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire.
66 */
67 public function get_expiration( $lock_type ) {
68 return $this->get_expiration_from( $this->get_existing_lock( $lock_type ) );
69 }
70
71 /**
72 * Given the lock string, derives the lock expiration timestamp (or false if it cannot be determined).
73 *
74 * @param string $lock_value String containing a timestamp, or pipe-separated combination of unique value and timestamp.
75 *
76 * @return false|int
77 */
78 private function get_expiration_from( $lock_value ) {
79 $lock_string = explode( '|', $lock_value );
80
81 // Old style lock?
82 if ( count( $lock_string ) === 1 && is_numeric( $lock_string[0] ) ) {
83 return (int) $lock_string[0];
84 }
85
86 // New style lock?
87 if ( count( $lock_string ) === 2 && is_numeric( $lock_string[1] ) ) {
88 return (int) $lock_string[1];
89 }
90
91 return false;
92 }
93
94 /**
95 * Get the key to use for storing the lock in the transient
96 *
97 * @param string $lock_type A string to identify different lock types.
98 * @return string
99 */
100 protected function get_key( $lock_type ) {
101 return sprintf( 'action_scheduler_lock_%s', $lock_type );
102 }
103
104 /**
105 * Supplies the existing lock value, or an empty string if not set.
106 *
107 * @param string $lock_type A string to identify different lock types.
108 *
109 * @return string
110 */
111 private function get_existing_lock( $lock_type ) {
112 global $wpdb;
113
114 // Now grab the existing lock value, if there is one.
115 return (string) $wpdb->get_var(
116 $wpdb->prepare(
117 "SELECT option_value FROM $wpdb->options WHERE option_name = %s",
118 $this->get_key( $lock_type )
119 )
120 );
121 }
122
123 /**
124 * Supplies a lock value consisting of a unique value and the current timestamp, which are separated by a pipe
125 * character.
126 *
127 * Example: (string) "649de012e6b262.09774912|1688068114"
128 *
129 * @param string $lock_type A string to identify different lock types.
130 *
131 * @return string
132 */
133 private function new_lock_value( $lock_type ) {
134 return uniqid( '', true ) . '|' . ( time() + $this->get_duration( $lock_type ) );
135 }
136 }
137