local-meta.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. if ( ! defined( 'ABSPATH' ) ) {
  3. exit; // Exit if accessed directly
  4. }
  5. if ( ! class_exists( 'ACF_Local_Meta' ) ) :
  6. class ACF_Local_Meta {
  7. /** @var array Storage for meta data. */
  8. var $meta = array();
  9. /** @var mixed Storage for the current post_id. */
  10. var $post_id = 0;
  11. /**
  12. * __construct
  13. *
  14. * Sets up the class functionality.
  15. *
  16. * @date 8/10/18
  17. * @since 5.8.0
  18. *
  19. * @param void
  20. * @return void
  21. */
  22. function __construct() {
  23. // add filters
  24. add_filter( 'acf/pre_load_post_id', array( $this, 'pre_load_post_id' ), 1, 2 );
  25. add_filter( 'acf/pre_load_meta', array( $this, 'pre_load_meta' ), 1, 2 );
  26. add_filter( 'acf/pre_load_metadata', array( $this, 'pre_load_metadata' ), 1, 4 );
  27. }
  28. /**
  29. * add
  30. *
  31. * Adds postmeta to storage.
  32. * Accepts data in either raw or request format.
  33. *
  34. * @date 8/10/18
  35. * @since 5.8.0
  36. *
  37. * @param array $meta An array of metdata to store.
  38. * @param mixed $post_id The post_id for this data.
  39. * @param bool $is_main Makes this postmeta visible to get_field() without a $post_id value.
  40. * @return array
  41. */
  42. function add( $meta = array(), $post_id = 0, $is_main = false ) {
  43. // Capture meta if supplied meta is from a REQUEST.
  44. if ( $this->is_request( $meta ) ) {
  45. $meta = $this->capture( $meta, $post_id );
  46. }
  47. // Add to storage.
  48. $this->meta[ $post_id ] = $meta;
  49. // Set $post_id reference when is the "main" postmeta.
  50. if ( $is_main ) {
  51. $this->post_id = $post_id;
  52. }
  53. // Return meta.
  54. return $meta;
  55. }
  56. /**
  57. * is_request
  58. *
  59. * Returns true if the supplied $meta is from a REQUEST (serialized <form> data).
  60. *
  61. * @date 11/3/19
  62. * @since 5.7.14
  63. *
  64. * @param array $meta An array of metdata to check.
  65. * @return bool
  66. */
  67. function is_request( $meta = array() ) {
  68. return acf_is_field_key( key( $meta ) );
  69. }
  70. /**
  71. * capture
  72. *
  73. * Returns a flattened array of meta for the given postdata.
  74. * This is achieved by simulating a save whilst capturing all meta changes.
  75. *
  76. * @date 26/2/19
  77. * @since 5.7.13
  78. *
  79. * @param array $values An array of raw values.
  80. * @param mixed $post_id The post_id for this data.
  81. * @return array
  82. */
  83. function capture( $values = array(), $post_id = 0 ) {
  84. // Reset meta.
  85. $this->meta[ $post_id ] = array();
  86. // Listen for any added meta.
  87. add_filter( 'acf/pre_update_metadata', array( $this, 'capture_update_metadata' ), 1, 5 );
  88. // Simulate update.
  89. if ( $values ) {
  90. acf_update_values( $values, $post_id );
  91. }
  92. // Remove listener filter.
  93. remove_filter( 'acf/pre_update_metadata', array( $this, 'capture_update_metadata' ), 1, 5 );
  94. // Return meta.
  95. return $this->meta[ $post_id ];
  96. }
  97. /**
  98. * capture_update_metadata
  99. *
  100. * Records all meta activity and returns a non null value to bypass DB updates.
  101. *
  102. * @date 26/2/19
  103. * @since 5.7.13
  104. *
  105. * @param null $null .
  106. * @param (int|string) $post_id The post id.
  107. * @param string $name The meta name.
  108. * @param mixed $value The meta value.
  109. * @param bool $hidden If the meta is hidden (starts with an underscore).
  110. * @return false.
  111. */
  112. function capture_update_metadata( $null, $post_id, $name, $value, $hidden ) {
  113. $name = ( $hidden ? '_' : '' ) . $name;
  114. $this->meta[ $post_id ][ $name ] = $value;
  115. // Return non null value to escape update process.
  116. return true;
  117. }
  118. /**
  119. * remove
  120. *
  121. * Removes postmeta from storage.
  122. *
  123. * @date 8/10/18
  124. * @since 5.8.0
  125. *
  126. * @param mixed $post_id The post_id for this data.
  127. * @return void
  128. */
  129. function remove( $post_id = 0 ) {
  130. // unset meta
  131. unset( $this->meta[ $post_id ] );
  132. // reset post_id
  133. if ( $post_id === $this->post_id ) {
  134. $this->post_id = 0;
  135. }
  136. }
  137. /**
  138. * pre_load_meta
  139. *
  140. * Injects the local meta.
  141. *
  142. * @date 8/10/18
  143. * @since 5.8.0
  144. *
  145. * @param null $null An empty parameter. Return a non null value to short-circuit the function.
  146. * @param mixed $post_id The post_id for this data.
  147. * @return mixed
  148. */
  149. function pre_load_meta( $null, $post_id ) {
  150. if ( isset( $this->meta[ $post_id ] ) ) {
  151. return $this->meta[ $post_id ];
  152. }
  153. return $null;
  154. }
  155. /**
  156. * pre_load_metadata
  157. *
  158. * Injects the local meta.
  159. *
  160. * @date 8/10/18
  161. * @since 5.8.0
  162. *
  163. * @param null $null An empty parameter. Return a non null value to short-circuit the function.
  164. * @param (int|string) $post_id The post id.
  165. * @param string $name The meta name.
  166. * @param bool $hidden If the meta is hidden (starts with an underscore).
  167. * @return mixed
  168. */
  169. function pre_load_metadata( $null, $post_id, $name, $hidden ) {
  170. $name = ( $hidden ? '_' : '' ) . $name;
  171. if ( isset( $this->meta[ $post_id ] ) ) {
  172. if ( isset( $this->meta[ $post_id ][ $name ] ) ) {
  173. return $this->meta[ $post_id ][ $name ];
  174. }
  175. return '__return_null';
  176. }
  177. return $null;
  178. }
  179. /**
  180. * pre_load_post_id
  181. *
  182. * Injects the local post_id.
  183. *
  184. * @date 8/10/18
  185. * @since 5.8.0
  186. *
  187. * @param null $null An empty parameter. Return a non null value to short-circuit the function.
  188. * @param mixed $post_id The post_id for this data.
  189. * @return mixed
  190. */
  191. function pre_load_post_id( $null, $post_id ) {
  192. if ( ! $post_id && $this->post_id ) {
  193. return $this->post_id;
  194. }
  195. return $null;
  196. }
  197. }
  198. endif; // class_exists check
  199. /**
  200. * acf_setup_meta
  201. *
  202. * Adds postmeta to storage.
  203. *
  204. * @date 8/10/18
  205. * @since 5.8.0
  206. * @see ACF_Local_Meta::add() for list of parameters.
  207. *
  208. * @return array
  209. */
  210. function acf_setup_meta( $meta = array(), $post_id = 0, $is_main = false ) {
  211. return acf_get_instance( 'ACF_Local_Meta' )->add( $meta, $post_id, $is_main );
  212. }
  213. /**
  214. * acf_reset_meta
  215. *
  216. * Removes postmeta to storage.
  217. *
  218. * @date 8/10/18
  219. * @since 5.8.0
  220. * @see ACF_Local_Meta::remove() for list of parameters.
  221. *
  222. * @return void
  223. */
  224. function acf_reset_meta( $post_id = 0 ) {
  225. return acf_get_instance( 'ACF_Local_Meta' )->remove( $post_id );
  226. }