Merge branch 'release/5.7.9' into develop
This commit is contained in:
commit
be39e3ba22
5
acf.php
5
acf.php
|
|
@ -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');
|
||||
|
|
|
|||
|
|
@ -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%;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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'),
|
||||
)
|
||||
));
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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', '' ); ?>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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'];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
?>
|
||||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ){
|
||||
|
|
|
|||
|
|
@ -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
|
||||
));
|
||||
|
||||
|
||||
|
|
|
|||
12
readme.txt
12
readme.txt
|
|
@ -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*
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue