Merge branch 'release/5.7.9' into develop

This commit is contained in:
Remco Tolsma 2018-12-19 09:14:02 +01:00
commit be39e3ba22
20 changed files with 477 additions and 305 deletions

View File

@ -3,7 +3,7 @@
Plugin Name: Advanced Custom Fields PRO
Plugin URI: https://www.advancedcustomfields.com/
Description: Customize WordPress with powerful, professional and intuitive fields.
Version: 5.7.8
Version: 5.7.9
Author: Elliot Condon
Author URI: http://www.elliotcondon.com/
Copyright: Elliot Condon
@ -18,7 +18,7 @@ if( ! class_exists('ACF') ) :
class ACF {
/** @var string The plugin version number */
var $version = '5.7.8';
var $version = '5.7.9';
/** @var array The plugin settings array */
var $settings = array();
@ -170,6 +170,7 @@ class ACF {
acf_include('includes/forms/form-front.php');
acf_include('includes/forms/form-nav-menu.php');
acf_include('includes/forms/form-post.php');
acf_include('includes/forms/form-gutenberg.php');
acf_include('includes/forms/form-taxonomy.php');
acf_include('includes/forms/form-user.php');
acf_include('includes/forms/form-widget.php');

View File

@ -190,7 +190,7 @@
border-bottom-width: 0;
}
.acf-tooltip.right {
margin-right: -8px;
margin-left: 8px;
}
.acf-tooltip.right:before {
top: 50%;
@ -200,7 +200,7 @@
border-left-width: 0;
}
.acf-tooltip.bottom {
margin-bottom: -8px;
margin-top: 8px;
}
.acf-tooltip.bottom:before {
bottom: 100%;

View File

@ -279,9 +279,6 @@ html[dir="rtl"] .acf-fields.-left > .acf-field > .acf-input {
.acf-postbox {
position: relative;
}
#acf_after_title-sortables .acf-postbox {
margin: 20px 0 0;
}
.acf-postbox > .inside {
margin: 0 !important;
/* override WP style - do not delete - you have tried this before */
@ -310,6 +307,9 @@ html[dir="rtl"] .acf-fields.-left > .acf-field > .acf-input {
padding: 15px;
text-align: center;
}
#post-body-content #acf_after_title-sortables {
margin: 20px 0 -20px;
}
/* seamless */
.acf-postbox.seamless {
border: 0 none;

View File

@ -777,69 +777,42 @@
return $el.find('select, textarea, input').serializeArray();
}
/**
* acf.serializeAjax
* acf.serializeForAjax
*
* Returns an object containing name => value data ready to be encoded for Ajax.
*
* @date 15/8/18
* @since 5.7.3
* @date 17/12/18
* @since 5.8.0
*
* @param jQUery $el The element or form to serialize.
* @param string prefix The input prefix to scope to.
* @return object
*/
/*
acf.serializeAjax = function( $el, prefix ){
acf.serializeForAjax = function( $el ){
// vars
var data = {};
var index = {};
var inputs = $el.find('select, textarea, input').serializeArray();
// remove prefix
if( prefix !== undefined ) {
// Serialize inputs.
var inputs = acf.serializeArray( $el );
// filter and modify
inputs = inputs.filter(function( item ){
return item.name.indexOf(prefix) === 0;
}).map(function( item ){
// remove prefix from name
item.name = item.name.slice(prefix.length);
// fix [foo][bar] to foo[bar]
if( item.name.slice(0, 1) == '[' ) {
item.name = item.name.slice(1).replace(']', '');
}
return item;
});
}
// build object
// Loop over inputs and build data.
inputs.map(function( item ){
// fix foo[] to foo[0], foo[1], etc
// Append to array.
if( item.name.slice(-2) === '[]' ) {
// ensure index exists
index[ item.name ] = index[ item.name ] || 0;
index[ item.name ]++;
// replace [] with [0]
item.name = item.name.replace('[]', '[' + (index[ item.name ]-1) + ']');
}
// append to data
data[ item.name ] = data[ item.name ] || [];
data[ item.name ].push( item.value );
// Append
} else {
data[ item.name ] = item.value;
}
});
// return
return data;
};
*/
/**
* addAction
@ -2112,6 +2085,21 @@
return ( getLocks( $el, type ).length > 0 );
};
/**
* acf.isGutenberg
*
* Returns true if the Gutenberg editor is being used.
*
* @date 14/11/18
* @since 5.8.0
*
* @param vois
* @return bool
*/
acf.isGutenberg = function(){
return ( window.wp && wp.blocks );
};
/*
* exists
*
@ -3489,11 +3477,12 @@
changed: false,
actions: {
'validation_failure': 'startListening'
'validation_failure': 'startListening',
'validation_success': 'stopListening'
},
events: {
'change .acf-field': 'startListening',
'change form .acf-field': 'startListening',
'submit form': 'stopListening'
},
@ -4036,46 +4025,47 @@
var $target = this.get('target');
if( !$target ) return;
// reset class
$tooltip.removeClass('right left bottom top');
// Reset position.
$tooltip.removeClass('right left bottom top').css({ top: 0, left: 0 });
// position
// Declare tollerance to edge of screen.
var tolerance = 10;
var target_w = $target.outerWidth();
var target_h = $target.outerHeight();
var target_t = $target.offset().top;
var target_l = $target.offset().left;
var tooltip_w = $tooltip.outerWidth();
var tooltip_h = $tooltip.outerHeight();
// calculate top
var top = target_t - tooltip_h;
var left = target_l + (target_w / 2) - (tooltip_w / 2);
// Find target position.
var targetWidth = $target.outerWidth();
var targetHeight = $target.outerHeight();
var targetTop = $target.offset().top;
var targetLeft = $target.offset().left;
// too far left
// Find tooltip position.
var tooltipWidth = $tooltip.outerWidth();
var tooltipHeight = $tooltip.outerHeight();
var tooltipTop = $tooltip.offset().top; // Should be 0, but WP media grid causes this to be 32 (toolbar padding).
// Assume default top alignment.
var top = targetTop - tooltipHeight - tooltipTop;
var left = targetLeft + (targetWidth / 2) - (tooltipWidth / 2);
// Check if too far left.
if( left < tolerance ) {
$tooltip.addClass('right');
left = target_l + target_w;
top = target_t + (target_h / 2) - (tooltip_h / 2);
// too far right
} else if( (left + tooltip_w + tolerance) > $(window).width() ) {
left = targetLeft + targetWidth;
top = targetTop + (targetHeight / 2) - (tooltipHeight / 2) - tooltipTop;
// Check if too far right.
} else if( (left + tooltipWidth + tolerance) > $(window).width() ) {
$tooltip.addClass('left');
left = target_l - tooltip_w;
top = target_t + (target_h / 2) - (tooltip_h / 2);
left = targetLeft - tooltipWidth;
top = targetTop + (targetHeight / 2) - (tooltipHeight / 2) - tooltipTop;
// too far top
// Check if too far up.
} else if( top - $(window).scrollTop() < tolerance ) {
$tooltip.addClass('bottom');
top = target_t + target_h;
top = targetTop + targetHeight - tooltipTop;
// No colision with edges.
} else {
$tooltip.addClass('top');
}
// update css
@ -5540,6 +5530,15 @@
return this.$('input[type="text"]');
},
setValue: function( val ){
// update input (with change)
acf.val( this.$input(), val );
// update iris
this.$inputText().iris('color', val);
},
initialize: function(){
// vars
@ -6011,8 +6010,7 @@
var lat = this.get('lat');
var lng = this.get('lng');
// map
// Create Map.
var mapArgs = {
scrollwheel: false,
zoom: parseInt( zoom ),
@ -6026,10 +6024,8 @@
};
mapArgs = acf.applyFilters('google_map_args', mapArgs, this);
var map = new google.maps.Map( this.$canvas()[0], mapArgs );
this.addMapEvents( map, this );
// marker
// Create Marker.
var markerArgs = acf.parseArgs(mapArgs.marker, {
draggable: true,
raiseOnDrag: true,
@ -6037,12 +6033,23 @@
});
markerArgs = acf.applyFilters('google_map_marker_args', markerArgs, this);
var marker = new google.maps.Marker( markerArgs );
this.addMarkerEvents( marker, this );
// Maybe Create Autocomplete.
var autocomplete = false;
if( acf.isset(google, 'maps', 'places', 'Autocomplete') ) {
var autocompleteArgs = mapArgs.autocomplete || {};
autocompleteArgs = acf.applyFilters('google_map_autocomplete_args', autocompleteArgs, this);
autocomplete = new google.maps.places.Autocomplete( this.$search()[0], autocompleteArgs );
autocomplete.bindTo('bounds', map);
}
// reference
// Add map events.
this.addMapEvents( this, map, marker, autocomplete );
// Append references.
map.acf = this;
map.marker = marker;
map.autocomplete = autocomplete;
this.map = map;
// action for 3rd party customization
@ -6053,17 +6060,33 @@
this.renderVal( val );
},
addMapEvents: function( map, field ){
addMapEvents: function( field, map, marker, autocomplete ){
// autocomplete
if( acf.isset(window, 'google', 'maps', 'places', 'Autocomplete') ) {
// Click map.
google.maps.event.addListener( map, 'click', function( e ) {
// vars
var autocompleteArgs = map.autocomplete || {};
var autocomplete = new google.maps.places.Autocomplete( this.$search()[0], autocompleteArgs );
var lat = e.latLng.lat();
var lng = e.latLng.lng();
// bind
autocomplete.bindTo('bounds', map);
// search
field.searchPosition( lat, lng );
});
// Drag marker.
google.maps.event.addListener( marker, 'dragend', function(){
// vars
var position = this.getPosition();
var lat = position.lat();
var lng = position.lng();
// search
field.searchPosition( lat, lng );
});
// Autocomplete search.
if( autocomplete ) {
// autocomplete event place_changed is triggered each time the input changes
// customize the place object with the current "search value" to allow users controll over the address text
@ -6073,30 +6096,6 @@
field.setPlace( place );
});
}
// click
google.maps.event.addListener( map, 'click', function( e ) {
// vars
var lat = e.latLng.lat();
var lng = e.latLng.lng();
// search
field.searchPosition( lat, lng );
});
},
addMarkerEvents: function( marker, field ){
// dragend
google.maps.event.addListener( marker, 'dragend', function(){
// vars
var position = this.getPosition();
var lat = position.lat();
var lng = position.lng();
// search
field.searchPosition( lat, lng );
});
},
searchPosition: function( lat, lng ){
@ -10508,6 +10507,24 @@
// return
return this;
},
save: function( event ) {
var data = {};
if ( event ) {
event.preventDefault();
}
//_.each( this.$el.serializeArray(), function( pair ) {
// data[ pair.name ] = pair.value;
//});
// Serialize data more thoroughly to allow chckbox inputs to save.
data = acf.serializeForAjax(this.$el);
this.controller.trigger( 'attachment:compat:waiting', ['waiting'] );
this.model.saveCompat( data ).always( _.bind( this.postSave, this ) );
}
});
@ -10649,30 +10666,6 @@
'change #product-type': 'onChange'
},
initialize: function(){
},
/*
checkScreenEvents: function(){
// vars
var events = [
'change #page_template',
'change #parent_id',
'change #post-formats-select input',
'change .categorychecklist input',
'change .categorychecklist select',
'change .acf-taxonomy-field[data-save="1"] input',
'change .acf-taxonomy-field[data-save="1"] select',
'change #product-type'
];
acf.screen.on('change', '#product-type', 'fetch');
},
*/
isPost: function(){
return acf.get('screen') === 'post';
},
@ -10715,6 +10708,10 @@
return this.getPageParent() ? 'child' : 'parent';
},
getPostType: function(){
return $('#post_type').val();
},
getPostFormat: function( e, $el ){
var $el = $('#post-formats-select input:checked');
if( $el.length ) {
@ -10724,7 +10721,7 @@
return null;
},
getPostTerms: function(){
getPostCoreTerms: function(){
// vars
var terms = {};
@ -10750,6 +10747,15 @@
}
}
// return
return terms;
},
getPostTerms: function(){
// Get core terms.
var terms = this.getPostCoreTerms();
// loop over taxonomy fields and add their values
acf.getFields({type: 'taxonomy'}).map(function( field ){
@ -10819,6 +10825,11 @@
ajaxData.post_id = acf.get('post_id');
}
// post type
if( (postType = this.getPostType()) !== null ) {
ajaxData.post_type = postType;
}
// page template
if( (pageTemplate = this.getPageTemplate()) !== null ) {
ajaxData.page_template = pageTemplate;
@ -10914,48 +10925,114 @@
}
});
/*
// tests
acf.registerScreenChange('#page_template', function( e, $el ){
return $('#page_template').val();
/**
* gutenScreen
*
* Adds compatibility with the Gutenberg edit screen.
*
* @date 11/12/18
* @since 5.8.0
*
* @param void
* @return void
*/
var gutenScreen = new acf.Model({
// Wait until load to avoid 'core' issues when loading taxonomies.
wait: 'load',
initialize: function(){
// Bail early if not Gutenberg.
if( !acf.isGutenberg() ) {
return;
}
// Listen for changes.
wp.data.subscribe(this.proxy(this.onChange));
// Customize "acf.screen.get" functions.
acf.screen.getPageTemplate = this.getPageTemplate;
acf.screen.getPageParent = this.getPageParent;
acf.screen.getPostType = this.getPostType;
acf.screen.getPostFormat = this.getPostFormat;
acf.screen.getPostCoreTerms = this.getPostCoreTerms;
},
onChange: function(){
// Get edits.
var edits = wp.data.select( 'core/editor' ).getPostEdits();
// Check specific attributes.
var attributes = [
'template',
'parent',
'format'
];
// Append taxonomy attributes.
var taxonomies = wp.data.select( 'core' ).getTaxonomies() || [];
taxonomies.map(function( taxonomy ){
attributes.push( taxonomy.rest_base );
});
acf.registerScreenData({
name: 'page_template',
change: '#page_template',
val: function(){
var $input = $(this.el);
return $input.length ? $input.val() : null;
// Filter out attributes that have not changed.
attributes = attributes.filter(this.proxy(function( attr ){
return ( edits[attr] && edits[attr] !== this.get(attr) );
}));
// Trigger change if has attributes.
if( attributes.length ) {
this.triggerChange( edits )
}
},
triggerChange: function( edits ){
// Update this.data if edits are provided.
if( edits !== undefined ) {
this.data = edits;
}
// Check screen.
acf.screen.check();
},
getPageTemplate: function(){
return wp.data.select( 'core/editor' ).getEditedPostAttribute( 'template' );
},
getPageParent: function( e, $el ){
return wp.data.select( 'core/editor' ).getEditedPostAttribute( 'parent' );
},
getPostType: function(){
return wp.data.select( 'core/editor' ).getEditedPostAttribute( 'type' );
},
getPostFormat: function( e, $el ){
return wp.data.select( 'core/editor' ).getEditedPostAttribute( 'format' );
},
getPostCoreTerms: function(){
// vars
var terms = {};
// Loop over taxonomies.
var taxonomies = wp.data.select( 'core' ).getTaxonomies() || [];
taxonomies.map(function( taxonomy ){
// Append selected taxonomies to terms object.
terms[ taxonomy.slug ] = wp.data.select( 'core/editor' ).getEditedPostAttribute( taxonomy.rest_base );
});
acf.registerScreenData({
name: 'post_terms',
change: '.acf-taxonomy-field[data-save="1"]',
val: function(){
var $input = $(this.el);
return $input.length ? $input.val() : null;
}
});
acf.registerScreenData({
name: 'post_terms',
change: '#product-type',
val: function( terms ){
var $select = $('#product-type');
if( $select.length ) {
terms.push('product_cat:'+$select.val());
}
// return
return terms;
}
},
});
acf.screen.get('post_terms');
acf.screen.getPostTerms();
*/
})(jQuery);
(function($, undefined){

File diff suppressed because one or more lines are too long

View File

@ -304,8 +304,8 @@ class ACF_Admin_Tool_Export extends ACF_Admin_Tool {
'prefix' => false,
'value' => '',
'choices' => array(
'all' => 'Include all settings',
'minimal' => 'Ignore empty settings'
'all' => __('Include all settings', 'acf'),
'minimal' => __('Ignore empty settings', 'acf'),
)
));
*/

View File

@ -18,7 +18,7 @@ $class = $active ? 'single' : 'grid';
?>
<div class="wrap" id="acf-admin-tools">
<h1><?php _e('Tools', 'acf'); ?> <?php if( $active ): ?><a class="page-title-action" href="<?php echo acf_get_admin_tools_url(); ?>">Back to all tools</a><?php endif; ?></h1>
<h1><?php _e('Tools', 'acf'); ?> <?php if( $active ): ?><a class="page-title-action" href="<?php echo acf_get_admin_tools_url(); ?>"><?php _e('Back to all tools', 'acf'); ?></a><?php endif; ?></h1>
<div class="acf-meta-box-wrap -<?php echo $class; ?>">
<?php do_meta_boxes( $screen_id, 'normal', '' ); ?>

View File

@ -3604,51 +3604,63 @@ function acf_get_truncated( $text, $length = 64 ) {
function acf_get_current_url() {
// vars
$home = home_url();
// Get url to current request.
$url = home_url($_SERVER['REQUEST_URI']);
// test
//$home = 'http://acf5/dev/wp-admin';
//$url = $home . '/dev/wp-admin/api-template/acf_form';
// explode url (4th bit is the sub folder)
$bits = explode('/', $home, 4);
/*
Array (
[0] => http:
[1] =>
[2] => acf5
[3] => dev
)
*/
// handle sub folder
if( !empty($bits[3]) ) {
$find = '/' . $bits[3];
$pos = strpos($url, $find);
$length = strlen($find);
if( $pos !== false ) {
$url = substr_replace($url, '', $pos, $length);
// Fix bug where multisite sub-directory path segment is repeated.
// Eg. http://multisite.local/sub1/sub1/sample-page/
if( is_multisite() ) {
$url = acf_str_join( home_url(), $_SERVER['REQUEST_URI'] );
}
}
// return
// Return url.
return $url;
}
/**
* acf_str_join
*
* Joins together 2 strings removing any overlapping characters.
* Useful for urls. Eg: 'test.local/foo/' + '/foo/bar/' = 'test.local/foo/bar/'
*
* @date 19/11/18
* @since 5.8.0
*
* @param string $s1 The first string.
* @param string $s2 The seccond string.
* @return string
*/
function acf_str_join( $s1 = '', $s2 = '' ) {
// Remember number of chars that overlap.
$overlap = 0;
// Find shortest word length.
$length = min( strlen($s1), strlen($s2) );
// Find number of chars that overlap.
for( $i = 0; $i < $length; $i++ ) {
if( substr($s1, -$i) === substr($s2, 0, $i) ) {
$overlap = $i;
}
}
// shorten $s2 based on overlap
if( $overlap ) {
$s2 = substr($s2, $overlap);
}
// Return joined string.
return $s1 . $s2;
}
// Tests.
//acf_test( acf_str_join('http://multisite.local/sub1/', '/sample-page/'), 'http://multisite.local/sub1/sample-page/' );
//acf_test( acf_str_join('http://multisite.local/sub1/', 'sample-page/'), 'http://multisite.local/sub1/sample-page/' );
//acf_test( acf_str_join('http://multisite.local/sub1/', '/sub1'), 'http://multisite.local/sub1/sub1' );
//acf_test( acf_str_join('http://multisite.local/sub1/', '/sub1/sample-page/'), 'http://multisite.local/sub1/sample-page/' );
//acf_test( acf_str_join('http://multisite.local/', '/sub1/sample-page/'), 'http://multisite.local/sub1/sample-page/' );
/*
* acf_current_user_can_admin
@ -5076,43 +5088,54 @@ function acf_strip_protocol( $url ) {
*
* @type function
* @date 11/01/2017
* @since 5.8.0 Added filter to prevent connection.
* @since 5.5.4
*
* @param $attachment_id (int)
* @param $post_id (int)
* @return (boolean)
* @param int $attachment_id The attachment ID.
* @param int $post_id The post ID.
* @return bool True if attachment was connected.
*/
function acf_connect_attachment_to_post( $attachment_id = 0, $post_id = 0 ) {
// bail ealry if $attachment_id is not valid
if( !$attachment_id || !is_numeric($attachment_id) ) return false;
// Bail ealry if $attachment_id is not valid.
if( !$attachment_id || !is_numeric($attachment_id) ) {
return false;
}
// Bail ealry if $post_id is not valid.
if( !$post_id || !is_numeric($post_id) ) {
return false;
}
// bail ealry if $post_id is not valid
if( !$post_id || !is_numeric($post_id) ) return false;
/**
* Filters whether or not to connect the attachment.
*
* @date 8/11/18
* @since 5.8.0
*
* @param bool $bool Returning false will prevent the connection. Default true.
* @param int $attachment_id The attachment ID.
* @param int $post_id The post ID.
*/
if( !apply_filters('acf/connect_attachment_to_post', true, $attachment_id, $post_id) ) {
return false;
}
// vars
$post = get_post( $attachment_id );
// check if valid post
// Check if is valid post.
if( $post && $post->post_type == 'attachment' && $post->post_parent == 0 ) {
// update
wp_update_post( array('ID' => $post->ID, 'post_parent' => $post_id) );
// return
return true;
}
// return
return true;
}

View File

@ -413,6 +413,7 @@ function have_rows( $selector, $post_id = false ) {
// case: Change in $post_id was due to a nested loop ending
// action: move up one level through the loops
acf_remove_loop('active');
$active_loop = $previous_loop;
} else {
@ -435,6 +436,7 @@ function have_rows( $selector, $post_id = false ) {
// case: Change in $field_name was due to a nested loop ending
// action: move up one level through the loops
acf_remove_loop('active');
$active_loop = $previous_loop;
} else {

View File

@ -118,9 +118,9 @@ class acf_field_date_picker extends acf_field {
);
// special attributes
foreach( array( 'readonly', 'disabled', 'required' ) as $k ) {
foreach( array( 'readonly', 'disabled' ) as $k ) {
if( !empty($field[ $k ]) ) {
$hidden_input[ $k ] = $text_input[ $k ] = $k;
$text_input[ $k ] = $k;
}
}

View File

@ -674,6 +674,26 @@ class acf_field__group extends acf_field {
}
}
/**
* delete_field
*
* Called when deleting a field of this type.
*
* @date 8/11/18
* @since 5.8.0
*
* @param arra $field The field settings.
* @return void
*/
function delete_field( $field ) {
// loop over sub fields and delete them
if( $field['sub_fields'] ) {
foreach( $field['sub_fields'] as $sub_field ) {
acf_delete_field( $sub_field['ID'] );
}
}
}
}

View File

@ -169,24 +169,22 @@ class acf_field_message extends acf_field {
*
* @return $field - the field array holding all the field options
*/
function load_field( $field ) {
// remove name to avoid caching issue
$field['name'] = '';
// remove instructions
$field['instructions'] = '';
// remove required to avoid JS issues
$field['required'] = 0;
// set value other than 'null' to avoid ACF loading / caching issue
$field['value'] = false;
// return
return $field;
}
}

View File

@ -305,6 +305,11 @@ class acf_field_select extends acf_field {
$select['multiple'] = 'multiple';
$select['size'] = 5;
$select['name'] .= '[]';
// Reduce size to single line if UI.
if( $field['ui'] ) {
$select['size'] = 1;
}
}

View File

@ -134,12 +134,14 @@ class acf_field_tab extends acf_field {
*
* @return $field - the field array holding all the field options
*/
function load_field( $field ) {
// remove name to avoid caching issue
$field['name'] = '';
// remove instructions
$field['instructions'] = '';
// remove required to avoid JS issues
$field['required'] = 0;

View File

@ -203,14 +203,10 @@ class acf_field_user extends acf_field {
}
}
// optgroup or single
if( !empty($args['role']) && count($args['role']) == 1 ) {
$results = $results[0]['children'];
}
}

View File

@ -1,6 +1,6 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly.
if( ! class_exists('ACF_Form_Gutenberg') ) :
@ -11,79 +11,108 @@ class ACF_Form_Gutenberg {
*
* Setup for class functionality.
*
* @date 13/2/18
* @since 5.6.9
* @date 13/12/18
* @since 5.8.0
*
* @param n/a
* @return n/a
* @param void
* @return void
*/
function __construct() {
// filters
add_filter( 'replace_editor', array($this, 'replace_editor'), 99, 2 );
}
// Add actions.
add_action('enqueue_block_editor_assets', array($this, 'enqueue_block_editor_assets'));
/**
* replace_editor
*
* Check if Gutenberg is replacing the editor.
*
* @date 13/2/18
* @since 5.6.9
*
* @param boolean $replace True if the editor is being replaced by Gutenberg.
* @param object $post The WP_Post being edited.
* @return boolean
*/
function replace_editor( $replace, $post ) {
// check if Gutenberg is replacing
if( $replace ) {
// actions
add_action('admin_footer', array($this, 'admin_footer'));
}
// return
return $replace;
// Ignore validation during meta-box-loader AJAX request.
add_action('acf/validate_save_post', array($this, 'acf_validate_save_post'), 999);
}
/**
* admin_footer
* enqueue_block_editor_assets
*
* Append missing HTML to Gutenberg editor.
* Allows a safe way to customize Guten-only functionality.
*
* @date 13/2/18
* @since 5.6.9
* @date 14/12/18
* @since 5.8.0
*
* @param n/a
* @return n/a
* @param void
* @return void
*/
function enqueue_block_editor_assets() {
function admin_footer() {
// Remove edit_form_after_title.
add_action( 'add_meta_boxes', array($this, 'add_meta_boxes'), 20, 0 );
// edit_form_after_title is not run due to missing action, call this manually
?>
<div id="acf-form-after-title">
<?php acf_get_instance('ACF_Form_Post')->edit_form_after_title(); ?>
</div>
<?php
// Call edit_form_after_title manually.
add_action( 'block_editor_meta_box_hidden_fields', array($this, 'block_editor_meta_box_hidden_fields') );
}
/**
* add_meta_boxes
*
* Modify screen for Gutenberg.
*
* @date 13/12/18
* @since 5.8.0
*
* @param void
* @return void
*/
function add_meta_boxes() {
// move #acf-form-after-title
// Remove 'edit_form_after_title' action.
remove_action('edit_form_after_title', array(acf_get_instance('ACF_Form_Post'), 'edit_form_after_title'));
}
/**
* block_editor_meta_box_hidden_fields
*
* Modify screen for Gutenberg.
*
* @date 13/12/18
* @since 5.8.0
*
* @param void
* @return void
*/
function block_editor_meta_box_hidden_fields() {
// Manually call 'edit_form_after_title' function.
acf_get_instance('ACF_Form_Post')->edit_form_after_title();
// Move elements around screen.
?>
<script type="text/javascript">
$('#normal-sortables').before( $('#acf-form-after-title') );
(function($) {
acf.addAction('prepare', function(){
$('#normal-sortables').before( $('#acf_after_title-sortables') );
}, 1);
})(jQuery);
</script>
<?php
}
/**
* acf_validate_save_post
*
* Ignore errors during the Gutenberg "save metaboxes" AJAX request.
* Allows data to save and prevent UX issues.
*
* @date 16/12/18
* @since 5.8.0
*
* @param void
* @return void
*/
function acf_validate_save_post() {
// Check if current request came from Gutenberg.
if( isset($_GET['meta-box-loader']) ) {
acf_reset_validation_errors();
}
}
}
acf_new_instance('ACF_Form_Gutenberg');
endif;
?>

View File

@ -336,10 +336,9 @@ class ACF_Form_Post {
return $post_id;
}
// validate for published post (allow draft to save without validation)
// Validate and display errors for published post.
// - Allows draft to save without validation.
if( $post->post_status == 'publish' ) {
// show errors
acf_validate_save_post( true );
}

View File

@ -268,7 +268,14 @@ if( $this->view == 'add' ): ?>
// vars
var $form = $('#addtag');
var $fields = $('#acf-term-fields');
var html = $fields.html();
var html = '';
// Store a copy of the $fields html used later to replace after AJAX request.
// Hook into 'prepare' action to allow ACF core helpers to first modify DOM.
// Fixes issue where hidden #acf-hidden-wp-editor is initialized again.
acf.addAction('prepare', function(){
html = $fields.html();
}, 6);
// WP triggers click as primary action
$submit.on('click', function( e ){

View File

@ -436,7 +436,8 @@ class acf_field_gallery extends acf_field {
// get posts
$posts = acf_get_posts(array(
'post_type' => 'attachment',
'post__in' => $post__in
'post__in' => $post__in,
'update_post_meta_cache' => true
));

View File

@ -66,6 +66,18 @@ From your WordPress dashboard
== Changelog ==
= 5.7.9 =
*Release Date - 17 December 2018*
* Fix - Added custom metabox location (acf_after_title) compatibility with Gutenberg.
* Fix - Added dynamic metabox check compatibility with Gutenberg.
* Fix - Fixed bug causing required date picker fields to prevent form submit.
* Fix - Fixed bug preventing multi-input values from saving correctly within media modals.
* Fix - Fixed bug where `acf_form()` redirects to an incorrect URL for sub-sites.
* Fix - Fixed bug where breaking out of a sub `have_rows()` loop could produce undesired results.
* Dev - Added filter 'acf/connect_attachment_to_post' to prevent connecting attachments to posts.
* Dev - Added JS filter 'google_map_autocomplete_args' to customize Google Maps autocomplete settings.
= 5.7.8 =
*Release Date - 7 December 2018*