/freemius/includes/fs-core-functions.php

  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. global $fs_core_logger; 
  13.  
  14. $fs_core_logger = FS_Logger::get_logger( WP_FS__SLUG . '_core', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK ); 
  15.  
  16. if ( ! function_exists( 'fs_dummy' ) ) { 
  17. function fs_dummy() { 
  18.  
  19. /** Url. 
  20. --------------------------------------------------------------------------------------------*/ 
  21. function fs_get_url_daily_cache_killer() { 
  22. return date( '\YY\Mm\Dd' ); 
  23.  
  24. /** Templates / Views. 
  25. --------------------------------------------------------------------------------------------*/ 
  26. if ( ! function_exists( 'fs_get_template_path' ) ) { 
  27. function fs_get_template_path( $path ) { 
  28. return WP_FS__DIR_TEMPLATES . '/' . trim( $path, '/' ); 
  29.  
  30. function fs_include_template( $path, &$params = null ) { 
  31. $VARS = &$params; 
  32. include( fs_get_template_path( $path ) ); 
  33.  
  34. function fs_include_once_template( $path, &$params = null ) { 
  35. $VARS = &$params; 
  36. include_once( fs_get_template_path( $path ) ); 
  37.  
  38. function fs_require_template( $path, &$params = null ) { 
  39. $VARS = &$params; 
  40. require( fs_get_template_path( $path ) ); 
  41.  
  42. function fs_require_once_template( $path, &$params = null ) { 
  43. $VARS = &$params; 
  44. require_once( fs_get_template_path( $path ) ); 
  45.  
  46. function fs_get_template( $path, &$params = null ) { 
  47. ob_start(); 
  48.  
  49. $VARS = &$params; 
  50. require( fs_get_template_path( $path ) ); 
  51.  
  52. return ob_get_clean(); 
  53.  
  54. /** Scripts and styles including. 
  55. --------------------------------------------------------------------------------------------*/ 
  56. function fs_enqueue_local_style( $handle, $path, $deps = array(), $ver = false, $media = 'all' ) { 
  57. global $fs_core_logger; 
  58. if ( $fs_core_logger->is_on() ) { 
  59. $fs_core_logger->info( 'handle = ' . $handle . '; path = ' . $path . ';' ); 
  60. $fs_core_logger->info( 'plugin_basename = ' . plugins_url( WP_FS__DIR_CSS . trim( $path, '/' ) ) ); 
  61. $fs_core_logger->info( 'plugins_url = ' . plugins_url( plugin_basename( WP_FS__DIR_CSS . '/' . trim( $path, '/' ) ) ) ); 
  62.  
  63. wp_enqueue_style( $handle, plugins_url( plugin_basename( WP_FS__DIR_CSS . '/' . trim( $path, '/' ) ) ), $deps, $ver, $media ); 
  64.  
  65. function fs_enqueue_local_script( $handle, $path, $deps = array(), $ver = false, $in_footer = 'all' ) { 
  66. global $fs_core_logger; 
  67. if ( $fs_core_logger->is_on() ) { 
  68. $fs_core_logger->info( 'handle = ' . $handle . '; path = ' . $path . ';' ); 
  69. $fs_core_logger->info( 'plugin_basename = ' . plugins_url( WP_FS__DIR_JS . trim( $path, '/' ) ) ); 
  70. $fs_core_logger->info( 'plugins_url = ' . plugins_url( plugin_basename( WP_FS__DIR_JS . '/' . trim( $path, '/' ) ) ) ); 
  71.  
  72. wp_enqueue_script( $handle, plugins_url( plugin_basename( WP_FS__DIR_JS . '/' . trim( $path, '/' ) ) ), $deps, $ver, $in_footer ); 
  73.  
  74. function fs_img_url( $path, $img_dir = WP_FS__DIR_IMG ) { 
  75. return plugins_url( plugin_basename( $img_dir . '/' . trim( $path, '/' ) ) ); 
  76.  
  77. /** Request handlers. 
  78. --------------------------------------------------------------------------------------------*/ 
  79. /** 
  80. * @param string $key 
  81. * @param mixed $def 
  82. * 
  83. * @return mixed 
  84. */ 
  85. function fs_request_get( $key, $def = false ) { 
  86. return isset( $_REQUEST[ $key ] ) ? $_REQUEST[ $key ] : $def; 
  87.  
  88. function fs_request_has( $key ) { 
  89. return isset( $_REQUEST[ $key ] ); 
  90.  
  91. function fs_request_get_bool( $key, $def = false ) { 
  92. if ( ! isset( $_REQUEST[ $key ] ) ) { 
  93. return $def; 
  94.  
  95. if ( 1 == $_REQUEST[ $key ] || 'true' === strtolower( $_REQUEST[ $key ] ) ) { 
  96. return true; 
  97.  
  98. if ( 0 == $_REQUEST[ $key ] || 'false' === strtolower( $_REQUEST[ $key ] ) ) { 
  99. return false; 
  100.  
  101. return $def; 
  102.  
  103. function fs_request_is_post() { 
  104. return ( 'post' === strtolower( $_SERVER['REQUEST_METHOD'] ) ); 
  105.  
  106. function fs_request_is_get() { 
  107. return ( 'get' === strtolower( $_SERVER['REQUEST_METHOD'] ) ); 
  108.  
  109. function fs_get_action( $action_key = 'action' ) { 
  110. if ( ! empty( $_REQUEST[ $action_key ] ) ) { 
  111. return strtolower( $_REQUEST[ $action_key ] ); 
  112.  
  113. if ( 'action' == $action_key ) { 
  114. $action_key = 'fs_action'; 
  115.  
  116. if ( ! empty( $_REQUEST[ $action_key ] ) ) { 
  117. return strtolower( $_REQUEST[ $action_key ] ); 
  118.  
  119. return false; 
  120.  
  121. function fs_request_is_action( $action, $action_key = 'action' ) { 
  122. return ( strtolower( $action ) === fs_get_action( $action_key ) ); 
  123.  
  124. /** 
  125. * @author Vova Feldman (@svovaf) 
  126. * @since 1.0.0 
  127. * 
  128. * @since 1.2.1.5 Allow nonce verification. 
  129. * 
  130. * @param string $action 
  131. * @param string $action_key 
  132. * @param string $nonce_key 
  133. * 
  134. * @return bool 
  135. */ 
  136. function fs_request_is_action_secure( 
  137. $action,  
  138. $action_key = 'action',  
  139. $nonce_key = 'nonce' 
  140. ) { 
  141. if ( strtolower( $action ) !== fs_get_action( $action_key ) ) { 
  142. return false; 
  143.  
  144. $nonce = ! empty( $_REQUEST[ $nonce_key ] ) ? 
  145. $_REQUEST[ $nonce_key ] : 
  146. ''; 
  147.  
  148. if ( empty( $nonce ) || 
  149. ( false === wp_verify_nonce( $nonce, $action ) ) 
  150. ) { 
  151. return false; 
  152.  
  153. return true; 
  154.  
  155. function fs_is_plugin_page( $menu_slug ) { 
  156. return ( is_admin() && $_REQUEST['page'] === $menu_slug ); 
  157.  
  158. /** Core UI. 
  159. --------------------------------------------------------------------------------------------*/ 
  160. /** 
  161. * @param string $slug 
  162. * @param string $page 
  163. * @param string $action 
  164. * @param string $title 
  165. * @param array $params 
  166. * @param bool $is_primary 
  167. * @param string|bool $icon_class Optional class for an icon (since 1.1.7). 
  168. * @param string|bool $confirmation Optional confirmation message before submit (since 1.1.7). 
  169. * @param string $method Since 1.1.7 
  170. * 
  171. * @uses fs_ui_get_action_button() 
  172. */ 
  173. function fs_ui_action_button( 
  174. $slug,  
  175. $page,  
  176. $action,  
  177. $title,  
  178. $params = array(),  
  179. $is_primary = true,  
  180. $icon_class = false,  
  181. $confirmation = false,  
  182. $method = 'GET' 
  183. ) { 
  184. echo fs_ui_get_action_button( 
  185. $slug,  
  186. $page,  
  187. $action,  
  188. $title,  
  189. $params,  
  190. $is_primary,  
  191. $icon_class,  
  192. $confirmation,  
  193. $method 
  194. ); 
  195.  
  196. /** 
  197. * @author Vova Feldman (@svovaf) 
  198. * @since 1.1.7 
  199. * 
  200. * @param string $slug 
  201. * @param string $page 
  202. * @param string $action 
  203. * @param string $title 
  204. * @param array $params 
  205. * @param bool $is_primary 
  206. * @param string|bool $icon_class Optional class for an icon. 
  207. * @param string|bool $confirmation Optional confirmation message before submit. 
  208. * @param string $method 
  209. * 
  210. * @return string 
  211. */ 
  212. function fs_ui_get_action_button( 
  213. $slug,  
  214. $page,  
  215. $action,  
  216. $title,  
  217. $params = array(),  
  218. $is_primary = true,  
  219. $icon_class = false,  
  220. $confirmation = false,  
  221. $method = 'GET' 
  222. ) { 
  223. // Prepend icon (if set). 
  224. $title = ( is_string( $icon_class ) ? '<i class="' . $icon_class . '"></i> ' : '' ) . $title; 
  225.  
  226. if ( is_string( $confirmation ) ) { 
  227. return sprintf( '<form action="%s" method="%s"><input type="hidden" name="fs_action" value="%s">%s<a href="#" class="%s" onclick="if (confirm(\'%s\')) this.parentNode.submit(); return false;">%s</a></form>',  
  228. freemius( $slug )->_get_admin_page_url( $page, $params ),  
  229. $method,  
  230. $action,  
  231. wp_nonce_field( $action, '_wpnonce', true, false ),  
  232. 'button' . ( $is_primary ? ' button-primary' : '' ),  
  233. $confirmation,  
  234. $title 
  235. ); 
  236. } else if ( 'GET' !== strtoupper( $method ) ) { 
  237. return sprintf( '<form action="%s" method="%s"><input type="hidden" name="fs_action" value="%s">%s<a href="#" class="%s" onclick="this.parentNode.submit(); return false;">%s</a></form>',  
  238. freemius( $slug )->_get_admin_page_url( $page, $params ),  
  239. $method,  
  240. $action,  
  241. wp_nonce_field( $action, '_wpnonce', true, false ),  
  242. 'button' . ( $is_primary ? ' button-primary' : '' ),  
  243. $title 
  244. ); 
  245. } else { 
  246. return sprintf( '<a href="%s" class="%s">%s</a></form>',  
  247. wp_nonce_url( freemius( $slug )->_get_admin_page_url( $page, array_merge( $params, array( 'fs_action' => $action ) ) ), $action ),  
  248. 'button' . ( $is_primary ? ' button-primary' : '' ),  
  249. $title 
  250. ); 
  251.  
  252. function fs_ui_action_link( $slug, $page, $action, $title, $params = array() ) { 
  253. ?><a class="" 
  254. 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 
  255.  
  256. /**function fs_error_handler($errno, $errstr, $errfile, $errline) 
  257. { 
  258. if (false === strpos($errfile, 'freemius/')) 
  259. { 
  260. // @todo Dump Freemius errors to local log. 
  261. } 
  262.   
  263. // switch ($errno) { 
  264. // case E_USER_ERROR: 
  265. // break; 
  266. // case E_WARNING: 
  267. // case E_USER_WARNING: 
  268. // break; 
  269. // case E_NOTICE: 
  270. // case E_USER_NOTICE: 
  271. // break; 
  272. // default: 
  273. // break; 
  274. // } 
  275. } 
  276.   
  277. set_error_handler('fs_error_handler');*/ 
  278.  
  279. if ( ! function_exists( 'fs_nonce_url' ) ) { 
  280. /** 
  281. * Retrieve URL with nonce added to URL query. 
  282. * 
  283. * Originally was using `wp_nonce_url()` but the new version 
  284. * changed the return value to escaped URL, that's not the expected 
  285. * behaviour. 
  286. * 
  287. * @author Vova Feldman (@svovaf) 
  288. * @since ~1.1.3 
  289. * 
  290. * @param string $actionurl URL to add nonce action. 
  291. * @param int|string $action Optional. Nonce action name. Default -1. 
  292. * @param string $name Optional. Nonce name. Default '_wpnonce'. 
  293. * 
  294. * @return string Escaped URL with nonce action added. 
  295. */ 
  296. function fs_nonce_url( $actionurl, $action = - 1, $name = '_wpnonce' ) { 
  297. return add_query_arg( $name, wp_create_nonce( $action ), $actionurl ); 
  298.  
  299. if ( ! function_exists( 'fs_starts_with' ) ) { 
  300. /** 
  301. * Check if string starts with. 
  302. * 
  303. * @author Vova Feldman (@svovaf) 
  304. * @since 1.1.3 
  305. * 
  306. * @param string $haystack 
  307. * @param string $needle 
  308. * 
  309. * @return bool 
  310. */ 
  311. function fs_starts_with( $haystack, $needle ) { 
  312. $length = strlen( $needle ); 
  313.  
  314. return ( substr( $haystack, 0, $length ) === $needle ); 
  315.  
  316. #region Url Canonization ------------------------------------------------------------------ 
  317.  
  318. if ( ! function_exists( 'fs_canonize_url' ) ) { 
  319. /** 
  320. * @author Vova Feldman (@svovaf) 
  321. * @since 1.1.3 
  322. * 
  323. * @param string $url 
  324. * @param bool $omit_host 
  325. * @param array $ignore_params 
  326. * 
  327. * @return string 
  328. */ 
  329. function fs_canonize_url( $url, $omit_host = false, $ignore_params = array() ) { 
  330. $parsed_url = parse_url( strtolower( $url ) ); 
  331.  
  332. // if ( ! isset( $parsed_url['host'] ) ) { 
  333. // return $url; 
  334. // } 
  335.  
  336. $canonical = ( ( $omit_host || ! isset( $parsed_url['host'] ) ) ? '' : $parsed_url['host'] ) . $parsed_url['path']; 
  337.  
  338. if ( isset( $parsed_url['query'] ) ) { 
  339. parse_str( $parsed_url['query'], $queryString ); 
  340. $canonical .= '?' . fs_canonize_query_string( $queryString, $ignore_params ); 
  341.  
  342. return $canonical; 
  343.  
  344. if ( ! function_exists( 'fs_canonize_query_string' ) ) { 
  345. /** 
  346. * @author Vova Feldman (@svovaf) 
  347. * @since 1.1.3 
  348. * 
  349. * @param array $params 
  350. * @param array $ignore_params 
  351. * @param bool $params_prefix 
  352. * 
  353. * @return string 
  354. */ 
  355. function fs_canonize_query_string( array $params, array &$ignore_params, $params_prefix = false ) { 
  356. if ( ! is_array( $params ) || 0 === count( $params ) ) { 
  357. return ''; 
  358.  
  359. // Url encode both keys and values 
  360. $keys = fs_urlencode_rfc3986( array_keys( $params ) ); 
  361. $values = fs_urlencode_rfc3986( array_values( $params ) ); 
  362. $params = array_combine( $keys, $values ); 
  363.  
  364. // Parameters are sorted by name, using lexicographical byte value ordering. 
  365. // Ref: Spec: 9.1.1 (1) 
  366. uksort( $params, 'strcmp' ); 
  367.  
  368. $pairs = array(); 
  369. foreach ( $params as $parameter => $value ) { 
  370. $lower_param = strtolower( $parameter ); 
  371.  
  372. // Skip ignore params. 
  373. if ( in_array( $lower_param, $ignore_params ) || 
  374. ( false !== $params_prefix && fs_starts_with( $lower_param, $params_prefix ) ) 
  375. ) { 
  376. continue; 
  377.  
  378. if ( is_array( $value ) ) { 
  379. // If two or more parameters share the same name, they are sorted by their value 
  380. // Ref: Spec: 9.1.1 (1) 
  381. natsort( $value ); 
  382. foreach ( $value as $duplicate_value ) { 
  383. $pairs[] = $lower_param . '=' . $duplicate_value; 
  384. } else { 
  385. $pairs[] = $lower_param . '=' . $value; 
  386.  
  387. if ( 0 === count( $pairs ) ) { 
  388. return ''; 
  389.  
  390. return implode( "&", $pairs ); 
  391.  
  392. if ( ! function_exists( 'fs_urlencode_rfc3986' ) ) { 
  393. /** 
  394. * @author Vova Feldman (@svovaf) 
  395. * @since 1.1.3 
  396. * 
  397. * @param string|string[] $input 
  398. * 
  399. * @return array|mixed|string 
  400. */ 
  401. function fs_urlencode_rfc3986( $input ) { 
  402. if ( is_array( $input ) ) { 
  403. return array_map( 'fs_urlencode_rfc3986', $input ); 
  404. } else if ( is_scalar( $input ) ) { 
  405. return str_replace( '+', ' ', str_replace( '%7E', '~', rawurlencode( $input ) ) ); 
  406.  
  407. return ''; 
  408.  
  409. #endregion Url Canonization ------------------------------------------------------------------ 
  410.  
  411. function fs_download_image( $from, $to ) { 
  412. $ch = curl_init( $from ); 
  413. $fp = fopen( fs_normalize_path( $to ), 'wb' ); 
  414. curl_setopt( $ch, CURLOPT_FILE, $fp ); 
  415. curl_setopt( $ch, CURLOPT_HEADER, 0 ); 
  416. curl_exec( $ch ); 
  417. curl_close( $ch ); 
  418. fclose( $fp ); 
  419.  
  420. /** General Utilities 
  421. --------------------------------------------------------------------------------------------*/ 
  422.  
  423. /** 
  424. * Sorts an array by the value of the priority key. 
  425. * 
  426. * @author Daniel Iser (@danieliser) 
  427. * @since 1.1.7 
  428. * 
  429. * @param $a 
  430. * @param $b 
  431. * 
  432. * @return int 
  433. */ 
  434. function fs_sort_by_priority( $a, $b ) { 
  435.  
  436. // If b has a priority and a does not, b wins. 
  437. if ( ! isset( $a['priority'] ) && isset( $b['priority'] ) ) { 
  438. return 1; 
  439. } // If b has a priority and a does not, b wins. 
  440. elseif ( isset( $a['priority'] ) && ! isset( $b['priority'] ) ) { 
  441. return - 1; 
  442. } // If neither has a priority or both priorities are equal its a tie. 
  443. elseif ( ( ! isset( $a['priority'] ) && ! isset( $b['priority'] ) ) || $a['priority'] === $b['priority'] ) { 
  444. return 0; 
  445.  
  446. // If both have priority return the winner. 
  447. return ( $a['priority'] < $b['priority'] ) ? - 1 : 1; 
.