form-gutenberg.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <?php
  2. if ( ! defined( 'ABSPATH' ) ) {
  3. exit; // Exit if accessed directly.
  4. }
  5. if ( ! class_exists( 'ACF_Form_Gutenberg' ) ) :
  6. class ACF_Form_Gutenberg {
  7. /**
  8. * __construct
  9. *
  10. * Setup for class functionality.
  11. *
  12. * @date 13/12/18
  13. * @since 5.8.0
  14. *
  15. * @param void
  16. * @return void
  17. */
  18. function __construct() {
  19. // Add actions.
  20. add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) );
  21. // Ignore validation during meta-box-loader AJAX request.
  22. add_action( 'acf/validate_save_post', array( $this, 'acf_validate_save_post' ), 999 );
  23. }
  24. /**
  25. * enqueue_block_editor_assets
  26. *
  27. * Allows a safe way to customize Guten-only functionality.
  28. *
  29. * @date 14/12/18
  30. * @since 5.8.0
  31. *
  32. * @param void
  33. * @return void
  34. */
  35. function enqueue_block_editor_assets() {
  36. // Remove edit_form_after_title.
  37. add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 20, 0 );
  38. // Call edit_form_after_title manually.
  39. add_action( 'block_editor_meta_box_hidden_fields', array( $this, 'block_editor_meta_box_hidden_fields' ) );
  40. // Customize editor metaboxes.
  41. add_filter( 'filter_block_editor_meta_boxes', array( $this, 'filter_block_editor_meta_boxes' ) );
  42. // Trigger ACF enqueue scripts as the site editor doesn't trigger this from form-post.php
  43. acf_enqueue_scripts(
  44. array(
  45. 'uploader' => true,
  46. )
  47. );
  48. }
  49. /**
  50. * add_meta_boxes
  51. *
  52. * Modify screen for Gutenberg.
  53. *
  54. * @date 13/12/18
  55. * @since 5.8.0
  56. *
  57. * @param void
  58. * @return void
  59. */
  60. function add_meta_boxes() {
  61. // Remove 'edit_form_after_title' action.
  62. remove_action( 'edit_form_after_title', array( acf_get_instance( 'ACF_Form_Post' ), 'edit_form_after_title' ) );
  63. }
  64. /**
  65. * block_editor_meta_box_hidden_fields
  66. *
  67. * Modify screen for Gutenberg.
  68. *
  69. * @date 13/12/18
  70. * @since 5.8.0
  71. *
  72. * @param void
  73. * @return void
  74. */
  75. function block_editor_meta_box_hidden_fields() {
  76. // Manually call 'edit_form_after_title' function.
  77. acf_get_instance( 'ACF_Form_Post' )->edit_form_after_title();
  78. }
  79. /**
  80. * filter_block_editor_meta_boxes
  81. *
  82. * description
  83. *
  84. * @date 5/4/19
  85. * @since 5.7.14
  86. *
  87. * @param type $var Description. Default.
  88. * @return type Description.
  89. */
  90. function filter_block_editor_meta_boxes( $wp_meta_boxes ) {
  91. // Globals
  92. global $current_screen;
  93. // Move 'acf_after_title' metaboxes into 'normal' location.
  94. if ( isset( $wp_meta_boxes[ $current_screen->id ]['acf_after_title'] ) ) {
  95. // Extract locations.
  96. $locations = $wp_meta_boxes[ $current_screen->id ];
  97. // Ensure normal location exists.
  98. if ( ! isset( $locations['normal'] ) ) {
  99. $locations['normal'] = array();
  100. }
  101. if ( ! isset( $locations['normal']['high'] ) ) {
  102. $locations['normal']['high'] = array();
  103. }
  104. // Append metaboxes.
  105. foreach ( $locations['acf_after_title'] as $priority => $meta_boxes ) {
  106. $locations['normal']['high'] = array_merge( $meta_boxes, $locations['normal']['high'] );
  107. }
  108. // Update original data.
  109. $wp_meta_boxes[ $current_screen->id ] = $locations;
  110. unset( $wp_meta_boxes[ $current_screen->id ]['acf_after_title'] );
  111. // Avoid conflicts with saved metabox order.
  112. add_filter( 'get_user_option_meta-box-order_' . $current_screen->id, array( $this, 'modify_user_option_meta_box_order' ) );
  113. }
  114. // Return
  115. return $wp_meta_boxes;
  116. }
  117. /**
  118. * modify_user_option_meta_box_order
  119. *
  120. * Filters the `meta-box-order_{$post_type}` value by prepending "acf_after_title" data to "normal".
  121. * Fixes a bug where metaboxes with position "acf_after_title" do not appear in the block editor.
  122. *
  123. * @date 11/7/19
  124. * @since 5.8.2
  125. *
  126. * @param array $stored_meta_box_order User's existing meta box order.
  127. * @return array Modified array with meta boxes moved around.
  128. */
  129. function modify_user_option_meta_box_order( $locations ) {
  130. if ( ! empty( $locations['acf_after_title'] ) ) {
  131. if ( ! empty( $locations['normal'] ) ) {
  132. $locations['normal'] = $locations['acf_after_title'] . ',' . $locations['normal'];
  133. } else {
  134. $locations['normal'] = $locations['acf_after_title'];
  135. }
  136. unset( $locations['acf_after_title'] );
  137. }
  138. return $locations;
  139. }
  140. /**
  141. * acf_validate_save_post
  142. *
  143. * Ignore errors during the Gutenberg "save metaboxes" AJAX request.
  144. * Allows data to save and prevent UX issues.
  145. *
  146. * @date 16/12/18
  147. * @since 5.8.0
  148. *
  149. * @param void
  150. * @return void
  151. */
  152. function acf_validate_save_post() {
  153. // Check if current request came from Gutenberg.
  154. if ( isset( $_GET['meta-box-loader'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Verified elsewhere.
  155. acf_reset_validation_errors();
  156. }
  157. }
  158. }
  159. acf_new_instance( 'ACF_Form_Gutenberg' );
  160. endif;