entities
10 years ago
managers
10 years ago
sdk
10 years ago
class-freemius-abstract.php
10 years ago
class-freemius.php
10 years ago
class-fs-api.php
10 years ago
class-fs-logger.php
10 years ago
class-fs-plugin-updater.php
10 years ago
class-fs-security.php
10 years ago
fs-core-functions.php
10 years ago
fs-plugin-functions.php
10 years ago
i18n.php
10 years ago
fs-core-functions.php
462 lines
| 1 | <?php |
| 2 | /** |
| 3 | * @package Freemius |
| 4 | * @copyright Copyright (c) 2015, Freemius, Inc. |
| 5 | * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License |
| 6 | * @since 1.0.3 |
| 7 | */ |
| 8 | |
| 9 | if ( ! defined( 'ABSPATH' ) ) { |
| 10 | exit; |
| 11 | } |
| 12 | |
| 13 | global $fs_core_logger; |
| 14 | |
| 15 | $fs_core_logger = FS_Logger::get_logger( WP_FS__SLUG . '_core', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK ); |
| 16 | |
| 17 | function fs_dummy() { |
| 18 | } |
| 19 | |
| 20 | /* Url. |
| 21 | --------------------------------------------------------------------------------------------*/ |
| 22 | function fs_get_url_daily_cache_killer() { |
| 23 | return date( '\YY\Mm\Dd' ); |
| 24 | } |
| 25 | |
| 26 | /* Templates / Views. |
| 27 | --------------------------------------------------------------------------------------------*/ |
| 28 | function fs_get_template_path( $path ) { |
| 29 | return WP_FS__DIR_TEMPLATES . '/' . trim( $path, '/' ); |
| 30 | } |
| 31 | |
| 32 | function fs_include_template( $path, &$params = null ) { |
| 33 | $VARS = &$params; |
| 34 | include( fs_get_template_path( $path ) ); |
| 35 | } |
| 36 | |
| 37 | function fs_include_once_template( $path, &$params = null ) { |
| 38 | $VARS = &$params; |
| 39 | include_once( fs_get_template_path( $path ) ); |
| 40 | } |
| 41 | |
| 42 | function fs_require_template( $path, &$params = null ) { |
| 43 | $VARS = &$params; |
| 44 | require( fs_get_template_path( $path ) ); |
| 45 | } |
| 46 | |
| 47 | function fs_require_once_template( $path, &$params = null ) { |
| 48 | $VARS = &$params; |
| 49 | require_once( fs_get_template_path( $path ) ); |
| 50 | } |
| 51 | |
| 52 | function fs_get_template( $path, &$params = null ) { |
| 53 | ob_start(); |
| 54 | |
| 55 | $VARS = &$params; |
| 56 | require_once( fs_get_template_path( $path ) ); |
| 57 | |
| 58 | return ob_get_clean(); |
| 59 | } |
| 60 | |
| 61 | function __fs( $key ) { |
| 62 | global $fs_text; |
| 63 | |
| 64 | if ( ! isset( $fs_text ) ) { |
| 65 | require_once( dirname( __FILE__ ) . '/i18n.php' ); |
| 66 | } |
| 67 | |
| 68 | return isset( $fs_text[ $key ] ) ? $fs_text[ $key ] : $key; |
| 69 | } |
| 70 | |
| 71 | function _efs( $key ) { |
| 72 | echo __fs( $key ); |
| 73 | } |
| 74 | |
| 75 | /* Scripts and styles including. |
| 76 | --------------------------------------------------------------------------------------------*/ |
| 77 | function fs_enqueue_local_style( $handle, $path, $deps = array(), $ver = false, $media = 'all' ) { |
| 78 | global $fs_core_logger; |
| 79 | if ( $fs_core_logger->is_on() ) { |
| 80 | $fs_core_logger->info( 'handle = ' . $handle . '; path = ' . $path . ';' ); |
| 81 | $fs_core_logger->info( 'plugin_basename = ' . plugins_url( WP_FS__DIR_CSS . trim( $path, '/' ) ) ); |
| 82 | $fs_core_logger->info( 'plugins_url = ' . plugins_url( plugin_basename( WP_FS__DIR_CSS . '/' . trim( $path, '/' ) ) ) ); |
| 83 | } |
| 84 | |
| 85 | wp_enqueue_style( $handle, plugins_url( plugin_basename( WP_FS__DIR_CSS . '/' . trim( $path, '/' ) ) ), $deps, $ver, $media ); |
| 86 | } |
| 87 | |
| 88 | function fs_enqueue_local_script( $handle, $path, $deps = array(), $ver = false, $in_footer = 'all' ) { |
| 89 | global $fs_core_logger; |
| 90 | if ( $fs_core_logger->is_on() ) { |
| 91 | $fs_core_logger->info( 'handle = ' . $handle . '; path = ' . $path . ';' ); |
| 92 | $fs_core_logger->info( 'plugin_basename = ' . plugins_url( WP_FS__DIR_JS . trim( $path, '/' ) ) ); |
| 93 | $fs_core_logger->info( 'plugins_url = ' . plugins_url( plugin_basename( WP_FS__DIR_JS . '/' . trim( $path, '/' ) ) ) ); |
| 94 | } |
| 95 | |
| 96 | wp_enqueue_script( $handle, plugins_url( plugin_basename( WP_FS__DIR_JS . '/' . trim( $path, '/' ) ) ), $deps, $ver, $in_footer ); |
| 97 | } |
| 98 | |
| 99 | function fs_img_url( $path ) { |
| 100 | return plugins_url( plugin_basename( WP_FS__DIR_IMG . '/' . trim( $path, '/' ) ) ); |
| 101 | } |
| 102 | |
| 103 | /* Request handlers. |
| 104 | --------------------------------------------------------------------------------------------*/ |
| 105 | /** |
| 106 | * @param string $key |
| 107 | * @param mixed $def |
| 108 | * |
| 109 | * @return mixed |
| 110 | */ |
| 111 | function fs_request_get( $key, $def = false ) { |
| 112 | return isset( $_REQUEST[ $key ] ) ? $_REQUEST[ $key ] : $def; |
| 113 | } |
| 114 | |
| 115 | function fs_request_has( $key ) { |
| 116 | return isset( $_REQUEST[ $key ] ); |
| 117 | } |
| 118 | |
| 119 | function fs_request_get_bool( $key, $def = false ) { |
| 120 | return ( isset( $_REQUEST[ $key ] ) && ( 1 == $_REQUEST[ $key ] || 'true' === strtolower( $_REQUEST[ $key ] ) ) ) ? true : $def; |
| 121 | } |
| 122 | |
| 123 | function fs_request_is_post() { |
| 124 | return ( 'post' === strtolower( $_SERVER['REQUEST_METHOD'] ) ); |
| 125 | } |
| 126 | |
| 127 | function fs_request_is_get() { |
| 128 | return ( 'get' === strtolower( $_SERVER['REQUEST_METHOD'] ) ); |
| 129 | } |
| 130 | |
| 131 | function fs_get_action( $action_key = 'action' ) { |
| 132 | if ( ! empty( $_REQUEST[ $action_key ] ) ) { |
| 133 | return strtolower( $_REQUEST[ $action_key ] ); |
| 134 | } |
| 135 | |
| 136 | if ( 'action' == $action_key ) { |
| 137 | $action_key = 'fs_action'; |
| 138 | |
| 139 | if ( ! empty( $_REQUEST[ $action_key ] ) ) { |
| 140 | return strtolower( $_REQUEST[ $action_key ] ); |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | return false; |
| 145 | } |
| 146 | |
| 147 | function fs_request_is_action( $action, $action_key = 'action' ) { |
| 148 | return ( strtolower( $action ) === fs_get_action( $action_key ) ); |
| 149 | } |
| 150 | |
| 151 | function fs_is_plugin_page( $menu_slug ) { |
| 152 | return ( is_admin() && $_REQUEST['page'] === $menu_slug ); |
| 153 | } |
| 154 | |
| 155 | /** |
| 156 | * Get client IP. |
| 157 | * |
| 158 | * @author Vova Feldman (@svovaf) |
| 159 | * @since 1.1.2 |
| 160 | * |
| 161 | * @return string|null |
| 162 | */ |
| 163 | function fs_get_ip() { |
| 164 | $fields = array( |
| 165 | 'HTTP_CF_CONNECTING_IP', |
| 166 | 'HTTP_CLIENT_IP', |
| 167 | 'HTTP_X_FORWARDED_FOR', |
| 168 | 'HTTP_X_FORWARDED', |
| 169 | 'HTTP_FORWARDED_FOR', |
| 170 | 'HTTP_FORWARDED', |
| 171 | 'REMOTE_ADDR', |
| 172 | ); |
| 173 | |
| 174 | foreach ( $fields as $ip_field ) { |
| 175 | if ( ! empty( $_SERVER[ $ip_field ] ) ) { |
| 176 | return $_SERVER[ $ip_field ]; |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | return null; |
| 181 | } |
| 182 | |
| 183 | /* Core UI. |
| 184 | --------------------------------------------------------------------------------------------*/ |
| 185 | function fs_ui_action_button( $slug, $page, $action, $title, $params = array(), $is_primary = true ) { |
| 186 | ?><a class="button<?php if ( $is_primary ) { |
| 187 | echo ' button-primary'; |
| 188 | } ?>" |
| 189 | href="<?php echo wp_nonce_url( freemius( $slug )->_get_admin_page_url( $page, array_merge( $params, array( 'fs_action' => $action ) ) ), $action ) ?>"><?php echo $title ?></a><?php |
| 190 | } |
| 191 | |
| 192 | function fs_ui_action_link( $slug, $page, $action, $title, $params = array() ) { |
| 193 | ?><a class="" |
| 194 | href="<?php echo wp_nonce_url( freemius( $slug )->_get_admin_page_url( $page, array_merge( $params, array( 'fs_action' => $action ) ) ), $action ) ?>"><?php echo $title ?></a><?php |
| 195 | } |
| 196 | |
| 197 | /* Core Redirect (copied from BuddyPress). |
| 198 | --------------------------------------------------------------------------------------------*/ |
| 199 | /** |
| 200 | * Redirects to another page, with a workaround for the IIS Set-Cookie bug. |
| 201 | * |
| 202 | * @link http://support.microsoft.com/kb/q176113/ |
| 203 | * @since 1.5.1 |
| 204 | * @uses apply_filters() Calls 'wp_redirect' hook on $location and $status. |
| 205 | * |
| 206 | * @param string $location The path to redirect to |
| 207 | * @param int $status Status code to use |
| 208 | * |
| 209 | * @return bool False if $location is not set |
| 210 | */ |
| 211 | function fs_redirect( $location, $status = 302 ) { |
| 212 | global $is_IIS; |
| 213 | |
| 214 | if ( headers_sent() ) { |
| 215 | return false; |
| 216 | } |
| 217 | |
| 218 | if ( ! $location ) // allows the wp_redirect filter to cancel a redirect |
| 219 | { |
| 220 | return false; |
| 221 | } |
| 222 | |
| 223 | $location = fs_sanitize_redirect( $location ); |
| 224 | |
| 225 | if ( $is_IIS ) { |
| 226 | header( "Refresh: 0;url=$location" ); |
| 227 | } else { |
| 228 | if ( php_sapi_name() != 'cgi-fcgi' ) { |
| 229 | status_header( $status ); |
| 230 | } // This causes problems on IIS and some FastCGI setups |
| 231 | header( "Location: $location" ); |
| 232 | } |
| 233 | |
| 234 | return true; |
| 235 | } |
| 236 | |
| 237 | /** |
| 238 | * Sanitizes a URL for use in a redirect. |
| 239 | * |
| 240 | * @since 2.3 |
| 241 | * |
| 242 | * @param string $location |
| 243 | * |
| 244 | * @return string redirect-sanitized URL |
| 245 | */ |
| 246 | function fs_sanitize_redirect( $location ) { |
| 247 | $location = preg_replace( '|[^a-z0-9-~+_.?#=&;,/:%!]|i', '', $location ); |
| 248 | $location = fs_kses_no_null( $location ); |
| 249 | |
| 250 | // remove %0d and %0a from location |
| 251 | $strip = array( '%0d', '%0a' ); |
| 252 | $found = true; |
| 253 | while ( $found ) { |
| 254 | $found = false; |
| 255 | foreach ( (array) $strip as $val ) { |
| 256 | while ( strpos( $location, $val ) !== false ) { |
| 257 | $found = true; |
| 258 | $location = str_replace( $val, '', $location ); |
| 259 | } |
| 260 | } |
| 261 | } |
| 262 | |
| 263 | return $location; |
| 264 | } |
| 265 | |
| 266 | /** |
| 267 | * Removes any NULL characters in $string. |
| 268 | * |
| 269 | * @since 1.0.0 |
| 270 | * |
| 271 | * @param string $string |
| 272 | * |
| 273 | * @return string |
| 274 | */ |
| 275 | function fs_kses_no_null( $string ) { |
| 276 | $string = preg_replace( '/\0+/', '', $string ); |
| 277 | $string = preg_replace( '/(\\\\0)+/', '', $string ); |
| 278 | |
| 279 | return $string; |
| 280 | } |
| 281 | |
| 282 | /*function fs_error_handler($errno, $errstr, $errfile, $errline) |
| 283 | { |
| 284 | if (false === strpos($errfile, 'freemius/')) |
| 285 | { |
| 286 | // @todo Dump Freemius errors to local log. |
| 287 | } |
| 288 | |
| 289 | // switch ($errno) { |
| 290 | // case E_USER_ERROR: |
| 291 | // break; |
| 292 | // case E_WARNING: |
| 293 | // case E_USER_WARNING: |
| 294 | // break; |
| 295 | // case E_NOTICE: |
| 296 | // case E_USER_NOTICE: |
| 297 | // break; |
| 298 | // default: |
| 299 | // break; |
| 300 | // } |
| 301 | } |
| 302 | |
| 303 | set_error_handler('fs_error_handler');*/ |
| 304 | |
| 305 | if ( function_exists( 'wp_normalize_path' ) ) { |
| 306 | /** |
| 307 | * Normalize a filesystem path. |
| 308 | * |
| 309 | * Replaces backslashes with forward slashes for Windows systems, and ensures |
| 310 | * no duplicate slashes exist. |
| 311 | * |
| 312 | * @param string $path Path to normalize. |
| 313 | * |
| 314 | * @return string Normalized path. |
| 315 | */ |
| 316 | function fs_normalize_path( $path ) { |
| 317 | return wp_normalize_path( $path ); |
| 318 | } |
| 319 | } else { |
| 320 | function fs_normalize_path( $path ) { |
| 321 | $path = str_replace( '\\', '/', $path ); |
| 322 | $path = preg_replace( '|/+|', '/', $path ); |
| 323 | |
| 324 | return $path; |
| 325 | } |
| 326 | } |
| 327 | |
| 328 | function fs_nonce_url( $actionurl, $action = - 1, $name = '_wpnonce' ) { |
| 329 | // $actionurl = str_replace( '&', '&', $actionurl ); |
| 330 | return add_query_arg( $name, wp_create_nonce( $action ), $actionurl ); |
| 331 | } |
| 332 | |
| 333 | /** |
| 334 | * Check if string starts with. |
| 335 | * |
| 336 | * @author Vova Feldman (@svovaf) |
| 337 | * @since 1.1.3 |
| 338 | * |
| 339 | * @param string $haystack |
| 340 | * @param string $needle |
| 341 | * |
| 342 | * @return bool |
| 343 | */ |
| 344 | function fs_starts_with( $haystack, $needle ) { |
| 345 | $length = strlen( $needle ); |
| 346 | |
| 347 | return ( substr( $haystack, 0, $length ) === $needle ); |
| 348 | } |
| 349 | |
| 350 | #region Url Canonization ------------------------------------------------------------------ |
| 351 | |
| 352 | /** |
| 353 | * @author Vova Feldman (@svovaf) |
| 354 | * @since 1.1.3 |
| 355 | * |
| 356 | * @param string $url |
| 357 | * @param bool $omit_host |
| 358 | * @param array $ignore_params |
| 359 | * |
| 360 | * @return string |
| 361 | */ |
| 362 | function fs_canonize_url( $url, $omit_host = false, $ignore_params = array() ) { |
| 363 | $parsed_url = parse_url( strtolower( $url ) ); |
| 364 | |
| 365 | // if ( ! isset( $parsed_url['host'] ) ) { |
| 366 | // return $url; |
| 367 | // } |
| 368 | |
| 369 | $canonical = ( ( $omit_host || ! isset( $parsed_url['host'] ) ) ? '' : $parsed_url['host'] ) . $parsed_url['path']; |
| 370 | |
| 371 | if ( isset( $parsed_url['query'] ) ) { |
| 372 | parse_str( $parsed_url['query'], $queryString ); |
| 373 | $canonical .= '?' . fs_canonize_query_string( $queryString, $ignore_params ); |
| 374 | } |
| 375 | |
| 376 | return $canonical; |
| 377 | } |
| 378 | |
| 379 | /** |
| 380 | * @author Vova Feldman (@svovaf) |
| 381 | * @since 1.1.3 |
| 382 | * |
| 383 | * @param array $params |
| 384 | * @param array $ignore_params |
| 385 | * @param bool $params_prefix |
| 386 | * |
| 387 | * @return string |
| 388 | */ |
| 389 | function fs_canonize_query_string( array $params, array &$ignore_params, $params_prefix = false ) { |
| 390 | if ( ! is_array( $params ) || 0 === count( $params ) ) { |
| 391 | return ''; |
| 392 | } |
| 393 | |
| 394 | // Urlencode both keys and values |
| 395 | $keys = fs_urlencode_rfc3986( array_keys( $params ) ); |
| 396 | $values = fs_urlencode_rfc3986( array_values( $params ) ); |
| 397 | $params = array_combine( $keys, $values ); |
| 398 | |
| 399 | // Parameters are sorted by name, using lexicographical byte value ordering. |
| 400 | // Ref: Spec: 9.1.1 (1) |
| 401 | uksort( $params, 'strcmp' ); |
| 402 | |
| 403 | $pairs = array(); |
| 404 | foreach ( $params as $parameter => $value ) { |
| 405 | $lower_param = strtolower( $parameter ); |
| 406 | |
| 407 | // Skip ignore params. |
| 408 | if ( in_array( $lower_param, $ignore_params ) || ( false !== $params_prefix && startsWith( $lower_param, $params_prefix ) ) ) { |
| 409 | continue; |
| 410 | } |
| 411 | |
| 412 | if ( is_array( $value ) ) { |
| 413 | // If two or more parameters share the same name, they are sorted by their value |
| 414 | // Ref: Spec: 9.1.1 (1) |
| 415 | natsort( $value ); |
| 416 | foreach ( $value as $duplicate_value ) { |
| 417 | $pairs[] = $lower_param . '=' . $duplicate_value; |
| 418 | } |
| 419 | } else { |
| 420 | $pairs[] = $lower_param . '=' . $value; |
| 421 | } |
| 422 | } |
| 423 | |
| 424 | if ( 0 === count( $pairs ) ) { |
| 425 | return ''; |
| 426 | } |
| 427 | |
| 428 | return implode( "&", $pairs ); |
| 429 | } |
| 430 | |
| 431 | /** |
| 432 | * @author Vova Feldman (@svovaf) |
| 433 | * @since 1.1.3 |
| 434 | * |
| 435 | * @param string|string[] $input |
| 436 | * |
| 437 | * @return array|mixed|string |
| 438 | */ |
| 439 | function fs_urlencode_rfc3986( $input ) { |
| 440 | if ( is_array( $input ) ) { |
| 441 | return array_map( 'fs_urlencode_rfc3986', $input ); |
| 442 | } else if ( is_scalar( $input ) ) { |
| 443 | return str_replace( '+', ' ', str_replace( '%7E', '~', rawurlencode( $input ) ) ); |
| 444 | } |
| 445 | |
| 446 | return ''; |
| 447 | } |
| 448 | |
| 449 | #endregion Url Canonization ------------------------------------------------------------------ |
| 450 | |
| 451 | function fs_download_image( $from, $to ) { |
| 452 | $ch = curl_init( $from ); |
| 453 | $fp = fopen( fs_normalize_path( $to ), 'wb' ); |
| 454 | curl_setopt( $ch, CURLOPT_FILE, $fp ); |
| 455 | curl_setopt( $ch, CURLOPT_HEADER, 0 ); |
| 456 | curl_exec( $ch ); |
| 457 | curl_close( $ch ); |
| 458 | fclose( $fp ); |
| 459 | } |
| 460 | |
| 461 | |
| 462 |