PluginProbe ʕ •ᴥ•ʔ
Gallery : FooGallery / 3.2.6
Gallery : FooGallery v3.2.6
3.3.2 3.3.3 3.3.0 3.1.31 3.1.32 3.1.34 3.1.36 3.2.0 3.2.6 trunk 1.10.3 2.0.24 2.1.34 2.2.44 2.3.3 2.4.32 3.0.6 3.1.11 3.1.12 3.1.13 3.1.20 3.1.25 3.1.26 3.1.26.1 3.1.26.2
foogallery / freemius / includes / fs-essential-functions.php
foogallery / freemius / includes Last commit date
customizer 4 weeks ago debug 4 weeks ago entities 4 weeks ago managers 4 weeks ago sdk 4 weeks ago supplements 4 weeks ago class-freemius-abstract.php 4 weeks ago class-freemius.php 4 weeks ago class-fs-admin-notices.php 4 weeks ago class-fs-api.php 4 weeks ago class-fs-garbage-collector.php 4 weeks ago class-fs-hook-snapshot.php 4 weeks ago class-fs-lock.php 4 weeks ago class-fs-logger.php 4 weeks ago class-fs-options.php 4 weeks ago class-fs-plugin-updater.php 4 weeks ago class-fs-security.php 4 weeks ago class-fs-storage.php 4 weeks ago class-fs-user-lock.php 4 weeks ago fs-core-functions.php 4 weeks ago fs-essential-functions.php 4 weeks ago fs-html-escaping-functions.php 4 weeks ago fs-plugin-info-dialog.php 4 weeks ago index.php 4 weeks ago l10n.php 4 weeks ago
fs-essential-functions.php
421 lines
1 <?php
2 /**
3 * IMPORTANT:
4 * This file will be loaded based on the order of the plugins/themes load.
5 * If there's a theme and a plugin using Freemius, the plugin's essential
6 * file will always load first.
7 *
8 * @package Freemius
9 * @copyright Copyright (c) 2015, Freemius, Inc.
10 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
11 * @since 1.1.5
12 */
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 if ( ! function_exists( 'fs_normalize_path' ) ) {
18 if ( function_exists( 'wp_normalize_path' ) ) {
19 /**
20 * Normalize a filesystem path.
21 *
22 * Replaces backslashes with forward slashes for Windows systems, and ensures
23 * no duplicate slashes exist.
24 *
25 * @param string $path Path to normalize.
26 *
27 * @return string Normalized path.
28 */
29 function fs_normalize_path( $path ) {
30 return wp_normalize_path( $path );
31 }
32 } else {
33 function fs_normalize_path( $path ) {
34 $path = str_replace( '\\', '/', $path );
35 $path = preg_replace( '|/+|', '/', $path );
36
37 return $path;
38 }
39 }
40 }
41
42 require_once dirname( __FILE__ ) . '/supplements/fs-essential-functions-2.2.1.php';
43
44 #region Core Redirect (copied from BuddyPress) -----------------------------------------
45
46 if ( ! function_exists( 'fs_redirect' ) ) {
47 /**
48 * Redirects to another page, with a workaround for the IIS Set-Cookie bug.
49 *
50 * @link http://support.microsoft.com/kb/q176113/
51 * @since 1.5.1
52 * @uses apply_filters() Calls 'wp_redirect' hook on $location and $status.
53 *
54 * @param string $location The path to redirect to.
55 * @param bool $exit If true, exit after redirect (Since 1.2.1.5).
56 * @param int $status Status code to use.
57 *
58 * @return bool False if $location is not set
59 */
60 function fs_redirect( $location, $exit = true, $status = 302 ) {
61 global $is_IIS;
62
63 $file = '';
64 $line = '';
65 if ( headers_sent($file, $line) ) {
66 if ( WP_FS__DEBUG_SDK && class_exists( 'FS_Admin_Notices' ) ) {
67 $notices = FS_Admin_Notices::instance( 'global' );
68
69 $notices->add( "Freemius failed to redirect the page because the headers have been already sent from line <b><code>{$line}</code></b> in file <b><code>{$file}</code></b>. If it's unexpected, it usually happens due to invalid space and/or EOL character(s).", 'Oops...', 'error' );
70 }
71
72 return false;
73 }
74
75 if ( defined( 'DOING_AJAX' ) ) {
76 // Don't redirect on AJAX calls.
77 return false;
78 }
79
80 if ( ! $location ) // allows the wp_redirect filter to cancel a redirect
81 {
82 return false;
83 }
84
85 $location = fs_sanitize_redirect( $location );
86
87 if ( $is_IIS ) {
88 header( "Refresh: 0;url=$location" );
89 } else {
90 if ( php_sapi_name() != 'cgi-fcgi' ) {
91 status_header( $status );
92 } // This causes problems on IIS and some FastCGI setups
93 header( "Location: $location" );
94 }
95
96 if ( $exit ) {
97 exit();
98 }
99
100 return true;
101 }
102
103 if ( ! function_exists( 'fs_sanitize_redirect' ) ) {
104 /**
105 * Sanitizes a URL for use in a redirect.
106 *
107 * @since 2.3
108 *
109 * @param string $location
110 *
111 * @return string redirect-sanitized URL
112 */
113 function fs_sanitize_redirect( $location ) {
114 $location = preg_replace( '|[^a-z0-9-~+_.?#=&;,/:%!]|i', '', $location );
115 $location = fs_kses_no_null( $location );
116
117 // remove %0d and %0a from location
118 $strip = array( '%0d', '%0a' );
119 $found = true;
120 while ( $found ) {
121 $found = false;
122 foreach ( (array) $strip as $val ) {
123 while ( strpos( $location, $val ) !== false ) {
124 $found = true;
125 $location = str_replace( $val, '', $location );
126 }
127 }
128 }
129
130 return $location;
131 }
132 }
133
134 if ( ! function_exists( 'fs_kses_no_null' ) ) {
135 /**
136 * Removes any NULL characters in $string.
137 *
138 * @since 1.0.0
139 *
140 * @param string $string
141 *
142 * @return string
143 */
144 function fs_kses_no_null( $string ) {
145 $string = preg_replace( '/\0+/', '', $string );
146 $string = preg_replace( '/(\\\\0)+/', '', $string );
147
148 return $string;
149 }
150 }
151 }
152
153 #endregion Core Redirect (copied from BuddyPress) -----------------------------------------
154
155 if ( ! function_exists( 'fs_get_ip' ) ) {
156 /**
157 * Get server IP.
158 *
159 * @since 2.5.1 This method returns the server IP.
160 *
161 * @author Vova Feldman (@svovaf)
162 * @since 1.1.2
163 *
164 * @return string|null
165 */
166 function fs_get_ip() {
167 return empty( $_SERVER[ 'SERVER_ADDR' ] ) ?
168 null :
169 $_SERVER[ 'SERVER_ADDR' ];
170 }
171 }
172
173 if ( ! function_exists( 'fs_find_caller_plugin_file' ) ) {
174 /**
175 * Leverage backtrace to find caller plugin main file path.
176 *
177 * @author Vova Feldman (@svovaf)
178 * @since 1.0.6
179 *
180 * @return string
181 */
182 function fs_find_caller_plugin_file() {
183 /**
184 * All the code below will be executed once on activation.
185 * If the user changes the main plugin's file name, the file_exists()
186 * will catch it.
187 */
188 if ( ! function_exists( 'get_plugins' ) ) {
189 require_once ABSPATH . 'wp-admin/includes/plugin.php';
190 }
191
192 $all_plugins = fs_get_plugins( true );
193 $all_plugins_paths = array();
194
195 // Get active plugin's main files real full names (might be symlinks).
196 foreach ( $all_plugins as $relative_path => $data ) {
197 $all_plugins_paths[] = fs_normalize_path( realpath( WP_PLUGIN_DIR . '/' . $relative_path ) );
198 }
199
200 $plugin_file = null;
201 for ( $i = 1, $bt = debug_backtrace(), $len = count( $bt ); $i < $len; $i ++ ) {
202 if ( empty( $bt[ $i ]['file'] ) ) {
203 continue;
204 }
205
206 if ( in_array( fs_normalize_path( $bt[ $i ]['file'] ), $all_plugins_paths ) ) {
207 $plugin_file = $bt[ $i ]['file'];
208 break;
209 }
210 }
211
212 if ( is_null( $plugin_file ) ) {
213 // Throw an error to the developer in case of some edge case dev environment.
214 wp_die(
215 'Freemius SDK couldn\'t find the plugin\'s main file. Please contact sdk@freemius.com with the current error.',
216 'Error',
217 array( 'back_link' => true )
218 );
219 }
220
221 return $plugin_file;
222 }
223 }
224
225 require_once dirname( __FILE__ ) . '/supplements/fs-essential-functions-1.1.7.1.php';
226
227 if ( ! function_exists( 'fs_update_sdk_newest_version' ) ) {
228 /**
229 * Update SDK newest version reference.
230 *
231 * @author Vova Feldman (@svovaf)
232 * @since 1.1.6
233 *
234 * @param string $sdk_relative_path
235 * @param string|bool $plugin_file
236 *
237 * @global $fs_active_plugins
238 */
239 function fs_update_sdk_newest_version( $sdk_relative_path, $plugin_file = false ) {
240 /**
241 * If there is a plugin running an older version of FS (1.2.1 or below), the `fs_update_sdk_newest_version()`
242 * function in the older version will be used instead of this one. But since the older version is using
243 * the `is_plugin_active` function to check if a plugin is active, passing the theme's `plugin_path` to the
244 * `is_plugin_active` function will return false since the path is not a plugin path, so `in_activation` will be
245 * `true` for theme modules and the upgrading of the SDK version to 1.2.2 or newer version will work fine.
246 *
247 * Future versions that will call this function will use the proper logic here instead of just relying on the
248 * `is_plugin_active` function to fail for themes.
249 *
250 * @author Leo Fajardo (@leorw)
251 * @since 1.2.2
252 */
253
254 global $fs_active_plugins;
255
256 $newest_sdk = $fs_active_plugins->plugins[ $sdk_relative_path ];
257
258 if ( ! is_string( $plugin_file ) ) {
259 $plugin_file = plugin_basename( fs_find_caller_plugin_file() );
260 }
261
262 if ( ! isset( $newest_sdk->type ) || 'theme' !== $newest_sdk->type ) {
263 if ( ! function_exists( 'is_plugin_active' ) ) {
264 require_once ABSPATH . 'wp-admin/includes/plugin.php';
265 }
266
267 $in_activation = ( ! is_plugin_active( $plugin_file ) );
268 } else {
269 $theme = wp_get_theme();
270 $in_activation = ( $newest_sdk->plugin_path == $theme->stylesheet );
271 }
272
273 $fs_active_plugins->newest = (object) array(
274 'plugin_path' => $plugin_file,
275 'sdk_path' => $sdk_relative_path,
276 'version' => $newest_sdk->version,
277 'in_activation' => $in_activation,
278 'timestamp' => time(),
279 );
280
281 // Update DB with latest SDK version and path.
282 update_option( 'fs_active_plugins', $fs_active_plugins );
283 }
284 }
285
286 if ( ! function_exists( 'fs_newest_sdk_plugin_first' ) ) {
287 /**
288 * Reorder the plugins load order so the plugin with the newest Freemius SDK is loaded first.
289 *
290 * @author Vova Feldman (@svovaf)
291 * @since 1.1.6
292 *
293 * @return bool Was plugin order changed. Return false if plugin was loaded first anyways.
294 *
295 * @global $fs_active_plugins
296 */
297 function fs_newest_sdk_plugin_first() {
298 global $fs_active_plugins;
299
300 /**
301 * @todo Multi-site network activated plugin are always loaded prior to site plugins so if there's a plugin activated in the network mode that has an older version of the SDK of another plugin which is site activated that has new SDK version, the fs-essential-functions.php will be loaded from the older SDK. Same thing about MU plugins (loaded even before network activated plugins).
302 *
303 * @link https://github.com/Freemius/wordpress-sdk/issues/26
304 */
305
306 $newest_sdk_plugin_path = $fs_active_plugins->newest->plugin_path;
307
308 $active_plugins = get_option( 'active_plugins', array() );
309 $updated_active_plugins = array( $newest_sdk_plugin_path );
310
311 $plugin_found = false;
312 $is_first_path = true;
313
314 foreach ( $active_plugins as $key => $plugin_path ) {
315 if ( $plugin_path === $newest_sdk_plugin_path ) {
316 if ( $is_first_path ) {
317 // if it's the first plugin already, no need to continue
318 return false;
319 }
320
321 $plugin_found = true;
322
323 // Skip the plugin (it is already added as the 1st item of $updated_active_plugins).
324 continue;
325 }
326
327 $updated_active_plugins[] = $plugin_path;
328
329 if ( $is_first_path ) {
330 $is_first_path = false;
331 }
332 }
333
334 if ( $plugin_found ) {
335 update_option( 'active_plugins', $updated_active_plugins );
336
337 return true;
338 }
339
340 if ( is_multisite() ) {
341 // Plugin is network active.
342 $network_active_plugins = get_site_option( 'active_sitewide_plugins', array() );
343
344 if ( isset( $network_active_plugins[ $newest_sdk_plugin_path ] ) ) {
345 reset( $network_active_plugins );
346 if ( $newest_sdk_plugin_path === key( $network_active_plugins ) ) {
347 // Plugin is already activated first on the network level.
348 return false;
349 } else {
350 $time = $network_active_plugins[ $newest_sdk_plugin_path ];
351
352 // Remove plugin from its current position.
353 unset( $network_active_plugins[ $newest_sdk_plugin_path ] );
354
355 // Set it to be included first.
356 $network_active_plugins = array( $newest_sdk_plugin_path => $time ) + $network_active_plugins;
357
358 update_site_option( 'active_sitewide_plugins', $network_active_plugins );
359
360 return true;
361 }
362 }
363 }
364
365 return false;
366 }
367 }
368
369 if ( ! function_exists( 'fs_fallback_to_newest_active_sdk' ) ) {
370 /**
371 * Go over all Freemius SDKs in the system and find and "remember"
372 * the newest SDK which is associated with an active plugin.
373 *
374 * @author Vova Feldman (@svovaf)
375 * @since 1.1.6
376 *
377 * @global $fs_active_plugins
378 */
379 function fs_fallback_to_newest_active_sdk() {
380 global $fs_active_plugins;
381
382 /**
383 * @var object $newest_sdk_data
384 */
385 $newest_sdk_data = null;
386 $newest_sdk_path = null;
387
388 foreach ( $fs_active_plugins->plugins as $sdk_relative_path => $data ) {
389 if ( is_null( $newest_sdk_data ) || version_compare( $data->version, $newest_sdk_data->version, '>' )
390 ) {
391 // If plugin inactive or SDK starter file doesn't exist, remove SDK reference.
392 if ( 'plugin' === $data->type ) {
393 $is_module_active = is_plugin_active( $data->plugin_path );
394 } else {
395 $active_theme = wp_get_theme();
396 $is_module_active = ( $data->plugin_path === $active_theme->get_template() );
397 }
398
399 $is_sdk_exists = file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $sdk_relative_path . '/start.php' ) );
400
401 if ( ! $is_module_active || ! $is_sdk_exists ) {
402 unset( $fs_active_plugins->plugins[ $sdk_relative_path ] );
403
404 // No need to store the data since it will be stored in fs_update_sdk_newest_version()
405 // or explicitly with update_option().
406 } else {
407 $newest_sdk_data = $data;
408 $newest_sdk_path = $sdk_relative_path;
409 }
410 }
411 }
412
413 if ( is_null( $newest_sdk_data ) ) {
414 // Couldn't find any SDK reference.
415 $fs_active_plugins = new stdClass();
416 update_option( 'fs_active_plugins', $fs_active_plugins );
417 } else {
418 fs_update_sdk_newest_version( $newest_sdk_path, $newest_sdk_data->plugin_path );
419 }
420 }
421 }