PageRenderTime 38ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/components/Templates.php

https://github.com/ElmsPark/pods
PHP | 467 lines | 252 code | 82 blank | 133 comment | 45 complexity | 589d3b2ce177442ae86a709505d31f46 MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. * Name: Templates
  4. *
  5. * Description: An easy to use templating engine for Pods. Use {@field_name} magic tags to output values, within your HTML markup.
  6. *
  7. * Version: 2.0
  8. *
  9. * Category: Advanced
  10. *
  11. * Menu Page: edit.php?post_type=_pods_template
  12. * Menu Add Page: post-new.php?post_type=_pods_template
  13. *
  14. * @package Pods\Components
  15. * @subpackage Templates
  16. */
  17. class Pods_Templates extends PodsComponent {
  18. /**
  19. * Pods object
  20. *
  21. * @var object
  22. *
  23. * @since 2.0.0
  24. */
  25. static $obj = null;
  26. /**
  27. * Whether to enable deprecated functionality based on old function usage
  28. *
  29. * @var bool
  30. *
  31. * @since 2.0.0
  32. */
  33. static $deprecated = false;
  34. /**
  35. * Object type
  36. *
  37. * @var string
  38. *
  39. * @since 2.0.0
  40. */
  41. private $object_type = '_pods_template';
  42. /**
  43. * Do things like register/enqueue scripts and stylesheets
  44. *
  45. * @since 2.0.0
  46. */
  47. public function __construct () {
  48. $args = array(
  49. 'label' => 'Pod Templates',
  50. 'labels' => array( 'singular_name' => 'Pod Template' ),
  51. 'public' => false,
  52. 'can_export' => false,
  53. 'show_ui' => true,
  54. 'show_in_menu' => false,
  55. 'query_var' => false,
  56. 'rewrite' => false,
  57. 'has_archive' => false,
  58. 'hierarchical' => false,
  59. 'supports' => array( 'title', 'author', 'revisions' ),
  60. 'menu_icon' => PODS_URL . 'ui/images/icon16.png'
  61. );
  62. if ( !is_super_admin() )
  63. $args[ 'capability_type' ] = 'pods_template';
  64. $args = PodsInit::object_label_fix( $args, 'post_type' );
  65. register_post_type( $this->object_type, apply_filters( 'pods_internal_register_post_type_object_template', $args ) );
  66. if ( is_admin() ) {
  67. add_filter( 'post_updated_messages', array( $this, 'setup_updated_messages' ), 10, 1 );
  68. add_action( 'dbx_post_advanced', array( $this, 'edit_page_form' ), 10 );
  69. add_action( 'pods_meta_groups', array( $this, 'add_meta_boxes' ) );
  70. add_filter( 'get_post_metadata', array( $this, 'get_meta' ), 10, 4 );
  71. add_filter( 'update_post_metadata', array( $this, 'save_meta' ), 10, 4 );
  72. add_action( 'pods_meta_save_pre_post__pods_template', array( $this, 'fix_filters' ), 10, 5 );
  73. add_action( 'post_updated', array( $this, 'clear_cache' ), 10, 3 );
  74. add_action( 'delete_post', array( $this, 'clear_cache' ), 10, 1 );
  75. add_filter( 'post_row_actions', array( $this, 'remove_row_actions' ), 10, 2 );
  76. add_filter( 'bulk_actions-edit-' . $this->object_type, array( $this, 'remove_bulk_actions' ) );
  77. add_filter( 'builder_layout_filter_non_layout_post_types', array( $this, 'disable_builder_layout' ) );
  78. }
  79. }
  80. public function disable_builder_layout ( $post_types ) {
  81. $post_types[] = $this->object_type;
  82. return $post_types;
  83. }
  84. /**
  85. * Update Post Type messages
  86. *
  87. * @param array $messages
  88. *
  89. * @return array
  90. * @since 2.0.2
  91. */
  92. public function setup_updated_messages ( $messages ) {
  93. global $post, $post_ID;
  94. $post_type = get_post_type_object( $this->object_type );
  95. $labels = $post_type->labels;
  96. $messages[ $post_type->name ] = array(
  97. 1 => sprintf( __( '%s updated. <a href="%s">%s</a>', 'pods' ), $labels->singular_name, esc_url( get_permalink( $post_ID ) ), $labels->view_item ),
  98. 2 => __( 'Custom field updated.', 'pods' ),
  99. 3 => __( 'Custom field deleted.', 'pods' ),
  100. 4 => sprintf( __( '%s updated.', 'pods' ), $labels->singular_name ),
  101. /* translators: %s: date and time of the revision */
  102. 5 => isset( $_GET[ 'revision' ] ) ? sprintf( __( '%s restored to revision from %s', 'pods' ), $labels->singular_name, wp_post_revision_title( (int) $_GET[ 'revision' ], false ) ) : false,
  103. 6 => sprintf( __( '%s published. <a href="%s">%s</a>', 'pods' ), $labels->singular_name, esc_url( get_permalink( $post_ID ) ), $labels->view_item ),
  104. 7 => sprintf( __( '%s saved.', 'pods' ), $labels->singular_name ),
  105. 8 => sprintf( __( '%s submitted. <a target="_blank" href="%s">Preview %s</a>', 'pods' ),
  106. $labels->singular_name,
  107. esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ),
  108. $labels->singular_name
  109. ),
  110. 9 => sprintf( __( '%s scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview %s</a>', 'pods' ),
  111. $labels->singular_name,
  112. // translators: Publish box date format, see http://php.net/date
  113. date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ),
  114. esc_url( get_permalink( $post_ID ) ),
  115. $labels->singular_name
  116. ),
  117. 10 => sprintf( __( '%s draft updated. <a target="_blank" href="%s">Preview %s</a>', 'pods' ), $labels->singular_name, esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ), $labels->singular_name )
  118. );
  119. if ( false === (boolean) $post_type->public ) {
  120. $messages[ $post_type->name ][ 1 ] = sprintf( __( '%s updated.', 'pods' ), $labels->singular_name );
  121. $messages[ $post_type->name ][ 6 ] = sprintf( __( '%s published.', 'pods' ), $labels->singular_name );
  122. $messages[ $post_type->name ][ 8 ] = sprintf( __( '%s submitted.', 'pods' ), $labels->singular_name );
  123. $messages[ $post_type->name ][ 9 ] = sprintf( __( '%s scheduled for: <strong>%1$s</strong>.', 'pods' ),
  124. $labels->singular_name,
  125. // translators: Publish box date format, see http://php.net/date
  126. date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) )
  127. );
  128. $messages[ $post_type->name ][ 10 ] = sprintf( __( '%s draft updated.', 'pods' ), $labels->singular_name );
  129. }
  130. return $messages;
  131. }
  132. /**
  133. * Enqueue styles
  134. *
  135. * @since 2.0.0
  136. */
  137. public function admin_assets () {
  138. wp_enqueue_style( 'pods-admin' );
  139. }
  140. /**
  141. * Fix filters, specifically removing balanceTags
  142. *
  143. * @since 2.0.1
  144. */
  145. public function fix_filters ( $data, $pod = null, $id = null, $groups = null, $post = null ) {
  146. remove_filter( 'content_save_pre', 'balanceTags', 50 );
  147. }
  148. /**
  149. * Remove unused row actions
  150. *
  151. * @since 2.0.5
  152. */
  153. function remove_row_actions ( $actions, $post ) {
  154. global $current_screen;
  155. if ( $this->object_type != $current_screen->post_type )
  156. return $actions;
  157. if ( isset( $actions[ 'view' ] ) )
  158. unset( $actions[ 'view' ] );
  159. if ( isset( $actions[ 'inline hide-if-no-js' ] ) )
  160. unset( $actions[ 'inline hide-if-no-js' ] );
  161. // W3 Total Cache
  162. if ( isset( $actions[ 'pgcache_purge' ] ) )
  163. unset( $actions[ 'pgcache_purge' ] );
  164. return $actions;
  165. }
  166. /**
  167. * Remove unused bulk actions
  168. *
  169. * @since 2.0.5
  170. */
  171. public function remove_bulk_actions ( $actions ) {
  172. if ( isset( $actions[ 'edit' ] ) )
  173. unset( $actions[ 'edit' ] );
  174. return $actions;
  175. }
  176. /**
  177. * Clear cache on save
  178. *
  179. * @since 2.0.0
  180. */
  181. public function clear_cache ( $data, $pod = null, $id = null, $groups = null, $post = null ) {
  182. if ( !is_array( $data ) && 0 < $data ) {
  183. $post = $data;
  184. $post = get_post( $post );
  185. if ( is_object( $id ) ) {
  186. $old_post = $id;
  187. pods_transient_clear( 'pods_object_template_' . $old_post->post_name );
  188. }
  189. }
  190. if ( $this->object_type != $post->post_type )
  191. return;
  192. pods_transient_clear( 'pods_object_template' );
  193. pods_transient_clear( 'pods_object_template_' . $post->post_name );
  194. }
  195. /**
  196. * Change post title placeholder text
  197. *
  198. * @since 2.0.0
  199. */
  200. public function set_title_text ( $text, $post ) {
  201. return __( 'Enter template name here', 'pods' );
  202. }
  203. /**
  204. * Edit page form
  205. *
  206. * @since 2.0.0
  207. */
  208. public function edit_page_form () {
  209. global $post_type;
  210. if ( $this->object_type != $post_type )
  211. return;
  212. add_filter( 'enter_title_here', array( $this, 'set_title_text' ), 10, 2 );
  213. }
  214. /**
  215. * Add meta boxes to the page
  216. *
  217. * @since 2.0.0
  218. */
  219. public function add_meta_boxes () {
  220. $pod = array(
  221. 'name' => $this->object_type,
  222. 'type' => 'post_type'
  223. );
  224. if ( isset( PodsMeta::$post_types[ $pod[ 'name' ] ] ) )
  225. return;
  226. $fields = array(
  227. array(
  228. 'name' => 'code',
  229. 'label' => __( 'Content', 'pods' ),
  230. 'type' => 'code'
  231. )
  232. );
  233. pods_group_add( $pod, __( 'Template', 'pods' ), $fields, 'normal', 'high' );
  234. $fields = array(
  235. array(
  236. 'name' => 'admin_only',
  237. 'label' => __( 'Show to Admins Only?', 'pods' ),
  238. 'default' => 0,
  239. 'type' => 'boolean',
  240. 'dependency' => true
  241. ),
  242. array(
  243. 'name' => 'restrict_capability',
  244. 'label' => __( 'Restrict access by Capability?', 'pods' ),
  245. 'default' => 0,
  246. 'type' => 'boolean',
  247. 'dependency' => true
  248. ),
  249. array(
  250. 'name' => 'capability_allowed',
  251. 'label' => __( 'Capability Allowed', 'pods' ),
  252. 'help' => __( 'Comma-separated list of cababilities, for example add_podname_item, please see the Roles and Capabilities component for the complete list and a way to add your own.', 'pods' ),
  253. 'type' => 'text',
  254. 'default' => '',
  255. 'depends-on' => array( 'restrict_capability' => true )
  256. )
  257. );
  258. pods_group_add( $pod, __( 'Restrict Access', 'pods' ), $fields, 'normal', 'high' );
  259. }
  260. /**
  261. * Get the fields
  262. *
  263. * @param null $_null
  264. * @param int $post_ID
  265. * @param string $meta_key
  266. * @param bool $single
  267. *
  268. * @return array|bool|int|mixed|null|string|void
  269. */
  270. public function get_meta ( $_null, $post_ID = null, $meta_key = null, $single = false ) {
  271. if ( 'code' == $meta_key ) {
  272. $post = get_post( $post_ID );
  273. if ( is_object( $post ) && $this->object_type == $post->post_type )
  274. return $post->post_content;
  275. }
  276. return $_null;
  277. }
  278. /**
  279. * Save the fields
  280. *
  281. * @param $_null
  282. * @param int $post_ID
  283. * @param string $meta_key
  284. * @param string $meta_value
  285. *
  286. * @return bool|int|null
  287. */
  288. public function save_meta ( $_null, $post_ID = null, $meta_key = null, $meta_value = null ) {
  289. if ( 'code' == $meta_key ) {
  290. $post = get_post( $post_ID );
  291. if ( is_object( $post ) && $this->object_type == $post->post_type ) {
  292. $postdata = array(
  293. 'ID' => $post_ID,
  294. 'post_content' => pods_sanitize( $meta_value )
  295. );
  296. remove_filter( current_filter(), array( $this, __FUNCTION__ ), 10 );
  297. $revisions = false;
  298. if ( has_action( 'pre_post_update', 'wp_save_post_revision' ) ) {
  299. remove_action( 'pre_post_update', 'wp_save_post_revision' );
  300. $revisions = true;
  301. }
  302. wp_update_post( $postdata );
  303. if ( $revisions )
  304. add_action( 'pre_post_update', 'wp_save_post_revision' );
  305. return true;
  306. }
  307. }
  308. return $_null;
  309. }
  310. /**
  311. * Display the page template
  312. *
  313. * @param string $template The template name
  314. * @param string $code Custom template code to use instead
  315. * @param object $obj The Pods object
  316. * @param bool $deprecated Whether to use deprecated functionality based on old function usage
  317. *
  318. * @return mixed|string|void
  319. * @since 2.0.0
  320. */
  321. public static function template ( $template, $code = null, $obj = null, $deprecated = false ) {
  322. if ( !empty( $obj ) )
  323. self::$obj =& $obj;
  324. else
  325. $obj =& self::$obj;
  326. self::$deprecated = $deprecated;
  327. if ( empty( $obj ) || !is_object( $obj ) )
  328. return '';
  329. if ( empty( $code ) && !empty( $template ) ) {
  330. $template = $obj->api->load_template( array( 'name' => $template ) );
  331. if ( !empty( $template ) ) {
  332. if ( !empty( $template[ 'code' ] ) )
  333. $code = $template[ 'code' ];
  334. $permission = pods_permission( $template[ 'options' ] );
  335. $permission = (boolean) apply_filters( 'pods_templates_permission', $permission, $code, $template, $obj );
  336. if ( !$permission ) {
  337. return apply_filters( 'pods_templates_permission_denied', __( 'You do not have access to view this content.', 'pods' ), $code, $template, $obj );
  338. }
  339. }
  340. }
  341. $code = apply_filters( 'pods_templates_pre_template', $code, $template, $obj );
  342. $code = apply_filters( 'pods_templates_pre_template_' . $template[ 'slug' ], $code, $template, $obj );
  343. ob_start();
  344. if ( !empty( $code ) ) {
  345. // Only detail templates need $this->id
  346. if ( empty( $obj->id ) ) {
  347. while ( $obj->fetch() ) {
  348. echo self::do_template( $code, $obj );
  349. }
  350. }
  351. else
  352. echo self::do_template( $code, $obj );
  353. }
  354. $out = ob_get_clean();
  355. $out = apply_filters( 'pods_templates_post_template', $out, $code, $template, $obj );
  356. $out = apply_filters( 'pods_templates_post_template_' . $template[ 'slug' ], $out, $code, $template, $obj );
  357. return $out;
  358. }
  359. /**
  360. * Parse a template string
  361. *
  362. * @param string $code The template string to parse
  363. * @param object $obj The Pods object
  364. *
  365. * @since 1.8.5
  366. */
  367. public static function do_template ( $code, $obj = null ) {
  368. if ( !empty( $obj ) )
  369. self::$obj =& $obj;
  370. else
  371. $obj =& self::$obj;
  372. if ( empty( $obj ) || !is_object( $obj ) )
  373. return '';
  374. $code = str_replace( '$this->', '$obj->', $code );
  375. if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
  376. ob_start();
  377. eval( "?>$code" );
  378. $out = ob_get_clean();
  379. }
  380. else
  381. $out = $code;
  382. $out = $obj->do_magic_tags( $out );
  383. return apply_filters( 'pods_templates_do_template', $out, $code, $obj );
  384. }
  385. }