PluginProbe
Advanced Custom Fields (ACF®) / 6.0.3
Advanced Custom Fields (ACF®) v6.0.3
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 / upgrades.php
upgrades.php
546 lines 11.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * acf_has_upgrade
5 *
6 * Returns true if this site has an upgrade avaialble.
7 *
8 * @date 24/8/18
9 * @since 5.7.4
10 *
11 * @param void
12 * @return bool
13 */
14 function acf_has_upgrade() {
15 $db_version = acf_get_db_version();
16
17 if ( $db_version && acf_version_compare( $db_version, '<', ACF_UPGRADE_VERSION ) ) {
18 return true;
19 }
20
21 if ( $db_version !== ACF_VERSION ) {
22 acf_update_db_version( ACF_VERSION );
23 }
24
25 return false;
26 }
27
28 /**
29 * Runs upgrade routines if this site has an upgrade available.
30 *
31 * @date 24/8/18
32 * @since 5.7.4
33 */
34 function acf_upgrade_all() {
35 // Increase time limit if possible.
36 if ( function_exists( 'set_time_limit' ) ) {
37 set_time_limit( 600 );
38 }
39
40 // start timer
41 timer_start();
42
43 // log
44 acf_dev_log( 'ACF Upgrade Begin.' );
45
46 // vars
47 $db_version = acf_get_db_version();
48
49 // 5.0.0
50 if ( acf_version_compare( $db_version, '<', '5.0.0' ) ) {
51 acf_upgrade_500();
52 }
53
54 // 5.5.0
55 if ( acf_version_compare( $db_version, '<', '5.5.0' ) ) {
56 acf_upgrade_550();
57 }
58
59 /**
60 * When adding new upgrade routines here, increment the ACF_UPGRADE_VERSION
61 * constant in `acf.php` to the new highest upgrade version.
62 */
63
64 // upgrade DB version once all updates are complete
65 acf_update_db_version( ACF_VERSION );
66
67 if ( is_multisite() ) {
68 // Clears the network upgrade notification banner after site upgrades.
69 delete_site_transient( 'acf_network_upgrade_needed_' . ACF_UPGRADE_VERSION );
70 }
71
72 // log
73 global $wpdb;
74 acf_dev_log( 'ACF Upgrade Complete.', $wpdb->num_queries, timer_stop( 0 ) );
75 }
76
77 /**
78 * acf_get_db_version
79 *
80 * Returns the ACF DB version.
81 *
82 * @date 10/09/2016
83 * @since 5.4.0
84 *
85 * @param void
86 * @return string
87 */
88 function acf_get_db_version() {
89 return get_option( 'acf_version' );
90 }
91
92 /*
93 * acf_update_db_version
94 *
95 * Updates the ACF DB version.
96 *
97 * @date 10/09/2016
98 * @since 5.4.0
99 *
100 * @param string $version The new version.
101 * @return void
102 */
103 function acf_update_db_version( $version = '' ) {
104 update_option( 'acf_version', $version );
105 }
106
107 /**
108 * acf_upgrade_500
109 *
110 * Version 5 introduces new post types for field groups and fields.
111 *
112 * @date 23/8/18
113 * @since 5.7.4
114 *
115 * @param void
116 * @return void
117 */
118 function acf_upgrade_500() {
119
120 // log
121 acf_dev_log( 'ACF Upgrade 5.0.0.' );
122
123 // action
124 do_action( 'acf/upgrade_500' );
125
126 // do tasks
127 acf_upgrade_500_field_groups();
128
129 // update version
130 acf_update_db_version( '5.0.0' );
131 }
132
133 /**
134 * acf_upgrade_500_field_groups
135 *
136 * Upgrades all ACF4 field groups to ACF5
137 *
138 * @date 23/8/18
139 * @since 5.7.4
140 *
141 * @param void
142 * @return void
143 */
144 function acf_upgrade_500_field_groups() {
145
146 // log
147 acf_dev_log( 'ACF Upgrade 5.0.0 Field Groups.' );
148
149 // get old field groups
150 $ofgs = get_posts(
151 array(
152 'numberposts' => -1,
153 'post_type' => 'acf',
154 'orderby' => 'menu_order title',
155 'order' => 'asc',
156 'suppress_filters' => true,
157 )
158 );
159
160 // loop
161 if ( $ofgs ) {
162 foreach ( $ofgs as $ofg ) {
163 acf_upgrade_500_field_group( $ofg );
164 }
165 }
166 }
167
168 /**
169 * acf_upgrade_500_field_group
170 *
171 * Upgrades a ACF4 field group to ACF5
172 *
173 * @date 23/8/18
174 * @since 5.7.4
175 *
176 * @param object $ofg The old field group post object.
177 * @return array $nfg The new field group array.
178 */
179 function acf_upgrade_500_field_group( $ofg ) {
180
181 // log
182 acf_dev_log( 'ACF Upgrade 5.0.0 Field Group.', $ofg );
183
184 // vars
185 $nfg = array(
186 'ID' => 0,
187 'title' => $ofg->post_title,
188 'menu_order' => $ofg->menu_order,
189 );
190
191 // construct the location rules
192 $rules = get_post_meta( $ofg->ID, 'rule', false );
193 $anyorall = get_post_meta( $ofg->ID, 'allorany', true );
194 if ( is_array( $rules ) ) {
195
196 // if field group was duplicated, rules may be a serialized string!
197 $rules = array_map( 'maybe_unserialize', $rules );
198
199 // convert rules to groups
200 $nfg['location'] = acf_convert_rules_to_groups( $rules, $anyorall );
201 }
202
203 // settings
204 if ( $position = get_post_meta( $ofg->ID, 'position', true ) ) {
205 $nfg['position'] = $position;
206 }
207
208 if ( $layout = get_post_meta( $ofg->ID, 'layout', true ) ) {
209 $nfg['layout'] = $layout;
210 }
211
212 if ( $hide_on_screen = get_post_meta( $ofg->ID, 'hide_on_screen', true ) ) {
213 $nfg['hide_on_screen'] = maybe_unserialize( $hide_on_screen );
214 }
215
216 // save field group
217 // acf_upgrade_field_group will call the acf_get_valid_field_group function and apply 'compatibility' changes
218 $nfg = acf_update_field_group( $nfg );
219
220 // log
221 acf_dev_log( '> Complete.', $nfg );
222
223 // action for 3rd party
224 do_action( 'acf/upgrade_500_field_group', $nfg, $ofg );
225
226 // upgrade fields
227 acf_upgrade_500_fields( $ofg, $nfg );
228
229 // trash?
230 if ( $ofg->post_status == 'trash' ) {
231 acf_trash_field_group( $nfg['ID'] );
232 }
233
234 // return
235 return $nfg;
236 }
237
238 /**
239 * acf_upgrade_500_fields
240 *
241 * Upgrades all ACF4 fields to ACF5 from a specific field group
242 *
243 * @date 23/8/18
244 * @since 5.7.4
245 *
246 * @param object $ofg The old field group post object.
247 * @param array $nfg The new field group array.
248 * @return void
249 */
250 function acf_upgrade_500_fields( $ofg, $nfg ) {
251
252 // log
253 acf_dev_log( 'ACF Upgrade 5.0.0 Fields.' );
254
255 // global
256 global $wpdb;
257
258 // get field from postmeta
259 $rows = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE post_id = %d AND meta_key LIKE %s", $ofg->ID, 'field_%' ), ARRAY_A );
260
261 // check
262 if ( $rows ) {
263
264 // vars
265 $checked = array();
266
267 // loop
268 foreach ( $rows as $row ) {
269
270 // vars
271 $field = $row['meta_value'];
272 $field = maybe_unserialize( $field );
273 $field = maybe_unserialize( $field ); // run again for WPML
274
275 // bail early if key already migrated (potential duplicates in DB)
276 if ( isset( $checked[ $field['key'] ] ) ) {
277 continue;
278 }
279 $checked[ $field['key'] ] = 1;
280
281 // add parent
282 $field['parent'] = $nfg['ID'];
283
284 // migrate field
285 $field = acf_upgrade_500_field( $field );
286 }
287 }
288 }
289
290 /**
291 * acf_upgrade_500_field
292 *
293 * Upgrades a ACF4 field to ACF5
294 *
295 * @date 23/8/18
296 * @since 5.7.4
297 *
298 * @param array $field The old field.
299 * @return array $field The new field.
300 */
301 function acf_upgrade_500_field( $field ) {
302
303 // log
304 acf_dev_log( 'ACF Upgrade 5.0.0 Field.', $field );
305
306 // order_no is now menu_order
307 $field['menu_order'] = acf_extract_var( $field, 'order_no', 0 );
308
309 // correct very old field keys (field2 => field_2)
310 if ( substr( $field['key'], 0, 6 ) !== 'field_' ) {
311 $field['key'] = 'field_' . str_replace( 'field', '', $field['key'] );
312 }
313
314 // extract sub fields
315 $sub_fields = array();
316 if ( $field['type'] == 'repeater' ) {
317
318 // loop over sub fields
319 if ( ! empty( $field['sub_fields'] ) ) {
320 foreach ( $field['sub_fields'] as $sub_field ) {
321 $sub_fields[] = $sub_field;
322 }
323 }
324
325 // remove sub fields from field
326 unset( $field['sub_fields'] );
327
328 } elseif ( $field['type'] == 'flexible_content' ) {
329
330 // loop over layouts
331 if ( is_array( $field['layouts'] ) ) {
332 foreach ( $field['layouts'] as $i => $layout ) {
333
334 // generate key
335 $layout['key'] = uniqid( 'layout_' );
336
337 // loop over sub fields
338 if ( ! empty( $layout['sub_fields'] ) ) {
339 foreach ( $layout['sub_fields'] as $sub_field ) {
340 $sub_field['parent_layout'] = $layout['key'];
341 $sub_fields[] = $sub_field;
342 }
343 }
344
345 // remove sub fields from layout
346 unset( $layout['sub_fields'] );
347
348 // update
349 $field['layouts'][ $i ] = $layout;
350
351 }
352 }
353 }
354
355 // save field
356 $field = acf_update_field( $field );
357
358 // log
359 acf_dev_log( '> Complete.', $field );
360
361 // sub fields
362 if ( $sub_fields ) {
363 foreach ( $sub_fields as $sub_field ) {
364 $sub_field['parent'] = $field['ID'];
365 acf_upgrade_500_field( $sub_field );
366 }
367 }
368
369 // action for 3rd party
370 do_action( 'acf/update_500_field', $field );
371
372 // return
373 return $field;
374 }
375
376 /**
377 * acf_upgrade_550
378 *
379 * Version 5.5 adds support for the wp_termmeta table added in WP 4.4.
380 *
381 * @date 23/8/18
382 * @since 5.7.4
383 *
384 * @param void
385 * @return void
386 */
387 function acf_upgrade_550() {
388
389 // log
390 acf_dev_log( 'ACF Upgrade 5.5.0.' );
391
392 // action
393 do_action( 'acf/upgrade_550' );
394
395 // do tasks
396 acf_upgrade_550_termmeta();
397
398 // update version
399 acf_update_db_version( '5.5.0' );
400 }
401
402 /**
403 * acf_upgrade_550_termmeta
404 *
405 * Upgrades all ACF4 termmeta saved in wp_options to the wp_termmeta table.
406 *
407 * @date 23/8/18
408 * @since 5.7.4
409 *
410 * @param void
411 * @return void
412 */
413 function acf_upgrade_550_termmeta() {
414
415 // log
416 acf_dev_log( 'ACF Upgrade 5.5.0 Termmeta.' );
417
418 // bail early if no wp_termmeta table
419 if ( get_option( 'db_version' ) < 34370 ) {
420 return;
421 }
422
423 // get all taxonomies
424 $taxonomies = get_taxonomies( false, 'objects' );
425
426 // loop
427 if ( $taxonomies ) {
428 foreach ( $taxonomies as $taxonomy ) {
429 acf_upgrade_550_taxonomy( $taxonomy->name );
430 }
431 }
432
433 // action for 3rd party
434 do_action( 'acf/upgrade_550_termmeta' );
435 }
436
437 /*
438 * acf_wp_upgrade_550_termmeta
439 *
440 * When the database is updated to support term meta, migrate ACF term meta data across.
441 *
442 * @date 23/8/18
443 * @since 5.7.4
444 *
445 * @param string $wp_db_version The new $wp_db_version.
446 * @param string $wp_current_db_version The old (current) $wp_db_version.
447 * @return void
448 */
449 function acf_wp_upgrade_550_termmeta( $wp_db_version, $wp_current_db_version ) {
450 if ( $wp_db_version >= 34370 && $wp_current_db_version < 34370 ) {
451 if ( acf_version_compare( acf_get_db_version(), '>', '5.5.0' ) ) {
452 acf_upgrade_550_termmeta();
453 }
454 }
455 }
456 add_action( 'wp_upgrade', 'acf_wp_upgrade_550_termmeta', 10, 2 );
457
458 /**
459 * acf_upgrade_550_taxonomy
460 *
461 * Upgrades all ACF4 termmeta for a specific taxonomy.
462 *
463 * @date 24/8/18
464 * @since 5.7.4
465 *
466 * @param string $taxonomy The taxonomy name.
467 * @return void
468 */
469 function acf_upgrade_550_taxonomy( $taxonomy ) {
470
471 // log
472 acf_dev_log( 'ACF Upgrade 5.5.0 Taxonomy.', $taxonomy );
473
474 // global
475 global $wpdb;
476
477 // vars
478 $search = $taxonomy . '_%';
479 $_search = '_' . $search;
480
481 // escape '_'
482 // http://stackoverflow.com/questions/2300285/how-do-i-escape-in-sql-server
483 $search = str_replace( '_', '\_', $search );
484 $_search = str_replace( '_', '\_', $_search );
485
486 // search
487 // results show faster query times using 2 LIKE vs 2 wildcards
488 $rows = $wpdb->get_results(
489 $wpdb->prepare(
490 "SELECT *
491 FROM $wpdb->options
492 WHERE option_name LIKE %s
493 OR option_name LIKE %s",
494 $search,
495 $_search
496 ),
497 ARRAY_A
498 );
499
500 // loop
501 if ( $rows ) {
502 foreach ( $rows as $row ) {
503
504 /*
505 Use regex to find "(_)taxonomy_(term_id)_(field_name)" and populate $matches:
506 Array
507 (
508 [0] => _category_3_color
509 [1] => _
510 [2] => 3
511 [3] => color
512 )
513 */
514 if ( ! preg_match( "/^(_?){$taxonomy}_(\d+)_(.+)/", $row['option_name'], $matches ) ) {
515 continue;
516 }
517
518 // vars
519 $term_id = $matches[2];
520 $meta_key = $matches[1] . $matches[3];
521 $meta_value = $row['option_value'];
522
523 // update
524 // memory usage reduced by 50% by using a manual insert vs update_metadata() function.
525 // update_metadata( 'term', $term_id, $meta_name, $meta_value );
526 $wpdb->insert(
527 $wpdb->termmeta,
528 array(
529 'term_id' => $term_id,
530 'meta_key' => $meta_key,
531 'meta_value' => $meta_value,
532 )
533 );
534
535 // log
536 acf_dev_log( 'ACF Upgrade 5.5.0 Term.', $term_id, $meta_key );
537
538 // action
539 do_action( 'acf/upgrade_550_taxonomy_term', $term_id );
540 }
541 }
542
543 // action for 3rd party
544 do_action( 'acf/upgrade_550_taxonomy', $taxonomy );
545 }
546