PluginProbe
Advanced Custom Fields (ACF®) / 5.8.6
Advanced Custom Fields (ACF®) v5.8.6
6.8.9 6.8.8 6.8.7 6.8.6 6.8.5 6.8.4 6.8.3 6.8.2 6.8.1 5.8.5 5.8.6 5.8.7 5.8.8 5.8.9 5.9.0 5.9.1 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 5.9.9 6.0.0 All 230 releases
advanced-custom-fields / includes / revisions.php
revisions.php
476 lines 9.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
4
5 if( ! class_exists('acf_revisions') ) :
6
7 class acf_revisions {
8
9 // vars
10 var $cache = array();
11
12
13 /*
14 * __construct
15 *
16 * A good place to add actions / filters
17 *
18 * @type function
19 * @date 11/08/13
20 *
21 * @param N/A
22 * @return N/A
23 */
24
25 function __construct() {
26
27 // actions
28 add_action('wp_restore_post_revision', array($this, 'wp_restore_post_revision'), 10, 2 );
29
30
31 // filters
32 add_filter('wp_save_post_revision_check_for_changes', array($this, 'wp_save_post_revision_check_for_changes'), 10, 3);
33 add_filter('_wp_post_revision_fields', array($this, 'wp_preview_post_fields'), 10, 2 );
34 add_filter('_wp_post_revision_fields', array($this, 'wp_post_revision_fields'), 10, 2 );
35 add_filter('acf/validate_post_id', array($this, 'acf_validate_post_id'), 10, 2 );
36
37 }
38
39
40 /*
41 * wp_preview_post_fields
42 *
43 * This function is used to trick WP into thinking that one of the $post's fields has changed and
44 * will allow an autosave to be updated.
45 * Fixes an odd bug causing the preview page to render the non autosave post data on every odd attempt
46 *
47 * @type function
48 * @date 21/10/2014
49 * @since 5.1.0
50 *
51 * @param $fields (array)
52 * @return $fields
53 */
54
55 function wp_preview_post_fields( $fields ) {
56
57 // bail early if not previewing a post
58 if( acf_maybe_get_POST('wp-preview') !== 'dopreview' ) return $fields;
59
60
61 // add to fields if ACF has changed
62 if( acf_maybe_get_POST('_acf_changed') ) {
63
64 $fields['_acf_changed'] = 'different than 1';
65
66 }
67
68
69 // return
70 return $fields;
71
72 }
73
74
75 /*
76 * wp_save_post_revision_check_for_changes
77 *
78 * This filter will return false and force WP to save a revision. This is required due to
79 * WP checking only post_title, post_excerpt and post_content values, not custom fields.
80 *
81 * @type filter
82 * @date 19/09/13
83 *
84 * @param $return (boolean) defaults to true
85 * @param $last_revision (object) the last revision that WP will compare against
86 * @param $post (object) the $post that WP will compare against
87 * @return $return (boolean)
88 */
89
90 function wp_save_post_revision_check_for_changes( $return, $last_revision, $post ) {
91
92 // if acf has changed, return false and prevent WP from performing 'compare' logic
93 if( acf_maybe_get_POST('_acf_changed') ) return false;
94
95
96 // return
97 return $return;
98
99 }
100
101
102 /*
103 * wp_post_revision_fields
104 *
105 * This filter will add the ACF fields to the returned array
106 * Versions 3.5 and 3.6 of WP feature different uses of the revisions filters, so there are
107 * some hacks to allow both versions to work correctly
108 *
109 * @type filter
110 * @date 11/08/13
111 *
112 * @param $post_id (int)
113 * @return $post_id (int)
114 */
115
116 function wp_post_revision_fields( $fields, $post = null ) {
117
118 // validate page
119 if( acf_is_screen('revision') || acf_is_ajax('get-revision-diffs') ) {
120
121 // bail early if is restoring
122 if( acf_maybe_get_GET('action') === 'restore' ) return $fields;
123
124 // allow
125
126 } else {
127
128 // bail early (most likely saving a post)
129 return $fields;
130
131 }
132
133
134 // vars
135 $append = array();
136 $order = array();
137 $post_id = acf_maybe_get($post, 'ID');
138
139
140 // compatibility with WP < 4.5 (test)
141 if( !$post_id ) {
142
143 global $post;
144 $post_id = $post->ID;
145
146 }
147
148
149 // get all postmeta
150 $meta = get_post_meta( $post_id );
151
152
153 // bail early if no meta
154 if( !$meta ) return $fields;
155
156
157 // loop
158 foreach( $meta as $name => $value ) {
159
160 // attempt to find key value
161 $key = acf_maybe_get( $meta, '_'.$name );
162
163
164 // bail ealry if no key
165 if( !$key ) continue;
166
167
168 // update vars
169 $value = $value[0];
170 $key = $key[0];
171
172
173 // bail early if $key is a not a field_key
174 if( !acf_is_field_key($key) ) continue;
175
176
177 // get field
178 $field = acf_get_field( $key );
179 $field_title = $field['label'] . ' (' . $name . ')';
180 $field_order = $field['menu_order'];
181 $ancestors = acf_get_field_ancestors( $field );
182
183
184 // ancestors
185 if( !empty($ancestors) ) {
186
187 // vars
188 $count = count($ancestors);
189 $oldest = acf_get_field( $ancestors[$count-1] );
190
191
192 // update vars
193 $field_title = str_repeat('- ', $count) . $field_title;
194 $field_order = $oldest['menu_order'] . '.1';
195
196 }
197
198
199 // append
200 $append[ $name ] = $field_title;
201 $order[ $name ] = $field_order;
202
203
204 // hook into specific revision field filter and return local value
205 add_filter("_wp_post_revision_field_{$name}", array($this, 'wp_post_revision_field'), 10, 4);
206
207 }
208
209
210 // append
211 if( !empty($append) ) {
212
213 // vars
214 $prefix = '_';
215
216
217 // add prefix
218 $append = acf_add_array_key_prefix($append, $prefix);
219 $order = acf_add_array_key_prefix($order, $prefix);
220
221
222 // sort by name (orders sub field values correctly)
223 array_multisort($order, $append);
224
225
226 // remove prefix
227 $append = acf_remove_array_key_prefix($append, $prefix);
228
229
230 // append
231 $fields = $fields + $append;
232
233 }
234
235
236 // return
237 return $fields;
238
239 }
240
241
242 /*
243 * wp_post_revision_field
244 *
245 * This filter will load the value for the given field and return it for rendering
246 *
247 * @type filter
248 * @date 11/08/13
249 *
250 * @param $value (mixed) should be false as it has not yet been loaded
251 * @param $field_name (string) The name of the field
252 * @param $post (mixed) Holds the $post object to load from - in WP 3.5, this is not passed!
253 * @param $direction (string) to / from - not used
254 * @return $value (string)
255 */
256
257 function wp_post_revision_field( $value, $field_name, $post = null, $direction = false) {
258
259 // bail ealry if is empty
260 if( empty($value) ) return $value;
261
262
263 // value has not yet been 'maybe_unserialize'
264 $value = maybe_unserialize( $value );
265
266
267 // vars
268 $post_id = $post->ID;
269
270
271 // load field
272 $field = acf_maybe_get_field( $field_name, $post_id );
273
274
275 // default formatting
276 if( is_array($value) ) {
277
278 $value = implode(', ', $value);
279
280 } elseif( is_object($value) ) {
281
282 $value = serialize($value);
283
284 }
285
286
287 // image
288 if( $field['type'] == 'image' || $field['type'] == 'file' ) {
289
290 $url = wp_get_attachment_url($value);
291 $value = $value . ' (' . $url . ')';
292
293 }
294
295
296 // return
297 return $value;
298
299 }
300
301
302 /*
303 * wp_restore_post_revision
304 *
305 * This action will copy and paste the metadata from a revision to the post
306 *
307 * @type action
308 * @date 11/08/13
309 *
310 * @param $parent_id (int) the destination post
311 * @return $revision_id (int) the source post
312 */
313
314 function wp_restore_post_revision( $post_id, $revision_id ) {
315
316 // copy postmeta from revision to post (restore from revision)
317 acf_copy_postmeta( $revision_id, $post_id );
318
319
320 // Make sure the latest revision is also updated to match the new $post data
321 // get latest revision
322 $revision = acf_get_post_latest_revision( $post_id );
323
324
325 // save
326 if( $revision ) {
327
328 // copy postmeta from revision to latest revision (potentialy may be the same, but most likely are different)
329 acf_copy_postmeta( $revision_id, $revision->ID );
330
331 }
332
333 }
334
335
336 /*
337 * acf_validate_post_id
338 *
339 * This function will modify the $post_id and allow loading values from a revision
340 *
341 * @type function
342 * @date 6/3/17
343 * @since 5.5.10
344 *
345 * @param $post_id (int)
346 * @param $_post_id (int)
347 * @return $post_id (int)
348 */
349
350 function acf_validate_post_id( $post_id, $_post_id ) {
351
352 // bail early if no preview in URL
353 if( !isset($_GET['preview']) ) return $post_id;
354
355
356 // bail early if $post_id is not numeric
357 if( !is_numeric($post_id) ) return $post_id;
358
359
360 // vars
361 $k = $post_id;
362 $preview_id = 0;
363
364
365 // check cache
366 if( isset($this->cache[$k]) ) return $this->cache[$k];
367
368
369 // validate
370 if( isset($_GET['preview_id']) ) {
371
372 $preview_id = (int) $_GET['preview_id'];
373
374 } elseif( isset($_GET['p']) ) {
375
376 $preview_id = (int) $_GET['p'];
377
378 } elseif( isset($_GET['page_id']) ) {
379
380 $preview_id = (int) $_GET['page_id'];
381
382 }
383
384
385 // bail early id $preview_id does not match $post_id
386 if( $preview_id != $post_id ) return $post_id;
387
388
389 // attempt find revision
390 $revision = acf_get_post_latest_revision( $post_id );
391
392
393 // save
394 if( $revision && $revision->post_parent == $post_id) {
395
396 $post_id = (int) $revision->ID;
397
398 }
399
400
401 // set cache
402 $this->cache[$k] = $post_id;
403
404
405 // return
406 return $post_id;
407
408 }
409
410 }
411
412 // initialize
413 acf()->revisions = new acf_revisions();
414
415 endif; // class_exists check
416
417
418 /*
419 * acf_save_post_revision
420 *
421 * This function will copy meta from a post to it's latest revision
422 *
423 * @type function
424 * @date 26/09/2016
425 * @since 5.4.0
426 *
427 * @param $post_id (int)
428 * @return n/a
429 */
430
431 function acf_save_post_revision( $post_id = 0 ) {
432
433 // get latest revision
434 $revision = acf_get_post_latest_revision( $post_id );
435
436
437 // save
438 if( $revision ) {
439
440 acf_copy_postmeta( $post_id, $revision->ID );
441
442 }
443
444 }
445
446
447 /*
448 * acf_get_post_latest_revision
449 *
450 * This function will return the latest revision for a given post
451 *
452 * @type function
453 * @date 25/06/2016
454 * @since 5.3.8
455 *
456 * @param $post_id (int)
457 * @return $post_id (int)
458 */
459
460 function acf_get_post_latest_revision( $post_id ) {
461
462 // vars
463 $revisions = wp_get_post_revisions( $post_id );
464
465
466 // shift off and return first revision (will return null if no revisions)
467 $revision = array_shift($revisions);
468
469
470 // return
471 return $revision;
472
473 }
474
475
476 ?>