PodsView

The Pods - Custom Content Types and Fields PodsView class.

Defined (1)

The class is defined in the following location(s).

/classes/PodsView.php  
  1. class PodsView { 
  2.  
  3. /** 
  4. * @var array $cache_modes Array of available cache modes 
  5. */ 
  6. static $cache_modes = array( 'none', 'transient', 'site-transient', 'cache', 'option-cache' ); 
  7.  
  8. /** 
  9. * @return \PodsView 
  10. */ 
  11. private function __construct() { 
  12.  
  13. /** 
  14. * @static 
  15. * @param string $view Path of the view file 
  16. * @param array|null $data (optional) Data to pass on to the template 
  17. * @param bool|int|array $expires (optional) Time in seconds for the cache to expire, if 0 no expiration. 
  18. * @param string $cache_mode (optional) Decides the caching method to use for the view. 
  19. * @return bool|mixed|null|string|void 
  20. * @since 2.0 
  21. */ 
  22. public static function view( $view, $data = null, $expires = false, $cache_mode = 'cache' ) { 
  23.  
  24. /** 
  25. * Override the value of $view. For example, using Pods AJAX View. 
  26. * To use, set first param to true. If that param in not null, this method returns its value. 
  27. * @param null|bool If not set to null, this filter overrides the rest of the method. 
  28. * @param string $view Path of the view file 
  29. * @param array|null $data (optional) Data to pass on to the template 
  30. * @param bool|int|array $expires (optional) Time in seconds for the cache to expire, if 0 no expiration. 
  31. * @param string $cache_mode (optional) Decides the caching method to use for the view. 
  32. * @returns The value of the first param. 
  33. * @since 2.4.1 
  34. */ 
  35. $filter_check = apply_filters( 'pods_view_alt_view', null, $view, $data, $expires, $cache_mode ); 
  36. if ( !is_null( $filter_check ) ) { 
  37. return $filter_check; 
  38.  
  39.  
  40. // Advanced $expires handling 
  41. $expires = self::expires( $expires, $cache_mode ); 
  42.  
  43. if ( !in_array( $cache_mode, self::$cache_modes ) ) { 
  44. $cache_mode = 'cache'; 
  45.  
  46. // Support my-view.php?custom-key=X#hash keying for cache 
  47. $view_id = ''; 
  48.  
  49. if ( !is_array( $view ) ) { 
  50. $view_q = explode( '?', $view ); 
  51.  
  52. if ( 1 < count( $view_q ) ) { 
  53. $view_id = '?' . $view_q[ 1 ]; 
  54.  
  55. $view = $view_q[ 0 ]; 
  56.  
  57. $view_h = explode( '#', $view ); 
  58.  
  59. if ( 1 < count( $view_h ) ) { 
  60. $view_id .= '#' . $view_h[ 1 ]; 
  61.  
  62. $view = $view_h[ 0 ]; 
  63.  
  64. // Support dynamic tags! 
  65. $view_id = pods_evaluate_tags( $view_id ); 
  66.  
  67. $view = apply_filters( 'pods_view_inc', $view, $data, $expires, $cache_mode ); 
  68.  
  69. $view_key = $view; 
  70.  
  71. if ( is_array( $view_key ) ) { 
  72. $view_key = implode( '-', $view_key ) . '.php'; 
  73.  
  74. if ( false !== realpath( $view_key ) ) { 
  75. $view_key = realpath( $view_key ); 
  76.  
  77. $pods_ui_dir = realpath( PODS_DIR . 'ui/' ); 
  78. $pods_components_dir = realpath( PODS_DIR . 'components/' ); 
  79. $abspath_dir = realpath( ABSPATH ); 
  80.  
  81. $cache_key = pods_str_replace( $abspath_dir, '/', $view_key, 1 ); 
  82.  
  83. $output = false; 
  84.  
  85. $caching = false; 
  86.  
  87. if ( false !== $expires && false === strpos( $view_key, $pods_ui_dir ) && false === strpos( $view_key, $pods_components_dir ) ) { 
  88. $caching = true; 
  89.  
  90. if ( $caching ) { 
  91. $output = self::get( 'pods-view-' . $cache_key . $view_id, $cache_mode, 'pods_view' ); 
  92.  
  93. if ( false === $output || null === $output ) { 
  94. $output = self::get_template_part( $view, $data ); 
  95.  
  96. if ( false !== $output && $caching ) { 
  97. self::set( 'pods-view-' . $cache_key . $view_id, $output, $expires, $cache_mode, 'pods_view' ); 
  98.  
  99. $output = apply_filters( 'pods_view_output_' . $cache_key, $output, $view, $data, $expires, $cache_mode ); 
  100. $output = apply_filters( 'pods_view_output', $output, $view, $data, $expires, $cache_mode ); 
  101.  
  102. return $output; 
  103.  
  104. /** 
  105. * @static 
  106. * @param string $key Key for the cache 
  107. * @param string $cache_mode (optional) Decides the caching method to use for the view. 
  108. * @param string $group (optional) Set the group of the value. 
  109. * @param string $callback (optional) Callback function to run to set the value if not cached. 
  110. * @return bool|mixed|null|void 
  111. * @since 2.0 
  112. */ 
  113. public static function get( $key, $cache_mode = 'cache', $group = '', $callback = null ) { 
  114.  
  115. $object_cache = false; 
  116.  
  117. if ( isset( $GLOBALS[ 'wp_object_cache' ] ) && is_object( $GLOBALS[ 'wp_object_cache' ] ) ) { 
  118. $object_cache = true; 
  119.  
  120. if ( !in_array( $cache_mode, self::$cache_modes ) ) { 
  121. $cache_mode = 'cache'; 
  122.  
  123. $group_key = ''; 
  124.  
  125. if ( !empty( $group ) ) { 
  126. $group_key = $group . '_'; 
  127.  
  128. $original_key = $key; 
  129.  
  130. // Patch for limitations in DB 
  131. if ( 44 < strlen( $group_key . $key ) ) { 
  132. $key = md5( $key ); 
  133.  
  134. if ( empty( $group_key ) ) { 
  135. $group_key = 'pods_'; 
  136.  
  137. $value = null; 
  138.  
  139. $called = false; 
  140.  
  141. $pods_nocache = pods_var_raw( 'pods_nocache' ); 
  142. $nocache = array(); 
  143.  
  144. if ( pods_is_admin() && null !== $pods_nocache ) { 
  145. if ( 1 < strlen( $pods_nocache ) ) { 
  146. $nocache = explode( ', ', $pods_nocache ); 
  147. else { 
  148. $nocache = self::$cache_modes; 
  149.  
  150. if ( apply_filters( 'pods_view_cache_alt_get', false, $cache_mode, $group_key . $key, $original_key, $group ) ) { 
  151. $value = apply_filters( 'pods_view_cache_alt_get_value', $value, $cache_mode, $group_key . $key, $original_key, $group ); 
  152. elseif ( 'transient' == $cache_mode && !in_array( $cache_mode, $nocache ) ) { 
  153. $value = get_transient( $group_key . $key ); 
  154. elseif ( 'site-transient' == $cache_mode && !in_array( $cache_mode, $nocache ) ) { 
  155. $value = get_site_transient( $group_key . $key ); 
  156. elseif ( 'cache' == $cache_mode && $object_cache && !in_array( $cache_mode, $nocache ) ) { 
  157. $value = wp_cache_get( $key, ( empty( $group ) ? 'pods_view' : $group ) ); 
  158. elseif ( 'option-cache' == $cache_mode && !in_array( $cache_mode, $nocache ) ) { 
  159. global $_wp_using_ext_object_cache; 
  160.  
  161. $pre = apply_filters( 'pre_transient_' . $key, false ); 
  162.  
  163. if ( false !== $pre ) { 
  164. $value = $pre; 
  165. elseif ( $_wp_using_ext_object_cache ) { 
  166. $value = wp_cache_get( $key, ( empty( $group ) ? 'pods_option_cache' : $group ) ); 
  167. $timeout = wp_cache_get( '_timeout_' . $key, ( empty( $group ) ? 'pods_option_cache' : $group ) ); 
  168.  
  169. if ( !empty( $timeout ) && $timeout < time() ) { 
  170. if ( is_callable( $callback ) ) { 
  171. // Callback function should do it's own set/update for cache 
  172. $callback_value = call_user_func( $callback, $original_key, $group, $cache_mode ); 
  173.  
  174. if ( null !== $callback_value && false !== $callback_value ) { 
  175. $value = $callback_value; 
  176.  
  177. $called = true; 
  178. else { 
  179. $value = false; 
  180.  
  181. wp_cache_delete( $key, ( empty( $group ) ? 'pods_option_cache' : $group ) ); 
  182. wp_cache_delete( '_timeout_' . $key, ( empty( $group ) ? 'pods_option_cache' : $group ) ); 
  183. else { 
  184. $transient_option = '_pods_option_' . $key; 
  185. $transient_timeout = '_pods_option_timeout_' . $key; 
  186.  
  187. $value = get_option( $transient_option ); 
  188. $timeout = get_option( $transient_timeout ); 
  189.  
  190. if ( !empty( $timeout ) && $timeout < time() ) { 
  191. if ( is_callable( $callback ) ) { 
  192. // Callback function should do it's own set/update for cache 
  193. $callback_value = call_user_func( $callback, $original_key, $group, $cache_mode ); 
  194.  
  195. if ( null !== $callback_value && false !== $callback_value ) { 
  196. $value = $callback_value; 
  197.  
  198. $called = true; 
  199. else { 
  200. $value = false; 
  201.  
  202. delete_option( $transient_option ); 
  203. delete_option( $transient_timeout ); 
  204.  
  205. if ( false !== $value ) { 
  206. $value = apply_filters( 'transient_' . $key, $value ); 
  207. else { 
  208. $value = false; 
  209.  
  210. if ( false === $value && is_callable( $callback ) && !$called ) { 
  211. // Callback function should do it's own set/update for cache 
  212. $callback_value = call_user_func( $callback, $original_key, $group, $cache_mode ); 
  213.  
  214. if ( null !== $callback_value && false !== $callback_value ) { 
  215. $value = $callback_value; 
  216.  
  217. $value = apply_filters( 'pods_view_get_' . $cache_mode, $value, $original_key, $group ); 
  218.  
  219. return $value; 
  220.  
  221. /** 
  222. * @static 
  223. * Set a cached value 
  224. * @param string $key Key for the cache 
  225. * @param mixed $value Value to add to the cache 
  226. * @param int $expires (optional) Time in seconds for the cache to expire, if 0 no expiration. 
  227. * @param string $cache_mode (optional) Decides the caching method to use for the view. 
  228. * @param string $group (optional) Set the group of the value. 
  229. * @return bool|mixed|null|string|void 
  230. * @since 2.0 
  231. */ 
  232. public static function set( $key, $value, $expires = 0, $cache_mode = null, $group = '' ) { 
  233.  
  234. $object_cache = false; 
  235.  
  236. if ( isset( $GLOBALS[ 'wp_object_cache' ] ) && is_object( $GLOBALS[ 'wp_object_cache' ] ) ) { 
  237. $object_cache = true; 
  238.  
  239. // Advanced $expires handling 
  240. $expires = self::expires( $expires, $cache_mode ); 
  241.  
  242. if ( !in_array( $cache_mode, self::$cache_modes ) ) { 
  243. $cache_mode = 'cache'; 
  244.  
  245. $group_key = ''; 
  246.  
  247. if ( !empty( $group ) ) { 
  248. $group_key = $group . '_'; 
  249.  
  250. $original_key = $key; 
  251.  
  252. // Patch for limitations in DB 
  253. if ( 44 < strlen( $group_key . $key ) ) { 
  254. $key = md5( $key ); 
  255.  
  256. if ( empty( $group_key ) ) { 
  257. $group_key = 'pods_'; 
  258.  
  259. if ( apply_filters( 'pods_view_cache_alt_set', false, $cache_mode, $group_key . $key, $original_key, $value, $expires, $group ) ) { 
  260. return $value; 
  261. elseif ( 'transient' == $cache_mode ) { 
  262. set_transient( $group_key . $key, $value, $expires ); 
  263. elseif ( 'site-transient' == $cache_mode ) { 
  264. set_site_transient( $group_key . $key, $value, $expires ); 
  265. elseif ( 'cache' == $cache_mode && $object_cache ) { 
  266. wp_cache_set( $key, $value, ( empty( $group ) ? 'pods_view' : $group ), $expires ); 
  267. elseif ( 'option-cache' == $cache_mode ) { 
  268. global $_wp_using_ext_object_cache; 
  269.  
  270. $value = apply_filters( 'pre_set_transient_' . $key, $value ); 
  271.  
  272. if ( $_wp_using_ext_object_cache ) { 
  273. $result = wp_cache_set( $key, $value, ( empty( $group ) ? 'pods_option_cache' : $group ) ); 
  274.  
  275. if ( $expires ) { 
  276. $result = wp_cache_set( '_timeout_' . $key, $expires, ( empty( $group ) ? 'pods_option_cache' : $group ) ); 
  277. else { 
  278. $transient_timeout = '_pods_option_timeout_' . $key; 
  279. $key = '_pods_option_' . $key; 
  280.  
  281. if ( false === get_option( $key ) ) { 
  282. if ( $expires ) { 
  283. add_option( $transient_timeout, time() + $expires, '', 'no' ); 
  284.  
  285. $result = add_option( $key, $value, '', 'no' ); 
  286. else { 
  287. if ( $expires ) { 
  288. update_option( $transient_timeout, time() + $expires ); 
  289.  
  290. $result = update_option( $key, $value ); 
  291.  
  292. if ( $result ) { 
  293. do_action( 'set_transient_' . $key ); 
  294. do_action( 'setted_transient', $key ); 
  295.  
  296. do_action( 'pods_view_set_' . $cache_mode, $original_key, $value, $expires, $group ); 
  297.  
  298. return $value; 
  299.  
  300. /** 
  301. * @static 
  302. * Clear a cached value 
  303. * @param string|bool $key Key for the cache 
  304. * @param string $cache_mode (optional) Decides the caching method to use for the view. 
  305. * @param string $group (optional) Set the group. 
  306. * @return bool 
  307. * @since 2.0 
  308. */ 
  309. public static function clear( $key = true, $cache_mode = null, $group = '' ) { 
  310.  
  311. $object_cache = false; 
  312.  
  313. if ( isset( $GLOBALS[ 'wp_object_cache' ] ) && is_object( $GLOBALS[ 'wp_object_cache' ] ) ) { 
  314. $object_cache = true; 
  315.  
  316. global $wpdb; 
  317.  
  318. if ( !in_array( $cache_mode, self::$cache_modes ) ) { 
  319. $cache_mode = 'cache'; 
  320.  
  321. $group_key = ''; 
  322.  
  323. if ( !empty( $group ) ) { 
  324. $group_key = $group . '_'; 
  325.  
  326. $full_key = $original_key = $key; 
  327.  
  328. if ( true !== $key ) { 
  329. // Patch for limitations in DB 
  330. if ( 44 < strlen( $group_key . $key ) ) { 
  331. $key = md5( $key ); 
  332.  
  333. if ( empty( $group_key ) ) { 
  334. $group_key = 'pods_'; 
  335.  
  336. $full_key = $group_key . $key; 
  337.  
  338. if ( apply_filters( 'pods_view_cache_alt_set', false, $cache_mode, $full_key, $original_key, '', 0, $group ) ) { 
  339. return true; 
  340. elseif ( 'transient' == $cache_mode ) { 
  341. if ( true === $key ) { 
  342. $group_key = pods_sanitize_like( $group_key ); 
  343.  
  344. $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE option_name LIKE '_transient_{$group_key}%'" ); 
  345.  
  346. if ( $object_cache ) { 
  347. wp_cache_flush(); 
  348. else { 
  349. delete_transient( $group_key . $key ); 
  350. elseif ( 'site-transient' == $cache_mode ) { 
  351. if ( true === $key ) { 
  352. $group_key = pods_sanitize_like( $group_key ); 
  353.  
  354. $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE option_name LIKE '_site_transient_{$group_key}%'" ); 
  355.  
  356. if ( $object_cache ) { 
  357. wp_cache_flush(); 
  358. else { 
  359. delete_site_transient( $group_key . $key ); 
  360. elseif ( 'cache' == $cache_mode && $object_cache ) { 
  361. if ( true === $key ) { 
  362. wp_cache_flush(); 
  363. else { 
  364. wp_cache_delete( ( empty( $key ) ? 'pods_view' : $key ), ( empty( $group ) ? 'pods_view' : $group ) ); 
  365. elseif ( 'option-cache' == $cache_mode ) { 
  366. global $_wp_using_ext_object_cache; 
  367.  
  368. do_action( 'delete_transient_' . $key, $key ); 
  369.  
  370. if ( $_wp_using_ext_object_cache ) { 
  371. $result = wp_cache_delete( $key, ( empty( $group ) ? 'pods_option_cache' : $group ) ); 
  372.  
  373. wp_cache_delete( '_timeout_' . $key, ( empty( $group ) ? 'pods_option_cache' : $group ) ); 
  374. else { 
  375. $option_timeout = '_pods_option_timeout_' . $key; 
  376. $option = '_pods_option_' . $key; 
  377.  
  378. $result = delete_option( $option ); 
  379.  
  380. if ( $result ) { 
  381. delete_option( $option_timeout ); 
  382.  
  383. if ( $result ) { 
  384. do_action( 'deleted_transient', $key ); 
  385.  
  386. do_action( 'pods_view_clear_' . $cache_mode, $original_key, $group ); 
  387.  
  388. return true; 
  389.  
  390. /** 
  391. * @static 
  392. * @param $_view 
  393. * @param null|array $_data 
  394. * @return bool|mixed|string|void 
  395. */ 
  396. public static function get_template_part( $_view, $_data = null ) { 
  397.  
  398. /** to be reviewed later, should have more checks and restrictions like a whitelist etc 
  399. if ( 0 === strpos( $_view, 'http://' ) || 0 === strpos( $_view, 'https://' ) ) { 
  400. $_view = apply_filters( 'pods_view_url_include', $_view ); 
  401.   
  402. if ( empty( $_view ) || ( defined( 'PODS_REMOTE_VIEWS' ) && PODS_REMOTE_VIEWS ) ) 
  403. return ''; 
  404.   
  405. $response = wp_remote_get( $_view ); 
  406.   
  407. return wp_remote_retrieve_body( $response ); 
  408. }*/ 
  409.  
  410. $_view = self::locate_template( $_view ); 
  411.  
  412. if ( empty( $_view ) ) { 
  413. return $_view; 
  414.  
  415. if ( !empty( $_data ) && is_array( $_data ) ) { 
  416. extract( $_data, EXTR_SKIP ); 
  417.  
  418. ob_start(); 
  419. require $_view; 
  420. $output = ob_get_clean(); 
  421.  
  422. return $output; 
  423.  
  424. /** 
  425. * @static 
  426. * @param $_view 
  427. * @return bool|mixed|string|void 
  428. */ 
  429. private static function locate_template( $_view ) { 
  430.  
  431. if ( is_array( $_view ) ) { 
  432. $_views = array(); 
  433.  
  434. if ( isset( $_view[ 0 ] ) && false === strpos( $_view[ 0 ], '.php' ) ) { 
  435. $_view_count = count( $_view ); 
  436.  
  437. for ( $_view_x = $_view_count; 0 < $_view_x; $_view_x-- ) { 
  438. $_view_v = array_slice( $_view, 0, $_view_x ); 
  439.  
  440. $_views[] = implode( '-', $_view_v ) . '.php'; 
  441. else { 
  442. $_views = $_view; 
  443.  
  444. $_view = false; 
  445.  
  446. foreach ( $_views as $_view_check ) { 
  447. $_view = self::locate_template( $_view_check ); 
  448.  
  449. if ( !empty( $_view ) ) { 
  450. break; 
  451.  
  452. return $_view; 
  453.  
  454. // Keep it safe 
  455. $_view = trim( str_replace( array( '../', '\\' ), array( '', '/' ), (string) $_view ) ); 
  456.  
  457. if ( empty( $_view ) ) { 
  458. return false; 
  459.  
  460. $_real_view = realpath( $_view ); 
  461.  
  462. if ( empty( $_real_view ) ) { 
  463. $_real_view = $_view; 
  464.  
  465. $located = false; 
  466.  
  467. // Is the view's file somewhere within the plugin directory tree? 
  468. // Note: we explicitly whitelist PODS_DIR for the case of symlinks (see issue #2945) 
  469. if ( false !== strpos( $_real_view, realpath( WP_PLUGIN_DIR ) ) || 
  470. false !== strpos( $_real_view, realpath( WPMU_PLUGIN_DIR ) ) || 
  471. false !== strpos( $_real_view, PODS_DIR ) 
  472. ) { 
  473. if ( file_exists( $_view ) ) { 
  474. $located = $_view; 
  475. else { 
  476. $located = apply_filters( 'pods_view_locate_template', $located, $_view ); 
  477.  
  478. } else { // The view's file is outside the plugin directory 
  479. $_real_view = trim( $_real_view, '/' ); 
  480.  
  481. if ( empty( $_real_view ) ) { 
  482. return false; 
  483.  
  484. // Allow views in the theme or child theme 
  485. if ( file_exists( realpath( get_stylesheet_directory() . '/' . $_real_view ) ) ) { 
  486. $located = realpath( get_stylesheet_directory() . '/' . $_real_view ); 
  487. elseif ( file_exists( realpath( get_template_directory() . '/' . $_real_view ) ) ) { 
  488. $located = realpath( get_template_directory() . '/' . $_real_view ); 
  489.  
  490. return $located; 
  491.  
  492.  
  493. /** 
  494. * Advanced $expires handling 
  495. * @param array|bool|int $expires 
  496. * @param string $cache_mode 
  497. * @return bool|int 
  498. * @since 3.0 
  499. * @static 
  500. */ 
  501. public static function expires( $expires, $cache_mode = 'cache' ) { 
  502.  
  503. // Different $expires if user is anonymous or logged in or specific capability 
  504. if ( is_array( $expires ) ) { 
  505. if ( ( isset( $expires[ 'anonymous' ] ) || isset( $expires[ 'user_with_access' ] ) ) && isset( $expires[ 'user' ] ) ) { 
  506. if ( isset( $expires[ 'user_with_access' ] ) ) { 
  507. $expires = array( 
  508. pods_var_raw( 'anonymous', $expires, false ),  
  509. pods_var_raw( 'user', $expires, false ),  
  510. pods_var_raw( 'user_with_access', $expires, false ),  
  511. pods_var_raw( 'capability', $expires, null, null, true ) 
  512. ); 
  513. elseif ( isset( $expires[ 'anonymous' ] ) ) { 
  514. $expires = array( 
  515. pods_var_raw( 'anonymous', $expires, false ),  
  516. pods_var_raw( 'user', $expires, false ),  
  517. pods_var_raw( 'capability', $expires, null, null, true ) 
  518. ); 
  519. else { 
  520. $expires = array_values( $expires ); 
  521.  
  522. if ( 4 == count( $expires ) ) { 
  523. if ( !is_user_logged_in() ) { 
  524. $expires = pods_var_raw( 0, $expires, false ); 
  525. else { 
  526. $user_no_access = pods_var_raw( 1, $expires, false ); 
  527. $user_with_access = pods_var_raw( 2, $expires, false ); 
  528. $capability = pods_var_raw( 3, $expires, null, null, true ); 
  529.  
  530. $expires = pods_var_user( $user_no_access, $user_with_access, $capability ); 
  531. else { 
  532. $anon = pods_var_raw( 0, $expires, false ); 
  533. $user = pods_var_raw( 1, $expires, false ); 
  534. $capability = pods_var_raw( 2, $expires, null, null, true ); 
  535.  
  536. $expires = pods_var_user( $anon, $user, $capability ); 
  537.  
  538. if ( 'none' == $cache_mode ) { 
  539. $expires = false; 
  540. elseif ( false !== $expires ) { 
  541. $expires = (int) $expires; 
  542.  
  543. if ( $expires < 1 ) { 
  544. $expires = 0; 
  545.  
  546. return $expires; 
  547.  
  548.  
  549. private static function filter_callback( $value ) { 
  550.  
  551. if ( in_array( $value, array( '', null, false ) ) ) { 
  552. return false; 
  553.  
  554. return true;