增强套件,可改进"高级自定义字段"管理
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

511 lines
13 KiB

  1. <?php
  2. if(!defined('ABSPATH'))
  3. exit;
  4. if(!class_exists('acfe_dynamic_module')):
  5. class acfe_dynamic_module{
  6. // vars
  7. public $active = false,
  8. $settings = '',
  9. $post_type = '',
  10. $label = '',
  11. $textdomain = '',
  12. $tool = '',
  13. $columns = array(),
  14. $tools = array();
  15. /*
  16. * Construct
  17. */
  18. function __construct(){
  19. $this->initialize();
  20. if(!$this->active)
  21. return;
  22. $this->actions();
  23. $this->add_local_field_group();
  24. add_action('init', array($this, 'init'));
  25. add_action('current_screen', array($this, '_current_screen'));
  26. add_action('acf/save_post', array($this, '_save_post'), 20);
  27. add_action('trashed_post', array($this, '_trashed_post'));
  28. add_action('untrashed_post', array($this, '_untrashed_post'));
  29. add_filter('acf/get_post_types', array($this, 'get_post_types'), 10, 2);
  30. }
  31. /*
  32. * Initialize
  33. */
  34. function initialize(){
  35. // ...
  36. }
  37. /*
  38. * Init
  39. */
  40. function actions(){
  41. // ...
  42. }
  43. /*
  44. * Get Name
  45. */
  46. function get_name($post_id){
  47. return false;
  48. }
  49. /*
  50. * Init
  51. */
  52. function init(){
  53. // ...
  54. }
  55. /*
  56. * Current Screen
  57. */
  58. function _current_screen(){
  59. $this->current_screen();
  60. // Single
  61. if(acf_is_screen($this->post_type)){
  62. remove_meta_box('slugdiv', $this->post_type, 'normal');
  63. add_action('admin_enqueue_scripts', array($this, '_post_head'));
  64. add_action('post_submitbox_misc_actions', array($this, '_post_submitbox_misc_actions'));
  65. add_filter('enter_title_here', array($this, 'post_enter_title_here'), 10, 2);
  66. add_action('admin_footer', array($this, '_post_footer'));
  67. add_action('load-post.php', array($this, 'post_load'));
  68. add_action('load-post-new.php', array($this, 'post_new_load'));
  69. add_filter('submenu_file', array($this, 'submenu_file'));
  70. $this->post_screen();
  71. // List
  72. }elseif(acf_is_screen("edit-{$this->post_type}")){
  73. global $wp_post_statuses;
  74. $wp_post_statuses['publish']->label_count = _n_noop( 'Active <span class="count">(%s)</span>', 'Active <span class="count">(%s)</span>', 'acf' );
  75. add_filter("manage_edit-{$this->post_type}_columns", array($this, '_edit_columns'));
  76. add_action("manage_{$this->post_type}_posts_custom_column", array($this, 'edit_columns_html'), 10, 2);
  77. add_filter('display_post_states', array($this, 'display_post_states'), 10, 2);
  78. add_filter('post_row_actions', array($this, '_edit_row_actions'), 10, 2);
  79. add_filter('page_row_actions', array($this, '_edit_row_actions'), 10, 2);
  80. add_action('admin_footer', array($this, 'edit_footer'));
  81. add_action('load-edit.php', array($this, 'edit_load'));
  82. add_filter("bulk_actions-edit-{$this->post_type}", array($this, 'bulk_actions'));
  83. add_filter("handle_bulk_actions-edit-{$this->post_type}", array($this, 'handle_bulk_actions'), 10, 3);
  84. $this->edit_screen();
  85. }
  86. }
  87. function current_screen(){
  88. // ...
  89. }
  90. function post_screen(){
  91. // ...
  92. }
  93. function post_load(){
  94. // ...
  95. }
  96. function post_new_load(){
  97. // ...
  98. }
  99. function submenu_file($submenu_file){
  100. return "edit.php?post_type={$this->post_type}";
  101. }
  102. function edit_screen(){
  103. // ...
  104. }
  105. function edit_load(){
  106. // ...
  107. }
  108. function bulk_actions($actions){
  109. acfe_unset($actions, 'edit');
  110. foreach($this->tools as $action){
  111. $action_name = $action === 'php' ? 'PHP' : 'Json';
  112. $actions["export_{$action}"] = __('Export ', 'acf') . $action_name;
  113. }
  114. return $actions;
  115. }
  116. function handle_bulk_actions($redirect, $action, $post_ids){
  117. $post_ids = acfe_maybe_get_REQUEST('post');
  118. if(!$post_ids)
  119. return $redirect;
  120. foreach($this->tools as $tool_action){
  121. if($action !== "export_{$tool_action}")
  122. continue;
  123. $keys = array();
  124. foreach($post_ids as $post_id){
  125. $name = $this->get_name($post_id);
  126. if(!$name)
  127. continue;
  128. $keys[] = $name;
  129. }
  130. $keys = implode('+', $keys);
  131. $url = admin_url("edit.php?post_type=acf-field-group&page=acf-tools&tool={$this->tool}&action={$tool_action}&keys={$keys}");
  132. wp_redirect($url);
  133. exit;
  134. }
  135. return $redirect;
  136. }
  137. /*
  138. * Post Head
  139. */
  140. function _post_head(){
  141. // no autosave
  142. wp_dequeue_script('autosave');
  143. $this->post_head();
  144. }
  145. function post_head(){
  146. // ...
  147. }
  148. /*
  149. * Post Submit Box
  150. */
  151. function _post_submitbox_misc_actions($post){
  152. $status = $post->post_status === 'publish' || $post->post_status === 'auto-draft' ? __("Active",'acf') : __("Inactive",'acf');
  153. $name = $this->get_name($post->ID);
  154. $tools = array();
  155. foreach($this->tools as $action){
  156. $action_name = $action === 'php' ? 'PHP' : 'Json';
  157. $tools[] = '<a href="' . admin_url("edit.php?post_type=acf-field-group&page=acf-tools&tool={$this->tool}&action={$action}&keys={$name}") . '">' . $action_name . '</a>';
  158. }
  159. if($tools){ ?>
  160. <div class="misc-pub-section acfe-misc-export">
  161. <span class="dashicons dashicons-editor-code"></span>
  162. Export: <?php echo implode(' ', $tools); ?>
  163. </div>
  164. <?php } ?>
  165. <script type="text/javascript">
  166. (function($) {
  167. $('#post-status-display').html('<?php echo $status; ?>');
  168. <?php if($tools){ ?>$('.acfe-misc-export').insertAfter('.misc-pub-post-status');<?php } ?>
  169. })(jQuery);
  170. </script>
  171. <?php
  172. $this->post_submitbox_misc_actions($post);
  173. }
  174. function post_submitbox_misc_actions($post){
  175. // ...
  176. }
  177. /*
  178. * Post Enter Title Here
  179. */
  180. function post_enter_title_here($placeholder, $post){
  181. return $this->label;
  182. }
  183. /*
  184. * Post Footer
  185. */
  186. function _post_footer(){
  187. ?>
  188. <script type="text/javascript">
  189. (function($){
  190. $('#post').submit(function(e){
  191. // vars
  192. var $title = $('#titlewrap #title');
  193. // empty
  194. if($title.val())
  195. return;
  196. e.preventDefault();
  197. alert('<?php echo $this->label; ?> is required.');
  198. $title.focus();
  199. });
  200. })(jQuery);
  201. </script>
  202. <?php
  203. $this->post_footer();
  204. }
  205. function post_footer(){
  206. // ...
  207. }
  208. /*
  209. * Edit Columns
  210. */
  211. function _edit_columns($columns){
  212. if(empty($this->columns))
  213. return $columns;
  214. $columns = array_merge(array('cb' => $columns['cb'], 'title' => $columns['title']), $this->columns);
  215. return $this->edit_columns($columns);
  216. }
  217. function edit_columns($columns){
  218. return $columns;
  219. }
  220. /*
  221. * Edit Columns HTML
  222. */
  223. function edit_columns_html($column, $post_id){
  224. // ...
  225. }
  226. /*
  227. * Display Post States
  228. */
  229. function display_post_states($post_states, $post){
  230. if($post->post_status === 'acf-disabled'){
  231. $post_states['acf-disabled'] = '<span class="dashicons dashicons-hidden acf-js-tooltip" title="' . _x('Disabled', 'post status', 'acf') . '"></span>';
  232. }
  233. return $post_states;
  234. }
  235. /*
  236. * Edit Row Actions
  237. */
  238. function _edit_row_actions($actions, $post){
  239. if(!in_array($post->post_status, array('publish', 'acf-disabled')))
  240. return $actions;
  241. $post_id = $post->ID;
  242. $name = $this->get_name($post_id);
  243. acfe_unset($actions, 'inline hide-if-no-js');
  244. // View
  245. $view = $this->edit_row_actions_view($post, $name);
  246. if($view)
  247. $actions['view'] = $view;
  248. // Tools
  249. foreach($this->tools as $action){
  250. $action_name = $action === 'php' ? 'PHP' : 'Json';
  251. $actions[$action] = '<a href="' . admin_url("edit.php?post_type=acf-field-group&page=acf-tools&tool={$this->tool}&action={$action}&keys={$name}") . '">' . $action_name . '</a>';
  252. }
  253. return $this->edit_row_actions($actions, $post);
  254. }
  255. function edit_row_actions($actions, $post){
  256. return $actions;
  257. }
  258. function edit_row_actions_view($post, $name){
  259. return false;
  260. }
  261. /*
  262. * Edit Foot
  263. */
  264. function edit_footer(){
  265. // ...
  266. }
  267. /*
  268. * ACF Save post
  269. */
  270. function _save_post($post_id){
  271. if(!is_numeric($post_id) || get_post_type($post_id) !== $this->post_type)
  272. return;
  273. $this->save_post($post_id);
  274. }
  275. function save_post($post_id){
  276. // ...
  277. }
  278. /*
  279. * Trashed Post Type
  280. */
  281. function _trashed_post($post_id){
  282. if(get_post_type($post_id) !== $this->post_type)
  283. return;
  284. $this->trashed_post($post_id);
  285. }
  286. function trashed_post($post_id){
  287. // ...
  288. }
  289. /*
  290. * Untrashed Post Type
  291. */
  292. function _untrashed_post($post_id){
  293. if(get_post_type($post_id) !== $this->post_type)
  294. return;
  295. $this->_save_post($post_id);
  296. $this->untrashed_post($post_id);
  297. }
  298. function untrashed_post($post_id){
  299. // ...
  300. }
  301. /*
  302. * Import
  303. */
  304. function import($name, $args){
  305. // ...
  306. }
  307. /*
  308. * Export
  309. */
  310. function export_choices(){
  311. return array();
  312. }
  313. function export_data($name){
  314. // ...
  315. }
  316. function export_php($data){
  317. return false;
  318. }
  319. /*
  320. * Reset
  321. */
  322. function reset(){
  323. // ...
  324. }
  325. /*
  326. * Exclude Post Type
  327. */
  328. function get_post_types($post_types, $args){
  329. if(empty($post_types))
  330. return $post_types;
  331. foreach($post_types as $k => $post_type){
  332. if($post_type !== $this->post_type)
  333. continue;
  334. unset($post_types[$k]);
  335. }
  336. return $post_types;
  337. }
  338. /*
  339. * Get Field Labels Recursive
  340. */
  341. function get_fields_labels_recursive(&$array, $field){
  342. $label = '';
  343. $ancestors = isset($field['ancestors']) ? $field['ancestors'] : count(acf_get_field_ancestors($field));
  344. $label = str_repeat('- ', $ancestors) . $label;
  345. $label .= !empty($field['label']) ? $field['label'] : '(' . __('no label', 'acf') . ')';
  346. $label .= $field['required'] ? ' <span class="acf-required">*</span>' : '';
  347. $array[$field['key']] = $label;
  348. if(isset($field['sub_fields']) && !empty($field['sub_fields'])){
  349. foreach($field['sub_fields'] as $s_field){
  350. $this->get_fields_labels_recursive($array, $s_field);
  351. }
  352. }
  353. }
  354. /*
  355. * Add Local Field Group
  356. */
  357. function add_local_field_group(){
  358. // ...
  359. }
  360. }
  361. endif;