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