PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/components/Advanced-Templates/Advanced-Templates.php

https://github.com/ElmsPark/pods
PHP | 821 lines | 462 code | 105 blank | 254 comment | 90 complexity | fe6d071fc5a4bf17d304c6ced82a1d7f MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. * Name: Advanced Templates
  4. *
  5. * Description: Creates advanced view templates for displaying Pod data on the front end via a Shortcode.
  6. *
  7. * Version: <strong>PROTOTYPE</strong>
  8. *
  9. * Category: Advanced
  10. *
  11. * Developer Mode: on
  12. *
  13. * Menu Page: edit.php?post_type=_pods_adv_template
  14. * Menu Add Page: post-new.php?post_type=_pods_adv_template
  15. * @package Pods\Components
  16. * @subpackage Advanced Templates
  17. */
  18. /**
  19. * ==Disclaimer==
  20. * I have not worked on Pods before, nor seen any of the code,
  21. * so please go easy on me.
  22. * I still dont know the api or your coding standards so I'm just winging it for now.
  23. * I do hope that my thought patterns are not to far off others.
  24. *
  25. *
  26. *
  27. * ==SOME NOTES==
  28. *
  29. * Comments:
  30. * I still struggle to comment my work effectivly. I will try to be more consistant.
  31. *
  32. * The UI:
  33. * I know some people are very much against custom UI's in WordPress.
  34. * I did try with the WordPress UI, but space became an issue and somethings
  35. * just wouldn't work.
  36. * I did try model the Editor UI within Wordpress so it looked at least like it belonged.
  37. * Please let me know if it will be an issue.
  38. *
  39. * What it does:
  40. * This aim of this component is to allow you build wrapper elements around a pod,
  41. * and display it on a page via a shortcode or as a widget.
  42. *
  43. * I'm not sure of the name "Advanced Templates" but I'll leave it for now.
  44. * Maybe something like Pod Elements or what ever.
  45. *
  46. * It current just works on a loop. I'm going to add options to set the template up
  47. * for single view, list, parameters setting, things like that...
  48. *
  49. * Anyway, this is just a prototype component to help me learn and understand pods better
  50. * and hey, It might be useful.
  51. *
  52. * ~ David
  53. *
  54. */
  55. class Pods_Advanced_Templates extends PodsComponent {
  56. /**
  57. * object type
  58. *
  59. * @since 0.1
  60. */
  61. private $object_type = '_pods_adv_template';
  62. /**
  63. * component name
  64. *
  65. * @since 0.1
  66. */
  67. private $component_name = 'Advanced Templates';
  68. /**
  69. * menu name for switching between post type and custom UI
  70. *
  71. * @since 0.1
  72. */
  73. private $pods_menu = 'pods';
  74. /**
  75. * template buffer
  76. *
  77. * @since 0.1
  78. */
  79. private $template_data = array();
  80. /**
  81. * burrered list of pods
  82. *
  83. * @since 0.1
  84. */
  85. private $pods_list = array();
  86. /**
  87. * footer scripts buffer
  88. *
  89. * @since 0.1
  90. */
  91. private $template_foot;
  92. /**
  93. * shortcodes used buffer
  94. *
  95. * @since 0.1
  96. */
  97. private $shortcodes_used;
  98. /**
  99. * header buffer
  100. *
  101. * @since 0.1
  102. */
  103. private $template_head;
  104. public function __construct() {
  105. #populate the pods list
  106. $api = pods_api();
  107. $this->pods_list = $api->load_pods();
  108. # register out templates post type
  109. $args = array(
  110. 'label' => 'Advanced Templates',
  111. 'labels' => array('singular_name' => 'Pod Advanced Template'),
  112. 'public' => false,
  113. 'can_export' => false,
  114. 'show_ui' => true,
  115. 'show_in_menu' => false,
  116. 'query_var' => false,
  117. 'rewrite' => false,
  118. 'has_archive' => false,
  119. 'hierarchical' => false,
  120. 'supports' => array('title', 'author', 'revisions'),
  121. 'menu_icon' => PODS_URL . 'ui/images/icon16.png'
  122. );
  123. if (!is_super_admin())
  124. $args['capability_type'] = 'pods_adv_template';
  125. $args = PodsInit::object_label_fix($args, 'post_type');
  126. register_post_type($this->object_type, apply_filters('pods_internal_register_post_type_object_adv_template', $args));
  127. if (is_admin()) {
  128. # on save finds and caches used shortcodes so we dont need to check on each page load
  129. add_action('post_updated', array($this, 'build_cache'), 10, 3);
  130. # Clear the cache of used shortcodes on delete
  131. add_action('delete_post', array($this, 'clear_cache'), 10, 1);
  132. add_filter('post_row_actions', array($this, 'remove_row_actions'), 10, 2);
  133. add_filter('bulk_actions-edit-' . $this->object_type, array($this, 'remove_bulk_actions'));
  134. #custom list view
  135. add_filter('manage_' . $this->object_type . '_posts_columns', array($this, 'edit_columns'));
  136. add_action('manage_' . $this->object_type . '_posts_custom_column', array($this, 'column_content'), 10, 2);
  137. } else {
  138. # Prefetch page ID for hooking in early so we can the PHP early.
  139. # This allows a template to be able to add_actions and filters
  140. add_action('init', array($this, 'pre_process'), 1);
  141. }
  142. #early saving from the custom UI screen
  143. if (isset($_POST['_wpnonce'])) {
  144. if (wp_verify_nonce($_POST['_wpnonce'], 'pat-edit-template')) {
  145. unset($_POST['_wpnonce']);
  146. unset($_POST['_wp_http_referer']);
  147. $data = stripslashes_deep($_POST['data']);
  148. $shortcodes = get_transient('pods_advtemplates');
  149. # Manually build a custom post for a template
  150. $templateArgs = array(
  151. 'post_name' => $data['slug'],
  152. 'post_title' => $data['name'],
  153. 'post_type' => '_pods_adv_template'
  154. );
  155. if (!empty($data['pod']))
  156. $templateArgs['post_status'] = 'publish';
  157. else
  158. # if there is no pod attached, draft it.
  159. $templateArgs['post_status'] = 'draft';
  160. # Create or insert a template
  161. if (!empty($data['ID'])) {
  162. $templateArgs['ID'] = $data['ID'];
  163. $lastPost = wp_update_post($templateArgs);
  164. } else {
  165. $lastPost = wp_insert_post($templateArgs);
  166. }
  167. # Save template settings as a post meta.
  168. update_post_meta($lastPost, '_pods_adv_template', $data);
  169. # Add shortcode to shortcode list.
  170. $shortcodes[$lastPost] = $data['slug'];
  171. set_transient('pods_advtemplates', $shortcodes);
  172. # Send back to post type manager
  173. wp_redirect('edit.php?post_type='.$this->object_type.'&last=' . $lastPost);
  174. die;
  175. }
  176. }
  177. # Grab the default edit page - direct to UI
  178. # Editing: redirect with edit=ID
  179. if (isset($_GET['post']) && isset($_GET['action'])) {
  180. # Check if its our post type
  181. if ($this->object_type == get_post_type($_GET['post']) && $_GET['action'] == 'edit') {
  182. wp_redirect('admin.php?page=pods-component-advanced-templates&edit=' . $_GET['post']);
  183. die;
  184. }
  185. }
  186. # Editing: new template
  187. if (isset($_GET['post_type'])) {
  188. # if its a new post - send to the ui as a new tempalte
  189. if ($this->object_type == $_GET['post_type'] && 'post-new.php' == basename($_SERVER['SCRIPT_NAME'])) {
  190. wp_redirect('admin.php?page=pods-component-advanced-templates&edit');
  191. die;
  192. }
  193. }
  194. # Admin: Send to admin UI
  195. if (!empty($_GET['page'])) {
  196. if ('pods-component-advanced-templates' == $_GET['page'] && !isset($_GET['edit'])) {
  197. wp_redirect('edit.php?post_type='.$this->object_type);
  198. die;
  199. } elseif ('pods-component-advanced-templates' == $_GET['page'] && isset($_GET['edit'])) {
  200. # Switch menu type from post type to admin ui.
  201. # This overides the post type to a page
  202. add_action('admin_menu', array($this, 'admin_menu_switch'), 101);
  203. }
  204. }
  205. }
  206. /**
  207. * Pickup prescan the content to find shortcodes being used,
  208. * then push headers .
  209. * This needs to be done on init action to allow the use of adding actions and filters
  210. * in the PHP tab of a template.
  211. *
  212. */
  213. function pre_process() {
  214. /**
  215. * Not the best way to do it, does not support custom types.
  216. * I'm basically guessing my way through this.
  217. * Any suggestions?
  218. */
  219. # Convert request URL to post ID
  220. $postID = url_to_postid($_SERVER['REQUEST_URI']);
  221. if (empty($postID)) {
  222. # It may be a front page item
  223. $frontPage = get_option('page_on_front');
  224. if (!empty($frontPage)) {
  225. # Get the front page
  226. $posts[] = get_post($frontPage);
  227. } else {
  228. # Blog page, get the posts being shown
  229. $args = array(
  230. 'numberposts' => get_option('posts_per_page')
  231. );
  232. $posts = get_posts($args);
  233. }
  234. } else {
  235. # Found the ID, load it up.
  236. $posts[] = get_post($postID);
  237. }
  238. # Cant find anything, just get out.
  239. if (empty($posts))
  240. return;
  241. # Load up the cache of shortcode tempaltes used on this page
  242. $usedCache = get_transient('pods_adv_template_used');
  243. #loop through the posts found
  244. foreach ($posts as $post) {
  245. # If there are shortcode templates used on this post process it.
  246. if (!empty($usedCache[$post->ID])) {
  247. # Get the template used
  248. foreach ($usedCache[$post->ID] as $template => $code) {
  249. #load up the template or use it if its been used already
  250. if(!isset($this->shortcodes_used[$code])){
  251. $templateData = get_post_meta($template, '_pods_adv_template', true);
  252. $this->shortcodes_used[$code] = $templateData;
  253. }else{
  254. $templateData = $this->shortcodes_used[$code];
  255. }
  256. # Dynamically add the shortcode so we dont need to register everything.
  257. add_shortcode($code, array($this, 'render_shortcode'));
  258. #Execute the PHP code of the template.
  259. # Any add_filter or add_action for after init will now work
  260. # Any php function should be available
  261. if (!empty($templateData['phpCode'])) {
  262. eval($templateData['phpCode']);
  263. }
  264. # enqueue external script libraries correctly.
  265. if (!empty($templateData['jsLib'])) {
  266. foreach ($templateData['jsLib'] as $key => $url) {
  267. $in_footer = 0;
  268. if (2 == (int) $templateData['jsLibLoc'][$key]) {
  269. $in_footer = 1;
  270. }
  271. wp_enqueue_script('adv-' . $key, $url, array(), false, $in_footer);
  272. }
  273. }
  274. # enqueue external CSS libraries correctly.
  275. if (!empty($templateData['cssLib'])) {
  276. foreach ($templateData['cssLib'] as $key => $url) {
  277. wp_enqueue_style('adv-' . $key, $url);
  278. }
  279. }
  280. # Process CSS and Build in the Cache file.
  281. # PHP is available to make it more dynamic.
  282. ob_start();
  283. eval(' ?>' . $templateData['cssCode']);
  284. $Css = ob_get_clean();
  285. # build a temp file for this and register its existance
  286. $cssCache = get_transient('_pods_adv_template_css_cache');
  287. $cachePath = wp_upload_dir();
  288. $cssHash = md5($Css);
  289. if (!file_exists($cachePath['basedir'] . '/cache')) {
  290. mkdir($cachePath['basedir'] . '/cache');
  291. }
  292. # check cache and clear exired items
  293. if (empty($cssCache)) {
  294. $cssCache = array();
  295. } else {
  296. # cleanout expired stuff
  297. foreach ($cssCache as $cachefile => $expire) {
  298. if (mktime() - $expire > 0) {
  299. unlink($cachePath['basedir'] . '/cache/' . $cachefile . '.css');
  300. unset($cssCache[$cachefile]);
  301. }
  302. }
  303. }
  304. # make new cache file
  305. $tempfile = $cachePath['basedir'] . '/cache/' . $cssHash . '.css';
  306. $cached = true;
  307. if (!file_exists($tempfile)) {
  308. # write new file
  309. $cached = false;
  310. $fp = @fopen($tempfile, 'w+');
  311. if ($fp) {
  312. $cached = true;
  313. fwrite($fp, $Css);
  314. fclose($fp);
  315. $cssCache[$cssHash] = strtotime('+5 days');
  316. set_transient('_pods_adv_template_css_cache', $cssCache);
  317. }
  318. }
  319. if ($cached) {
  320. # enqueue cache file correctly
  321. wp_enqueue_style($cssHash, $cachePath['baseurl'] . '/cache/' . $cssHash . '.css');
  322. } else {
  323. # resort to header placement if cant write the file
  324. $this->template_head .= "<style type=\"text/css\">\n" . $Css . "\n</stlyle>\n";
  325. }
  326. # Buffer the javascript tab content for the footer.
  327. if (!empty($templateData['javascriptCode'])) {
  328. $this->template_foot .= "\n" . $templateData['javascriptCode'];
  329. add_action('wp_footer', array($this, 'footer_scripts'));
  330. }
  331. }
  332. }
  333. }
  334. }
  335. /**
  336. * Render Shortcode
  337. * Still got work to do here!
  338. */
  339. function render_shortcode($content, $args, $code) {
  340. # get the pod
  341. # Will do sorting, finding and stuff like that later. for now, its a test with the data as a whole.
  342. $pods = pods($this->pods_list[$this->shortcodes_used[$code]['pod']]['name']);
  343. # Just get everything for now.
  344. $pods->find();
  345. # find the loop statment to get the loopable area for each pod record.
  346. $pattern = '\[(\[?)(loop)\b([^\]\/]*(?:\/(?!\])[^\]\/]*)*?)(?:(\/)\]|\](?:([^\[]*+(?:\[(?!\/\2\])[^\[]*+)*+)\[\/\2\])?)(\]?)';
  347. preg_match_all('/' . $pattern . '/s', $this->shortcodes_used[$code]['htmlCode'], $loops);
  348. if (!empty($loops)) {
  349. foreach ($loops[0] as $loopKey => $loopcode) {
  350. if (!empty($loops[2][$loopKey]) && !empty($loops[5][$loopKey])) {
  351. $this->shortcodes_used[$code]['htmlCode'] = str_replace($loopcode, Pods_Templates::template(null, $loops[5][$loopKey], $pods), $this->shortcodes_used[$code]['htmlCode']);
  352. }
  353. }
  354. ob_start();
  355. eval('?> ' . $this->shortcodes_used[$code]['htmlCode']);
  356. $return = ob_get_clean();
  357. }else{
  358. # Push the full template as a loop
  359. # Process php in the template
  360. ob_start();
  361. eval('?> ' . $this->shortcodes_used[$code]['htmlCode']);
  362. $this->shortcodes_used[$code]['htmlCode'] = ob_get_clean();
  363. vardump($pods);
  364. # Push it to the template renderer
  365. $return = Pods_Templates::template(null, $this->shortcodes_used[$code]['htmlCode'], $pods);
  366. }
  367. # Do it again for embeded shortcodes in the templates.
  368. return do_shortcode($return);
  369. }
  370. /**
  371. * Get list of used Shortcodes in the content provided
  372. * Recursive to find any shortcode templates within templates
  373. * This allows header libs and php etc. to load correctly in embeded codes
  374. */
  375. function get_used($content, $codes) {
  376. /**
  377. * I may want to cache this process.
  378. */
  379. $codesList = array();
  380. foreach ($codes as $id => $code) {
  381. $codesList[$code] = $id;
  382. }
  383. $tagregexp = join('|', array_map('preg_quote', $codes));
  384. # Just pulled in the code from WP get_regex and customizzed it to only
  385. # look for shortcodes of templates we've made.
  386. $regex =
  387. '\\[' # Opening bracket
  388. . '(\\[?)' # 1: Optional second opening bracket for escaping shortcodes: [[tag]]
  389. . "($tagregexp)" # 2: Shortcode name
  390. . '\\b' # Word boundary
  391. . '(' # 3: Unroll the loop: Inside the opening shortcode tag
  392. . '[^\\]\\/]*' # Not a closing bracket or forward slash
  393. . '(?:'
  394. . '\\/(?!\\])' # A forward slash not followed by a closing bracket
  395. . '[^\\]\\/]*' # Not a closing bracket or forward slash
  396. . ')*?'
  397. . ')'
  398. . '(?:'
  399. . '(\\/)' # 4: Self closing tag ...
  400. . '\\]' # ... and closing bracket
  401. . '|'
  402. . '\\]' # Closing bracket
  403. . '(?:'
  404. . '(' # 5: Unroll the loop: Optionally, anything between the opening and closing shortcode tags
  405. . '[^\\[]*+' # Not an opening bracket
  406. . '(?:'
  407. . '\\[(?!\\/\\2\\])' # An opening bracket not followed by the closing shortcode tag
  408. . '[^\\[]*+' # Not an opening bracket
  409. . ')*+'
  410. . ')'
  411. . '\\[\\/\\2\\]' # Closing shortcode tag
  412. . ')?'
  413. . ')'
  414. . '(\\]?)'; # 6: Optional second closing brocket for escaping shortcodes: [[tag]]
  415. preg_match_all('/' . $regex . '/s', $content, $found);
  416. $foundList = array();
  417. # If found any shortcodes process them
  418. if (!empty($found[2])) {
  419. foreach ($found[2] as $foundCode) {
  420. if (!isset($foundList[$codesList[$foundCode]])) {
  421. # register the template code as not to use it again
  422. $foundList[$codesList[$foundCode]] = $foundCode;
  423. # Fetch the template data
  424. $foundTemplate = get_post_meta($codesList[$foundCode], '_pods_adv_template', true);
  425. # if there is content in the html tab, process it to find
  426. # embeded shortcodes.
  427. # And yes you can create a endless loop by placing its own
  428. # shortcode in its html tab. Don't do it!
  429. if (!empty($foundTemplate['htmlCode']))
  430. $foundList = $foundList + $this->get_used($foundTemplate['htmlCode'], $codes);
  431. }
  432. }
  433. }
  434. # Send back the list of codes used
  435. return $foundList;
  436. }
  437. /**
  438. * Output Footer Scripts
  439. *
  440. */
  441. function footer_scripts() {
  442. # Simply echo out the javascript
  443. # I may want to make this cached like the CSS and have it enqueue it correctly.
  444. if (!empty($this->template_foot)) {
  445. echo "<script type='text/javascript'>\n/* <![CDATA[ */\n";
  446. echo $this->template_foot;
  447. echo "/* ]]> */\n</script>\n";
  448. }
  449. }
  450. /**
  451. * Set the edit list columns
  452. */
  453. function edit_columns($columns) {
  454. # Defining the columns i want
  455. $columns = array(
  456. 'cb' => '<input type="checkbox" />',
  457. 'title' => __('Template', 'pods'),
  458. 'shortcode' => __('Shortcode', 'pods'),
  459. 'pod' => __('Pod', 'pods'),
  460. 'date' => __('Date', 'pods')
  461. );
  462. return $columns;
  463. }
  464. /**
  465. * Column content for list edit
  466. */
  467. function column_content($column, $post_id) {
  468. global $post, $_pod;
  469. if (empty($this->template_data[$post_id])) {
  470. $this->template_data[$post_id] = get_post_meta($post_id, '_pods_adv_template', true);
  471. }
  472. switch ($column) {
  473. /* the pod column. */
  474. case 'pod' :
  475. if (empty($this->template_data[$post_id]['name']))
  476. echo '<em class="description">' . __('not set', 'pods') . '</em>';
  477. else
  478. echo $this->pods_list[$this->template_data[$post_id]['pod']]['name'];
  479. break;
  480. /* the shortcode column. */
  481. case 'shortcode' :
  482. echo '[' . $this->template_data[$post_id]['slug'] . ']';
  483. break;
  484. /* Just break out of the switch statement for everything else. */
  485. default :
  486. break;
  487. }
  488. }
  489. /**
  490. * Manage menu overides for switching between post type and admin page
  491. *
  492. */
  493. public function admin_menu_switch() {
  494. global $submenu;
  495. #replace the default registered post type with a custom UI page instead.
  496. foreach ($submenu[$this->pods_menu] as $menu_key => &$menu) {
  497. if ($this->component_name == $menu[3]) {
  498. $menu[2] = 'pods-component-' . sanitize_title($this->component_name);
  499. }
  500. }
  501. }
  502. /**
  503. * Enqueue styles
  504. *
  505. * @since 2.0.0
  506. */
  507. public function admin_assets() {
  508. if (!isset($_GET['post_type'])) {
  509. global $submenu;
  510. # Cleanup my overide.
  511. unset($submenu['pods'][0]);
  512. }
  513. wp_enqueue_style('pat_adminStyle', PODS_URL . 'components/Advanced-Templates/ui/styles/core.css');
  514. if (isset($_GET['edit'])) {
  515. /**
  516. * I'm loading in an embeded version of codemirror as i needed extra
  517. * features thats only available in the newly released V3.0
  518. * Maybe we can add it to the core?
  519. */
  520. wp_enqueue_style('thickbox');
  521. wp_enqueue_style('codemirror', PODS_URL . 'components/Advanced-Templates/ui/codemirror/lib/codemirror.css', false, array(), false);
  522. wp_enqueue_style('codemirror-simple-hint', PODS_URL . 'components/Advanced-Templates/ui/codemirror/lib/util/simple-hint.css', false);
  523. wp_enqueue_style('codemirror-dialog-css', PODS_URL . 'components/Advanced-Templates/ui/codemirror/lib/util/dialog.css', false);
  524. wp_enqueue_style('codemirror', PODS_URL . 'components/Advanced-Templates/ui/codemirror/lib/codemirror.css', false);
  525. wp_enqueue_script("jquery", false, array(), false, false);
  526. wp_enqueue_script('jquery-ui-core', false, array(), false, false);
  527. wp_enqueue_script('jquery-ui-sortable', false, array(), false, false);
  528. wp_enqueue_script('jquery-ui-draggable', false, array(), false, false);
  529. wp_enqueue_script('jquery-ui-droppable', false, array(), false, false);
  530. wp_enqueue_script('media-upload', false, array(), false, false);
  531. wp_enqueue_script('thickbox', false, array(), false, false);
  532. wp_enqueue_script('codemirror', PODS_URL . 'components/Advanced-Templates/ui/codemirror/lib/codemirror.js', array(), false, true);
  533. wp_enqueue_script('codemirror-overlay', PODS_URL . 'components/Advanced-Templates/ui/codemirror/lib/util/overlay.js', array(), false, true);
  534. wp_enqueue_script('codemirror-mode-css', PODS_URL . 'components/Advanced-Templates/ui/codemirror/mode/css/css.js', array(), false, true);
  535. wp_enqueue_script('codemirror-mode-js', PODS_URL . 'components/Advanced-Templates/ui/codemirror/mode/javascript/javascript.js', array(), false, true);
  536. wp_enqueue_script('codemirror-mode-xml', PODS_URL . 'components/Advanced-Templates/ui/codemirror/mode/xml/xml.js', array(), false, true);
  537. wp_enqueue_script('codemirror-mode-clike', PODS_URL . 'components/Advanced-Templates/ui/codemirror/mode/clike/clike.js', array(), false, true);
  538. wp_enqueue_script('codemirror-mode-php', PODS_URL . 'components/Advanced-Templates/ui/codemirror/mode/php/php.js', array(), false, true);
  539. wp_enqueue_script('codemirror-mode-htmlmxed', PODS_URL . 'components/Advanced-Templates/ui/codemirror/mode/htmlmixed/htmlmixed.js', array(), false, true);
  540. wp_enqueue_script('codemirror-simple-hintjs', PODS_URL . 'components/Advanced-Templates/ui/codemirror/lib/util/simple-hint.js', array(), false, true);
  541. wp_enqueue_script('codemirror-close-tag', PODS_URL . 'components/Advanced-Templates/ui/codemirror/lib/util/closetag.js', array(), false, true);
  542. wp_enqueue_script('codemirror-xml-hint', PODS_URL . 'components/Advanced-Templates/ui/codemirror/lib/util/xml-hint.js', array(), false, true);
  543. wp_enqueue_script('codemirror-dialog-js', PODS_URL . 'components/Advanced-Templates/ui/codemirror/lib/util/dialog.js', array(), false, true);
  544. wp_enqueue_script('codemirror-srchcursor-js', PODS_URL . 'components/Advanced-Templates/ui/codemirror/lib/util/searchcursor.js', array(), false, true);
  545. wp_enqueue_script('codemirror-multiplex-js', PODS_URL . 'components/Advanced-Templates/ui/codemirror/lib/util/multiplex.js', array(), false, true);
  546. wp_enqueue_script('codemirror-search-js', PODS_URL . 'components/Advanced-Templates/ui/codemirror/lib/util/search.js', array(), false, true);
  547. wp_enqueue_script('bootstrap-typeahead', PODS_URL . 'components/Advanced-Templates/ui/libs/js/typeahead.js', array(), false, true);
  548. wp_enqueue_script('editor-js', PODS_URL . 'components/Advanced-Templates/ui/libs/js/editor.js', array(), false, true);
  549. wp_enqueue_style('pat_adminecleaner', PODS_URL . 'components/Advanced-Templates/ui/css/editor.css');
  550. } else {
  551. wp_enqueue_style('pods-admin');
  552. }
  553. }
  554. /**
  555. * Remove unused row actions
  556. *
  557. * @since 2.0.5
  558. */
  559. function remove_row_actions($actions, $post) {
  560. global $current_screen;
  561. if ($this->object_type != $current_screen->post_type)
  562. return $actions;
  563. if (isset($actions['view']))
  564. unset($actions['view']);
  565. if (isset($actions['inline hide-if-no-js']))
  566. unset($actions['inline hide-if-no-js']);
  567. # W3 Total Cache
  568. if (isset($actions['pgcache_purge']))
  569. unset($actions['pgcache_purge']);
  570. return $actions;
  571. }
  572. /**
  573. * Remove unused bulk actions
  574. *
  575. * @since 2.0.5
  576. */
  577. public function remove_bulk_actions($actions) {
  578. if (isset($actions['edit']))
  579. unset($actions['edit']);
  580. return $actions;
  581. }
  582. /**
  583. * build cache on save
  584. * Registeres a list of tempalte shortcodes used in a post.
  585. * This is so the we can load up the headers before the do_shortcode to enable us
  586. * to enqueue then correctly
  587. */
  588. public function build_cache($data, $pod = null, $id = null, $groups = null, $post = null) {
  589. if (!is_array($data) && 0 < $data) {
  590. $codes = get_transient('pods_advtemplates');
  591. if (!empty($pod->post_content)) {
  592. $usedCodes = $this->get_used($pod->post_content, $codes);
  593. $usedCache = get_transient('pods_adv_template_used');
  594. $usedCache[$data] = $usedCodes;
  595. set_transient('pods_adv_template_used', $usedCache);
  596. $post = $data;
  597. $post = get_post($post);
  598. if (is_object($id)) {
  599. $old_post = $id;
  600. pods_transient_clear('pods_object_adv_template_' . $old_post->post_title);
  601. }
  602. }
  603. }
  604. if (empty($post))
  605. return;
  606. if ($this->object_type != $post->post_type)
  607. return;
  608. pods_transient_clear('pods_object_adv_template');
  609. pods_transient_clear('pods_object_adv_template_' . $post->post_title);
  610. }
  611. /**
  612. * Clear cache on delete
  613. *Clean up used shortcode list
  614. * @since 2.0.0
  615. */
  616. public function clear_cache($data, $pod = null, $id = null, $groups = null, $post = null) {
  617. if (!is_array($data) && 0 < $data) {
  618. $codes = get_transient('pods_adv_template_used');
  619. if (isset($codes[$data])) {
  620. unset($codes[$data]);
  621. set_transient('pods_adv_template_used', $codes);
  622. }
  623. $post = $data;
  624. $post = get_post($post);
  625. if (is_object($id)) {
  626. $old_post = $id;
  627. pods_transient_clear('pods_object_adv_template_' . $old_post->post_title);
  628. }
  629. }
  630. if (empty($post))
  631. return;
  632. if ($this->object_type != $post->post_type)
  633. return;
  634. pods_transient_clear('pods_object_adv_template');
  635. pods_transient_clear('pods_object_adv_template_' . $post->post_title);
  636. }
  637. /**
  638. * Build admin area
  639. *
  640. * @param $options
  641. *
  642. * @since 2.0.0
  643. */
  644. public function admin($options, $component) {
  645. $method = 'template_ajax';
  646. require_once PODS_DIR . 'components/Advanced-Templates/ui/libs/functions.php';
  647. pods_view(PODS_DIR . 'components/Advanced-Templates/ui/editor.php', compact(array_keys(get_defined_vars())));
  648. }
  649. /**
  650. * a simple helper for me :)
  651. */
  652. function dump($a, $die = true) {
  653. echo '<pre>';
  654. print_r($a);
  655. echo '</pre>';
  656. if ($die) {
  657. die;
  658. }
  659. }
  660. /**
  661. * Handle the Conversion AJAX
  662. *
  663. * @param $params
  664. */
  665. public function ajax_template_ajax($params) {
  666. $out['type'] = $params->process;
  667. switch ($params->process) {
  668. case 'swap_pod':
  669. $api = pods_api();
  670. $_pods = $api->load_pods();
  671. $podFields = array();
  672. foreach ($_pods as $pod) {
  673. if ((int) $params->pod === (int) $pod['id']) {
  674. if (!empty($pod['options']['supports_title']))
  675. $podFields[] = "@title";
  676. if (!empty($pod['options']['supports_editor']))
  677. $podFields[] = "@content";
  678. foreach ($pod['fields'] as $podField => $fiedSet) {
  679. $podFields[] = "@" . $podField;
  680. }
  681. }
  682. }
  683. $out['data'] = $podFields;
  684. break;
  685. case 'apply_changes':
  686. # Need to confirm things have been saved and updated..
  687. parse_str(stripslashes($params->data), $predata);
  688. if (get_magic_quotes_gpc()) {
  689. $predata = array_map('stripslashes_deep', $predata);
  690. }
  691. $data = $predata['data'];
  692. $templateArgs = array(
  693. 'post_name' => $data['slug'],
  694. 'post_title' => $data['name'],
  695. 'post_type' => '_pods_adv_template'
  696. );
  697. if (!empty($data['pod']))
  698. $templateArgs['post_status'] = 'publish';
  699. else
  700. $templateArgs['post_status'] = 'draft';
  701. if (!empty($data['ID'])) {
  702. $templateArgs['ID'] = $data['ID'];
  703. $lastPost = wp_update_post($templateArgs);
  704. } else {
  705. $lastPost = wp_insert_post($templateArgs);
  706. }
  707. update_post_meta($lastPost, '_pods_adv_template', $data);
  708. $out['title'] = $data['name'];
  709. $out['id'] = $lastPost;
  710. break;
  711. }
  712. header("ContentType:application/json charset=utf-8");
  713. echo json_encode($out);
  714. }
  715. }
  716. ?>