PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 2.8.23.4
Pods – Custom Content Types and Fields v2.8.23.4
2.7.31.4 2.8.23.5 2.9.19.5 3.0.10.5 3.1.4.3 3.2.8.4 3.3.9.2 2.8.23.4 2.9.19.4 3.0.10.4 3.1.4.2 3.2.8.3 3.3.9.1 trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 3.2.5 3.2.6 3.2.7 3.2.7.1 3.2.8 3.2.8.1 3.2.8.2 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9
pods / tribe-common / src / Tribe / Feature_Detection.php
pods / tribe-common / src / Tribe Last commit date
Admin 2 weeks ago Ajax 2 weeks ago Asset 2 weeks ago Context 2 weeks ago Customizer 2 weeks ago Debug_Bar 2 weeks ago Dialog 2 weeks ago Documentation 2 weeks ago Duplicate 2 weeks ago Editor 2 weeks ago Image 2 weeks ago JSON_LD 2 weeks ago Languages 2 weeks ago Log 2 weeks ago Meta 2 weeks ago Models 2 weeks ago PUE 2 weeks ago Process 2 weeks ago Promoter 2 weeks ago REST 2 weeks ago Repository 2 weeks ago Service_Providers 2 weeks ago Shortcode 2 weeks ago Support 2 weeks ago Tabbed_View 2 weeks ago Tooltip 2 weeks ago Traits 2 weeks ago Utils 2 weeks ago Validator 2 weeks ago Widget 2 weeks ago Abstract_Deactivation.php 2 weeks ago Abstract_Plugin_Register.php 2 weeks ago App_Shop.php 2 weeks ago Assets.php 2 weeks ago Assets_Pipeline.php 2 weeks ago Autoloader.php 2 weeks ago Cache.php 2 weeks ago Cache_Listener.php 2 weeks ago Changelog_Reader.php 2 weeks ago Container.php 2 weeks ago Context.php 2 weeks ago Cost_Utils.php 2 weeks ago Credits.php 2 weeks ago Customizer.php 2 weeks ago DB_Lock.php 2 weeks ago Data.php 2 weeks ago Date_Utils.php 2 weeks ago Db.php 2 weeks ago Debug.php 2 weeks ago Dependency.php 2 weeks ago Deprecation.php 2 weeks ago Editor.php 2 weeks ago Error.php 2 weeks ago Exception.php 2 weeks ago Extension.php 2 weeks ago Extension_Loader.php 2 weeks ago Feature_Detection.php 2 weeks ago Field.php 2 weeks ago Field_Conditional.php 2 weeks ago Freemius.php 2 weeks ago Log.php 2 weeks ago Main.php 2 weeks ago Notices.php 2 weeks ago Plugin_Meta_Links.php 2 weeks ago Plugins.php 2 weeks ago Plugins_API.php 2 weeks ago Post_History.php 2 weeks ago Post_Transient.php 2 weeks ago Promise.php 2 weeks ago Repository.php 2 weeks ago Rewrite.php 2 weeks ago Settings.php 2 weeks ago Settings_Manager.php 2 weeks ago Settings_Tab.php 2 weeks ago Simple_Table.php 2 weeks ago Support.php 2 weeks ago Tabbed_View.php 2 weeks ago Template.php 2 weeks ago Template_Factory.php 2 weeks ago Template_Part_Cache.php 2 weeks ago Templates.php 2 weeks ago Terms.php 2 weeks ago Timezones.php 2 weeks ago Tracker.php 2 weeks ago Updater.php 2 weeks ago Validate.php 2 weeks ago View_Helpers.php 2 weeks ago
Feature_Detection.php
259 lines
1 <?php
2 /**
3 * An abstraction layer to handle feature detection queries the plugin components
4 * might need.
5 *
6 * @since 4.7.23
7 */
8
9 use Tribe__Utils__Array as Arr;
10
11 /**
12 * Class Tribe__Feature_Detection
13 *
14 * @since 4.7.23
15 */
16 class Tribe__Feature_Detection {
17
18 /**
19 * The name of the transient storing the support check results.
20 *
21 * @var string
22 */
23 public static $transient = 'tribe_feature_detection';
24
25 /**
26 * A set of example byte sizes of result sets.
27 *
28 * @since 4.10.2
29 *
30 * @var array
31 */
32 public static $example_size = [
33 'post_result' => 6000,
34 ];
35
36 /**
37 * The name of the option that will be used to indicate a feature detection is running.
38 *
39 * @var string
40 */
41 protected $lock_option_name;
42
43 /**
44 * Checks whether async, AJAX-based, background processing is supported or not.
45 *
46 * To avoid making this costly check on each load the result of this check is cached
47 * in the `tribe_feature_detection` transient, under the `supports_async_process` key.
48 *
49 * @since 4.7.23
50 *
51 * @param bool $force Whether to use the cache value, if available, or force the check
52 * to be made again.
53 *
54 * @return bool Whether async, AJAX-based, background processing is supported or not.
55 */
56 public function supports_async_process( $force = false ) {
57 /**
58 * Filters whether async, AJAX-based, processing is supported or not.
59 *
60 * Returning a non `null` value here will make this method bail and
61 * return the filtered value immediately.
62 *
63 * @since 4.7.23
64 *
65 * @param bool $supports_async_process Whether async, AJAX-based, processing is supported or not.
66 * @param bool $force Whether the check is forcing the cached value to be refreshed
67 * or not.
68 */
69 $supports_async_process = apply_filters( 'tribe_supports_async_process', null, $force );
70 if ( null !== $supports_async_process ) {
71 return (bool) $supports_async_process;
72 }
73
74 $cached = get_transient( self::$transient );
75
76 $this->lock_option_name = 'tribe_feature_support_check_lock';
77 if (
78 $force
79 || false === $cached
80 || ( is_array( $cached ) && ! isset( $cached['supports_async_process'] ) )
81 ) {
82 if ( $this->is_locked() ) {
83 // We're already running this check, bail and return the safe option for the time being.
84 return false;
85 }
86
87 // Let's avoid race conditions by running two or more checks at the same time.
88 $this->lock();
89
90 // Log that we're checking for AJAX-based async process support using the tester.
91 tribe( 'logger' )->log( 'Checking for AJAX-based async processing support triggering a test request.', Tribe__Log::DEBUG );
92
93 /*
94 * Build and dispatch the tester: if it works a transient should be set.
95 */
96 $tester = new Tribe__Process__Tester();
97 tribe( 'logger' )->log( 'Dispatching AJAX-based async processing support test request.', Tribe__Log::DEBUG );
98 $tester->dispatch();
99
100 $wait_up_to = 10;
101 $start = time();
102 $supports_async_process = false;
103 $transient_name = Tribe__Process__Tester::TRANSIENT_NAME;
104
105 while ( time() <= $start + $wait_up_to ) {
106 // We want to force a refetch from the database on each check.
107 wp_cache_delete( $transient_name, 'transient' );
108 $supports_async_process = (bool) get_transient( $transient_name );
109
110 if ( $supports_async_process ) {
111 break;
112 }
113 sleep( $wait_up_to / 5 );
114 }
115
116 // Remove it not to spoof future checks.
117 delete_transient( $transient_name );
118
119 $this->unlock();
120
121 $cached['supports_async_process'] = $supports_async_process;
122
123 if ( $supports_async_process ) {
124 tribe( 'logger' )->log( 'AJAX-based async processing is supported.', Tribe__Log::DEBUG );
125 } else {
126 tribe( 'logger' )->log( 'AJAX-based async processing is not supported; background processing will rely on WP Cron.', Tribe__Log::DEBUG );
127 }
128
129 set_transient( self::$transient, $cached, WEEK_IN_SECONDS );
130 }
131
132 return $cached['supports_async_process'];
133 }
134
135 /**
136 * Sets the lock option to `1` to indicate a feature detection is running.
137 *
138 * @since 4.8.1
139 */
140 protected function lock() {
141 update_option( $this->lock_option_name, '1' );
142 }
143
144 /**
145 * Deletes the lock option to indicate the current feature detection process is done.
146 *
147 * @since 4.8.1
148 */
149 protected function unlock() {
150 delete_option( $this->lock_option_name );
151 }
152
153 /**
154 * Checks whether a feature detection lock is currently in place or not.
155 *
156 * @since 4.8.1
157 *
158 * @return bool Whether a feature detection lock is currently in place or not.
159 */
160 protected function is_locked() {
161 $lock_option = get_option( $this->lock_option_name );
162
163 return ! empty( $lock_option );
164 }
165
166 /**
167 * Returns the value of the `max_allowed_packet` MYSQL variable, if set, or a default value.
168 *
169 * @since 4.10.2
170 *
171 * @return int The byte size of the `max_allowed_packet` MYSQL variable.
172 */
173 public function get_mysql_max_packet_size() {
174 /**
175 * Filters the value of the `max_allowed_packet` variable before it's read from the database.
176 *
177 * If the value returned from this filter is not `null`, then it will be assumed to be the value.
178 *
179 * @since 4.10.2
180 *
181 * @param int $mysql_max_packet_size The value of the `max_allowed_packet` variable, initially `null`.
182 */
183 $mysql_max_packet_size = apply_filters( 'tribe_max_allowed_packet_size', null );
184
185 if ( null !== $mysql_max_packet_size ) {
186 return absint( $mysql_max_packet_size );
187 }
188
189 /** @var Tribe__Cache $cache */
190 $cache = tribe( 'cache' );
191
192 $cached = $cache->get( 'max_allowed_packet' );
193
194 if ( false !== $cached ) {
195 return $cached;
196 }
197
198 global $wpdb;
199 $mysql_max_packet_size = $wpdb->get_var( "SHOW VARIABLES LIKE 'max_allowed_packet'", 1 );
200 // At min set it to 2 MBs.
201 $mysql_max_packet_size = absint( max( absint( $mysql_max_packet_size ), 2097152 ) );
202
203 $cache->set( 'max_allowed_packet', $mysql_max_packet_size, WEEK_IN_SECONDS );
204
205 return $mysql_max_packet_size;
206 }
207
208 /**
209 * Returns the suggested SQL LIMIT value, based on the `max_allowed_packet` size and example string length.
210 *
211 * This is useful to size "reasonable" LIMITs when dealing with either very long queries or potentially long
212 * result sets.
213 *
214 * @since 4.10.2
215 *
216 * @param string $example_string The example string.
217 *
218 * @return int The suggested LIMIT value.
219 */
220 public function mysql_limit_for_string( $example_string ) {
221 $byte_size = function_exists( 'mb_strlen' )
222 ? mb_strlen( $example_string )
223 : strlen( $example_string );
224
225 return $this->mysql_limit_for_size( $byte_size );
226 }
227
228 /**
229 * Returns the SQL LIMIT for a byte size, in relation to the `max_allowed_packet` value.
230 *
231 * @since 4.10.2
232 *
233 * @param int $byte_size The byte size to check.
234 *
235 * @return int The SQL LIMIT value.
236 */
237 public function mysql_limit_for_size( $byte_size ) {
238 return absint( floor( $this->get_mysql_max_packet_size() / $byte_size ) * 0.8 );
239 }
240
241 /**
242 * Provides the SQL LIMIT value, in relation to the `max_allowed_packet` value, for a pre-existing example.
243 *
244 * Defaults to the complete post result example string if the example is not found.
245 *
246 * @since 4.10.2
247 *
248 * @param string $example The name of the example to return. See the `Tribe__Feature_Detection::$example_sizes`
249 * prop for the available examples. Defaults to the `post_result` one.
250 *
251 * @return int The SQL LIMIT value for the example.
252 */
253 public function mysql_limit_for_example( $example ) {
254 $example_size = Arr::get( static::$example_size, $example, static::$example_size['post_result'] );
255
256 return $this->mysql_limit_for_size( $example_size );
257 }
258 }
259