$owner, 'expires' => time() + self::TTL); if (add_option(self::OPTION, $lock, '', 'no')) { return $owner; } $current = get_option(self::OPTION, null); if (!is_array($current) || !isset($current['owner'], $current['expires']) || (int) $current['expires'] <= time()) { if (self::compare_and_delete($current) && add_option(self::OPTION, $lock, '', 'no')) { return $owner; } } unset($owner, $lock, $current); return false; } public static function release($owner) { $current = get_option(self::OPTION, null); if (!is_array($current) || !isset($current['owner']) || !is_string($current['owner']) || !is_string($owner) || !hash_equals($current['owner'], $owner)) { return false; } return self::compare_and_delete($current); } private static function compare_and_delete($expected) { global $wpdb; $serialized = maybe_serialize($expected); $deleted = $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name = %s AND option_value = %s", self::OPTION, $serialized ) ); if (1 === $deleted) { wp_cache_delete(self::OPTION, 'options'); return true; } return false; } }